From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from DUZPR83CU001.outbound.protection.outlook.com (mail-northeuropeazon11022092.outbound.protection.outlook.com [52.101.66.92]) by lore.virtuozzo.com (Postfix) with ESMTPS id 8CCD280266 for ; Fri, 4 Sep 2026 15:33:28 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=q0bNiSqsiZ55peao7CqeQ/ldownvyHUY1dkwRXKZyZYtFPH2u7KMRXMDHTmt0cXHi3JsEuAb3egjRuvzLlVDeFgRe+Y+3MCgkEmUPYKRVvDwTJ9bzv4xLEHimchowno2bqiHemC/ABYj9iT2s4hh+R5x6oOcT+BF3Po/PJb9orDwgy4jrTgngqGj63u6Ls6ETR29RR60LcdVdUEIgphjMevO1dT8Q6jveFB69dcu4kMip7k2pVNbl9dA+byCGA/Boy88E2HViYk9xFoLdkoBDQ2xH4E4INlBHMt1+anBfJnf0mpMILlSrhEhNT4JNFfqkNH0smGfw7VeHql6wuOBcw== 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=EpqTgo5e8ch7Bb1JBJnUheQEBRTo4gQN/fbLioCbewE=; b=XIOSBDwv818E4Myx2wmaaywFJpVujU91um76WhpGU5H5vpUvFPnG5YSiPRczOk8/u46Eh6fKmFFcdrtJFSRJKjJYFtLL+bZ9i7ydQg86Zd0QGz5h3KXYiva/xAYvhuKOikLo8fT1IqpTq47byfFlqkV7qisF3A7TbQt0QrOsNSyz1FoEukCLpzimAyiNoI+Sa8HzYr6ZBCk7gSXcnEL5D7+gMRpRJleT+seBkIIYMaLco6snOP27XnWHc8aXannCdBI9sxCtXSXoiKk1rhuWsQuIRBh3niYjK7XCtzNp1PKxyhnhNAti9A+Lf1C0HNRsx5wXjzaBQgoCBMDJKFZNxg== 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=EpqTgo5e8ch7Bb1JBJnUheQEBRTo4gQN/fbLioCbewE=; b=JuSJO5LHy8snXb2cKObmuAtTQTsczxSf8dVpaVP+VXWFc7R50nTEJHU+A75krVfZN+J1QSgS/H1kujAxMkJlL5JjqC/RYM1Yl7Qy/U3IjCZOZdY4ZOJSpv2pjBe75aUqUUsY7MW/tAdgf7QlTUo/n+H5bKtzbanAHzGBgVWD1GjPVqDrdrcWtYgbSK5EeH06H9OtCdrCgLUWh7EETMPi8JqbnRkJ8vZiolcBmSXqLaja3aK/eotTTiTVs+3v9M+eoKB1X82YHFUqk4z/c6ljQTCmfZVMn+IhMLbDDlOGv6bKzn4c/s0KT6rKzCe247T6edG8syNkezA3cKWPnN2ZQw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=virtuozzo.com; Received: from VI0PR08MB10656.eurprd08.prod.outlook.com (2603:10a6:800:20a::12) by VE1PR08MB5678.eurprd08.prod.outlook.com (2603:10a6:800:1a0::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.382.10; Fri, 4 Sep 2026 15:33:25 +0000 Received: from VI0PR08MB10656.eurprd08.prod.outlook.com ([fe80::4e37:b189:ddcd:3dd8]) by VI0PR08MB10656.eurprd08.prod.outlook.com ([fe80::4e37:b189:ddcd:3dd8%7]) with mapi id 15.21.0382.007; Fri, 4 Sep 2026 15:33:25 +0000 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Subject: Re: [QEMU HCI-8.0 PATCH v2 4/5] vhost-blk: watch the device for resize events From: Andrey Drobyshev To: Andrey Zhadchenko Cc: svt-core@virtuozzo.com, den@openvz.org, andrey.drobyshev@virtuozzo.com In-Reply-To: <20260904132155.180581-5-andrey.zhadchenko@virtuozzo.com> References: <20260904132155.180581-1-andrey.zhadchenko@virtuozzo.com> <20260904132155.180581-5-andrey.zhadchenko@virtuozzo.com> Date: Fri, 04 Sep 2026 18:33:18 +0300 Message-Id: <178853599893.728973.14654758383882924790.b4-review@b4> X-Mailer: b4 0.16.0 X-ClientProxiedBy: VI1PR09CA0127.eurprd09.prod.outlook.com (2603:10a6:803:12c::11) To VI0PR08MB10656.eurprd08.prod.outlook.com (2603:10a6:800:20a::12) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI0PR08MB10656:EE_|VE1PR08MB5678:EE_ X-MS-Office365-Filtering-Correlation-Id: 106d62fd-3c2d-4520-3c4c-08df0a99dbbc 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|1800799024|366016|376014|23010399003|52116014|5113699003|18002099003|22082099003|3023799007|56012099006|10067099003|4143699003|38350700014; X-Microsoft-Antispam-Message-Info: PJPZRNhR/tIJm3NC5EWbCxEQH7NWBMeJmDeu4IVcUjps5Hep/lmXpvtpDyXnYc2/J81TF69jaT2BQbgbw9ayqLu4EB5/iWsicskeuf9wodR/iwGoklbYqwZ6t7Np0HI14X3NSeDEkvqkHEgyb82LUvxyvBWG7w3hAUoMCyVR5DT2KBI9GbSfouq56JCPFrA5DzIcqJJZk9LEk2xR10Rr/mE8xJQPdPkAuhLBSHdiLL1zhgLui5FX/EesYAi9BWKXqlOVTA/wMchtVX6pkIRa39OWG3HT8NnvlojJG/JgpxBdH85jlrIVqnLZK6N3HXAXe+YfpYGT5Qnc3VXNa1lKpTbz1NBO7c65BgaX/iLMeCrV+5BtHgDW+E5/Tb3Ye+O/2rOFmY8XmuwJE1COdl/Oksk9qL0PJ/Hn9LZNCDtn64V5YpS5paToEB8kZYhoy9stY8dIKXdethvxTE1RIml1feviVXGkj+z8UnYST+qbHVQHcFVeehazS0RQOxjs931gUJBQICriaK1PuDQC0hvoG4PY4ArNXzwlJGHSE/VhzNsXLum7BkKHMiKo+H5ILV5RwWWqMDO6IyCdOXy7muUbFSphYNbvpsNhObuglKcq8eXmd48oHW2AoB5TfrSp+Iw+9pCI/q0nToIa1WQmv4F2zOC7uHTb7iUD30zujTD+QrKIyGKwr4MLEGK9WivVu/Nnbk3jZNJFDYJGVWvX3yopYUHkVqXtn2TPT1OqBf3Ij7c= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VI0PR08MB10656.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(366016)(376014)(23010399003)(52116014)(5113699003)(18002099003)(22082099003)(3023799007)(56012099006)(10067099003)(4143699003)(38350700014);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?Tys2QS94YktNU0tnajdPaGRQU25LWjAxMFByZGpyd05YdzZMTGorcUU1MVdP?= =?utf-8?B?MlAxRlNNSUhER3lYeVJqOXk2YjJUb2ZWV3NrWXpQUTZmN2xvWVRreDlhd0dQ?= =?utf-8?B?NFdqV1V3S3d1YWd5dTY5RGd4RzVpLzRVRy9Tc3hEVnBsQzZhRDRVSXU1dG1X?= =?utf-8?B?Rk5raUdPNnZUNEdaNmdVcE4vc1hZVXEycVJGb3h4dC9oNDExL1NkaVFIVTZG?= =?utf-8?B?Z0x3Z2kzYkxQRFM2ZmZoNjhBSEtNemVNR1BWdmdaeW9EWEtRNFVaZjNWdHZz?= =?utf-8?B?WGluUzFyNGlKRS9XME13VTVsTjRNUVpmT1RXbFZVL3VsRHV3TGU4cjluT2J3?= =?utf-8?B?eldPYW90RG5oQUNEZEhsRi9QUll2M3BiSWw0S3RBL2ZWZGhNb1d5ZDFINnRr?= =?utf-8?B?WU9Hd3BRcmF4L1FYOEZxQU5Pd1VYOEt3d2ZPS2hNWTcxc0pjQjN2NDlka3hL?= =?utf-8?B?eXRhZHpXWkpVd1RFbTNFa3J6NWtVUXF0UzdDVmdxOGlkZGg0MlhQQzhHQTVP?= =?utf-8?B?WlZMTmo2a1hmaGNtclQ1QnNMdHplN1NIUXdVV25pSVNLWEJXNVdLUDIxMUQz?= =?utf-8?B?WHdQMldJc2ZwK0I3RU92VzJkclRRTndWd1RjWmVlWlZxZjhLWmRndXczelBi?= =?utf-8?B?cEN1V1hjRDArek5hcUkrb3F1OXVZSGZ3U2lLUE9IK2hJcUsrNVlIb1pnUXg0?= =?utf-8?B?KzNPUFk4YTJMY0ZnblY2UGRvbDNXWHZYcE1UTGYxVzVFZHNYUXdFMUtHc0E3?= =?utf-8?B?SXJLUkJBbFdoaUp5cTlGUk9XZnpxTVRYbDFYYVNqY21jdjZsQzE2NkpKRHZ5?= =?utf-8?B?bm96bC9LVjZRZVQvZXNlU2ZDbGM1N1YvSGlLMmJzdzZQYTVxeUpGTTRKK2w0?= =?utf-8?B?RHp0RlJUSVhUbDA2dFRLNDRwVGdydkNsVGhvT2lrMUx6TE5ZbHZIVnB1TnZq?= =?utf-8?B?OThDZ29vWWxEMUJQZExCSm5TRm1lOVFFSllNVndSUFN2dTJISUdpVUhYSWpw?= =?utf-8?B?MGYxNEJVMzlrWmtVS1A4a0Zza3ZpZGxJUGxENThzSkdnNFVqUkZuMTdUNWlZ?= =?utf-8?B?ZkM2TWdrN3lpa2syRDQrSlJiWFBBd1h3YXYwOGs0SlBacTVqb3dsbUlGQ0th?= =?utf-8?B?Sjd1bkJZQ2xtbUdFTW92aG1jS1k0dDJwYW9UbG9rdVpDa1REbEw0ZWJCclFG?= =?utf-8?B?TkFEWUFLZGt6ZnF1K1JuL0RpUzNYb0pPbmRxWjhQa2pVbmRybTJubHg3QytU?= =?utf-8?B?VTVRdjJRVHRHa3hYMnhCeGFMOVd6NG1ES1dxUkNlQjJEZ2pBZ2NaOTcxUE9w?= =?utf-8?B?QTdidWRWMGNJVHIzQWpaY3FZcFFZNEU2OVJzYUFSbHJLdzRHR0lCR0ppNDBw?= =?utf-8?B?UzlIc09NcHh0V0dMeVBXMmR4NVdHeTcyaWZZVHhsR3FtS2xzekM5cFI5RTRE?= =?utf-8?B?VUJYV0ViV3E1R1JsUEJaODY2eTk1emZuenJzZTRnaG1tdnlOZmc2VmRodU93?= =?utf-8?B?cEZvRXBLTlZhbzNvYVR0T0xhb0Rpa2h2VGFUbTZ1ajh3OVorVkJORjNYN0Mz?= =?utf-8?B?US9LbDBnZklWMEhVNmdxVUh0S0dkaUNwSDRxb1JBb29tamplYmEvd2pWUVZ4?= =?utf-8?B?dHhsTHRrdW9weTRybjlQV3lhdWF2OHZEQ0Z6YlZwOFdiSVplbEg4dDFMcWlq?= =?utf-8?B?K3RaaGJqNDVXbUdNSStWc3AzQktzWGRNdFk0eHdvaG1DcUFhbXRaK3ljcjBV?= =?utf-8?B?bjMvNmdxS0J3RUUwZmEwMzY0NUk2SG1ZRWthdVRyOExPSzZML3VUd29sOFg5?= =?utf-8?B?VG95QXdyRnFIZk93eWFPMXZvRXU5ZFJFYjE2cWRMdzh0NjdkYXJaeGtJcmw3?= =?utf-8?B?dVpmeHE5bGRBS1ZVWjl1dzB6UE1idHZ2Vm5xbDlqd1VpUE1oY0dVbUN6Y0hl?= =?utf-8?B?RmowZWpERG5uR3lEUGhyY3RSRCtuR0RCYXN3ekxuR2gza0NOaWtxaC9aaEs1?= =?utf-8?B?L3NLamFxaDA2ck13ZVBJWnROQnZPYlpERjhHSFhiVkJEOUdQZFc3MEJEWmxj?= =?utf-8?B?V1RJOHc3bTZUQmoxdXQ4Yi9KRFdQQWhkak9mbis2N0ttOUZXY212TWJFeXAv?= =?utf-8?B?bUhHVWxTT2xSWjI3ZjVVNjI0T0U4akhWUis4M0UwbHdwdVhmbWFoQ0NnUitZ?= =?utf-8?B?ejhnT3R2eHVyUlZ4aVZlOWorL1pNOFlrQis4VjI5Tnp2SnQ1bEFKWUxkNE5r?= =?utf-8?B?dktlSVV5d1RTUXNzckM5MGJaRXRoNyt2NFR5VHJNVFpvajgvY0Q5MW9vc3Jz?= =?utf-8?B?SUNVZnEyRXl0cVU4TE5maEI1dlVEVy8vZnZRYmt6N3NBK2cvWlFmZkFaUkZp?= =?utf-8?Q?9E6w49OtDghmx88c=3D?= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-Network-Message-Id: 106d62fd-3c2d-4520-3c4c-08df0a99dbbc X-MS-Exchange-CrossTenant-AuthSource: VI0PR08MB10656.eurprd08.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Sep 2026 15:33:24.3752 (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: hkEMEicAwP7XFWpkR8pt89jWrGiSHmLPgZ4o7MPsvaxyEWkuoeOCHCAG1pNCKS7nMMb2I3IE482MNynrrw0OVQwQqIdzVoRQ9YItpU2apuc= X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1PR08MB5678 > 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. > > 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? > + 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 -- Andrey Drobyshev