[libvirt] [PATCH v2 0/4] devices: filesystem: type volume

The patches introduce new filesystem type volume: <filesystem type='volume' accessmode='passthrough'> <driver type='ploop' format='ploop'/> <source pool='pool' volume='volume'/> <target dir='/'/> </filesystem> This makes possible to use storage volumes as the source for disks. v2: -split patches -rebased Olga Krishtal (4): filesystem: adds possibility to use storage pool as fs source devices: filesystems: added volume type vz: refactoring of prlsdkCreateCt vz: support filesystem type volume src/conf/domain_audit.c | 4 +- src/conf/domain_conf.c | 52 +++++++++++++--- src/conf/domain_conf.h | 4 +- src/libvirt_private.syms | 1 + src/lxc/lxc_cgroup.c | 2 +- src/lxc/lxc_container.c | 50 +++++++-------- src/lxc/lxc_controller.c | 18 +++--- src/lxc/lxc_native.c | 5 +- src/lxc/lxc_process.c | 4 +- src/openvz/openvz_conf.c | 6 +- src/openvz/openvz_driver.c | 4 +- src/qemu/qemu_command.c | 2 +- src/storage/storage_driver.c | 4 +- src/vbox/vbox_common.c | 6 +- src/vmx/vmx.c | 6 +- src/vz/vz_driver.c | 2 +- src/vz/vz_sdk.c | 145 ++++++++++++++++++++++++++++++++++--------- src/vz/vz_sdk.h | 2 +- 18 files changed, 221 insertions(+), 96 deletions(-) -- 1.8.3.1

Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com> --- src/conf/domain_audit.c | 4 ++-- src/conf/domain_conf.c | 34 ++++++++++++++++++++++++------- src/conf/domain_conf.h | 3 ++- src/libvirt_private.syms | 1 + src/lxc/lxc_cgroup.c | 2 +- src/lxc/lxc_container.c | 50 +++++++++++++++++++++++----------------------- src/lxc/lxc_controller.c | 18 ++++++++--------- src/lxc/lxc_native.c | 5 +++-- src/lxc/lxc_process.c | 4 ++-- src/openvz/openvz_conf.c | 6 +++--- src/openvz/openvz_driver.c | 4 ++-- src/qemu/qemu_command.c | 2 +- src/vbox/vbox_common.c | 6 +++--- src/vmx/vmx.c | 6 +++--- src/vz/vz_sdk.c | 12 +++++------ 15 files changed, 90 insertions(+), 67 deletions(-) diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index 6ad0acb..53a58ac 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -296,8 +296,8 @@ virDomainAuditFS(virDomainObjPtr vm, const char *reason, bool success) { virDomainAuditGenericDev(vm, "fs", - oldDef ? oldDef->src : NULL, - newDef ? newDef->src : NULL, + oldDef ? oldDef->src->path : NULL, + newDef ? newDef->src->path : NULL, reason, success); } diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9f7b906..0b33b3b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1698,12 +1698,31 @@ void virDomainControllerDefFree(virDomainControllerDefPtr def) VIR_FREE(def); } +virDomainFSDefPtr +virDomainFSDefNew(void) +{ + virDomainFSDefPtr ret; + + if (VIR_ALLOC(ret) < 0) + return NULL; + + if (VIR_ALLOC(ret->src) < 0) + goto cleanup; + + return ret; + + cleanup: + virDomainFSDefFree(ret); + return NULL; + +} + void virDomainFSDefFree(virDomainFSDefPtr def) { if (!def) return; - VIR_FREE(def->src); + virStorageSourceFree(def->src); VIR_FREE(def->dst); virDomainDeviceInfoClear(&def->info); @@ -8528,7 +8547,7 @@ virDomainFSDefParseXML(xmlNodePtr node, ctxt->node = node; - if (VIR_ALLOC(def) < 0) + if (!(def = virDomainFSDefNew())) return NULL; type = virXMLPropString(node, "type"); @@ -8655,7 +8674,7 @@ virDomainFSDefParseXML(xmlNodePtr node, goto error; } - def->src = source; + def->src->path = source; source = NULL; def->dst = target; target = NULL; @@ -20144,6 +20163,7 @@ virDomainFSDefFormat(virBufferPtr buf, const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode); const char *fsdriver = virDomainFSDriverTypeToString(def->fsdriver); const char *wrpolicy = virDomainFSWrpolicyTypeToString(def->wrpolicy); + const char *src = def->src->path; if (!type) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -20180,22 +20200,22 @@ virDomainFSDefFormat(virBufferPtr buf, case VIR_DOMAIN_FS_TYPE_MOUNT: case VIR_DOMAIN_FS_TYPE_BIND: virBufferEscapeString(buf, "<source dir='%s'/>\n", - def->src); + src); break; case VIR_DOMAIN_FS_TYPE_BLOCK: virBufferEscapeString(buf, "<source dev='%s'/>\n", - def->src); + src); break; case VIR_DOMAIN_FS_TYPE_FILE: virBufferEscapeString(buf, "<source file='%s'/>\n", - def->src); + src); break; case VIR_DOMAIN_FS_TYPE_TEMPLATE: virBufferEscapeString(buf, "<source name='%s'/>\n", - def->src); + src); break; case VIR_DOMAIN_FS_TYPE_RAM: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ba0ad5f..281abba 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -802,7 +802,7 @@ struct _virDomainFSDef { int wrpolicy; /* enum virDomainFSWrpolicy */ int format; /* virStorageFileFormat */ unsigned long long usage; /* in bytes */ - char *src; + virStorageSourcePtr src; char *dst; bool readonly; virDomainDeviceInfo info; @@ -2474,6 +2474,7 @@ virDomainDiskDefPtr virDomainDiskFindByBusAndDst(virDomainDefPtr def, int bus, char *dst); void virDomainControllerDefFree(virDomainControllerDefPtr def); +virDomainFSDefPtr virDomainFSDefNew(void); virDomainControllerDefPtr virDomainControllerDefNew(virDomainControllerType type); void virDomainFSDefFree(virDomainFSDefPtr def); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ccb4c5e..5f3a809 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -292,6 +292,7 @@ virDomainDiskSetDriver; virDomainDiskSetFormat; virDomainDiskSetSource; virDomainDiskSetType; +virDomainFSDefNew; virDomainFSDefFree; virDomainFSIndexByName; virDomainFSInsert; diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index ea86d36..1c42ab5 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -412,7 +412,7 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def, continue; if (virCgroupAllowDevicePath(cgroup, - def->fss[i]->src, + def->fss[i]->src->path, def->fss[i]->readonly ? VIR_CGROUP_DEVICE_READ : VIR_CGROUP_DEVICE_RW, false) < 0) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 916a37b..a39e24f 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -619,27 +619,27 @@ static int lxcContainerResolveSymlinks(virDomainFSDefPtr fs, bool gentle) if (!fs->src || fs->symlinksResolved) return 0; - if (access(fs->src, F_OK)) { + if (access(fs->src->path, F_OK)) { if (gentle) { /* Just ignore the error for the while, we'll try again later */ - VIR_DEBUG("Skipped unaccessible '%s'", fs->src); + VIR_DEBUG("Skipped unaccessible '%s'", fs->src->path); return 0; } else { virReportSystemError(errno, - _("Failed to access '%s'"), fs->src); + _("Failed to access '%s'"), fs->src->path); return -1; } } - VIR_DEBUG("Resolving '%s'", fs->src); - if (virFileResolveAllLinks(fs->src, &newroot) < 0) { + VIR_DEBUG("Resolving '%s'", fs->src->path); + if (virFileResolveAllLinks(fs->src->path, &newroot) < 0) { if (gentle) { - VIR_DEBUG("Skipped non-resolvable '%s'", fs->src); + VIR_DEBUG("Skipped non-resolvable '%s'", fs->src->path); return 0; } else { virReportSystemError(errno, _("Failed to resolve symlink at %s"), - fs->src); + fs->src->path); } return -1; } @@ -647,10 +647,10 @@ static int lxcContainerResolveSymlinks(virDomainFSDefPtr fs, bool gentle) /* Mark it resolved to skip it the next time */ fs->symlinksResolved = true; - VIR_DEBUG("Resolved '%s' to %s", fs->src, newroot); + VIR_DEBUG("Resolved '%s' to %s", fs->src->path, newroot); - VIR_FREE(fs->src); - fs->src = newroot; + VIR_FREE(fs->src->path); + fs->src->path = newroot; return 0; } @@ -698,8 +698,8 @@ static int lxcContainerPrepareRoot(virDomainDefPtr def, root->dst = tmp; root->type = VIR_DOMAIN_FS_TYPE_MOUNT; - VIR_FREE(root->src); - root->src = dst; + VIR_FREE(root->src->path); + root->src->path = dst; return 0; } @@ -711,7 +711,7 @@ static int lxcContainerPivotRoot(virDomainFSDefPtr root) ret = -1; - VIR_DEBUG("Pivot via %s", root->src); + VIR_DEBUG("Pivot via %s", root->src->path); /* root->parent must be private, so make / private. */ if (mount("", "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) { @@ -720,7 +720,7 @@ static int lxcContainerPivotRoot(virDomainFSDefPtr root) goto err; } - if (virAsprintf(&oldroot, "%s/.oldroot", root->src) < 0) + if (virAsprintf(&oldroot, "%s/.oldroot", root->src->path) < 0) goto err; if (virFileMakePath(oldroot) < 0) { @@ -751,18 +751,18 @@ static int lxcContainerPivotRoot(virDomainFSDefPtr root) } /* ... and mount our root onto it */ - if (mount(root->src, newroot, NULL, MS_BIND|MS_REC, NULL) < 0) { + if (mount(root->src->path, newroot, NULL, MS_BIND|MS_REC, NULL) < 0) { virReportSystemError(errno, _("Failed to bind %s to new root %s"), - root->src, newroot); + root->src->path, newroot); goto err; } if (root->readonly) { - if (mount(root->src, newroot, NULL, MS_BIND|MS_REC|MS_RDONLY|MS_REMOUNT, NULL) < 0) { + if (mount(root->src->path, newroot, NULL, MS_BIND|MS_REC|MS_RDONLY|MS_REMOUNT, NULL) < 0) { virReportSystemError(errno, _("Failed to make new root %s readonly"), - root->src); + root->src->path); goto err; } } @@ -1179,9 +1179,9 @@ static int lxcContainerMountFSBind(virDomainFSDefPtr fs, int ret = -1; struct stat st; - VIR_DEBUG("src=%s dst=%s", fs->src, fs->dst); + VIR_DEBUG("src=%s dst=%s", fs->src->path, fs->dst); - if (virAsprintf(&src, "%s%s", srcprefix, fs->src) < 0) + if (virAsprintf(&src, "%s%s", srcprefix, fs->src->path) < 0) goto cleanup; if (stat(fs->dst, &st) < 0) { @@ -1514,9 +1514,9 @@ static int lxcContainerMountFSBlock(virDomainFSDefPtr fs, char *src = NULL; int ret = -1; - VIR_DEBUG("src=%s dst=%s", fs->src, fs->dst); + VIR_DEBUG("src=%s dst=%s", fs->src->path, fs->dst); - if (virAsprintf(&src, "%s%s", srcprefix, fs->src) < 0) + if (virAsprintf(&src, "%s%s", srcprefix, fs->src->path) < 0) goto cleanup; ret = lxcContainerMountFSBlockHelper(fs, src, srcprefix, sec_mount_options); @@ -1622,14 +1622,14 @@ static int lxcContainerMountAllFS(virDomainDefPtr vmDef, if (STREQ(vmDef->fss[i]->dst, "/")) continue; - VIR_DEBUG("Mounting '%s' -> '%s'", vmDef->fss[i]->src, vmDef->fss[i]->dst); + VIR_DEBUG("Mounting '%s' -> '%s'", vmDef->fss[i]->src->path, vmDef->fss[i]->dst); if (lxcContainerResolveSymlinks(vmDef->fss[i], false) < 0) return -1; if (!(vmDef->fss[i]->src && - STRPREFIX(vmDef->fss[i]->src, vmDef->fss[i]->dst)) && + STRPREFIX(vmDef->fss[i]->src->path, vmDef->fss[i]->dst)) && lxcContainerUnmountSubtree(vmDef->fss[i]->dst, false) < 0) return -1; @@ -1777,7 +1777,7 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, /* FIXME: we should find a way to unmount these mounts for container * even user namespace is enabled. */ - if (STREQ(root->src, "/") && (!vmDef->idmap.nuidmap) && + if (STREQ(root->src->path, "/") && (!vmDef->idmap.nuidmap) && lxcContainerUnmountForSharedRoot(stateDir, vmDef->name) < 0) goto cleanup; diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index e58ff1b..f55aadc 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -424,18 +424,18 @@ static int virLXCControllerSetupLoopDeviceFS(virDomainFSDefPtr fs) int lofd; char *loname = NULL; - if ((lofd = virFileLoopDeviceAssociate(fs->src, &loname)) < 0) + if ((lofd = virFileLoopDeviceAssociate(fs->src->path, &loname)) < 0) return -1; VIR_DEBUG("Changing fs %s to use type=block for dev %s", - fs->src, loname); + fs->src->path, loname); /* * We now change it into a block device type, so that * the rest of container setup 'just works' */ fs->type = VIR_DOMAIN_FS_TYPE_BLOCK; - VIR_FREE(fs->src); - fs->src = loname; + VIR_FREE(fs->src->path); + fs->src->path = loname; loname = NULL; return lofd; @@ -485,21 +485,21 @@ static int virLXCControllerSetupNBDDeviceFS(virDomainFSDefPtr fs) return -1; } - if (virFileNBDDeviceAssociate(fs->src, + if (virFileNBDDeviceAssociate(fs->src->path, fs->format, fs->readonly, &dev) < 0) return -1; VIR_DEBUG("Changing fs %s to use type=block for dev %s", - fs->src, dev); + fs->src->path, dev); /* * We now change it into a block device type, so that * the rest of container setup 'just works' */ fs->type = VIR_DOMAIN_FS_TYPE_BLOCK; - VIR_FREE(fs->src); - fs->src = dev; + VIR_FREE(fs->src->path); + fs->src->path = dev; return 0; } @@ -635,7 +635,7 @@ static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) /* The NBD device will be cleaned up while the cgroup will end. * For this we need to remember the qemu-nbd pid and add it to * the cgroup*/ - if (virLXCControllerAppendNBDPids(ctrl, fs->src) < 0) + if (virLXCControllerAppendNBDPids(ctrl, fs->src->path) < 0) goto cleanup; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index acbc20b..ed92049 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -32,6 +32,7 @@ #include "util/virlog.h" #include "util/virstring.h" #include "util/virconf.h" +#include "conf/domain_conf.h" #define VIR_FROM_THIS VIR_FROM_LXC @@ -46,12 +47,12 @@ lxcCreateFSDef(int type, { virDomainFSDefPtr def; - if (VIR_ALLOC(def) < 0) + if (!(def = virDomainFSDefNew())) return NULL; def->type = type; def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; - if (src && VIR_STRDUP(def->src, src) < 0) + if (src && VIR_STRDUP(def->src->path, src) < 0) goto error; if (VIR_STRDUP(def->dst, dst) < 0) goto error; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 28313f0..6761394 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1153,12 +1153,12 @@ virLXCProcessEnsureRootFS(virDomainObjPtr vm) if (root) return 0; - if (VIR_ALLOC(root) < 0) + if (!(root = virDomainFSDefNew()) < 0) goto error; root->type = VIR_DOMAIN_FS_TYPE_MOUNT; - if (VIR_STRDUP(root->src, "/") < 0 || + if (VIR_STRDUP(root->src->path, "/") < 0 || VIR_STRDUP(root->dst, "/") < 0) goto error; diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index 50f4902..da67488 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -351,11 +351,11 @@ openvzReadFSConf(virDomainDefPtr def, veid); goto error; } else if (ret > 0) { - if (VIR_ALLOC(fs) < 0) + if (!(fs = virDomainFSDefNew()) < 0) goto error; fs->type = VIR_DOMAIN_FS_TYPE_TEMPLATE; - if (VIR_STRDUP(fs->src, temp) < 0) + if (VIR_STRDUP(fs->src->path, temp) < 0) goto error; } else { /* OSTEMPLATE was not found, VE was booted from a private dir directly */ @@ -374,7 +374,7 @@ openvzReadFSConf(virDomainDefPtr def, goto error; fs->type = VIR_DOMAIN_FS_TYPE_MOUNT; - if (!(fs->src = virStringReplace(temp, "$VEID", veid_str))) + if (!(fs->src->path = virStringReplace(temp, "$VEID", veid_str))) goto error; VIR_FREE(veid_str); diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 48c264b..2bb9db0 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -206,7 +206,7 @@ static int openvzSetInitialConfig(virDomainDefPtr vmdef) goto cleanup; } - if (openvzWriteVPSConfigParam(vpsid, "VE_PRIVATE", vmdef->fss[0]->src) < 0) { + if (openvzWriteVPSConfigParam(vpsid, "VE_PRIVATE", vmdef->fss[0]->src->path) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not set the source dir for the filesystem")); goto cleanup; @@ -2050,7 +2050,7 @@ openvzUpdateDevice(virDomainDefPtr vmdef, cur = vmdef->fss[pos]; /* We only allow updating the quota */ - if (STRNEQ(cur->src, fs->src) + if (STRNEQ(cur->src->path, fs->src->path) || cur->type != fs->type || cur->accessmode != fs->accessmode || cur->wrpolicy != fs->wrpolicy diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3898ed7..1c50c4c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2087,7 +2087,7 @@ qemuBuildFSStr(virDomainFSDefPtr fs, } virBufferAsprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias); - virBufferAsprintf(&opt, ",path=%s", fs->src); + virBufferAsprintf(&opt, ",path=%s", fs->src->path); if (fs->readonly) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_READONLY)) { diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 8e49268..0996a1e 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -1839,7 +1839,7 @@ vboxAttachSharedFolder(virDomainDefPtr def, vboxGlobalData *data, IMachine *mach continue; VBOX_UTF8_TO_UTF16(def->fss[i]->dst, &nameUtf16); - VBOX_UTF8_TO_UTF16(def->fss[i]->src, &hostPathUtf16); + VBOX_UTF8_TO_UTF16(def->fss[i]->src->path, &hostPathUtf16); writable = !def->fss[i]->readonly; gVBoxAPI.UIMachine.CreateSharedFolder(machine, nameUtf16, hostPathUtf16, @@ -3448,7 +3448,7 @@ vboxDumpSharedFolders(virDomainDefPtr def, vboxGlobalData *data, IMachine *machi gVBoxAPI.UISharedFolder.GetHostPath(sharedFolder, &hostPathUtf16); VBOX_UTF16_TO_UTF8(hostPathUtf16, &hostPath); - if (VIR_STRDUP(def->fss[i]->src, hostPath) < 0) { + if (VIR_STRDUP(def->fss[i]->src->path, hostPath) < 0) { VBOX_UTF8_FREE(hostPath); VBOX_UTF16_FREE(hostPathUtf16); goto sharedFoldersCleanup; @@ -4159,7 +4159,7 @@ static int vboxDomainAttachDeviceImpl(virDomainPtr dom, PRBool writable; VBOX_UTF8_TO_UTF16(dev->data.fs->dst, &nameUtf16); - VBOX_UTF8_TO_UTF16(dev->data.fs->src, &hostPathUtf16); + VBOX_UTF8_TO_UTF16(dev->data.fs->src->path, &hostPathUtf16); writable = !dev->data.fs->readonly; rc = gVBoxAPI.UIMachine.CreateSharedFolder(machine, nameUtf16, hostPathUtf16, diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index d443dd0..f910f4f 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -2422,7 +2422,7 @@ int virVMXParseFileSystem(virConfPtr conf, int number, virDomainFSDefPtr *def) return -1; } - if (VIR_ALLOC(*def) < 0) + if (!(*def = virDomainFSDefNew())) return -1; (*def)->type = VIR_DOMAIN_FS_TYPE_MOUNT; @@ -2450,7 +2450,7 @@ int virVMXParseFileSystem(virConfPtr conf, int number, virDomainFSDefPtr *def) if (virVMXGetConfigString(conf, hostPath_name, &hostPath, false) < 0) goto cleanup; - (*def)->src = hostPath; + (*def)->src->path = hostPath; hostPath = NULL; /* vmx:guestName */ @@ -3690,7 +3690,7 @@ virVMXFormatFileSystem(virDomainFSDefPtr def, int number, virBufferPtr buffer) virBufferAsprintf(buffer, "sharedFolder%d.writeAccess = \"%s\"\n", number, def->readonly ? "false" : "true"); virBufferAsprintf(buffer, "sharedFolder%d.hostPath = \"%s\"\n", number, - def->src); + def->src->path); virBufferAsprintf(buffer, "sharedFolder%d.guestName = \"%s\"\n", number, def->dst); diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index eff6114..b13b84d 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -658,7 +658,7 @@ prlsdkGetFSInfo(PRL_HANDLE prldisk, if (!(buf = prlsdkGetStringParamVar(PrlVmDev_GetImagePath, prldisk))) goto cleanup; - fs->src = buf; + fs->src->path = buf; buf = NULL; if (!(buf = prlsdkGetStringParamVar(PrlVmDevHd_GetMountPoint, prldisk))) @@ -699,7 +699,7 @@ prlsdkAddDomainHardDisksInfo(vzDriverPtr driver, PRL_HANDLE sdkdom, virDomainDef if (PDT_USE_REAL_DEVICE != emulatedType && IS_CT(def)) { - if (VIR_ALLOC(fs) < 0) + if (!(fs = virDomainFSDefNew())) goto error; if (prlsdkGetFSInfo(hdd, fs) < 0) @@ -3533,13 +3533,13 @@ prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs) pret = PrlVmDev_SetEmulatedType(sdkdisk, PDT_USE_IMAGE_FILE); prlsdkCheckRetGoto(pret, cleanup); - pret = PrlVmDev_SetSysName(sdkdisk, fs->src); + pret = PrlVmDev_SetSysName(sdkdisk, fs->src->path); prlsdkCheckRetGoto(pret, cleanup); - pret = PrlVmDev_SetImagePath(sdkdisk, fs->src); + pret = PrlVmDev_SetImagePath(sdkdisk, fs->src->path); prlsdkCheckRetGoto(pret, cleanup); - pret = PrlVmDev_SetFriendlyName(sdkdisk, fs->src); + pret = PrlVmDev_SetFriendlyName(sdkdisk, fs->src->path); prlsdkCheckRetGoto(pret, cleanup); pret = PrlVmDevHd_SetMountPoint(sdkdisk, fs->dst); @@ -3892,7 +3892,7 @@ prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def) prlsdkCheckRetGoto(pret, cleanup); if (useTemplate) { - pret = PrlVmCfg_SetOsTemplate(sdkdom, def->fss[0]->src); + pret = PrlVmCfg_SetOsTemplate(sdkdom, def->fss[0]->src->path); prlsdkCheckRetGoto(pret, cleanup); } -- 1.8.3.1

New type of <devices> <filesystem type= 'volume'> is introduced. This patch allows to use volumes for storing the filesystem, that is accessed from the guest e.g. root directory for container. To take advantage of volumes as a backend of filesystem volume and pool names should be specified: <filesystem type= 'volume'> <source pool='pool name' volume='volume name'/> Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com> --- src/conf/domain_conf.c | 18 +++++++++++++++--- src/conf/domain_conf.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0b33b3b..558a33e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -365,7 +365,8 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "file", "template", "ram", - "bind") + "bind", + "volume") VIR_ENUM_IMPL(virDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST, "default", @@ -8600,6 +8601,10 @@ virDomainFSDefParseXML(xmlNodePtr node, } else if (def->type == VIR_DOMAIN_FS_TYPE_RAM) { usage = virXMLPropString(cur, "usage"); units = virXMLPropString(cur, "units"); + } else if (def->type == VIR_DOMAIN_FS_TYPE_VOLUME) { + def->src->type = VIR_STORAGE_TYPE_VOLUME; + if (virDomainDiskSourcePoolDefParse(cur, &def->src->srcpool) < 0) + goto error; } } else if (!target && xmlStrEqual(cur->name, BAD_CAST "target")) { @@ -8644,8 +8649,8 @@ virDomainFSDefParseXML(xmlNodePtr node, def->wrpolicy = VIR_DOMAIN_FS_WRPOLICY_DEFAULT; } - if (source == NULL && - def->type != VIR_DOMAIN_FS_TYPE_RAM) { + if (source == NULL && def->type != VIR_DOMAIN_FS_TYPE_RAM + && def->type != VIR_DOMAIN_FS_TYPE_VOLUME) { virReportError(VIR_ERR_NO_SOURCE, target ? "%s" : NULL, target); goto error; @@ -20222,6 +20227,13 @@ virDomainFSDefFormat(virBufferPtr buf, virBufferAsprintf(buf, "<source usage='%lld' units='KiB'/>\n", def->usage / 1024); break; + + case VIR_DOMAIN_FS_TYPE_VOLUME: + virBufferAddLit(buf, "<source"); + virBufferEscapeString(buf, " pool='%s'", def->src->srcpool->pool); + virBufferEscapeString(buf, " volume='%s'", def->src->srcpool->volume); + virBufferAddLit(buf, "/>\n"); + break; } virBufferEscapeString(buf, "<target dir='%s'/>\n", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 281abba..a129320 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -759,6 +759,7 @@ typedef enum { VIR_DOMAIN_FS_TYPE_TEMPLATE, /* Expands a OS template to a guest dir */ VIR_DOMAIN_FS_TYPE_RAM, /* Mount a RAM filesystem on a guest dir */ VIR_DOMAIN_FS_TYPE_BIND, /* Binds a guest dir to another guest dir */ + VIR_DOMAIN_FS_TYPE_VOLUME, /* Mounts storage pool volume to a guest */ VIR_DOMAIN_FS_TYPE_LAST } virDomainFSType; -- 1.8.3.1

We do not need to check domainf fs type there, because it is done in prlsdkCheckUnsupportedParams. Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com> --- src/vz/vz_sdk.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index b13b84d..dd7eb6e 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -3859,26 +3859,9 @@ prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def) PRL_UINT32 flags; int ret = -1; int useTemplate = 0; - size_t i; - if (def->nfss > 1) { - /* Check all filesystems */ - for (i = 0; i < def->nfss; i++) { - if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_FILE) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Unsupported filesystem type.")); - return -1; - } - } - } else if (def->nfss == 1) { - if (def->fss[0]->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) { - useTemplate = 1; - } else if (def->fss[0]->type != VIR_DOMAIN_FS_TYPE_FILE) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Unsupported filesystem type.")); - return -1; - } - } + if (def->nfss == 1 && def->fss[0]->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) + useTemplate = 1; confParam.nVmType = PVT_CT; confParam.sConfigSample = "vswap.1024MB"; -- 1.8.3.1

Vz containers are able to use ploop volumes from storage pools to work upon. To use filesystem type volume, pool name and volume name should be specifaed in <source> : <filesystem type='volume' accessmode='passthrough'> <driver type='ploop' format='ploop'/> <source pool='guest_images' volume='TEST_POOL_CT'/> <target dir='/'/> </filesystem> The information about pool and volume is stored in ct dom configuration: <StorageURL>libvirt://localhost/pool_name/vol_name</StorageURL> and can be easily obtained via PrlVmDevHd_GetStorageURL sdk call. The only shorcoming: if storage pool is moved somewhere the ct should be redefined in order to refresh the information aboot path to root.hdd Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com> --- src/storage/storage_driver.c | 4 +- src/vz/vz_driver.c | 2 +- src/vz/vz_sdk.c | 126 +++++++++++++++++++++++++++++++++++++++---- src/vz/vz_sdk.h | 2 +- 4 files changed, 120 insertions(+), 14 deletions(-) diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index cb9d578..99e9df2 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -3508,7 +3508,9 @@ virStorageTranslateDiskSourcePool(virConnectPtr conn, case VIR_STORAGE_VOL_BLOCK: def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK; break; - + case VIR_STORAGE_VOL_PLOOP: + def->src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE; + break; case VIR_STORAGE_VOL_NETWORK: case VIR_STORAGE_VOL_NETDIR: virReportError(VIR_ERR_INTERNAL_ERROR, diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c index b17cea7..811a3c4 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -762,7 +762,7 @@ vzDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags) if (prlsdkCreateVm(driver, def)) goto cleanup; } else if (def->os.type == VIR_DOMAIN_OSTYPE_EXE) { - if (prlsdkCreateCt(driver, def)) + if (prlsdkCreateCt(conn, driver, def)) goto cleanup; } else { virReportError(VIR_ERR_INVALID_ARG, diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c index dd7eb6e..43832f0 100644 --- a/src/vz/vz_sdk.c +++ b/src/vz/vz_sdk.c @@ -33,6 +33,7 @@ #include "virtime.h" #include "virhostcpu.h" +#include "storage/storage_driver.h" #include "vz_sdk.h" #define VIR_FROM_THIS VIR_FROM_PARALLELS @@ -645,6 +646,9 @@ prlsdkGetFSInfo(PRL_HANDLE prldisk, { char *buf = NULL; int ret = -1; + char *storage = NULL; + char **matches = NULL; + virURIPtr uri = NULL; fs->type = VIR_DOMAIN_FS_TYPE_FILE; fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP; @@ -655,12 +659,50 @@ prlsdkGetFSInfo(PRL_HANDLE prldisk, fs->readonly = false; fs->symlinksResolved = false; - if (!(buf = prlsdkGetStringParamVar(PrlVmDev_GetImagePath, prldisk))) + if (!(storage = prlsdkGetStringParamVar(PrlVmDevHd_GetStorageURL, prldisk))) goto cleanup; - fs->src->path = buf; - buf = NULL; + if (!virStringIsEmpty(storage)) { + if (!(uri = virURIParse(storage))) + goto cleanup; + if (STRNEQ("libvirt", uri->scheme)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown backend for filesystem: '%s'"), + uri->scheme); + goto cleanup; + } + + if (!(matches = virStringSplitCount(uri->path, "/", 0, NULL)) || + !matches[0]) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("splitting StorageUrl failed %s"), uri->path); + goto cleanup; + } + if (!matches[1]) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("can't identify pool %s"), matches[1]); + goto cleanup; + } + if (!matches[2]) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("can't identify volume %s"), matches[2]); + goto cleanup; + } + fs->type = VIR_DOMAIN_FS_TYPE_VOLUME; + if (VIR_ALLOC(fs->src->srcpool) < 0) + goto cleanup; + if (VIR_STRDUP(fs->src->srcpool->pool, matches[1]) < 0) + goto cleanup; + if (VIR_STRDUP(fs->src->srcpool->volume, matches[2]) < 0) + goto cleanup; + } else { + + if (!(buf = prlsdkGetStringParamVar(PrlVmDev_GetImagePath, prldisk))) + goto cleanup; + fs->src->path = buf; + buf = NULL; + } if (!(buf = prlsdkGetStringParamVar(PrlVmDevHd_GetMountPoint, prldisk))) goto cleanup; @@ -671,6 +713,8 @@ prlsdkGetFSInfo(PRL_HANDLE prldisk, cleanup: VIR_FREE(buf); + VIR_FREE(storage); + virStringFreeList(matches); return ret; } @@ -1680,7 +1724,6 @@ prlsdkLoadDomain(vzDriverPtr driver, virDomainObjPtr dom) PRL_HANDLE job; virCheckNonNullArgGoto(dom, error); - pdom = dom->privateData; sdkdom = prlsdkSdkDomainLookupByUUID(driver, dom->def->uuid); if (sdkdom == PRL_INVALID_HANDLE) @@ -1721,7 +1764,6 @@ prlsdkLoadDomain(vzDriverPtr driver, virDomainObjPtr dom) /* depends on prlsdkAddVNCInfo */ if (prlsdkAddDomainHardware(driver, sdkdom, def) < 0) goto error; - /* depends on prlsdkAddDomainHardware */ if (prlsdkConvertBootOrder(sdkdom, def) < 0) goto error; @@ -2695,7 +2737,8 @@ static int prlsdkCheckNetUnsupportedParams(virDomainNetDefPtr net) static int prlsdkCheckFSUnsupportedParams(virDomainFSDefPtr fs) { - if (fs->type != VIR_DOMAIN_FS_TYPE_FILE) { + if (fs->type != VIR_DOMAIN_FS_TYPE_FILE && + fs->type != VIR_DOMAIN_FS_TYPE_VOLUME) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only file based filesystems are " "supported by vz driver.")); @@ -3508,12 +3551,14 @@ prlsdkUpdateDevice(vzDriverPtr driver, return 0; } + static int prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs) { PRL_RESULT pret; PRL_HANDLE sdkdisk = PRL_INVALID_HANDLE; int ret = -1; + char *storage = NULL; if (fs->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) return 0; @@ -3524,6 +3569,14 @@ prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs) pret = PrlVmCfg_CreateVmDev(sdkdom, PDE_HARD_DISK, &sdkdisk); prlsdkCheckRetGoto(pret, cleanup); + if (fs->type == VIR_DOMAIN_FS_TYPE_VOLUME) { + if (virAsprintf(&storage, "libvirt://localhost/%s/%s", fs->src->srcpool->pool, + fs->src->srcpool->volume) < 0) + goto cleanup; + pret = PrlVmDevHd_SetStorageURL(sdkdisk, storage); + prlsdkCheckRetGoto(pret, cleanup); + } + pret = PrlVmDev_SetEnabled(sdkdisk, 1); prlsdkCheckRetGoto(pret, cleanup); @@ -3548,6 +3601,7 @@ prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs) ret = 0; cleanup: + VIR_FREE(storage); PrlHandle_Free(sdkdisk); return ret; } @@ -3767,7 +3821,6 @@ prlsdkDoApplyConfig(vzDriverPtr driver, if (prlsdkSetBootOrderVm(sdkdom, def) < 0) goto error; } - return 0; error: @@ -3791,7 +3844,6 @@ prlsdkApplyConfig(vzDriverPtr driver, sdkdom = prlsdkSdkDomainLookupByUUID(driver, dom->def->uuid); if (sdkdom == PRL_INVALID_HANDLE) return -1; - job = PrlVm_BeginEdit(sdkdom); if (PRL_FAILED(waitJob(job))) return -1; @@ -3803,7 +3855,6 @@ prlsdkApplyConfig(vzDriverPtr driver, if (PRL_FAILED(waitJob(job))) ret = -1; } - PrlHandle_Free(sdkdom); return ret; @@ -3848,8 +3899,52 @@ prlsdkCreateVm(vzDriverPtr driver, virDomainDefPtr def) return ret; } +static int +virStorageTranslatePoolLocal(virConnectPtr conn, virStorageSourcePtr src) +{ + + virStoragePoolPtr pool = NULL; + virStorageVolPtr vol = NULL; + virStorageVolInfo info; + int ret = -1; + + if (!(pool = virStoragePoolLookupByName(conn, src->srcpool->pool))) + return -1; + if (virStoragePoolIsActive(pool) != 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("storage pool '%s' containing volume '%s' " + "is not active"), src->srcpool->pool, + src->srcpool->volume); + goto cleanup; + } + + if (!(vol = virStorageVolLookupByName(pool, src->srcpool->volume))) + goto cleanup; + + if (virStorageVolGetInfo(vol, &info) < 0) + goto cleanup; + + if (info.type != VIR_STORAGE_VOL_PLOOP) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unsupported volume format '%s'"), + virStorageVolTypeToString(info.type)); + goto cleanup; + } + + if (!(src->path = virStorageVolGetPath(vol))) + goto cleanup; + + ret = 0; + + cleanup: + virObjectUnref(pool); + virObjectUnref(vol); + return ret; +} + + int -prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def) +prlsdkCreateCt(virConnectPtr conn, vzDriverPtr driver, virDomainDefPtr def) { PRL_HANDLE sdkdom = PRL_INVALID_HANDLE; PRL_GET_VM_CONFIG_PARAM_DATA confParam; @@ -3859,9 +3954,18 @@ prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def) PRL_UINT32 flags; int ret = -1; int useTemplate = 0; + size_t i; - if (def->nfss == 1 && def->fss[0]->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) + if (def->nfss == 1 && def->fss[0]->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) { useTemplate = 1; + } else if (def->fss[0]->type != VIR_DOMAIN_FS_TYPE_FILE) { + for (i = 0; i < def->nfss; i++) { + if (def->fss[i]->type == VIR_DOMAIN_FS_TYPE_VOLUME) { + if (virStorageTranslatePoolLocal(conn, def->fss[i]->src) < 0) + goto cleanup; + } + } + } confParam.nVmType = PVT_CT; confParam.sConfigSample = "vswap.1024MB"; diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h index 41557a3..4767fdd 100644 --- a/src/vz/vz_sdk.h +++ b/src/vz/vz_sdk.h @@ -57,7 +57,7 @@ prlsdkApplyConfig(vzDriverPtr driver, virDomainObjPtr dom, virDomainDefPtr new); int prlsdkCreateVm(vzDriverPtr driver, virDomainDefPtr def); -int prlsdkCreateCt(vzDriverPtr driver, virDomainDefPtr def); +int prlsdkCreateCt(virConnectPtr conn, vzDriverPtr driver, virDomainDefPtr def); int prlsdkUnregisterDomain(vzDriverPtr driver, virDomainObjPtr dom, unsigned int flags); int -- 1.8.3.1
participants (1)
-
Olga Krishtal