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