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@xxxxxxxxxxx/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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list