From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from DB3PR0202CU003.outbound.protection.outlook.com (mail-northeuropeazon11020129.outbound.protection.outlook.com [52.101.84.129]) by lore.virtuozzo.com (Postfix) with ESMTPS id 19EA780275 for ; Thu, 3 Sep 2026 12:35:09 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ZmMZEGA78JF7exDO1x0Wz/9p8yspSNiTnpZ2kfgbbS0FSTq79GINrG6I7zdc2eVdsDdjCWnGDbR0Rb+h5xl0wDAfkNJH4cUd6Khz5ljcE5rwlmJeA3Q6zBpk+F8U6vJDdIn8LunCWpDvpwk8SEkjXzIcOfkcrbHIr8tg5thaPZ1N+nIsZYZ7GkC9xbMQ1lvNHBzt8MY8XuX2gANE19Lo3hPLe4vTUieQAK4zoXdmNn4jqd9zrnrECgxzVYNfh/z2IP4XZvMIh/MAFSeI8HnPFfyoO9cTUsdQ/SK+sTZag+WA48Yh3goESVnXixSG8BezBWxarrdAum7sgrsC2Mtm8Q== 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=meEOmm0qrGNBBlIfsxAyrd8MWFHTMZBvKRux0aBXMIc=; b=YLs8TdVdpmdbcztP+VnMdlLHsh25rTN1ZxBm131nXSBQ23TmRF9zRYz/0p/CevgomFS4bz/4QXn/eTSG29ozT0yiws8stZHaBnQnaC/ohO3r9AcBV2DYWu8RcpnbucXwQNDpI+C6f+s8I0DYgClNmpqSeYPHCJ40R/JTvYWWQrEpMS5QuCbKLtHTk4ddl7RV6gODgHxxdwmPTxhuNYOmgMCQUNQpm9jkT4ijcNfiYB4c9qtE2wzYSkDhx0ZqWPrDqKSO1VGWkOs5Y/Rxdl602ymGBEm0Me9LcfJssU/WFgPeCS+QfAVCgbPmWIbYxx4ATK1+0HIxAyWG3rrTgV4Wbg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 130.117.225.111) smtp.rcpttodomain=virtuozzo.com smtp.mailfrom=virtuozzo.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=virtuozzo.com; dkim=pass (signature was verified) header.d=virtuozzo.com; arc=none (0) 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=meEOmm0qrGNBBlIfsxAyrd8MWFHTMZBvKRux0aBXMIc=; b=nQZC9KRmHzRHV7smZRHXOMR+OLPd/imKFYMgjd0fipdDGAaayDFeKa4iRPfOSGRsCEeR4sar5h1eTpDO23B4SD+sBhDyCnqfWnj0hoqHjqKj7o9sYsUWK/pUh4V6LBthS9ZLLRUp9mInu3RB6K+1NXLHlZXSWoxHtvkY8RDxXoVXTJI8D0y09+ALtgNhT7PttTVV79IkBDL7M1Yk4oXgQYXHdzM3fyWsRcNxk21PCBf38Pa/AWR4TZWAT3QdDIxzlVzJr4NjxlIjcjmMnw0SLaRimXLT16EOLRWESPfWqePuEvgtByYVpAEx1PnDYj1d7em2p93W+wlGgjTOpur6jA== Received: from PAZP264CA0178.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:236::20) by GVXPR08MB10408.eurprd08.prod.outlook.com (2603:10a6:150:149::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.382.10; Thu, 3 Sep 2026 12:34:59 +0000 Received: from MI3PEPF00008491.eurprd03.prod.outlook.com (2603:10a6:102:236:cafe::90) by PAZP264CA0178.outlook.office365.com (2603:10a6:102:236::20) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.382.12 via Frontend Transport; Thu, 3 Sep 2026 12:34:58 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 130.117.225.111) smtp.mailfrom=virtuozzo.com; dkim=pass (signature was verified) header.d=virtuozzo.com;dmarc=pass action=none header.from=virtuozzo.com; Received-SPF: Pass (protection.outlook.com: domain of virtuozzo.com designates 130.117.225.111 as permitted sender) receiver=protection.outlook.com; client-ip=130.117.225.111; helo=relay.virtuozzo.com; pr=C Received: from relay.virtuozzo.com (130.117.225.111) by MI3PEPF00008491.mail.protection.outlook.com (10.167.240.152) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.382.8 via Frontend Transport; Thu, 3 Sep 2026 12:34:58 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-ID:Date:Subject:From: Content-Type; bh=meEOmm0qrGNBBlIfsxAyrd8MWFHTMZBvKRux0aBXMIc=; b=n39Yr04Tpmp4 IzoX+tdnpMBqfB98ZtINM40W2TeBVDKaiJpogoTeKfMW3g3DSCctaLIKm4JKhKZvXgWv/cshvyLVU iFFsB6p2cL74vlbGmQSN26hU/6Lhu/7uN7woTlB2WED6DsFWq+a/gYvlm6cPc6m3xEPbhx5MYleHi Vv1+7bQD4iFMPBRiGxG7NtLnO+XIwVBZ/MPBBB16I+w+ZPWlvTyJfXrrqXkDT/fzUSce8iZyYk6o4 LS82UD4RSKx1JVPnUiFsSHcq/gT/c02Yl500XkA7UKnKf3g3Aedl8asHw7F1x4ScKDfO9lH4GlIQ0 gNGJVKL8vUVkkDBT7biqjw==; Received: from [130.117.225.5] (helo=vz9-demens-1.aci.vzint.dev) by relay.virtuozzo.com with esmtp (Exim 4.96) (envelope-from ) id 1x26cF-00AcxS-1b; Thu, 03 Sep 2026 14:34:56 +0200 From: Andrey Zhadchenko To: svt-core@virtuozzo.com Cc: den@openvz.org, andrey.drobyshev@virtuozzo.com Subject: [QEMU HCI-8.0 PATCH 4/5] vhost-blk: watch the device for resize events Date: Thu, 3 Sep 2026 15:32:03 +0300 Message-ID: <20260903123204.24035-5-andrey.zhadchenko@virtuozzo.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20260903123204.24035-1-andrey.zhadchenko@virtuozzo.com> References: <20260903123204.24035-1-andrey.zhadchenko@virtuozzo.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MI3PEPF00008491:EE_|GVXPR08MB10408:EE_ X-MS-Office365-Filtering-Correlation-Id: 3d7a578a-265b-458c-0a90-08df09b7c444 X-LD-Processed: 0bc7f26d-0264-416e-a6fc-8352af79c58f,ExtAddr List-Id: svt-core@virtuozzo.com 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|36860700016|1800799024|82310400026|23010399003|376014|5113699003|10067099003|18002099003|22082099003|57112099003; X-Microsoft-Antispam-Message-Info: l5YDt51++wTRqO6oYrFcvLuPQamElkoqAkyre++zXK9048WSzXRDTPtPK73vp0cSc8d8rd+FTnalQCfOBZPpiRuMPvAx9h4n79b+xMEDdlnuGwWkQOGWITm1o/+sezbXIVDrJmix21aVOwAHzw5+Eq3ql8Kv8hYHJiw0qm3b7R9dhkjara/ia6OLYURDdgpvY5fydRM8gWFArHGlAmOIWlTI5HKZGPl5KURmDF2RI86G69qhN3+IHh875ZkZ/YWbt3kLSMeUQzcOAL+YmswNSN+UWYFmLI8M0EVBOecZT9KTJQk3JCG4aMLdd9jVtbfSSKnDtU1AOFThJ3zaUI5YpX5rkW+wVXdZbKyAAr7H6NJXiLJ+9jQq8RwWngS/cH9sxAbWjqKyZywKLKEwjsoZvI71SfyDyq6ODtwF5Ub2l9oT6/C+ZDbCsHGoLP2D023lnvriJOwOsYvtglIzaTmeverrpz9VbHOrIaCMaOCtpy13vZHJZxam6rNryY8WEgrlNkYyKMHRcKtprfFzs3WoxPEEz+BMNho7a3fmq4rRYsA0+8TvZm79LfiQeavi/3Y2PU26KShlNEziVHXgYsd4UqKEkX3eb/S0ZWTR88Qipr0UPCOkqWqfmAckuuNMTkxFs70KZZco9e954IiFJUQWyPDPdb6Gyh1KE+q73JvU2aiWb1MVPmaKM0RvIvyXUPpT2gJwuGKPjqn7RCeFAp8n64+9JsZWA0h/J/g+5gtC04QNbU1WgVImbtppjhpxESFaiGTa+VpAG/o4xGqcaBQUQOuARWrXrICrd48UdLfOH42cw8LXZMOmwsQ3VEyTGmLTutBrfFiVAD8v/7WbiJg+rJfNIqwWBzd6uyzqQiVFu+RDmvPbPzpUmirfSg33CsyBR26RRSR2Qh0jzeeQK3OFFW5Hl9ComryGtJ3Vr27xCLM= X-Forefront-Antispam-Report: CIP:130.117.225.111;CTRY:CH;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:relay.virtuozzo.com;PTR:relay.virtuozzo.com;CAT:NONE;SFS:(13230040)(36860700016)(1800799024)(82310400026)(23010399003)(376014)(5113699003)(10067099003)(18002099003)(22082099003)(57112099003);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: IHDVw+o8WR5efsjip82+lQNQTxDsM+t9TRWTip6eIkM/kv8qLUNfmOdpqmVsijy69hbpKayJNFtQIAl8Q/QuWKlcibJwO1zeYe/2jqk9kx0iqMaOYtPteWqOsNFaIv9kiv3hD+8sYygjI6mHSBZmC9OxZJM//l7fGAN64KWqrj+Ibt0hPd1Kh8LuUNFRH/jBtUCxc61QfWET7URAv9HJYGgh1egBHmBeLFqavt3oZZVMFzdHSvY35L7KD7d721uX/oohqbK6+sXtM2PJplUnwz43Ti9tAXof5Jt/7fH51JJbmWhSTQ4xGvENgqkcVnmUHs1uuAoNCwymfas6m3kix2zf3UnOja0kXQccBSDEokdM+7O+itvoaWEomWfWswAm2XZESUlX7HFwg+tXphPiDkQ31PeyeMoYbT667ZR6KDHGM2G/RBGYNgZrnw3ANGjB X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Sep 2026 12:34:58.5960 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 3d7a578a-265b-458c-0a90-08df09b7c444 X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=0bc7f26d-0264-416e-a6fc-8352af79c58f;Ip=[130.117.225.111];Helo=[relay.virtuozzo.com] X-MS-Exchange-CrossTenant-AuthSource: MI3PEPF00008491.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: GVXPR08MB10408 Resize was tied to block node, which we removed some time ago. Luckily we can make resize automated: watch netlink for relevant events and call virtio_notify_config() if we detect capacity change. Failed netlink setup during creation leads to failure, but this is a price we are ready to pay for consistency. https://virtuozzo.atlassian.net/browse/VSTOR-143437 Signed-off-by: Andrey Zhadchenko --- hw/block/vhost-blk.c | 193 ++++++++++++++++++++++++++++++++++ include/hw/virtio/vhost-blk.h | 5 + 2 files changed, 198 insertions(+) diff --git a/hw/block/vhost-blk.c b/hw/block/vhost-blk.c index 47b6e560d4..f8eca4d58a 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,8 +27,13 @@ #include "linux-headers/linux/vhost.h" #include #include +#include #include "system/runstate.h" +static int vhost_blk_uevent_fd = -1; +static QLIST_HEAD(, VHostBlk) vhost_blk_uevent_watchers = + QLIST_HEAD_INITIALIZER(vhost_blk_uevent_watchers); + static int vhost_blk_start(VirtIODevice *vdev) { VHostBlk *s = VHOST_BLK(vdev); @@ -230,6 +237,182 @@ static int vhost_blk_update_size(VHostBlk *s, Error **errp) return changed; } +static void vhost_blk_resize_bh(void *opaque) +{ + VHostBlk *s = opaque; + Error *local_err = NULL; + int ret; + + ret = vhost_blk_update_size(s, &local_err); + if (ret < 0) { + error_report_err(local_err); + return; + } + + if (ret) { + virtio_notify_config(VIRTIO_DEVICE(s)); + } +} + +static void vhost_blk_uevent_read(void *opaque) +{ + char buffer[64 * 1024 + 1]; + + 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(vhost_blk_uevent_fd, buffer, sizeof(buffer) - 1, + MSG_DONTWAIT, (struct sockaddr *)&source, &source_len); + if (len < 0) { + if (errno == EINTR) { + continue; + } + if (errno == ENOBUFS) { + VHostBlk *s; + + /* uevents dropped. Re-check just to be sure */ + QLIST_FOREACH(s, &vhost_blk_uevent_watchers, uevent_node) { + qemu_bh_schedule(s->resize_bh); + } + continue; + } + if (errno != EAGAIN && errno != EWOULDBLOCK) { + 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 <= UINT_MAX && event_minor <= UINT_MAX) { + VHostBlk *s; + + QLIST_FOREACH(s, &vhost_blk_uevent_watchers, uevent_node) { + dev_t rdev = s->backend_rdev; + + if (major(rdev) == event_major && + minor(rdev) == event_minor) { + qemu_bh_schedule(s->resize_bh); + } + } + } + } +} + +static bool vhost_blk_uevent_init(Error **errp) +{ + struct sockaddr_nl address = { + .nl_family = AF_NETLINK, + .nl_groups = 1, + }; + + if (vhost_blk_uevent_fd >= 0) { + return true; + } + + vhost_blk_uevent_fd = socket(AF_NETLINK, + SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, + NETLINK_KOBJECT_UEVENT); + if (vhost_blk_uevent_fd < 0) { + error_setg_errno(errp, errno, + "vhost-blk: unable to create uevent socket"); + return false; + } + + if (bind(vhost_blk_uevent_fd, (struct sockaddr *)&address, + sizeof(address)) < 0) { + error_setg_errno(errp, errno, + "vhost-blk: unable to bind uevent socket"); + qemu_close(vhost_blk_uevent_fd); + vhost_blk_uevent_fd = -1; + return false; + } + + qemu_set_fd_handler(vhost_blk_uevent_fd, vhost_blk_uevent_read, + NULL, NULL); + return true; +} + +static void vhost_blk_uevent_cleanup_if_unused(void) +{ + if (vhost_blk_uevent_fd < 0 || + !QLIST_EMPTY(&vhost_blk_uevent_watchers)) { + return; + } + + qemu_set_fd_handler(vhost_blk_uevent_fd, NULL, NULL, NULL); + qemu_close(vhost_blk_uevent_fd); + vhost_blk_uevent_fd = -1; +} + +static void vhost_blk_uevent_register(VHostBlk *s) +{ + s->resize_bh = qemu_bh_new(vhost_blk_resize_bh, s); + QLIST_INSERT_HEAD(&vhost_blk_uevent_watchers, s, uevent_node); + s->uevent_registered = true; +} + +static void vhost_blk_uevent_unregister(VHostBlk *s) +{ + if (!s->uevent_registered) { + return; + } + + QLIST_REMOVE(s, uevent_node); + s->uevent_registered = false; + qemu_bh_delete(s->resize_bh); + s->resize_bh = NULL; + vhost_blk_uevent_cleanup_if_unused(); +} + static bool vhost_blk_open_backend(VHostBlk *s, Error **errp) { BlockConf *conf = &s->conf.conf; @@ -254,6 +437,7 @@ static bool vhost_blk_open_backend(VHostBlk *s, Error **errp) s->conf.devpath); goto fail; } + s->backend_rdev = st.st_rdev; if (ioctl(s->backend_fd, BLKROGET, &readonly) < 0) { error_setg_errno(errp, errno, @@ -332,6 +516,12 @@ static void vhost_blk_device_realize(DeviceState *dev, Error **errp) return; } + if (!vhost_blk_uevent_init(errp)) { + qemu_close(s->backend_fd); + s->backend_fd = -1; + return; + } + s->dev.nvqs = conf->num_queues; s->dev.max_queues = conf->num_queues; s->dev.vqs = g_new0(struct vhost_virtqueue, s->dev.nvqs); @@ -366,6 +556,7 @@ static void vhost_blk_device_realize(DeviceState *dev, Error **errp) goto cleanup; } + vhost_blk_uevent_register(s); return; cleanup: @@ -385,6 +576,7 @@ cleanup: virtio_del_queue(vdev, i); } virtio_cleanup(vdev); + vhost_blk_uevent_cleanup_if_unused(); return; } @@ -393,6 +585,7 @@ static void vhost_blk_device_unrealize(DeviceState *dev) VirtIODevice *vdev = VIRTIO_DEVICE(dev); VHostBlk *s = VHOST_BLK(dev); + vhost_blk_uevent_unregister(s); qemu_del_vm_change_state_handler(s->mighand); vhost_blk_set_status(vdev, 0); vhost_dev_cleanup(&s->dev); diff --git a/include/hw/virtio/vhost-blk.h b/include/hw/virtio/vhost-blk.h index c6646f5845..815939419f 100644 --- a/include/hw/virtio/vhost-blk.h +++ b/include/hw/virtio/vhost-blk.h @@ -14,6 +14,7 @@ #include "standard-headers/linux/virtio_blk.h" #include "hw/block/block.h" #include "hw/virtio/vhost.h" +#include "qemu/queue.h" #define TYPE_VHOST_BLK "vhost-blk" #define VHOST_BLK(obj) \ @@ -43,6 +44,10 @@ typedef struct VHostBlk { struct vhost_dev dev; bool vhost_started; uint64_t length; + uint64_t backend_rdev; + QEMUBH *resize_bh; + QLIST_ENTRY(VHostBlk) uevent_node; + bool uevent_registered; } VHostBlk; #endif -- 2.43.5