]> xenbits.xensource.com Git - libvirt.git/commitdiff
Support QEMU's virtual FAT block device driver
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 16 Nov 2009 18:08:29 +0000 (18:08 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 23 Nov 2009 12:17:16 +0000 (12:17 +0000)
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

14 files changed:
docs/schemas/domain.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_conf.c
src/security/security_selinux.c
src/xen/xend_internal.c
src/xen/xm_internal.c
tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tests/qemuxml2xmltest.c

index e726801fe173b1093ee71fb573f8b626576b13fc..5b8f7f8a9fbacedc6abef94f4597a8b815efb203 100644 (file)
             <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>
index 0a7eef7bc3ef3c85f085589718d436df57bf14ca..42820a7f962b34abab40e8726cd7ae81f3c1f3f9 100644 (file)
@@ -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",
index 1fdb4fac7ecfe691b3740aa43c9b3a7b4c82b78f..62014639f96b2c179dea4b5c54ef055e7a465f8b 100644 (file)
@@ -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
 };
index f26e94dd8e2eda53474163ebdb9acea28f64a825..5f68411f88712e36d1faf9091924293f71390120 100644 (file)
@@ -1994,8 +1994,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);
@@ -2003,6 +2025,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 &&
@@ -2071,7 +2094,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);
index bd838e67a997252053009232ffe4cb2f6e6749d1..255ba537b5ca21ac68fab0f2249f1d980cd7f9e3 100644 (file)
@@ -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;
         }
index d61e9e699b07c99319750a0ae6891cec16788f0c..e370eb887ad44423ef283fc97832275311addc3b 100644 (file)
@@ -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;
             }
         }
     }
index 2ee321f0b3e9f0af9d50bdaa655ca51e77e6a8ab..40c199682eda08835afd7cf23efe2aa4a4b912fd 100644 (file)
@@ -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);
     }
index 1ef2602b7614ff1c8fc71cb0e5ef3c27f588e6a9..1dd90d035a0ace5dd057c16ebc1a37647c63d5fb 100644 (file)
@@ -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 (file)
index 0000000..da1163b
--- /dev/null
@@ -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 (file)
index 0000000..818ca93
--- /dev/null
@@ -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 (file)
index 0000000..4b4e3f4
--- /dev/null
@@ -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 (file)
index 0000000..9e32b68
--- /dev/null
@@ -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>
index c94837994610996d8fd9e5cb2928e65ab51d1cd4..677c5b4ccb61754fed85672aa2d1acf20d025057 100644 (file)
@@ -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 |
index 25ef2ce235f9c828af82e54e44ffccb9d9784d08..793900c8e3ab99f965364f3c2b8d74cedd212491 100644 (file)
@@ -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");