From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from DU2PR03CU002.outbound.protection.outlook.com (mail-northeuropeazon11021143.outbound.protection.outlook.com [52.101.65.143]) by lore.virtuozzo.com (Postfix) with ESMTPS id A281D802A5 for ; Mon, 5 Oct 2026 09:26:49 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=A9hrJWKKA9dXMTl15PIsy9gR5ounmoon9I5ML0OBXY1FZG2uDdyV2n3j4L7rGLr/p5beLhnkh2sH/m+FCgVsGZ/mS6+uFcYZcQfOGfoVk1w1+Qc/2lVqfwfafBUyTUZ+SyxcehiTnhaQdOxz1SXGGnSlXwGiarRxokXmePj8MiApGB+3raZ3hHJYAQREW2MUfRr6d+bJIG9F4Hgbd7YU10v0FyuqZe6YH6R7BH/hrt1oid6Q7dLt0Nzm/Lks0yaXjsvoPr6mY1ymvKf9Zvx2BghF73d7046xX2r1SmkNfxZAaeLBGG95PNGsJcSUmcvLikHYEY03P75AbVCKE9ILTg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=7L03lP0NHz2GG2NJ4071S4/M6h4t84fHyLeYSvUYVgg=; b=OcqDHBcRe4/wTVm3fdd4CgQgGDdlpmNVox2mt2DCkDKRDqDXyvp7Odjiauldgmq+DlBrXXLEB1CSp0tl4I4BqM4LlhkT0c6jI/h91/ovsGhLCacFfRpVLZl3du2LsL1m7+jK6mDkj5Ht6/2VvGBBxDDHdn93/dReW1guxiQLrG3+fEyT78ByRrwPBSw89Q0LZWjaoWA1hqITiwP2OuTQKmGn/eOr79d9NRKPIorGkS4GJ4nflXBFKLp+fkSob/zu9UcpyRLUi4QMYoIa17SOfBU+M82ifbx8Yw2LJvaihHA5WTH5QqdP8Q3dfedSSbh2Lnju4cOKBNXHyUyEJdMyDg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 2a00:1450:4864:30::e) smtp.rcpttodomain=virtuozzo.com smtp.mailfrom=openvz.org; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=openvz.org; dkim=pass (signature was verified) header.d=openvz.org; arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.onmicrosoft.com; s=selector2-virtuozzo-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=7L03lP0NHz2GG2NJ4071S4/M6h4t84fHyLeYSvUYVgg=; b=CQbj0oOWx9Zg4/MYSHsVGFo6CEBmy0QFCqUOVwGsoL4g0SXEmGZAU28NPMUhmNS9zMF1ZtWHw3BwI+E0TwQujLSHrXipvwgcsQoqNxNLysHV/UqRvNCu8gG9n4adSasPGF9pIyfjsH3UW17uOMFq1BK+DAcv7LpGH0Bx17EJv+c= Received: from DU2PR04CA0310.eurprd04.prod.outlook.com (2603:10a6:10:2b5::15) by DU2PR08MB10204.eurprd08.prod.outlook.com (2603:10a6:10:49b::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.496.14; Mon, 5 Oct 2026 09:26:44 +0000 Received: from MI3PEPF00008553.eurprd05.prod.outlook.com (2603:10a6:10:2b5:cafe::7a) by DU2PR04CA0310.outlook.office365.com (2603:10a6:10:2b5::15) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.472.20 via Frontend Transport; Mon, 5 Oct 2026 09:26:44 +0000 Authentication-Results: spf=pass (sender IP is 2a00:1450:4864:30::e) smtp.mailfrom=openvz.org; dkim=pass (signature was verified) header.d=openvz.org;dmarc=pass action=none header.from=openvz.org; Received-SPF: Pass (protection.outlook.com: domain of openvz.org designates 2a00:1450:4864:30::e as permitted sender) receiver=protection.outlook.com; client-ip=2a00:1450:4864:30::e; helo=mail-wr2-x0e.google.com; pr=C Received: from mail-wr2-x0e.google.com (2a00:1450:4864:30::e) by MI3PEPF00008553.mail.protection.outlook.com (2603:10a6:298:1::87) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.472.14 via Frontend Transport; Mon, 5 Oct 2026 09:26:42 +0000 Received: by mail-wr2-x0e.google.com with SMTP id ffacd0b85a97d-48b01d89b23so694283f8f.2 for ; Mon, 05 Oct 2026 02:26:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1791192401; x=1791797201; darn=virtuozzo.com; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=7L03lP0NHz2GG2NJ4071S4/M6h4t84fHyLeYSvUYVgg=; b=iCu70/Mw6rcap9EA3Ic/Tk1+rwBGBsXc0/LzvQFPRxAtCLsh/mQcAkeea2KLb4fyzO PyRO/KYwyGKtmCWMUu9gWR+DBZZ80GGGaqMvjL0N9N01SG1b+mnhToG/OBhozdGIC10H eHMa0KfyXS8dU63s1+csHbLvhsMl1eyqRVdoqlS9IWYQLAThFvUVXzzTgSDJrJxK2hAz 2qCSUZx2vQKYSBacDzYoTcHYanWtM9zsU0St01bFal2C/IECuIJHToHKgFwu86FmC18h Wvv1TNSmskEkIy1M9rskwdHGbuxs8ArScnYsZE+/xeT7DZHKG0c7sdy1I9HpVnOOjlAZ lO9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791192401; x=1791797201; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=7L03lP0NHz2GG2NJ4071S4/M6h4t84fHyLeYSvUYVgg=; b=TdhGo8/mDvY1zt6G/n2ANbeKWu/b1eeuI7W5h2Dv18SpJgPkE1Hl4MbgMByTRamss3 pXFbdY5WlHh5JPz+lKFsBp3HpAuNpbkvOh6Rit53gD4yqiyVtIc7nFK0wVXcYmtLSfyy Ozp4cVl5y3jnN0m9BoBgpkQQ8phW7aVNolNO0QP77bw6vYukE7Zf/BeM4biOAW4AwOAs bLV8DxSdGwyxckDyo+xW6TwtGLoJgg6Ft/AmJ+0m4+LBnCGQeo09BqlzrflL5mWJLhB8 v7BobEywOoaGowCM9QBBr7XK68K6JCG/TTGO6NS7gVkwZBWK3ABB6rKqQRHxkDztENV5 nYvg== X-Gm-Message-State: AFq9FYLq5pzVijNh6IGiJX0090mk2t5GP9dO4oIy3WtW9u1cmyii7eGo 8B0d9GDrQGFuVC6ynu3azKJIGw4uTZVjozKxO9A6h/lXYBccLpNRw/SeWcw0czA520h86mRKK+5 rVD39ol4= X-Gm-Gg: AYBFou2+z3PYsorbkFbsV0Pkwjzp3via6rkuRvpXxoC9jA3vevqEZvUvdhsmjgqixtn OgFAXAYOuzyziVSbBl2cRdlQgR3wFtEIVLRwoAh1PzmX7SUQrc0ploQlePfMvkIQLBD+5mznJ5t xDtVqEr1rQsfpUiK8FhVO+fc6JzHnwbvcaICIzTWMPdpZB4KBtYaDbZykllioQ2IMBVrPj5VIbQ d98yBcjqgEEJwrRJ/2HABZlujHLp28JpT7Qut3U3tasQRTcOVGt7/4XZmcfok3oDtql2SnUNNpD hjhmhNZB5f+RTeEbPERyjXljQtmjLgZuhDULSnXeoGeRiV7dYBPe8OvsF5LyXQJ2Fm9wU1cq4eb gDbjSAvGIJCt1zcpVg+/Fjq7AwzuSX2XDgBAIg6hP56M0GeNLMI5NkUZmg41Uxo0+snzyH9t+gl WxIwS7ggfGJ0MOvvVSuxyQBM8MpmLe99k42we63czJZwHf2dqngAbPnn018Ag411rafUM= X-Received: by 2002:adf:e199:0:b0:488:7f69:632c with SMTP id ffacd0b85a97d-48b12736b25mr16217170f8f.56.1791192401372; Mon, 05 Oct 2026 02:26:41 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:bff9:47a9:54d2:1c0b]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48c62270739sm2434715f8f.11.2026.10.05.02.26.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Oct 2026 02:26:40 -0700 (PDT) From: "Denis V. Lunev" To: svt-core@virtuozzo.com Cc: andrey.drobyshev@virtuozzo.com, den@openvz.org Subject: [PATCH hci-8.0 v2 3/3] iotests/migrate-cpr-exec: cover chardevs with logfile= #VSTOR-148304 Date: Mon, 5 Oct 2026 11:26:35 +0200 Message-ID: <20261005092635.3564485-4-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261005092635.3564485-1-den@openvz.org> References: <20261005092635.3564485-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-EOPTenantAttributedMessage: 0bc7f26d-0264-416e-a6fc-8352af79c58f:0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MI3PEPF00008553:EE_|DU2PR08MB10204:EE_ X-MS-Office365-Filtering-Correlation-Id: 14a74329-f6ad-46f3-5e28-08df22c2c43f X-LD-Processed: 0bc7f26d-0264-416e-a6fc-8352af79c58f,ExtAddr X-MS-Exchange-AtpMessageProperties: SA X-MS-Exchange-SenderADCheck: 0 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|704161211799003|48200799018|43022699015|61400799027|376014|6059299003|82310400026|9140799003|16102099003|18002099003|22082099003|55112099003|10067099003|5063699009|56012099006; X-Microsoft-Antispam-Message-Info: e3Zw6b1UFckoyyQb5omrmwoLSv9m3NmI2HHPFQfE2rjJZAZblEL9NfcTEiTLNnC7tyfE9ydXZXEob87AvPTbEmgcSEDTM+/VnwF+MgIaQhKmUtbYHxDAVolUBo1wmZZZCAYEwGraS+jqrcpb59SeZcxvITOAi3aKFYYb//3EIIZSfty5rTgKfgXlz8aNzJuJn5CuVnvG70qzV50CxLVSf1x93dZ99XF5CwQajol6vLx/V0oQSRQwV/KC0W6fCsLocngd88Ax4BHcSPpystZjy/ItWnamLYqwpkpuWl5Sxu3iKt/MWWbpeXk5W1XhcrPRYuMRCGmsk8/hLbl2TtYkre/QdiYRribXKgH53W6KbD6lWQggrbLhzvo7J9jMJ6A5SkDHhGJH8XL0gKiJfr3LqM6BQ0HXJW1igbAB7R5dMOvbZiVryIwUMnKG/caVLU0VDDkBCnZyw5Az9DzjJiPHk7gRsZa6K9it0Me9Z8qgoqoCUs5y1zjsDDGNcX1S/44dZtUgcYoUw11cn2+lXOLXcznUIcgH7PfLeUi9L/JjO3J+NS9AlFDKOo7oGbTKnsd4I04EIbZ6+lEk52FRPryppVRiW+o1J48OLyw9gF+05daJHYfl9oKN3fDMPLIjqf63Tzw3+LP6PrC3ldkEHDg1aItixeGiumPHHEKabQQpMjqU2zCjFxHQ6ciiEAhcJP1SVdqqoXm5tv54m6+cioix2HAedqmUjU1GjSQ7jWNFVzr1kPceiYP8x8tVJC1eL3bO6KDEnPU+zoAdsuMEr4lAIQPJlcWCoXsSUJbPlvhbx/fzk+21acvPFq2DioeD900pJQVMCwZv/u4UxLJSqucx4xfucoZ5Q3zQ3iNpC4AgD4mRaGOis3SFCykaXzL0MuDK3t1g0+LAiKOvKMr65oBTkA== X-Forefront-Antispam-Report: CIP:2a00:1450:4864:30::e;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail-wr2-x0e.google.com;PTR:mail-wr2-x0e.google.com;CAT:NONE;SFS:(13230040)(704161211799003)(48200799018)(43022699015)(61400799027)(376014)(6059299003)(82310400026)(9140799003)(16102099003)(18002099003)(22082099003)(55112099003)(10067099003)(5063699009)(56012099006);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: unSj1V95MUGOTwFfLqYVVpyJKYnm3XTGgN2o9HRSuxOrWHExQTboyJGM1O0Z0zJ+kiWu28clOeg4nNgk8Sz+UYmsKit+CzdQTs5sz3Ctrae4ACgPVwXUCuYns+dYgrI1+0bldDPxBlep7IMxvGFOr5sfByfTrS6DJeY+ldpIqROKL3PSz2U+d3wK0pKCVZ9h26MeXa3xRoVktzoNPqLcg7doGlpwMDRjfsnoDiVLs0Z6trf0ItZMKGTZ9eqAWp12fj1nYNTK5ZaRFX2w8D7pP0kbRaVM7YKPfy4M/IRDmN5c4H5nHR/ExxRc0r40dSsR+SVK2FeRDouH46ra7frv47M33SON+QDyNyEyd3DtclECOCU5Git7cLE5/SRPw8KIm+mxPp4j4VNuksB4sA+UHei2JG9n71qbL+WdpaG9o+V+mST2qZlh9TJLJ8/6p5RD X-ExternalRecipientOutboundConnectors: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-Auto-Response-Suppress: DR, OOF, AutoReply X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Oct 2026 09:26:42.0197 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 14a74329-f6ad-46f3-5e28-08df22c2c43f X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-AuthSource: MI3PEPF00008553.eurprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU2PR08MB10204 List-Id: From: Denis V. Lunev Run a console pty with its log in an fdset, a guest agent socket and a second QMP monitor, each with a log, through cpr-exec with a command line whose logfile paths cannot be created, as libvirt's is. Cover chardev-change to a new log for pty and socket, and a failed chardev-change, whose rollback must keep the old log preserved. Signed-off-by: Denis V. Lunev --- tests/qemu-iotests/tests/migrate-cpr-exec | 154 ++++++++++++++++++ tests/qemu-iotests/tests/migrate-cpr-exec.out | 4 +- 2 files changed, 156 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/tests/migrate-cpr-exec b/tests/qemu-iotests/tests/migrate-cpr-exec index 51e6cbcd659..2b30929561c 100755 --- a/tests/qemu-iotests/tests/migrate-cpr-exec +++ b/tests/qemu-iotests/tests/migrate-cpr-exec @@ -288,6 +288,160 @@ class TestCprExec(iotests.QMPTestCase): '-device', 'isa-serial,chardev=char0') self._test_cpr(pre_cpr_hook=change_socket) + BAD_LOG = os.path.join(iotests.test_dir, 'nonexistent', 'chr.log') + + def _serial_write(self, data: str) -> None: + for c in data: + self.vm.qtest(f'outb 0x3f8 {ord(c)}') + + def _open_files(self) -> set: + fd_dir = f'/proc/{self.vm.get_pid()}/fd' + files = set() + for fd in os.listdir(fd_dir): + try: + files.add(os.readlink(os.path.join(fd_dir, fd))) + except FileNotFoundError: + pass + return files + + def _replace_arg(self, old: str, new: str) -> None: + args = list(self.vm._qemu_full_args) + args[args.index(old)] = new + self.vm._qemu_full_args = tuple(args) + + def _read(self, path: str) -> str: + with open(path, encoding='utf-8') as f: + return f.read() + + def _log_path(self, name: str) -> str: + path = os.path.join(iotests.test_dir, name) + self.addCleanup(lambda: os.path.exists(path) and os.remove(path)) + return path + + def test_chardev_logfile(self) -> None: + """Log fds survive cpr-exec; the new logfile= paths are never opened""" + console_log = self._log_path('console.log') + agent_log = self._log_path('agent.log') + mon_log = self._log_path('mon.log') + agent_sock = iotests.file_path('agent.sock') + mon_sock = iotests.file_path('mon.sock') + + console = 'pty,id=charserial0,logfile=/dev/fdset/1,logappend=on' + agent = (f'socket,id=charchannel0,path={agent_sock},server=on,' + f'wait=off,logfile={agent_log}') + mon = (f'socket,id=charmonitor1,path={mon_sock},server=on,' + f'wait=off,logfile={mon_log}') + + def pre_cpr(): + self._serial_write('before\n') + for c in (console, agent, mon): + self._replace_arg(c, c.replace(c[c.index('logfile='):], + f'logfile={self.BAD_LOG}')) + args = list(self.vm._qemu_full_args) + i = args.index('-add-fd') + self.vm._qemu_full_args = tuple(args[:i] + args[i + 2:]) + + def post_cpr(): + self._serial_write('after\n') + self.assertEqual(self._read(console_log), 'before\nafter\n') + self.assertLessEqual({agent_log, mon_log}, self._open_files()) + self.assertFalse(os.path.exists(os.path.dirname(self.BAD_LOG))) + + fd = os.open(console_log, os.O_WRONLY | os.O_CREAT | os.O_APPEND) + try: + self.vm.add_fd(fd, 1, 'console') + self.vm.add_args( + '-chardev', console, + '-device', 'isa-serial,chardev=charserial0', + '-chardev', agent, '-device', 'virtio-serial', + '-device', 'virtserialport,chardev=charchannel0,' + 'name=org.qemu.guest_agent.0', + '-chardev', mon, '-mon', 'chardev=charmonitor1,mode=control') + self._test_cpr(pre_cpr_hook=pre_cpr, post_cpr_hook=post_cpr) + finally: + os.close(fd) + + def _test_chardev_change_logfile(self, backend: str, data_new: dict, + opts_old: str) -> None: + """cpr-exec after chardev-change preserves the new log, not the old""" + log_old = self._log_path('chr-old.log') + log_new = self._log_path('chr-new.log') + arg = f'{backend},id=char0,{opts_old}logfile={log_old}' + + def change(): + self._serial_write('before\n') + res = self.vm.qmp('chardev-change', id='char0', + backend={'type': backend, + 'data': {**data_new, + 'logfile': log_new}}) + assert 'return' in res, res + self._replace_arg(arg, f'{backend},id=char0,{opts_old}' + f'logfile={self.BAD_LOG}') + + def post_cpr(): + self._serial_write('after\n') + self.assertEqual(self._read(log_old), 'before\n') + self.assertEqual(self._read(log_new), 'after\n') + self.assertNotIn(log_old, self._open_files()) + + self.vm.add_args('-chardev', arg, + '-device', 'isa-serial,chardev=char0') + self._test_cpr(pre_cpr_hook=change, post_cpr_hook=post_cpr) + + def test_chardev_change_logfile_pty(self) -> None: + self._test_chardev_change_logfile('pty', {}, '') + + def test_chardev_change_logfile_socket(self) -> None: + sock1 = iotests.file_path('chr-log-sock1') + sock2 = iotests.file_path('chr-log-sock2') + self._test_chardev_change_logfile( + 'socket', + {'addr': {'type': 'unix', 'data': {'path': sock2}}, + 'server': True, 'wait': False}, + f'path={sock1},server=on,wait=off,') + + def test_chardev_change_logfile_rollback(self) -> None: + """A rolled back chardev-change keeps the old log preserved""" + log = self._log_path('chr.log') + log_new = self._log_path('chr-new.log') + link = self._log_path('pty-rollback.link') + open(link, 'w').close() + arg = f'pty,id=char0,logfile={log}' + + def failed_change(): + self._serial_write('before\n') + res = self.vm.qmp('chardev-change', id='char0', + backend={'type': 'pty', + 'data': {'path': link, + 'logfile': log_new}}) + assert 'error' in res, res + self._replace_arg(arg, f'pty,id=char0,logfile={self.BAD_LOG}') + + def post_cpr(): + self._serial_write('after\n') + self.assertEqual(self._read(log), 'before\nafter\n') + + self.vm.add_args('-chardev', arg, + '-device', 'isa-serial,chardev=char0') + self._test_cpr(pre_cpr_hook=failed_change, post_cpr_hook=post_cpr) + + def test_chardev_logfile_not_preserved(self) -> None: + """A log the source did not save is dropped, not reopened by path""" + log = self._log_path('unsaved.log') + arg = 'pty,id=char0' + + def add_log(): + self._replace_arg(arg, f'{arg},logfile={log}') + + def post_cpr(): + self.assertFalse(os.path.exists(log)) + + self.vm.add_args('-chardev', arg, + '-device', 'isa-serial,chardev=char0') + self._test_cpr(pre_cpr_hook=add_log, post_cpr_hook=post_cpr) + self.assertIn("chardev 'char0': log file was not preserved, " + "continuing without it", self.vm.get_log()) + def test_nbd_attached_hd(self) -> None: nbd_img = os.path.join(iotests.test_dir, 'nbd_disk') iotests.qemu_img_create('-f', 'qcow2', nbd_img, '64M') diff --git a/tests/qemu-iotests/tests/migrate-cpr-exec.out b/tests/qemu-iotests/tests/migrate-cpr-exec.out index 5ce2f9a2ed9..cfa5c0d0e66 100644 --- a/tests/qemu-iotests/tests/migrate-cpr-exec.out +++ b/tests/qemu-iotests/tests/migrate-cpr-exec.out @@ -1,5 +1,5 @@ -.............................. +................................... ---------------------------------------------------------------------- -Ran 30 tests +Ran 35 tests OK -- 2.53.0