From cfe09209063705ebcd3f8734f3553788a5954c73 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 6 Mar 2019 11:54:47 -0600 Subject: [PATCH] backup: Implement checkpoint APIs for remote driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The remote code generator had to be taught about the new virDomainCheckpointPtr type, at which point the remote driver code for checkpoints can be generated. Signed-off-by: Eric Blake Reviewed-by: Daniel P. Berrangé --- src/remote/remote_daemon_dispatch.c | 20 +++++ src/remote/remote_driver.c | 24 +++++- src/remote/remote_protocol.x | 123 +++++++++++++++++++++++++++- src/remote_protocol-structs | 69 ++++++++++++++++ src/rpc/gendispatch.pl | 32 ++++---- 5 files changed, 252 insertions(+), 16 deletions(-) diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 856c5e48e7..444c03a644 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -90,6 +90,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; @@ -102,6 +103,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 @@ -7301,6 +7303,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) { @@ -7421,6 +7429,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(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 925ada1cac..72c2336b7a 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -146,6 +146,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); @@ -158,6 +159,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); /*----------------------------------------------------------------------*/ @@ -8242,6 +8244,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) { @@ -8324,6 +8332,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) { @@ -8573,7 +8588,14 @@ 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.6.0 */ + .domainCheckpointGetXMLDesc = remoteDomainCheckpointGetXMLDesc, /* 5.6.0 */ + .domainListAllCheckpoints = remoteDomainListAllCheckpoints, /* 5.6.0 */ + .domainCheckpointListAllChildren = remoteDomainCheckpointListAllChildren, /* 5.6.0 */ + .domainCheckpointLookupByName = remoteDomainCheckpointLookupByName, /* 5.6.0 */ + .domainCheckpointGetParent = remoteDomainCheckpointGetParent, /* 5.6.0 */ + .domainCheckpointDelete = remoteDomainCheckpointDelete, /* 5.6.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 2e45b5cef0..2f91bd1921 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -140,6 +140,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; @@ -336,6 +339,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; @@ -3649,6 +3658,70 @@ struct remote_network_port_delete_args { unsigned int flags; }; +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_all_checkpoints_args { + remote_nonnull_domain dom; + int need_results; + unsigned int flags; +}; + +struct remote_domain_list_all_checkpoints_ret { /* insert@1 */ + remote_nonnull_domain_checkpoint checkpoints; + int ret; +}; + +struct remote_domain_checkpoint_list_all_children_args { + remote_nonnull_domain_checkpoint checkpoint; + int need_results; + unsigned int flags; +}; + +struct remote_domain_checkpoint_list_all_children_ret { /* insert@1 */ + remote_nonnull_domain_checkpoint checkpoints; + 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_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_delete_args { + remote_nonnull_domain_checkpoint checkpoint; + unsigned int flags; +}; /*----- Protocol. -----*/ @@ -6463,5 +6536,53 @@ enum remote_procedure { * @generate: both * @acl: network_port:delete */ - REMOTE_PROC_NETWORK_PORT_DELETE = 410 + REMOTE_PROC_NETWORK_PORT_DELETE = 410, + + /** + * @generate: both + * @acl: domain:checkpoint + * @acl: domain:fs_freeze:VIR_DOMAIN_CHECKPOINT_CREATE_QUIESCE + */ + REMOTE_PROC_DOMAIN_CHECKPOINT_CREATE_XML = 411, + + /** + * @generate: both + * @acl: domain:read + * @acl: domain:read_secure:VIR_DOMAIN_CHECKPOINT_XML_SECURE + */ + REMOTE_PROC_DOMAIN_CHECKPOINT_GET_XML_DESC = 412, + + /** + * @generate: both + * @priority: high + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_LIST_ALL_CHECKPOINTS = 413, + + /** + * @generate: both + * @priority: high + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_CHECKPOINT_LIST_ALL_CHILDREN = 414, + + /** + * @generate: both + * @priority: high + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_CHECKPOINT_LOOKUP_BY_NAME = 415, + + /** + * @generate: both + * @priority: high + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_CHECKPOINT_GET_PARENT = 416, + + /** + * @generate: both + * @acl: domain:checkpoint + */ + REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 2398494520..a42b4a9671 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -50,6 +50,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; @@ -3043,6 +3047,64 @@ struct remote_network_port_delete_args { remote_nonnull_network_port port; u_int flags; }; +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_all_checkpoints_args { + remote_nonnull_domain dom; + int need_results; + u_int flags; +}; +struct remote_domain_list_all_checkpoints_ret { + struct { + u_int checkpoints_len; + remote_nonnull_domain_checkpoint * checkpoints_val; + } checkpoints; + int ret; +}; +struct remote_domain_checkpoint_list_all_children_args { + remote_nonnull_domain_checkpoint checkpoint; + int need_results; + u_int flags; +}; +struct remote_domain_checkpoint_list_all_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_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_delete_args { + remote_nonnull_domain_checkpoint checkpoint; + u_int flags; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN = 1, REMOTE_PROC_CONNECT_CLOSE = 2, @@ -3454,4 +3516,11 @@ enum remote_procedure { REMOTE_PROC_NETWORK_PORT_SET_PARAMETERS = 408, REMOTE_PROC_NETWORK_PORT_GET_XML_DESC = 409, REMOTE_PROC_NETWORK_PORT_DELETE = 410, + REMOTE_PROC_DOMAIN_CHECKPOINT_CREATE_XML = 411, + REMOTE_PROC_DOMAIN_CHECKPOINT_GET_XML_DESC = 412, + REMOTE_PROC_DOMAIN_LIST_ALL_CHECKPOINTS = 413, + REMOTE_PROC_DOMAIN_CHECKPOINT_LIST_ALL_CHILDREN = 414, + REMOTE_PROC_DOMAIN_CHECKPOINT_LOOKUP_BY_NAME = 415, + REMOTE_PROC_DOMAIN_CHECKPOINT_GET_PARENT = 416, + REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE = 417, }; diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index f683e711ce..4e548e14cd 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -58,6 +58,7 @@ sub fixup_name { $name =~ s/Nwfilter/NWFilter/; $name =~ s/Xml$/XML/; + $name =~ s/Xml2$/XML2/; $name =~ s/Uri$/URI/; $name =~ s/Uuid$/UUID/; $name =~ s/Id$/ID/; @@ -567,18 +568,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 +725,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|network_port|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|network_port|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 +783,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|network_port|storage_pool|storage_vol|interface|node_device|secret|nwfilter|nwfilter_binding|domain_snapshot) (\S+);/) { + } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|network_port|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 +1331,14 @@ 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|network_port|storage_pool|storage_vol|interface|secret|nwfilter|nwfilter_binding|domain_snapshot) (\S+);/) { + } elsif ($args_member =~ m/^remote_nonnull_(domain|network|network_port|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 eq "domain_snapshot" || + $name eq "domain_checkpoint") { $priv_src = "$arg_name->domain->conn"; } elsif ($name eq "network_port") { $priv_src = "$arg_name->net->conn"; @@ -1523,7 +1527,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|network_port|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|network_port|storage_vol|storage_pool|domain_checkpoint|domain_snapshot|domain|server|client) (\S+)<(\S+)>;/) { my $proc_name = name_to_TypeName($1); if ($structprefix eq "admin") { @@ -1576,7 +1580,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|network_port|storage_pool|storage_vol|node_device|interface|secret|nwfilter|nwfilter_binding|domain_snapshot) (\S+);/) { + } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|network_port|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); @@ -1590,7 +1594,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);"); @@ -1934,7 +1938,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"; -- GitLab