From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from AM0PR02CU008.outbound.protection.outlook.com (mail-westeuropeazon11023142.outbound.protection.outlook.com [52.101.72.142]) by lore.virtuozzo.com (Postfix) with ESMTPS id A4A518015A for ; Tue, 8 Sep 2026 00:31:06 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Jx2lGed4TBYV3vohvkl221EL86W0mrbhXDp+czu6miGZi61/9O6aZ/WuLiytt6hKczEZb8iaZjAbypDx1HLI+YYbjH7odqbOsLFGnE7agAnI6DdBwgc4nikuAwHiaMlFmDlXnYsgOXQUR5tEx/eG4b7g6dBqU4gwRfU+xQkGS1TfAi39/D4fV8oH26utEBgGDAjlXfa2ZO7GHlkdPYsPyNeBZvtiUdwqjvHs8g8f6Ou9PR5foj5oYVDoxtYGim3yMr9JVrFFQPAMuCdy49Qz7jeo9TGc0zYjK0rLTZGwWC76M+4iJXDM39L6YSdTkMYeu7qy1FIVEpBf+RAXtl5pAA== 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=Tu0xqOiimik1PGgzu9SGNAmZyBEAetGNwXsYGtwNl0g=; b=OsF95Zs3HRm71kDbajgtjL+Fg5V3MdNFN0M1Ud6UkqCp3DQgvY17NwDlEUxLT/qEUCEKQUuVf4AYBojTNAkINCnQU9D52EiU7wx9NaqD4PHHcqp9pVuqTiCl5C7UGM4ZajgQVn0XlQXsT9hCtvQ74kbgmly5WmVIPR35jZI9BVb3PRt4+mubIERCOWx2AYMFASzm6n1n8FpTGak8HrYGIceiEpvMkd++8JYf68tq9mz+ZNIt9U7PpqnDC6t8EQixATPJP4/kLqan4Vkmr8CogzT3Yw0BcSjouWLmnJ9A8EKyaJD5IH1tUy/31JRVQMo//S92iNuv9bF6cXFANoG2Uw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=virtuozzo.com; dmarc=pass action=none header.from=virtuozzo.com; dkim=pass header.d=virtuozzo.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Tu0xqOiimik1PGgzu9SGNAmZyBEAetGNwXsYGtwNl0g=; b=m3mK9bl9uHqIlumyqZOvRoPoImPJQLTe358Qylg5fXXynUi3aER/U2KK8Owx7+GwpbkGwZWAuoeM3LVVdDZAxpn/4ZOmuEjinpta9SC+j6CYpfIBYEP6wAcaZBCTo9ATlsdFcuZP0guSI+GCCDg6B0x2028KbUvjvI1aCXeebpRFBGO27C8kwlO/X+VAUS9FBlWHb6vHSFIi8V5I/8LR1f/N/3HbhOzgTtkjWd9sKnYYxXp7XuV7rqbb9rUw/Cwcpcss+UCqibSxXDv5/Wg9Wh/lHW9lkKXs3rZitKkDL2v53aNs8rCgdx4AfedRe7/MbrhIihm7tysLVIFrGqhaKg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=virtuozzo.com; Received: from PA4PR08MB6061.eurprd08.prod.outlook.com (2603:10a6:102:e9::13) by AS2PR08MB8503.eurprd08.prod.outlook.com (2603:10a6:20b:55e::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.406.6; Tue, 8 Sep 2026 00:31:04 +0000 Received: from PA4PR08MB6061.eurprd08.prod.outlook.com ([fe80::c3bf:e107:b1d2:6a00]) by PA4PR08MB6061.eurprd08.prod.outlook.com ([fe80::c3bf:e107:b1d2:6a00%3]) with mapi id 15.21.0382.007; Tue, 8 Sep 2026 00:31:04 +0000 Message-ID: Date: Tue, 8 Sep 2026 02:31:03 +0200 User-Agent: Mozilla Thunderbird Subject: Re: [QEMU HCI-8.0 PATCH v2 4/5] vhost-blk: watch the device for resize events To: Andrey Drobyshev Cc: svt-core@virtuozzo.com, den@openvz.org References: <20260904132155.180581-1-andrey.zhadchenko@virtuozzo.com> <20260904132155.180581-5-andrey.zhadchenko@virtuozzo.com> <178853599893.728973.14654758383882924790.b4-review@b4> Content-Language: en-US From: Andrey Zhadchenko In-Reply-To: <178853599893.728973.14654758383882924790.b4-review@b4> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-ClientProxiedBy: ZR0P278CA0187.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:44::9) To PA4PR08MB6061.eurprd08.prod.outlook.com (2603:10a6:102:e9::13) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PA4PR08MB6061:EE_|AS2PR08MB8503:EE_ X-MS-Office365-Filtering-Correlation-Id: c0b2287f-5c50-48bd-46e4-08df0d40776d List-Id: svt-core@virtuozzo.com X-LD-Processed: 0bc7f26d-0264-416e-a6fc-8352af79c58f,ExtAddr X-MS-Exchange-Transport-Rules-Loop: 1 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|23010399003|1800799024|376014|10067099003|5113699003|3023799007|56012099006|22082099003|18002099003|4143699003|5023799004; X-Microsoft-Antispam-Message-Info: aph02NwN922bd/3OetXcoV9J0VBNhaZ77mTPY0pG/Yh6Ipy7Ihgnnigvuiu8CUEiOoHI6+CtrlOtruo20T26JAG07z2ajyzSxGPmsO+fYFQXVW18cCdYamHkb8kchzp+otnD5FLw9FnLTGsLgSIElSy4sf6eKV7KaK0iQ9qMhNdCuzZvirvP+hMyRy/dF53ITA01npAF38E7iX6Nt0YHEIAutxM8Oy62ENjonG5xNT1jUe4sR1mUUO3Z1yhG82ZJ2L+hAsdBhmNdoWHW7PzCIghN6LbbNFsWNUn8Y/dtgn4x3dtqeCunoiwkrOXw9zXszJDRKtDaGt5B1RhlGGHFZUWWTUYfnrHWZiFFU0OvkwLq02O+35G09bvy4V7IXA2s4RItSTL8eItvXBS6EMVkqJ/wpyasdlNHa8wTiYH8TSPiln92O82evP69bFyGcMrZbDVbNai59DJc2zfdvUxC+RZNCyJ06a0PBjXXPKXERYMMW8V8HlxxZ7VD5tF9FXnH3taYRpJTh/0Y5LyWRIP4LyqBSgMf2oYz+QGdrppK+NT2pVZt2f+zM2tb0XNtCRyDJAV/SLyHgprauex1ywf42cEimCZTaxb5HXTJynG47bvAt7RXXp1O1hg+LxkBSyLJaV1xsu+Qpw1MjIWmBsu2i5nmwN5OQMqXJYzC7rvxfro= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PA4PR08MB6061.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(366016)(23010399003)(1800799024)(376014)(10067099003)(5113699003)(3023799007)(56012099006)(22082099003)(18002099003)(4143699003)(5023799004);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?WlpWUXd5d1FJeU9VbTUrbGR5MjJMbHd4cDBCOEFzbHhVL25mSEJFTnBTdytI?= =?utf-8?B?czhnQ0RRck9ieW11MDJjZWFCT055WFpiSDdpK2dNTzV2T3kwN1ZVY1pubXNX?= =?utf-8?B?NUowNUVadjRKS0hPYlRzWDlkVkFPUXZmdVR4MlQxcXAvZjhDcEgvSWxxMCtH?= =?utf-8?B?Q2RKYTRXU25iT2V5NTkvS0dZSTB0eEovbFJGQ2xUNXpCakdBSjRXbU9qQjJx?= =?utf-8?B?VWR6aVlua1VqcjVQOVpSR1N5K3FRUlljdndDTDFLV2cvU3lFRTBsQ3BaQzhT?= =?utf-8?B?UlgxLzZibGFDbHQ0WHlPRmk4b2FtYWFEQW51VWtKRnMwQTh1Y2gvN0ZmUWZi?= =?utf-8?B?Z1F3MU1ZWjJ2Qm1BbUhieURycjlPejJWNE5hWnVoMjdyamdub0RTU0E2czdL?= =?utf-8?B?R1l5Q3RUZlB4YkF6cHZ4Q0ZNMjliQVMyOWY3cU5JaWR1aDBqTGcxTGY1bmRL?= =?utf-8?B?MVlyd3QwYVFkUE13NXQyZWh2MC92bCtjdFpwYXlxVFhJZzFHbHB5U2kzR3R2?= =?utf-8?B?bWQzTk1tenJiKzE5YnpBbUFzL1VhSGsvSEZxQ0UyVnZ6UE1tTkFBV0VyR1Qr?= =?utf-8?B?MjFCK0RTLzVFZnJ4bFZ4RXVXbUJOalllb1NxT1ZjaVZZekxVQjNxeGNBNUc4?= =?utf-8?B?VTBPMm5EMkpsVGMvZWFkb0hoc3VqM0R3NCtIWUNkRUZid0V2U2ZBV2g1UFlN?= =?utf-8?B?UEt6TDQ1YXlrWFhEd1EwcVdibUN5azN5YmtxQUNTblMrY0h2R1FyQ2UyNkdC?= =?utf-8?B?Z2xhQ05SR3ZBWjZ2MWFvRGNOS3NNK1FJRFdTZG8xVDZGTFhzc1g0VVdZeW54?= =?utf-8?B?OXl2OUlpMTZKa3p1Y3B2Yk43dDVJNHNPOVVBN0JHWXNkTFl3S08zUGc3Y0l3?= =?utf-8?B?dkhVeDFRR285dmJXNG1kTGpvbDI3QUdqY2ZHdkt0eWtiRjJ6c0dtOFByQzlo?= =?utf-8?B?MFNVSmFlYVhJN25FZkNkMVFuMk03S0VKUjJ4b0R5NlZYZjFSS3RtZWZFRGFB?= =?utf-8?B?YWZxVHFPNk9pT0ZwUTRQRlF3UHA0Y2gwT2JGOHIzcUNtaVVoelpMcll1RnVF?= =?utf-8?B?dVFOOW5ReVRHT1dEMEpCM1VrVDk4WS9kR3FvUDd5THBtRkM0VWZ5NTJscXZr?= =?utf-8?B?dVZMZVBaSzNiamdLbGVDL2lpTFlORkNBU0RVYkk5OWxHZzA1d3ZEdEI4Rmwz?= =?utf-8?B?Y3ZzZGlobjBKUFBxbmJhVE1uNzcxOTVVUWtMLy9OcHBJbG1zem9mMDdSN3VG?= =?utf-8?B?Q2NHVnZqRUV6MHh2M2xybGJBbDNUNFR2SXhOeE81MWxHU3d6WkN4LzJjY01S?= =?utf-8?B?cmVTSW5BNk1EYXplL1l0UVZuajQvUmpNMDBUOHRXZDgvL25UZDRZTGRhK3Vm?= =?utf-8?B?KzhTYWppQUx4RmozbXdIYzR6SzB3bWd0aXFNVklBa2pTNmlpTktHYTFkTStD?= =?utf-8?B?MkQ0Ukt3bG1vMWdIYytLMG9oY0M2TStGTExrcnBFWWJHY3ZwOXRWM201MTFx?= =?utf-8?B?YXUrRkw5TDlBc05LNXFQVWJTcytET1JjVkViK3NnbnFVbXdqbWlxc1ZsdWsw?= =?utf-8?B?U215VkxZbVVSY1FQaWRDUll6MjBBZ2dONkpxaHFadytmR1VzSXlMQnQrdWlW?= =?utf-8?B?ZGlqa0d3c1l0ZEJtYllmcEc2MmExUm9xd21nWmlEK1BEaE4xT0hjWWVTNDgx?= =?utf-8?B?SlVVWUN6TVVjSU5Ta0o3NERZc2xteDNjaTREcWY3ei9JbzkwMnRGUTNuclhU?= =?utf-8?B?QXhKbVJFZSs3MDJMRmcxeGNNNlpQQm90UUxFK1MyQk0vb0x4dUdVbk5SUmlN?= =?utf-8?B?a2Z4SzN5d3Q4WTRyUHlFK081ajc1bEc4VkdTa29OZ3pxRzRHU2psMDlaV3R1?= =?utf-8?B?YnZ0cW03RmQzYzA5MUlLblJZZHJETjhWTzdkM3FWRGlrVmpHTUFMbXBmVGJF?= =?utf-8?B?clBJbnlvQ01xdWp6WmtPTzd4T2JFOE5JeEd1N0tNN1NraFhWbWswKzhISUpw?= =?utf-8?B?WG9HUDk2TEJsa1N5c1RmWHNQdS9UcXl1d0tCdjdyQVVaVUVOdjlYUVcyb3VK?= =?utf-8?B?bDcrczhsREg3MTgyTmRkcnNlN1dYY0doUjBBUVVYRUc4YmZHM3JpWDVwdEQx?= =?utf-8?B?Rmtjcmd2RWk5bFZvdDdiSnRKMVZYZ1p4WnBsNE5DUi9XdGg0U2hQZFMrZmtz?= =?utf-8?B?SHZOcGIzYUhGS3ZTbUYzNkFBVDQ1NC9TY0ttQkU2QllRYmh2WTRoZXdHd2N4?= =?utf-8?B?bEEvamhnMk9YQ0FXOE9RL2xrdTVpTXRqZWk4d0d5NDF1QU5zQ3BZTS9qWWZo?= =?utf-8?B?M2NpcGl2eWlEVkw0d1hiREJGRktEL095MDlLYnR3WDMvYWhQTEgvUVFOT2li?= =?utf-8?Q?AP/beWUOBBB+Krkc=3D?= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-Network-Message-Id: c0b2287f-5c50-48bd-46e4-08df0d40776d X-MS-Exchange-CrossTenant-AuthSource: PA4PR08MB6061.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Sep 2026 00:31:04.4178 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: tnn4BF6chfmmJUhNJHQvEjHywHnaIXWiWhNYOWOPIcjL8ByNGtLPqFZH0DdjtJmcSpdOKGQlj6dTxnhyen000lu/DS84mHZpLcVzG5mweC8= X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS2PR08MB8503 On 9/4/26 17:33, Andrey Drobyshev wrote: >> Resize was tied to block node, which we removed a few patches ago. >> Luckily we can make resize automated: receive an uevent socket >> from the management layer via the new "ueventfd" property (e.g. a >> /dev/fdset/N path), watch it for relevant netlink messages and >> call virtio_notify_config() if we detect a capacity change. >> >> The socket is set up (possibly with filter) by management layer. >> We only need to check that it is netlink and do some message >> filtering. >> >> When the property is not set, capacity changes are not detected. > > So libvirt must ALWAYS set it, and we fail in .realize() if it's not > set. Correct? Let's mention it. This is an optional field. If it is not set, nothing happens: vhost_blk_uevent_attach() returns true and realize goes on. > >> >> https://virtuozzo.atlassian.net/browse/VSTOR-143437 >> Signed-off-by: Andrey Zhadchenko >> >> diff --git a/hw/block/vhost-blk.c b/hw/block/vhost-blk.c >> index 04a7013e521..7cb842a859e 100644 >> --- a/hw/block/vhost-blk.c >> +++ b/hw/block/vhost-blk.c >> @@ -10,7 +10,9 @@ >> >> #include "qemu/osdep.h" >> #include "qapi/error.h" >> +#include "qemu/cutils.h" >> #include "qemu/error-report.h" >> +#include "qemu/main-loop.h" >> #include "qom/object.h" >> #include "hw/qdev-core.h" >> #include "hw/boards.h" >> @@ -25,6 +27,7 @@ >> #include "linux-headers/linux/vhost.h" >> #include >> #include >> +#include >> #include "system/runstate.h" >> >> static int vhost_blk_start(VirtIODevice *vdev) >> @@ -228,6 +231,173 @@ static int vhost_blk_update_size(VHostBlk *s, bool *changed, Error **errp) >> return 0; >> } >> >> +static void vhost_blk_resize_bh(void *opaque) >> +{ >> + VHostBlk *s = opaque; >> + Error *local_err = NULL; >> + bool changed; >> + >> + if (vhost_blk_update_size(s, &changed, &local_err) < 0) { >> + error_report_err(local_err); >> + return; >> + } >> + >> + if (changed) { >> + virtio_notify_config(VIRTIO_DEVICE(s)); >> + } >> +} >> + >> +/* >> + * The uevent socket is created, bound and filtered by the management >> + * layer and passed to us via the "ueventfd" property. >> + */ >> +static void vhost_blk_uevent_read(void *opaque) >> +{ >> + VHostBlk *s = opaque; >> + char buffer[64 * 1024 + 1]; > > include/linux/kobject.h > 33:#define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ > > Looks like 64K is overkill, maybe 4K? > >> + >> + for (;;) { >> + struct sockaddr_nl source; >> + socklen_t source_len = sizeof(source); >> + uint64_t event_major = UINT64_MAX; >> + uint64_t event_minor = UINT64_MAX; >> + bool action_change = false; >> + bool subsystem_block = false; >> + bool resize = false; >> + char *field; >> + char *end; >> + ssize_t len; >> + >> + memset(&source, 0, sizeof(source)); >> + len = recvfrom(s->uevent_fd, buffer, sizeof(buffer) - 1, >> + MSG_DONTWAIT, (struct sockaddr *)&source, &source_len); >> + if (len < 0) { >> + if (errno == EINTR) { >> + continue; >> + } >> + if (errno == ENOBUFS) { >> + /* Some events may be dropped, just re-check */ >> + qemu_bh_schedule(s->resize_bh); >> + continue; >> + } >> + if (errno != EAGAIN && errno != EWOULDBLOCK) { > > Should ENOMEM go here to? And if it's an error that breaks the socket, > like EBADF or smth else - maybe spit the error and detach the handler? > What's the point of keeping it afterwards? ENOMEM is expected only for recvmsg. > >> + error_report("vhost-blk: unable to receive uevent: %s", >> + strerror(errno)); >> + } >> + return; >> + } >> + >> + if (source.nl_family != AF_NETLINK || source.nl_pid != 0) { >> + continue; >> + } >> + >> + buffer[len] = '\0'; >> + field = buffer; >> + end = buffer + len; >> + while (field < end) { >> + size_t field_len = strnlen(field, end - field); >> + >> + if (!strcmp(field, "ACTION=change")) { >> + action_change = true; >> + } else if (!strcmp(field, "SUBSYSTEM=block")) { >> + subsystem_block = true; >> + } else if (!strcmp(field, "RESIZE=1")) { >> + resize = true; >> + } else if (g_str_has_prefix(field, "MAJOR=")) { >> + uint64_t value; >> + >> + if (!qemu_strtou64(field + strlen("MAJOR="), NULL, 10, >> + &value)) { >> + event_major = value; >> + } >> + } else if (g_str_has_prefix(field, "MINOR=")) { >> + uint64_t value; >> + >> + if (!qemu_strtou64(field + strlen("MINOR="), NULL, 10, >> + &value)) { >> + event_minor = value; >> + } >> + } >> + >> + if (field_len == end - field) { >> + break; >> + } >> + field += field_len + 1; >> + } >> + >> + if (action_change && subsystem_block && resize && >> + event_major == major(s->backend_rdev) && >> + event_minor == minor(s->backend_rdev)) { >> + qemu_bh_schedule(s->resize_bh); >> + } >> + } >> +} >> + >> +static bool vhost_blk_uevent_check(int fd, const char *src, Error **errp) >> +{ >> + socklen_t optlen; >> + int domain; >> + int protocol; >> + >> + optlen = sizeof(domain); >> + if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &domain, &optlen) < 0) { >> + error_setg_errno(errp, errno, "vhost-blk: '%s' is not a socket", src); >> + return false; >> + } >> + >> + optlen = sizeof(protocol); >> + if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &protocol, &optlen) < 0) { >> + error_setg_errno(errp, errno, >> + "vhost-blk: unable to get protocol of '%s'", src); >> + return false; >> + } >> + >> + if (domain != AF_NETLINK || protocol != NETLINK_KOBJECT_UEVENT) { >> + error_setg(errp, >> + "vhost-blk: '%s' is not a NETLINK_KOBJECT_UEVENT socket", >> + src); >> + return false; >> + } > > How about also checking nl_groups? Should be 1 for multicast. I.e. > > if (getsockname(fd, (struct sockaddr *)&addr, &addrlen) < 0) { > error_setg_errno(...); > return false; > } > if (addr.nl_groups != 1) { > error_setg(errp, "vhost-blk: '%s' is not subscribed to kernel uevents", > src); > return false; > } > >> + >> + return true; >> +} >> + >> +static bool vhost_blk_uevent_attach(VHostBlk *s, Error **errp) >> +{ >> + if (!s->conf.ueventfd) { >> + return true; >> + } >> + >> + s->uevent_fd = qemu_open(s->conf.ueventfd, O_RDWR, errp); > > For conf values monitor_fd_param() is usually used, so how about > > s->uevent_fd = monitor_fd_param(monitor_cur(), s->conf.ueventfd, errp); > > Andrey >