[libvirt] [PATCH v2 0/5] parallels: manage container's filesystems

This patch series adds ability to manage container's filesystems: you can add or remove fs from existing container or create new one, based on existing disk image. Dmitry Guryanov (5): add ploop fs driver type parallels: dump info about container filesystems parallels: commit with PVCF_DETACH_HDD_BUNDLE flag parallels: allow to add filesystems to container parallels: create container from existing image docs/formatdomain.html.in | 3 +- docs/schemas/domaincommon.rng | 1 + docs/schemas/storagecommon.rng | 1 + src/conf/domain_conf.c | 3 +- src/conf/domain_conf.h | 1 + src/parallels/parallels_sdk.c | 209 +++++++++++++++++++-- src/qemu/qemu_command.c | 1 + .../domain-parallels-ct-simple.xml | 5 + 8 files changed, 206 insertions(+), 18 deletions(-) -- 2.1.0

Ploop is a pseudo device which makeit possible to access to an image in a file as a block device. Like loop devices, but with additional features, like snapshots, write tracker and without double-caching. It used in PCS for containers and in OpenVZ. You can manage ploop devices and images with ploop utility (http://git.openvz.org/?p=ploop). Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com> --- Changes in v2: * extend domaincommon.rng and storagecommon.rng * add documentation note about ploop fs driver format * add fs with new type to domain-parallels-ct-simple.xml to check it in unit test docs/formatdomain.html.in | 3 ++- docs/schemas/domaincommon.rng | 1 + docs/schemas/storagecommon.rng | 1 + src/conf/domain_conf.c | 3 ++- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 1 + tests/domainschemadata/domain-parallels-ct-simple.xml | 5 +++++ 7 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 8fcbd29..39d661b 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2607,7 +2607,8 @@ attribute provides the format type. For example, LXC supports a type of "loop", with a format of "raw" or "nbd" with any format. QEMU supports a type of "path" - or "handle", but no formats. + or "handle", but no formats. Parallels driver supports + a type of "ploop" with a format of "ploop". </li> </ul> </dd> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index cd35485..85cc3be 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2003,6 +2003,7 @@ <value>handle</value> <value>loop</value> <value>nbd</value> + <value>ploop</value> </choice> </attribute> </optional> diff --git a/docs/schemas/storagecommon.rng b/docs/schemas/storagecommon.rng index 629505f..5f71b10 100644 --- a/docs/schemas/storagecommon.rng +++ b/docs/schemas/storagecommon.rng @@ -75,6 +75,7 @@ <value>vdi</value> <value>fat</value> <value>vhd</value> + <value>ploop</value> <ref name='storageFormatBacking'/> </choice> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index aafc05e..b502b50 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -374,7 +374,8 @@ VIR_ENUM_IMPL(virDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST, "path", "handle", "loop", - "nbd") + "nbd", + "ploop") VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_ACCESSMODE_LAST, "passthrough", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 57297cd..44f00a0 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -791,6 +791,7 @@ typedef enum { VIR_DOMAIN_FS_DRIVER_TYPE_HANDLE, VIR_DOMAIN_FS_DRIVER_TYPE_LOOP, VIR_DOMAIN_FS_DRIVER_TYPE_NBD, + VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP, VIR_DOMAIN_FS_DRIVER_TYPE_LAST } virDomainFSDriverType; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d5679de..077962f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -151,6 +151,7 @@ VIR_ENUM_IMPL(qemuDomainFSDriver, VIR_DOMAIN_FS_DRIVER_TYPE_LAST, "local", "handle", NULL, + NULL, NULL); VIR_ENUM_DECL(qemuNumaPolicy) diff --git a/tests/domainschemadata/domain-parallels-ct-simple.xml b/tests/domainschemadata/domain-parallels-ct-simple.xml index a2b87ce..b79e963 100644 --- a/tests/domainschemadata/domain-parallels-ct-simple.xml +++ b/tests/domainschemadata/domain-parallels-ct-simple.xml @@ -18,6 +18,11 @@ <source name='centos-6-x86_64'/> <target dir='/'/> </filesystem> + <filesystem type='file' accessmode='passthrough'> + <driver type='ploop' format='ploop'/> + <source file='/path/to/ploop/dir'/> + <target dir='/mnt'/> + </filesystem> <video> <model type='vga' vram='16777216' heads='1'> <acceleration accel3d='no' accel2d='no'/> -- 2.1.0

Obtain information about container's filesystems and store it in virDomainDef structure. Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com> --- Changes in v2: * fix cleanup in prlsdkAddDomainHardDisksInfo src/parallels/parallels_sdk.c | 65 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 0b5430d..3c10be3 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -535,6 +535,55 @@ prlsdkGetDiskInfo(PRL_HANDLE prldisk, } static int +prlsdkGetFSInfo(PRL_HANDLE prldisk, + virDomainFSDefPtr fs) +{ + char *buf = NULL; + PRL_UINT32 buflen = 0; + PRL_RESULT pret; + int ret = -1; + + fs->type = VIR_DOMAIN_FS_TYPE_FILE; + fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP; + fs->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; + fs->wrpolicy = VIR_DOMAIN_FS_WRPOLICY_DEFAULT; + fs->format = VIR_STORAGE_FILE_PLOOP; + + fs->readonly = false; + fs->symlinksResolved = false; + + pret = PrlVmDev_GetImagePath(prldisk, NULL, &buflen); + prlsdkCheckRetGoto(pret, cleanup); + + if (VIR_ALLOC_N(buf, buflen) < 0) + goto cleanup; + + pret = PrlVmDev_GetImagePath(prldisk, buf, &buflen); + prlsdkCheckRetGoto(pret, cleanup); + + fs->src = buf; + buf = NULL; + + pret = PrlVmDevHd_GetMountPoint(prldisk, NULL, &buflen); + prlsdkCheckRetGoto(pret, cleanup); + + if (VIR_ALLOC_N(buf, buflen) < 0) + goto cleanup; + + pret = PrlVmDevHd_GetMountPoint(prldisk, buf, &buflen); + prlsdkCheckRetGoto(pret, cleanup); + + fs->dst = buf; + buf = NULL; + + ret = 0; + + cleanup: + VIR_FREE(buf); + return ret; +} + +static int prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) { PRL_RESULT pret; @@ -542,6 +591,7 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) PRL_UINT32 i; PRL_HANDLE hdd = PRL_INVALID_HANDLE; virDomainDiskDefPtr disk = NULL; + virDomainFSDefPtr fs = NULL; pret = PrlVmCfg_GetHardDisksCount(sdkdom, &hddCount); prlsdkCheckRetGoto(pret, error); @@ -551,9 +601,16 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) prlsdkCheckRetGoto(pret, error); if (IS_CT(def)) { - /* TODO: convert info about disks in container - * to virDomainFSDef structs */ - VIR_WARN("Skipping disk information for container"); + + if (VIR_ALLOC(fs) < 0) + goto error; + + if (prlsdkGetFSInfo(hdd, fs) < 0) + goto error; + + if (virDomainFSInsert(def, fs) < 0) + goto error; + fs = NULL; PrlHandle_Free(hdd); hdd = PRL_INVALID_HANDLE; @@ -569,6 +626,7 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0) goto error; + disk = NULL; } } @@ -577,6 +635,7 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) error: PrlHandle_Free(hdd); virDomainDiskDefFree(disk); + virDomainFSDefFree(fs); return -1; } -- 2.1.0

On 13.01.2015 12:27, Dmitry Guryanov wrote:
Obtain information about container's filesystems and store it in virDomainDef structure.
Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com> ---
Changes in v2: * fix cleanup in prlsdkAddDomainHardDisksInfo
src/parallels/parallels_sdk.c | 65 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-)
diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 0b5430d..3c10be3 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -535,6 +535,55 @@ prlsdkGetDiskInfo(PRL_HANDLE prldisk, }
static int +prlsdkGetFSInfo(PRL_HANDLE prldisk, + virDomainFSDefPtr fs) +{ + char *buf = NULL; + PRL_UINT32 buflen = 0; + PRL_RESULT pret; + int ret = -1; + + fs->type = VIR_DOMAIN_FS_TYPE_FILE; + fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP; + fs->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; + fs->wrpolicy = VIR_DOMAIN_FS_WRPOLICY_DEFAULT; + fs->format = VIR_STORAGE_FILE_PLOOP; + + fs->readonly = false; + fs->symlinksResolved = false; + + pret = PrlVmDev_GetImagePath(prldisk, NULL, &buflen); + prlsdkCheckRetGoto(pret, cleanup); + + if (VIR_ALLOC_N(buf, buflen) < 0) + goto cleanup; + + pret = PrlVmDev_GetImagePath(prldisk, buf, &buflen); + prlsdkCheckRetGoto(pret, cleanup); + + fs->src = buf; + buf = NULL; + + pret = PrlVmDevHd_GetMountPoint(prldisk, NULL, &buflen); + prlsdkCheckRetGoto(pret, cleanup); + + if (VIR_ALLOC_N(buf, buflen) < 0) + goto cleanup; + + pret = PrlVmDevHd_GetMountPoint(prldisk, buf, &buflen); + prlsdkCheckRetGoto(pret, cleanup); + + fs->dst = buf; + buf = NULL; + + ret = 0; + + cleanup: + VIR_FREE(buf); + return ret; +} + +static int prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) { PRL_RESULT pret; @@ -542,6 +591,7 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) PRL_UINT32 i; PRL_HANDLE hdd = PRL_INVALID_HANDLE; virDomainDiskDefPtr disk = NULL; + virDomainFSDefPtr fs = NULL;
pret = PrlVmCfg_GetHardDisksCount(sdkdom, &hddCount); prlsdkCheckRetGoto(pret, error); @@ -551,9 +601,16 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) prlsdkCheckRetGoto(pret, error);
if (IS_CT(def)) { - /* TODO: convert info about disks in container - * to virDomainFSDef structs */ - VIR_WARN("Skipping disk information for container"); + + if (VIR_ALLOC(fs) < 0) + goto error; + + if (prlsdkGetFSInfo(hdd, fs) < 0) + goto error; + + if (virDomainFSInsert(def, fs) < 0) + goto error; + fs = NULL;
Okay, but I'd reorder the else branch to match the pattern laid out by this branch. Something like this: diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index d9dd745..69d13cb 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -610,8 +610,8 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) if (virDomainFSInsert(def, fs) < 0) goto error; + fs = NULL; - PrlHandle_Free(hdd); hdd = PRL_INVALID_HANDLE; } else { @@ -621,12 +621,12 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) if (prlsdkGetDiskInfo(hdd, disk, false) < 0) goto error; - PrlHandle_Free(hdd); - hdd = PRL_INVALID_HANDLE; - if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0) goto error; + disk = NULL; + PrlHandle_Free(hdd); + hdd = PRL_INVALID_HANDLE; } }
PrlHandle_Free(hdd); hdd = PRL_INVALID_HANDLE; @@ -569,6 +626,7 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def)
if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0) goto error; + disk = NULL; } }
@@ -577,6 +635,7 @@ prlsdkAddDomainHardDisksInfo(PRL_HANDLE sdkdom, virDomainDefPtr def) error: PrlHandle_Free(hdd); virDomainDiskDefFree(disk); + virDomainFSDefFree(fs); return -1; }
Michal

PCS removes disk image from filesystem, if you remove it from config. There is a special flag PVCF_DETACH_HDD_BUNDLE which allow to remove disk only from VM/CT config. If you call virDomainDefine and remove some disk from config it should be preserved, so call PrlVm_CommitEx always with flag PVCF_DETACH_HDD_BUNDLE. Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com> --- src/parallels/parallels_sdk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 3c10be3..a74fef6 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -2730,7 +2730,7 @@ prlsdkApplyConfig(virConnectPtr conn, ret = prlsdkDoApplyConfig(sdkdom, new); if (ret == 0) { - job = PrlVm_Commit(sdkdom); + job = PrlVm_CommitEx(sdkdom, PVCF_DETACH_HDD_BUNDLE); if (PRL_FAILED(waitJob(job, privconn->jobTimeout))) ret = -1; } -- 2.1.0

Handle information about filesystems in domain config and add corresponding devices to container via parallels sdk. Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com> --- Changes in v2: * fix formatting src/parallels/parallels_sdk.c | 109 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index a74fef6..51e4bbe 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -1923,8 +1923,14 @@ prlsdkCheckUnsupportedParams(PRL_HANDLE sdkdom, virDomainDefPtr def) return -1; } - if (def->nfss != 0 || - def->nsounds != 0 || def->nhostdevs != 0 || + if (!IS_CT(def) && def->nfss != 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Filesystems in VMs are not supported " + "by parallels driver")); + return -1; + } + + if (def->nsounds != 0 || def->nhostdevs != 0 || def->nredirdevs != 0 || def->nsmartcards != 0 || def->nparallels || def->nchannels != 0 || def->nleases != 0 || def->nhubs != 0) { @@ -2343,6 +2349,60 @@ static int prlsdkCheckDiskUnsupportedParams(virDomainDiskDefPtr disk) return 0; } +static int prlsdkCheckFSUnsupportedParams(virDomainFSDefPtr fs) +{ + if (fs->type != VIR_DOMAIN_FS_TYPE_FILE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only file based filesystems are " + "supported by parallels driver.")); + return -1; + } + + if (fs->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_PLOOP) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only ploop fs driver is " + "supported by parallels driver.")); + return -1; + } + + if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Changing fs access mode is not " + "supported by parallels driver.")); + return -1; + } + + if (fs->wrpolicy != VIR_DOMAIN_FS_WRPOLICY_DEFAULT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Changing fs write policy is not " + "supported by parallels driver.")); + return -1; + } + + if (fs->format != VIR_STORAGE_FILE_PLOOP) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only ploop disk images are " + "supported by parallels driver.")); + return -1; + } + + if (fs->readonly) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting readonly for filesystems is " + "supported by parallels driver.")); + return -1; + } + + if (fs->space_hard_limit || fs->space_soft_limit) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Setting fs quotas is not " + "supported by parallels driver.")); + return -1; + } + + return 0; +} + static int prlsdkApplyGraphicsParams(PRL_HANDLE sdkdom, virDomainDefPtr def) { virDomainGraphicsDefPtr gr; @@ -2646,6 +2706,46 @@ static int prlsdkAddDisk(PRL_HANDLE sdkdom, virDomainDiskDefPtr disk) } static int +prlsdkAddFS(PRL_HANDLE sdkdom, virDomainFSDefPtr fs) +{ + PRL_RESULT pret; + PRL_HANDLE sdkdisk = PRL_INVALID_HANDLE; + int ret = -1; + + if (prlsdkCheckFSUnsupportedParams(fs) < 0) + return -1; + + pret = PrlVmCfg_CreateVmDev(sdkdom, PDE_HARD_DISK, &sdkdisk); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDev_SetEnabled(sdkdisk, 1); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDev_SetConnected(sdkdisk, 1); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDev_SetEmulatedType(sdkdisk, PDT_USE_IMAGE_FILE); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDev_SetSysName(sdkdisk, fs->src); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDev_SetImagePath(sdkdisk, fs->src); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDev_SetFriendlyName(sdkdisk, fs->src); + prlsdkCheckRetGoto(pret, cleanup); + + pret = PrlVmDevHd_SetMountPoint(sdkdisk, fs->dst); + prlsdkCheckRetGoto(pret, cleanup); + + ret = 0; + + cleanup: + PrlHandle_Free(sdkdisk); + return ret; +} +static int prlsdkDoApplyConfig(PRL_HANDLE sdkdom, virDomainDefPtr def) { @@ -2703,6 +2803,11 @@ prlsdkDoApplyConfig(PRL_HANDLE sdkdom, goto error; } + for (i = 0; i < def->nfss; i++) { + if (prlsdkAddFS(sdkdom, def->fss[i]) < 0) + goto error; + } + return 0; error: -- 2.1.0

It's possible to create a container with existing disk image as root filesystem. You need to remove existing disks from PCS VM config and then add a new one, pointing to your image. And then call PrlVm_RegEx with PRNVM_PRESERVE_DISK flag. With this patch you can create such container with something like this for new domain XML config: <filesystem type='file' accessmode='passthrough'> <driver type='ploop' format='ploop'/> <source file='/path-to-image'/> <target dir='/'/> </filesystem> Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com> --- Changes in v2: * use type size_t for 'i' src/parallels/parallels_sdk.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 51e4bbe..57c65d7 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -2892,14 +2892,26 @@ prlsdkCreateCt(virConnectPtr conn, virDomainDefPtr def) PRL_HANDLE result = PRL_INVALID_HANDLE; PRL_RESULT pret; int ret = -1; + int useTemplate = 0; + size_t i; - if (def->nfss && (def->nfss > 1 || - def->fss[0]->type != VIR_DOMAIN_FS_TYPE_TEMPLATE)) { - - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("There must be no more than 1 template FS for " - "container creation")); - return -1; + 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; + } } confParam.nVmType = PVT_CT; @@ -2913,22 +2925,23 @@ prlsdkCreateCt(virConnectPtr conn, virDomainDefPtr def) pret = PrlResult_GetParamByIndex(result, 0, &sdkdom); prlsdkCheckRetGoto(pret, cleanup); - if (def->nfss == 1) { + if (useTemplate) { pret = PrlVmCfg_SetOsTemplate(sdkdom, def->fss[0]->src); prlsdkCheckRetGoto(pret, cleanup); + } ret = prlsdkDoApplyConfig(sdkdom, def); if (ret) goto cleanup; - job = PrlVm_RegEx(sdkdom, "", PACF_NON_INTERACTIVE_MODE); + job = PrlVm_RegEx(sdkdom, "", PACF_NON_INTERACTIVE_MODE|PRNVM_PRESERVE_DISK); if (PRL_FAILED(waitJob(job, privconn->jobTimeout))) ret = -1; cleanup: PrlHandle_Free(sdkdom); - return -1; + return ret; } int -- 2.1.0

On 13.01.2015 12:27, Dmitry Guryanov wrote:
It's possible to create a container with existing disk image as root filesystem. You need to remove existing disks from PCS VM config and then add a new one, pointing to your image. And then call PrlVm_RegEx with PRNVM_PRESERVE_DISK flag.
With this patch you can create such container with something like this for new domain XML config:
<filesystem type='file' accessmode='passthrough'> <driver type='ploop' format='ploop'/> <source file='/path-to-image'/> <target dir='/'/> </filesystem>
Signed-off-by: Dmitry Guryanov <dguryanov@parallels.com> ---
Changes in v2: * use type size_t for 'i'
src/parallels/parallels_sdk.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index 51e4bbe..57c65d7 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -2892,14 +2892,26 @@ prlsdkCreateCt(virConnectPtr conn, virDomainDefPtr def) PRL_HANDLE result = PRL_INVALID_HANDLE; PRL_RESULT pret; int ret = -1; + int useTemplate = 0; + size_t i;
- if (def->nfss && (def->nfss > 1 || - def->fss[0]->type != VIR_DOMAIN_FS_TYPE_TEMPLATE)) { - - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("There must be no more than 1 template FS for " - "container creation")); - return -1; + 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; + } }
confParam.nVmType = PVT_CT; @@ -2913,22 +2925,23 @@ prlsdkCreateCt(virConnectPtr conn, virDomainDefPtr def) pret = PrlResult_GetParamByIndex(result, 0, &sdkdom); prlsdkCheckRetGoto(pret, cleanup);
- if (def->nfss == 1) { + if (useTemplate) { pret = PrlVmCfg_SetOsTemplate(sdkdom, def->fss[0]->src); prlsdkCheckRetGoto(pret, cleanup); + }
ret = prlsdkDoApplyConfig(sdkdom, def); if (ret) goto cleanup;
- job = PrlVm_RegEx(sdkdom, "", PACF_NON_INTERACTIVE_MODE); + job = PrlVm_RegEx(sdkdom, "", PACF_NON_INTERACTIVE_MODE|PRNVM_PRESERVE_DISK);
s/|/ | /
if (PRL_FAILED(waitJob(job, privconn->jobTimeout))) ret = -1;
cleanup: PrlHandle_Free(sdkdom); - return -1; + return ret; }
int
Michal

On 13.01.2015 12:27, Dmitry Guryanov wrote:
This patch series adds ability to manage container's filesystems: you can add or remove fs from existing container or create new one, based on existing disk image.
Dmitry Guryanov (5): add ploop fs driver type parallels: dump info about container filesystems parallels: commit with PVCF_DETACH_HDD_BUNDLE flag parallels: allow to add filesystems to container parallels: create container from existing image
docs/formatdomain.html.in | 3 +- docs/schemas/domaincommon.rng | 1 + docs/schemas/storagecommon.rng | 1 + src/conf/domain_conf.c | 3 +- src/conf/domain_conf.h | 1 + src/parallels/parallels_sdk.c | 209 +++++++++++++++++++-- src/qemu/qemu_command.c | 1 + .../domain-parallels-ct-simple.xml | 5 + 8 files changed, 206 insertions(+), 18 deletions(-)
Okay, I've fixed some small nits, ACKed and pushed. Michal

On 01/16/2015 04:13 PM, Michal Privoznik wrote:
On 13.01.2015 12:27, Dmitry Guryanov wrote:
This patch series adds ability to manage container's filesystems: you can add or remove fs from existing container or create new one, based on existing disk image.
Dmitry Guryanov (5): add ploop fs driver type parallels: dump info about container filesystems parallels: commit with PVCF_DETACH_HDD_BUNDLE flag parallels: allow to add filesystems to container parallels: create container from existing image
docs/formatdomain.html.in | 3 +- docs/schemas/domaincommon.rng | 1 + docs/schemas/storagecommon.rng | 1 + src/conf/domain_conf.c | 3 +- src/conf/domain_conf.h | 1 + src/parallels/parallels_sdk.c | 209 +++++++++++++++++++-- src/qemu/qemu_command.c | 1 + .../domain-parallels-ct-simple.xml | 5 + 8 files changed, 206 insertions(+), 18 deletions(-)
Okay, I've fixed some small nits, ACKed and pushed.
Michal
Thanks! -- Dmitry Guryanov
participants (2)
-
Dmitry Guryanov
-
Michal Privoznik