[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [RFC] tools/libxl: add disk snapshot support






On Wed, Apr 2, 2014 at 2:21 PM, Bamvor Jian Zhang <bjzhang@xxxxxxxx> wrote:
add internal disk snapshot support through qemu qmp, including create,
delete and list.

Signed-off-by: Bamvor Jian Zhang <bjzhang@xxxxxxxx>
---
Â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@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.