--- daemon/remote.c | 8 ++++++++ src/access/viraccessperm.c | 3 ++- src/access/viraccessperm.h | 6 ++++++ src/datatypes.c | 36 ++++++++++++++++++++++++++++++++++++ src/datatypes.h | 2 ++ src/remote/remote_driver.c | 7 +++++++ src/remote/remote_protocol.x | 24 +++++++++++++++++++++++- src/rpc/gendispatch.pl | 29 ++++++++++++++++++++++------- 8 files changed, 106 insertions(+), 9 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index e414f92..90cbb01 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -101,6 +101,7 @@ static void make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNod static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src); static void make_nonnull_nwfilter(remote_nonnull_nwfilter *net_dst, virNWFilterPtr nwfilter_src); static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src); +static void make_nonnull_domain_backup(remote_nonnull_domain_backup *backup_dst, virDomainBackupPtr backup_src); static int remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors, @@ -6733,6 +6734,13 @@ make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDo make_nonnull_domain(&snapshot_dst->dom, snapshot_src->domain); } +static void +make_nonnull_domain_backup(remote_nonnull_domain_backup *backup_dst, virDomainBackupPtr backup_src) +{ + ignore_value(VIR_STRDUP_QUIET(backup_dst->name, backup_src->name)); + make_nonnull_domain(&backup_dst->dom, backup_src->domain); +} + static int remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors, int nerrors, diff --git a/src/access/viraccessperm.c b/src/access/viraccessperm.c index 0f58290..16216c0 100644 --- a/src/access/viraccessperm.c +++ b/src/access/viraccessperm.c @@ -43,7 +43,8 @@ VIR_ENUM_IMPL(virAccessPermDomain, "fs_trim", "fs_freeze", "block_read", "block_write", "mem_read", "open_graphics", "open_device", "screenshot", - "open_namespace", "set_time", "set_password"); + "open_namespace", "set_time", "set_password", + "backup"); VIR_ENUM_IMPL(virAccessPermInterface, VIR_ACCESS_PERM_INTERFACE_LAST, diff --git a/src/access/viraccessperm.h b/src/access/viraccessperm.h index 1817da7..06d5184 100644 --- a/src/access/viraccessperm.h +++ b/src/access/viraccessperm.h @@ -306,6 +306,12 @@ typedef enum { */ VIR_ACCESS_PERM_DOMAIN_SET_PASSWORD, + /** + * @desc: Backup domain + * @message: Backing domain up requires authorization + */ + VIR_ACCESS_PERM_DOMAIN_BACKUP, /* Backup domain */ + VIR_ACCESS_PERM_DOMAIN_LAST, } virAccessPermDomain; diff --git a/src/datatypes.c b/src/datatypes.c index b090b12..86dfba3 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -893,6 +893,42 @@ virDomainSnapshotDispose(void *obj) /** + * virGetDomainBackup: + * @domain: the domain to backup + * @name: pointer to the domain backup name + * + * Allocates a new domain backup object. When the object is no longer needed, + * virObjectUnref() must be called in order to not leak data. + * + * Returns a pointer to the domain backup object, or NULL on error. + */ +virDomainBackupPtr +virGetDomainBackup(virDomainPtr domain, const char *name) +{ + virDomainBackupPtr ret = NULL; + + if (virDataTypesInitialize() < 0) + return NULL; + + virCheckDomainGoto(domain, error); + virCheckNonNullArgGoto(name, error); + + if (!(ret = virObjectNew(virDomainBackupClass))) + goto error; + if (VIR_STRDUP(ret->name, name) < 0) + goto error; + + ret->domain = virObjectRef(domain); + + return ret; + + error: + virObjectUnref(ret); + return NULL; +} + + +/** * virDomainBackupDispose: * @obj: the domain backup to release * diff --git a/src/datatypes.h b/src/datatypes.h index 59edda8..577a2a0 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -726,6 +726,8 @@ virNWFilterPtr virGetNWFilter(virConnectPtr conn, const unsigned char *uuid); virDomainSnapshotPtr virGetDomainSnapshot(virDomainPtr domain, const char *name); +virDomainBackupPtr virGetDomainBackup(virDomainPtr domain, + const char *name); virAdmConnectPtr virAdmConnectNew(void); diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index a3cd7cd..357ffc0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -147,6 +147,7 @@ static virStorageVolPtr get_nonnull_storage_vol(virConnectPtr conn, remote_nonnu 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 virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr domain, remote_nonnull_domain_snapshot snapshot); +static virDomainBackupPtr get_nonnull_domain_backup(virDomainPtr dom, remote_nonnull_domain_backup backup); 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); static void make_nonnull_interface(remote_nonnull_interface *interface_dst, virInterfacePtr interface_src); @@ -7865,6 +7866,11 @@ get_nonnull_domain_snapshot(virDomainPtr domain, remote_nonnull_domain_snapshot return virGetDomainSnapshot(domain, snapshot.name); } +static virDomainBackupPtr +get_nonnull_domain_backup(virDomainPtr dom, remote_nonnull_domain_backup backup) +{ + return virGetDomainBackup(dom, backup.name); +} /* Make remote_nonnull_domain and remote_nonnull_network. */ static void @@ -8164,6 +8170,7 @@ static virHypervisorDriver hypervisor_driver = { .domainMigrateStartPostCopy = remoteDomainMigrateStartPostCopy, /* 1.3.3 */ .domainGetGuestVcpus = remoteDomainGetGuestVcpus, /* 2.0.0 */ .domainSetGuestVcpus = remoteDomainSetGuestVcpus, /* 2.0.0 */ + .domainBackupCreateXML = remoteDomainBackupCreateXML, /* 2.5.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index e8382dc..5f58abe 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -312,6 +312,12 @@ struct remote_nonnull_domain_snapshot { remote_nonnull_domain dom; }; +/* A backup which may not be NULL. */ +struct remote_nonnull_domain_backup { + remote_nonnull_string name; + remote_nonnull_domain dom; +}; + /* A domain or network which may be NULL. */ typedef remote_nonnull_domain *remote_domain; typedef remote_nonnull_network *remote_network; @@ -2679,6 +2685,16 @@ struct remote_domain_snapshot_delete_args { unsigned int flags; }; +struct remote_domain_backup_create_xml_args { + remote_nonnull_domain dom; + remote_nonnull_string xml_desc; + unsigned int flags; +}; + +struct remote_domain_backup_create_xml_ret { + remote_nonnull_domain_backup back; +}; + struct remote_domain_open_console_args { remote_nonnull_domain dom; remote_string dev_name; @@ -5934,5 +5950,11 @@ enum remote_procedure { * @generate: both * @acl: none */ - REMOTE_PROC_NODE_DEVICE_EVENT_UPDATE = 377 + REMOTE_PROC_NODE_DEVICE_EVENT_UPDATE = 377, + + /** + * @generate: both + * @acl: domain:backup + */ + REMOTE_PROC_DOMAIN_BACKUP_CREATE_XML = 378 }; diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index 173189c..cd0ca83 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -523,6 +523,19 @@ elsif ($mode eq "server") { push(@free_list, " virObjectUnref(snapshot);\n" . " virObjectUnref(dom);"); + } elsif ($args_member =~ m/^remote_nonnull_domain_backup (\S+);$/) { + push(@vars_list, "virDomainPtr dom = NULL"); + push(@vars_list, "virDomainBackupPtr backup = NULL"); + push(@getters_list, + " if (!(dom = get_nonnull_domain(priv->conn, args->${1}.dom)))\n" . + " goto cleanup;\n" . + "\n" . + " if (!(backup = get_nonnull_domain_backup(dom, args->${1})))\n" . + " goto cleanup;\n"); + push(@args_list, "backup"); + push(@free_list, + " virObjectUnref(backup);\n" . + " virObjectUnref(dom);"); } elsif ($args_member =~ m/^(?:(?:admin|remote)_string|remote_uuid) (\S+)<\S+>;/) { push_privconn(\@args_list); push(@args_list, "args->$1.$1_val"); @@ -665,7 +678,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|node_device|interface|network|storage_vol|storage_pool|domain_snapshot|domain|server|client) (\S+)<(\S+)>;/) { + } elsif ($ret_member =~ m/(?:admin|remote)_nonnull_(secret|nwfilter|node_device|interface|network|storage_vol|storage_pool|domain_snapshot|domain_backup|domain|server|client) (\S+)<(\S+)>;/) { $modern_ret_struct_name = $1; $single_ret_list_error_msg_type = $1; $single_ret_list_name = $2; @@ -723,7 +736,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|domain_snapshot) (\S+);/) { + } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|node_device|secret|nwfilter|domain_snapshot|domain_backup) (\S+);/) { my $type_name = name_to_TypeName($1); if ($call->{ProcName} eq "DomainCreateWithFlags") { @@ -1268,7 +1281,7 @@ 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|domain_snapshot) (\S+);/) { + } elsif ($args_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|interface|secret|nwfilter|domain_snapshot|domain_backup) (\S+);/) { my $name = $1; my $arg_name = $2; my $type_name = name_to_TypeName($name); @@ -1276,6 +1289,8 @@ elsif ($mode eq "client") { if ($is_first_arg) { if ($name eq "domain_snapshot") { $priv_src = "$arg_name->domain->conn"; + } elsif ($name eq "domain_backup") { + $priv_src = "$arg_name->domain->conn"; } else { $priv_src = "$arg_name->conn"; } @@ -1461,7 +1476,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|node_device|interface|network|storage_vol|storage_pool|domain_snapshot|domain|server|client) (\S+)<(\S+)>;/) { + } elsif ($ret_member =~ m/(?:admin|remote)_nonnull_(secret|nwfilter|node_device|interface|network|storage_vol|storage_pool|domain_snapshot|domain_backup|domain|server|client) (\S+)<(\S+)>;/) { my $proc_name = name_to_TypeName($1); if ($structprefix eq "admin") { @@ -1513,7 +1528,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|domain_snapshot) (\S+);/) { + } elsif ($ret_member =~ m/^remote_nonnull_(domain|network|storage_pool|storage_vol|node_device|interface|secret|nwfilter|domain_snapshot|domain_backup) (\S+);/) { my $name = $1; my $arg_name = $2; my $type_name = name_to_TypeName($name); @@ -1527,7 +1542,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_snapshot|domain_backup/) { my $dom = "$priv_src"; $dom =~ s/->conn//; push(@ret_list, "rv = get_nonnull_$name($dom, ret.$arg_name);"); @@ -1863,7 +1878,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_snapshot|domain_backup|client/) { $priv_src =~ s/->conn//; } print " if (result) {\n"; -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list