[libvirt] [PATCH v5 09/20] backup: Implement backup APIs for remote driver

Eric Blake posted 20 patches 6 years, 11 months ago
[libvirt] [PATCH v5 09/20] backup: Implement backup APIs for remote driver
Posted by Eric Blake 6 years, 11 months ago
The remote code generator had to be taught about the new
virDomainCheckpointPtr type, at which point the remote driver
code for backups can be generated.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 src/remote/remote_daemon_dispatch.c |  22 ++-
 src/remote/remote_driver.c          |  33 +++-
 src/remote/remote_protocol.x        | 239 +++++++++++++++++++++++++++-
 src/remote_protocol-structs         | 129 +++++++++++++++
 src/rpc/gendispatch.pl              |  32 ++--
 5 files changed, 435 insertions(+), 20 deletions(-)

diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
index df28259042..5433378539 100644
--- a/src/remote/remote_daemon_dispatch.c
+++ b/src/remote/remote_daemon_dispatch.c
@@ -1,7 +1,7 @@
 /*
  * remote_daemon_dispatch.c: handlers for RPC method calls
  *
- * Copyright (C) 2007-2018 Red Hat, Inc.
+ * Copyright (C) 2007-2019 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -89,6 +89,7 @@ static virStorageVolPtr get_nonnull_storage_vol(virConnectPtr conn, remote_nonnu
 static virSecretPtr get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret);
 static virNWFilterPtr get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
 static virNWFilterBindingPtr get_nonnull_nwfilter_binding(virConnectPtr conn, remote_nonnull_nwfilter_binding binding);
+static virDomainCheckpointPtr get_nonnull_domain_checkpoint(virDomainPtr dom, remote_nonnull_domain_checkpoint checkpoint);
 static virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr dom, remote_nonnull_domain_snapshot snapshot);
 static virNodeDevicePtr get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev);
 static int make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src) ATTRIBUTE_RETURN_CHECK;
@@ -100,6 +101,7 @@ static int make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNode
 static int make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src) ATTRIBUTE_RETURN_CHECK;
 static int make_nonnull_nwfilter(remote_nonnull_nwfilter *net_dst, virNWFilterPtr nwfilter_src) ATTRIBUTE_RETURN_CHECK;
 static int make_nonnull_nwfilter_binding(remote_nonnull_nwfilter_binding *binding_dst, virNWFilterBindingPtr binding_src) ATTRIBUTE_RETURN_CHECK;
+static int make_nonnull_domain_checkpoint(remote_nonnull_domain_checkpoint *checkpoint_dst, virDomainCheckpointPtr checkpoint_src) ATTRIBUTE_RETURN_CHECK;
 static int make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src) ATTRIBUTE_RETURN_CHECK;

 static int
@@ -7238,6 +7240,12 @@ get_nonnull_nwfilter_binding(virConnectPtr conn, remote_nonnull_nwfilter_binding
     return virGetNWFilterBinding(conn, binding.portdev, binding.filtername);
 }

+static virDomainCheckpointPtr
+get_nonnull_domain_checkpoint(virDomainPtr dom, remote_nonnull_domain_checkpoint checkpoint)
+{
+    return virGetDomainCheckpoint(dom, checkpoint.name);
+}
+
 static virDomainSnapshotPtr
 get_nonnull_domain_snapshot(virDomainPtr dom, remote_nonnull_domain_snapshot snapshot)
 {
@@ -7348,6 +7356,18 @@ make_nonnull_nwfilter_binding(remote_nonnull_nwfilter_binding *binding_dst, virN
     return 0;
 }

+static int
+make_nonnull_domain_checkpoint(remote_nonnull_domain_checkpoint *checkpoint_dst, virDomainCheckpointPtr checkpoint_src)
+{
+    if (VIR_STRDUP_QUIET(checkpoint_dst->name, checkpoint_src->name) < 0)
+        return -1;
+    if (make_nonnull_domain(&checkpoint_dst->dom, checkpoint_src->domain) < 0) {
+        VIR_FREE(checkpoint_dst->name);
+        return -1;
+    }
+    return 0;
+}
+
 static int
 make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src)
 {
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index eabe7a3823..44428073d9 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -2,7 +2,7 @@
  * remote_driver.c: driver to provide access to libvirtd running
  *   on a remote machine
  *
- * Copyright (C) 2007-2015 Red Hat, Inc.
+ * Copyright (C) 2007-2019 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -145,6 +145,7 @@ static virStoragePoolPtr get_nonnull_storage_pool(virConnectPtr conn, remote_non
 static virStorageVolPtr get_nonnull_storage_vol(virConnectPtr conn, remote_nonnull_storage_vol vol);
 static virNodeDevicePtr get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev);
 static virSecretPtr get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret);
+static virDomainCheckpointPtr get_nonnull_domain_checkpoint(virDomainPtr domain, remote_nonnull_domain_checkpoint checkpoint);
 static virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr domain, remote_nonnull_domain_snapshot snapshot);
 static void make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
 static void make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr net_src);
@@ -156,6 +157,7 @@ make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNodeDevicePtr d
 static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
 static void make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src);
 static void make_nonnull_nwfilter_binding(remote_nonnull_nwfilter_binding *binding_dst, virNWFilterBindingPtr binding_src);
+static void make_nonnull_domain_checkpoint(remote_nonnull_domain_checkpoint *checkpoint_dst, virDomainCheckpointPtr checkpoint_src);
 static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);

 /*----------------------------------------------------------------------*/
@@ -8193,6 +8195,12 @@ get_nonnull_nwfilter_binding(virConnectPtr conn, remote_nonnull_nwfilter_binding
     return virGetNWFilterBinding(conn, binding.portdev, binding.filtername);
 }

+static virDomainCheckpointPtr
+get_nonnull_domain_checkpoint(virDomainPtr domain, remote_nonnull_domain_checkpoint checkpoint)
+{
+    return virGetDomainCheckpoint(domain, checkpoint.name);
+}
+
 static virDomainSnapshotPtr
 get_nonnull_domain_snapshot(virDomainPtr domain, remote_nonnull_domain_snapshot snapshot)
 {
@@ -8267,6 +8275,13 @@ make_nonnull_nwfilter_binding(remote_nonnull_nwfilter_binding *binding_dst, virN
     binding_dst->filtername = binding_src->filtername;
 }

+static void
+make_nonnull_domain_checkpoint(remote_nonnull_domain_checkpoint *checkpoint_dst, virDomainCheckpointPtr checkpoint_src)
+{
+    checkpoint_dst->name = checkpoint_src->name;
+    make_nonnull_domain(&checkpoint_dst->dom, checkpoint_src->domain);
+}
+
 static void
 make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src)
 {
@@ -8516,7 +8531,21 @@ static virHypervisorDriver hypervisor_driver = {
     .connectCompareHypervisorCPU = remoteConnectCompareHypervisorCPU, /* 4.4.0 */
     .connectBaselineHypervisorCPU = remoteConnectBaselineHypervisorCPU, /* 4.4.0 */
     .nodeGetSEVInfo = remoteNodeGetSEVInfo, /* 4.5.0 */
-    .domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo /* 4.5.0 */
+    .domainGetLaunchSecurityInfo = remoteDomainGetLaunchSecurityInfo, /* 4.5.0 */
+    .domainCheckpointCreateXML = remoteDomainCheckpointCreateXML, /* 5.2.0 */
+    .domainCheckpointGetXMLDesc = remoteDomainCheckpointGetXMLDesc, /* 5.2.0 */
+    .domainListCheckpoints = remoteDomainListCheckpoints, /* 5.2.0 */
+    .domainCheckpointListChildren = remoteDomainCheckpointListChildren, /* 5.2.0 */
+    .domainCheckpointLookupByName = remoteDomainCheckpointLookupByName, /* 5.2.0 */
+    .domainHasCurrentCheckpoint = remoteDomainHasCurrentCheckpoint, /* 5.2.0 */
+    .domainCheckpointGetParent = remoteDomainCheckpointGetParent, /* 5.2.0 */
+    .domainCheckpointCurrent = remoteDomainCheckpointCurrent, /* 5.2.0 */
+    .domainCheckpointIsCurrent = remoteDomainCheckpointIsCurrent, /* 5.2.0 */
+    .domainCheckpointHasMetadata = remoteDomainCheckpointHasMetadata, /* 5.2.0 */
+    .domainCheckpointDelete = remoteDomainCheckpointDelete, /* 5.2.0 */
+    .domainBackupBegin = remoteDomainBackupBegin, /* 5.2.0 */
+    .domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 5.2.0 */
+    .domainBackupEnd = remoteDomainBackupEnd, /* 5.2.0 */
 };

 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 74be4b37d0..ca03460756 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3,7 +3,7 @@
  *   remote_internal driver and libvirtd.  This protocol is
  *   internal and may change at any time.
  *
- * Copyright (C) 2006-2015 Red Hat, Inc.
+ * Copyright (C) 2006-2019 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -137,6 +137,9 @@ const REMOTE_AUTH_TYPE_LIST_MAX = 20;
 /* Upper limit on list of memory stats */
 const REMOTE_DOMAIN_MEMORY_STATS_MAX = 1024;

+/* Upper limit on lists of domain checkpoints. */
+const REMOTE_DOMAIN_CHECKPOINT_LIST_MAX = 16384;
+
 /* Upper limit on lists of domain snapshots. */
 const REMOTE_DOMAIN_SNAPSHOT_LIST_MAX = 16384;

@@ -322,6 +325,12 @@ struct remote_nonnull_secret {
     remote_nonnull_string usageID;
 };

+/* A checkpoint which may not be NULL. */
+struct remote_nonnull_domain_checkpoint {
+    remote_nonnull_string name;
+    remote_nonnull_domain dom;
+};
+
 /* A snapshot which may not be NULL. */
 struct remote_nonnull_domain_snapshot {
     remote_nonnull_string name;
@@ -3564,6 +3573,137 @@ struct remote_connect_list_all_nwfilter_bindings_ret { /* insert@1 */
     remote_nonnull_nwfilter_binding bindings<REMOTE_NWFILTER_BINDING_LIST_MAX>;
     unsigned int ret;
 };
+struct remote_domain_checkpoint_create_xml_args {
+    remote_nonnull_domain dom;
+    remote_nonnull_string xml_desc;
+    unsigned int flags;
+};
+
+struct remote_domain_checkpoint_create_xml_ret {
+    remote_nonnull_domain_checkpoint checkpoint;
+};
+
+struct remote_domain_checkpoint_get_xml_desc_args {
+    remote_nonnull_domain_checkpoint checkpoint;
+    unsigned int flags;
+};
+
+struct remote_domain_checkpoint_get_xml_desc_ret {
+    remote_nonnull_string xml;
+};
+
+struct remote_domain_list_checkpoints_args {
+    remote_nonnull_domain dom;
+    int need_results;
+    unsigned int flags;
+};
+
+struct remote_domain_list_checkpoints_ret { /* insert@1 */
+    remote_nonnull_domain_checkpoint checkpoints<REMOTE_DOMAIN_CHECKPOINT_LIST_MAX>;
+    int ret;
+};
+
+struct remote_domain_checkpoint_list_children_args {
+    remote_nonnull_domain_checkpoint checkpoint;
+    int need_results;
+    unsigned int flags;
+};
+
+struct remote_domain_checkpoint_list_children_ret { /* insert@1 */
+    remote_nonnull_domain_checkpoint checkpoints<REMOTE_DOMAIN_CHECKPOINT_LIST_MAX>;
+    int ret;
+};
+
+struct remote_domain_checkpoint_lookup_by_name_args {
+    remote_nonnull_domain dom;
+    remote_nonnull_string name;
+    unsigned int flags;
+};
+
+struct remote_domain_checkpoint_lookup_by_name_ret {
+    remote_nonnull_domain_checkpoint checkpoint;
+};
+
+struct remote_domain_has_current_checkpoint_args {
+    remote_nonnull_domain dom;
+    unsigned int flags;
+};
+
+struct remote_domain_has_current_checkpoint_ret {
+    int result;
+};
+
+struct remote_domain_checkpoint_get_parent_args {
+    remote_nonnull_domain_checkpoint checkpoint;
+    unsigned int flags;
+};
+
+struct remote_domain_checkpoint_get_parent_ret {
+    remote_nonnull_domain_checkpoint parent;
+};
+
+struct remote_domain_checkpoint_current_args {
+    remote_nonnull_domain dom;
+    unsigned int flags;
+};
+
+struct remote_domain_checkpoint_current_ret {
+    remote_nonnull_domain_checkpoint checkpoint;
+};
+
+struct remote_domain_checkpoint_is_current_args {
+    remote_nonnull_domain_checkpoint checkpoint;
+    unsigned int flags;
+};
+
+struct remote_domain_checkpoint_is_current_ret {
+    int current;
+};
+
+struct remote_domain_checkpoint_has_metadata_args {
+    remote_nonnull_domain_checkpoint checkpoint;
+    unsigned int flags;
+};
+
+struct remote_domain_checkpoint_has_metadata_ret {
+    int metadata;
+};
+
+struct remote_domain_checkpoint_delete_args {
+    remote_nonnull_domain_checkpoint checkpoint;
+    unsigned int flags;
+};
+
+struct remote_domain_backup_begin_args {
+    remote_nonnull_domain dom;
+    remote_string disk_xml;
+    remote_string checkpoint_xml;
+    unsigned int flags;
+};
+
+struct remote_domain_backup_begin_ret {
+    int result;
+};
+
+struct remote_domain_backup_get_xml_desc_args {
+    remote_nonnull_domain dom;
+    int id;
+    unsigned int flags;
+};
+
+struct remote_domain_backup_get_xml_desc_ret {
+    remote_nonnull_string xml;
+};
+
+struct remote_domain_backup_end_args {
+    remote_nonnull_domain dom;
+    int id;
+    unsigned int flags;
+};
+
+struct remote_domain_backup_end_ret {
+    int retcode;
+};

 struct remote_connect_get_storage_pool_capabilities_args {
     unsigned int flags;
@@ -6342,5 +6482,100 @@ enum remote_procedure {
      * @generate: both
      * @acl: connect:read
      */
-    REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES = 403
+    REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES = 403,
+
+   /**
+     * @generate: both
+     * @acl: domain:checkpoint
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_CREATE_XML = 404,
+
+    /**
+     * @generate: both
+     * @acl: domain:read
+     * @acl: domain:read_secure:VIR_DOMAIN_CHECKPOINT_XML_SECURE
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_GET_XML_DESC = 405,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_LIST_CHECKPOINTS = 406,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_LIST_CHILDREN = 407,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_LOOKUP_BY_NAME = 408,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_HAS_CURRENT_CHECKPOINT = 409,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_CURRENT = 410,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_GET_PARENT = 411,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_IS_CURRENT = 412,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_HAS_METADATA = 413,
+
+    /**
+     * @generate: both
+     * @acl: domain:checkpoint
+     */
+    REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 414,
+
+    /**
+     * @generate: both
+     * @acl: domain:checkpoint
+     * @acl: domain:block_read
+     */
+    REMOTE_PROC_DOMAIN_BACKUP_BEGIN = 415,
+
+    /**
+     * @generate: both
+     * @priority: high
+     * @acl: domain:read
+     */
+    REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 416,
+
+    /**
+     * @generate: both
+     * @acl: domain:checkpoint
+     */
+    REMOTE_PROC_DOMAIN_BACKUP_END = 417
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 768189c573..70f560c1b1 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -46,6 +46,10 @@ struct remote_nonnull_secret {
         int                        usageType;
         remote_nonnull_string      usageID;
 };
+struct remote_nonnull_domain_checkpoint {
+        remote_nonnull_string      name;
+        remote_nonnull_domain      dom;
+};
 struct remote_nonnull_domain_snapshot {
         remote_nonnull_string      name;
         remote_nonnull_domain      dom;
@@ -2981,6 +2985,117 @@ struct remote_connect_get_storage_pool_capabilities_args {
 struct remote_connect_get_storage_pool_capabilities_ret {
         remote_nonnull_string      capabilities;
 };
+struct remote_domain_checkpoint_create_xml_args {
+        remote_nonnull_domain      dom;
+        remote_nonnull_string      xml_desc;
+        u_int                      flags;
+};
+struct remote_domain_checkpoint_create_xml_ret {
+        remote_nonnull_domain_checkpoint checkpoint;
+};
+struct remote_domain_checkpoint_get_xml_desc_args {
+        remote_nonnull_domain_checkpoint checkpoint;
+        u_int                      flags;
+};
+struct remote_domain_checkpoint_get_xml_desc_ret {
+        remote_nonnull_string      xml;
+};
+struct remote_domain_list_checkpoints_args {
+        remote_nonnull_domain      dom;
+        int                        need_results;
+        u_int                      flags;
+};
+struct remote_domain_list_checkpoints_ret {
+        struct {
+                u_int              checkpoints_len;
+                remote_nonnull_domain_checkpoint * checkpoints_val;
+        } checkpoints;
+        int                        ret;
+};
+struct remote_domain_checkpoint_list_children_args {
+        remote_nonnull_domain_checkpoint checkpoint;
+        int                        need_results;
+        u_int                      flags;
+};
+struct remote_domain_checkpoint_list_children_ret {
+        struct {
+                u_int              checkpoints_len;
+                remote_nonnull_domain_checkpoint * checkpoints_val;
+        } checkpoints;
+        int                        ret;
+};
+struct remote_domain_checkpoint_lookup_by_name_args {
+        remote_nonnull_domain      dom;
+        remote_nonnull_string      name;
+        u_int                      flags;
+};
+struct remote_domain_checkpoint_lookup_by_name_ret {
+        remote_nonnull_domain_checkpoint checkpoint;
+};
+struct remote_domain_has_current_checkpoint_args {
+        remote_nonnull_domain      dom;
+        u_int                      flags;
+};
+struct remote_domain_has_current_checkpoint_ret {
+        int                        result;
+};
+struct remote_domain_checkpoint_get_parent_args {
+        remote_nonnull_domain_checkpoint checkpoint;
+        u_int                      flags;
+};
+struct remote_domain_checkpoint_get_parent_ret {
+        remote_nonnull_domain_checkpoint parent;
+};
+struct remote_domain_checkpoint_current_args {
+        remote_nonnull_domain      dom;
+        u_int                      flags;
+};
+struct remote_domain_checkpoint_current_ret {
+        remote_nonnull_domain_checkpoint checkpoint;
+};
+struct remote_domain_checkpoint_is_current_args {
+        remote_nonnull_domain_checkpoint checkpoint;
+        u_int                      flags;
+};
+struct remote_domain_checkpoint_is_current_ret {
+        int                        current;
+};
+struct remote_domain_checkpoint_has_metadata_args {
+        remote_nonnull_domain_checkpoint checkpoint;
+        u_int                      flags;
+};
+struct remote_domain_checkpoint_has_metadata_ret {
+        int                        metadata;
+};
+struct remote_domain_checkpoint_delete_args {
+        remote_nonnull_domain_checkpoint checkpoint;
+        u_int                      flags;
+};
+struct remote_domain_backup_begin_args {
+        remote_nonnull_domain      dom;
+        remote_string              disk_xml;
+        remote_string              checkpoint_xml;
+        u_int                      flags;
+};
+struct remote_domain_backup_begin_ret {
+        int                        result;
+};
+struct remote_domain_backup_get_xml_desc_args {
+        remote_nonnull_domain      dom;
+        int                        id;
+        u_int                      flags;
+};
+struct remote_domain_backup_get_xml_desc_ret {
+        remote_nonnull_string      xml;
+};
+struct remote_domain_backup_end_args {
+        remote_nonnull_domain      dom;
+        int                        id;
+        u_int                      flags;
+};
+struct remote_domain_backup_end_ret {
+        int                        retcode;
+};
 enum remote_procedure {
         REMOTE_PROC_CONNECT_OPEN = 1,
         REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3385,4 +3500,18 @@ enum remote_procedure {
         REMOTE_PROC_CONNECT_LIST_ALL_NWFILTER_BINDINGS = 401,
         REMOTE_PROC_DOMAIN_SET_IOTHREAD_PARAMS = 402,
         REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES = 403,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_CREATE_XML = 404,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_GET_XML_DESC = 405,
+        REMOTE_PROC_DOMAIN_LIST_CHECKPOINTS = 406,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_LIST_CHILDREN = 407,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_LOOKUP_BY_NAME = 408,
+        REMOTE_PROC_DOMAIN_HAS_CURRENT_CHECKPOINT = 409,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_CURRENT = 410,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_GET_PARENT = 411,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_IS_CURRENT = 412,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_HAS_METADATA = 413,
+        REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 414,
+        REMOTE_PROC_DOMAIN_BACKUP_BEGIN = 415,
+        REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 416,
+        REMOTE_PROC_DOMAIN_BACKUP_END = 417,
 };
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
index ae3a42c4c1..1d20a7f277 100755
--- a/src/rpc/gendispatch.pl
+++ b/src/rpc/gendispatch.pl
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 #
-# Copyright (C) 2010-2015 Red Hat, Inc.
+# Copyright (C) 2010-2018 Red Hat, Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -567,18 +567,20 @@ elsif ($mode eq "server") {
                     push(@args_list, "$2");
                     push(@free_list,
                          "    virObjectUnref($2);");
-                } elsif ($args_member =~ m/^remote_nonnull_domain_snapshot (\S+);$/) {
+                } elsif ($args_member =~ m/^remote_nonnull_domain_(checkpoint|snapshot) (\S+);$/) {
+                    my $type_name = name_to_TypeName($1);
+
                     push(@vars_list, "virDomainPtr dom = NULL");
-                    push(@vars_list, "virDomainSnapshotPtr snapshot = NULL");
+                    push(@vars_list, "virDomain${type_name}Ptr ${1} = NULL");
                     push(@getters_list,
-                         "    if (!(dom = get_nonnull_domain($conn, args->${1}.dom)))\n" .
+                         "    if (!(dom = get_nonnull_domain($conn, args->${2}.dom)))\n" .
                          "        goto cleanup;\n" .
                          "\n" .
-                         "    if (!(snapshot = get_nonnull_domain_snapshot(dom, args->${1})))\n" .
+                         "    if (!($1 = get_nonnull_domain_${1}(dom, args->$2)))\n" .
                          "        goto cleanup;\n");
-                    push(@args_list, "snapshot");
+                    push(@args_list, "$1");
                     push(@free_list,
-                         "    virObjectUnref(snapshot);\n" .
+                         "    virObjectUnref($1);\n" .
                          "    virObjectUnref(dom);");
                 } elsif ($args_member =~ m/^(?:(?:admin|remote)_string|remote_uuid) (\S+)<\S+>;/) {
                     push(@args_list, $conn) if !@args_list;
@@ -722,7 +724,7 @@ elsif ($mode eq "server") {
                         if (!$modern_ret_as_list) {
                             push(@ret_list, "ret->$3 = tmp.$3;");
                         }
-                    } elsif ($ret_member =~ m/(?:admin|remote)_nonnull_(secret|nwfilter|nwfilter_binding|node_device|interface|network|storage_vol|storage_pool|domain_snapshot|domain|server|client) (\S+)<(\S+)>;/) {
+                    } elsif ($ret_member =~ m/(?:admin|remote)_nonnull_(secret|nwfilter|nwfilter_binding|node_device|interface|network|storage_vol|storage_pool|domain_checkpoint|domain_snapshot|domain|server|client) (\S+)<(\S+)>;/) {
                         $modern_ret_struct_name = $1;
                         $single_ret_list_error_msg_type = $1;
                         $single_ret_list_name = $2;
@@ -780,7 +782,7 @@ elsif ($mode eq "server") {
                     $single_ret_var = $1;
                     $single_ret_by_ref = 0;
                     $single_ret_check = " == NULL";
-                } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|node_device|secret|nwfilter|nwfilter_binding|domain_snapshot) (\S+);/) {
+                } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|node_device|secret|nwfilter|nwfilter_binding|domain_checkpoint|domain_snapshot) (\S+);/) {
                     my $type_name = name_to_TypeName($1);

                     if ($call->{ProcName} eq "DomainCreateWithFlags") {
@@ -1328,13 +1330,13 @@ elsif ($mode eq "client") {
                     $priv_src = "dev->conn";
                     push(@args_list, "virNodeDevicePtr dev");
                     push(@setters_list, "args.name = dev->name;");
-                } elsif ($args_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|secret|nwfilter|nwfilter_binding|domain_snapshot) (\S+);/) {
+                } elsif ($args_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|secret|nwfilter|nwfilter_binding|domain_checkpoint|domain_snapshot) (\S+);/) {
                     my $name = $1;
                     my $arg_name = $2;
                     my $type_name = name_to_TypeName($name);

                     if ($is_first_arg) {
-                        if ($name eq "domain_snapshot") {
+                        if ($name =~ m/^domain_.*/) {
                             $priv_src = "$arg_name->domain->conn";
                         } else {
                             $priv_src = "$arg_name->conn";
@@ -1521,7 +1523,7 @@ elsif ($mode eq "client") {
                         }

                         push(@ret_list, "memcpy(result->$3, ret.$3, sizeof(result->$3));");
-                    } elsif ($ret_member =~ m/(?:admin|remote)_nonnull_(secret|nwfilter|nwfilter_binding|node_device|interface|network|storage_vol|storage_pool|domain_snapshot|domain|server|client) (\S+)<(\S+)>;/) {
+                    } elsif ($ret_member =~ m/(?:admin|remote)_nonnull_(secret|nwfilter|nwfilter_binding|node_device|interface|network|storage_vol|storage_pool|domain_checkpoint|domain_snapshot|domain|server|client) (\S+)<(\S+)>;/) {
                         my $proc_name = name_to_TypeName($1);

                         if ($structprefix eq "admin") {
@@ -1574,7 +1576,7 @@ elsif ($mode eq "client") {
                     push(@ret_list, "VIR_FREE(ret.$1);");
                     $single_ret_var = "char *rv = NULL";
                     $single_ret_type = "char *";
-                } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|node_device|interface|secret|nwfilter|nwfilter_binding|domain_snapshot) (\S+);/) {
+                } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|node_device|interface|secret|nwfilter|nwfilter_binding|domain_checkpoint|domain_snapshot) (\S+);/) {
                     my $name = $1;
                     my $arg_name = $2;
                     my $type_name = name_to_TypeName($name);
@@ -1588,7 +1590,7 @@ elsif ($mode eq "client") {
                         $single_ret_var = "int rv = -1";
                         $single_ret_type = "int";
                     } else {
-                        if ($name eq "domain_snapshot") {
+                        if ($name =~ m/^domain_.*/) {
                             my $dom = "$priv_src";
                             $dom =~ s/->conn//;
                             push(@ret_list, "rv = get_nonnull_$name($dom, ret.$arg_name);");
@@ -1932,7 +1934,7 @@ elsif ($mode eq "client") {
             print "    }\n";
             print "\n";
         } elsif ($modern_ret_as_list) {
-            if ($modern_ret_struct_name =~ m/domain_snapshot|client/) {
+            if ($modern_ret_struct_name =~ m/domain_checkpoint|domain_snapshot|client/) {
                 $priv_src =~ s/->conn//;
             }
             print "    if (result) {\n";
-- 
2.20.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v5 09/20] backup: Implement backup APIs for remote driver
Posted by Eric Blake 6 years, 10 months ago
On 3/6/19 11:47 PM, Eric Blake wrote:
> The remote code generator had to be taught about the new
> virDomainCheckpointPtr type, at which point the remote driver
> code for backups can be generated.
> 
> Signed-off-by: Eric Blake <eblake@redhat.com>
> ---

Question for Dan:

> +   /**
> +     * @generate: both
> +     * @acl: domain:checkpoint
> +     */
> +    REMOTE_PROC_DOMAIN_CHECKPOINT_CREATE_XML = 404,

Patch 8/20 created a new domain:checkpoint access category, which works
well here...


> +
> +    /**
> +     * @generate: both
> +     * @acl: domain:checkpoint
> +     * @acl: domain:block_read

This one should be block_write, not block_read, because it is copying
out guest data (which could be a security consideration); basically, the
same as virDomainBlockCopy.

> +     */
> +    REMOTE_PROC_DOMAIN_BACKUP_BEGIN = 415,

...my question is whether it is possible to make the domain:checkpoint
permission be conditional on whether the checkpointXml argument was
supplied. It's unlikely that someone with domain:block_write to copy
disks won't also have domain:checkpoint, but if they aren't creating a
checkpoint, it would be nicer to not require that access right.  Is the
only way to do that by having libvirt declare a flag which gets set any
time checkpointXml is non-NULL, so that we can then do
domain:checkpoint:FLAG_NAME? (This would be an unusual case where
libvirt would set the flag on the user's behalf, and where the flag
exists more for the ACL checking than for something inherent to what the
user has to tell the driver).  The same question applies to my proposed
virDomainSnapshotCreateXML2 (there, it would be domain:snapshot instead
of domain:block_write as the unconditional permission, but a conditional
permission on domain:checkpoint when checkpointXml is non-NULL would be
nice to figure out).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list