All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] tools/libxl: add disk snapshot support
@ 2014-04-02 11:21 Bamvor Jian Zhang
  2014-04-03 14:14 ` Ian Jackson
  2014-05-15  8:38 ` David kiarie
  0 siblings, 2 replies; 6+ messages in thread
From: Bamvor Jian Zhang @ 2014-04-02 11:21 UTC (permalink / raw)
  To: xen-devel; +Cc: anthony.perard, ian.jackson, ian.campbell, Bamvor Jian Zhang

add internal disk snapshot support through qemu qmp, including create,
delete and list.

Signed-off-by: Bamvor Jian Zhang <bjzhang@suse.com>
---
 tools/libxl/libxl.c          |  29 ++++++++++
 tools/libxl/libxl.h          |   9 +++
 tools/libxl/libxl_internal.h |  15 +++++
 tools/libxl/libxl_qmp.c      | 132 +++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_types.idl  |  12 ++++
 tools/libxl/xl.h             |   3 +
 tools/libxl/xl_cmdimpl.c     | 114 +++++++++++++++++++++++++++++++++++++
 tools/libxl/xl_cmdtable.c    |  18 ++++++
 8 files changed, 332 insertions(+)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 30b0b06..76b4c65 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -5661,6 +5661,35 @@ int libxl_fd_set_cloexec(libxl_ctx *ctx, int fd, int cloexec)
 int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock)
   { return fd_set_flags(ctx,fd, F_GETFL,F_SETFL,"FL", O_NONBLOCK, nonblock); }
 
+int libxl__disk_snapshot_create(libxl_ctx *ctx, int domid,
+                                libxl_snapshot *snapshot)
+{
+    int rc;
+    GC_INIT(ctx);
+    rc = libxl__qmp_disk_snapshot_internal(gc, domid, snapshot);
+    GC_FREE;
+    return rc;
+}
+
+int libxl__disk_snapshot_delete(libxl_ctx *ctx, int domid,
+                                libxl_snapshot *snapshot)
+{
+    int rc;
+    GC_INIT(ctx);
+    rc = libxl__qmp_disk_snapshot_delete_internal(gc, domid, snapshot);
+    GC_FREE;
+    return rc;
+}
+
+int libxl__disk_snapshot_list(libxl_ctx *ctx, int domid,
+                              libxl_snapshot **snapshotp)
+{
+    GC_INIT(ctx);
+    libxl__qmp_disk_snapshot_list_internal(gc, domid, snapshotp);
+    GC_FREE;
+    return 0;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index b2c3015..5139a01 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1151,6 +1151,15 @@ int libxl_flask_getenforce(libxl_ctx *ctx);
 int libxl_flask_setenforce(libxl_ctx *ctx, int mode);
 int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size);
 
+/* disk snapshot api
+ * support create, delete and list for internal snapshot of a single disk
+ */
+int libxl__disk_snapshot_create(libxl_ctx *ctx, int domid,
+                                libxl_snapshot *snapshot);
+int libxl__disk_snapshot_delete(libxl_ctx *ctx, int domid,
+                                libxl_snapshot *snapshot);
+int libxl__disk_snapshot_list(libxl_ctx *ctx, int domid,
+                              libxl_snapshot **snapshotp);
 /* misc */
 
 /* Each of these sets or clears the flag according to whether the
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index c2b73c4..ab73a1d 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1585,6 +1585,21 @@ _hidden int libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enabl
 _hidden int libxl__qmp_insert_cdrom(libxl__gc *gc, int domid, const libxl_device_disk *disk);
 /* Add a virtual CPU */
 _hidden int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int index);
+/* disk internal snapshot */
+int libxl__qmp_disk_snapshot_internal(libxl__gc *gc, int domid,
+                                      libxl_snapshot *snapshot);
+/* caller should ensure that the id and name at lease exist one and only exist
+ * one. */
+int libxl__qmp_disk_snapshot_delete_internal(libxl__gc *gc, int domid,
+                                             libxl_snapshot *snapshot);
+int libxl__qmp_disk_snapshot_list_internal(libxl__gc *gc, int domid,
+                                           libxl_snapshot **snapshotp);
+/* tranaction operation for disk snapshot: support internal and external
+ * snapshot */
+int libxl__qmp_disk_snapshot_transaction(libxl__gc *gc, int domid,
+                                         libxl_snapshot *snapshot, int nb);
+/* run and get qmp result */
+int libxl__qmp_test(libxl__gc *gc, int domid, const char* command);
 /* close and free the QMP handler */
 _hidden void libxl__qmp_close(libxl__qmp_handler *qmp);
 /* remove the socket file, if the file has already been removed,
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 8433e42..5f7cbf4 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -939,6 +939,138 @@ int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int idx)
     return qmp_run_command(gc, domid, "cpu-add", args, NULL, NULL);
 }
 
+int libxl__qmp_disk_snapshot_transaction(libxl__gc *gc, int domid,
+                                         libxl_snapshot *snapshot, int nb)
+{
+    libxl__json_object *args = NULL;
+    libxl__json_object *types = NULL;
+    libxl__json_object **type = NULL;
+    libxl__json_object **device = NULL;
+    int i;
+
+    type = (libxl__json_object**)calloc(nb, sizeof(libxl__json_object*));
+    device = (libxl__json_object**)calloc(nb, sizeof(libxl__json_object*));
+    types = libxl__json_object_alloc(gc, JSON_ARRAY);
+    for ( i = 0; i < nb; i++ ) {
+        qmp_parameters_add_string(gc, &type[i], "type",
+                                  "blockdev-snapshot-internal-sync");
+        qmp_parameters_add_string(gc, &device[i], "device", snapshot[i].device);
+        qmp_parameters_add_string(gc, &device[i], "name", snapshot[i].name);
+        qmp_parameters_common_add(gc, &type[i], "data", device[i]);
+        flexarray_append(types->u.array, (void*)type[i]);
+    }
+    qmp_parameters_common_add(gc, &args, "actions", types);
+    return qmp_run_command(gc, domid, "transaction", args, NULL, NULL);
+}
+
+int libxl__qmp_disk_snapshot_internal(libxl__gc *gc, int domid,
+                                      libxl_snapshot *snapshot)
+{
+    return libxl__qmp_disk_snapshot_transaction(gc, domid, snapshot, 1);
+}
+
+static int qmp_disk_snapshot_list_internal_callback(libxl__qmp_handler *qmp,
+                                                    const libxl__json_object *response,
+                                                    void *opaque)
+{
+    const libxl__json_object *obj = NULL;
+    const libxl__json_object *label = NULL;
+    const libxl__json_object *insert_dev = NULL;
+    const libxl__json_object *image = NULL;
+    const libxl__json_object *snapshot_array = NULL;
+    const libxl__json_object *snapshot_node = NULL;
+    int i = 0;
+    int j = 0;
+    libxl_snapshot **snapshotp = (libxl_snapshot**)opaque;
+    char *device = strdup((*snapshotp)[0].device);
+    libxl_snapshot *snapshot;
+    int count;
+
+    for (i = 0; (obj = libxl__json_array_get(response, i)); i++) {
+        if (!libxl__json_object_is_map(obj))
+            continue;
+
+        label = libxl__json_map_get("device", obj, JSON_STRING);
+        if ( strcmp(libxl__json_object_get_string(label), device) )
+            continue;
+
+        insert_dev = libxl__json_map_get("inserted", obj, JSON_MAP);
+        if ( insert_dev == NULL ) {
+            goto not_found;
+        }
+
+        image = libxl__json_map_get("image", insert_dev, JSON_MAP);
+        if ( image == NULL ) {
+            goto not_found;
+        }
+
+        snapshot_array = libxl__json_map_get("snapshots", image, JSON_ARRAY);
+        if ( snapshot_array == NULL ) {
+            goto not_found;
+        }
+
+        count = libxl__json_object_get_array(snapshot_array)->count;
+        *snapshotp = realloc(*snapshotp, sizeof(libxl_snapshot)*(count + 1));
+        memset(*snapshotp, 0, sizeof(libxl_snapshot)*(count + 1));
+        for ( j = 0; j < count; j++ ) {
+            snapshot_node = libxl__json_array_get(snapshot_array, j);
+            snapshot = &(*snapshotp)[j];
+            snapshot->device = strdup(device);
+            label = libxl__json_map_get("id", snapshot_node, JSON_STRING);
+            snapshot->id = strdup(libxl__json_object_get_string(label));
+            label = libxl__json_map_get("name", snapshot_node, JSON_STRING);
+            snapshot->name = strdup(libxl__json_object_get_string(label));
+            label = libxl__json_map_get("vm-state-size", snapshot_node,
+                                        JSON_INTEGER);
+            snapshot->vm_state_size = libxl__json_object_get_integer(label);
+            label = libxl__json_map_get("date-sec", snapshot_node,
+                                        JSON_INTEGER);
+            snapshot->date_sec = libxl__json_object_get_integer(label);
+            label = libxl__json_map_get("date-nsec", snapshot_node,
+                                        JSON_INTEGER);
+            snapshot->date_nsec = libxl__json_object_get_integer(label);
+            label = libxl__json_map_get("vm-clock-sec", snapshot_node,
+                                        JSON_INTEGER);
+            snapshot->vm_clock_sec = libxl__json_object_get_integer(label);
+            label = libxl__json_map_get("vm-clock-nsec", snapshot_node,
+                                        JSON_INTEGER);
+            snapshot->vm_clock_nsec = libxl__json_object_get_integer(label);
+        }
+        goto found;
+    }
+not_found:
+    free((*snapshotp)[0].device);
+    (*snapshotp)[0].device = NULL;
+found:
+    free(device);
+    return 0;
+}
+
+int libxl__qmp_disk_snapshot_delete_internal(libxl__gc *gc, int domid,
+                                             libxl_snapshot *snapshot)
+{
+    libxl__json_object *args = NULL;
+
+    qmp_parameters_add_string(gc, &args, "device", snapshot->device);
+    if (snapshot->id)
+        qmp_parameters_add_string(gc, &args, "id", snapshot->id);
+    else if (snapshot->name)
+        qmp_parameters_add_string(gc, &args, "name", snapshot->name);
+    else
+        return -1;
+
+    return qmp_run_command(gc, domid, "blockdev-snapshot-delete-internal-sync",
+                           args, NULL, NULL);
+}
+
+
+int libxl__qmp_disk_snapshot_list_internal(libxl__gc *gc, int domid,
+                                          libxl_snapshot **snapshotp)
+{
+    return qmp_run_command(gc, domid, "query-block", NULL,
+                           qmp_disk_snapshot_list_internal_callback, snapshotp);
+}
+
 int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid,
                                const libxl_domain_config *guest_config)
 {
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 612645c..ca4bf36 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -598,3 +598,15 @@ libxl_event = Struct("event",[
                                  ])),
            ("domain_create_console_available", Struct(None, [])),
            ]))])
+
+libxl_snapshot = Struct("snapshot",[
+    ("device",        string),
+    ("name",          string),
+    ("id",            string),
+    ("vm_state_size", uint64),
+    ("date_sec",      uint64),
+    ("date_nsec",     uint64),
+    ("vm_clock_sec",  uint64),
+    ("vm_clock_nsec", uint64),
+    ])
+
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index 10a2e66..d3894c0 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -110,6 +110,9 @@ int main_loadpolicy(int argc, char **argv);
 int main_remus(int argc, char **argv);
 #endif
 int main_devd(int argc, char **argv);
+int main_disk_snapshot_create(int argc, char **argv);
+int main_disk_snapshot_delete(int argc, char **argv);
+int main_disk_snapshot_list(int argc, char **argv);
 
 void help(const char *command);
 
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 8389468..215270e 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -7381,6 +7381,120 @@ out:
     return ret;
 }
 
+int main_disk_snapshot_create(int argc, char **argv) {
+    uint32_t domid;
+    int opt;
+    int rc = 0;
+    libxl_snapshot snapshot;
+    struct timeval timeval;
+
+    memset(&snapshot, 0, sizeof(libxl_snapshot));
+    SWITCH_FOREACH_OPT(opt, "n:", NULL, "disk-snapshot-create", 2) {
+    case 'n':
+        snapshot.name = strdup(optarg);
+        break;
+    }
+
+    if ( !snapshot.name ) {
+        snapshot.name = (char*)malloc(sizeof(time_t) * 8 + 1);
+        gettimeofday(&timeval, NULL);
+        sprintf(snapshot.name, "%ld", timeval.tv_sec);
+    }
+
+    if ( argc - optind != 2 ) {
+        fprintf(stderr, "no domain name and disk, exit!!!\n");
+        return -1;
+    }
+    domid = find_domain(argv[optind++]);
+    snapshot.device = strdup(argv[optind++]);
+    rc = libxl__disk_snapshot_create(ctx, domid, &snapshot);
+    libxl_snapshot_dispose(&snapshot);
+
+    return rc;
+}
+
+int main_disk_snapshot_delete(int argc, char **argv) {
+    uint32_t domid;
+    int opt;
+    int rc = 0;
+    libxl_snapshot snapshot;
+
+    memset(&snapshot, 0, sizeof(libxl_snapshot));
+    SWITCH_FOREACH_OPT(opt, "i:n:", NULL, "disk-snapshot-delete", 2) {
+    case 'i':
+        snapshot.id = strdup(optarg);
+        break;
+    case 'n':
+        snapshot.name = strdup(optarg);
+        break;
+    }
+
+    if ( snapshot.id == NULL && snapshot.name == NULL ) {
+        fprintf(stderr, "should provide id or name for deleting\n");
+        return -1;
+    }
+    domid = find_domain(argv[optind++]);
+    snapshot.device = strdup(argv[optind++]);
+    rc = libxl__disk_snapshot_delete(ctx, domid, &snapshot);
+    libxl_snapshot_dispose(&snapshot);
+
+    return rc;
+}
+
+int main_disk_snapshot_list(int argc, char **argv) {
+    uint32_t domid;
+    int opt;
+    libxl_snapshot *snapshot;
+    int rc = 0;
+    int i = 0;
+    struct tm *tm;
+    time_t time;
+
+    SWITCH_FOREACH_OPT(opt, "", NULL, "disk-snapshot-list", 2) {
+        /* No options */
+    }
+
+    snapshot = (libxl_snapshot*)malloc(sizeof(libxl_snapshot));
+    memset(snapshot, 0, sizeof(libxl_snapshot));
+    domid = find_domain(argv[optind++]);
+    snapshot[0].device = strdup(argv[optind++]);
+
+    rc = libxl__disk_snapshot_list(ctx, domid, &snapshot);
+    if (snapshot[0].device == NULL ) {
+        fprintf(stderr, "snapshot on this device does not exist\n");
+        rc = -1;
+        goto error;
+    }
+    if (snapshot[0].name == NULL && snapshot[0].id == NULL ) {
+        fprintf(stderr, "no this device: %s\n", snapshot[0].device);
+        rc = -1;
+        goto error;
+    }
+    printf("Snapshot list:\n");
+    printf("ID        TAG                 VM SIZE                DATE"
+            "       VM CLOCK\n");
+    while(snapshot[i].name != NULL && snapshot[i].id != NULL ) {
+        printf("%-10s", snapshot[i].id);
+        printf("%-20s", snapshot[i].name);
+        printf("%7lu", snapshot[i].vm_state_size);
+        time = (time_t)snapshot[i].date_sec;
+        tm = gmtime(&time);
+        printf(" %04d-%02d-%02d %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1,
+                tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+        printf("   %02lu:%02lu:%02lu.%03lu\n", snapshot[i].vm_clock_sec / 3600,
+                snapshot[i].vm_clock_sec / 60, snapshot[i].vm_clock_sec % 60,
+                snapshot[i].vm_clock_nsec / 1000000);
+        libxl_snapshot_dispose(&snapshot[i]);
+        i++;
+    }
+    goto exit;
+error:
+    libxl_snapshot_dispose(&snapshot[0]);
+exit:
+    free(snapshot);
+    return rc;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
index e8ab93a..930da22 100644
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -497,6 +497,24 @@ struct cmd_spec cmd_table[] = {
       "[options]",
       "-F                      Run in the foreground",
     },
+    { "disk-snapshot-create",
+      &main_disk_snapshot_create, 0, 1,
+      "Do domain disk snapshot create",
+      "[-n] <Domain>",
+      "  -n name                        snapshot name. if ignore, use second from Epoch",
+    },
+    { "disk-snapshot-delete",
+      &main_disk_snapshot_delete, 0, 1,
+      "Do domain disk snapshot delete",
+      "[-n|-i] <Domain> <device>",
+      "  -n name                        snapshot name\n"
+      "  -i id                          snapshot id",
+    },
+    { "disk-snapshot-list",
+      &main_disk_snapshot_list, 0, 1,
+      "Do domain disk snapshot list",
+      "<Domain> <device>",
+    },
 };
 
 int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC] tools/libxl: add disk snapshot support
  2014-04-02 11:21 [RFC] tools/libxl: add disk snapshot support Bamvor Jian Zhang
@ 2014-04-03 14:14 ` Ian Jackson
  2014-04-07  9:11   ` Bamvor Jian Zhang
  2014-05-15  8:38 ` David kiarie
  1 sibling, 1 reply; 6+ messages in thread
From: Ian Jackson @ 2014-04-03 14:14 UTC (permalink / raw)
  To: Bamvor Jian Zhang; +Cc: anthony.perard, ian.campbell, xen-devel

Bamvor Jian Zhang writes ("[RFC] tools/libxl: add disk snapshot support"):
> add internal disk snapshot support through qemu qmp, including create,
> delete and list.

Thanks for this submission.

To review this idea, I think it is really necessary for me to
understand the proposed semantics.  Sadly you don't provide a
documentation patch.

I think this would be much easier to review in the form of a patch to
docs/man/xl.pod.1.  There needs to be a conceptual explanation of what
a snapshot is, where it is stored, and so forth.

Your code appears simply to send some messages to qemu.  I don't
understand how that can do anything particularly useful.

Thanks,
Ian.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC] tools/libxl: add disk snapshot support
  2014-04-03 14:14 ` Ian Jackson
@ 2014-04-07  9:11   ` Bamvor Jian Zhang
  0 siblings, 0 replies; 6+ messages in thread
From: Bamvor Jian Zhang @ 2014-04-07  9:11 UTC (permalink / raw)
  To: Ian.Jackson; +Cc: anthony.perard, ian.campbell, xen-devel

hi, ian
 "Ian Jackson" <Ian.Jackson@eu.citrix.com> written:
>
> Bamvor Jian Zhang writes ("[RFC] tools/libxl: add disk snapshot support"):
> > add internal disk snapshot support through qemu qmp, including create,
> > delete and list.
>
> Thanks for this submission.
>
> To review this idea, I think it is really necessary for me to
> understand the proposed semantics.  Sadly you don't provide a
> documentation patch.
>
> I think this would be much easier to review in the form of a patch to
> docs/man/xl.pod.1.  There needs to be a conceptual explanation of what
> a snapshot is, where it is stored, and so forth.
thanks, i will add doc in next version.

regards

bamvor
>
> Your code appears simply to send some messages to qemu.  I don't
> understand how that can do anything particularly useful.
>
> Thanks,
> Ian.
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC] tools/libxl: add disk snapshot support
  2014-04-02 11:21 [RFC] tools/libxl: add disk snapshot support Bamvor Jian Zhang
  2014-04-03 14:14 ` Ian Jackson
@ 2014-05-15  8:38 ` David kiarie
  2014-05-15 10:01   ` Bamvor Jian Zhang
  1 sibling, 1 reply; 6+ messages in thread
From: David kiarie @ 2014-05-15  8:38 UTC (permalink / raw)
  To: Bamvor Jian Zhang; +Cc: Anthony PERARD, Ian Jackson, Ian Campbell, xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 17480 bytes --]

On Wed, Apr 2, 2014 at 2:21 PM, Bamvor Jian Zhang <bjzhang@suse.com> wrote:

> add internal disk snapshot support through qemu qmp, including create,
> delete and list.
>
> Signed-off-by: Bamvor Jian Zhang <bjzhang@suse.com>
> ---
>  tools/libxl/libxl.c          |  29 ++++++++++
>  tools/libxl/libxl.h          |   9 +++
>  tools/libxl/libxl_internal.h |  15 +++++
>  tools/libxl/libxl_qmp.c      | 132
> +++++++++++++++++++++++++++++++++++++++++++
>  tools/libxl/libxl_types.idl  |  12 ++++
>  tools/libxl/xl.h             |   3 +
>  tools/libxl/xl_cmdimpl.c     | 114 +++++++++++++++++++++++++++++++++++++
>  tools/libxl/xl_cmdtable.c    |  18 ++++++
>  8 files changed, 332 insertions(+)
>
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index 30b0b06..76b4c65 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -5661,6 +5661,35 @@ int libxl_fd_set_cloexec(libxl_ctx *ctx, int fd,
> int cloexec)
>  int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock)
>    { return fd_set_flags(ctx,fd, F_GETFL,F_SETFL,"FL", O_NONBLOCK,
> nonblock); }
>
> +int libxl__disk_snapshot_create(libxl_ctx *ctx, int domid,
> +                                libxl_snapshot *snapshot)
> +{
> +    int rc;
> +    GC_INIT(ctx);
> +    rc = libxl__qmp_disk_snapshot_internal(gc, domid, snapshot);
> +    GC_FREE;
> +    return rc;
> +}
> +
> +int libxl__disk_snapshot_delete(libxl_ctx *ctx, int domid,
> +                                libxl_snapshot *snapshot)
> +{
> +    int rc;
> +    GC_INIT(ctx);
> +    rc = libxl__qmp_disk_snapshot_delete_internal(gc, domid, snapshot);
> +    GC_FREE;
> +    return rc;
> +}
> +
> +int libxl__disk_snapshot_list(libxl_ctx *ctx, int domid,
> +                              libxl_snapshot **snapshotp)
> +{
> +    GC_INIT(ctx);
> +    libxl__qmp_disk_snapshot_list_internal(gc, domid, snapshotp);
> +    GC_FREE;
> +    return 0;
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index b2c3015..5139a01 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -1151,6 +1151,15 @@ int libxl_flask_getenforce(libxl_ctx *ctx);
>  int libxl_flask_setenforce(libxl_ctx *ctx, int mode);
>  int libxl_flask_loadpolicy(libxl_ctx *ctx, void *policy, uint32_t size);
>
> +/* disk snapshot api
> + * support create, delete and list for internal snapshot of a single disk
> + */
> +int libxl__disk_snapshot_create(libxl_ctx *ctx, int domid,
> +                                libxl_snapshot *snapshot);
> +int libxl__disk_snapshot_delete(libxl_ctx *ctx, int domid,
> +                                libxl_snapshot *snapshot);
> +int libxl__disk_snapshot_list(libxl_ctx *ctx, int domid,
> +                              libxl_snapshot **snapshotp);
>  /* misc */
>
>  /* Each of these sets or clears the flag according to whether the
> diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
> index c2b73c4..ab73a1d 100644
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -1585,6 +1585,21 @@ _hidden int
> libxl__qmp_set_global_dirty_log(libxl__gc *gc, int domid, bool enabl
>  _hidden int libxl__qmp_insert_cdrom(libxl__gc *gc, int domid, const
> libxl_device_disk *disk);
>  /* Add a virtual CPU */
>  _hidden int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int index);
> +/* disk internal snapshot */
> +int libxl__qmp_disk_snapshot_internal(libxl__gc *gc, int domid,
> +                                      libxl_snapshot *snapshot);
> +/* caller should ensure that the id and name at lease exist one and only
> exist
> + * one. */
> +int libxl__qmp_disk_snapshot_delete_internal(libxl__gc *gc, int domid,
> +                                             libxl_snapshot *snapshot);
> +int libxl__qmp_disk_snapshot_list_internal(libxl__gc *gc, int domid,
> +                                           libxl_snapshot **snapshotp);
> +/* tranaction operation for disk snapshot: support internal and external
> + * snapshot */
> +int libxl__qmp_disk_snapshot_transaction(libxl__gc *gc, int domid,
> +                                         libxl_snapshot *snapshot, int
> nb);
> +/* run and get qmp result */
> +int libxl__qmp_test(libxl__gc *gc, int domid, const char* command);
>  /* close and free the QMP handler */
>  _hidden void libxl__qmp_close(libxl__qmp_handler *qmp);
>  /* remove the socket file, if the file has already been removed,
> diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
> index 8433e42..5f7cbf4 100644
> --- a/tools/libxl/libxl_qmp.c
> +++ b/tools/libxl/libxl_qmp.c
> @@ -939,6 +939,138 @@ int libxl__qmp_cpu_add(libxl__gc *gc, int domid, int
> idx)
>      return qmp_run_command(gc, domid, "cpu-add", args, NULL, NULL);
>  }
>
> +int libxl__qmp_disk_snapshot_transaction(libxl__gc *gc, int domid,
> +                                         libxl_snapshot *snapshot, int nb)
> +{
> +    libxl__json_object *args = NULL;
> +    libxl__json_object *types = NULL;
> +    libxl__json_object **type = NULL;
> +    libxl__json_object **device = NULL;
> +    int i;
> +
> +    type = (libxl__json_object**)calloc(nb, sizeof(libxl__json_object*));
> +    device = (libxl__json_object**)calloc(nb,
> sizeof(libxl__json_object*));
> +    types = libxl__json_object_alloc(gc, JSON_ARRAY);
> +    for ( i = 0; i < nb; i++ ) {
> +        qmp_parameters_add_string(gc, &type[i], "type",
> +                                  "blockdev-snapshot-internal-sync");
> +        qmp_parameters_add_string(gc, &device[i], "device",
> snapshot[i].device);
> +        qmp_parameters_add_string(gc, &device[i], "name",
> snapshot[i].name);
> +        qmp_parameters_common_add(gc, &type[i], "data", device[i]);
> +        flexarray_append(types->u.array, (void*)type[i]);
> +    }
> +    qmp_parameters_common_add(gc, &args, "actions", types);
> +    return qmp_run_command(gc, domid, "transaction", args, NULL, NULL);
> +}
> +
> +int libxl__qmp_disk_snapshot_internal(libxl__gc *gc, int domid,
> +                                      libxl_snapshot *snapshot)
> +{
> +    return libxl__qmp_disk_snapshot_transaction(gc, domid, snapshot, 1);
> +}
> +
> +static int qmp_disk_snapshot_list_internal_callback(libxl__qmp_handler
> *qmp,
> +                                                    const
> libxl__json_object *response,
> +                                                    void *opaque)
> +{
> +    const libxl__json_object *obj = NULL;
> +    const libxl__json_object *label = NULL;
> +    const libxl__json_object *insert_dev = NULL;
> +    const libxl__json_object *image = NULL;
> +    const libxl__json_object *snapshot_array = NULL;
> +    const libxl__json_object *snapshot_node = NULL;
> +    int i = 0;
> +    int j = 0;
> +    libxl_snapshot **snapshotp = (libxl_snapshot**)opaque;
> +    char *device = strdup((*snapshotp)[0].device);
> +    libxl_snapshot *snapshot;
> +    int count;
> +
> +    for (i = 0; (obj = libxl__json_array_get(response, i)); i++) {
> +        if (!libxl__json_object_is_map(obj))
> +            continue;
> +
> +        label = libxl__json_map_get("device", obj, JSON_STRING);
> +        if ( strcmp(libxl__json_object_get_string(label), device) )
> +            continue;
> +
> +        insert_dev = libxl__json_map_get("inserted", obj, JSON_MAP);
> +        if ( insert_dev == NULL ) {
> +            goto not_found;
> +        }
> +
> +        image = libxl__json_map_get("image", insert_dev, JSON_MAP);
> +        if ( image == NULL ) {
> +            goto not_found;
> +        }
> +
> +        snapshot_array = libxl__json_map_get("snapshots", image,
> JSON_ARRAY);
> +        if ( snapshot_array == NULL ) {
> +            goto not_found;
> +        }
> +
> +        count = libxl__json_object_get_array(snapshot_array)->count;
> +        *snapshotp = realloc(*snapshotp, sizeof(libxl_snapshot)*(count +
> 1));
> +        memset(*snapshotp, 0, sizeof(libxl_snapshot)*(count + 1));
> +        for ( j = 0; j < count; j++ ) {
> +            snapshot_node = libxl__json_array_get(snapshot_array, j);
> +            snapshot = &(*snapshotp)[j];
> +            snapshot->device = strdup(device);
> +            label = libxl__json_map_get("id", snapshot_node, JSON_STRING);
> +            snapshot->id = strdup(libxl__json_object_get_string(label));
> +            label = libxl__json_map_get("name", snapshot_node,
> JSON_STRING);
> +            snapshot->name = strdup(libxl__json_object_get_string(label));
> +            label = libxl__json_map_get("vm-state-size", snapshot_node,
> +                                        JSON_INTEGER);
> +            snapshot->vm_state_size =
> libxl__json_object_get_integer(label);
> +            label = libxl__json_map_get("date-sec", snapshot_node,
> +                                        JSON_INTEGER);
> +            snapshot->date_sec = libxl__json_object_get_integer(label);
> +            label = libxl__json_map_get("date-nsec", snapshot_node,
> +                                        JSON_INTEGER);
> +            snapshot->date_nsec = libxl__json_object_get_integer(label);
> +            label = libxl__json_map_get("vm-clock-sec", snapshot_node,
> +                                        JSON_INTEGER);
> +            snapshot->vm_clock_sec =
> libxl__json_object_get_integer(label);
> +            label = libxl__json_map_get("vm-clock-nsec", snapshot_node,
> +                                        JSON_INTEGER);
> +            snapshot->vm_clock_nsec =
> libxl__json_object_get_integer(label);
> +        }
> +        goto found;
> +    }
> +not_found:
> +    free((*snapshotp)[0].device);
> +    (*snapshotp)[0].device = NULL;
> +found:
> +    free(device);
> +    return 0;
> +}
> +
> +int libxl__qmp_disk_snapshot_delete_internal(libxl__gc *gc, int domid,
> +                                             libxl_snapshot *snapshot)
> +{
> +    libxl__json_object *args = NULL;
> +
> +    qmp_parameters_add_string(gc, &args, "device", snapshot->device);
> +    if (snapshot->id)
> +        qmp_parameters_add_string(gc, &args, "id", snapshot->id);
> +    else if (snapshot->name)
> +        qmp_parameters_add_string(gc, &args, "name", snapshot->name);
> +    else
> +        return -1;
> +
> +    return qmp_run_command(gc, domid,
> "blockdev-snapshot-delete-internal-sync",
> +                           args, NULL, NULL);
> +}
> +
>

What qemu are you using?

IIUC the block-snapshot-<operation>-internal-sync commands have not being
implemented here.Well they are not synchronized.I can only see
block-snapshot-<operation>- ones; no sync

 +
> +int libxl__qmp_disk_snapshot_list_internal(libxl__gc *gc, int domid,
> +                                          libxl_snapshot **snapshotp)
> +{
> +    return qmp_run_command(gc, domid, "query-block", NULL,
> +                           qmp_disk_snapshot_list_internal_callback,
> snapshotp);
> +}
> +
>  int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid,
>                                 const libxl_domain_config *guest_config)
>  {
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index 612645c..ca4bf36 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -598,3 +598,15 @@ libxl_event = Struct("event",[
>                                   ])),
>             ("domain_create_console_available", Struct(None, [])),
>             ]))])
> +
> +libxl_snapshot = Struct("snapshot",[
> +    ("device",        string),
> +    ("name",          string),
> +    ("id",            string),
> +    ("vm_state_size", uint64),
> +    ("date_sec",      uint64),
> +    ("date_nsec",     uint64),
> +    ("vm_clock_sec",  uint64),
> +    ("vm_clock_nsec", uint64),
> +    ])
> +
> diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
> index 10a2e66..d3894c0 100644
> --- a/tools/libxl/xl.h
> +++ b/tools/libxl/xl.h
> @@ -110,6 +110,9 @@ int main_loadpolicy(int argc, char **argv);
>  int main_remus(int argc, char **argv);
>  #endif
>  int main_devd(int argc, char **argv);
> +int main_disk_snapshot_create(int argc, char **argv);
> +int main_disk_snapshot_delete(int argc, char **argv);
> +int main_disk_snapshot_list(int argc, char **argv);
>
>  void help(const char *command);
>
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index 8389468..215270e 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -7381,6 +7381,120 @@ out:
>      return ret;
>  }
>
> +int main_disk_snapshot_create(int argc, char **argv) {
> +    uint32_t domid;
> +    int opt;
> +    int rc = 0;
> +    libxl_snapshot snapshot;
> +    struct timeval timeval;
> +
> +    memset(&snapshot, 0, sizeof(libxl_snapshot));
> +    SWITCH_FOREACH_OPT(opt, "n:", NULL, "disk-snapshot-create", 2) {
> +    case 'n':
> +        snapshot.name = strdup(optarg);
> +        break;
> +    }
> +
> +    if ( !snapshot.name ) {
> +        snapshot.name = (char*)malloc(sizeof(time_t) * 8 + 1);
> +        gettimeofday(&timeval, NULL);
> +        sprintf(snapshot.name, "%ld", timeval.tv_sec);
> +    }
> +
> +    if ( argc - optind != 2 ) {
> +        fprintf(stderr, "no domain name and disk, exit!!!\n");
> +        return -1;
> +    }
> +    domid = find_domain(argv[optind++]);
> +    snapshot.device = strdup(argv[optind++]);
> +    rc = libxl__disk_snapshot_create(ctx, domid, &snapshot);
> +    libxl_snapshot_dispose(&snapshot);
> +
> +    return rc;
> +}
> +
> +int main_disk_snapshot_delete(int argc, char **argv) {
> +    uint32_t domid;
> +    int opt;
> +    int rc = 0;
> +    libxl_snapshot snapshot;
> +
> +    memset(&snapshot, 0, sizeof(libxl_snapshot));
> +    SWITCH_FOREACH_OPT(opt, "i:n:", NULL, "disk-snapshot-delete", 2) {
> +    case 'i':
> +        snapshot.id = strdup(optarg);
> +        break;
> +    case 'n':
> +        snapshot.name = strdup(optarg);
> +        break;
> +    }
> +
> +    if ( snapshot.id == NULL && snapshot.name == NULL ) {
> +        fprintf(stderr, "should provide id or name for deleting\n");
> +        return -1;
> +    }
> +    domid = find_domain(argv[optind++]);
> +    snapshot.device = strdup(argv[optind++]);
> +    rc = libxl__disk_snapshot_delete(ctx, domid, &snapshot);
> +    libxl_snapshot_dispose(&snapshot);
> +
> +    return rc;
> +}
> +
> +int main_disk_snapshot_list(int argc, char **argv) {
> +    uint32_t domid;
> +    int opt;
> +    libxl_snapshot *snapshot;
> +    int rc = 0;
> +    int i = 0;
> +    struct tm *tm;
> +    time_t time;
> +
> +    SWITCH_FOREACH_OPT(opt, "", NULL, "disk-snapshot-list", 2) {
> +        /* No options */
> +    }
> +
> +    snapshot = (libxl_snapshot*)malloc(sizeof(libxl_snapshot));
> +    memset(snapshot, 0, sizeof(libxl_snapshot));
> +    domid = find_domain(argv[optind++]);
> +    snapshot[0].device = strdup(argv[optind++]);
> +
> +    rc = libxl__disk_snapshot_list(ctx, domid, &snapshot);
> +    if (snapshot[0].device == NULL ) {
> +        fprintf(stderr, "snapshot on this device does not exist\n");
> +        rc = -1;
> +        goto error;
> +    }
> +    if (snapshot[0].name == NULL && snapshot[0].id == NULL ) {
> +        fprintf(stderr, "no this device: %s\n", snapshot[0].device);
> +        rc = -1;
> +        goto error;
> +    }
> +    printf("Snapshot list:\n");
> +    printf("ID        TAG                 VM SIZE                DATE"
> +            "       VM CLOCK\n");
> +    while(snapshot[i].name != NULL && snapshot[i].id != NULL ) {
> +        printf("%-10s", snapshot[i].id);
> +        printf("%-20s", snapshot[i].name);
> +        printf("%7lu", snapshot[i].vm_state_size);
> +        time = (time_t)snapshot[i].date_sec;
> +        tm = gmtime(&time);
> +        printf(" %04d-%02d-%02d %02d:%02d:%02d", tm->tm_year + 1900,
> tm->tm_mon + 1,
> +                tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
> +        printf("   %02lu:%02lu:%02lu.%03lu\n", snapshot[i].vm_clock_sec /
> 3600,
> +                snapshot[i].vm_clock_sec / 60, snapshot[i].vm_clock_sec %
> 60,
> +                snapshot[i].vm_clock_nsec / 1000000);
> +        libxl_snapshot_dispose(&snapshot[i]);
> +        i++;
> +    }
> +    goto exit;
> +error:
> +    libxl_snapshot_dispose(&snapshot[0]);
> +exit:
> +    free(snapshot);
> +    return rc;
> +}
> +
>  /*
>   * Local variables:
>   * mode: C
> diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c
> index e8ab93a..930da22 100644
> --- a/tools/libxl/xl_cmdtable.c
> +++ b/tools/libxl/xl_cmdtable.c
> @@ -497,6 +497,24 @@ struct cmd_spec cmd_table[] = {
>        "[options]",
>        "-F                      Run in the foreground",
>      },
> +    { "disk-snapshot-create",
> +      &main_disk_snapshot_create, 0, 1,
> +      "Do domain disk snapshot create",
> +      "[-n] <Domain>",
> +      "  -n name                        snapshot name. if ignore, use
> second from Epoch",
> +    },
> +    { "disk-snapshot-delete",
> +      &main_disk_snapshot_delete, 0, 1,
> +      "Do domain disk snapshot delete",
> +      "[-n|-i] <Domain> <device>",
> +      "  -n name                        snapshot name\n"
> +      "  -i id                          snapshot id",
> +    },
> +    { "disk-snapshot-list",
> +      &main_disk_snapshot_list, 0, 1,
> +      "Do domain disk snapshot list",
> +      "<Domain> <device>",
> +    },
>  };
>
>  int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
> --
> 1.8.1.4
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
>

[-- Attachment #1.2: Type: text/html, Size: 22163 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC] tools/libxl: add disk snapshot support
  2014-05-15  8:38 ` David kiarie
@ 2014-05-15 10:01   ` Bamvor Jian Zhang
  2014-05-15 10:35     ` David kiarie
  0 siblings, 1 reply; 6+ messages in thread
From: Bamvor Jian Zhang @ 2014-05-15 10:01 UTC (permalink / raw)
  To: David kiarie
  Cc: Zhiqiang Zhou, Ian Campbell, Ian Jackson, Chun Yan Liu,
	xen-devel, Anthony PERARD

Hi, David

 >>>David kiarie <davidkiarie4@gmail.com> wrote:
> On Wed, Apr 2, 2014 at 2:21 PM, Bamvor Jian Zhang <bjzhang@suse.com> wrote:
>
> > add internal disk snapshot support through qemu qmp, including create,
> > delete and list.
> >
> > Signed-off-by: Bamvor Jian Zhang <bjzhang@suse.com>
> > ---
> >  tools/libxl/libxl.c          |  29 ++++++++++
> >  tools/libxl/libxl.h          |   9 +++
> >  tools/libxl/libxl_internal.h |  15 +++++
> >  tools/libxl/libxl_qmp.c      | 132
> > +++++++++++++++++++++++++++++++++++++++++++
> >  tools/libxl/libxl_types.idl  |  12 ++++
> >  tools/libxl/xl.h             |   3 +
> >  tools/libxl/xl_cmdimpl.c     | 114 +++++++++++++++++++++++++++++++++++++
> >  tools/libxl/xl_cmdtable.c    |  18 ++++++
> >  8 files changed, 332 insertions(+)
> >
>
> What qemu are you using?
>
> IIUC the block-snapshot-<operation>-internal-sync commands have not being
> implemented here.Well they are not synchronized.I can only see
> block-snapshot-<operation>- ones; no sync
it is upstream qemu, it maybe takes a long time for discussion and reviewing
the snapshot feature and code. i guess xen will update the qemu before our
snasphot patch get ack.

regards

bamvor

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC] tools/libxl: add disk snapshot support
  2014-05-15 10:01   ` Bamvor Jian Zhang
@ 2014-05-15 10:35     ` David kiarie
  0 siblings, 0 replies; 6+ messages in thread
From: David kiarie @ 2014-05-15 10:35 UTC (permalink / raw)
  To: Bamvor Jian Zhang
  Cc: Zhiqiang Zhou, Ian Campbell, Ian Jackson, Chun Yan Liu,
	xen-devel, Anthony PERARD


[-- Attachment #1.1: Type: text/plain, Size: 1382 bytes --]

Okay,..I will use it too


On Thu, May 15, 2014 at 1:01 PM, Bamvor Jian Zhang <bjzhang@suse.com> wrote:

> Hi, David
>
>  >>>David kiarie <davidkiarie4@gmail.com> wrote:
> > On Wed, Apr 2, 2014 at 2:21 PM, Bamvor Jian Zhang <bjzhang@suse.com>
> wrote:
> >
> > > add internal disk snapshot support through qemu qmp, including create,
> > > delete and list.
> > >
> > > Signed-off-by: Bamvor Jian Zhang <bjzhang@suse.com>
> > > ---
> > >  tools/libxl/libxl.c          |  29 ++++++++++
> > >  tools/libxl/libxl.h          |   9 +++
> > >  tools/libxl/libxl_internal.h |  15 +++++
> > >  tools/libxl/libxl_qmp.c      | 132
> > > +++++++++++++++++++++++++++++++++++++++++++
> > >  tools/libxl/libxl_types.idl  |  12 ++++
> > >  tools/libxl/xl.h             |   3 +
> > >  tools/libxl/xl_cmdimpl.c     | 114
> +++++++++++++++++++++++++++++++++++++
> > >  tools/libxl/xl_cmdtable.c    |  18 ++++++
> > >  8 files changed, 332 insertions(+)
> > >
> >
> > What qemu are you using?
> >
> > IIUC the block-snapshot-<operation>-internal-sync commands have not being
> > implemented here.Well they are not synchronized.I can only see
> > block-snapshot-<operation>- ones; no sync
> it is upstream qemu, it maybe takes a long time for discussion and
> reviewing
> the snapshot feature and code. i guess xen will update the qemu before our
> snasphot patch get ack.
>
> regards
>
> bamvor
>
>
>
>

[-- Attachment #1.2: Type: text/html, Size: 2203 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-05-15 10:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-02 11:21 [RFC] tools/libxl: add disk snapshot support Bamvor Jian Zhang
2014-04-03 14:14 ` Ian Jackson
2014-04-07  9:11   ` Bamvor Jian Zhang
2014-05-15  8:38 ` David kiarie
2014-05-15 10:01   ` Bamvor Jian Zhang
2014-05-15 10:35     ` David kiarie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.