On Tue, Nov 17, 2009 at 04:08:08PM +0100, Daniel Veillard wrote: > On Tue, Nov 17, 2009 at 01:20:15PM +0000, Daniel P. Berrange wrote: > > 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"); > > ACK, that's funky, and I guess this will stay a qemu only feature. > One thing I wonder about the semantic is what happen if the underlying > files get modified while QEmu tries to access that 'floppy'. I assume > "domain can crash an burn" is just fine Yes, QEMU has this to say "What you should never do: * use non-ASCII filenames ; * use "-snapshot" together with ":rw:" ; * expect it to work when loadvm'ing ; * write to the FAT directory on the host system while accessing it with the guest system. " Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list