[libvirt] [PATCH] vbox: Support shared folders

Matthias Bolte matthias.bolte at googlemail.com
Tue Jun 7 11:38:18 UTC 2011


Shared folders are handled as filesystems and can also be hotplugged.
---

Currently this just maps shared folder to a filesystem element with type
mount. The filesystem element has an accessmode attribute that is not
useful for VirtualBox. Als the target element only has a dir attribute,
but VirtualBox shares doen't support that, you can only give them a name.

<filesystem type='mount' accessmode='passthrough'>
  <source dir='/tmp'/>
  <target dir='foobar'/>
  <readonly/>
</filesystem>

I wonder if we should add a shared folder type like this:

<filesystem type='sharedfolder'>
  <source dir='/tmp'/>
  <target name='foobar'/>
  <readonly/>
</filesystem>

Or is this to specific to VirtualBox?

VirtualBox 4.0 added the automount option that automatically mounts a
shared folder in the guest. On Windows it is mounted to a free drive
letter on Linux it's mounted to /media/<prefix>_<shared-folder-name>.
The <prefix> is a global configuration option in VirtualBox. I wonder
if and how to expose that in libvirt.

Matthias

 docs/drvvbox.html.in |    5 ++
 src/vbox/vbox_tmpl.c |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+), 0 deletions(-)

diff --git a/docs/drvvbox.html.in b/docs/drvvbox.html.in
index ef55757..1fcafde 100644
--- a/docs/drvvbox.html.in
+++ b/docs/drvvbox.html.in
@@ -61,6 +61,11 @@ vbox+ssh://user@example.com/session  (remote access, SSH tunnelled)
       <target dev='fda'/>
     </disk>
 
+    <filesystem type='mount'>
+      <source dir='/home/user/stuff'/>
+      <target dir='my-shared-folder'/>
+    </filesystem>
+
     <!--BRIDGE-->
     <interface type='bridge'>
       <source bridge='eth0'/>
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 2986f5a..13c324f 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -2249,6 +2249,7 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, int flags) {
                     /* Not supported by libvirt yet */
                 } else if (device == DeviceType_SharedFolder) {
                     /* Not supported by libvirt yet */
+                    /* Can VirtualBox really boot from a shared folder? */
                 }
             }
 
@@ -2752,6 +2753,67 @@ static char *vboxDomainGetXMLDesc(virDomainPtr dom, int flags) {
 
 #endif /* VBOX_API_VERSION >= 3001 */
 
+            /* shared folders */
+            vboxArray sharedFolders = VBOX_ARRAY_INITIALIZER;
+
+            def->nfss = 0;
+
+            vboxArrayGet(&sharedFolders, machine,
+                         machine->vtbl->GetSharedFolders);
+
+            if (sharedFolders.count > 0) {
+                if (VIR_ALLOC_N(def->fss, sharedFolders.count) < 0) {
+                    virReportOOMError();
+                    goto sharedFoldersCleanup;
+                }
+
+                for (i = 0; i < sharedFolders.count; i++) {
+                    ISharedFolder *sharedFolder = sharedFolders.items[i];
+                    PRUnichar *nameUtf16 = NULL;
+                    char *name = NULL;
+                    PRUnichar *hostPathUtf16 = NULL;
+                    char *hostPath = NULL;
+                    PRBool writable = PR_FALSE;
+
+                    if (VIR_ALLOC(def->fss[i]) < 0) {
+                        virReportOOMError();
+                        goto sharedFoldersCleanup;
+                    }
+
+                    def->fss[i]->type = VIR_DOMAIN_FS_TYPE_MOUNT;
+
+                    sharedFolder->vtbl->GetHostPath(sharedFolder, &hostPathUtf16);
+                    VBOX_UTF16_TO_UTF8(hostPathUtf16, &hostPath);
+                    def->fss[i]->src = strdup(hostPath);
+                    VBOX_UTF8_FREE(hostPath);
+                    VBOX_UTF16_FREE(hostPathUtf16);
+
+                    if (def->fss[i]->src == NULL) {
+                        virReportOOMError();
+                        goto sharedFoldersCleanup;
+                    }
+
+                    sharedFolder->vtbl->GetName(sharedFolder, &nameUtf16);
+                    VBOX_UTF16_TO_UTF8(nameUtf16, &name);
+                    def->fss[i]->dst = strdup(name);
+                    VBOX_UTF8_FREE(name);
+                    VBOX_UTF16_FREE(nameUtf16);
+
+                    if (def->fss[i]->dst == NULL) {
+                        virReportOOMError();
+                        goto sharedFoldersCleanup;
+                    }
+
+                    sharedFolder->vtbl->GetWritable(sharedFolder, &writable);
+                    def->fss[i]->readonly = !writable;
+
+                    ++def->nfss;
+                }
+            }
+
+sharedFoldersCleanup:
+            vboxArrayRelease(&sharedFolders);
+
             /* dump network cards if present */
             def->nnets = 0;
             /* Get which network cards are enabled */
@@ -4790,6 +4852,38 @@ vboxAttachUSB(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
     }
 }
 
+static void
+vboxAttachSharedFolder(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine)
+{
+    int i;
+    PRUnichar *nameUtf16;
+    PRUnichar *hostPathUtf16;
+    PRBool writable;
+
+    if (def->nfss == 0)
+        return;
+
+    for (i = 0; i < def->nfss; i++) {
+        if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
+            continue;
+
+        VBOX_UTF8_TO_UTF16(def->fss[i]->dst, &nameUtf16);
+        VBOX_UTF8_TO_UTF16(def->fss[i]->src, &hostPathUtf16);
+        writable = !def->fss[i]->readonly;
+
+#if VBOX_API_VERSION < 4000
+        machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+                                          writable);
+#else /* VBOX_API_VERSION >= 4000 */
+        machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+                                          writable, PR_FALSE);
+#endif /* VBOX_API_VERSION >= 4000 */
+
+        VBOX_UTF16_FREE(nameUtf16);
+        VBOX_UTF16_FREE(hostPathUtf16);
+    }
+}
+
 static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
     VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL);
     IMachine       *machine     = NULL;
@@ -4927,6 +5021,7 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml) {
     vboxAttachVideo(def, machine);
     vboxAttachDisplay(def, data, machine);
     vboxAttachUSB(def, data, machine);
+    vboxAttachSharedFolder(def, data, machine);
 
     /* Save the machine settings made till now and close the
      * session. also free up the mchiid variable used.
@@ -5271,6 +5366,34 @@ static int vboxDomainAttachDeviceImpl(virDomainPtr dom,
                         if (dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
                         }
                     }
+                } else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
+                           dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
+                    PRUnichar *nameUtf16;
+                    PRUnichar *hostPathUtf16;
+                    PRBool writable;
+
+                    VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
+                    VBOX_UTF8_TO_UTF16(dev->data.fs->src, &hostPathUtf16);
+                    writable = !dev->data.fs->readonly;
+
+#if VBOX_API_VERSION < 4000
+                    rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+                                                           writable);
+#else /* VBOX_API_VERSION >= 4000 */
+                    rc = machine->vtbl->CreateSharedFolder(machine, nameUtf16, hostPathUtf16,
+                                                           writable, PR_FALSE);
+#endif /* VBOX_API_VERSION >= 4000 */
+
+                    if (NS_FAILED(rc)) {
+                        vboxError(VIR_ERR_INTERNAL_ERROR,
+                                  _("could not attach shared folder '%s', rc=%08x"),
+                                  dev->data.fs->dst, (unsigned)rc);
+                    } else {
+                        ret = 0;
+                    }
+
+                    VBOX_UTF16_FREE(nameUtf16);
+                    VBOX_UTF16_FREE(hostPathUtf16);
                 }
                 machine->vtbl->SaveSettings(machine);
                 VBOX_RELEASE(machine);
@@ -5425,6 +5548,23 @@ static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) {
                         if (dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
                         }
                     }
+                } else if (dev->type == VIR_DOMAIN_DEVICE_FS &&
+                           dev->data.fs->type == VIR_DOMAIN_FS_TYPE_MOUNT) {
+                    PRUnichar *nameUtf16;
+
+                    VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16);
+
+                    rc = machine->vtbl->RemoveSharedFolder(machine, nameUtf16);
+
+                    if (NS_FAILED(rc)) {
+                        vboxError(VIR_ERR_INTERNAL_ERROR,
+                                  _("could not detach shared folder '%s', rc=%08x"),
+                                  dev->data.fs->dst, (unsigned)rc);
+                    } else {
+                        ret = 0;
+                    }
+
+                    VBOX_UTF16_FREE(nameUtf16);
                 }
                 machine->vtbl->SaveSettings(machine);
                 VBOX_RELEASE(machine);
-- 
1.7.0.4




More information about the libvir-list mailing list