* [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.