From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from atuin.qyliss.net (localhost [IPv6:::1]) by atuin.qyliss.net (Postfix) with ESMTP id 9D2161D0D7; Wed, 10 Dec 2025 10:55:35 +0000 (UTC) Received: by atuin.qyliss.net (Postfix, from userid 993) id 09FA51D074; Wed, 10 Dec 2025 10:55:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on atuin.qyliss.net X-Spam-Level: X-Spam-Status: No, score=-0.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DMARC_MISSING,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=4.0.1 Received: from fout-a5-smtp.messagingengine.com (fout-a5-smtp.messagingengine.com [103.168.172.148]) by atuin.qyliss.net (Postfix) with ESMTPS id 0F8C11D071 for ; Wed, 10 Dec 2025 10:55:32 +0000 (UTC) Received: from phl-compute-11.internal (phl-compute-11.internal [10.202.2.51]) by mailfout.phl.internal (Postfix) with ESMTP id 1A33CEC058B for ; Wed, 10 Dec 2025 05:55:29 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-11.internal (MEProxy); Wed, 10 Dec 2025 05:55:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alyssa.is; h=cc :content-transfer-encoding:content-type:date:date:from:from :in-reply-to:message-id:mime-version:reply-to:subject:subject:to :to; s=fm3; t=1765364129; x=1765450529; bh=amhGuM2Iuj7k89ybqmumS li7AfE6YVJ+F53KWn0qKG8=; b=KgsEt3obbRle8RZZVNLmJl4pwSBWptO2iYKhC Ej7dLyXWGWd4YhUob2n43TqASuowu/qM6K1VGSw1yqxw86A7xd0njZAjEXNLaVaL 2TfiveMwz/XCjTiWs6L0USnMTwOt1R1MKH79XCcvoPJD7/kaMBmz1tJbBOQstR0N Ejkbweh7TDIMCBDlcNWt029WeIv1gYzIAgbG1gmnIjFNglAxfkeU23CPLzHUqzU/ UCiNzBE3xn7wC8gSTYvk7fbWdyR1VUwSIWd6NZd7H6dwHvF5bp6A52yskYBIQmWu i5FleXtDPTwJf1F8haZRD3dGrbuewsLa3H8yFFZTXCdne4h4g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:date:feedback-id:feedback-id:from:from:in-reply-to :message-id:mime-version:reply-to:subject:subject:to:to :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t= 1765364129; x=1765450529; bh=amhGuM2Iuj7k89ybqmumSli7AfE6YVJ+F53 KWn0qKG8=; b=ltjDDvl20n+I0FzNxpwblfn4jIEz+4UczY6xBKAsxPvvvjoEn6L aGQCa3MKiG16YRYI4XQPvcRhWkBx8CPiPMAgzsSfznNE/tFGz9h8g7pCNgR/OHAE JPhP2hHMYKLmxv63jSZFh7AMoTykzKZqCodYsLOH+yplf7M18KX64e0NT225dzDk xRUAIfsQQ5MI4euGhAim8MILXXiqa8RXbqHKToE0jhdRdEy0adQ2GVtwizDVV2et v1/0YZyBR3HtYnbqoeTwOQ7JvS9a3h+7REyNSoK4wJLWSiloFJ9Lh3v6AcbA0yj8 VwkSprqIkPYajWlMgfKymOSfuhFhlexq4Mg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddvvddvhecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecunecujfgurhephffvufffkffoggfgsedtkeertdertddtne cuhfhrohhmpeetlhihshhsrgcutfhoshhsuceohhhisegrlhihshhsrgdrihhsqeenucgg tffrrghtthgvrhhnpeeludekgeegieehjeeuffdtiefgjeffudeufeekueefgeelkedvke euffdtvdfgvdenucffohhmrghinhepphgrthhhqddrihhspdhfihhlvggpnhgrmhgvrdgr shdpphgrthhhrdhishenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrih hlfhhrohhmpehhihesrghlhihsshgrrdhishdpnhgspghrtghpthhtohepuddpmhhouggv pehsmhhtphhouhhtpdhrtghpthhtohepuggvvhgvlhesshhpvggtthhruhhmqdhoshdroh hrgh X-ME-Proxy: Feedback-ID: i12284293:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Wed, 10 Dec 2025 05:55:28 -0500 (EST) Received: by fw12.qyliss.net (Postfix, from userid 1000) id B3F516BCFD0A; Wed, 10 Dec 2025 11:55:17 +0100 (CET) From: Alyssa Ross To: devel@spectrum-os.org Subject: [PATCH 1/2] host/rootfs: atomically delete VM directories Date: Wed, 10 Dec 2025 11:55:14 +0100 Message-ID: <20251210105515.1033548-1-hi@alyssa.is> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: C23X6XGADCIICORR6XDUBBHCVJDSIW6T X-Message-ID-Hash: C23X6XGADCIICORR6XDUBBHCVJDSIW6T X-MailFrom: hi@alyssa.is X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-devel.spectrum-os.org-0; header-match-devel.spectrum-os.org-1; header-match-devel.spectrum-os.org-2; header-match-devel.spectrum-os.org-3; header-match-devel.spectrum-os.org-4; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.9 Precedence: list List-Id: Patches and low-level development discussion Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Create a hidden empty directory, swap it with the original one, then remove both. Teach lsvm to ignore both hidden and empty directories, and now we no longer have a race where lsvm would get confused if a VM directory was in the process of being recursively removed when it looked at it. Fixes: b51a97f ("host/rootfs: add run-appimage program") Signed-off-by: Alyssa Ross --- host/rootfs/image/usr/bin/run-appimage | 7 ++++++- host/rootfs/image/usr/bin/run-flatpak | 7 ++++++- tools/lsvm.rs | 19 ++++++++++++++----- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/host/rootfs/image/usr/bin/run-appimage b/host/rootfs/image/usr/bin/run-appimage index 36f57b85..d61a79c6 100755 --- a/host/rootfs/image/usr/bin/run-appimage +++ b/host/rootfs/image/usr/bin/run-appimage @@ -43,4 +43,9 @@ if { s6-instance-delete /run/service/vm-services $id } if { umount ${dir}/mount } # mount namespace if { umount ${dir}/mount } # private bind mount -rm -r $dir /run/configs/${id} + +# Atomically swap the VM directory with an empty one, which will be ignored by +# lsvm, then remove it, so we never have half a VM directory. +if { mkdir /run/vm/by-id/.${id} } +if { exch /run/vm/by-id/.${id} $dir } +background { rm -rf /run/vm/by-id/.${id} $dir } diff --git a/host/rootfs/image/usr/bin/run-flatpak b/host/rootfs/image/usr/bin/run-flatpak index 2ef20433..6be21075 100755 --- a/host/rootfs/image/usr/bin/run-flatpak +++ b/host/rootfs/image/usr/bin/run-flatpak @@ -45,4 +45,9 @@ if { s6-instance-delete -- /run/service/vm-services $id } if { umount ${dir}/mount } # mount namespace if { umount ${dir}/mount } # private bind mount -rm -r $dir /run/configs/${id} + +# Atomically swap the VM directory with an empty one, which will be ignored by +# lsvm, then remove it, so we never have half a VM directory. +if { mkdir /run/vm/by-id/.${id} } +if { exch /run/vm/by-id/.${id} $dir } +background { rm -rf /run/vm/by-id/.${id} $dir } diff --git a/tools/lsvm.rs b/tools/lsvm.rs index 8f98e4f6..5d67ac6f 100644 --- a/tools/lsvm.rs +++ b/tools/lsvm.rs @@ -81,12 +81,21 @@ fn run() -> Result<(), String> { for entry in read_dir("/run/vm/by-id").map_err(|e| format!("reading /run/vm/by-id: {e}"))? { let entry = entry.map_err(|e| format!("iterating /run/vm/by-id: {e}"))?; - if entry - .file_type() - .map_err(|e| format!("getting type of {:?}: {e}", entry.path()))? - .is_dir() + if !entry.file_name().as_bytes().starts_with(b".") + && entry + .file_type() + .map_err(|e| format!("getting type of {:?}: {e}", entry.path()))? + .is_dir() { - names.insert(entry.file_name(), Vec::new()); + let path = entry.path(); + if path + .read_dir() + .map_err(|e| format!("reading {path:?}: {e}"))? + .next() + .is_some() + { + names.insert(entry.file_name(), Vec::new()); + } } } -- 2.51.0