File snapshots.patch of Package libvirt

Index: libvirt-0.4.6/include/libvirt/libvirt.h.in
===================================================================
--- libvirt-0.4.6.orig/include/libvirt/libvirt.h.in
+++ libvirt-0.4.6/include/libvirt/libvirt.h.in
@@ -470,6 +470,21 @@ int                     virDomainRestore
                                                  const char *from);
 
 /*
+ * Snapshots
+ */
+int                     virDomainSnapshotCreate (virDomainPtr domain,
+                                                 const char* name);
+int                     virDomainSnapshotApply  (virDomainPtr domain,
+                                                 const char* name);
+int                     virDomainSnapshotDelete (virDomainPtr domain,
+                                                 const char* name);
+int                     virDomainNumOfSnapshots (virDomainPtr domain);
+int                     virDomainListSnapshots  (virDomainPtr domain,
+                                                 char **const names,
+                                                 int maxnames);
+
+
+/*
  * Domain core dump
  */
 int                     virDomainCoreDump       (virDomainPtr domain,
Index: libvirt-0.4.6/src/libvirt.c
===================================================================
--- libvirt-0.4.6.orig/src/libvirt.c
+++ libvirt-0.4.6/src/libvirt.c
@@ -1659,6 +1659,168 @@ virDomainRestore(virConnectPtr conn, con
     return -1;
 }
 
+
+/**
+ * virDomainSnapshotCreate:
+ * @domain: a domain object
+ * @name: name for the new snapshot
+ *
+ * Creates a snapshot from a running domain
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSnapshotCreate(virDomainPtr domain, const char* name)
+{
+    virConnectPtr conn;
+
+    DEBUG("domain=%p", domain);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        return (-1);
+    }
+
+    conn = domain->conn;
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        return (-1);
+    }
+
+    if (conn->driver->domainSnapshotCreate)
+        return conn->driver->domainSnapshotCreate(domain, name);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+/**
+ * virDomainSnapshotApply:
+ * @domain: a domain object
+ * @name: name of the snapshot to apply
+ *
+ * Starts a domain using a given snapshot. The domain needs to be shut down
+ * before calling thsi function.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSnapshotApply(virDomainPtr domain, const char* name)
+{
+    virConnectPtr conn;
+
+    DEBUG("domain=%p", domain);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        return (-1);
+    }
+
+    conn = domain->conn;
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        return (-1);
+    }
+
+    if (conn->driver->domainSnapshotApply)
+        return conn->driver->domainSnapshotApply(domain, name);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+/**
+ * virDomainSnapshotDelete:
+ * @domain: a domain object
+ * @name: name of the snapshot to delete
+ *
+ * Deletes a snapshot from the given domain
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSnapshotDelete(virDomainPtr domain, const char* name)
+{
+    virConnectPtr conn;
+
+    DEBUG("domain=%p", domain);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        return (-1);
+    }
+
+    conn = domain->conn;
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        return (-1);
+    }
+
+    if (conn->driver->domainSnapshotDelete)
+        return conn->driver->domainSnapshotDelete(domain, name);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+/**
+ * virDomainNumOfSnapshots:
+ * @domain: a domain object
+ *
+ * Returns the number of snapshots of the given domain or -1 in case of failure
+ */
+int
+virDomainNumOfSnapshots(virDomainPtr domain)
+{
+    virConnectPtr conn;
+
+    DEBUG("domain=%p", domain);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        return (-1);
+    }
+
+    conn = domain->conn;
+    if (conn->driver->domainNumOfSnapshots)
+        return conn->driver->domainNumOfSnapshots(domain);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+/**
+ * virDomainListSnapshots:
+ * @domain: a domain object
+ * @names: pointer to an array to store the snapshot names
+ * @maxnames: size of the array
+ *
+ * List the names of all snapshots of the given domain. The names are
+ * stored in the @names array. Unused array entries are set to NULL.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainListSnapshots(virDomainPtr domain, char **const names, int maxnames)
+{
+    virConnectPtr conn;
+
+    DEBUG("domain=%p", domain);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        return (-1);
+    }
+
+    conn = domain->conn;
+    if (conn->driver->domainListSnapshots)
+        return conn->driver->domainListSnapshots(domain, names, maxnames);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
+}
+
+
 /**
  * virDomainCoreDump:
  * @domain: a domain object
Index: libvirt-0.4.6/src/driver.h
===================================================================
--- libvirt-0.4.6.orig/src/driver.h
+++ libvirt-0.4.6/src/driver.h
@@ -146,6 +146,21 @@ typedef int
         (*virDrvDomainRestore)		(virConnectPtr conn,
                                          const char *from);
 typedef int
+        (*virDrvDomainSnapshotCreate)   (virDomainPtr domain,
+                                        const char* name);
+typedef int
+        (*virDrvDomainSnapshotApply)    (virDomainPtr domain,
+                                        const char* name);
+typedef int
+        (*virDrvDomainSnapshotDelete)   (virDomainPtr domain,
+                                        const char* name);
+typedef int
+        (*virDrvDomainNumOfSnapshots)   (virDomainPtr domain);
+typedef int
+        (*virDrvDomainListSnapshots)    (virDomainPtr domain,
+                                        char **const names,
+                                        int maxnames);
+typedef int
         (*virDrvDomainCoreDump)		(virDomainPtr domain,
                                          const char *to,
                                          int flags);
@@ -352,6 +367,12 @@ struct _virDriver {
     virDrvDomainMemoryPeek      domainMemoryPeek;
     virDrvNodeGetCellsFreeMemory	nodeGetCellsFreeMemory;
     virDrvNodeGetFreeMemory		getFreeMemory;
+
+    virDrvDomainSnapshotCreate  domainSnapshotCreate;
+    virDrvDomainSnapshotApply  domainSnapshotApply;
+    virDrvDomainSnapshotDelete  domainSnapshotDelete;
+    virDrvDomainNumOfSnapshots  domainNumOfSnapshots;
+    virDrvDomainListSnapshots  domainListSnapshots;
 };
 
 typedef int
Index: libvirt-0.4.6/src/xen_unified.c
===================================================================
--- libvirt-0.4.6.orig/src/xen_unified.c
+++ libvirt-0.4.6/src/xen_unified.c
@@ -869,6 +869,81 @@ xenUnifiedDomainRestore (virConnectPtr c
 }
 
 static int
+xenUnifiedDomainSnapshotCreate(virDomainPtr domain, const char* name)
+{
+    GET_PRIVATE(domain->conn);
+    int i;
+
+    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
+        if (priv->opened[i] &&
+            drivers[i]->domainSnapshotCreate &&
+            drivers[i]->domainSnapshotCreate(domain, name) == 0)
+            return 0;
+
+    return -1;
+}
+
+static int
+xenUnifiedDomainSnapshotApply(virDomainPtr domain, const char* name)
+{
+    GET_PRIVATE(domain->conn);
+    int i;
+
+    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
+        if (priv->opened[i] &&
+            drivers[i]->domainSnapshotApply &&
+            drivers[i]->domainSnapshotApply(domain, name) == 0)
+            return 0;
+
+    return -1;
+}
+
+static int
+xenUnifiedDomainSnapshotDelete(virDomainPtr domain, const char* name)
+{
+    GET_PRIVATE(domain->conn);
+    int i;
+
+    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
+        if (priv->opened[i] &&
+            drivers[i]->domainSnapshotDelete &&
+            drivers[i]->domainSnapshotDelete(domain, name) == 0)
+            return 0;
+
+    return -1;
+}
+
+static int
+xenUnifiedDomainNumOfSnapshots(virDomainPtr domain)
+{
+    GET_PRIVATE(domain->conn);
+    int i;
+
+    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
+        if (priv->opened[i] &&
+            drivers[i]->domainNumOfSnapshots)
+            return drivers[i]->domainNumOfSnapshots(domain);
+
+    return -1;
+}
+
+static int
+xenUnifiedDomainListSnapshots(virDomainPtr domain, char **const names,
+    int maxnames)
+{
+    GET_PRIVATE(domain->conn);
+    int i;
+
+    for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i)
+        if (priv->opened[i] &&
+            drivers[i]->domainListSnapshots &&
+            drivers[i]->domainListSnapshots(domain, names, maxnames) == 0)
+            return 0;
+
+    return -1;
+}
+
+static int
 xenUnifiedDomainCoreDump (virDomainPtr dom, const char *to, int flags)
 {
     GET_PRIVATE(dom->conn);
@@ -1336,6 +1411,11 @@ static virDriver xenUnifiedDriver = {
     .domainGetInfo 		= xenUnifiedDomainGetInfo,
     .domainSave 			= xenUnifiedDomainSave,
     .domainRestore 		= xenUnifiedDomainRestore,
+    .domainSnapshotCreate = xenUnifiedDomainSnapshotCreate,
+    .domainSnapshotApply = xenUnifiedDomainSnapshotApply,
+    .domainSnapshotDelete = xenUnifiedDomainSnapshotDelete,
+    .domainNumOfSnapshots = xenUnifiedDomainNumOfSnapshots,
+    .domainListSnapshots = xenUnifiedDomainListSnapshots,
     .domainCoreDump 		= xenUnifiedDomainCoreDump,
     .domainSetVcpus 		= xenUnifiedDomainSetVcpus,
     .domainPinVcpu 		= xenUnifiedDomainPinVcpu,
Index: libvirt-0.4.6/src/xen_unified.h
===================================================================
--- libvirt-0.4.6.orig/src/xen_unified.h
+++ libvirt-0.4.6/src/xen_unified.h
@@ -63,6 +63,11 @@ struct xenUnifiedDriver {
         virDrvDomainGetInfo		domainGetInfo;
         virDrvDomainSave		domainSave;
         virDrvDomainRestore		domainRestore;
+        virDrvDomainSnapshotCreate   domainSnapshotCreate;
+        virDrvDomainSnapshotApply    domainSnapshotApply;
+        virDrvDomainSnapshotDelete   domainSnapshotDelete;
+        virDrvDomainNumOfSnapshots   domainNumOfSnapshots;
+        virDrvDomainListSnapshots    domainListSnapshots;
         virDrvDomainCoreDump		domainCoreDump;
         virDrvDomainSetVcpus		domainSetVcpus;
         virDrvDomainPinVcpu		domainPinVcpu;
Index: libvirt-0.4.6/src/xend_internal.c
===================================================================
--- libvirt-0.4.6.orig/src/xend_internal.c
+++ libvirt-0.4.6/src/xend_internal.c
@@ -51,6 +51,12 @@
 
 #ifndef PROXY
 
+static int xenDaemonDomainSnapshotCreate(virDomainPtr domain, const char* name);
+static int xenDaemonDomainSnapshotApply(virDomainPtr domain, const char* name);
+static int xenDaemonDomainSnapshotDelete(virDomainPtr domain, const char* name);
+static int xenDaemonDomainNumOfSnapshots(virDomainPtr domain);
+static int xenDaemonDomainListSnapshots(virDomainPtr domain, char **const names, int maxnames);
+
 /*
  * The number of Xen scheduler parameters
  */
@@ -3070,6 +3076,87 @@ xenDaemonDomainRestore(virConnectPtr con
     }
     return xend_op(conn, "", "op", "restore", "file", filename, NULL);
 }
+
+static int
+xenDaemonDomainSnapshotCreate(virDomainPtr domain, const char* name)
+{
+    if ((domain == NULL) || (name == NULL)) {
+        virXendError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+    return xend_op(domain->conn, domain->name, "op",
+        "snapshot_create", "name", name, NULL);
+}
+
+static int
+xenDaemonDomainSnapshotApply(virDomainPtr domain, const char* name)
+{
+    if ((domain == NULL) || (name == NULL)) {
+        virXendError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+    return xend_op(domain->conn, domain->name, "op",
+        "snapshot_apply", "name", name, NULL);
+}
+
+static int
+xenDaemonDomainSnapshotDelete(virDomainPtr domain, const char* name)
+{
+    if ((domain == NULL) || (name == NULL)) {
+        virXendError(domain->conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return (-1);
+    }
+    return xend_op(domain->conn, domain->name, "op",
+        "snapshot_delete", "name", name, NULL);
+}
+
+static int
+xenDaemonDomainNumOfSnapshots(virDomainPtr domain)
+{
+    struct sexpr *root, *node, *value;
+    int i;
+
+    root = sexpr_get(domain->conn,
+        "/xend/domain/%s?op=snapshot_list", domain->name);
+    if (root == NULL)
+        return -1;
+
+    for (node = root, i = 0; node->kind == SEXPR_CONS; node = node->u.s.cdr) {
+        value = node->u.s.car;
+
+        if (value->kind == SEXPR_VALUE)
+            i++;
+    }
+
+    return i;
+}
+
+static int
+xenDaemonDomainListSnapshots(virDomainPtr domain, char **const names,
+    int maxnames)
+{
+    struct sexpr *root, *node, *value;
+    int i;
+    root = sexpr_get(domain->conn,
+        "/xend/domain/%s?op=snapshot_list", domain->name);
+    if (root == NULL)
+        return -1;
+
+    for (node = root, i = 0; node->kind == SEXPR_CONS; node = node->u.s.cdr) {
+        value = node->u.s.car;
+
+        if (value->kind == SEXPR_VALUE) {
+            names[i] = strdup(value->u.value);
+            if (++i > maxnames)
+                return 0;
+        }
+    }
+
+    for (; i < maxnames; i++)
+        names[i] = NULL;
+
+    return 0;
+}
 #endif /* !PROXY */
 
 /**
@@ -4824,6 +4911,11 @@ struct xenUnifiedDriver xenDaemonDriver 
     xenDaemonDomainGetInfo,      /* domainGetInfo */
     xenDaemonDomainSave,         /* domainSave */
     xenDaemonDomainRestore,      /* domainRestore */
+    xenDaemonDomainSnapshotCreate, /* domainSnapshotCreate */
+    xenDaemonDomainSnapshotApply, /* domainSnapshotApply */
+    xenDaemonDomainSnapshotDelete, /* domainSnapshotDelete */
+    xenDaemonDomainNumOfSnapshots, /* domainNumOfSnapshots */
+    xenDaemonDomainListSnapshots, /* domainListSnapshots */
     xenDaemonDomainCoreDump,     /* domainCoreDump */
     xenDaemonDomainSetVcpus,     /* domainSetVcpus */
     xenDaemonDomainPinVcpu,      /* domainPinVcpu */
Index: libvirt-0.4.6/src/proxy_internal.c
===================================================================
--- libvirt-0.4.6.orig/src/proxy_internal.c
+++ libvirt-0.4.6/src/proxy_internal.c
@@ -66,6 +66,11 @@ struct xenUnifiedDriver xenProxyDriver =
     xenProxyDomainGetInfo, /* domainGetInfo */
     NULL, /* domainSave */
     NULL, /* domainRestore */
+    NULL, /* domainSnapshotCreate */
+    NULL, /* domainSnapshotApply */
+    NULL, /* domainSnapshotDelete */
+    NULL, /* domainNumOfSnapshots */
+    NULL, /* domainListSnapshots */
     NULL, /* domainCoreDump */
     NULL, /* domainSetVcpus */
     NULL, /* domainPinVcpu */
Index: libvirt-0.4.6/src/xen_internal.c
===================================================================
--- libvirt-0.4.6.orig/src/xen_internal.c
+++ libvirt-0.4.6/src/xen_internal.c
@@ -700,6 +700,11 @@ struct xenUnifiedDriver xenHypervisorDri
     xenHypervisorGetDomainInfo, /* domainGetInfo */
     NULL, /* domainSave */
     NULL, /* domainRestore */
+    NULL, /* domainSnapshotCreate */
+    NULL, /* domainSnapshotApply */
+    NULL, /* domainSnapshotDelete */
+    NULL, /* domainNumOfSnapshots */
+    NULL, /* domainListSnapshots */
     NULL, /* domainCoreDump */
     xenHypervisorSetVcpus, /* domainSetVcpus */
     xenHypervisorPinVcpu, /* domainPinVcpu */
Index: libvirt-0.4.6/src/xm_internal.c
===================================================================
--- libvirt-0.4.6.orig/src/xm_internal.c
+++ libvirt-0.4.6/src/xm_internal.c
@@ -105,6 +105,11 @@ struct xenUnifiedDriver xenXMDriver = {
     xenXMDomainGetInfo, /* domainGetInfo */
     NULL, /* domainSave */
     NULL, /* domainRestore */
+    NULL, /* domainSnapshotCreate */
+    NULL, /* domainSnapshotApply */
+    NULL, /* domainSnapshotDelete */
+    NULL, /* domainNumOfSnapshots */
+    NULL, /* domainListSnapshots */
     NULL, /* domainCoreDump */
     xenXMDomainSetVcpus, /* domainSetVcpus */
     xenXMDomainPinVcpu, /* domainPinVcpu */
Index: libvirt-0.4.6/src/xs_internal.c
===================================================================
--- libvirt-0.4.6.orig/src/xs_internal.c
+++ libvirt-0.4.6/src/xs_internal.c
@@ -66,6 +66,11 @@ struct xenUnifiedDriver xenStoreDriver =
     xenStoreGetDomainInfo, /* domainGetInfo */
     NULL, /* domainSave */
     NULL, /* domainRestore */
+    NULL, /* domainSnapshotCreate */
+    NULL, /* domainSnapshotApply */
+    NULL, /* domainSnapshotDelete */
+    NULL, /* domainNumOfSnapshots */
+    NULL, /* domainListSnapshots */
     NULL, /* domainCoreDump */
     NULL, /* domainSetVcpus */
     NULL, /* domainPinVcpu */
Index: libvirt-0.4.6/src/virsh.c
===================================================================
--- libvirt-0.4.6.orig/src/virsh.c
+++ libvirt-0.4.6/src/virsh.c
@@ -1100,6 +1100,189 @@ cmdSave(vshControl *ctl, const vshCmd *c
     return ret;
 }
 
+
+/*
+ * "snapshot-create" command
+ */
+static vshCmdInfo info_snapshot_create[] = {
+    {"syntax", "snapshot-create <domain> <name>"},
+    {"help", gettext_noop("Create a snapshot of the domain")},
+    {"desc", gettext_noop("Create a snapshot of the domain")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_snapshot_create[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("Domain name, id or uuid")},
+    {"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("Name of the snapshot")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotCreate(vshControl * ctl, vshCmd * cmd)
+{
+    virDomainPtr dom;
+    char *name;
+    char *domain;
+    int ret = TRUE;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(name = vshCommandOptString(cmd, "name", NULL)))
+        return FALSE;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", &domain)))
+        return FALSE;
+
+    if (virDomainSnapshotCreate(dom, name) == 0) {
+        vshPrint(ctl, _("Snapshot %s created for domain %s\n"), name, domain);
+    } else {
+        vshError(ctl, FALSE, _("Failed to create snapshot %s for domain %s"),
+            name, domain);
+        ret = FALSE;
+    }
+
+    virDomainFree(dom);
+    return ret;
+}
+
+/*
+ * "snapshot-apply" command
+ */
+static vshCmdInfo info_snapshot_apply[] = {
+    {"syntax", "snapshot-apply <domain> <name>"},
+    {"help", gettext_noop("Start the domain using a snapshot")},
+    {"desc", gettext_noop("Start the domain using a snapshot")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_snapshot_apply[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("Domain name, id or uuid")},
+    {"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("Name of the snapshot")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotApply(vshControl * ctl, vshCmd * cmd)
+{
+    virDomainPtr dom;
+    char *name;
+    char *domain;
+    int ret = TRUE;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(name = vshCommandOptString(cmd, "name", NULL)))
+        return FALSE;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", &domain)))
+        return FALSE;
+
+    if (virDomainSnapshotApply(dom, name) == 0) {
+        vshPrint(ctl, _("Domain %s started using snapshot %s\n"),
+            domain, name);
+    } else {
+        vshError(ctl, FALSE, _("Failed to start domain %s using snapshot %s"),
+            domain, name);
+        ret = FALSE;
+    }
+
+    virDomainFree(dom);
+    return ret;
+}
+
+/*
+ * "snapshot-delete" command
+ */
+static vshCmdInfo info_snapshot_delete[] = {
+    {"syntax", "snapshot-delete <domain> <name>"},
+    {"help", gettext_noop("Delete a snapshot from a domain")},
+    {"desc", gettext_noop("Delete a snapshot from a domain")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_snapshot_delete[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("Domain name, id or uuid")},
+    {"name", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("Name of the snapshot")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotDelete(vshControl * ctl, vshCmd * cmd)
+{
+    virDomainPtr dom;
+    char *name;
+    char *domain;
+    int ret = TRUE;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(name = vshCommandOptString(cmd, "name", NULL)))
+        return FALSE;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", &domain)))
+        return FALSE;
+
+    if (virDomainSnapshotDelete(dom, name) == 0) {
+        vshPrint(ctl, _("Snapshot %s deleted from domain %s\n"), name, domain);
+    } else {
+        vshError(ctl, FALSE, _("Failed to delete snapshot %s from domain %s"),
+            name, domain);
+        ret = FALSE;
+    }
+
+    virDomainFree(dom);
+    return ret;
+}
+
+/*
+ * "snapshot-list" command
+ */
+static vshCmdInfo info_snapshot_list[] = {
+    {"syntax", "snapshot-list <domain>"},
+    {"help", gettext_noop("List all snapshots of a domain")},
+    {"desc", gettext_noop("List all snapshots of a domain")},
+    {NULL, NULL}
+};
+
+static vshCmdOptDef opts_snapshot_list[] = {
+    {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("Domain name, id or uuid")},
+    {NULL, 0, 0, NULL}
+};
+
+static int
+cmdSnapshotList(vshControl * ctl, vshCmd * cmd)
+{
+    virDomainPtr dom;
+    char *domain;
+    char** names;
+    int num;
+    int i;
+    int ret = TRUE;
+
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", &domain)))
+        return FALSE;
+
+    // TODO Display snapshot details
+    num = virDomainNumOfSnapshots(dom);
+    names = malloc(num * sizeof(*names));
+    virDomainListSnapshots(dom, names, num);
+
+    for (i = 0; i < num; i++) {
+        printf("%s\n", names[i]);
+        free(names[i]);
+    }
+
+    free(names);
+    virDomainFree(dom);
+    return ret;
+}
+
 /*
  * "schedinfo" command
  */
@@ -5568,6 +5751,12 @@ static const vshCmdDef commands[] = {
     {"undefine", cmdUndefine, opts_undefine, info_undefine},
     {"uri", cmdURI, NULL, info_uri},
 
+    {"snapshot-create", cmdSnapshotCreate, opts_snapshot_create, info_snapshot_create},
+    {"snapshot-apply", cmdSnapshotApply, opts_snapshot_apply, info_snapshot_apply},
+    {"snapshot-delete", cmdSnapshotDelete, opts_snapshot_delete, info_snapshot_delete},
+    {"snapshot-list", cmdSnapshotList, opts_snapshot_list, info_snapshot_list},
+
+
     {"vol-create", cmdVolCreate, opts_vol_create, info_vol_create},
     {"vol-create-as", cmdVolCreateAs, opts_vol_create_as, info_vol_create_as},
     {"vol-delete", cmdVolDelete, opts_vol_delete, info_vol_delete},
Index: libvirt-0.4.6/src/lxc_driver.c
===================================================================
--- libvirt-0.4.6.orig/src/lxc_driver.c
+++ libvirt-0.4.6/src/lxc_driver.c
@@ -1203,6 +1203,11 @@ static virDriver lxcDriver = {
     NULL, /* domainMemoryPeek */
     NULL, /* nodeGetCellsFreeMemory */
     NULL, /* getFreeMemory */
+    NULL, /* domainSnapshotCreate */
+    NULL, /* domainSnapshotApply */
+    NULL, /* domainSnapshotDelete */
+    NULL, /* domainNumOfSnapshots */
+    NULL, /* domainListSnapshots */
 };
 
 
Index: libvirt-0.4.6/src/openvz_driver.c
===================================================================
--- libvirt-0.4.6.orig/src/openvz_driver.c
+++ libvirt-0.4.6/src/openvz_driver.c
@@ -1014,6 +1014,11 @@ static virDriver openvzDriver = {
     NULL, /* domainMemoryPeek */
     NULL, /* nodeGetCellsFreeMemory */
     NULL, /* nodeGetFreeMemory */
+    NULL, /* domainSnapshotCreate */
+    NULL, /* domainSnapshotApply */
+    NULL, /* domainSnapshotDelete */
+    NULL, /* domainNumOfSnapshots */
+    NULL, /* domainListSnapshots */
 };
 
 int openvzRegister(void) {
Index: libvirt-0.4.6/src/qemu_driver.c
===================================================================
--- libvirt-0.4.6.orig/src/qemu_driver.c
+++ libvirt-0.4.6/src/qemu_driver.c
@@ -4079,6 +4079,11 @@ static virDriver qemuDriver = {
     NULL, /* nodeGetCellsFreeMemory */
     NULL, /* getFreeMemory */
 #endif
+    NULL, /* domainSnapshotCreate */
+    NULL, /* domainSnapshotApply */
+    NULL, /* domainSnapshotDelete */
+    NULL, /* domainNumOfSnapshots */
+    NULL, /* domainListSnapshots */
 };
 
 static virNetworkDriver qemuNetworkDriver = {
Index: libvirt-0.4.6/src/remote_internal.c
===================================================================
--- libvirt-0.4.6.orig/src/remote_internal.c
+++ libvirt-0.4.6/src/remote_internal.c
@@ -4888,6 +4888,11 @@ static virDriver driver = {
     .domainMemoryPeek = remoteDomainMemoryPeek,
     .nodeGetCellsFreeMemory = remoteNodeGetCellsFreeMemory,
     .getFreeMemory = remoteNodeGetFreeMemory,
+    .domainSnapshotCreate = NULL,
+    .domainSnapshotApply = NULL,
+    .domainSnapshotDelete = NULL,
+    .domainNumOfSnapshots = NULL,
+    .domainListSnapshots = NULL,
 };
 
 static virNetworkDriver network_driver = {
Index: libvirt-0.4.6/src/test.c
===================================================================
--- libvirt-0.4.6.orig/src/test.c
+++ libvirt-0.4.6/src/test.c
@@ -1595,6 +1595,11 @@ static virDriver testDriver = {
     NULL, /* domainMemoryPeek */
     testNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */
     NULL, /* getFreeMemory */
+    NULL, /* domainSnapshotCreate */
+    NULL, /* domainSnapshotApply */
+    NULL, /* domainSnapshotDelete */
+    NULL, /* domainNumOfSnapshots */
+    NULL, /* domainListSnapshots */
 };
 
 static virNetworkDriver testNetworkDriver = {
Index: libvirt-0.4.6/src/libvirt_sym.version
===================================================================
--- libvirt-0.4.6.orig/src/libvirt_sym.version
+++ libvirt-0.4.6/src/libvirt_sym.version
@@ -35,6 +35,11 @@
 	virDomainRestore;
 	virDomainResume;
 	virDomainSave;
+	virDomainSnapshotCreate;
+	virDomainSnapshotApply;
+	virDomainSnapshotDelete;
+	virDomainNumOfSnapshots;
+	virDomainListSnapshots;
 	virDomainCoreDump;
         virDomainSetMemory;
 	virDomainSetMaxMemory;
Index: libvirt-0.4.6/docs/libvirt-api.xml
===================================================================
--- libvirt-0.4.6.orig/docs/libvirt-api.xml
+++ libvirt-0.4.6/docs/libvirt-api.xml
@@ -143,6 +143,11 @@
      <exports symbol='virInitialize' type='function'/>
      <exports symbol='virDomainMigrate' type='function'/>
      <exports symbol='virDomainSuspend' type='function'/>
+     <exports symbol='virDomainSnapshotApply' type='function'/>
+     <exports symbol='virDomainSnapshotCreate' type='function'/>
+     <exports symbol='virDomainSnapshotDelete' type='function'/>
+     <exports symbol='virDomainNumOfSnapshots' type='function'/>
+     <exports symbol='virDomainListSnapshots' type='function'/>
      <exports symbol='virNetworkCreate' type='function'/>
      <exports symbol='virDomainDestroy' type='function'/>
      <exports symbol='virConnectNumOfNetworks' type='function'/>
@@ -1096,6 +1101,36 @@ see note above'/>
       <return type='int' info='0 in case of success and -1 in case of failure.'/>
       <arg name='domain' type='virDomainPtr' info='a domain object'/>
     </function>
+    <function name='virDomainSnapshotApply' file='libvirt' module='libvirt'>
+      <info>Start a shut off domain based on a previously taken snapshot</info>
+      <return type='int' info='0 in case of success and -1 in case of failure.'/>
+      <arg name='domain' type='virDomainPtr' info='a domain object'/>
+      <arg name='name' type='const char *' info='name of the snapshot'/>
+    </function>
+    <function name='virDomainSnapshotCreate' file='libvirt' module='libvirt'>
+      <info>Create a snapshot from a running domain</info>
+      <return type='int' info='0 in case of success and -1 in case of failure.'/>
+      <arg name='domain' type='virDomainPtr' info='a domain object'/>
+      <arg name='name' type='const char *' info='name of the snapshot'/>
+    </function>
+    <function name='virDomainSnapshotDelete' file='libvirt' module='libvirt'>
+      <info>Delete a snapshot from a domain</info>
+      <return type='int' info='0 in case of success and -1 in case of failure.'/>
+      <arg name='domain' type='virDomainPtr' info='a domain object'/>
+      <arg name='name' type='const char *' info='name of the snapshot'/>
+    </function>
+    <function name='virDomainNumOfSnapshots' file='libvirt' module='libvirt'>
+      <info>Returns the number of snapshot a given domain has</info>
+      <return type='int' info='the number of snapshots in case of success and -1 in case of failure.'/>
+      <arg name='domain' type='virDomainPtr' info='a domain object'/>
+    </function>
+    <function name='virDomainListSnapshots' file='libvirt' module='libvirt'>
+      <info>Returns the names of the snapshots of a domain</info>
+      <return type='int' info='0 in case of success and -1 in case of failure.'/>
+      <arg name='domain' type='virDomainPtr' info='a domain object'/>
+      <arg name='names' type='char ** const' info='pointer to an array to store the snapshot names'/>
+      <arg name='maxnames' type='int' info='size of the names array'/>
+    </function>
     <function name='virDomainUndefine' file='libvirt' module='libvirt'>
       <info>Undefine a domain but does not stop it if it is running</info>
       <return type='int' info='0 in case of success, -1 in case of error'/>
Index: libvirt-0.4.6/python/libvirt-py.c
===================================================================
--- libvirt-0.4.6.orig/python/libvirt-py.c
+++ libvirt-0.4.6/python/libvirt-py.c
@@ -25,6 +25,25 @@ LIBVIRT_END_ALLOW_THREADS;
 }
 
 PyObject *
+libvirt_virDomainSnapshotDelete(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    int c_retval;
+    virDomainPtr domain;
+    PyObject *pyobj_domain;
+    char * name;
+
+    if (!PyArg_ParseTuple(args, (char *)"Oz:virDomainSnapshotDelete", &pyobj_domain, &name))
+        return(NULL);
+    domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+LIBVIRT_BEGIN_ALLOW_THREADS;
+
+    c_retval = virDomainSnapshotDelete(domain, name);
+LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_intWrap((int) c_retval);
+    return(py_retval);
+}
+
+PyObject *
 libvirt_virStorageVolGetKey(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     PyObject *py_retval;
     const char * c_retval;
@@ -520,24 +539,6 @@ LIBVIRT_END_ALLOW_THREADS;
 }
 
 PyObject *
-libvirt_virNetworkGetName(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
-    PyObject *py_retval;
-    const char * c_retval;
-    virNetworkPtr network;
-    PyObject *pyobj_network;
-
-    if (!PyArg_ParseTuple(args, (char *)"O:virNetworkGetName", &pyobj_network))
-        return(NULL);
-    network = (virNetworkPtr) PyvirNetwork_Get(pyobj_network);
-LIBVIRT_BEGIN_ALLOW_THREADS;
-
-    c_retval = virNetworkGetName(network);
-LIBVIRT_END_ALLOW_THREADS;
-    py_retval = libvirt_charPtrConstWrap((const char *) c_retval);
-    return(py_retval);
-}
-
-PyObject *
 libvirt_virNetworkDestroy(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     PyObject *py_retval;
     int c_retval;
@@ -771,6 +772,25 @@ LIBVIRT_END_ALLOW_THREADS;
 }
 
 PyObject *
+libvirt_virDomainSnapshotCreate(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    int c_retval;
+    virDomainPtr domain;
+    PyObject *pyobj_domain;
+    char * name;
+
+    if (!PyArg_ParseTuple(args, (char *)"Oz:virDomainSnapshotCreate", &pyobj_domain, &name))
+        return(NULL);
+    domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+LIBVIRT_BEGIN_ALLOW_THREADS;
+
+    c_retval = virDomainSnapshotCreate(domain, name);
+LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_intWrap((int) c_retval);
+    return(py_retval);
+}
+
+PyObject *
 libvirt_virNetworkDefineXML(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     PyObject *py_retval;
     virNetworkPtr c_retval;
@@ -806,6 +826,24 @@ LIBVIRT_END_ALLOW_THREADS;
 }
 
 PyObject *
+libvirt_virDomainNumOfSnapshots(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    int c_retval;
+    virDomainPtr domain;
+    PyObject *pyobj_domain;
+
+    if (!PyArg_ParseTuple(args, (char *)"O:virDomainNumOfSnapshots", &pyobj_domain))
+        return(NULL);
+    domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+LIBVIRT_BEGIN_ALLOW_THREADS;
+
+    c_retval = virDomainNumOfSnapshots(domain);
+LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_intWrap((int) c_retval);
+    return(py_retval);
+}
+
+PyObject *
 libvirt_virDomainResume(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     PyObject *py_retval;
     int c_retval;
@@ -824,6 +862,25 @@ LIBVIRT_END_ALLOW_THREADS;
 }
 
 PyObject *
+libvirt_virDomainSnapshotApply(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    int c_retval;
+    virDomainPtr domain;
+    PyObject *pyobj_domain;
+    char * name;
+
+    if (!PyArg_ParseTuple(args, (char *)"Oz:virDomainSnapshotApply", &pyobj_domain, &name))
+        return(NULL);
+    domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+LIBVIRT_BEGIN_ALLOW_THREADS;
+
+    c_retval = virDomainSnapshotApply(domain, name);
+LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_intWrap((int) c_retval);
+    return(py_retval);
+}
+
+PyObject *
 libvirt_virConnectGetHostname(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     PyObject *py_retval;
     char * c_retval;
@@ -897,6 +954,24 @@ LIBVIRT_END_ALLOW_THREADS;
 }
 
 PyObject *
+libvirt_virNetworkGetName(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    const char * c_retval;
+    virNetworkPtr network;
+    PyObject *pyobj_network;
+
+    if (!PyArg_ParseTuple(args, (char *)"O:virNetworkGetName", &pyobj_network))
+        return(NULL);
+    network = (virNetworkPtr) PyvirNetwork_Get(pyobj_network);
+LIBVIRT_BEGIN_ALLOW_THREADS;
+
+    c_retval = virNetworkGetName(network);
+LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_charPtrConstWrap((const char *) c_retval);
+    return(py_retval);
+}
+
+PyObject *
 libvirt_virConnectGetCapabilities(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     PyObject *py_retval;
     char * c_retval;
Index: libvirt-0.4.6/python/libvirt-py.h
===================================================================
--- libvirt-0.4.6.orig/python/libvirt-py.h
+++ libvirt-0.4.6/python/libvirt-py.h
@@ -1,6 +1,7 @@
 /* Generated */
 
 PyObject * libvirt_virStoragePoolGetXMLDesc(PyObject *self, PyObject *args);
+PyObject * libvirt_virDomainSnapshotDelete(PyObject *self, PyObject *args);
 PyObject * libvirt_virStorageVolGetKey(PyObject *self, PyObject *args);
 PyObject * libvirt_virConnectClose(PyObject *self, PyObject *args);
 PyObject * libvirt_virDomainDefineXML(PyObject *self, PyObject *args);
@@ -28,7 +29,6 @@ PyObject * libvirt_virConnectNumOfNetwor
 PyObject * libvirt_virStorageVolGetName(PyObject *self, PyObject *args);
 PyObject * libvirt_virStoragePoolLookupByUUIDString(PyObject *self, PyObject *args);
 PyObject * libvirt_virDomainGetXMLDesc(PyObject *self, PyObject *args);
-PyObject * libvirt_virNetworkGetName(PyObject *self, PyObject *args);
 PyObject * libvirt_virNetworkDestroy(PyObject *self, PyObject *args);
 PyObject * libvirt_virStoragePoolLookupByName(PyObject *self, PyObject *args);
 PyObject * libvirt_virNetworkGetBridgeName(PyObject *self, PyObject *args);
@@ -42,13 +42,17 @@ PyObject * libvirt_virNetworkSetAutostar
 PyObject * libvirt_virDomainGetMaxMemory(PyObject *self, PyObject *args);
 PyObject * libvirt_virResetLastError(PyObject *self, PyObject *args);
 PyObject * libvirt_virStoragePoolFree(PyObject *self, PyObject *args);
+PyObject * libvirt_virDomainSnapshotCreate(PyObject *self, PyObject *args);
 PyObject * libvirt_virNetworkDefineXML(PyObject *self, PyObject *args);
 PyObject * libvirt_virConnResetLastError(PyObject *self, PyObject *args);
+PyObject * libvirt_virDomainNumOfSnapshots(PyObject *self, PyObject *args);
 PyObject * libvirt_virDomainResume(PyObject *self, PyObject *args);
+PyObject * libvirt_virDomainSnapshotApply(PyObject *self, PyObject *args);
 PyObject * libvirt_virConnectGetHostname(PyObject *self, PyObject *args);
 PyObject * libvirt_virDomainGetName(PyObject *self, PyObject *args);
 PyObject * libvirt_virNetworkGetXMLDesc(PyObject *self, PyObject *args);
 PyObject * libvirt_virConnectNumOfStoragePools(PyObject *self, PyObject *args);
+PyObject * libvirt_virNetworkGetName(PyObject *self, PyObject *args);
 PyObject * libvirt_virConnectGetCapabilities(PyObject *self, PyObject *args);
 PyObject * libvirt_virDomainLookupByName(PyObject *self, PyObject *args);
 PyObject * libvirt_virConnectFindStoragePoolSources(PyObject *self, PyObject *args);
Index: libvirt-0.4.6/python/libvirt.py
===================================================================
--- libvirt-0.4.6.orig/python/libvirt.py
+++ libvirt-0.4.6/python/libvirt.py
@@ -359,6 +359,12 @@ class virDomain:
         ret = libvirtmod.virDomainGetName(self._o)
         return ret
 
+    def numOfSnapshots(self):
+        """Returns the number of snapshot a given domain has """
+        ret = libvirtmod.virDomainNumOfSnapshots(self._o)
+        if ret == -1: raise libvirtError ('virDomainNumOfSnapshots() failed', dom=self)
+        return ret
+
     def reboot(self, flags):
         """Reboot a domain, the domain object is still usable there
           after but the domain OS is being stopped for a restart.
@@ -433,6 +439,24 @@ class virDomain:
         if ret == -1: raise libvirtError ('virDomainShutdown() failed', dom=self)
         return ret
 
+    def snapshotApply(self, name):
+        """Start a shut off domain based on a previously taken snapshot """
+        ret = libvirtmod.virDomainSnapshotApply(self._o, name)
+        if ret == -1: raise libvirtError ('virDomainSnapshotApply() failed', dom=self)
+        return ret
+
+    def snapshotCreate(self, name):
+        """Create a snapshot from a running domain """
+        ret = libvirtmod.virDomainSnapshotCreate(self._o, name)
+        if ret == -1: raise libvirtError ('virDomainSnapshotCreate() failed', dom=self)
+        return ret
+
+    def snapshotDelete(self, name):
+        """Delete a snapshot from a domain """
+        ret = libvirtmod.virDomainSnapshotDelete(self._o, name)
+        if ret == -1: raise libvirtError ('virDomainSnapshotDelete() failed', dom=self)
+        return ret
+
     def suspend(self):
         """Suspends an active domain, the process is frozen without
           further access to CPU resources and I/O but the memory used
@@ -489,6 +513,12 @@ class virDomain:
         ret = libvirtmod.virDomainInterfaceStats(self._o, path)
         return ret
 
+    def listSnapshots(self):
+        """Returns the names of the snapshots of a domain """
+        ret = libvirtmod.virDomainListSnapshots(self._o)
+        if ret is None: raise libvirtError ('virDomainListSnapshots() failed', dom=self)
+        return ret
+
     def pinVcpu(self, vcpu, cpumap):
         """Dynamically change the real CPUs which can be allocated to
           a virtual CPU. This function requires privileged access to
Index: libvirt-0.4.6/python/libvir.c
===================================================================
--- libvirt-0.4.6.orig/python/libvir.c
+++ libvirt-0.4.6/python/libvir.c
@@ -1466,6 +1466,35 @@ libvirt_virStoragePoolLookupByUUID(PyObj
     return(py_retval);
 }
 
+static PyObject *
+libvirt_virDomainListSnapshots(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    int i, num;
+    char** names;
+    virDomainPtr domain;
+    PyObject *pyobj_domain;
+
+    if (!PyArg_ParseTuple(args, (char *)"O:virDomainListSnapshots",
+            &pyobj_domain))
+        return(NULL);
+    domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+LIBVIRT_BEGIN_ALLOW_THREADS;
+    num = virDomainNumOfSnapshots(domain);
+    names = malloc(num * sizeof(*names));
+    virDomainListSnapshots(domain, names, num);
+LIBVIRT_END_ALLOW_THREADS;
+
+    py_retval = PyList_New(num);
+    for (i = 0; i < num; i++) {
+        PyList_SetItem(py_retval, i, Py_BuildValue("s", names[i]));
+        free(names[i]);
+    }
+    free(names);
+
+    return(py_retval);
+}
+
 
 
 /************************************************************************
@@ -1502,6 +1531,7 @@ static PyMethodDef libvirtMethods[] = {
     {(char *) "virDomainSetSchedulerParameters", libvirt_virDomainSetSchedulerParameters, METH_VARARGS, NULL},
     {(char *) "virDomainGetVcpus", libvirt_virDomainGetVcpus, METH_VARARGS, NULL},
     {(char *) "virDomainPinVcpu", libvirt_virDomainPinVcpu, METH_VARARGS, NULL},
+    {(char *) "virDomainListSnapshots", libvirt_virDomainListSnapshots, METH_VARARGS, NULL},
     {(char *) "virConnectListStoragePools", libvirt_virConnectListStoragePools, METH_VARARGS, NULL},
     {(char *) "virConnectListDefinedStoragePools", libvirt_virConnectListDefinedStoragePools, METH_VARARGS, NULL},
     {(char *) "virStoragePoolGetAutostart", libvirt_virStoragePoolGetAutostart, METH_VARARGS, NULL},
Index: libvirt-0.4.6/python/libvirt-python-api.xml
===================================================================
--- libvirt-0.4.6.orig/python/libvirt-python-api.xml
+++ libvirt-0.4.6/python/libvirt-python-api.xml
@@ -135,6 +135,11 @@
       <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
       <arg name='params' type='virSchedParameterPtr' info='pointer to scheduler parameter objects'/>
     </function>
+    <function name='virDomainListSnapshots' file='python'>
+      <info>Returns the names of the snapshots of a domain</info>
+      <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
+      <return type='str *' info='the list of Names or None in case of error'/>
+    </function>
     <function name='virConnectListStoragePools' file='python'>
       <info>list the storage pools, stores the pointers to the names in @names</info>
       <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
Index: libvirt-0.4.6/python/generator.py
===================================================================
--- libvirt-0.4.6.orig/python/generator.py
+++ libvirt-0.4.6/python/generator.py
@@ -306,6 +306,7 @@ skip_impl = (
     'virDomainSetSchedulerParameters',
     'virDomainGetVcpus',
     'virDomainPinVcpu',
+    'virDomainListSnapshots',
     'virStoragePoolGetUUID',
     'virStoragePoolGetUUIDString',
     'virStoragePoolLookupByUUID',
openSUSE Build Service is sponsored by