---
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