From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1650655984952628.1852019498233; Fri, 22 Apr 2022 12:33:04 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-625-rS0Ib5mZOxOhT0MtYhPXng-1; Fri, 22 Apr 2022 15:32:43 -0400 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id AE5171014A86; Fri, 22 Apr 2022 19:32:37 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 92C4D565DDE; Fri, 22 Apr 2022 19:32:37 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 4AB971940355; Fri, 22 Apr 2022 19:32:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id CF23B194035B for ; Fri, 22 Apr 2022 19:32:35 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 9E5EB2166B5E; Fri, 22 Apr 2022 19:32:35 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast10.extmail.prod.ext.rdu2.redhat.com [10.11.55.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 99E832166B18 for ; Fri, 22 Apr 2022 19:32:31 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id BF7571E17FE5 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-73-FSYHhr2dPS6AxIdVAB9b8w-1; Fri, 22 Apr 2022 15:32:24 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 31E3D21600; Fri, 22 Apr 2022 19:32:23 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id DEEC613AE1; Fri, 22 Apr 2022 19:32:22 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id UM89NMYCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:22 +0000 X-MC-Unique: rS0Ib5mZOxOhT0MtYhPXng-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: FSYHhr2dPS6AxIdVAB9b8w-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 01/11] libvirt: introduce virDomainSaveParametersFlags public API Date: Fri, 22 Apr 2022 21:32:07 +0200 Message-Id: <20220422193217.22513-2-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 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-ZM-MESSAGEID: 1650655985866100001 Content-Type: text/plain; charset="utf-8"; x-default="true" add new API in order to be able to extend parameters to the domain save operation. We will use it to fit the existing arguments of VirDomainSaveFlags, and then add parallel saves functionality. Signed-off-by: Claudio Fontana --- include/libvirt/libvirt-domain.h | 9 ++++++ src/driver-hypervisor.h | 7 +++++ src/libvirt-domain.c | 51 ++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 4 files changed, 72 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-dom= ain.h index 2d5718301e..f3a4daf034 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1270,6 +1270,7 @@ typedef enum { VIR_DOMAIN_SAVE_RUNNING =3D 1 << 1, /* Favor running over paused = */ VIR_DOMAIN_SAVE_PAUSED =3D 1 << 2, /* Favor paused over running = */ VIR_DOMAIN_SAVE_RESET_NVRAM =3D 1 << 3, /* Re-initialize NVRAM from t= emplate */ + VIR_DOMAIN_SAVE_PARALLEL =3D 1 << 4, /* Parallel Save/Restore to m= ultiple files */ } virDomainSaveRestoreFlags; =20 int virDomainSave (virDomainPtr domain, @@ -1278,6 +1279,10 @@ int virDomainSaveFlags (vir= DomainPtr domain, const char *to, const char *dxml, unsigned int flags); +int virDomainSaveParametersFlags (virDomainPtr domain, + virTypedParameterPtr= params, + int nparams, + unsigned int flags); int virDomainRestore (virConnectPtr conn, const char *from); int virDomainRestoreFlags (virConnectPtr conn, @@ -1285,6 +1290,10 @@ int virDomainRestoreFlags (vir= ConnectPtr conn, const char *dxml, unsigned int flags); =20 +# define VIR_SAVE_PARAM_TO "to" +# define VIR_SAVE_PARAM_DXML "dxml" +# define VIR_SAVE_PARAM_PARALLEL_CONNECTIONS "parallel.connections" + /* See below for virDomainSaveImageXMLFlags */ char * virDomainSaveImageGetXMLDesc (virConnectPtr conn, const char *file, diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 4423eb0885..a4e1d21e76 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -240,6 +240,12 @@ typedef int const char *dxml, unsigned int flags); =20 +typedef int +(*virDrvDomainSaveParametersFlags)(virDomainPtr domain, + virTypedParameterPtr params, + int nparams, + unsigned int flags); + typedef int (*virDrvDomainRestore)(virConnectPtr conn, const char *from); @@ -1489,6 +1495,7 @@ struct _virHypervisorDriver { virDrvDomainGetControlInfo domainGetControlInfo; virDrvDomainSave domainSave; virDrvDomainSaveFlags domainSaveFlags; + virDrvDomainSaveParametersFlags domainSaveParametersFlags; virDrvDomainRestore domainRestore; virDrvDomainRestoreFlags domainRestoreFlags; virDrvDomainSaveImageGetXMLDesc domainSaveImageGetXMLDesc; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index a197618673..1ab1580f8a 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -953,6 +953,57 @@ virDomainSaveFlags(virDomainPtr domain, const char *to, return -1; } =20 +/** + * virDomainSaveParametersFlags: + * @domain: a domain object + * @params: save parameters + * @nparams: number of save parameters + * @flags: bitwise-OR of virDomainSaveRestoreFlags + * + * This method extends virDomainSaveFlags by adding parameters to Save. + * + * If @flags includes VIR_DOMAIN_SAVE_PARALLEL, then libvirt will + * attempt to trigger a parallel transfer to multiple files, + * where the number of extra files is determined by the parameter + * VIR_SAVE_PARAM_PARALLEL_CONNECTIONS. + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virDomainSaveParametersFlags(virDomainPtr domain, + virTypedParameterPtr params, int nparams, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "params=3D%p, nparams=3D%d, flags=3D0x%x", + params, nparams, flags); + VIR_TYPED_PARAMS_DEBUG(params, nparams); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn =3D domain->conn; + + virCheckReadOnlyGoto(conn->flags, error); + + VIR_EXCLUSIVE_FLAGS_GOTO(VIR_DOMAIN_SAVE_RUNNING, + VIR_DOMAIN_SAVE_PAUSED, + error); + + if (conn->driver->domainSaveParametersFlags) { + if (conn->driver->domainSaveParametersFlags(domain, params, nparam= s, flags) < 0) + goto error; + return 0; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} + =20 /** * virDomainRestore: diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index f93692c427..eb3a7afb75 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -916,4 +916,9 @@ LIBVIRT_8.0.0 { virDomainSetLaunchSecurityState; } LIBVIRT_7.8.0; =20 +LIBVIRT_8.3.0 { + global: + virDomainSaveParametersFlags; +} LIBVIRT_8.0.0; + # .... define new API here using predicted next version number .... --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1650655973098442.20200270909095; Fri, 22 Apr 2022 12:32:53 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-644-AVIKUB8IN3mDM8rCx-xUMw-1; Fri, 22 Apr 2022 15:32:44 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 3A00038107B7; Fri, 22 Apr 2022 19:32:34 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2634F40CF918; Fri, 22 Apr 2022 19:32:34 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 2DF631940355; Fri, 22 Apr 2022 19:32:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id B1FA7194036D for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 7FF4C565DCE; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast10.extmail.prod.ext.rdu2.redhat.com [10.11.55.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7B503565DD4 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 64AAF1E17FE5 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-642-Hp8M2xCTPPyllBOHTj4J4Q-1; Fri, 22 Apr 2022 15:32:25 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 874ED21601; Fri, 22 Apr 2022 19:32:23 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 413B213AE1; Fri, 22 Apr 2022 19:32:23 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id yEWUDccCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:23 +0000 X-MC-Unique: AVIKUB8IN3mDM8rCx-xUMw-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: Hp8M2xCTPPyllBOHTj4J4Q-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 02/11] remote: Add RPC support for the virDomainSaveParametersFlags API Date: Fri, 22 Apr 2022 21:32:08 +0200 Message-Id: <20220422193217.22513-3-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 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-ZM-MESSAGEID: 1650655973814100021 Content-Type: text/plain; charset="utf-8"; x-default="true" Signed-off-by: Claudio Fontana --- src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 17 ++++++++++++++++- src/remote_protocol-structs | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 7e7a21fcab..1fc5d41971 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8446,6 +8446,7 @@ static virHypervisorDriver hypervisor_driver =3D { .domainGetControlInfo =3D remoteDomainGetControlInfo, /* 0.9.3 */ .domainSave =3D remoteDomainSave, /* 0.3.0 */ .domainSaveFlags =3D remoteDomainSaveFlags, /* 0.9.4 */ + .domainSaveParametersFlags =3D remoteDomainSaveParametersFlags, /* 8.3= .0 */ .domainRestore =3D remoteDomainRestore, /* 0.3.0 */ .domainRestoreFlags =3D remoteDomainRestoreFlags, /* 0.9.4 */ .domainSaveImageGetXMLDesc =3D remoteDomainSaveImageGetXMLDesc, /* 0.9= .4 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 4f13cef662..c2ae5c5748 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -230,6 +230,9 @@ const REMOTE_NODE_MEMORY_PARAMETERS_MAX =3D 64; /* Upper limit on migrate parameters */ const REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX =3D 64; =20 +/* Upper limit on save/restore parameters */ +const REMOTE_DOMAIN_SAVE_PARAMS_MAX =3D 64; + /* Upper limit on number of job stats */ const REMOTE_DOMAIN_JOB_STATS_MAX =3D 64; =20 @@ -3227,6 +3230,12 @@ struct remote_domain_migrate_confirm3_params_args { int cancelled; }; =20 +struct remote_domain_save_parameters_flags_args { + remote_nonnull_domain dom; + remote_typed_param params; + unsigned int flags; +}; + /* The device removed event is the last event where we have to support * dual forms for back-compat to older clients; all future events can * use just the modern form with callbackID. */ @@ -6920,5 +6929,11 @@ enum remote_procedure { * @generate: both * @acl: domain:write */ - REMOTE_PROC_DOMAIN_SET_LAUNCH_SECURITY_STATE =3D 439 + REMOTE_PROC_DOMAIN_SET_LAUNCH_SECURITY_STATE =3D 439, + + /** + * @generate: both + * @acl: domain:hibernate + */ + REMOTE_PROC_DOMAIN_SAVE_PARAMETERS_FLAGS =3D 440 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index d88176781d..89eadeb644 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -563,6 +563,14 @@ struct remote_domain_save_flags_args { remote_string dxml; u_int flags; }; +struct remote_domain_save_parameters_flags_args { + remote_nonnull_domain dom; + struct { + u_int params_len; + remote_typed_param * params_val; + } params; + u_int flags; +}; struct remote_domain_restore_args { remote_nonnull_string from; }; @@ -3689,4 +3697,5 @@ enum remote_procedure { REMOTE_PROC_NETWORK_CREATE_XML_FLAGS =3D 437, REMOTE_PROC_DOMAIN_EVENT_MEMORY_DEVICE_SIZE_CHANGE =3D 438, REMOTE_PROC_DOMAIN_SET_LAUNCH_SECURITY_STATE =3D 439, + REMOTE_PROC_DOMAIN_SAVE_PARAMETERS_FLAGS =3D 440, }; --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1650655956806789.9818089211523; Fri, 22 Apr 2022 12:32:36 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-605-RzkEpi9SOY-hFR4mbiox-Q-1; Fri, 22 Apr 2022 15:32:31 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4339A3806659; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2609A2026609; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 5EB751940359; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id B8BE81940351 for ; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 9D97841636F; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast07.extmail.prod.ext.rdu2.redhat.com [10.11.55.23]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9981441636E for ; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 771413C0FEA1 for ; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-614-6RjyAfdpP7KmWADBnXy4fA-1; Fri, 22 Apr 2022 15:32:25 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id DC0951F388; Fri, 22 Apr 2022 19:32:23 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 98F2113AE1; Fri, 22 Apr 2022 19:32:23 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id KDnRIscCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:23 +0000 X-MC-Unique: RzkEpi9SOY-hFR4mbiox-Q-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: 6RjyAfdpP7KmWADBnXy4fA-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 03/11] qemu: add a stub for virDomainSaveParametersFlags API Date: Fri, 22 Apr 2022 21:32:09 +0200 Message-Id: <20220422193217.22513-4-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 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-ZM-MESSAGEID: 1650655957753100001 Content-Type: text/plain; charset="utf-8"; x-default="true" Signed-off-by: Claudio Fontana --- src/qemu/qemu_driver.c | 66 ++++++++++++++++++++++++++++++++++++--- src/qemu/qemu_saveimage.c | 2 ++ src/qemu/qemu_saveimage.h | 1 + src/qemu/qemu_snapshot.c | 2 +- 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 77012eb527..cfc68e3135 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2631,7 +2631,7 @@ static int qemuDomainSaveInternal(virQEMUDriver *driver, virDomainObj *vm, const char *path, int compressed, virCommand *compressor, - const char *xmlin, unsigned int flags) + const char *xmlin, int nconn, unsigned int flags) { g_autofree char *xml =3D NULL; bool was_running =3D false; @@ -2712,7 +2712,7 @@ qemuDomainSaveInternal(virQEMUDriver *driver, xml =3D NULL; =20 ret =3D qemuSaveImageCreate(driver, vm, path, data, compressor, - flags, VIR_ASYNC_JOB_SAVE); + nconn, flags, VIR_ASYNC_JOB_SAVE); if (ret < 0) goto endjob; =20 @@ -2781,7 +2781,7 @@ qemuDomainSaveFlags(virDomainPtr dom, const char *pat= h, const char *dxml, goto cleanup; =20 ret =3D qemuDomainSaveInternal(driver, vm, path, compressed, - compressor, dxml, flags); + compressor, dxml, 0, flags); =20 cleanup: virDomainObjEndAPI(&vm); @@ -2794,6 +2794,63 @@ qemuDomainSave(virDomainPtr dom, const char *path) return qemuDomainSaveFlags(dom, path, NULL, 0); } =20 +static int +qemuDomainSaveParametersFlags(virDomainPtr dom, + virTypedParameterPtr params, int nparams, + unsigned int flags) +{ + const char *to =3D NULL; + const char *dxml =3D NULL; + virQEMUDriver *driver =3D dom->conn->privateData; + int compressed; + g_autoptr(virCommand) compressor =3D NULL; + int ret =3D -1; + int nconn =3D 0; + virDomainObj *vm =3D NULL; + g_autoptr(virQEMUDriverConfig) cfg =3D NULL; + + virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE | + VIR_DOMAIN_SAVE_RUNNING | + VIR_DOMAIN_SAVE_PAUSED | + VIR_DOMAIN_SAVE_PARALLEL, -1); + + if (virTypedParamsValidate(params, nparams, + VIR_SAVE_PARAM_TO, VIR_TYPED_PARAM_STRING, + VIR_SAVE_PARAM_DXML, VIR_TYPED_PARAM_STRING, + VIR_SAVE_PARAM_PARALLEL_CONNECTIONS, VIR_TY= PED_PARAM_INT, + NULL) < 0) + return -1; + + if (virTypedParamsGetString(params, nparams, VIR_SAVE_PARAM_TO, &to) <= 0) + return -1; + if (virTypedParamsGetString(params, nparams, VIR_SAVE_PARAM_DXML, &dxm= l) < 0) + return -1; + if (virTypedParamsGetInt(params, nparams, VIR_SAVE_PARAM_PARALLEL_CONN= ECTIONS, &nconn) < 0) + return -1; + + cfg =3D virQEMUDriverGetConfig(driver); + if ((compressed =3D qemuSaveImageGetCompressionProgram(cfg->saveImageF= ormat, + &compressor, + "save", false)) <= 0) + goto cleanup; + + if (!(vm =3D qemuDomainObjFromDomain(dom))) + goto cleanup; + + if (virDomainSaveFlagsEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) + goto cleanup; + + ret =3D qemuDomainSaveInternal(driver, vm, to, compressed, + compressor, dxml, nconn, flags); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + static char * qemuDomainManagedSavePath(virQEMUDriver *driver, virDomainObj *vm) { @@ -2844,7 +2901,7 @@ qemuDomainManagedSave(virDomainPtr dom, unsigned int = flags) VIR_INFO("Saving state of domain '%s' to '%s'", vm->def->name, name); =20 ret =3D qemuDomainSaveInternal(driver, vm, name, compressed, - compressor, NULL, flags); + compressor, NULL, 0, flags); if (ret =3D=3D 0) vm->hasManagedSave =3D true; =20 @@ -20826,6 +20883,7 @@ static virHypervisorDriver qemuHypervisorDriver =3D= { .domainGetControlInfo =3D qemuDomainGetControlInfo, /* 0.9.3 */ .domainSave =3D qemuDomainSave, /* 0.2.0 */ .domainSaveFlags =3D qemuDomainSaveFlags, /* 0.9.4 */ + .domainSaveParametersFlags =3D qemuDomainSaveParametersFlags, /* 8.3.0= */ .domainRestore =3D qemuDomainRestore, /* 0.2.0 */ .domainRestoreFlags =3D qemuDomainRestoreFlags, /* 0.9.4 */ .domainSaveImageGetXMLDesc =3D qemuDomainSaveImageGetXMLDesc, /* 0.9.4= */ diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c index 4fd4c5cfcd..6e7f067be2 100644 --- a/src/qemu/qemu_saveimage.c +++ b/src/qemu/qemu_saveimage.c @@ -258,6 +258,7 @@ qemuSaveImageCreate(virQEMUDriver *driver, const char *path, virQEMUSaveData *data, virCommand *compressor, + int nconn, unsigned int flags, virDomainAsyncJob asyncJob) { @@ -269,6 +270,7 @@ qemuSaveImageCreate(virQEMUDriver *driver, virFileWrapperFd *wrapperFd =3D NULL; unsigned int wrapperFlags =3D VIR_FILE_WRAPPER_NON_BLOCKING; =20 + nconn =3D nconn; /* unused */ /* Obtain the file handle. */ if ((flags & VIR_DOMAIN_SAVE_BYPASS_CACHE)) { wrapperFlags |=3D VIR_FILE_WRAPPER_BYPASS_CACHE; diff --git a/src/qemu/qemu_saveimage.h b/src/qemu/qemu_saveimage.h index 391cd55ed0..b3d5c02fd6 100644 --- a/src/qemu/qemu_saveimage.h +++ b/src/qemu/qemu_saveimage.h @@ -96,6 +96,7 @@ qemuSaveImageCreate(virQEMUDriver *driver, const char *path, virQEMUSaveData *data, virCommand *compressor, + int nconn, unsigned int flags, virDomainAsyncJob asyncJob); =20 diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index b62fab7bb3..f4eeb9276c 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -1457,7 +1457,7 @@ qemuSnapshotCreateActiveExternal(virQEMUDriver *drive= r, memory_existing =3D virFileExists(snapdef->memorysnapshotfile); =20 if ((ret =3D qemuSaveImageCreate(driver, vm, snapdef->memorysnapsh= otfile, - data, compressor, 0, + data, compressor, 0, 0, VIR_ASYNC_JOB_SNAPSHOT)) < 0) goto cleanup; =20 --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 165065596835167.63717761721455; Fri, 22 Apr 2022 12:32:48 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-423-MkVTTm5NMyW1cCkWnE8rrQ-1; Fri, 22 Apr 2022 15:32:37 -0400 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id AA9639697C6; Fri, 22 Apr 2022 19:32:32 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9260D565DD6; Fri, 22 Apr 2022 19:32:32 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id A6BCE1940351; Fri, 22 Apr 2022 19:32:30 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id F40951940351 for ; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id E55CE565DD6; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast10.extmail.prod.ext.rdu2.redhat.com [10.11.55.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E12DD565DCE for ; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C5C401E17FE6 for ; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-650-M-fnz-EpO3KE8Ga-LRR-LA-1; Fri, 22 Apr 2022 15:32:25 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 387CA21607; Fri, 22 Apr 2022 19:32:24 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id EA69A13AE1; Fri, 22 Apr 2022 19:32:23 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id iJcXN8cCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:23 +0000 X-MC-Unique: MkVTTm5NMyW1cCkWnE8rrQ-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: M-fnz-EpO3KE8Ga-LRR-LA-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 04/11] qemu: initial implementation for the virDomainSaveParametersFlags API Date: Fri, 22 Apr 2022 21:32:10 +0200 Message-Id: <20220422193217.22513-5-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 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-ZM-MESSAGEID: 1650655969810100017 Content-Type: text/plain; charset="utf-8"; x-default="true" make the qemuDomainSaveParametersFlags minimally functional by preparing the files for the multifd channels, but stop short of using them, relying on normal migration to file for now. Signed-off-by: Claudio Fontana --- src/qemu/qemu_saveimage.c | 256 +++++++++++++++++++++++++++++++------- src/qemu/qemu_saveimage.h | 8 ++ 2 files changed, 220 insertions(+), 44 deletions(-) diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c index 6e7f067be2..6a65d72fb3 100644 --- a/src/qemu/qemu_saveimage.c +++ b/src/qemu/qemu_saveimage.c @@ -248,6 +248,192 @@ qemuSaveImageGetCompressionCommand(virQEMUSaveFormat = compression) return ret; } =20 +/* + * virQEMUSaveFdInit: initialize a virQEMUSaveFd + * + * @saveFd: the structure to initialize + * @base: the main file name + * @idx: 0 for the main file, >0 for multifd channels. + * @user: uid + * @group: gid + * @flags: the general flags + * + * Returns -1 on error, 0 on success, + * and in both cases virQEMUSaveFdFini must be called to free resources. + */ +static int virQEMUSaveFdInit(virQEMUSaveFd *saveFd, const char *base, int = idx, + uid_t user, gid_t group, unsigned int flags) +{ + unsigned int directFlag =3D 0; + unsigned int wrapperFlags =3D VIR_FILE_WRAPPER_NON_BLOCKING; + + if (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) { + directFlag =3D virFileDirectFdFlag(); + wrapperFlags |=3D VIR_FILE_WRAPPER_BYPASS_CACHE; + } + if (idx > 0) { + saveFd->path =3D g_strdup_printf("%s.%d", base, idx); + } else { + saveFd->path =3D g_strdup(base); + } + saveFd->wrapper =3D NULL; + saveFd->fd =3D virQEMUFileOpenAs(user, group, false, saveFd->path, + O_WRONLY | O_TRUNC | O_CREAT | directFl= ag, + &saveFd->need_unlink); + if (saveFd->fd < 0) + return -1; + + if (idx > 0) { + /* no wrapper required for the multifd channels */ + } else { + saveFd->wrapper =3D virFileWrapperFdNew(&saveFd->fd, saveFd->path,= wrapperFlags); + if (!saveFd->wrapper) + return -1; + } + return 0; +} + +/* + * virQEMUSaveFdClose: close a virQEMUSaveFd descriptor with normal close. + * + * @saveFd: the saveFd structure with the file descriptors to close. + * @vm: the virDomainObj (necessary to release lock) + * + * If saveFd is NULL, the function will return success. + * + * Returns -1 on error, 0 on success. + */ +static int virQEMUSaveFdClose(virQEMUSaveFd *saveFd, virDomainObj *vm) +{ + if (!saveFd) + return 0; + + if (VIR_CLOSE(saveFd->fd) < 0) { + virReportSystemError(errno, _("unable to close %s"), saveFd->path); + return -1; + } + if (qemuDomainFileWrapperFDClose(vm, saveFd->wrapper) < 0) + return -1; + + return 0; +} + +/* + * virQEMUSaveFdFini: finalize a virQEMUSaveFd + * + * @saveFd: the saveFd structure containing the resources to free. + * @vm: the virDomainObj (necessary to release lock) + * @ret: the current operation result (< 0 is failure) + * + * If saveFd is NULL, the return value will be unchanged. + * + * Returns ret, or -1 if an error is detected. + */ +static int virQEMUSaveFdFini(virQEMUSaveFd *saveFd, virDomainObj *vm, int = ret) +{ + if (!saveFd) + return ret; + VIR_FORCE_CLOSE(saveFd->fd); + if (qemuDomainFileWrapperFDClose(vm, saveFd->wrapper) < 0) { + ret =3D -1; + } + if (ret < 0 && saveFd->need_unlink && saveFd->path) { + unlink(saveFd->path); + } + if (saveFd->wrapper) { + virFileWrapperFdFree(saveFd->wrapper); + saveFd->wrapper =3D NULL; + } + + g_free(saveFd->path); + saveFd->path =3D NULL; + return ret; +} + +/* + * qemuSaveImageFreeMultiFd: free all multifd virQEMUSaveFds. + * @multiFd: the array of saveFds + * @vm: the virDomainObj, to release lock + * @nconn: number of multifd channels + * @ret: the current operation result (< 0 is failure) + * + * If multiFd is NULL, the return value will be unchanged. + * + * Returns ret, or -1 if an error is detected. + */ +static int qemuSaveImageFreeMultiFd(virQEMUSaveFd *multiFd, virDomainObj *= vm, int nconn, int ret) +{ + int i; + + if (!multiFd) + return ret; + + for (i =3D 0; i < nconn; i++) { + ret =3D virQEMUSaveFdFini(&multiFd[i], vm, ret); + } + /* + * do it again to unlink all in the error case, + * if error happened in the middle of previous loop. + */ + for (i =3D 0; i < nconn; i++) { + ret =3D virQEMUSaveFdFini(&multiFd[i], vm, ret); + } + g_free(multiFd); + return ret; +} + +/* + * qemuSaveImageCloseMultiFd: perform normal close on all multifd virQEMUS= aveFds. + * If multiFd is NULL, the function will return success. + * + * Returns -1 on error, 0 on success. + */ + +static int qemuSaveImageCloseMultiFd(virQEMUSaveFd *multiFd, int nconn, vi= rDomainObj *vm) +{ + int i; + + if (!multiFd) + return 0; + + for (i =3D 0; i < nconn; i++) { + if (virQEMUSaveFdClose(&multiFd[i], vm) < 0) { + return -1; + } + } + return 0; +} + +/* + * qemuSaveImageCreateMultiFd: allocate and initialize all multifd virQEMU= SaveFds. + * + * Returns the new array of virQEMUSaveFds, or NULL on error. + */ + +static virQEMUSaveFd * +qemuSaveImageCreateMultiFd(virQEMUDriver *driver, virDomainObj *vm, + const char *path, uid_t user, gid_t group, + int nconn, unsigned int flags) +{ + virQEMUSaveFd *multiFd =3D g_new0(virQEMUSaveFd, nconn); + int i; + + for (i =3D 0; i < nconn; i++) { + virQEMUSaveFd *m =3D &multiFd[i]; + if (virQEMUSaveFdInit(m, path, i + 1, user, group, flags) < 0 || + qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, = m->fd) < 0) { + + virQEMUSaveFdFini(m, vm, -1); + goto error; + } + } + return multiFd; + + error: + qemuSaveImageFreeMultiFd(multiFd, vm, nconn, -1); + return NULL; +} + =20 /* Helper function to execute a migration to file with a correct save head= er * the caller needs to make sure that the processors are stopped and do al= l other @@ -263,42 +449,35 @@ qemuSaveImageCreate(virQEMUDriver *driver, virDomainAsyncJob asyncJob) { g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(driver); - bool needUnlink =3D false; + virQEMUSaveFd saveFd; + virQEMUSaveFd *multiFd =3D NULL; int ret =3D -1; - int fd =3D -1; - int directFlag =3D 0; - virFileWrapperFd *wrapperFd =3D NULL; - unsigned int wrapperFlags =3D VIR_FILE_WRAPPER_NON_BLOCKING; - - nconn =3D nconn; /* unused */ - /* Obtain the file handle. */ - if ((flags & VIR_DOMAIN_SAVE_BYPASS_CACHE)) { - wrapperFlags |=3D VIR_FILE_WRAPPER_BYPASS_CACHE; - directFlag =3D virFileDirectFdFlag(); - if (directFlag < 0) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("bypass cache unsupported by this system")); - goto cleanup; - } - } =20 - fd =3D virQEMUFileOpenAs(cfg->user, cfg->group, false, path, - O_WRONLY | O_TRUNC | O_CREAT | directFlag, - &needUnlink); - if (fd < 0) + if (virQEMUSaveFdInit(&saveFd, path, 0, cfg->user, cfg->group, flags) = < 0) { goto cleanup; - - if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) = < 0) + } + if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, save= Fd.fd) < 0) goto cleanup; =20 - if (!(wrapperFd =3D virFileWrapperFdNew(&fd, path, wrapperFlags))) + if (virQEMUSaveDataWrite(data, saveFd.fd, saveFd.path) < 0) goto cleanup; =20 - if (virQEMUSaveDataWrite(data, fd, path) < 0) - goto cleanup; + if (flags & VIR_DOMAIN_SAVE_PARALLEL) { + /* Perform parallel multifd migration to files (main fd + channels= ) */ + if (!(multiFd =3D qemuSaveImageCreateMultiFd(driver, vm, saveFd.pa= th, cfg->user, cfg->group, nconn, flags))) + goto cleanup; + /* still using single fd migration for now */ + if (qemuMigrationSrcToFile(driver, vm, saveFd.fd, compressor, asyn= cJob) < 0) + goto cleanup; + if (qemuSaveImageCloseMultiFd(multiFd, nconn, vm) < 0) + goto cleanup; + } else { + /* Perform non-parallel migration to file */ + if (qemuMigrationSrcToFile(driver, vm, saveFd.fd, compressor, asyn= cJob) < 0) + goto cleanup; + } =20 - /* Perform the migration */ - if (qemuMigrationSrcToFile(driver, vm, fd, compressor, asyncJob) < 0) + if (virQEMUSaveFdClose(&saveFd, vm) < 0) goto cleanup; =20 /* Touch up file header to mark image complete. */ @@ -307,29 +486,18 @@ qemuSaveImageCreate(virQEMUDriver *driver, * up to seek backwards on wrapperFd. The reopened fd will * trigger a single page of file system cache pollution, but * that's acceptable. */ - if (VIR_CLOSE(fd) < 0) { - virReportSystemError(errno, _("unable to close %s"), path); - goto cleanup; - } - - if (qemuDomainFileWrapperFDClose(vm, wrapperFd) < 0) - goto cleanup; =20 - if ((fd =3D qemuDomainOpenFile(cfg, vm->def, path, O_WRONLY, NULL)) < = 0 || - virQEMUSaveDataFinish(data, &fd, path) < 0) + if ((saveFd.fd =3D qemuDomainOpenFile(cfg, vm->def, saveFd.path, O_WRO= NLY, NULL)) < 0 || + virQEMUSaveDataFinish(data, &saveFd.fd, saveFd.path) < 0) goto cleanup; =20 ret =3D 0; =20 - cleanup: - VIR_FORCE_CLOSE(fd); - if (qemuDomainFileWrapperFDClose(vm, wrapperFd) < 0) - ret =3D -1; - virFileWrapperFdFree(wrapperFd); =20 - if (ret < 0 && needUnlink) - unlink(path); + cleanup: =20 + ret =3D qemuSaveImageFreeMultiFd(multiFd, vm, nconn, ret); + ret =3D virQEMUSaveFdFini(&saveFd, vm, ret); return ret; } =20 diff --git a/src/qemu/qemu_saveimage.h b/src/qemu/qemu_saveimage.h index b3d5c02fd6..24dcd213a5 100644 --- a/src/qemu/qemu_saveimage.h +++ b/src/qemu/qemu_saveimage.h @@ -54,6 +54,14 @@ struct _virQEMUSaveData { }; =20 =20 +typedef struct _virQEMUSaveFd virQEMUSaveFd; +struct _virQEMUSaveFd { + char *path; + int fd; + bool need_unlink; + virFileWrapperFd *wrapper; +}; + virDomainDef * qemuSaveImageUpdateDef(virQEMUDriver *driver, virDomainDef *def, --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1650655966351353.4039722513538; Fri, 22 Apr 2022 12:32:46 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-456-8Gr4JtjqORe82hGdkHAf1Q-1; Fri, 22 Apr 2022 15:32:43 -0400 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4129486B8A8; Fri, 22 Apr 2022 19:32:37 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 26D3A416370; Fri, 22 Apr 2022 19:32:37 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id BC8831940355; Fri, 22 Apr 2022 19:32:36 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 67F6D194035B for ; Fri, 22 Apr 2022 19:32:36 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 371439E68; Fri, 22 Apr 2022 19:32:36 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast04.extmail.prod.ext.rdu2.redhat.com [10.11.55.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 326AF9E64 for ; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D1B0A1014A60 for ; Fri, 22 Apr 2022 19:32:27 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-152-fg4gqTyaOmCdSaD9vylUXA-1; Fri, 22 Apr 2022 15:32:26 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 8951B21608; Fri, 22 Apr 2022 19:32:24 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 45F2313AE1; Fri, 22 Apr 2022 19:32:24 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id iG7/DsgCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:24 +0000 X-MC-Unique: 8Gr4JtjqORe82hGdkHAf1Q-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: fg4gqTyaOmCdSaD9vylUXA-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 05/11] iohelper: move runIO function to a separate module Date: Fri, 22 Apr 2022 21:32:11 +0200 Message-Id: <20220422193217.22513-6-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 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-ZM-MESSAGEID: 1650655967785100014 Content-Type: text/plain; charset="utf-8"; x-default="true" where it can be reused by other helpers. No changes other than the move. Signed-off-by: Claudio Fontana --- src/util/iohelper.c | 178 +---------------------------------- src/util/meson.build | 2 + src/util/runio.c | 214 +++++++++++++++++++++++++++++++++++++++++++ src/util/runio.h | 23 +++++ 4 files changed, 240 insertions(+), 177 deletions(-) create mode 100644 src/util/runio.c create mode 100644 src/util/runio.h diff --git a/src/util/iohelper.c b/src/util/iohelper.c index 1584321839..5a0098542e 100644 --- a/src/util/iohelper.c +++ b/src/util/iohelper.c @@ -38,183 +38,7 @@ #include "virrandom.h" #include "virstring.h" #include "virgettext.h" - -#define VIR_FROM_THIS VIR_FROM_STORAGE - -#ifndef O_DIRECT -# define O_DIRECT 0 -#endif - -struct runIOParams { - bool isBlockDev; - bool isDirect; - bool isWrite; - int fdin; - const char *fdinname; - int fdout; - const char *fdoutname; -}; - -/** - * runIOCopy: execute the IO copy based on the passed parameters - * @p: the IO parameters - * - * Execute the copy based on the passed parameters. - * - * Returns: size transfered, or < 0 on error. - */ - -static off_t -runIOCopy(const struct runIOParams p) -{ - g_autofree void *base =3D NULL; /* Location to be freed */ - char *buf =3D NULL; /* Aligned location within base */ - size_t buflen =3D 1024*1024; - intptr_t alignMask =3D 64*1024 - 1; - off_t total =3D 0; - -#if WITH_POSIX_MEMALIGN - if (posix_memalign(&base, alignMask + 1, buflen)) - abort(); - buf =3D base; -#else - buf =3D g_new0(char, buflen + alignMask); - base =3D buf; - buf =3D (char *) (((intptr_t) base + alignMask) & ~alignMask); -#endif - - while (1) { - ssize_t got; - - /* If we read with O_DIRECT from file we can't use saferead as - * it can lead to unaligned read after reading last bytes. - * If we write with O_DIRECT use should use saferead so that - * writes will be aligned. - * In other cases using saferead reduces number of syscalls. - */ - if (!p.isWrite && p.isDirect) { - if ((got =3D read(p.fdin, buf, buflen)) < 0 && - errno =3D=3D EINTR) - continue; - } else { - got =3D saferead(p.fdin, buf, buflen); - } - - if (got < 0) { - virReportSystemError(errno, _("Unable to read %s"), p.fdinname= ); - return -2; - } - if (got =3D=3D 0) - break; - - total +=3D got; - - /* handle last write size align in direct case */ - if (got < buflen && p.isDirect && p.isWrite) { - ssize_t aligned_got =3D (got + alignMask) & ~alignMask; - - memset(buf + got, 0, aligned_got - got); - - if (safewrite(p.fdout, buf, aligned_got) < 0) { - virReportSystemError(errno, _("Unable to write %s"), p.fdo= utname); - return -3; - } - - if (!p.isBlockDev && ftruncate(p.fdout, total) < 0) { - virReportSystemError(errno, _("Unable to truncate %s"), p.= fdoutname); - return -4; - } - - break; - } - - if (safewrite(p.fdout, buf, got) < 0) { - virReportSystemError(errno, _("Unable to write %s"), p.fdoutna= me); - return -3; - } - } - return total; -} - -static int -runIO(const char *path, int fd, int oflags) -{ - int ret =3D -1; - off_t total =3D 0; - struct stat sb; - struct runIOParams p; - - if (fstat(fd, &sb) < 0) { - virReportSystemError(errno, - _("Unable to access file descriptor %d path %= s"), - fd, path); - goto cleanup; - } - p.isBlockDev =3D S_ISBLK(sb.st_mode); - p.isDirect =3D O_DIRECT && (oflags & O_DIRECT); - - switch (oflags & O_ACCMODE) { - case O_RDONLY: - p.isWrite =3D false; - p.fdin =3D fd; - p.fdinname =3D path; - p.fdout =3D STDOUT_FILENO; - p.fdoutname =3D "stdout"; - break; - case O_WRONLY: - p.isWrite =3D true; - p.fdin =3D STDIN_FILENO; - p.fdinname =3D "stdin"; - p.fdout =3D fd; - p.fdoutname =3D path; - break; - - case O_RDWR: - default: - virReportSystemError(EINVAL, - _("Unable to process file with flags %d"), - (oflags & O_ACCMODE)); - goto cleanup; - } - /* To make the implementation simpler, we give up on any - * attempt to use O_DIRECT in a non-trivial manner. */ - if (!p.isBlockDev && p.isDirect) { - off_t off; - if (p.isWrite) { - if ((off =3D lseek(fd, 0, SEEK_END)) !=3D 0) { - virReportSystemError(off < 0 ? errno : EINVAL, "%s", - _("O_DIRECT write needs empty seekabl= e file")); - goto cleanup; - } - } else if ((off =3D lseek(fd, 0, SEEK_CUR)) !=3D 0) { - virReportSystemError(off < 0 ? errno : EINVAL, "%s", - _("O_DIRECT read needs entire seekable fi= le")); - goto cleanup; - } - } - total =3D runIOCopy(p); - if (total < 0) - goto cleanup; - - /* Ensure all data is written */ - if (virFileDataSync(p.fdout) < 0) { - if (errno !=3D EINVAL && errno !=3D EROFS) { - /* fdatasync() may fail on some special FDs, e.g. pipes */ - virReportSystemError(errno, _("unable to fsync %s"), p.fdoutna= me); - goto cleanup; - } - } - - ret =3D 0; - - cleanup: - if (VIR_CLOSE(fd) < 0 && - ret =3D=3D 0) { - virReportSystemError(errno, _("Unable to close %s"), path); - ret =3D -1; - } - return ret; -} +#include "runio.h" =20 static const char *program_name; =20 diff --git a/src/util/meson.build b/src/util/meson.build index 24350a3e67..58001a1699 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -175,6 +175,8 @@ keycode_dep =3D declare_dependency( =20 io_helper_sources =3D [ 'iohelper.c', + 'runio.c', + 'runio.h', ] =20 virt_util_lib =3D static_library( diff --git a/src/util/runio.c b/src/util/runio.c new file mode 100644 index 0000000000..a7b902af7e --- /dev/null +++ b/src/util/runio.c @@ -0,0 +1,214 @@ +/* + * runio.c: I/O copy function + * + * Copyright (C) 2011-2012 Red Hat, Inc. + * + * 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 +#include +#include +#include +#include + +#include "virthread.h" +#include "virfile.h" +#include "viralloc.h" +#include "virerror.h" +#include "virrandom.h" +#include "virstring.h" +#include "virgettext.h" +#include "runio.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +#ifndef O_DIRECT +# define O_DIRECT 0 +#endif + +struct runIOParams { + bool isBlockDev; + bool isDirect; + bool isWrite; + int fdin; + const char *fdinname; + int fdout; + const char *fdoutname; +}; + +/** + * runIOCopy: execute the IO copy based on the passed parameters + * @p: the IO parameters + * + * Execute the copy based on the passed parameters. + * + * Returns: size transfered, or < 0 on error. + */ + +static off_t +runIOCopy(const struct runIOParams p) +{ + g_autofree void *base =3D NULL; /* Location to be freed */ + char *buf =3D NULL; /* Aligned location within base */ + size_t buflen =3D 1024*1024; + intptr_t alignMask =3D 64*1024 - 1; + off_t total =3D 0; + +#if WITH_POSIX_MEMALIGN + if (posix_memalign(&base, alignMask + 1, buflen)) + abort(); + buf =3D base; +#else + buf =3D g_new0(char, buflen + alignMask); + base =3D buf; + buf =3D (char *) (((intptr_t) base + alignMask) & ~alignMask); +#endif + + while (1) { + ssize_t got; + + /* If we read with O_DIRECT from file we can't use saferead as + * it can lead to unaligned read after reading last bytes. + * If we write with O_DIRECT use should use saferead so that + * writes will be aligned. + * In other cases using saferead reduces number of syscalls. + */ + if (!p.isWrite && p.isDirect) { + if ((got =3D read(p.fdin, buf, buflen)) < 0 && + errno =3D=3D EINTR) + continue; + } else { + got =3D saferead(p.fdin, buf, buflen); + } + + if (got < 0) { + virReportSystemError(errno, _("Unable to read %s"), p.fdinname= ); + return -2; + } + if (got =3D=3D 0) + break; + + total +=3D got; + + /* handle last write size align in direct case */ + if (got < buflen && p.isDirect && p.isWrite) { + ssize_t aligned_got =3D (got + alignMask) & ~alignMask; + + memset(buf + got, 0, aligned_got - got); + + if (safewrite(p.fdout, buf, aligned_got) < 0) { + virReportSystemError(errno, _("Unable to write %s"), p.fdo= utname); + return -3; + } + + if (!p.isBlockDev && ftruncate(p.fdout, total) < 0) { + virReportSystemError(errno, _("Unable to truncate %s"), p.= fdoutname); + return -4; + } + + break; + } + + if (safewrite(p.fdout, buf, got) < 0) { + virReportSystemError(errno, _("Unable to write %s"), p.fdoutna= me); + return -3; + } + } + return total; +} + + +off_t +runIO(const char *path, int fd, int oflags) +{ + int ret =3D -1; + off_t total =3D 0; + struct stat sb; + struct runIOParams p; + + if (fstat(fd, &sb) < 0) { + virReportSystemError(errno, + _("Unable to access file descriptor %d path %= s"), + fd, path); + goto cleanup; + } + p.isBlockDev =3D S_ISBLK(sb.st_mode); + p.isDirect =3D O_DIRECT && (oflags & O_DIRECT); + + switch (oflags & O_ACCMODE) { + case O_RDONLY: + p.isWrite =3D false; + p.fdin =3D fd; + p.fdinname =3D path; + p.fdout =3D STDOUT_FILENO; + p.fdoutname =3D "stdout"; + break; + case O_WRONLY: + p.isWrite =3D true; + p.fdin =3D STDIN_FILENO; + p.fdinname =3D "stdin"; + p.fdout =3D fd; + p.fdoutname =3D path; + break; + + case O_RDWR: + default: + virReportSystemError(EINVAL, + _("Unable to process file with flags %d"), + (oflags & O_ACCMODE)); + goto cleanup; + } + /* To make the implementation simpler, we give up on any + * attempt to use O_DIRECT in a non-trivial manner. */ + if (!p.isBlockDev && p.isDirect) { + off_t off; + if (p.isWrite) { + if ((off =3D lseek(fd, 0, SEEK_END)) !=3D 0) { + virReportSystemError(off < 0 ? errno : EINVAL, "%s", + _("O_DIRECT write needs empty seekabl= e file")); + goto cleanup; + } + } else if ((off =3D lseek(fd, 0, SEEK_CUR)) !=3D 0) { + virReportSystemError(off < 0 ? errno : EINVAL, "%s", + _("O_DIRECT read needs entire seekable fi= le")); + goto cleanup; + } + } + total =3D runIOCopy(p); + if (total < 0) + goto cleanup; + + /* Ensure all data is written */ + if (virFileDataSync(p.fdout) < 0) { + if (errno !=3D EINVAL && errno !=3D EROFS) { + /* fdatasync() may fail on some special FDs, e.g. pipes */ + virReportSystemError(errno, _("unable to fsync %s"), p.fdoutna= me); + goto cleanup; + } + } + + ret =3D 0; + + cleanup: + if (VIR_CLOSE(fd) < 0 && + ret =3D=3D 0) { + virReportSystemError(errno, _("Unable to close %s"), path); + ret =3D -1; + } + return ret; +} diff --git a/src/util/runio.h b/src/util/runio.h new file mode 100644 index 0000000000..beb58606c9 --- /dev/null +++ b/src/util/runio.h @@ -0,0 +1,23 @@ +/* + * runio.h: I/O copy function + * + * Copyright (C) 2011-2012 Red Hat, Inc. + * + * 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 + * . + */ + +#pragma once + +off_t runIO(const char *path, int fd, int oflags); --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1650655959889236.47596674060367; Fri, 22 Apr 2022 12:32:39 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-275-eYGxdggzOJSuUH1AJSAZ6w-1; Fri, 22 Apr 2022 15:32:35 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9153C3C0FEA4; Fri, 22 Apr 2022 19:32:31 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7A68140EC01F; Fri, 22 Apr 2022 19:32:31 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 4729F1940379; Fri, 22 Apr 2022 19:32:30 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 437961940351 for ; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 238A014A5067; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast02.extmail.prod.ext.rdu2.redhat.com [10.11.55.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1F99B14A5066 for ; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id F00E89697C0 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-383-eE1r-CtrOamVHjyeCBz9mg-1; Fri, 22 Apr 2022 15:32:27 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id DF32D21602; Fri, 22 Apr 2022 19:32:24 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 978B513AE1; Fri, 22 Apr 2022 19:32:24 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id wKnIIsgCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:24 +0000 X-MC-Unique: eYGxdggzOJSuUH1AJSAZ6w-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: eE1r-CtrOamVHjyeCBz9mg-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 06/11] runio: add arguments to extend use beyond just stdin and stdout Date: Fri, 22 Apr 2022 21:32:12 +0200 Message-Id: <20220422193217.22513-7-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.85 on 10.11.54.7 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 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-ZM-MESSAGEID: 1650655961738100005 Content-Type: text/plain; charset="utf-8"; x-default="true" add arguments to runio to allow read/write from/to arbitrary file descriptors, as opposed to just stdin and stdout. Signed-off-by: Claudio Fontana --- src/util/iohelper.c | 2 +- src/util/runio.c | 6 +++--- src/util/runio.h | 17 ++++++++++++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/util/iohelper.c b/src/util/iohelper.c index 5a0098542e..93674c1e2f 100644 --- a/src/util/iohelper.c +++ b/src/util/iohelper.c @@ -96,7 +96,7 @@ main(int argc, char **argv) usage(EXIT_FAILURE); } =20 - if (fd < 0 || runIO(path, fd, oflags) < 0) + if (fd < 0 || runIO(path, fd, oflags, STDIN_FILENO, STDOUT_FILENO) < 0) goto error; =20 return 0; diff --git a/src/util/runio.c b/src/util/runio.c index a7b902af7e..ffd5141f00 100644 --- a/src/util/runio.c +++ b/src/util/runio.c @@ -134,7 +134,7 @@ runIOCopy(const struct runIOParams p) =20 =20 off_t -runIO(const char *path, int fd, int oflags) +runIO(const char *path, int fd, int oflags, int in_fd, int out_fd) { int ret =3D -1; off_t total =3D 0; @@ -155,12 +155,12 @@ runIO(const char *path, int fd, int oflags) p.isWrite =3D false; p.fdin =3D fd; p.fdinname =3D path; - p.fdout =3D STDOUT_FILENO; + p.fdout =3D out_fd; p.fdoutname =3D "stdout"; break; case O_WRONLY: p.isWrite =3D true; - p.fdin =3D STDIN_FILENO; + p.fdin =3D in_fd; p.fdinname =3D "stdin"; p.fdout =3D fd; p.fdoutname =3D path; diff --git a/src/util/runio.h b/src/util/runio.h index beb58606c9..66df588881 100644 --- a/src/util/runio.h +++ b/src/util/runio.h @@ -20,4 +20,19 @@ =20 #pragma once =20 -off_t runIO(const char *path, int fd, int oflags); +/* + * runIO: copy unidirectionally all data to/from a file descriptor. + * + * @path: the pathname corresponding to FD. + * @fd: the file descriptor to read from or write to. + * @oflags: the file status flags of FD. + * + * If the oflags indicate O_RDONLY, then the direction will be from FD, + * and @out_fd indicates the file to write to. + * + * If the oflags indicate O_WRONLY, then the direction will be to FD, + * and @in_fd indicates the file to read from. + * + * Returns the number of bytes transferred, or < 0 on error. + */ +off_t runIO(const char *path, int fd, int oflags, int in_fd, int out_fd); --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1650655961414560.0874103242089; Fri, 22 Apr 2022 12:32:41 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-125-l6iys7d3OsS0Akt2Nivohg-1; Fri, 22 Apr 2022 15:32:36 -0400 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 04D9786B8A1; Fri, 22 Apr 2022 19:32:31 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id E4077565DD7; Fri, 22 Apr 2022 19:32:30 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id DF420194036F; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id E74521940351 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id CACC740F494C; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast07.extmail.prod.ext.rdu2.redhat.com [10.11.55.23]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C695240F4948 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id AAD393C0FEA1 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-20-mYris8CgOgakwG1tXFd4-Q-1; Fri, 22 Apr 2022 15:32:27 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 3F0F921604; Fri, 22 Apr 2022 19:32:25 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id ECE8413AE1; Fri, 22 Apr 2022 19:32:24 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id QBSXN8gCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:24 +0000 X-MC-Unique: l6iys7d3OsS0Akt2Nivohg-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: mYris8CgOgakwG1tXFd4-Q-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 07/11] multifd-helper: new helper for parallel saves Date: Fri, 22 Apr 2022 21:32:13 +0200 Message-Id: <20220422193217.22513-8-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 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-ZM-MESSAGEID: 1650655961765100006 Content-Type: text/plain; charset="utf-8"; x-default="true" this helper listens on a unix socket which is provided to QEMU for multifd migration to/from files. The file descriptors are passed as command line parameters. Signed-off-by: Claudio Fontana --- src/libvirt_private.syms | 1 + src/util/meson.build | 13 +++ src/util/multifd-helper.c | 205 ++++++++++++++++++++++++++++++++++++++ src/util/virthread.c | 5 + src/util/virthread.h | 1 + 5 files changed, 225 insertions(+) create mode 100644 src/util/multifd-helper.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8a3e5f7f7c..cd279b8713 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3427,6 +3427,7 @@ virThreadCreateFull; virThreadID; virThreadIsSelf; virThreadJoin; +virThreadJoinRet; virThreadMaxName; virThreadSelf; virThreadSelfID; diff --git a/src/util/meson.build b/src/util/meson.build index 58001a1699..8ea74ff9e8 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -179,6 +179,12 @@ io_helper_sources =3D [ 'runio.h', ] =20 +multifd_helper_sources =3D [ + 'multifd-helper.c', + 'runio.c', + 'runio.h', +] + virt_util_lib =3D static_library( 'virt_util', [ @@ -216,6 +222,13 @@ if conf.has('WITH_LIBVIRTD') dtrace_gen_headers, ], } + virt_helpers +=3D { + 'name': 'libvirt_multifd_helper', + 'sources': [ + files(multifd_helper_sources), + dtrace_gen_headers, + ], + } endif =20 util_inc_dir =3D include_directories('.') diff --git a/src/util/multifd-helper.c b/src/util/multifd-helper.c new file mode 100644 index 0000000000..fab28bdb79 --- /dev/null +++ b/src/util/multifd-helper.c @@ -0,0 +1,205 @@ +/* + * multifd-helper.c: listens on Unix socket to perform I/O to multiple fil= es + * + * Copyright (C) 2022 SUSE LLC + * + * 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 + * . + * + * This has been written to support QEMU multifd migration to file, + * allowing better use of cpu resources to speed up the save/restore. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "virthread.h" +#include "virfile.h" +#include "virerror.h" +#include "virstring.h" +#include "virgettext.h" +#include "runio.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +typedef struct _multiFdConnData multiFdConnData; +struct _multiFdConnData { + int clientfd; + int filefd; + int oflags; + const char *path; + virThread tid; + + off_t total; +}; + +typedef struct _multiFdThreadArgs multiFdThreadArgs; +struct _multiFdThreadArgs { + int nchannels; + multiFdConnData *conn; /* contains main fd + nchannels */ + const char *sun_path; /* unix socket name to use for the server */ + + off_t total; +}; + +static void clientThreadFunc(void *a) +{ + multiFdConnData *c =3D a; + c->total =3D runIO(c->path, c->filefd, c->oflags, c->clientfd, c->clie= ntfd); +} + +static void serverThreadFunc(void *a) +{ + struct sockaddr_un serv_addr; + multiFdThreadArgs *args =3D a; + int i; + int sockfd =3D socket(AF_UNIX, SOCK_STREAM, 0); + const char buf[1] =3D {'R'}; + + args->total =3D -1; + + if (sockfd < 0) { + virReportSystemError(errno, "%s", _("serverThread: socket() failed= ")); + return; + } + /* initialize socket structure */ + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sun_family =3D AF_UNIX; + strncpy(serv_addr.sun_path, args->sun_path, sizeof(serv_addr.sun_path)= - 1); + unlink(args->sun_path); + if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0= ) { + virReportSystemError(errno, "%s", _("serverThread: bind() failed")= ); + goto cleanup; + } + if (listen(sockfd, args->nchannels + 1) < 0) { + virReportSystemError(errno, "%s", _("serverThread: listen() failed= ")); + goto cleanup; + } + + /* signal that the server is ready */ + if (safewrite(1, &buf, 1) !=3D 1) { + virReportSystemError(errno, "%s", _("serverThread: safewrite faile= d")); + goto cleanup; + } + + for (i =3D 0; i < args->nchannels + 1; i++) { + /* Wait for incoming connection. */ + multiFdConnData *c =3D &args->conn[i]; + if ((c->clientfd =3D accept(sockfd, NULL, NULL)) < 0) { + virReportSystemError(errno, "%s", _("serverThread: accept() fa= iled")); + goto cleanup; + } + if (virThreadCreate(&c->tid, true, &clientThreadFunc, c) < 0) { + virReportSystemError(errno, "%s", _("serverThread: client thre= ad creation failed")); + goto cleanup; + } + } + + args->total =3D 0; + for (i =3D 0; i < args->nchannels + 1; i++) { + multiFdConnData *c =3D &args->conn[i]; + if (virThreadJoinRet(&args->conn[i].tid) < 0) { + args->total =3D -1; + } else if (args->total >=3D 0) { + args->total +=3D c->total; + } + if (VIR_CLOSE(c->clientfd) < 0) { + args->total =3D -1; + } + } + + cleanup: + for (i =3D 0; i < args->nchannels + 1; i++) { + multiFdConnData *c =3D &args->conn[i]; + VIR_FORCE_CLOSE(c->clientfd); + } + if (VIR_CLOSE(sockfd) < 0) + args->total =3D -1; +} + +static const char *program_name; + +G_GNUC_NORETURN static void +usage(int status) +{ + if (status) { + fprintf(stderr, _("%s: try --help for more details"), program_name= ); + } else { + fprintf(stderr, _("Usage: %s UNIX_SOCNAME N MAINFD FD0 FD1 ... FDn= "), program_name); + } + exit(status); +} + +int +main(int argc, char **argv) +{ + virThread tid; + multiFdThreadArgs args =3D { 0 }; + int i; + + program_name =3D argv[0]; + + if (virGettextInitialize() < 0 || + virErrorInitialize() < 0) { + fprintf(stderr, _("%s: initialization failed"), program_name); + exit(EXIT_FAILURE); + } + + if (argc > 1 && STREQ(argv[1], "--help")) + usage(EXIT_SUCCESS); + if (argc < 4) + usage(EXIT_FAILURE); + + args.sun_path =3D argv[1]; + if (virStrToLong_i(argv[2], NULL, 10, &args.nchannels) < 0) + fprintf(stderr, _("%s: malformed number of channels N %s"), progra= m_name, argv[2]); + + if (argc < 4 + args.nchannels) + usage(EXIT_FAILURE); + + args.conn =3D g_new0(multiFdConnData, args.nchannels + 1); + + for (i =3D 3; i < 3 + args.nchannels + 1; i++) { + multiFdConnData *c =3D &args.conn[i - 3]; + + if (virStrToLong_i(argv[i], NULL, 10, &c->filefd) < 0) { + fprintf(stderr, _("%s: malformed FD %s"), program_name, argv[i= ]); + usage(EXIT_FAILURE); + } +#ifndef F_GETFL +#error "multifd-helper requires F_GETFL parameter of fcntl" +#endif + c->oflags =3D fcntl(c->filefd, F_GETFL); + } + + if (virThreadCreate(&tid, true, serverThreadFunc, &args) < 0) { + virReportSystemError(errno, _("%s: failed to create server thread"= ), program_name); + exit(EXIT_FAILURE); + } + + if (virThreadJoinRet(&tid) < 0) + exit(EXIT_FAILURE); + + if (args.total < 0) + exit(EXIT_FAILURE); + + exit(EXIT_SUCCESS); +} diff --git a/src/util/virthread.c b/src/util/virthread.c index 5422bb74fd..0f6c6a68fa 100644 --- a/src/util/virthread.c +++ b/src/util/virthread.c @@ -348,6 +348,11 @@ void virThreadJoin(virThread *thread) pthread_join(thread->thread, NULL); } =20 +int virThreadJoinRet(virThread *thread) +{ + return pthread_join(thread->thread, NULL); +} + void virThreadCancel(virThread *thread) { pthread_cancel(thread->thread); diff --git a/src/util/virthread.h b/src/util/virthread.h index 23abe0b6c9..5cecb9bd8a 100644 --- a/src/util/virthread.h +++ b/src/util/virthread.h @@ -89,6 +89,7 @@ int virThreadCreateFull(virThread *thread, void virThreadSelf(virThread *thread); bool virThreadIsSelf(virThread *thread); void virThreadJoin(virThread *thread); +int virThreadJoinRet(virThread *thread); =20 size_t virThreadMaxName(void); =20 --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1650655965166897.4228201811775; Fri, 22 Apr 2022 12:32:45 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-474-J5GKVRbMPauupF_GZdOGFw-1; Fri, 22 Apr 2022 15:32:42 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 22147281180C; Fri, 22 Apr 2022 19:32:35 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0C0B040EC01D; Fri, 22 Apr 2022 19:32:35 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 663E0194036A; Fri, 22 Apr 2022 19:32:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 0334B194036D for ; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id C4055565DD9; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast05.extmail.prod.ext.rdu2.redhat.com [10.11.55.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BF909565DD4 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A9A4B833942 for ; Fri, 22 Apr 2022 19:32:28 +0000 (UTC) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-96-kaDWv7cKPG2jXqeuDs2ZzQ-1; Fri, 22 Apr 2022 15:32:27 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 946E61F749; Fri, 22 Apr 2022 19:32:25 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 4D0CE13AE1; Fri, 22 Apr 2022 19:32:25 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id kJWSEMkCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:25 +0000 X-MC-Unique: J5GKVRbMPauupF_GZdOGFw-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: kaDWv7cKPG2jXqeuDs2ZzQ-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 08/11] qemu: wire up saveimage code with the multifd helper Date: Fri, 22 Apr 2022 21:32:14 +0200 Message-Id: <20220422193217.22513-9-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 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-ZM-MESSAGEID: 1650655965771100011 Content-Type: text/plain; charset="utf-8"; x-default="true" Signed-off-by: Claudio Fontana --- src/qemu/qemu_saveimage.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c index 6a65d72fb3..bb23788a5e 100644 --- a/src/qemu/qemu_saveimage.c +++ b/src/qemu/qemu_saveimage.c @@ -17,6 +17,7 @@ */ =20 #include +#include =20 #include "qemu_saveimage.h" #include "qemu_domain.h" @@ -412,7 +413,8 @@ static int qemuSaveImageCloseMultiFd(virQEMUSaveFd *mul= tiFd, int nconn, virDomai =20 static virQEMUSaveFd * qemuSaveImageCreateMultiFd(virQEMUDriver *driver, virDomainObj *vm, - const char *path, uid_t user, gid_t group, + virCommand *cmd, const char *path, + uid_t user, gid_t group, int nconn, unsigned int flags) { virQEMUSaveFd *multiFd =3D g_new0(virQEMUSaveFd, nconn); @@ -426,6 +428,8 @@ qemuSaveImageCreateMultiFd(virQEMUDriver *driver, virDo= mainObj *vm, virQEMUSaveFdFini(m, vm, -1); goto error; } + virCommandAddArgFormat(cmd, "%d", m->fd); + virCommandPassFD(cmd, m->fd, 0); } return multiFd; =20 @@ -463,8 +467,30 @@ qemuSaveImageCreate(virQEMUDriver *driver, goto cleanup; =20 if (flags & VIR_DOMAIN_SAVE_PARALLEL) { + g_autoptr(virCommand) cmd =3D NULL; + g_autofree char *helper_path =3D NULL; + qemuDomainObjPrivate *priv =3D vm->privateData; + g_autofree char *sun_path =3D g_strdup_printf("%s/save-multifd.soc= k", priv->libDir); + char buf[1]; + int helper_out =3D -1; + if (!(helper_path =3D virFileFindResource("libvirt_multifd_helper", + abs_top_builddir "/src", + LIBEXECDIR))) + goto cleanup; + cmd =3D virCommandNewArgList(helper_path, sun_path, NULL); + virCommandAddArgFormat(cmd, "%d", nconn); + virCommandAddArgFormat(cmd, "%d", saveFd.fd); + virCommandPassFD(cmd, saveFd.fd, 0); + virCommandSetOutputFD(cmd, &helper_out); /* should create pipe aut= omagically */ + /* Perform parallel multifd migration to files (main fd + channels= ) */ - if (!(multiFd =3D qemuSaveImageCreateMultiFd(driver, vm, saveFd.pa= th, cfg->user, cfg->group, nconn, flags))) + if (!(multiFd =3D qemuSaveImageCreateMultiFd(driver, vm, cmd, save= Fd.path, cfg->user, cfg->group, nconn, flags))) + goto cleanup; + if (virCommandRunAsync(cmd, NULL) < 0) + goto cleanup; + if (saferead(helper_out, &buf, 1) !=3D 1 || buf[0] !=3D 'R') + goto cleanup; + if (chown(sun_path, cfg->user, cfg->group) < 0) goto cleanup; /* still using single fd migration for now */ if (qemuMigrationSrcToFile(driver, vm, saveFd.fd, compressor, asyn= cJob) < 0) --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1650655970150990.3547288285246; Fri, 22 Apr 2022 12:32:50 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-414-cp5QVLPLNNisQEcqYhgMvw-1; Fri, 22 Apr 2022 15:32:44 -0400 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 966FB86B8A5; Fri, 22 Apr 2022 19:32:33 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7497B565DCE; Fri, 22 Apr 2022 19:32:33 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 076DB193F6EA; Fri, 22 Apr 2022 19:32:31 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 361FD1940376 for ; Fri, 22 Apr 2022 19:32:30 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 1256640F494F; Fri, 22 Apr 2022 19:32:30 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast04.extmail.prod.ext.rdu2.redhat.com [10.11.55.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0BC9840F494C for ; Fri, 22 Apr 2022 19:32:30 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E4F001014A6F for ; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-392-bTSbYEXKN-W8RT_wpKDmMg-1; Fri, 22 Apr 2022 15:32:27 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id E902B215FE; Fri, 22 Apr 2022 19:32:25 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id A22F613AE1; Fri, 22 Apr 2022 19:32:25 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id mKdyJckCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:25 +0000 X-MC-Unique: cp5QVLPLNNisQEcqYhgMvw-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: bTSbYEXKN-W8RT_wpKDmMg-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 09/11] qemu: implement qemuMigrationSrcToFilesMultiFd Date: Fri, 22 Apr 2022 21:32:15 +0200 Message-Id: <20220422193217.22513-10-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 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-ZM-MESSAGEID: 1650655971780100019 Content-Type: text/plain; charset="utf-8"; x-default="true" implement a function similar to qemuMigrationSrcToFile that migrates to multiple files using QEMU multifd. Signed-off-by: Claudio Fontana --- src/qemu/qemu_capabilities.c | 1 + src/qemu/qemu_migration.c | 129 ++++++++++++++++++++----------- src/qemu/qemu_migration.h | 7 ++ src/qemu/qemu_migration_params.c | 22 ++++++ src/qemu/qemu_migration_params.h | 9 +++ src/qemu/qemu_saveimage.c | 3 +- 6 files changed, 124 insertions(+), 47 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 6b4ed08499..01b570807b 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -1240,6 +1240,7 @@ struct virQEMUCapsStringFlags virQEMUCapsCommands[] = =3D { =20 struct virQEMUCapsStringFlags virQEMUCapsMigration[] =3D { { "rdma-pin-all", QEMU_CAPS_MIGRATE_RDMA }, + { "multifd", QEMU_MIGRATION_CAP_MULTIFD }, }; =20 /* Use virQEMUCapsQMPSchemaQueries for querying parameters of events */ diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 3e653543c6..9ce24c8cfc 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -5897,13 +5897,14 @@ qemuMigrationDstFinish(virQEMUDriver *driver, return dom; } =20 - /* Helper function called while vm is active. */ -int -qemuMigrationSrcToFile(virQEMUDriver *driver, virDomainObj *vm, - int fd, - virCommand *compressor, - virDomainAsyncJob asyncJob) +static int +qemuMigrationSrcToFileAux(virQEMUDriver *driver, virDomainObj *vm, + int fd, + virCommand *compressor, + virDomainAsyncJob asyncJob, + const char *sun_path, + int nchannels) { qemuDomainObjPrivate *priv =3D vm->privateData; bool bwParam =3D virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PA= RAM_BANDWIDTH); @@ -5914,24 +5915,24 @@ qemuMigrationSrcToFile(virQEMUDriver *driver, virDo= mainObj *vm, char *errbuf =3D NULL; virErrorPtr orig_err =3D NULL; g_autoptr(qemuMigrationParams) migParams =3D NULL; + bool needParams =3D (bwParam || sun_path); =20 if (qemuMigrationSetDBusVMState(driver, vm) < 0) return -1; =20 + if (sun_path && !virQEMUCapsGet(priv->qemuCaps, QEMU_MIGRATION_CAP_MUL= TIFD)) + return -1; + /* Increase migration bandwidth to unlimited since target is a file. * Failure to change migration speed is not fatal. */ - if (bwParam) { - if (!(migParams =3D qemuMigrationParamsNew())) - return -1; + if (needParams && !((migParams =3D qemuMigrationParamsNew()))) + return -1; =20 + if (bwParam) { if (qemuMigrationParamsSetULL(migParams, QEMU_MIGRATION_PARAM_MAX_BANDWIDTH, QEMU_DOMAIN_MIG_BANDWIDTH_MAX * 1024= * 1024) < 0) return -1; - - if (qemuMigrationParamsApply(driver, vm, asyncJob, migParams) < 0) - return -1; - priv->migMaxBandwidth =3D QEMU_DOMAIN_MIG_BANDWIDTH_MAX; } else { if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) =3D=3D 0)= { @@ -5942,6 +5943,17 @@ qemuMigrationSrcToFile(virQEMUDriver *driver, virDom= ainObj *vm, } } =20 + if (sun_path) { + qemuMigrationParamsSetCap(migParams, QEMU_MIGRATION_CAP_MULTIFD); + if (qemuMigrationParamsSetInt(migParams, + QEMU_MIGRATION_PARAM_MULTIFD_CHANNEL= S, + nchannels) < 0) + return -1; + } + + if (needParams && qemuMigrationParamsApply(driver, vm, asyncJob, migPa= rams) < 0) + return -1; + if (!virDomainObjIsActive(vm)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("guest unexpectedly quit")); @@ -5949,45 +5961,53 @@ qemuMigrationSrcToFile(virQEMUDriver *driver, virDo= mainObj *vm, return -1; } =20 - if (compressor && virPipe(pipeFD) < 0) + if (!sun_path && compressor && virPipe(pipeFD) < 0) return -1; =20 - /* All right! We can use fd migration, which means that qemu - * doesn't have to open() the file, so while we still have to - * grant SELinux access, we can do it on fd and avoid cleanup - * later, as well as skip futzing with cgroup. */ - if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, - compressor ? pipeFD[1] : fd) < 0) - goto cleanup; - if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) goto cleanup; =20 - if (!compressor) { - rc =3D qemuMonitorMigrateToFd(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - fd); + if (sun_path) { + rc =3D qemuMonitorMigrateToSocket(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, + sun_path); } else { - virCommandSetInputFD(compressor, pipeFD[0]); - virCommandSetOutputFD(compressor, &fd); - virCommandSetErrorBuffer(compressor, &errbuf); - virCommandDoAsyncIO(compressor); - if (virSetCloseExec(pipeFD[1]) < 0) { - virReportSystemError(errno, "%s", - _("Unable to set cloexec flag")); - qemuDomainObjExitMonitor(vm); - goto cleanup; - } - if (virCommandRunAsync(compressor, NULL) < 0) { - qemuDomainObjExitMonitor(vm); + /* + * All right! We can use fd migration, which means that qemu + * doesn't have to open() the file, so while we still have to + * grant SELinux access, we can do it on fd and avoid cleanup + * later, as well as skip futzing with cgroup. + */ + if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, + compressor ? pipeFD[1] : fd) < 0) goto cleanup; + + if (!compressor) { + rc =3D qemuMonitorMigrateToFd(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, + fd); + } else { + virCommandSetInputFD(compressor, pipeFD[0]); + virCommandSetOutputFD(compressor, &fd); + virCommandSetErrorBuffer(compressor, &errbuf); + virCommandDoAsyncIO(compressor); + if (virSetCloseExec(pipeFD[1]) < 0) { + virReportSystemError(errno, "%s", + _("Unable to set cloexec flag")); + qemuDomainObjExitMonitor(vm); + goto cleanup; + } + if (virCommandRunAsync(compressor, NULL) < 0) { + qemuDomainObjExitMonitor(vm); + goto cleanup; + } + rc =3D qemuMonitorMigrateToFd(priv->mon, + QEMU_MONITOR_MIGRATE_BACKGROUND, + pipeFD[1]); + if (VIR_CLOSE(pipeFD[0]) < 0 || + VIR_CLOSE(pipeFD[1]) < 0) + VIR_WARN("failed to close intermediate pipe"); } - rc =3D qemuMonitorMigrateToFd(priv->mon, - QEMU_MONITOR_MIGRATE_BACKGROUND, - pipeFD[1]); - if (VIR_CLOSE(pipeFD[0]) < 0 || - VIR_CLOSE(pipeFD[1]) < 0) - VIR_WARN("failed to close intermediate pipe"); } qemuDomainObjExitMonitor(vm); if (rc < 0) @@ -6008,7 +6028,7 @@ qemuMigrationSrcToFile(virQEMUDriver *driver, virDoma= inObj *vm, goto cleanup; } =20 - if (compressor && virCommandWait(compressor, NULL) < 0) + if (!sun_path && compressor && virCommandWait(compressor, NULL) < 0) goto cleanup; =20 qemuDomainEventEmitJobCompleted(driver, vm); @@ -6047,6 +6067,25 @@ qemuMigrationSrcToFile(virQEMUDriver *driver, virDom= ainObj *vm, return ret; } =20 +int +qemuMigrationSrcToFile(virQEMUDriver *driver, virDomainObj *vm, + int fd, + virCommand *compressor, + virDomainAsyncJob asyncJob) +{ + return qemuMigrationSrcToFileAux(driver, vm, fd, compressor, + asyncJob, NULL, -1); +} + +int +qemuMigrationSrcToFilesMultiFd(virQEMUDriver *driver, virDomainObj *vm, + virDomainAsyncJob asyncJob, + const char *sun_path, + int nchannels) +{ + return qemuMigrationSrcToFileAux(driver, vm, -1, NULL, + asyncJob, sun_path, nchannels); +} =20 int qemuMigrationSrcCancel(virQEMUDriver *driver, diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index a8afa66119..ddc8e65489 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -213,6 +213,13 @@ qemuMigrationSrcToFile(virQEMUDriver *driver, virDomainAsyncJob asyncJob) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT; =20 +int +qemuMigrationSrcToFilesMultiFd(virQEMUDriver *driver, virDomainObj *vm, + virDomainAsyncJob asyncJob, + const char *sun_path, + int nchannels) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) G_GNUC_WARN_UNUSED_RESULT; + int qemuMigrationSrcCancel(virQEMUDriver *driver, virDomainObj *vm); diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_par= ams.c index df2384b213..36174a66d8 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -1109,6 +1109,28 @@ qemuMigrationParamsFetch(virQEMUDriver *driver, } =20 =20 +void +qemuMigrationParamsSetCap(qemuMigrationParams *migParams, + virQEMUCapsFlags flag) +{ + ignore_value(virBitmapSetBit(migParams->caps, flag)); +} + + +int +qemuMigrationParamsSetInt(qemuMigrationParams *migParams, + qemuMigrationParam param, + int value) +{ + if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_INT)= < 0) + return -1; + + migParams->params[param].value.i =3D value; + migParams->params[param].set =3D true; + return 0; +} + + int qemuMigrationParamsSetULL(qemuMigrationParams *migParams, qemuMigrationParam param, diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_par= ams.h index 4a8815e776..99af73b4a4 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -123,6 +123,15 @@ qemuMigrationParamsFetch(virQEMUDriver *driver, int asyncJob, qemuMigrationParams **migParams); =20 +void +qemuMigrationParamsSetCap(qemuMigrationParams *migParams, + virQEMUCapsFlags flag); + +int +qemuMigrationParamsSetInt(qemuMigrationParams *migParams, + qemuMigrationParam param, + int value); + int qemuMigrationParamsSetULL(qemuMigrationParams *migParams, qemuMigrationParam param, diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c index bb23788a5e..9147acd70a 100644 --- a/src/qemu/qemu_saveimage.c +++ b/src/qemu/qemu_saveimage.c @@ -492,8 +492,7 @@ qemuSaveImageCreate(virQEMUDriver *driver, goto cleanup; if (chown(sun_path, cfg->user, cfg->group) < 0) goto cleanup; - /* still using single fd migration for now */ - if (qemuMigrationSrcToFile(driver, vm, saveFd.fd, compressor, asyn= cJob) < 0) + if (qemuMigrationSrcToFilesMultiFd(driver, vm, asyncJob, sun_path,= nconn) < 0) goto cleanup; if (qemuSaveImageCloseMultiFd(multiFd, nconn, vm) < 0) goto cleanup; --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 16506559674321012.167806087084; Fri, 22 Apr 2022 12:32:47 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-624-2DS5qiQbMc2HSNnOA-IzaA-1; Fri, 22 Apr 2022 15:32:42 -0400 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id ECF95281182B; Fri, 22 Apr 2022 19:32:35 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id D80DE416373; Fri, 22 Apr 2022 19:32:35 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id CB7E61940372; Fri, 22 Apr 2022 19:32:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id F2C381940351 for ; Fri, 22 Apr 2022 19:32:32 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id E325840EC022; Fri, 22 Apr 2022 19:32:32 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast02.extmail.prod.ext.rdu2.redhat.com [10.11.55.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DE08040EC020 for ; Fri, 22 Apr 2022 19:32:32 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 42B629697D3 for ; Fri, 22 Apr 2022 19:32:32 +0000 (UTC) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-481-ai_0ZfUgMUKy0Fjih80iWg-1; Fri, 22 Apr 2022 15:32:27 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 4964F1F748; Fri, 22 Apr 2022 19:32:26 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 02D4213AE1; Fri, 22 Apr 2022 19:32:25 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 4I0gOskCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:25 +0000 X-MC-Unique: 2DS5qiQbMc2HSNnOA-IzaA-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: ai_0ZfUgMUKy0Fjih80iWg-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 10/11] tools: add parallel parameter to virsh save command Date: Fri, 22 Apr 2022 21:32:16 +0200 Message-Id: <20220422193217.22513-11-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 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-ZM-MESSAGEID: 1650655967777100013 Content-Type: text/plain; charset="utf-8"; x-default="true" Signed-off-by: Claudio Fontana --- docs/manpages/virsh.rst | 23 ++++++++++++++----- tools/virsh-domain.c | 49 +++++++++++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst index d2e6528533..8d077b3cc5 100644 --- a/docs/manpages/virsh.rst +++ b/docs/manpages/virsh.rst @@ -3791,15 +3791,18 @@ save :: =20 save domain state-file [--bypass-cache] [--xml file] + [--parallel] [--parallel-connections connections] [{--running | --paused}] [--verbose] =20 -Saves a running domain (RAM, but not disk state) to a state file so that -it can be restored -later. Once saved, the domain will no longer be running on the -system, thus the memory allocated for the domain will be free for -other domains to use. ``virsh restore`` restores from this state file. +Saves a paused or running domain (RAM, but not disk state) to one or more +state files, so that it can be restored later. +Once saved, the domain will no longer be running on the system, +thus the memory allocated for the domain will be free for +other domains to use. ``virsh restore`` restores from state file/s. + If *--bypass-cache* is specified, the save will avoid the file system -cache, although this may slow down the operation. +cache; depending on the specific scenario this may slow down or speed up +the operation. =20 The progress may be monitored using ``domjobinfo`` virsh command and cance= led with ``domjobabort`` command (sent by another virsh instance). Another opt= ion @@ -3821,6 +3824,14 @@ based on the state the domain was in when the save w= as done; passing either the *--running* or *--paused* flag will allow overriding which state the ``restore`` should use. =20 +*--parallel* option will cause the save data to be sent over multiple +parallel connections to multiple files. The main save file is specified +with ``state-file``, and a number of additional connections can be +set using *--parallel-connections*, which will save to files named +``state-file``.1 , ``state-file``.2 ... up to ``connections``. + +Parallel connections may help in speeding up the save operation. + Domain saved state files assume that disk images will be unchanged between the creation and restore point. For a more complete system restore point, where the disk state is saved alongside the memory diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index d5fd8be7c3..8e7b0a7f5d 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4164,6 +4164,14 @@ static const vshCmdOptDef opts_save[] =3D { .type =3D VSH_OT_BOOL, .help =3D N_("avoid file system cache when saving") }, + {.name =3D "parallel", + .type =3D VSH_OT_BOOL, + .help =3D N_("enable parallel save to files") + }, + {.name =3D "parallel-connections", + .type =3D VSH_OT_INT, + .help =3D N_("number of connections/files for parallel save") + }, {.name =3D "xml", .type =3D VSH_OT_STRING, .completer =3D virshCompletePathLocalExisting, @@ -4193,6 +4201,11 @@ doSave(void *opaque) g_autoptr(virshDomain) dom =3D NULL; const char *name =3D NULL; const char *to =3D NULL; + virTypedParameterPtr params =3D NULL; + int nparams =3D 0; + int maxparams =3D 0; + int intOpt =3D 0; + int rv =3D -1; unsigned int flags =3D 0; const char *xmlfile =3D NULL; g_autofree char *xml =3D NULL; @@ -4206,29 +4219,46 @@ doSave(void *opaque) goto out_sig; #endif /* !WIN32 */ =20 - if (vshCommandOptStringReq(ctl, cmd, "file", &to) < 0) + if ((rv =3D vshCommandOptStringReq(ctl, cmd, "file", &to)) < 0) { goto out; - + } else { + if (virTypedParamsAddString(¶ms, &nparams, &maxparams, + VIR_SAVE_PARAM_TO, to) < 0) + goto out; + } if (vshCommandOptBool(cmd, "bypass-cache")) flags |=3D VIR_DOMAIN_SAVE_BYPASS_CACHE; + if (vshCommandOptBool(cmd, "parallel")) + flags |=3D VIR_DOMAIN_SAVE_PARALLEL; + if ((rv =3D vshCommandOptInt(ctl, cmd, "parallel-connections", &intOpt= )) < 0) { + goto out; + } else if (rv > 0) { + if (virTypedParamsAddInt(¶ms, &nparams, &maxparams, + VIR_SAVE_PARAM_PARALLEL_CONNECTIONS, intO= pt) < 0) + goto out; + } if (vshCommandOptBool(cmd, "running")) flags |=3D VIR_DOMAIN_SAVE_RUNNING; if (vshCommandOptBool(cmd, "paused")) flags |=3D VIR_DOMAIN_SAVE_PAUSED; =20 - if (vshCommandOptStringReq(ctl, cmd, "xml", &xmlfile) < 0) + if ((rv =3D vshCommandOptStringReq(ctl, cmd, "xml", &xmlfile)) < 0) goto out; =20 if (!(dom =3D virshCommandOptDomain(ctl, cmd, &name))) goto out; =20 - if (xmlfile && - virFileReadAll(xmlfile, VSH_MAX_XML_FILE, &xml) < 0) { - vshReportError(ctl); - goto out; + if (xmlfile) { + if (virFileReadAll(xmlfile, VSH_MAX_XML_FILE, &xml) < 0) { + vshReportError(ctl); + goto out; + } else if (virTypedParamsAddString(¶ms, &nparams, &maxparams, + VIR_SAVE_PARAM_DXML, xml) < 0) + goto out; } - - if (flags || xml) { + if (flags & VIR_DOMAIN_SAVE_PARALLEL) { + rc =3D virDomainSaveParametersFlags(dom, params, nparams, flags); + } else if (flags || xml) { rc =3D virDomainSaveFlags(dom, to, xml, flags); } else { rc =3D virDomainSave(dom, to); @@ -4242,6 +4272,7 @@ doSave(void *opaque) data->ret =3D 0; =20 out: + virTypedParamsFree(params, nparams); #ifndef WIN32 pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL); out_sig: --=20 2.34.1 From nobody Sat May 18 15:49:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=suse.de Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 165065596288148.02282317859351; Fri, 22 Apr 2022 12:32:42 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-192-cKu2E4HuO_GxHH_PnO_mmQ-1; Fri, 22 Apr 2022 15:32:38 -0400 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 81F9E1E1800F; Fri, 22 Apr 2022 19:32:32 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 39404416373; Fri, 22 Apr 2022 19:32:32 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 93109193F6DB; Fri, 22 Apr 2022 19:32:30 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 1D8931940374 for ; Fri, 22 Apr 2022 19:32:30 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id EC8E040F494B; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast07.extmail.prod.ext.rdu2.redhat.com [10.11.55.23]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E8D9D40F4948 for ; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D142D3C0FEAB for ; Fri, 22 Apr 2022 19:32:29 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-79-_9GQxAARPcKZZvUCv1LAAA-1; Fri, 22 Apr 2022 15:32:28 -0400 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 9E98921600; Fri, 22 Apr 2022 19:32:26 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 57F3C13AE1; Fri, 22 Apr 2022 19:32:26 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id YIkwE8oCY2L8bAAAMHmgww (envelope-from ); Fri, 22 Apr 2022 19:32:26 +0000 X-MC-Unique: cKu2E4HuO_GxHH_PnO_mmQ-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: _9GQxAARPcKZZvUCv1LAAA-1 From: Claudio Fontana To: =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= Subject: [libvirt RFC v2 11/11] qemu: add migration parameter multifd-compression Date: Fri, 22 Apr 2022 21:32:17 +0200 Message-Id: <20220422193217.22513-12-cfontana@suse.de> In-Reply-To: <20220422193217.22513-1-cfontana@suse.de> References: <20220422193217.22513-1-cfontana@suse.de> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: libvir-list@redhat.com, "Dr . David Alan Gilbert" , Claudio Fontana Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 2.85 on 10.11.54.10 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-ZM-MESSAGEID: 1650655963779100009 Content-Type: text/plain; charset="utf-8"; x-default="true" use zstd which is the only really interesting one. Signed-off-by: Claudio Fontana --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_migration.c | 6 ++++ src/qemu/qemu_migration_params.c | 49 ++++++++++++++++---------------- src/qemu/qemu_migration_params.h | 6 ++++ 5 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 01b570807b..9ad34969f7 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -669,6 +669,7 @@ VIR_ENUM_IMPL(virQEMUCaps, /* 425 */ "blockdev.nbd.tls-hostname", /* QEMU_CAPS_BLOCKDEV_NBD_TLS_H= OSTNAME */ "memory-backend-file.prealloc-threads", /* QEMU_CAPS_MEMORY_= BACKEND_PREALLOC_THREADS */ + "migration-param.multifd-compression", /* QEMU_CAPS_MIGRATIO= N_PARAM_MULTIFD_COMPRESSION */ ); =20 =20 @@ -1616,6 +1617,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSc= hemaQueries[] =3D { { "migrate-set-parameters/arg-type/downtime-limit", QEMU_CAPS_MIGRATIO= N_PARAM_DOWNTIME }, { "migrate-set-parameters/arg-type/xbzrle-cache-size", QEMU_CAPS_MIGRA= TION_PARAM_XBZRLE_CACHE_SIZE }, { "migrate-set-parameters/arg-type/block-bitmap-mapping/bitmaps/transf= orm", QEMU_CAPS_MIGRATION_PARAM_BLOCK_BITMAP_MAPPING }, + { "migrate-set-parameters/arg-type/multifd-compression", QEMU_CAPS_MIG= RATION_PARAM_MULTIFD_COMPRESSION }, { "nbd-server-start/arg-type/tls-creds", QEMU_CAPS_NBD_TLS }, { "nbd-server-add/arg-type/bitmap", QEMU_CAPS_NBD_BITMAP }, { "netdev_add/arg-type/+vhost-vdpa", QEMU_CAPS_NETDEV_VHOST_VDPA }, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 948029d60d..2b0de4113c 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -644,6 +644,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for = syntax-check */ /* 425 */ QEMU_CAPS_BLOCKDEV_NBD_TLS_HOSTNAME, /* tls hostname can be overriden = for NBD clients */ QEMU_CAPS_MEMORY_BACKEND_PREALLOC_THREADS, /* -object memory-backend-*= .prealloc-threads */ + QEMU_CAPS_MIGRATION_PARAM_MULTIFD_COMPRESSION, /* multifd-compression = in migrate-set-parameters */ =20 QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 9ce24c8cfc..65a3343622 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -5949,6 +5949,12 @@ qemuMigrationSrcToFileAux(virQEMUDriver *driver, vir= DomainObj *vm, QEMU_MIGRATION_PARAM_MULTIFD_CHANNEL= S, nchannels) < 0) return -1; + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_PARAM_MULTI= FD_COMPRESSION)) { + if (qemuMigrationParamsSetString(migParams, + QEMU_MIGRATION_PARAM_MULTIFD_= COMPRESSION, + "zstd") < 0) + return -1; + } } =20 if (needParams && qemuMigrationParamsApply(driver, vm, asyncJob, migPa= rams) < 0) diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_par= ams.c index 36174a66d8..f6b9dc337d 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -115,6 +115,7 @@ VIR_ENUM_IMPL(qemuMigrationParam, "xbzrle-cache-size", "max-postcopy-bandwidth", "multifd-channels", + "multifd-compression", ); =20 typedef struct _qemuMigrationParamsAlwaysOnItem qemuMigrationParamsAlwaysO= nItem; @@ -234,6 +235,7 @@ static const qemuMigrationParamType qemuMigrationParamT= ypes[] =3D { [QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE] =3D QEMU_MIGRATION_PARAM_TYPE= _ULL, [QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH] =3D QEMU_MIGRATION_PARAM= _TYPE_ULL, [QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS] =3D QEMU_MIGRATION_PARAM_TYPE_= INT, + [QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION] =3D QEMU_MIGRATION_PARAM_TY= PE_STRING, }; G_STATIC_ASSERT(G_N_ELEMENTS(qemuMigrationParamTypes) =3D=3D QEMU_MIGRATIO= N_PARAM_LAST); =20 @@ -898,31 +900,6 @@ qemuMigrationParamsApply(virQEMUDriver *driver, } =20 =20 -/** - * qemuMigrationParamsSetString: - * @migrParams: migration parameter object - * @param: parameter to set - * @value: new value - * - * Enables and sets the migration parameter @param in @migrParams. Returns= 0 on - * success and -1 on error. Libvirt error is reported. - */ -static int -qemuMigrationParamsSetString(qemuMigrationParams *migParams, - qemuMigrationParam param, - const char *value) -{ - if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_STRI= NG) < 0) - return -1; - - migParams->params[param].value.s =3D g_strdup(value); - - migParams->params[param].set =3D true; - - return 0; -} - - /* qemuMigrationParamsEnableTLS * @driver: pointer to qemu driver * @vm: domain object @@ -1144,6 +1121,28 @@ qemuMigrationParamsSetULL(qemuMigrationParams *migPa= rams, return 0; } =20 +/** + * qemuMigrationParamsSetString: + * @migrParams: migration parameter object + * @param: parameter to set + * @value: new value + * + * Enables and sets the migration parameter @param in @migrParams. Returns= 0 on + * success and -1 on error. Libvirt error is reported. + */ +int +qemuMigrationParamsSetString(qemuMigrationParams *migParams, + qemuMigrationParam param, + const char *value) +{ + if (qemuMigrationParamsCheckType(param, QEMU_MIGRATION_PARAM_TYPE_STRI= NG) < 0) + return -1; + + migParams->params[param].value.s =3D g_strdup(value); + migParams->params[param].set =3D true; + return 0; +} + =20 /** * Returns -1 on error, diff --git a/src/qemu/qemu_migration_params.h b/src/qemu/qemu_migration_par= ams.h index 99af73b4a4..23a4e0c8a2 100644 --- a/src/qemu/qemu_migration_params.h +++ b/src/qemu/qemu_migration_params.h @@ -60,6 +60,7 @@ typedef enum { QEMU_MIGRATION_PARAM_XBZRLE_CACHE_SIZE, QEMU_MIGRATION_PARAM_MAX_POSTCOPY_BANDWIDTH, QEMU_MIGRATION_PARAM_MULTIFD_CHANNELS, + QEMU_MIGRATION_PARAM_MULTIFD_COMPRESSION, =20 QEMU_MIGRATION_PARAM_LAST } qemuMigrationParam; @@ -137,6 +138,11 @@ qemuMigrationParamsSetULL(qemuMigrationParams *migPara= ms, qemuMigrationParam param, unsigned long long value); =20 +int +qemuMigrationParamsSetString(qemuMigrationParams *migParams, + qemuMigrationParam param, + const char *value); + int qemuMigrationParamsGetULL(qemuMigrationParams *migParams, qemuMigrationParam param, --=20 2.34.1