[libvirt] [PATCH] implement managedsave in libvirt xen legacy driver
Jim Fehlig
jfehlig at suse.com
Fri Nov 30 19:34:12 UTC 2012
Bamvor Jian Zhang wrote:
> Implement the domainManagedSave, domainHasManagedSaveImage, and
> domainManagedSaveRemove functions in the libvirt legacy xen driver.
>
Cool, thanks for the patch!
In case others are interested, one motivation for adding this
functionality in the legacy xen driver is to avoid xen-only hacks in the
nova libvirt driver.
> domainHasManagedSaveImage check the managedsave image from filesystem
> everytime. This is different from qemu and libxl driver. In qemu or
> libxl driver, there is a hasManagesSave flags in virDomainObjPtr which
> is not used in xen legacy driver. This flag could not add into xen
> driver ptr either, because the driver ptr will be release at the end of
> every libvirt api calls. Meanwhile, AFAIK, xen store all the flags in
> xen not in libvirt xen driver. There is no need to add this flags in xen.
>
I think checking the filesystem is the only way to go since xend doesn't
have the notion of managedsave. Do others see any issues with this
approach?
> ---
> i have test the following case for this patch:
> 1), "virsh managedsave" save domain to /var/lib/xen/save/domain_name.save.
> call xenUnifiedDomainManagedSave.
> 2), "virsh start": if managedsave image is exist, it should be boot from
> managed save image.
> call xenUnifiedDomainHasManagedSaveImage.
> 3), "virsh start --force-boot": fresh boot, delete the managed save image
> if exists.
> call xenUnifiedDomainHasManagedSaveImage,
> xenUnifiedDomainManagedSaveRemove.
> 4), "virsh managedsave-remove": remove managed save image.
> call xenUnifiedDomainManagedSaveRemove
> 5), "virsh undefine": undefine the domain, it will fail if mananed save
> image exist.
> call xenUnifiedDomainHasManagedSaveImage.
> 6), "virsh undefine --managed-save": undefine the domain, and remove
> mananed save image.
> call xenUnifiedDomainHasManagedSaveImage and
> xenUnifiedDomainManagedSaveRemove.
> 7), "virsh list --all --with-managed-save". list domain if managed save
> image exist. got nothing if non-exists.
> call xenUnifiedDomainHasManagedSaveImage.
> 8), "virsh list --all --without-managed-save". do not list the domain if
> managed save image exist.
> call xenUnifiedDomainHasManagedSaveImage.
>
Thanks for including your test cases. I've tried these on your patch as
well and looks good!
> src/xen/xen_driver.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> src/xen/xen_driver.h | 2 +
> 2 files changed, 110 insertions(+), 1 deletion(-)
>
> diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
> index 5a40757..0b2418d 100644
> --- a/src/xen/xen_driver.c
> +++ b/src/xen/xen_driver.c
> @@ -67,6 +67,7 @@
> #include "nodeinfo.h"
>
> #define VIR_FROM_THIS VIR_FROM_XEN
> +#define XEN_SAVE_DIR LOCALSTATEDIR "/lib/libvirt/xen/save"
>
#include "configmake.h" is needed for LOCALSTATEDIR
>
> static int
> xenUnifiedNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info);
> @@ -267,6 +268,7 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags)
> {
> int i, ret = VIR_DRV_OPEN_DECLINED;
> xenUnifiedPrivatePtr priv;
> + char ebuf[1024];
>
> #ifdef __sun
> /*
> @@ -406,6 +408,17 @@ xenUnifiedOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags)
> }
> #endif
>
> + if (virAsprintf(&priv->saveDir, "%s", XEN_SAVE_DIR) == -1) {
> + virReportOOMError();
> + goto fail;
> + }
> +
> + if (virFileMakePath(priv->saveDir) < 0) {
> + VIR_ERROR(_("Failed to create save dir '%s': %s"), priv->saveDir,
> + virStrerror(errno, ebuf, sizeof(ebuf)));
> + goto fail;
> + }
> +
> return VIR_DRV_OPEN_SUCCESS;
>
> fail:
> @@ -437,6 +450,7 @@ xenUnifiedClose(virConnectPtr conn)
> if (priv->opened[i])
> drivers[i]->xenClose(conn);
>
> + VIR_FREE(priv->saveDir);
> virMutexDestroy(&priv->lock);
> VIR_FREE(conn->privateData);
>
> @@ -1080,6 +1094,79 @@ xenUnifiedDomainSave(virDomainPtr dom, const char *to)
> return xenUnifiedDomainSaveFlags(dom, to, NULL, 0);
> }
>
> +static char *
> +xenUnifiedDomainManagedSavePath(xenUnifiedPrivatePtr priv, virDomainPtr dom)
> +{
> + char *ret;
> +
> + if (virAsprintf(&ret, "%s/%s.save", priv->saveDir, dom->name) < 0) {
> + virReportOOMError();
> + return NULL;
> + }
> +
> + VIR_DEBUG("managed save image: %s", ret);
> + return ret;
> +}
> +
> +static int
> +xenUnifiedDomainManagedSave(virDomainPtr dom, unsigned int flags)
> +{
> + GET_PRIVATE(dom->conn);
> + char *name;
> + int ret = -1;
> +
> + virCheckFlags(0, -1);
> +
> + name = xenUnifiedDomainManagedSavePath(priv, dom);
> + if (!name)
> + goto cleanup;
> +
> + if (priv->opened[XEN_UNIFIED_XEND_OFFSET])
> + ret = xenDaemonDomainSave(dom, name);
> +
> +cleanup:
> + VIR_FREE(name);
> + return ret;
> +}
> +
> +static int
> +xenUnifiedDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
> +{
> + GET_PRIVATE(dom->conn);
> + char *name;
> + int ret = -1;
> +
> + virCheckFlags(0, -1);
> +
> + name = xenUnifiedDomainManagedSavePath(priv, dom);
> + if (!name)
> + return ret;
> +
> + ret = virFileExists(name);
> + VIR_FREE(name);
> + return ret;
> +}
> +
> +static int
> +xenUnifiedDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
> +{
> + GET_PRIVATE(dom->conn);
> + char *name;
> + int ret = -1;
> +
> + virCheckFlags(0, -1);
> +
> + name = xenUnifiedDomainManagedSavePath(priv, dom);
> + if (!name)
> + goto cleanup;
>
I think we can do away with the cleanup label and simply return ret here.
> +
> + ret = unlink(name);
> + VIR_FREE(name);
> +
> +cleanup:
> + return ret;
> +}
> +
> static int
> xenUnifiedDomainRestoreFlags(virConnectPtr conn, const char *from,
> const char *dxml, unsigned int flags)
> @@ -1504,16 +1591,33 @@ static int
> xenUnifiedDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
> {
> GET_PRIVATE(dom->conn);
> + char *name;
> int i;
> + int ret = -1;
>
> virCheckFlags(0, -1);
>
> + name = xenUnifiedDomainManagedSavePath(priv, dom);
> + if (!name)
> + goto cleanup;
> +
> + if (virFileExists(name)) {
> + if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
> + ret = xenDaemonDomainRestore(dom->conn, name);
> + if (ret == 0)
> + unlink(name);
> + }
> + VIR_FREE(name);
> + goto cleanup;
> + }
>
name is leaked here if virFileExists() fails. You can initialize name
to NULL and then unconditionally free it in cleanup.
> +
> for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
> if (priv->opened[i] && drivers[i]->xenDomainCreate &&
> drivers[i]->xenDomainCreate(dom) == 0)
> return 0;
>
> - return -1;
> +cleanup:
> + return ret;
> }
>
> static int
> @@ -2218,6 +2322,9 @@ static virDriver xenUnifiedDriver = {
> .domainGetState = xenUnifiedDomainGetState, /* 0.9.2 */
> .domainSave = xenUnifiedDomainSave, /* 0.0.3 */
> .domainSaveFlags = xenUnifiedDomainSaveFlags, /* 0.9.4 */
> + .domainManagedSave = xenUnifiedDomainManagedSave, /* 1.0.1 */
> + .domainHasManagedSaveImage = xenUnifiedDomainHasManagedSaveImage, /* 1.0.1 */
> + .domainManagedSaveRemove = xenUnifiedDomainManagedSaveRemove, /* 1.0.1 */
> .domainRestore = xenUnifiedDomainRestore, /* 0.0.3 */
> .domainRestoreFlags = xenUnifiedDomainRestoreFlags, /* 0.9.4 */
> .domainCoreDump = xenUnifiedDomainCoreDump, /* 0.1.9 */
> diff --git a/src/xen/xen_driver.h b/src/xen/xen_driver.h
> index b3fbcff..078980e 100644
> --- a/src/xen/xen_driver.h
> +++ b/src/xen/xen_driver.h
> @@ -200,6 +200,8 @@ struct _xenUnifiedPrivate {
> /* Location of config files, either /etc
> * or /var/lib/xen */
> const char *configDir;
> + /* Location of managed save dir, default /var/lib/libvirt/xen/save */
> + char *saveDir;
>
> # if WITH_XEN_INOTIFY
> /* The inotify fd */
>
With exception of the few nits, looks good! I would like to hear what
others think about checking existence of the managed save image on each
invocation of domainHasManagedSaveImage().
Thanks,
Jim
More information about the libvir-list
mailing list