From nobody Mon Apr 29 18:59:18 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; dkim=pass; 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=nutanix.com ARC-Seal: i=1; a=rsa-sha256; t=1665048840; cv=none; d=zohomail.com; s=zohoarc; b=Z+6aPrwRno5EKlu6HKeCUbofG60WUUPoPwv/Q/F1IiMaaKo3E67LdBqUsqRZLbQ6cza6rNn6PLKZiGP0PuVOaflgNU0mjC6xVULGY95J7/X9+8YM0TnkwClpYeV8Y2sbdGbI6Jh1IUtC2TLR7tMS5fmDMn1V+attI+VR74tpqbY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1665048840; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=v2u5VaNoGorNTbyOQ5K6qHHKqIeJ4EoyO/ZEE37famM=; b=Y/PlpOQo4VL0Hi8iy7Y8yMoFEUEXFLACvC9YQccKK7ykimc8F4fTdARAi89+HeYR6L3fAfriaAnffn4xE1htcy2HFsMsC3exCVESmCWoAEPCdotDGOEtp5vMrfy41DrrO/NF73M8uKo2Ndt95MEEAnW5+Wqw6033yctyVFTgiY8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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 header.from= (p=none dis=none) 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 1665048840791376.8953135189753; Thu, 6 Oct 2022 02:34:00 -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-361-TbvIkW5WNQOjEtU7YXMS1g-1; Thu, 06 Oct 2022 05:33:56 -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 A522C29324B3; Thu, 6 Oct 2022 09:33:53 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (unknown [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8A335492B0E; Thu, 6 Oct 2022 09:33:53 +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 034721947B89; Thu, 6 Oct 2022 09:33:53 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id B86521946A4E for ; Thu, 6 Oct 2022 09:33:50 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id AC6A9111CD38; Thu, 6 Oct 2022 09:33:50 +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 A34BF111CD35 for ; Thu, 6 Oct 2022 09:33:47 +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 1900D803D4B for ; Thu, 6 Oct 2022 09:33:47 +0000 (UTC) Received: from mx0b-002c1b01.pphosted.com (mx0b-002c1b01.pphosted.com [148.163.155.12]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-601-tw3juYNBN--euboMdyraxg-1; Thu, 06 Oct 2022 05:33:45 -0400 Received: from pps.filterd (m0127844.ppops.net [127.0.0.1]) by mx0b-002c1b01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 2960YprX022771 for ; Thu, 6 Oct 2022 02:33:44 -0700 Received: from nam10-mw2-obe.outbound.protection.outlook.com (mail-mw2nam10lp2108.outbound.protection.outlook.com [104.47.55.108]) by mx0b-002c1b01.pphosted.com (PPS) with ESMTPS id 3jxn32bf67-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 06 Oct 2022 02:33:44 -0700 Received: from PH0PR02MB7384.namprd02.prod.outlook.com (2603:10b6:510:12::12) by SA1PR02MB8429.namprd02.prod.outlook.com (2603:10b6:806:1f4::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5676.24; Thu, 6 Oct 2022 09:33:41 +0000 Received: from PH0PR02MB7384.namprd02.prod.outlook.com ([fe80::a88:8114:7d28:5834]) by PH0PR02MB7384.namprd02.prod.outlook.com ([fe80::a88:8114:7d28:5834%7]) with mapi id 15.20.5676.034; Thu, 6 Oct 2022 09:33:41 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1665048839; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=v2u5VaNoGorNTbyOQ5K6qHHKqIeJ4EoyO/ZEE37famM=; b=hEAx48sAvpLMxV14Y7jJ00athxcKc3sshkhtQP5VIKaZVNUOEPErBOecrEw7HBRcl7MK9F BKhXwwCyx2qXReP7N9wQWPAFLzJK8Plaf5KPUNvJPcZjDbUgYhirGVw2xTEiujl6K0r5ye D6N71G2uRBOF1CG6R3DTj82fD42I/Wg= X-MC-Unique: TbvIkW5WNQOjEtU7YXMS1g-1 X-Original-To: libvir-list@listman.corp.redhat.com X-MC-Unique: tw3juYNBN--euboMdyraxg-1 From: "manish.mishra" To: manish.mishra@nutanix.com, libvir-list@redhat.com Subject: [RFC 1/1] Check for pid re-use before killing domain process Date: Thu, 6 Oct 2022 09:33:31 +0000 Message-Id: <20221006093331.237161-2-manish.mishra@nutanix.com> In-Reply-To: <20221006093331.237161-1-manish.mishra@nutanix.com> References: <20221006093331.237161-1-manish.mishra@nutanix.com> X-ClientProxiedBy: BYAPR11CA0067.namprd11.prod.outlook.com (2603:10b6:a03:80::44) To PH0PR02MB7384.namprd02.prod.outlook.com (2603:10b6:510:12::12) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH0PR02MB7384:EE_|SA1PR02MB8429:EE_ X-MS-Office365-Filtering-Correlation-Id: c979cf4c-7327-49af-e9d2-08daa77dda86 x-proofpoint-crosstenant: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0 X-Microsoft-Antispam-Message-Info: ePEiCIWGtmRoxbkhrfqU2Dno+0CcxVDMA0bdC+VMCBQCu8JuMeN2KkNlo/H/zFEK1w5j9tOECAMHSgGgtszFZSuW3jAU8jZoALnrmN07oGnMI3K5DriL4RLd6ZREjAYLHoID8B7KkFs/ArBHWeXKuSxNb+pm1aH8aZ4A3V3GYNgWoSLeN/lnkSBRPi5tk5z4dvBhAJtmvQ9331YzdMPoV53Q5+073ksANLwss60B3JGWKY7Tx+YHMYKdp5Dp58mrAQB/KpacdOhDR4JYtmpjFeN8WmznvrRVtzoWJps4RE1MVd5yFszA/9gDmuZ2Rg/tgtL88z0YucOX0B6iVH26EAL1CYIZHdO+82ZoxbTna9rSBOOke9mWRHkoqJ4AGcYQIlaek5aBABiWDU3vvyi4Pg7wRxeiufYURidkgvnHQ5UtN8Fc+EENO5LP3LK20RVXUxMoRCM1M+C29I4bQQ6pMQwR5nXuMpb8YWZr7jUv57leVo2le1G9N+VrzfSiX8z4GbEAprNDP/dr3PWEUQZ6oSdX7S+0p2+hCwLYeTTVno5Th/4yp9gID5J/0jeiB4KttNnrlyRr5FoKpnw3YtrHafefruU+Qk8NIBn6vhBi3+2whG9RepX3XsiD+p+F7SYGcNLIGSHGgBcNyXcAeaLNnUPW8HbNT2AqEyQR4IhZtf5c4hFm9lVVqQuQvB0OgVo5G0ytsJ48feiLOXjwF2CtoC58Y1UMlBq8+T5pXuXFFSNM0XSh6Hxi/+BGIQ1dx4ZQNrpYhr1M89ZhIqryBmvcHQ== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR02MB7384.namprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230022)(136003)(396003)(376002)(366004)(346002)(39860400002)(451199015)(66946007)(5660300002)(8936002)(6666004)(66476007)(66556008)(41300700001)(26005)(52116002)(6512007)(83380400001)(1076003)(38100700002)(30864003)(186003)(2616005)(6506007)(38350700002)(2906002)(36756003)(86362001)(6486002)(478600001)(8676002)(316002); DIR:OUT; SFP:1102 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?6ZWg1NzYbiaN6kY9+M/3BYS0QDTWiUfOFoyTznD9qaqakow76EGlGMMlnfXT?= =?us-ascii?Q?r8vDx//V3t81fsiEdG1TT5Ai38+iQViDLP5ytDZijcon1SZ+A/9IC1tG2HHe?= =?us-ascii?Q?X/nlzi0sPyda/zXj/ifWHH1xNdvg2FmNrWnYtHjqAVJoUI8dkhgYa2ZcAPEz?= =?us-ascii?Q?G6wZliq+ZYMw3lQktasdPfBdB12dEjhRK5DjnXL4cRRGCLwFW1iXsLn5tHKe?= =?us-ascii?Q?RNaYuu1Gijr5a+864oF9RtAA7T8rSyfZG/1wY4eMG7jvSPS8gcrX9EV/pEBs?= =?us-ascii?Q?sIWgTxnh2BqEQ7+po4/TteGRL+lPUwLiauwyIZYVEb+2T91PZ5ZqxitI9TXI?= =?us-ascii?Q?ZIXYseWhKYx1Z0U0v6+lcMcBesNVIWKuwxpYH2GRBD09vgq7TCkq3Ufb1O6A?= =?us-ascii?Q?d+J6+83MNeyLxHs4RhbzAD503B9vfFBxSAB0TG192aQQESGXcB8MKVQMHP1X?= =?us-ascii?Q?s4kYnQYdjmjxbbfWUAdTJbD+gj4ehci1XrnXR11pkfPhYqh7jvs51S9dzumV?= =?us-ascii?Q?q5miO2gEshbPwuW4IBBkHBsE/X2leqjgA6WTXcxSFKvvqtQNL5PyG8U7fVTg?= =?us-ascii?Q?esg8sWQm9TxRK6tmdmI7Ks1lmeeUv3js/B5UZl/cs3ly4ItAkyFoHd5uDJwy?= =?us-ascii?Q?J7MI13p9gwn8Snyro0DCi1rAj7ecLBs3CwcUdF7axMoit7c31Lcl0mFhy89X?= =?us-ascii?Q?12Tmd7AlOxvz7/uz4q2o5xHuORxCj6IX1GrbcEPKPwqlHP3movsLq28kIlU0?= =?us-ascii?Q?G6aLuUUdgpLv8gJhVF0uUQL8av8kXh2hP721EHBrOecZFnIO5xJYF3pMvXTB?= =?us-ascii?Q?4v6rsLbV0ONUQbNEgavL875yiBK/ZIhScKniS5VQntRPjuGtp3E9DEI+L6zq?= =?us-ascii?Q?AQ2x2ny1eXHRrwdCwKXFlAc+bUsc84WNi6tgJ193kMKPeEPHp2HlDFZ1n2M7?= =?us-ascii?Q?jmYoxgPoirKvhoZUoLGDNBScjPNy3/Uelr2VzcdEll53+35ai5Gbi5ExR2MS?= =?us-ascii?Q?cFrt7SUMdfVlJrqLvHWBVPCl1OUO0s8pXD7A+bSJ+rFEqNlmtwC3lr4Dkmzu?= =?us-ascii?Q?QXEbT/O0gz24rpv7RwJaDUtre/dNWiIWpFCMYaIbSCLdQGU1KQ3hZ+lyh/7V?= =?us-ascii?Q?3HcUiVajQrbazlV4nTJzs4lbBsTTYW3i6FaxQ9QdnbFpdXzm4tfrkDZg9TAB?= =?us-ascii?Q?d4xnWFj+xYf5VDHgRRV2J9+26FydEClNCTck8jnl4F8soUTVNbI1MNBYnjvi?= =?us-ascii?Q?KRCo20/oxunFaEIdvXCaCXftHo3nHLJd5xfhonLrM0Tqr1kp5JZi7rff/R+U?= =?us-ascii?Q?07eLZckzETQADwUW2H31q4pMf3/Y1Sie85lDohLitrfaWGAZxh6UUdQQscZi?= =?us-ascii?Q?4ArZFJBfq3NQLWj9tu1ZGykmT49YPyykMlOROZ205BeS9jrAIDp9wfSq5LY3?= =?us-ascii?Q?8hzlY6NV3As5T4fI+tvfOpOEl1wfk+G+jtd6soE55iV9rLLBUNXDKbja+zyG?= =?us-ascii?Q?kX+Yf8NlZRlyByo5r2pkABjymXo3IwP4rczipexFRww97kcE6IP/dBPrFvFP?= =?us-ascii?Q?RNxmwBBLigGKYFsaMSq8yx/ZPbfxX6BxYTWyAKAtsbHm/CwH+vdSHtQfWU0V?= =?us-ascii?Q?lw=3D=3D?= X-OriginatorOrg: nutanix.com X-MS-Exchange-CrossTenant-Network-Message-Id: c979cf4c-7327-49af-e9d2-08daa77dda86 X-MS-Exchange-CrossTenant-AuthSource: PH0PR02MB7384.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Oct 2022 09:33:40.9902 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: bb047546-786f-4de1-bd75-24e5b6f79043 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9ysfVqx0IedrJ64DfHYVxM+AOYQX1jvF7H0DkKFUofB+Q5cNwfSCtnRViC6MT9uMTie5gBKMsaBseCPP0PgpNNE1ojJ5KFzh9Qq428sndi0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA1PR02MB8429 X-Proofpoint-GUID: n_rMxMytqNnxaULPPp2tysD01VDfx4Hp X-Proofpoint-ORIG-GUID: n_rMxMytqNnxaULPPp2tysD01VDfx4Hp X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.528,FMLib:17.11.122.1 definitions=2022-10-05_05,2022-10-06_01,2022-06-22_01 X-Proofpoint-Spam-Reason: safe 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 3.1 on 10.11.54.3 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: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1665048842145100001 Content-Type: text/plain; charset="utf-8" Libvirt stores pid of domain(e.g Qemu) process when a domain process is sta= rted and same pid is used while destroying domain process. There is always a race possible that before libvirt tries to kill domain process, actual domain pr= ocess is already dead and same pid is used for another process. In that case libv= irt may kill an innocent process. With this patch we store start time of domain process when domain is starte= d and we match stime again while killing domain process if it does not match we c= an assume domain process is already dead. This patch series tries to create a generic interface which can be used for non-domain processes too, even though initial patch series handles re-use of domain process only. Signed-off-by: manish.mishra --- src/conf/domain_conf.c | 14 ++- src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 7 ++ src/qemu/qemu_domain.h | 1 + src/qemu/qemu_process.c | 49 ++++++-- src/util/vircommand.c | 37 ++++++ src/util/vircommand.h | 3 + src/util/virpidfile.c | 113 +++++++++++++----- src/util/virpidfile.h | 17 +++ src/util/virprocess.c | 73 ++++++++++- src/util/virprocess.h | 8 ++ .../qemustatusxml2xmldata/backup-pull-in.xml | 2 +- .../blockjob-blockdev-in.xml | 2 +- .../blockjob-mirror-in.xml | 2 +- .../migration-in-params-in.xml | 2 +- .../migration-out-nbd-bitmaps-in.xml | 2 +- .../migration-out-nbd-in.xml | 2 +- .../migration-out-nbd-out.xml | 2 +- .../migration-out-nbd-tls-in.xml | 2 +- .../migration-out-nbd-tls-out.xml | 2 +- .../migration-out-params-in.xml | 2 +- tests/qemustatusxml2xmldata/modern-in.xml | 2 +- tests/qemustatusxml2xmldata/upgrade-in.xml | 2 +- tests/qemustatusxml2xmldata/upgrade-out.xml | 2 +- .../qemustatusxml2xmldata/vcpus-multi-in.xml | 2 +- 25 files changed, 295 insertions(+), 56 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a609cc4f68..1639da04c7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -19031,6 +19031,13 @@ virDomainObjParseXML(xmlXPathContextPtr ctxt, } obj->pid =3D (pid_t)val; =20 + if (virXPathLong("string(./@stime)", ctxt, &val) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("invalid stime")); + return NULL; + } + obj->stime =3D val; + if ((n =3D virXPathNodeSet("./taint", ctxt, &taintNodes)) < 0) return NULL; for (i =3D 0; i < n; i++) { @@ -27372,10 +27379,13 @@ virDomainObjFormat(virDomainObj *obj, size_t i; =20 state =3D virDomainObjGetState(obj, &reason); - virBufferAsprintf(&buf, "\n", + virBufferAsprintf(&buf, + "\n", virDomainStateTypeToString(state), virDomainStateReasonToString(state, reason), - (long long)obj->pid); + (long long)obj->pid, + obj->stime); virBufferAdjustIndent(&buf, 2); =20 for (i =3D 0; i < VIR_DOMAIN_TAINT_LAST; i++) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 352b88eae5..7093180df5 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3097,6 +3097,7 @@ struct _virDomainObj { virDomainJobObj *job; =20 pid_t pid; /* 0 for no PID, avoid negative values like -1 */ + long long stime; /* Start time for domain process to check pid re-use.= */ virDomainStateReason state; =20 unsigned int autostart : 1; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5be40dbefe..e61e057e60 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2115,6 +2115,7 @@ virCommandSetPidFile; virCommandSetPreExecHook; virCommandSetSELinuxLabel; virCommandSetSendBuffer; +virCommandSetStimeFile; virCommandSetUID; virCommandSetUmask; virCommandSetWorkingDirectory; @@ -3128,6 +3129,9 @@ virPidFileRelease; virPidFileReleasePath; virPidFileWrite; virPidFileWritePath; +virPidStimeFileAcquirePath; +virPidStimeFileBuildPath; +virPidStimeFileReadPath; =20 =20 # util/virpolkit.h @@ -3161,6 +3165,9 @@ virProcessGroupKill; virProcessKill; virProcessKillPainfully; virProcessKillPainfullyDelay; +virProcessKillPainfullyDelayWithStime; +virProcessKillPainfullyWithStime; +virProcessKillWithStime; virProcessNamespaceAvailable; virProcessRunInFork; virProcessRunInMountNamespace; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index a22deaf113..30395491d9 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -114,6 +114,7 @@ struct _qemuDomainObjPrivate { =20 bool beingDestroyed; char *pidfile; + char *stimefile; =20 virDomainPCIAddressSet *pciaddrs; virDomainUSBAddressSet *usbaddrs; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 97336e2622..d0f60832fb 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -129,6 +129,12 @@ qemuProcessRemoveDomainStatus(virQEMUDriver *driver, errno !=3D ENOENT) VIR_WARN("Failed to remove PID file for %s: %s", vm->def->name, g_strerror(errno)); + + if (priv->stimefile && + unlink(priv->stimefile) < 0 && + errno !=3D ENOENT) + VIR_WARN("Failed to remove Stime file for %s: %s", + vm->def->name, g_strerror(errno)); } =20 =20 @@ -7124,6 +7130,21 @@ qemuProcessPrepareHost(virQEMUDriver *driver, return -1; } =20 + VIR_FREE(priv->stimefile); + if (!(priv->stimefile =3D virPidStimeFileBuildPath(cfg->stateDir, vm->= def->name))) { + virReportSystemError(errno, + "%s", _("Failed to build stimefile path.")); + return -1; + } + + if (unlink(priv->stimefile) < 0 && + errno !=3D ENOENT) { + virReportSystemError(errno, + _("Cannot remove stale Stime file %s"), + priv->stimefile); + return -1; + } + VIR_DEBUG("Write domain masterKey"); if (qemuDomainWriteMasterKeyFile(driver, vm) < 0) return -1; @@ -7550,6 +7571,7 @@ qemuProcessLaunch(virConnectPtr conn, virCommandSetErrorFD(cmd, &logfile); virCommandNonblockingFDs(cmd); virCommandSetPidFile(cmd, priv->pidfile); + virCommandSetStimeFile(cmd, priv->stimefile); virCommandDaemonize(cmd); virCommandRequireHandshake(cmd); =20 @@ -7574,6 +7596,12 @@ qemuProcessLaunch(virConnectPtr conn, goto cleanup; } =20 + if ((rv =3D virPidStimeFileReadPath(priv->stimefile, &vm->stime)) < 0)= { + VIR_DEBUG("Failed to get stime for pid=3D%lld vm=3D%p name=3D%s", + (long long)vm->pid, vm, vm->def->name); + goto cleanup; + } + VIR_DEBUG("Writing early domain status to disk"); if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0) goto cleanup; @@ -8009,18 +8037,21 @@ qemuProcessKill(virDomainObj *vm, unsigned int flag= s) } =20 if (flags & VIR_QEMU_PROCESS_KILL_NOWAIT) { - virProcessKill(vm->pid, - (flags & VIR_QEMU_PROCESS_KILL_FORCE) ? - SIGKILL : SIGTERM); + virProcessKillWithStime(vm->pid, + (flags & VIR_QEMU_PROCESS_KILL_FORCE) ? + SIGKILL : SIGTERM, + vm->stime); return 0; } =20 /* Request an extra delay of two seconds per current nhostdevs * to be safe against stalls by the kernel freeing up the resources */ - return virProcessKillPainfullyDelay(vm->pid, - !!(flags & VIR_QEMU_PROCESS_KILL_F= ORCE), - vm->def->nhostdevs * 2, - false); + return virProcessKillPainfullyDelayWithStime(vm->pid, + !!(flags & + VIR_QEMU_PROCESS_KILL_FOR= CE), + vm->def->nhostdevs * 2, + false, + vm->stime); } =20 =20 @@ -8702,6 +8733,10 @@ qemuProcessReconnect(void *opaque) if (!(priv->pidfile =3D virPidFileBuildPath(cfg->stateDir, obj->def->n= ame))) goto error; =20 + if (!(priv->stimefile =3D + virPidStimeFileBuildPath(cfg->stateDir, obj->def->name))) + goto error; + /* Restore the masterKey */ if (qemuDomainMasterKeyReadFile(priv) < 0) goto error; diff --git a/src/util/vircommand.c b/src/util/vircommand.c index 4e003266bf..1c95833457 100644 --- a/src/util/vircommand.c +++ b/src/util/vircommand.c @@ -125,6 +125,7 @@ struct _virCommand { =20 pid_t pid; char *pidfile; + char *stimefile; bool reap; bool rawStatus; =20 @@ -803,6 +804,8 @@ virExec(virCommand *cmd) =20 if (cmd->pidfile) { int pidfilefd =3D -1; + int stimefilefd =3D -1; + long long unsigned stime =3D 0; char c; =20 pidfilefd =3D virPidFileAcquirePath(cmd->pidfile, false, pid); @@ -814,6 +817,22 @@ virExec(virCommand *cmd) goto fork_error; } =20 + if (cmd->stimefile) { + /* If stimefile is present, get start time of process and store + * in stimefile. + */ + if (virProcessGetStartTime(pid, &stime) < 0) { + virReportSystemError(errno, + _("Failed to get start time for pid %= d"), + pid); + goto fork_error; + } + stimefilefd =3D virPidStimeFileAcquirePath(cmd->stimefile, fal= se, + (long long)stime); + if (stimefilefd < 0) + goto fork_error; + } + c =3D '1'; if (safewrite(pipesync[1], &c, sizeof(c)) !=3D sizeof(c)) { virReportSystemError(errno, "%s", _("Unable to notify child pr= ocess")); @@ -1073,6 +1092,17 @@ virCommandSetPidFile(virCommand *cmd, const char *pi= dfile) } =20 =20 +void +virCommandSetStimeFile(virCommand *cmd, const char *stimefile) +{ + if (virCommandHasError(cmd)) + return; + + VIR_FREE(cmd->stimefile); + cmd->stimefile =3D g_strdup(stimefile); +} + + gid_t virCommandGetGID(virCommand *cmd) { @@ -2553,6 +2583,12 @@ virCommandRunAsync(virCommand *cmd, pid_t *pid) goto cleanup; } =20 + if (cmd->stimefile && !cmd->pidfile) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Stime file can not be created without pidfile")); + goto cleanup; + } + if (dryRunBuffer || dryRunCallback) { g_autofree char *cmdstr =3D NULL; dryRunStatus =3D 0; @@ -3008,6 +3044,7 @@ virCommandFree(virCommand *cmd) } =20 g_free(cmd->pidfile); + g_free(cmd->stimefile); =20 if (cmd->reap) virCommandAbort(cmd); diff --git a/src/util/vircommand.h b/src/util/vircommand.h index c7a580e152..1b3bc285a5 100644 --- a/src/util/vircommand.h +++ b/src/util/vircommand.h @@ -59,6 +59,9 @@ void virCommandPassFD(virCommand *cmd, void virCommandSetPidFile(virCommand *cmd, const char *pidfile) ATTRIBUTE_NONNULL(2); =20 +void virCommandSetStimeFile(virCommand *cmd, + const char *stimefile) ATTRIBUTE_NONNULL(2); + gid_t virCommandGetGID(virCommand *cmd) ATTRIBUTE_NONNULL(1); =20 uid_t virCommandGetUID(virCommand *cmd) ATTRIBUTE_NONNULL(1); diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c index bfd967c1af..b6be32708a 100644 --- a/src/util/virpidfile.c +++ b/src/util/virpidfile.c @@ -40,17 +40,31 @@ =20 VIR_LOG_INIT("util.pidfile"); =20 -char *virPidFileBuildPath(const char *dir, const char* name) +char *virPidFileBuildPathCommon(const char *dir, const char* name, + const char* delim) { g_auto(virBuffer) buf =3D VIR_BUFFER_INITIALIZER; =20 virBufferAsprintf(&buf, "%s", dir); - virBufferEscapeString(&buf, "/%s.pid", name); + virBufferEscapeString(&buf, "/%s", name); + virBufferAsprintf(&buf, ".%s", delim); =20 return virBufferContentAndReset(&buf); } =20 =20 +char *virPidFileBuildPath(const char *dir, const char* name) +{ + return virPidFileBuildPathCommon(dir, name, "pid"); +} + + +char *virPidStimeFileBuildPath(const char *dir, const char* name) +{ + return virPidFileBuildPathCommon(dir, name, "stime"); +} + + int virPidFileWritePath(const char *pidfile, pid_t pid) { @@ -102,39 +116,38 @@ int virPidFileWrite(const char *dir, } =20 =20 -int virPidFileReadPath(const char *path, - pid_t *pid) +int virPidFileReadPathCommon(const char *path, + long long *value) { int fd; int rc; ssize_t bytes; - long long pid_value =3D 0; - char pidstr[VIR_INT64_STR_BUFLEN]; + long long val =3D 0; + char valuestr[VIR_INT64_STR_BUFLEN]; char *endptr =3D NULL; =20 - *pid =3D 0; + *value =3D 0; =20 if ((fd =3D open(path, O_RDONLY)) < 0) { rc =3D -errno; goto cleanup; } =20 - bytes =3D saferead(fd, pidstr, sizeof(pidstr)); + bytes =3D saferead(fd, valuestr, sizeof(valuestr)); if (bytes < 0) { rc =3D -errno; VIR_FORCE_CLOSE(fd); goto cleanup; } - pidstr[bytes] =3D '\0'; + valuestr[bytes] =3D '\0'; =20 - if (virStrToLong_ll(pidstr, &endptr, 10, &pid_value) < 0 || - !(*endptr =3D=3D '\0' || g_ascii_isspace(*endptr)) || - (pid_t) pid_value !=3D pid_value) { + if (virStrToLong_ll(valuestr, &endptr, 10, &val) < 0 || + !(*endptr =3D=3D '\0' || g_ascii_isspace(*endptr))) { rc =3D -EINVAL; goto cleanup; } =20 - *pid =3D pid_value; + *value =3D val; rc =3D 0; =20 cleanup: @@ -145,6 +158,31 @@ int virPidFileReadPath(const char *path, } =20 =20 +int virPidFileReadPath(const char *path, + pid_t *pid) +{ + long long val =3D 0; + int rc =3D 0; + + if ((rc =3D virPidFileReadPathCommon(path, &val))) { + return rc; + } + if ((pid_t)val !=3D val) { + return -1; + } + *pid =3D val; + + return 0; +} + + +int virPidStimeFileReadPath(const char *path, + long long *val) +{ + return virPidFileReadPathCommon(path, val); +} + + int virPidFileRead(const char *dir, const char *name, pid_t *pid) @@ -362,12 +400,13 @@ int virPidFileDelete(const char *dir, return virPidFileDeletePath(pidfile); } =20 -int virPidFileAcquirePath(const char *path, - bool waitForLock, - pid_t pid) + +int virPidFileAcquirePathCommon(const char *path, + bool waitForLock, + long long val) { int fd =3D -1; - char pidstr[VIR_INT64_STR_BUFLEN]; + char valstr[VIR_INT64_STR_BUFLEN]; =20 if (path[0] =3D=3D '\0') return 0; @@ -376,7 +415,7 @@ int virPidFileAcquirePath(const char *path, struct stat a, b; if ((fd =3D open(path, O_WRONLY|O_CREAT, 0644)) < 0) { virReportSystemError(errno, - _("Failed to open pid file '%s'"), + _("Failed to open file '%s'"), path); return -1; } @@ -391,7 +430,7 @@ int virPidFileAcquirePath(const char *path, =20 if (fstat(fd, &b) < 0) { virReportSystemError(errno, - _("Unable to check status of pid file '%s= '"), + _("Unable to check status of file '%s'"), path); VIR_FORCE_CLOSE(fd); return -1; @@ -399,17 +438,17 @@ int virPidFileAcquirePath(const char *path, =20 if (virFileLock(fd, false, 0, 1, waitForLock) < 0) { virReportSystemError(errno, - _("Failed to acquire pid file '%s'"), + _("Failed to acquire file '%s'"), path); VIR_FORCE_CLOSE(fd); return -1; } =20 - /* Now make sure the pidfile we locked is the same + /* Now make sure the file we locked is the same * one that now exists on the filesystem */ if (stat(path, &a) < 0) { - VIR_DEBUG("Pid file '%s' disappeared: %s", + VIR_DEBUG("File '%s' disappeared: %s", path, g_strerror(errno)); VIR_FORCE_CLOSE(fd); /* Someone else must be racing with us, so try again */ @@ -419,24 +458,24 @@ int virPidFileAcquirePath(const char *path, if (a.st_ino =3D=3D b.st_ino) break; =20 - VIR_DEBUG("Pid file '%s' was recreated", path); + VIR_DEBUG("File '%s' was recreated", path); VIR_FORCE_CLOSE(fd); /* Someone else must be racing with us, so try again */ } =20 - g_snprintf(pidstr, sizeof(pidstr), "%lld", (long long) pid); + g_snprintf(valstr, sizeof(valstr), "%lld", val); =20 if (ftruncate(fd, 0) < 0) { virReportSystemError(errno, - _("Failed to truncate pid file '%s'"), + _("Failed to truncate file '%s'"), path); VIR_FORCE_CLOSE(fd); return -1; } =20 - if (safewrite(fd, pidstr, strlen(pidstr)) < 0) { + if (safewrite(fd, valstr, strlen(valstr)) < 0) { virReportSystemError(errno, - _("Failed to write to pid file '%s'"), + _("Failed to write to file '%s'"), path); VIR_FORCE_CLOSE(fd); } @@ -445,6 +484,26 @@ int virPidFileAcquirePath(const char *path, } =20 =20 +int virPidFileAcquirePath(const char *path, + bool waitForLock, + pid_t pid) +{ + return virPidFileAcquirePathCommon(path, + waitForLock, + (long long)pid); +} + + +int virPidStimeFileAcquirePath(const char *path, + bool waitForLock, + long long stime) +{ + return virPidFileAcquirePathCommon(path, + waitForLock, + stime); +} + + int virPidFileAcquire(const char *dir, const char *name, bool waitForLock, diff --git a/src/util/virpidfile.h b/src/util/virpidfile.h index e84542f298..7c8fc2ddf2 100644 --- a/src/util/virpidfile.h +++ b/src/util/virpidfile.h @@ -26,8 +26,13 @@ #include #include "internal.h" =20 +char *virPidFileBuildPathCommon(const char *dir, + const char *name, + const char* delim); char *virPidFileBuildPath(const char *dir, const char *name); +char *virPidStimeFileBuildPath(const char *dir, + const char* name); =20 int virPidFileWritePath(const char *path, pid_t pid) G_GNUC_WARN_UNUSED_RESULT; @@ -35,8 +40,13 @@ int virPidFileWrite(const char *dir, const char *name, pid_t pid) G_GNUC_WARN_UNUSED_RESULT; =20 +int virPidFileReadPathCommon(const char *path, + long long *val) G_GNUC_WARN_UNUSED_RESULT; int virPidFileReadPath(const char *path, pid_t *pid) G_GNUC_WARN_UNUSED_RESULT; +int virPidStimeFileReadPath(const char *path, + long long *val) G_GNUC_WARN_UNUSED_RESULT; + int virPidFileRead(const char *dir, const char *name, pid_t *pid) G_GNUC_WARN_UNUSED_RESULT; @@ -56,9 +66,16 @@ int virPidFileDelete(const char *dir, const char *name); =20 =20 +int virPidFileAcquirePathCommon(const char *path, + bool waitForLock, + long long val) G_GNUC_WARN_UNUSED_RESULT; int virPidFileAcquirePath(const char *path, bool waitForLock, pid_t pid) G_GNUC_WARN_UNUSED_RESULT; +int virPidStimeFileAcquirePath(const char *path, + bool waitForLock, + long long stime) G_GNUC_WARN_UNUSED_RESULT; + int virPidFileAcquire(const char *dir, const char *name, bool waitForLock, diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 11f36e00a8..9507d1d600 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -24,6 +24,10 @@ =20 #include #include + +#ifndef WIN32 +# include +#endif #ifndef WIN32 # include #endif @@ -232,6 +236,19 @@ virProcessWait(pid_t pid, int *exitstatus, bool raw) return -1; } =20 +int virPidFdkill(int pidfd, int sig) +{ + siginfo_t siginfo; + + siginfo.si_code =3D SI_QUEUE; + siginfo.si_signo =3D sig; + siginfo.si_errno =3D 0; + siginfo.si_pid =3D getpid(); + siginfo.si_uid =3D getuid(); + + return syscall(SYS_pidfd_send_signal, pidfd, sig, &siginfo, 0); +} + #else /* WIN32 */ =20 char * @@ -259,10 +276,18 @@ virProcessWait(pid_t pid, int *exitstatus G_GNUC_UNUS= ED, bool raw G_GNUC_UNUSED) =20 #endif /* WIN32 */ =20 - -/* send signal to a single process */ -int virProcessKill(pid_t pid, int sig) +/* send signal to a single process + * + * If a valid stime value is provided, verify start time of process + * before sending signal to it. Value 0 for stime is considered as + * invalid. + */ +int virProcessKillWithStime(pid_t pid, int sig, + long long stime) { + int pidfd; + unsigned long long starttime; + if (pid <=3D 1) { errno =3D ESRCH; return -1; @@ -312,7 +337,21 @@ int virProcessKill(pid_t pid, int sig) } return 0; #else - return kill(pid, sig); + pidfd =3D syscall(SYS_pidfd_open, pid, 0); + if (pidfd =3D=3D -1) { + return -1; + } + + if (stime && (virProcessGetStartTime(pid, &starttime) >=3D 0) && + (long long)starttime !=3D stime) { + /* If start time of process does not match, it means actual + * process is already dead and pid has been re-used. + */ + errno =3D ESRCH; + return -1; + } + + return virPidFdkill(pidfd, sig); #endif } =20 @@ -334,6 +373,12 @@ int virProcessGroupKill(pid_t pid, int sig G_GNUC_UNUS= ED) } =20 =20 +int virProcessKill(pid_t pid, int sig) +{ + return virProcessKillWithStime(pid, sig, 0); +} + + /* get process group from a pid */ pid_t virProcessGroupGet(pid_t pid) { @@ -362,7 +407,10 @@ pid_t virProcessGroupGet(pid_t pid) * wait longer than the default. */ int -virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradela= y, bool group) +virProcessKillPainfullyDelayWithStime(pid_t pid, bool force, + unsigned int extradelay, + bool group, + long long stime) { size_t i; /* This is in 1/5th seconds since polling is on a 0.2s interval */ @@ -408,7 +456,7 @@ virProcessKillPainfullyDelay(pid_t pid, bool force, uns= igned int extradelay, boo if (group) rc =3D virProcessGroupKill(pid, signum); else - rc =3D virProcessKill(pid, signum); + rc =3D virProcessKillWithStime(pid, signum, stime); =20 if (rc < 0) { if (errno !=3D ESRCH) { @@ -431,11 +479,24 @@ virProcessKillPainfullyDelay(pid_t pid, bool force, u= nsigned int extradelay, boo } =20 =20 +int virProcessKillPainfullyDelay(pid_t pid, bool force, + unsigned int extradelay, + bool group) +{ + return virProcessKillPainfullyDelayWithStime(pid, force, extradelay, + group, 0); +} + int virProcessKillPainfully(pid_t pid, bool force) { return virProcessKillPainfullyDelay(pid, force, 0, false); } =20 +int virProcessKillPainfullyWithStime(pid_t pid, bool force, long long int = stime) +{ + return virProcessKillPainfullyDelayWithStime(pid, force, 0, false, sti= me); +} + #if WITH_DECL_CPU_SET_T =20 int virProcessSetAffinity(pid_t pid, virBitmap *map, bool quiet) diff --git a/src/util/virprocess.h b/src/util/virprocess.h index 91ad5618db..0e550c4806 100644 --- a/src/util/virprocess.h +++ b/src/util/virprocess.h @@ -52,14 +52,21 @@ virProcessWait(pid_t pid, int *exitstatus, bool raw) G_GNUC_WARN_UNUSED_RESULT; =20 int virProcessKill(pid_t pid, int sig); +int virProcessKillWithStime(pid_t pid, int sig, long long stime); int virProcessGroupKill(pid_t pid, int sig); pid_t virProcessGroupGet(pid_t pid); =20 int virProcessKillPainfully(pid_t pid, bool force); +int virProcessKillPainfullyWithStime(pid_t pid, bool force, long long stim= e); int virProcessKillPainfullyDelay(pid_t pid, bool force, unsigned int extradelay, bool group); +int virProcessKillPainfullyDelayWithStime(pid_t pid, + bool force, + unsigned int extradelay, + bool group, + long long stime); =20 int virProcessSetAffinity(pid_t pid, virBitmap *map, bool quiet); =20 @@ -204,3 +211,4 @@ int virProcessGetStatInfo(unsigned long long *cpuTime, int virProcessGetSchedInfo(unsigned long long *cpuWait, pid_t pid, pid_t tid); +int virPidFdkill(int pidfd, int sig); diff --git a/tests/qemustatusxml2xmldata/backup-pull-in.xml b/tests/qemusta= tusxml2xmldata/backup-pull-in.xml index e7fdc6c478..b11077577a 100644 --- a/tests/qemustatusxml2xmldata/backup-pull-in.xml +++ b/tests/qemustatusxml2xmldata/backup-pull-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml b/tests/q= emustatusxml2xmldata/blockjob-blockdev-in.xml index b62b3149c2..361ca8641e 100644 --- a/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml +++ b/tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/blockjob-mirror-in.xml b/tests/qem= ustatusxml2xmldata/blockjob-mirror-in.xml index e9f1d77856..8f165be2d8 100644 --- a/tests/qemustatusxml2xmldata/blockjob-mirror-in.xml +++ b/tests/qemustatusxml2xmldata/blockjob-mirror-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/migration-in-params-in.xml b/tests= /qemustatusxml2xmldata/migration-in-params-in.xml index 03773a089b..60d900453d 100644 --- a/tests/qemustatusxml2xmldata/migration-in-params-in.xml +++ b/tests/qemustatusxml2xmldata/migration-in-params-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-bitmaps-in.xml b= /tests/qemustatusxml2xmldata/migration-out-nbd-bitmaps-in.xml index 4ee44ffbd4..eb62f2aec8 100644 --- a/tests/qemustatusxml2xmldata/migration-out-nbd-bitmaps-in.xml +++ b/tests/qemustatusxml2xmldata/migration-out-nbd-bitmaps-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-in.xml b/tests/q= emustatusxml2xmldata/migration-out-nbd-in.xml index 636accf054..0d9e9e1acf 100644 --- a/tests/qemustatusxml2xmldata/migration-out-nbd-in.xml +++ b/tests/qemustatusxml2xmldata/migration-out-nbd-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml b/tests/= qemustatusxml2xmldata/migration-out-nbd-out.xml index de92146eaa..e5cc8dd854 100644 --- a/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml +++ b/tests/qemustatusxml2xmldata/migration-out-nbd-out.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-tls-in.xml b/tes= ts/qemustatusxml2xmldata/migration-out-nbd-tls-in.xml index 2cd6c9a5e9..f24bf6a9fb 100644 --- a/tests/qemustatusxml2xmldata/migration-out-nbd-tls-in.xml +++ b/tests/qemustatusxml2xmldata/migration-out-nbd-tls-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/migration-out-nbd-tls-out.xml b/te= sts/qemustatusxml2xmldata/migration-out-nbd-tls-out.xml index 6bdd128259..13a0ad10ea 100644 --- a/tests/qemustatusxml2xmldata/migration-out-nbd-tls-out.xml +++ b/tests/qemustatusxml2xmldata/migration-out-nbd-tls-out.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/migration-out-params-in.xml b/test= s/qemustatusxml2xmldata/migration-out-params-in.xml index 24ee86e4c0..6a1888de1b 100644 --- a/tests/qemustatusxml2xmldata/migration-out-params-in.xml +++ b/tests/qemustatusxml2xmldata/migration-out-params-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/modern-in.xml b/tests/qemustatusxm= l2xmldata/modern-in.xml index 7759034f7a..139a1ff441 100644 --- a/tests/qemustatusxml2xmldata/modern-in.xml +++ b/tests/qemustatusxml2xmldata/modern-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/upgrade-in.xml b/tests/qemustatusx= ml2xmldata/upgrade-in.xml index 7fa56429f4..08d089392c 100644 --- a/tests/qemustatusxml2xmldata/upgrade-in.xml +++ b/tests/qemustatusxml2xmldata/upgrade-in.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/upgrade-out.xml b/tests/qemustatus= xml2xmldata/upgrade-out.xml index e663b3dbb5..fb06b2f1c1 100644 --- a/tests/qemustatusxml2xmldata/upgrade-out.xml +++ b/tests/qemustatusxml2xmldata/upgrade-out.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/qemustatusxml2xmldata/vcpus-multi-in.xml b/tests/qemusta= tusxml2xmldata/vcpus-multi-in.xml index e71d6a83c7..de6679d0fa 100644 --- a/tests/qemustatusxml2xmldata/vcpus-multi-in.xml +++ b/tests/qemustatusxml2xmldata/vcpus-multi-in.xml @@ -1,4 +1,4 @@ - + --=20 2.22.3