From nobody Sun Feb 8 23:41:05 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as permitted sender) client-ip=207.211.31.120; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1593701292; cv=none; d=zohomail.com; s=zohoarc; b=LHI4yq5Y/GucTL+XpKkMuAKyA9oT4yTqJa0V5fHRDhK4M2ZFhIZ6Y6zCDWVaiZ6JXQKFsjus16Db0j/B30jdi6Pr729SgNXiY5WsJD0vimJNPFEGUu4nVC9Cw9o4ab/MuEts7xKAYfOWYVZZmQQqCciasziIASSmrm+j/m2+OZc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1593701292; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=VQwy9IR92r9jf2BcCVDJRmQmBe3VNpBCPQUFARS5vlk=; b=IEQVxDpvOJdrSArwD4OkTVQ2UNjrNGVTz6xQoWVqYUoZlYjrYohtG6ZkjfZ+SR4j/lNsDH/zPtyYuz1JoxqCN8juWeb3iDpaLT1w0+1hliUUOGATJcE8qHrQ87JHsZlS09toEy2/BRt6HZyRfuPbokZDIRd0Q0p3gnQFohcoqUs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by mx.zohomail.com with SMTPS id 1593701292873625.274576965825; Thu, 2 Jul 2020 07:48:12 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-253-GTtsiw5FN9e-sok6wczN6Q-1; Thu, 02 Jul 2020 10:46:37 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B2A6B87950D; Thu, 2 Jul 2020 14:46:31 +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 95F225C28E; Thu, 2 Jul 2020 14:46:31 +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 674106C9D1; Thu, 2 Jul 2020 14:46:31 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 062EeTx4011816 for ; Thu, 2 Jul 2020 10:40:29 -0400 Received: by smtp.corp.redhat.com (Postfix) id 4775B1002397; Thu, 2 Jul 2020 14:40:29 +0000 (UTC) Received: from speedmetal.redhat.com (unknown [10.40.208.18]) by smtp.corp.redhat.com (Postfix) with ESMTP id AF58E10013D2 for ; Thu, 2 Jul 2020 14:40:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1593701291; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=VQwy9IR92r9jf2BcCVDJRmQmBe3VNpBCPQUFARS5vlk=; b=elU5vVSVPFNyK5QpmCvUQQayHRiyrdEce0GVPp8lX/OkyKPu9oN+0Pz90UnfGY2+HeNscK iSoYzt9abLgD+AeDvJoRgWOl+PBbRO1h2pQADh/2PgobLnpQPcPYp0GGhnfzVCNSNQw7JC Wq43wahCcKlvENloTDI/BezfTHSnkV0= X-MC-Unique: GTtsiw5FN9e-sok6wczN6Q-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH 14/24] backup: Allow configuring incremental backup per-disk individually Date: Thu, 2 Jul 2020 16:40:00 +0200 Message-Id: <29e0b0282e8353055f7233bad4c6fa20bec1a1be.1593700474.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com 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: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" The semantics of the backup operation don't strictly require that all disks being backed up are part of the same incremental part (when a disk was checkpointed/backed up separately or in a different VM), or even they may not have an previous checkpoint at all (e.g. when the disk was freshly hotplugged to the vm). In such cases we can still create a common checkpoint for all of them and backup differences according to configuration. This patch adds a per-disk configuration of the checkpoint to do the incremental backup from via the 'incremental' attribute and allows perform full backups via the 'backupmode' attribute. Note that no changes to the qemu driver are necessary to take advantage of this as we already obey the per-disk 'incremental' field. https://bugzilla.redhat.com/show_bug.cgi?id=3D1829829 Signed-off-by: Peter Krempa --- docs/formatbackup.rst | 11 ++++ docs/schemas/domainbackup.rng | 16 ++++++ src/conf/backup_conf.c | 57 +++++++++++++++++++- src/conf/backup_conf.h | 11 ++++ tests/domainbackupxml2xmlin/backup-pull.xml | 12 +++++ tests/domainbackupxml2xmlout/backup-pull.xml | 12 +++++ 6 files changed, 118 insertions(+), 1 deletion(-) diff --git a/docs/formatbackup.rst b/docs/formatbackup.rst index 66583f562b..e5b6fc6eb0 100644 --- a/docs/formatbackup.rst +++ b/docs/formatbackup.rst @@ -65,6 +65,17 @@ were supplied). The following child elements and attribu= tes are supported: should take part in the backup and using ``no`` excludes the disk= from the backup. + ``backupmode`` + This attribute overrides the implied backup mode inherited from t= he + definition of the backup itself. Value ``full`` forces a full bac= kup + even if the backup calls for an incremental backup and ``incremen= tal`` + coupled with the attribute ``incremental=3D'CHECKPOINTNAME`` for = the disk + forces an incremental backup from ``CHECKPOINTNAME``. + + ``incremental`` + An optional attribute giving the name of an existing checkpoint o= f the + domain which overrides the one set by the ```` eleme= nt. + ``exportname`` Allows modification of the NBD export name for the given disk. By default equal to disk target. Valid only for pull mode backups. diff --git a/docs/schemas/domainbackup.rng b/docs/schemas/domainbackup.rng index 5165175152..650f5cd4c3 100644 --- a/docs/schemas/domainbackup.rng +++ b/docs/schemas/domainbackup.rng @@ -89,6 +89,20 @@ + + + + + full + incremental + + + + + + + + @@ -127,6 +141,7 @@ + @@ -196,6 +211,7 @@ + diff --git a/src/conf/backup_conf.c b/src/conf/backup_conf.c index e9eea5af75..4f28073ab2 100644 --- a/src/conf/backup_conf.c +++ b/src/conf/backup_conf.c @@ -56,6 +56,13 @@ VIR_ENUM_IMPL(virDomainBackupDiskState, "cancelling", "cancelled"); +VIR_ENUM_DECL(virDomainBackupDiskBackupMode); +VIR_ENUM_IMPL(virDomainBackupDiskBackupMode, + VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_LAST, + "", + "full", + "incremental"); + void virDomainBackupDefFree(virDomainBackupDefPtr def) { @@ -96,6 +103,7 @@ virDomainBackupDiskDefParseXML(xmlNodePtr node, g_autofree char *driver =3D NULL; g_autofree char *backup =3D NULL; g_autofree char *state =3D NULL; + g_autofree char *backupmode =3D NULL; int tmp; xmlNodePtr srcNode; unsigned int storageSourceParseFlags =3D 0; @@ -133,6 +141,19 @@ virDomainBackupDiskDefParseXML(xmlNodePtr node, def->exportbitmap =3D virXMLPropString(node, "exportbitmap"); } + if ((backupmode =3D virXMLPropString(node, "backupmode"))) { + if ((tmp =3D virDomainBackupDiskBackupModeTypeFromString(backupmod= e)) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid backupmode '%s' of disk '%s'"), + backupmode, def->name); + return -1; + } + + def->backupmode =3D tmp; + } + + def->incremental =3D virXMLPropString(node, "incremental"); + if (internal) { if (!(state =3D virXMLPropString(node, "state")) || (tmp =3D virDomainBackupDiskStateTypeFromString(state)) < 0) { @@ -342,6 +363,13 @@ virDomainBackupDiskDefFormat(virBufferPtr buf, if (disk->backup =3D=3D VIR_TRISTATE_BOOL_YES) { virBufferAsprintf(&attrBuf, " type=3D'%s'", virStorageTypeToString= (disk->store->type)); + if (disk->backupmode !=3D VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_DEFAU= LT) { + virBufferAsprintf(&attrBuf, " backupmode=3D'%s'", + virDomainBackupDiskBackupModeTypeToString(di= sk->backupmode)); + } + + virBufferEscapeString(&attrBuf, " incremental=3D'%s'", disk->incre= mental); + virBufferEscapeString(&attrBuf, " exportname=3D'%s'", disk->export= name); virBufferEscapeString(&attrBuf, " exportbitmap=3D'%s'", disk->expo= rtbitmap); @@ -465,6 +493,24 @@ virDomainBackupAlignDisks(virDomainBackupDefPtr def, return -1; } + if (backupdisk->backupmode =3D=3D VIR_DOMAIN_BACKUP_DISK_BACKUP_MO= DE_FULL && + backupdisk->incremental) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("'full' backup mode incompatible with 'increm= ental' for disk '%s'"), + backupdisk->name); + return -1; + } + + if (backupdisk->backupmode =3D=3D VIR_DOMAIN_BACKUP_DISK_BACKUP_MO= DE_INCREMENTAL && + !backupdisk->incremental && + !def->incremental) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("'incremental' backup mode of disk '%s' requi= res setting 'incremental' field for disk or backup"), + backupdisk->name); + return -1; + } + + if (backupdisk->backup =3D=3D VIR_TRISTATE_BOOL_YES && virDomainBackupDefAssignStore(backupdisk, domdisk->src, suffix= ) < 0) return -1; @@ -502,7 +548,16 @@ virDomainBackupAlignDisks(virDomainBackupDefPtr def, for (i =3D 0; i < def->ndisks; i++) { virDomainBackupDiskDefPtr backupdisk =3D &def->disks[i]; - if (def->incremental && !backupdisk->incremental) + if (backupdisk->backupmode =3D=3D VIR_DOMAIN_BACKUP_DISK_BACKUP_MO= DE_DEFAULT) { + if (def->incremental || backupdisk->incremental) { + backupdisk->backupmode =3D VIR_DOMAIN_BACKUP_DISK_BACKUP_M= ODE_INCREMENTAL; + } else { + backupdisk->backupmode =3D VIR_DOMAIN_BACKUP_DISK_BACKUP_M= ODE_FULL; + } + } + + if (!backupdisk->incremental && + backupdisk->backupmode =3D=3D VIR_DOMAIN_BACKUP_DISK_BACKUP_MO= DE_INCREMENTAL) backupdisk->incremental =3D g_strdup(def->incremental); } diff --git a/src/conf/backup_conf.h b/src/conf/backup_conf.h index 172eb1cf1c..3f8b592b8d 100644 --- a/src/conf/backup_conf.h +++ b/src/conf/backup_conf.h @@ -45,12 +45,23 @@ typedef enum { VIR_DOMAIN_BACKUP_DISK_STATE_LAST } virDomainBackupDiskState; + +typedef enum { + VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_DEFAULT =3D 0, + VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_FULL, + VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_INCREMENTAL, + + VIR_DOMAIN_BACKUP_DISK_BACKUP_MODE_LAST +} virDomainBackupDiskBackupMode; + + /* Stores disk-backup information */ typedef struct _virDomainBackupDiskDef virDomainBackupDiskDef; typedef virDomainBackupDiskDef *virDomainBackupDiskDefPtr; struct _virDomainBackupDiskDef { char *name; /* name matching the + + + + + + + + + + + + diff --git a/tests/domainbackupxml2xmlout/backup-pull.xml b/tests/domainbac= kupxml2xmlout/backup-pull.xml index 24fce9c0e7..d2f84cda7a 100644 --- a/tests/domainbackupxml2xmlout/backup-pull.xml +++ b/tests/domainbackupxml2xmlout/backup-pull.xml @@ -6,5 +6,17 @@ + + + + + + + + + + + + --=20 2.26.2