[libvirt] [PATCH 0/2] vmx: handle shared folders

The following patches add support for shared folders for VMware domains Jean-Baptiste Rouault (2): vmx: handle shared folders formatting vmx: handle shared folders parsing src/vmx/vmx.c | 193 +++++++++++++++++++++++++++- src/vmx/vmx.h | 5 + tests/vmx2xmldata/vmx2xml-sharedfolder.vmx | 9 ++ tests/vmx2xmldata/vmx2xml-sharedfolder.xml | 22 ++++ tests/vmx2xmltest.c | 2 + tests/xml2vmxdata/xml2vmx-sharedfolder.vmx | 18 +++ tests/xml2vmxdata/xml2vmx-sharedfolder.xml | 14 ++ tests/xml2vmxtest.c | 2 + 8 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 tests/vmx2xmldata/vmx2xml-sharedfolder.vmx create mode 100644 tests/vmx2xmldata/vmx2xml-sharedfolder.xml create mode 100644 tests/xml2vmxdata/xml2vmx-sharedfolder.vmx create mode 100644 tests/xml2vmxdata/xml2vmx-sharedfolder.xml -- 1.7.10.4

This patch adds support for generating vmx files with shared folders enabled. Update test suite accordingly. --- src/vmx/vmx.c | 59 +++++++++++++++++++++++++++- src/vmx/vmx.h | 3 ++ tests/xml2vmxdata/xml2vmx-sharedfolder.vmx | 18 +++++++++ tests/xml2vmxdata/xml2vmx-sharedfolder.xml | 14 +++++++ tests/xml2vmxtest.c | 2 + 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 tests/xml2vmxdata/xml2vmx-sharedfolder.vmx create mode 100644 tests/xml2vmxdata/xml2vmx-sharedfolder.xml diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index 3de7062..8a26f8c 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -262,6 +262,29 @@ def->disks[0]... ################################################################################ +## filesystems ################################################################# + + isolation.tools.hgfs.disable = "false" # defaults to "true" + +def->nfss = 1 <=> sharedFolder.maxNum = "1" # must match the number of shared folders + + sharedFolder[0..n] -> <filesystem> + +def->fss[0]... <=> sharedFolder0.present = "true" # defaults to "false" + sharedFolder0.enabled = "true" # defaults to "false" + sharedFolder0.expiration = "never" # defaults to "never" + sharedFolder0.readAccess = "true" # defaults to "false" +->type = _FS_TYPE_MOUNT +->fsdriver +->accessmode +->wrpolicy +->src = <value> <=> sharedFolder0.hostPath = "<value>" # defaults to ? +->dst = <value> <=> sharedFolder0.guestName = "<value>" +->readonly = <readonly> <=> sharedFolder0.writeAccess = "<value>" # "true" -> <readonly> = 0, "false" -> <readonly> = 1 + + + +################################################################################ ## nets ######################################################################## ethernet[0..3] -> <controller> @@ -3142,7 +3165,16 @@ virVMXFormatConfig(virVMXContext *ctx, virCapsPtr caps, virDomainDefPtr def, } /* def:fss */ - /* FIXME */ + if (def->nfss > 0) { + virBufferAddLit(&buffer, "isolation.tools.hgfs.disable = \"false\"\n"); + virBufferAsprintf(&buffer, "sharedFolder.maxNum = \"%d\"\n", def->nfss); + } + + for (i = 0; i < def->nfss; ++i) { + if (virVMXFormatFileSystem(def->fss[i], i, &buffer) < 0) { + goto cleanup; + } + } /* def:nets */ for (i = 0; i < def->nnets; ++i) { @@ -3496,6 +3528,31 @@ virVMXFormatFloppy(virVMXContext *ctx, virDomainDiskDefPtr def, int +virVMXFormatFileSystem(virDomainFSDefPtr def, int index, virBufferPtr buffer) +{ + if (def->type != VIR_DOMAIN_FS_TYPE_MOUNT) { + VMX_ERROR(VIR_ERR_CONFIG_UNSUPPORTED, + _("Only '%s' filesystem type is supported"), + virDomainFSTypeToString(VIR_DOMAIN_FS_TYPE_MOUNT)); + return -1; + } + + virBufferAsprintf(buffer, "sharedFolder%d.present = \"true\"\n", index); + virBufferAsprintf(buffer, "sharedFolder%d.enabled = \"true\"\n", index); + virBufferAsprintf(buffer, "sharedFolder%d.readAccess = \"true\"\n", index); + virBufferAsprintf(buffer, "sharedFolder%d.writeAccess = \"%s\"\n", index, + def->readonly ? "false" : "true"); + virBufferAsprintf(buffer, "sharedFolder%d.hostPath = \"%s\"\n", index, + def->src); + virBufferAsprintf(buffer, "sharedFolder%d.guestName = \"%s\"\n", index, + def->dst); + + return 0; +} + + + +int virVMXFormatEthernet(virDomainNetDefPtr def, int controller, virBufferPtr buffer) { diff --git a/src/vmx/vmx.h b/src/vmx/vmx.h index 4d54660..656aafa 100644 --- a/src/vmx/vmx.h +++ b/src/vmx/vmx.h @@ -120,6 +120,9 @@ int virVMXFormatCDROM(virVMXContext *ctx, virDomainDiskDefPtr def, int virVMXFormatFloppy(virVMXContext *ctx, virDomainDiskDefPtr def, virBufferPtr buffer, bool floppy_present[2]); +int virVMXFormatFileSystem(virDomainFSDefPtr def, int index, + virBufferPtr buffer); + int virVMXFormatEthernet(virDomainNetDefPtr def, int controller, virBufferPtr buffer); diff --git a/tests/xml2vmxdata/xml2vmx-sharedfolder.vmx b/tests/xml2vmxdata/xml2vmx-sharedfolder.vmx new file mode 100644 index 0000000..15a322a --- /dev/null +++ b/tests/xml2vmxdata/xml2vmx-sharedfolder.vmx @@ -0,0 +1,18 @@ +.encoding = "UTF-8" +config.version = "8" +virtualHW.version = "4" +guestOS = "other" +uuid.bios = "56 4d 9b ef ac d9 b4 e0-c8 f0 ae a8 b9 10 35 15" +displayName = "sharedFolder" +memsize = "4" +numvcpus = "1" +floppy0.present = "false" +floppy1.present = "false" +isolation.tools.hgfs.disable = "false" +sharedFolder.maxNum = "1" +sharedFolder0.present = "true" +sharedFolder0.enabled = "true" +sharedFolder0.readAccess = "true" +sharedFolder0.writeAccess = "true" +sharedFolder0.hostPath = "/path/to/shared" +sharedFolder0.guestName = "shared" diff --git a/tests/xml2vmxdata/xml2vmx-sharedfolder.xml b/tests/xml2vmxdata/xml2vmx-sharedfolder.xml new file mode 100644 index 0000000..2cc87d5 --- /dev/null +++ b/tests/xml2vmxdata/xml2vmx-sharedfolder.xml @@ -0,0 +1,14 @@ +<domain type='vmware'> + <name>sharedFolder</name> + <uuid>564d9bef-acd9-b4e0-c8f0-aea8b9103515</uuid> + <memory unit='KiB'>4096</memory> + <os> + <type>hvm</type> + </os> + <devices> + <filesystem type='mount'> + <source dir='/path/to/shared'/> + <target dir='shared'/> + </filesystem> + </devices> +</domain> diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c index 60a24b2..451b1e4 100644 --- a/tests/xml2vmxtest.c +++ b/tests/xml2vmxtest.c @@ -255,6 +255,8 @@ mymain(void) DO_TEST("floppy-file", "floppy-file", 4); DO_TEST("floppy-device", "floppy-device", 4); + DO_TEST("sharedfolder", "sharedfolder", 4); + DO_TEST("ethernet-e1000", "ethernet-e1000", 4); DO_TEST("ethernet-vmxnet2", "ethernet-vmxnet2", 4); -- 1.7.10.4

2012/7/11 Jean-Baptiste Rouault <jean-baptiste.rouault@diateam.net>:
This patch adds support for generating vmx files with shared folders enabled.
Update test suite accordingly.
+virVMXFormatFileSystem(virDomainFSDefPtr def, int index, virBufferPtr buffer)
I'll replace index with number here to avoid a warning about shadowing a global before pushing. ACK and pushed. -- Matthias Bolte http://photron.blogspot.com

This patch adds support for parsing vmx files with shared folders enabled. Update test suite accordingly. --- src/vmx/vmx.c | 134 +++++++++++++++++++++++++++- src/vmx/vmx.h | 2 + tests/vmx2xmldata/vmx2xml-sharedfolder.vmx | 9 ++ tests/vmx2xmldata/vmx2xml-sharedfolder.xml | 22 +++++ tests/vmx2xmltest.c | 2 + 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 tests/vmx2xmldata/vmx2xml-sharedfolder.vmx create mode 100644 tests/vmx2xmldata/vmx2xml-sharedfolder.xml diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index 8a26f8c..d4f75ee 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -1237,6 +1237,8 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx) bool present; int scsi_virtualDev[4] = { -1, -1, -1, -1 }; int unit; + bool hgfs_disabled = true; + long long shared_folders_num = 0; if (ctx->parseFileName == NULL) { VMX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", @@ -1676,7 +1678,37 @@ virVMXParseConfig(virVMXContext *ctx, virCapsPtr caps, const char *vmx) } /* def:fss */ - /* FIXME */ + if (virVMXGetConfigBoolean(conf, "isolation.tools.hgfs.disable", + &hgfs_disabled, true, true) < 0) { + goto cleanup; + } + + if (!hgfs_disabled) { + if (virVMXGetConfigLong(conf, "sharedFolder.maxNum", &shared_folders_num, + 0, true) < 0) { + goto cleanup; + } + + if (shared_folders_num) { + if (VIR_ALLOC_N(def->fss, shared_folders_num) < 0) { + virReportOOMError(); + goto cleanup; + } + + def->nfss = 0; + + for (port = 0; port < shared_folders_num; ++port) { + if (virVMXParseFileSystem(conf, port, + &def->fss[def->nfss]) < 0) { + goto cleanup; + } + + if (def->fss[def->nfss] != NULL) { + ++def->nfss; + } + } + } + } /* def:nets */ if (VIR_ALLOC_N(def->nets, 4) < 0) { @@ -2288,6 +2320,106 @@ virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf, +int virVMXParseFileSystem(virConfPtr conf, int index, virDomainFSDefPtr *def) +{ + int result = -1; + char prefix[48] = ""; + + char present_name[48] = ""; + bool present = false; + + char enabled_name[48] = ""; + bool enabled = false; + + char hostPath_name[48] = ""; + char *hostPath = NULL; + + char guestName_name[48] = ""; + char *guestName = NULL; + + char writeAccess_name[48] = ""; + bool writeAccess = false; + + if (def == NULL || *def != NULL) { + VMX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); + return -1; + } + + if (VIR_ALLOC(*def) < 0) { + virReportOOMError(); + return -1; + } + + (*def)->type = VIR_DOMAIN_FS_TYPE_MOUNT; + + snprintf(prefix, sizeof(prefix), "sharedFolder%d", index); + + VMX_BUILD_NAME(present); + VMX_BUILD_NAME(enabled); + VMX_BUILD_NAME(hostPath); + VMX_BUILD_NAME(guestName); + VMX_BUILD_NAME(writeAccess); + + /* vmx:present */ + if (virVMXGetConfigBoolean(conf, present_name, &present, false, true) < 0) { + goto cleanup; + } + + /* vmx:enabled */ + if (virVMXGetConfigBoolean(conf, enabled_name, &enabled, false, true) < 0) { + goto cleanup; + } + + if (!(present && enabled)) { + goto ignore; + } + + /* vmx:hostPath */ + if (virVMXGetConfigString(conf, hostPath_name, &hostPath, false) < 0) { + goto cleanup; + } + + (*def)->src = strdup(hostPath); + + /* vmx:guestName */ + if (virVMXGetConfigString(conf, guestName_name, &guestName, false) < 0) { + goto cleanup; + } + + (*def)->dst = strdup(guestName); + + /* vmx:writeAccess */ + if (virVMXGetConfigBoolean(conf, writeAccess_name, &writeAccess, false, + true) < 0) { + goto cleanup; + } + + (*def)->readonly = !writeAccess; + + result = 0; + + cleanup: + if (result < 0) { + virDomainFSDefFree(*def); + *def = NULL; + } + + VIR_FREE(hostPath); + VIR_FREE(guestName); + + return result; + + ignore: + virDomainFSDefFree(*def); + *def = NULL; + + result = 0; + + goto cleanup; +} + + + int virVMXParseEthernet(virConfPtr conf, int controller, virDomainNetDefPtr *def) { diff --git a/src/vmx/vmx.h b/src/vmx/vmx.h index 656aafa..8ae0707 100644 --- a/src/vmx/vmx.h +++ b/src/vmx/vmx.h @@ -90,6 +90,8 @@ int virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf, int device, int busType, int controllerOrBus, int unit, virDomainDiskDefPtr *def); +int virVMXParseFileSystem(virConfPtr conf, int index, virDomainFSDefPtr *def); + int virVMXParseEthernet(virConfPtr conf, int controller, virDomainNetDefPtr *def); int virVMXParseSerial(virVMXContext *ctx, virConfPtr conf, int port, diff --git a/tests/vmx2xmldata/vmx2xml-sharedfolder.vmx b/tests/vmx2xmldata/vmx2xml-sharedfolder.vmx new file mode 100644 index 0000000..e60fcd4 --- /dev/null +++ b/tests/vmx2xmldata/vmx2xml-sharedfolder.vmx @@ -0,0 +1,9 @@ +config.version = "8" +virtualHW.version = "4" +isolation.tools.hgfs.disable = "false" +sharedFolder.maxnum = "1" +sharedFolder0.present = "true" +sharedFolder0.enabled = "true" +sharedFolder0.hostPath = "/path/to/shared" +sharedFolder0.guestName = "shared" +sharedFolder0.writeAccess = "true" diff --git a/tests/vmx2xmldata/vmx2xml-sharedfolder.xml b/tests/vmx2xmldata/vmx2xml-sharedfolder.xml new file mode 100644 index 0000000..52b75de --- /dev/null +++ b/tests/vmx2xmldata/vmx2xml-sharedfolder.xml @@ -0,0 +1,22 @@ +<domain type='vmware'> + <uuid>00000000-0000-0000-0000-000000000000</uuid> + <memory unit='KiB'>32768</memory> + <currentMemory unit='KiB'>32768</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686'>hvm</type> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <filesystem type='mount' accessmode='passthrough'> + <source dir='/path/to/shared'/> + <target dir='shared'/> + </filesystem> + <video> + <model type='vmvga' vram='4096'/> + </video> + </devices> +</domain> diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c index 35740ea..4913152 100644 --- a/tests/vmx2xmltest.c +++ b/tests/vmx2xmltest.c @@ -240,6 +240,8 @@ mymain(void) DO_TEST("floppy-file", "floppy-file"); DO_TEST("floppy-device", "floppy-device"); + DO_TEST("sharedfolder", "sharedfolder"); + DO_TEST("ethernet-e1000", "ethernet-e1000"); DO_TEST("ethernet-vmxnet2", "ethernet-vmxnet2"); -- 1.7.10.4

2012/7/11 Jean-Baptiste Rouault <jean-baptiste.rouault@diateam.net>:
This patch adds support for parsing vmx files with shared folders enabled.
Update test suite accordingly. --- src/vmx/vmx.c | 134 +++++++++++++++++++++++++++- src/vmx/vmx.h | 2 + tests/vmx2xmldata/vmx2xml-sharedfolder.vmx | 9 ++ tests/vmx2xmldata/vmx2xml-sharedfolder.xml | 22 +++++ tests/vmx2xmltest.c | 2 + 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 tests/vmx2xmldata/vmx2xml-sharedfolder.vmx create mode 100644 tests/vmx2xmldata/vmx2xml-sharedfolder.xml
+int virVMXParseFileSystem(virConfPtr conf, int index, virDomainFSDefPtr *def)
I'll replace index with number here again as it shadows a global.
+ /* vmx:hostPath */ + if (virVMXGetConfigString(conf, hostPath_name, &hostPath, false) < 0) { + goto cleanup; + } + + (*def)->src = strdup(hostPath); + + /* vmx:guestName */ + if (virVMXGetConfigString(conf, guestName_name, &guestName, false) < 0) { + goto cleanup; + } + + (*def)->dst = strdup(guestName);
The result of strdup must be check for NULL. But there is no need to strdup it here as hostPath can just be stolen: (*def)->src = hostPath; hostPath = NULL; ACK and pushed with the mentioned changes. -- Matthias Bolte http://photron.blogspot.com
participants (2)
-
Jean-Baptiste Rouault
-
Matthias Bolte