From nobody Mon Dec 15 01:41:48 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1494599001132798.7102432012496; Fri, 12 May 2017 07:23:21 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id ADFAF65747; Fri, 12 May 2017 14:23:19 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 889758EE4A; Fri, 12 May 2017 14:23:19 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9C3A75EC6C; Fri, 12 May 2017 14:23:18 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v4CENCuu021155 for ; Fri, 12 May 2017 10:23:12 -0400 Received: by smtp.corp.redhat.com (Postfix) id 526AA8B171; Fri, 12 May 2017 14:23:12 +0000 (UTC) Received: from mx1.redhat.com (ext-mx05.extmail.prod.ext.phx2.redhat.com [10.5.110.29]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4BF247DB54 for ; Fri, 12 May 2017 14:23:12 +0000 (UTC) Received: from relay.sw.ru (mailhub.sw.ru [195.214.232.25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7135E448D94 for ; Fri, 12 May 2017 14:23:09 +0000 (UTC) Received: from dim-vz7.qa.sw.ru (msk-vpn.virtuozzo.com [195.214.232.6]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id v4CDbfTZ007950; Fri, 12 May 2017 16:37:41 +0300 (MSK) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com ADFAF65747 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com ADFAF65747 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 7135E448D94 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=pass (p=none dis=none) header.from=virtuozzo.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=nshirokovskiy@virtuozzo.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 7135E448D94 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Fri, 12 May 2017 16:37:18 +0300 Message-Id: <1494596248-446694-3-git-send-email-nshirokovskiy@virtuozzo.com> In-Reply-To: <1494596248-446694-1-git-send-email-nshirokovskiy@virtuozzo.com> References: <1494596248-446694-1-git-send-email-nshirokovskiy@virtuozzo.com> X-Greylist: Delayed for 00:44:58 by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 12 May 2017 14:23:10 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 12 May 2017 14:23:10 +0000 (UTC) for IP:'195.214.232.25' DOMAIN:'mailhub.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: 0.799 (BAYES_50, SPF_PASS) 195.214.232.25 mailhub.sw.ru 195.214.232.25 mailhub.sw.ru X-Scanned-By: MIMEDefang 2.78 on 10.5.110.29 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Cc: Dmitry Mishin Subject: [libvirt] [PATCH v2 RFC 02/12] api: backup: add driver based implementation X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 12 May 2017 14:23:20 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" --- include/libvirt/virterror.h | 2 + src/Makefile.am | 2 + src/datatypes.c | 60 +++++++++++++ src/datatypes.h | 29 ++++++ src/driver-hypervisor.h | 5 ++ src/libvirt-domain-backup.c | 209 ++++++++++++++++++++++++++++++++++++++++= ++++ src/libvirt_private.syms | 2 + src/libvirt_public.syms | 10 +++ src/util/virerror.c | 6 ++ 9 files changed, 325 insertions(+) create mode 100644 src/libvirt-domain-backup.c diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index 2efee8f..c9ae10e 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -132,6 +132,7 @@ typedef enum { =20 VIR_FROM_PERF =3D 65, /* Error from perf */ VIR_FROM_LIBSSH =3D 66, /* Error from libssh connection transpor= t */ + VIR_FROM_DOMAIN_BACKUP =3D 67,/* Error from domain backup */ =20 # ifdef VIR_ENUM_SENTINELS VIR_ERR_DOMAIN_LAST @@ -319,6 +320,7 @@ typedef enum { VIR_ERR_AGENT_UNSYNCED =3D 97, /* guest agent replies with wron= g id to guest-sync command */ VIR_ERR_LIBSSH =3D 98, /* error in libssh transport dri= ver */ + VIR_ERR_INVALID_DOMAIN_BACKUP =3D 99, /* invalid domain backup */ } virErrorNumber; =20 /** diff --git a/src/Makefile.am b/src/Makefile.am index f95f30e..c4ffc2f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -287,6 +287,7 @@ DRIVER_SOURCES =3D \ libvirt.c libvirt_internal.h \ libvirt-domain.c \ libvirt-domain-snapshot.c \ + libvirt-domain-backup.c \ libvirt-host.c \ libvirt-interface.c \ libvirt-network.c \ @@ -2682,6 +2683,7 @@ libvirt_setuid_rpc_client_la_SOURCES =3D \ libvirt.c \ libvirt-domain.c \ libvirt-domain-snapshot.c \ + libvirt-domain-backup.c \ libvirt-host.c \ libvirt-interface.c \ libvirt-network.c \ diff --git a/src/datatypes.c b/src/datatypes.c index 59ba956..365687c 100644 --- a/src/datatypes.c +++ b/src/datatypes.c @@ -37,6 +37,7 @@ virClassPtr virConnectClass; virClassPtr virConnectCloseCallbackDataClass; virClassPtr virDomainClass; virClassPtr virDomainSnapshotClass; +virClassPtr virDomainBackupClass; virClassPtr virInterfaceClass; virClassPtr virNetworkClass; virClassPtr virNodeDeviceClass; @@ -50,6 +51,7 @@ static void virConnectDispose(void *obj); static void virConnectCloseCallbackDataDispose(void *obj); static void virDomainDispose(void *obj); static void virDomainSnapshotDispose(void *obj); +static void virDomainBackupDispose(void *obj); static void virInterfaceDispose(void *obj); static void virNetworkDispose(void *obj); static void virNodeDeviceDispose(void *obj); @@ -88,6 +90,7 @@ virDataTypesOnceInit(void) DECLARE_CLASS_LOCKABLE(virConnectCloseCallbackData); DECLARE_CLASS(virDomain); DECLARE_CLASS(virDomainSnapshot); + DECLARE_CLASS(virDomainBackup); DECLARE_CLASS(virInterface); DECLARE_CLASS(virNetwork); DECLARE_CLASS(virNodeDevice); @@ -891,6 +894,63 @@ virDomainSnapshotDispose(void *obj) } =20 =20 +/** + * 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 need= ed, + * 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 =3D NULL; + + if (virDataTypesInitialize() < 0) + return NULL; + + virCheckDomainGoto(domain, error); + virCheckNonNullArgGoto(name, error); + + if (!(ret =3D virObjectNew(virDomainBackupClass))) + goto error; + if (VIR_STRDUP(ret->name, name) < 0) + goto error; + + ret->domain =3D virObjectRef(domain); + + return ret; + + error: + virObjectUnref(ret); + return NULL; +} + + +/** + * virDomainBackupDispose: + * @obj: the domain backup to release + * + * Unconditionally release all memory associated with a backup. + * The backup object must not be used once this method returns. + * + * It will also unreference the associated connection object, + * which may also be released if its ref count hits zero. + */ +static void +virDomainBackupDispose(void *obj) +{ + virDomainBackupPtr backup =3D obj; + VIR_DEBUG("release backup %p %s", backup, backup->name); + + VIR_FREE(backup->name); + virObjectUnref(backup->domain); +} + + virAdmConnectPtr virAdmConnectNew(void) { diff --git a/src/datatypes.h b/src/datatypes.h index 288e057..54006ef 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -32,6 +32,7 @@ extern virClassPtr virConnectClass; extern virClassPtr virDomainClass; extern virClassPtr virDomainSnapshotClass; +extern virClassPtr virDomainBackupClass; extern virClassPtr virInterfaceClass; extern virClassPtr virNetworkClass; extern virClassPtr virNodeDeviceClass; @@ -292,6 +293,21 @@ extern virClassPtr virAdmClientClass; } \ } while (0) =20 +# define virCheckDomainBackupReturn(obj, retval) \ + do { \ + virDomainBackupPtr _back =3D (obj); \ + if (!virObjectIsClass(_back, virDomainBackupClass) || \ + !virObjectIsClass(_back->domain, virDomainClass) || \ + !virObjectIsClass(_back->domain->conn, virConnectClass)) { \ + virReportErrorHelper(VIR_FROM_DOMAIN_BACKUP, \ + VIR_ERR_INVALID_DOMAIN_BACKUP, \ + __FILE__, __FUNCTION__, __LINE__, \ + __FUNCTION__); \ + virDispatchError(NULL); \ + return retval; \ + } \ + } while (0) + =20 /* Helper macros to implement VIR_DOMAIN_DEBUG using just C99. This * assumes you pass fewer than 15 arguments to VIR_DOMAIN_DEBUG, but @@ -675,6 +691,17 @@ struct _virNWFilter { unsigned char uuid[VIR_UUID_BUFLEN]; /* the network filter unique iden= tifier */ }; =20 +/** + * _virDomainBackup + * + * Internal structure associated with a domain backup + */ +struct _virDomainBackup { + virObject object; + char *name; + virDomainPtr domain; +}; + =20 /* * Helper APIs for allocating new object instances @@ -714,6 +741,8 @@ virNWFilterPtr virGetNWFilter(virConnectPtr conn, const unsigned char *uuid); virDomainSnapshotPtr virGetDomainSnapshot(virDomainPtr domain, const char *name); +virDomainBackupPtr virGetDomainBackup(virDomainPtr domain, + const char *name); =20 virAdmConnectPtr virAdmConnectNew(void); =20 diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 3053d7a..9c1756f 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1263,6 +1263,10 @@ typedef int unsigned long long threshold, unsigned int flags); =20 +typedef virDomainBackupPtr +(*virDrvDomainBackupCreateXML)(virDomainPtr domain, + const char *xmlDesc, + unsigned int flags); =20 typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1504,6 +1508,7 @@ struct _virHypervisorDriver { virDrvDomainSetGuestVcpus domainSetGuestVcpus; virDrvDomainSetVcpu domainSetVcpu; virDrvDomainSetBlockThreshold domainSetBlockThreshold; + virDrvDomainBackupCreateXML domainBackupCreateXML; }; =20 =20 diff --git a/src/libvirt-domain-backup.c b/src/libvirt-domain-backup.c new file mode 100644 index 0000000..f019d2c --- /dev/null +++ b/src/libvirt-domain-backup.c @@ -0,0 +1,209 @@ +/* + * libvirt-domain-backup.c: entry points for virDomainBackupPtr APIs + + * Copyright (C) 2017 Parallels International GmbH + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "datatypes.h" +#include "virlog.h" + +VIR_LOG_INIT("libvirt.domain-backup"); + +#define VIR_FROM_THIS VIR_FROM_DOMAIN_BACKUP + +/** + * virDomainBackupGetName: + * @backup: a backup object + * + * Get the public name for that backup + * + * Returns a pointer to the name or NULL, the string need not be deallocat= ed + * as its lifetime will be the same as the backup object. + */ +const char * +virDomainBackupGetName(virDomainBackupPtr backup) +{ + VIR_DEBUG("backup=3D%p", backup); + + virResetLastError(); + + virCheckDomainBackupReturn(backup, NULL); + + return backup->name; +} + + +/** + * virDomainBackupGetDomain: + * @backup: a backup object + * + * Provides the domain pointer associated with a backup. The + * reference counter on the domain is not increased by this + * call. + * + * WARNING: When writing libvirt bindings in other languages, do not use t= his + * function. Instead, store the domain and the backup object together. + * + * Returns the domain or NULL. + */ +virDomainPtr +virDomainBackupGetDomain(virDomainBackupPtr backup) +{ + VIR_DEBUG("backup=3D%p", backup); + + virResetLastError(); + + virCheckDomainBackupReturn(backup, NULL); + + return backup->domain; +} + + +/** + * virDomainBackupGetConnect: + * @backup: a backup object + * + * Provides the connection pointer associated with a backup. The + * reference counter on the connection is not increased by this + * call. + * + * WARNING: When writing libvirt bindings in other languages, do not use t= his + * function. Instead, store the connection and the backup object together. + * + * Returns the connection or NULL. + */ +virConnectPtr +virDomainBackupGetConnect(virDomainBackupPtr backup) +{ + VIR_DEBUG("backup=3D%p", backup); + + virResetLastError(); + + virCheckDomainBackupReturn(backup, NULL); + + return backup->domain->conn; +} + + +/** + * virDomainBackupCreateXML: + * @domain: a domain object + * @xmlDesc: domain backup XML description + * @flags: reserved, must be 0 + * + * Starts creating of the domain disks backup based on the xml description= in + * @xmlDesc. Backup is a copy of the specified domain disks at the moment = of + * operation start. + * + * Backup creates a blockjob for every specified disk hence the backup + * status can be tracked thru blockjob event API and the backup progress + * is given by per blockjob virDomainBlockJobInfo. Backup can be cancelled= by + * cancelling any of its still active blockjobs via virDomainBlockJobAbort. + * + * Known issues. In case libvirt connection is lost and restored back and = all + * backup blockjobs are already gone then currenly it is not possible to k= now + * whether backup is completed or failed. + * + * Returns an (opaque) virDomainBackupPtr on success, NULL on failure. + */ +virDomainBackupPtr +virDomainBackupCreateXML(virDomainPtr domain, + const char *xmlDesc, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "xmlDesc=3D%s, flags=3D%x", xmlDesc, flags); + + virResetLastError(); + + virCheckDomainReturn(domain, NULL); + conn =3D domain->conn; + + virCheckNonNullArgGoto(xmlDesc, error); + virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainBackupCreateXML) { + virDomainBackupPtr ret; + ret =3D conn->driver->domainBackupCreateXML(domain, xmlDesc, flags= ); + if (!ret) + goto error; + return ret; + } + + virReportUnsupportedError(); + error: + virDispatchError(conn); + return NULL; +} + + +/** + * virDomainBackupRef: + * @backup: the backup to hold a reference on + * + * Increment the reference count on the backup. For each + * additional call to this method, there shall be a corresponding + * call to virDomainBackupFree to release the reference count, once + * the caller no longer needs the reference to this object. + * + * This method is typically useful for applications where multiple + * threads are using a connection, and it is required that the + * connection and domain remain open until all threads have finished + * using the backup. ie, each new thread using a backup would + * increment the reference count. + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virDomainBackupRef(virDomainBackupPtr backup) +{ + VIR_DEBUG("backup=3D%p, refs=3D%d", backup, + backup ? backup->object.u.s.refs : 0); + + virResetLastError(); + + virCheckDomainBackupReturn(backup, -1); + + virObjectRef(backup); + return 0; +} + + +/** + * virDomainBackupFree: + * @backup: a domain backup object + * + * Free the domain backup object. The backup itself is not modified. + * The data structure is freed and should not be used thereafter. + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virDomainBackupFree(virDomainBackupPtr backup) +{ + VIR_DEBUG("backup=3D%p", backup); + + virResetLastError(); + + virCheckDomainBackupReturn(backup, -1); + + virObjectUnref(backup); + return 0; +} diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index afb9100..2b40d34 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1068,10 +1068,12 @@ virConnectCloseCallbackDataClass; virConnectCloseCallbackDataGetCallback; virConnectCloseCallbackDataRegister; virConnectCloseCallbackDataUnregister; +virDomainBackupClass; virDomainClass; virDomainSnapshotClass; virGetConnect; virGetDomain; +virGetDomainBackup; virGetDomainSnapshot; virGetInterface; virGetNetwork; diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 428cf2e..e3ee083 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -759,4 +759,14 @@ LIBVIRT_3.1.0 { virDomainSetVcpu; } LIBVIRT_3.0.0; =20 +LIBVIRT_3.4.0 { + global: + virDomainBackupRef; + virDomainBackupFree; + virDomainBackupGetName; + virDomainBackupGetDomain; + virDomainBackupGetConnect; + virDomainBackupCreateXML; +} LIBVIRT_3.1.0; + # .... define new API here using predicted next version number .... diff --git a/src/util/virerror.c b/src/util/virerror.c index ef17fb5..f666e6e 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -139,6 +139,7 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST, =20 "Perf", /* 65 */ "Libssh transport layer", + "Domain Backup", ) =20 =20 @@ -1400,6 +1401,11 @@ virErrorMsg(virErrorNumber error, const char *info) errmsg =3D _("guest agent replied with wrong id to guest-s= ync command"); else errmsg =3D _("guest agent replied with wrong id to guest-s= ync command: %s"); + case VIR_ERR_INVALID_DOMAIN_BACKUP: + if (info =3D=3D NULL) + errmsg =3D _("Invalid backup"); + else + errmsg =3D _("Invalid backup: %s"); break; case VIR_ERR_LIBSSH: if (info =3D=3D NULL) --=20 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list