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 --- docs/schemas/domain.rng | 16 ++++++ src/conf/domain_conf.c | 36 ++++++++++++-- src/conf/domain_conf.h | 1 + src/qemu/qemu_conf.c | 49 ++++++++++++++++++- src/security/security_selinux.c | 3 + src/xen/xend_internal.c | 7 ++- src/xen/xm_internal.c | 16 +++++- .../qemuxml2argv-disk-cdrom-empty.args | 2 +- .../qemuxml2argv-disk-drive-fat.args | 1 + .../qemuxml2argv-disk-drive-fat.xml | 24 ++++++++++ .../qemuxml2argv-floppy-drive-fat.args | 1 + .../qemuxml2argv-floppy-drive-fat.xml | 24 ++++++++++ tests/qemuxml2argvtest.c | 4 ++ tests/qemuxml2xmltest.c | 2 + 14 files changed, 173 insertions(+), 13 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 1bf44fd..7a3ef97 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -434,6 +434,22 @@ <ref name="diskspec"/> </interleave> </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"/> </choice> </element> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0a7eef7..42820a7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -90,7 +90,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, "block", - "file") + "file", + "dir") VIR_ENUM_IMPL(virDomainDiskDevice, VIR_DOMAIN_DISK_DEVICE_LAST, "disk", @@ -777,10 +778,22 @@ virDomainDiskDefParseXML(virConnectPtr conn, if ((source == NULL) && (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"); - else + break; + case VIR_DOMAIN_DISK_TYPE_BLOCK: 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 when they mean to omit the source element @@ -3951,12 +3964,25 @@ virDomainDiskDefFormat(virConnectPtr conn, } 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", def->src); - else + break; + case VIR_DOMAIN_DISK_TYPE_BLOCK: virBufferEscapeString(buf, " <source dev='%s'/>\n", 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", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1fdb4fa..6201463 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -67,6 +67,7 @@ enum virDomainVirtType { enum virDomainDiskType { VIR_DOMAIN_DISK_TYPE_BLOCK, VIR_DOMAIN_DISK_TYPE_FILE, + VIR_DOMAIN_DISK_TYPE_DIR, VIR_DOMAIN_DISK_TYPE_LAST }; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index c807688..2d72b4b 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1980,8 +1980,30 @@ int qemudBuildCommandLine(virConnectPtr conn, break; } - virBufferVSprintf(&opt, "file=%s", disk->src ? disk->src : ""); - virBufferVSprintf(&opt, ",if=%s", bus); + if (disk->src) { + 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) virBufferAddLit(&opt, ",media=cdrom"); virBufferVSprintf(&opt, ",index=%d", idx); @@ -1989,6 +2011,7 @@ int qemudBuildCommandLine(virConnectPtr conn, disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) virBufferAddLit(&opt, ",boot=on"); if (disk->driverType && + disk->type != VIR_DOMAIN_DISK_TYPE_DIR && qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_FORMAT) virBufferVSprintf(&opt, ",format=%s", disk->driverType); if (disk->serial && @@ -2057,7 +2080,27 @@ int qemudBuildCommandLine(virConnectPtr conn, } } - snprintf(file, PATH_MAX, "%s", disk->src); + 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); + } ADD_ARG_LIT(dev); ADD_ARG_LIT(file); diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index bd838e6..255ba53 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -687,6 +687,9 @@ SELinuxSetSecurityLabel(virConnectPtr conn, if (secdef->imagelabel) { 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) return -1; } diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index d61e9e6..e370eb8 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -5375,11 +5375,16 @@ xenDaemonFormatSxprDisk(virConnectPtr conn ATTRIBUTE_UNUSED, } else { if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) { virBufferVSprintf(buf, "(uname 'file:%s')", def->src); - } else { + } else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) { if (def->src[0] == '/') virBufferVSprintf(buf, "(uname 'phy:%s')", def->src); else virBufferVSprintf(buf, "(uname 'phy:/dev/%s')", def->src); + } else { + virXendError(conn, VIR_ERR_CONFIG_UNSUPPORTED, + _("unsupported disk type %s"), + virDomainDiskTypeToString(def->type)); + return -1; } } } diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c index f833ce7..31cff12 100644 --- a/src/xen/xm_internal.c +++ b/src/xen/xm_internal.c @@ -1973,9 +1973,19 @@ static int xenXMDomainConfigFormatDisk(virConnectPtr conn, if (STREQ(disk->driverName, "tap")) virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio"); } else { - virBufferVSprintf(&buf, "%s:", - disk->type == VIR_DOMAIN_DISK_TYPE_FILE ? - "file" : "phy"); + switch (disk->type) { + case VIR_DOMAIN_DISK_TYPE_FILE: + 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); } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args index 1ef2602..1dd90d0 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args @@ -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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args new file mode 100644 index 0000000..da1163b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args @@ -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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml new file mode 100644 index 0000000..818ca93 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml @@ -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> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args new file mode 100644 index 0000000..4b4e3f4 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args @@ -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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml new file mode 100644 index 0000000..9e32b68 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml @@ -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> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index c948379..677c5b4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -211,6 +211,10 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_DRIVE_BOOT); DO_TEST("disk-drive-boot-cdrom", QEMUD_CMD_FLAG_DRIVE | 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 | QEMUD_CMD_FLAG_DRIVE_BOOT | QEMUD_CMD_FLAG_DRIVE_FORMAT); DO_TEST("disk-drive-shared", QEMUD_CMD_FLAG_DRIVE | diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 25ef2ce..793900c 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -98,6 +98,8 @@ mymain(int argc, char **argv) DO_TEST("disk-many"); DO_TEST("disk-xenvbd"); DO_TEST("disk-usb"); + DO_TEST("floppy-drive-fat"); + DO_TEST("disk-drive-fat"); DO_TEST("disk-drive-fmt-qcow"); DO_TEST("disk-drive-cache-v1-wt"); DO_TEST("disk-drive-cache-v1-wb"); -- 1.6.5.2 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list