mirror of https://gitee.com/openkylin/libvirt.git
Support QEMU's virtual FAT block device driver
Introduce a new type="dir" mode for <disks> that allows use of QEMU's virtual FAT block device driver. eg <disk type='dir' device='floppy'> <source dir='/tmp/test'/> <target dev='fda' bus='fdc'/> <readonly/> </disk> gets turned into -drive file=fat:floppy:/tmp/test,if=floppy,index=0 Only read-only disks are supported with virtual FAT mode * src/conf/domain_conf.c, src/conf/domain_conf.h: Add type="dir" * docs/schemas/domain.rng: Document new disk type * src/xen/xend_internal.c, src/xen/xm_internal.c: Raise error for unsupported disk types * tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args: Fix empty disk file handling * tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args, tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml, tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args, tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml tests/qemuxml2argvtest.c: Test QEMU vitual FAT driver * src/qemu/qemu_conf.c: Support generating fat:/some/dir type disk args * src/security/security_selinux.c: Temporarily skip labelling of directory based disks
This commit is contained in:
parent
a73cd93b24
commit
e7c78b0a94
|
@ -434,6 +434,22 @@
|
||||||
<ref name="diskspec"/>
|
<ref name="diskspec"/>
|
||||||
</interleave>
|
</interleave>
|
||||||
</group>
|
</group>
|
||||||
|
<group>
|
||||||
|
<attribute name="type">
|
||||||
|
<value>dir</value>
|
||||||
|
</attribute>
|
||||||
|
<interleave>
|
||||||
|
<optional>
|
||||||
|
<element name="source">
|
||||||
|
<attribute name="dir">
|
||||||
|
<ref name="absFilePath"/>
|
||||||
|
</attribute>
|
||||||
|
<empty/>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
|
<ref name="diskspec"/>
|
||||||
|
</interleave>
|
||||||
|
</group>
|
||||||
<ref name="diskspec"/>
|
<ref name="diskspec"/>
|
||||||
</choice>
|
</choice>
|
||||||
</element>
|
</element>
|
||||||
|
|
|
@ -90,7 +90,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
|
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
|
||||||
"block",
|
"block",
|
||||||
"file")
|
"file",
|
||||||
|
"dir")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainDiskDevice, VIR_DOMAIN_DISK_DEVICE_LAST,
|
VIR_ENUM_IMPL(virDomainDiskDevice, VIR_DOMAIN_DISK_DEVICE_LAST,
|
||||||
"disk",
|
"disk",
|
||||||
|
@ -777,10 +778,22 @@ virDomainDiskDefParseXML(virConnectPtr conn,
|
||||||
if ((source == NULL) &&
|
if ((source == NULL) &&
|
||||||
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
||||||
|
|
||||||
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE)
|
switch (def->type) {
|
||||||
|
case VIR_DOMAIN_DISK_TYPE_FILE:
|
||||||
source = virXMLPropString(cur, "file");
|
source = virXMLPropString(cur, "file");
|
||||||
else
|
break;
|
||||||
|
case VIR_DOMAIN_DISK_TYPE_BLOCK:
|
||||||
source = virXMLPropString(cur, "dev");
|
source = virXMLPropString(cur, "dev");
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_DISK_TYPE_DIR:
|
||||||
|
source = virXMLPropString(cur, "dir");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected disk type %s"),
|
||||||
|
virDomainDiskTypeToString(def->type));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* People sometimes pass a bogus '' source path
|
/* People sometimes pass a bogus '' source path
|
||||||
when they mean to omit the source element
|
when they mean to omit the source element
|
||||||
|
@ -3951,12 +3964,25 @@ virDomainDiskDefFormat(virConnectPtr conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->src) {
|
if (def->src) {
|
||||||
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE)
|
switch (def->type) {
|
||||||
|
case VIR_DOMAIN_DISK_TYPE_FILE:
|
||||||
virBufferEscapeString(buf, " <source file='%s'/>\n",
|
virBufferEscapeString(buf, " <source file='%s'/>\n",
|
||||||
def->src);
|
def->src);
|
||||||
else
|
break;
|
||||||
|
case VIR_DOMAIN_DISK_TYPE_BLOCK:
|
||||||
virBufferEscapeString(buf, " <source dev='%s'/>\n",
|
virBufferEscapeString(buf, " <source dev='%s'/>\n",
|
||||||
def->src);
|
def->src);
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_DISK_TYPE_DIR:
|
||||||
|
virBufferEscapeString(buf, " <source dir='%s'/>\n",
|
||||||
|
def->src);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected disk type %s"),
|
||||||
|
virDomainDiskTypeToString(def->type));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virBufferVSprintf(buf, " <target dev='%s' bus='%s'/>\n",
|
virBufferVSprintf(buf, " <target dev='%s' bus='%s'/>\n",
|
||||||
|
|
|
@ -67,6 +67,7 @@ enum virDomainVirtType {
|
||||||
enum virDomainDiskType {
|
enum virDomainDiskType {
|
||||||
VIR_DOMAIN_DISK_TYPE_BLOCK,
|
VIR_DOMAIN_DISK_TYPE_BLOCK,
|
||||||
VIR_DOMAIN_DISK_TYPE_FILE,
|
VIR_DOMAIN_DISK_TYPE_FILE,
|
||||||
|
VIR_DOMAIN_DISK_TYPE_DIR,
|
||||||
|
|
||||||
VIR_DOMAIN_DISK_TYPE_LAST
|
VIR_DOMAIN_DISK_TYPE_LAST
|
||||||
};
|
};
|
||||||
|
|
|
@ -1994,8 +1994,30 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
virBufferVSprintf(&opt, "file=%s", disk->src ? disk->src : "");
|
if (disk->src) {
|
||||||
virBufferVSprintf(&opt, ",if=%s", bus);
|
if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
|
||||||
|
/* QEMU only supports magic FAT format for now */
|
||||||
|
if (disk->driverType &&
|
||||||
|
STRNEQ(disk->driverType, "fat")) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unsupported disk driver type for '%s'"),
|
||||||
|
disk->driverType);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!disk->readonly) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("cannot create virtual FAT disks in read-write mode"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
|
||||||
|
virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src);
|
||||||
|
else
|
||||||
|
virBufferVSprintf(&opt, "file=fat:%s,", disk->src);
|
||||||
|
} else {
|
||||||
|
virBufferVSprintf(&opt, "file=%s,", disk->src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virBufferVSprintf(&opt, "if=%s", bus);
|
||||||
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
|
||||||
virBufferAddLit(&opt, ",media=cdrom");
|
virBufferAddLit(&opt, ",media=cdrom");
|
||||||
virBufferVSprintf(&opt, ",index=%d", idx);
|
virBufferVSprintf(&opt, ",index=%d", idx);
|
||||||
|
@ -2003,6 +2025,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||||
disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
|
disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
|
||||||
virBufferAddLit(&opt, ",boot=on");
|
virBufferAddLit(&opt, ",boot=on");
|
||||||
if (disk->driverType &&
|
if (disk->driverType &&
|
||||||
|
disk->type != VIR_DOMAIN_DISK_TYPE_DIR &&
|
||||||
qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_FORMAT)
|
qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_FORMAT)
|
||||||
virBufferVSprintf(&opt, ",format=%s", disk->driverType);
|
virBufferVSprintf(&opt, ",format=%s", disk->driverType);
|
||||||
if (disk->serial &&
|
if (disk->serial &&
|
||||||
|
@ -2071,7 +2094,27 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
|
||||||
|
/* QEMU only supports magic FAT format for now */
|
||||||
|
if (disk->driverType &&
|
||||||
|
STRNEQ(disk->driverType, "fat")) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unsupported disk driver type for '%s'"),
|
||||||
|
disk->driverType);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!disk->readonly) {
|
||||||
|
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("cannot create virtual FAT disks in read-write mode"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
|
||||||
|
snprintf(file, PATH_MAX, "fat:floppy:%s", disk->src);
|
||||||
|
else
|
||||||
|
snprintf(file, PATH_MAX, "fat:%s", disk->src);
|
||||||
|
} else {
|
||||||
snprintf(file, PATH_MAX, "%s", disk->src);
|
snprintf(file, PATH_MAX, "%s", disk->src);
|
||||||
|
}
|
||||||
|
|
||||||
ADD_ARG_LIT(dev);
|
ADD_ARG_LIT(dev);
|
||||||
ADD_ARG_LIT(file);
|
ADD_ARG_LIT(file);
|
||||||
|
|
|
@ -687,6 +687,9 @@ SELinuxSetSecurityLabel(virConnectPtr conn,
|
||||||
|
|
||||||
if (secdef->imagelabel) {
|
if (secdef->imagelabel) {
|
||||||
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
||||||
|
/* XXX fixme - we need to recursively label the entriy tree :-( */
|
||||||
|
if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
|
||||||
|
continue;
|
||||||
if (SELinuxSetSecurityImageLabel(conn, vm, vm->def->disks[i]) < 0)
|
if (SELinuxSetSecurityImageLabel(conn, vm, vm->def->disks[i]) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5375,11 +5375,16 @@ xenDaemonFormatSxprDisk(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
} else {
|
} else {
|
||||||
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
|
if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
|
||||||
virBufferVSprintf(buf, "(uname 'file:%s')", def->src);
|
virBufferVSprintf(buf, "(uname 'file:%s')", def->src);
|
||||||
} else {
|
} else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
|
||||||
if (def->src[0] == '/')
|
if (def->src[0] == '/')
|
||||||
virBufferVSprintf(buf, "(uname 'phy:%s')", def->src);
|
virBufferVSprintf(buf, "(uname 'phy:%s')", def->src);
|
||||||
else
|
else
|
||||||
virBufferVSprintf(buf, "(uname 'phy:/dev/%s')", def->src);
|
virBufferVSprintf(buf, "(uname 'phy:/dev/%s')", def->src);
|
||||||
|
} else {
|
||||||
|
virXendError(conn, VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("unsupported disk type %s"),
|
||||||
|
virDomainDiskTypeToString(def->type));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1973,9 +1973,19 @@ static int xenXMDomainConfigFormatDisk(virConnectPtr conn,
|
||||||
if (STREQ(disk->driverName, "tap"))
|
if (STREQ(disk->driverName, "tap"))
|
||||||
virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio");
|
virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio");
|
||||||
} else {
|
} else {
|
||||||
virBufferVSprintf(&buf, "%s:",
|
switch (disk->type) {
|
||||||
disk->type == VIR_DOMAIN_DISK_TYPE_FILE ?
|
case VIR_DOMAIN_DISK_TYPE_FILE:
|
||||||
"file" : "phy");
|
virBufferAddLit(&buf, "file:");
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_DISK_TYPE_BLOCK:
|
||||||
|
virBufferAddLit(&buf, "phy:");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
xenXMError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unsupported disk type %s"),
|
||||||
|
virDomainDiskTypeToString(disk->type));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
virBufferVSprintf(&buf, "%s", disk->src);
|
virBufferVSprintf(&buf, "%s", disk->src);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0 -drive file=,if=ide,media=cdrom,index=2 -net none -serial none -parallel none -usb
|
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0 -drive if=ide,media=cdrom,index=2 -net none -serial none -parallel none -usb
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=fat:/var/somefiles,if=ide,index=0,boot=on -net none -serial none -parallel none -usb
|
|
@ -0,0 +1,24 @@
|
||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory>219200</memory>
|
||||||
|
<currentMemory>219200</currentMemory>
|
||||||
|
<vcpu>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='dir' device='disk'>
|
||||||
|
<driver name='qemu' type='fat'/>
|
||||||
|
<source dir='/var/somefiles'/>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
<readonly/>
|
||||||
|
</disk>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
|
@ -0,0 +1 @@
|
||||||
|
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot a -drive file=fat:floppy:/var/somefiles,if=floppy,index=0 -net none -serial none -parallel none -usb
|
|
@ -0,0 +1,24 @@
|
||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory>219200</memory>
|
||||||
|
<currentMemory>219200</currentMemory>
|
||||||
|
<vcpu>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='fd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='dir' device='floppy'>
|
||||||
|
<driver name='qemu' type='fat'/>
|
||||||
|
<source dir='/var/somefiles'/>
|
||||||
|
<target dev='fda' bus='fdc'/>
|
||||||
|
<readonly/>
|
||||||
|
</disk>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
|
@ -211,6 +211,10 @@ mymain(int argc, char **argv)
|
||||||
QEMUD_CMD_FLAG_DRIVE_BOOT);
|
QEMUD_CMD_FLAG_DRIVE_BOOT);
|
||||||
DO_TEST("disk-drive-boot-cdrom", QEMUD_CMD_FLAG_DRIVE |
|
DO_TEST("disk-drive-boot-cdrom", QEMUD_CMD_FLAG_DRIVE |
|
||||||
QEMUD_CMD_FLAG_DRIVE_BOOT);
|
QEMUD_CMD_FLAG_DRIVE_BOOT);
|
||||||
|
DO_TEST("floppy-drive-fat", QEMUD_CMD_FLAG_DRIVE |
|
||||||
|
QEMUD_CMD_FLAG_DRIVE_BOOT | QEMUD_CMD_FLAG_DRIVE_FORMAT);
|
||||||
|
DO_TEST("disk-drive-fat", QEMUD_CMD_FLAG_DRIVE |
|
||||||
|
QEMUD_CMD_FLAG_DRIVE_BOOT | QEMUD_CMD_FLAG_DRIVE_FORMAT);
|
||||||
DO_TEST("disk-drive-fmt-qcow", QEMUD_CMD_FLAG_DRIVE |
|
DO_TEST("disk-drive-fmt-qcow", QEMUD_CMD_FLAG_DRIVE |
|
||||||
QEMUD_CMD_FLAG_DRIVE_BOOT | QEMUD_CMD_FLAG_DRIVE_FORMAT);
|
QEMUD_CMD_FLAG_DRIVE_BOOT | QEMUD_CMD_FLAG_DRIVE_FORMAT);
|
||||||
DO_TEST("disk-drive-shared", QEMUD_CMD_FLAG_DRIVE |
|
DO_TEST("disk-drive-shared", QEMUD_CMD_FLAG_DRIVE |
|
||||||
|
|
|
@ -98,6 +98,8 @@ mymain(int argc, char **argv)
|
||||||
DO_TEST("disk-many");
|
DO_TEST("disk-many");
|
||||||
DO_TEST("disk-xenvbd");
|
DO_TEST("disk-xenvbd");
|
||||||
DO_TEST("disk-usb");
|
DO_TEST("disk-usb");
|
||||||
|
DO_TEST("floppy-drive-fat");
|
||||||
|
DO_TEST("disk-drive-fat");
|
||||||
DO_TEST("disk-drive-fmt-qcow");
|
DO_TEST("disk-drive-fmt-qcow");
|
||||||
DO_TEST("disk-drive-cache-v1-wt");
|
DO_TEST("disk-drive-cache-v1-wt");
|
||||||
DO_TEST("disk-drive-cache-v1-wb");
|
DO_TEST("disk-drive-cache-v1-wb");
|
||||||
|
|
Loading…
Reference in New Issue