From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f171.google.com (mail-oi1-f171.google.com [209.85.167.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9818839A7F4 for ; Wed, 7 Jan 2026 15:35:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.171 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767800114; cv=none; b=gzBZyJeW999j+8qYfBVkizrYQ8artC6988J0riVRiO6fz7scICqsX/0Mfl4UMWXzhzClReooDfbsCtau6p8k2Kvo8mUPuPOB6p3Fc3wINi58TiHkaVLb5FOzo3lulN5avEqvvUQe6dPTAYbwWQgOrydLd3Cq45mPO1GtYm0T128= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767800114; c=relaxed/simple; bh=UH7UVmm/ifZMz2a7ctzEVAj9QL1YqJfv9TEsJAmqvl0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R9DIA036fU+/EJONMx/0EixYvJlHM/T37zx0wsnKSjY9OSBl2EjGUe7Z4MAr1X0IFJTcDvvGDIPWmP7UO95DNyNhIaI6Cvq8SFpnoK8ydZ/kf+HJtYWJWHPhgQpZebDPkg1Ir09TGV+sG8KzGRIibzHwUuA0qR8JSFo/VXPg3r0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=Groves.net; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bMuO/cKD; arc=none smtp.client-ip=209.85.167.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=Groves.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bMuO/cKD" Received: by mail-oi1-f171.google.com with SMTP id 5614622812f47-450be85b7d9so1408781b6e.0 for ; Wed, 07 Jan 2026 07:35:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1767800110; x=1768404910; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=ezmCIUYTCpc47N9MRFviC1UdzpKfkRUPsUPtXb573Uk=; b=bMuO/cKDgBQ7MDSk9U5rZupNeiODJwTx7I9gFDCFydqoRNF5bb5XBxGm7iO3pn2zmN RJWqRTwynU8DZ/Me9oX3OL1LfaPxg14B7bdiRmWRZS4TZHssZrk3Ihp97s+ZtjHgWNh8 YIjNdzcT0FtM+bnOwTgYOjNB8SCxhrBqERxthL0J3Mt/FA+v5wfAwF54UwLNOv5dmsA0 EcVHjxwIK7HTCh57TbkiagniQE4U0EG04F69w+iLXXUK3kwMCPRTkYLC444XDiw9oYf5 aXZlR7uvFrBdaNyQhR/ylbn4O75Y8KrKto8jynUQU7yvwgquWvo1bIsqDzcVZzo4TFGl 9tBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767800110; x=1768404910; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ezmCIUYTCpc47N9MRFviC1UdzpKfkRUPsUPtXb573Uk=; b=dbjtjcPae6iYvhh058whQ23yuSQWy8itB3cMmHvrQHP9Q6DIjqON4DFEd38srmKMkb CJNQncuxFu3Zk1ukSey9Jc20gMoy9MU8HZJuDD8LXsePUX90Rj4lML9Lc1zPS1by86tB E303QuB79wJRu1mC6+3bWxGB8cO0ungk1K5ErqDaKvaH27oMCOH/hGsUAp2SOz8fRjA4 qvIb/tAdyusxPXBX7VdpFvF5ZWRO2SMZKGUTjo+jtbkpusSdPJEb4n2WrZA36R5uZNqk kwebQE+0zmCdfAAMvRIQObzt8v4X/2YcEkI81ZPylApfSp2FlSCzI8gi+sLTjZ0nGy/y nnqg== X-Forwarded-Encrypted: i=1; AJvYcCVNe81mVvDc9V+U6X9ilyGBJKEp1a1debfxA9oJ5/9/vg+IOQlGD0cdlQtWID/eszkEJM2rjJGy9to=@vger.kernel.org X-Gm-Message-State: AOJu0YxVMwbr8QF/M6NAwqY/fWsN1HgN/pnurGgcmrNmB8PO0ybdPRYD VU1QHFAOCe4M3UFwv5s2h082vjnCpS2s4LyJ5iJiFiKe5QSinbdzDfYe X-Gm-Gg: AY/fxX5+MvwjAlqyyeKb0AI4NbG23xXuQmvrzFVBQ5+vlBI7CBoFq228+B39yeF+Loe 8ezE1dYOr+GplPv+R1wTd/bSaSiUPKKjuJBS3KcVnCQSXXq4BWQUKGB6ZOXnkve+rCmnDcXLOr1 2dqjOVQO1BQ5d5sm2MOvLjYdcVpKg9z5bHgqX9e3vpYux7fpelt7f9sL3Vf/cnb43XyXyPv1GCu wVDiYOlvMaQXwk4SUosyhm+GjMV8MVGv/LLf/ATnh93HkaPP72oePnu/mgTVKaITpUsDQMPK/Br bVaBBTvzBdapqCyj3allKWMVuoVdBR36m0qTnSFSFzuR6GPHAFyhraqe0JhDs4At26dO1qh7uxe k5Ma9HQJEGEq0ICKtPMK/uelIQirn0MkRsM5bgXT+6+EzuJBRIB3nHUghTKhKYR3PgajpOSWmXg BkG6I75UUHyZg+0TaICixsYzVT5GYzGkviKWDzevCi29Il X-Google-Smtp-Source: AGHT+IHvJerAp0F2qVu0ANwUQaq5jdMW03NUN3RN1p6cxOBwInFyFNG7vh1+02TkB75u28LmDWlVDQ== X-Received: by 2002:a05:6808:2208:b0:459:bcff:a9ff with SMTP id 5614622812f47-45a6be8b053mr1272252b6e.34.1767800109996; Wed, 07 Jan 2026 07:35:09 -0800 (PST) Received: from localhost.localdomain ([2603:8080:1500:3d89:a917:5124:7300:7cef]) by smtp.gmail.com with ESMTPSA id 5614622812f47-45a5e183cd4sm2415499b6e.1.2026.01.07.07.35.07 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 07 Jan 2026 07:35:09 -0800 (PST) Sender: John Groves From: John Groves X-Google-Original-From: John Groves To: John Groves , Miklos Szeredi , Dan Williams , Bernd Schubert , Alison Schofield Cc: John Groves , Jonathan Corbet , Vishal Verma , Dave Jiang , Matthew Wilcox , Jan Kara , Alexander Viro , David Hildenbrand , Christian Brauner , "Darrick J . Wong" , Randy Dunlap , Jeff Layton , Amir Goldstein , Jonathan Cameron , Stefan Hajnoczi , Joanne Koong , Josef Bacik , Bagas Sanjaya , Chen Linxuan , James Morse , Fuad Tabba , Sean Christopherson , Shivank Garg , Ackerley Tng , Gregory Price , Aravind Ramesh , Ajay Joshi , venkataravis@micron.com, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, nvdimm@lists.linux.dev, linux-cxl@vger.kernel.org, linux-fsdevel@vger.kernel.org, John Groves Subject: [PATCH 2/2] Add test/daxctl-famfs.sh to test famfs mode transitions: Date: Wed, 7 Jan 2026 09:34:59 -0600 Message-ID: <20260107153459.64821-3-john@groves.net> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260107153459.64821-1-john@groves.net> References: <20260107153244.64703-1-john@groves.net> <20260107153459.64821-1-john@groves.net> Precedence: bulk X-Mailing-List: linux-cxl@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: John Groves - devdax <-> famfs mode switches - Verify famfs -> system-ram is rejected (must go via devdax) - Test JSON output shows correct mode - Test error handling for invalid modes The test is added to the destructive test suite since it modifies device modes. Signed-off-by: John Groves --- test/daxctl-famfs.sh | 253 +++++++++++++++++++++++++++++++++++++++++++ test/meson.build | 2 + 2 files changed, 255 insertions(+) create mode 100755 test/daxctl-famfs.sh diff --git a/test/daxctl-famfs.sh b/test/daxctl-famfs.sh new file mode 100755 index 0000000..12fbfef --- /dev/null +++ b/test/daxctl-famfs.sh @@ -0,0 +1,253 @@ +#!/bin/bash -Ex +# SPDX-License-Identifier: GPL-2.0 +# Copyright (C) 2025 Micron Technology, Inc. All rights reserved. +# +# Test daxctl famfs mode transitions and mode detection + +rc=77 +. $(dirname $0)/common + +trap 'cleanup $LINENO' ERR + +daxdev="" +original_mode="" + +cleanup() +{ + printf "Error at line %d\n" "$1" + # Try to restore to original mode if we know it + if [[ $daxdev && $original_mode ]]; then + "$DAXCTL" reconfigure-device -f -m "$original_mode" "$daxdev" 2>/dev/null || true + fi + exit $rc +} + +# Check if fsdev_dax module is available +check_fsdev_dax() +{ + if modinfo fsdev_dax &>/dev/null; then + return 0 + fi + if grep -qF "fsdev_dax" "/lib/modules/$(uname -r)/modules.builtin" 2>/dev/null; then + return 0 + fi + printf "fsdev_dax module not available, skipping\n" + exit 77 +} + +# Check if kmem module is available (needed for system-ram mode tests) +check_kmem() +{ + if modinfo kmem &>/dev/null; then + return 0 + fi + if grep -qF "kmem" "/lib/modules/$(uname -r)/modules.builtin" 2>/dev/null; then + return 0 + fi + printf "kmem module not available, skipping system-ram tests\n" + return 1 +} + +# Find an existing dax device to test with +find_daxdev() +{ + # Look for any available dax device + daxdev=$("$DAXCTL" list | jq -er '.[0].chardev // empty' 2>/dev/null) || true + + if [[ ! $daxdev ]]; then + printf "No dax device found, skipping\n" + exit 77 + fi + + # Save the original mode so we can restore it + original_mode=$("$DAXCTL" list -d "$daxdev" | jq -er '.[].mode') + + printf "Found dax device: %s (current mode: %s)\n" "$daxdev" "$original_mode" +} + +daxctl_get_mode() +{ + "$DAXCTL" list -d "$1" | jq -er '.[].mode' +} + +# Ensure device is in devdax mode for testing +ensure_devdax_mode() +{ + local mode + mode=$(daxctl_get_mode "$daxdev") + + if [[ "$mode" == "devdax" ]]; then + return 0 + fi + + if [[ "$mode" == "system-ram" ]]; then + printf "Device is in system-ram mode, attempting to convert to devdax...\n" + "$DAXCTL" reconfigure-device -f -m devdax "$daxdev" + elif [[ "$mode" == "famfs" ]]; then + printf "Device is in famfs mode, converting to devdax...\n" + "$DAXCTL" reconfigure-device -m devdax "$daxdev" + else + printf "Device is in unknown mode: %s\n" "$mode" + return 1 + fi + + [[ $(daxctl_get_mode "$daxdev") == "devdax" ]] +} + +# +# Test basic mode transitions involving famfs +# +test_famfs_mode_transitions() +{ + printf "\n=== Testing famfs mode transitions ===\n" + + # Ensure starting in devdax mode + ensure_devdax_mode + [[ $(daxctl_get_mode "$daxdev") == "devdax" ]] + printf "Initial mode: devdax - OK\n" + + # Test: devdax -> famfs + printf "Testing devdax -> famfs... " + "$DAXCTL" reconfigure-device -m famfs "$daxdev" + [[ $(daxctl_get_mode "$daxdev") == "famfs" ]] + printf "OK\n" + + # Test: famfs -> famfs (re-enable in same mode) + printf "Testing famfs -> famfs (re-enable)... " + "$DAXCTL" reconfigure-device -m famfs "$daxdev" + [[ $(daxctl_get_mode "$daxdev") == "famfs" ]] + printf "OK\n" + + # Test: famfs -> devdax + printf "Testing famfs -> devdax... " + "$DAXCTL" reconfigure-device -m devdax "$daxdev" + [[ $(daxctl_get_mode "$daxdev") == "devdax" ]] + printf "OK\n" + + # Test: devdax -> devdax (re-enable in same mode) + printf "Testing devdax -> devdax (re-enable)... " + "$DAXCTL" reconfigure-device -m devdax "$daxdev" + [[ $(daxctl_get_mode "$daxdev") == "devdax" ]] + printf "OK\n" +} + +# +# Test mode transitions with system-ram (requires kmem) +# +test_system_ram_transitions() +{ + printf "\n=== Testing system-ram transitions with famfs ===\n" + + # Ensure we start in devdax mode + ensure_devdax_mode + [[ $(daxctl_get_mode "$daxdev") == "devdax" ]] + + # Test: devdax -> system-ram + printf "Testing devdax -> system-ram... " + "$DAXCTL" reconfigure-device -N -m system-ram "$daxdev" + [[ $(daxctl_get_mode "$daxdev") == "system-ram" ]] + printf "OK\n" + + # Test: system-ram -> famfs should fail + printf "Testing system-ram -> famfs (should fail)... " + if "$DAXCTL" reconfigure-device -m famfs "$daxdev" 2>/dev/null; then + printf "FAILED - should have been rejected\n" + return 1 + fi + printf "OK (correctly rejected)\n" + + # Test: system-ram -> devdax -> famfs (proper path) + printf "Testing system-ram -> devdax -> famfs... " + "$DAXCTL" reconfigure-device -f -m devdax "$daxdev" + [[ $(daxctl_get_mode "$daxdev") == "devdax" ]] + "$DAXCTL" reconfigure-device -m famfs "$daxdev" + [[ $(daxctl_get_mode "$daxdev") == "famfs" ]] + printf "OK\n" + + # Restore to devdax for subsequent tests + "$DAXCTL" reconfigure-device -m devdax "$daxdev" +} + +# +# Test JSON output shows correct mode +# +test_json_output() +{ + printf "\n=== Testing JSON output for mode field ===\n" + + # Test devdax mode in JSON + ensure_devdax_mode + printf "Testing JSON output for devdax mode... " + mode=$("$DAXCTL" list -d "$daxdev" | jq -er '.[].mode') + [[ "$mode" == "devdax" ]] + printf "OK\n" + + # Test famfs mode in JSON + "$DAXCTL" reconfigure-device -m famfs "$daxdev" + printf "Testing JSON output for famfs mode... " + mode=$("$DAXCTL" list -d "$daxdev" | jq -er '.[].mode') + [[ "$mode" == "famfs" ]] + printf "OK\n" + + # Restore to devdax + "$DAXCTL" reconfigure-device -m devdax "$daxdev" +} + +# +# Test error messages for invalid transitions +# +test_error_handling() +{ + printf "\n=== Testing error handling ===\n" + + # Ensure we're in famfs mode + "$DAXCTL" reconfigure-device -m famfs "$daxdev" + + # Test that invalid mode is rejected + printf "Testing invalid mode rejection... " + if "$DAXCTL" reconfigure-device -m invalidmode "$daxdev" 2>/dev/null; then + printf "FAILED - invalid mode should be rejected\n" + return 1 + fi + printf "OK (correctly rejected)\n" + + # Restore to devdax + "$DAXCTL" reconfigure-device -m devdax "$daxdev" +} + +# +# Main test sequence +# +main() +{ + check_fsdev_dax + find_daxdev + + rc=1 # From here on, failures are real failures + + test_famfs_mode_transitions + test_json_output + test_error_handling + + # System-ram tests require kmem module + if check_kmem; then + # Save and disable online policy for system-ram tests + saved_policy="$(cat /sys/devices/system/memory/auto_online_blocks)" + echo "offline" > /sys/devices/system/memory/auto_online_blocks + + test_system_ram_transitions + + # Restore online policy + echo "$saved_policy" > /sys/devices/system/memory/auto_online_blocks + fi + + # Restore original mode + printf "\nRestoring device to original mode: %s\n" "$original_mode" + "$DAXCTL" reconfigure-device -f -m "$original_mode" "$daxdev" + + printf "\n=== All famfs tests passed ===\n" + + exit 0 +} + +main diff --git a/test/meson.build b/test/meson.build index 615376e..ad1d393 100644 --- a/test/meson.build +++ b/test/meson.build @@ -209,6 +209,7 @@ if get_option('destructive').enabled() device_dax_fio = find_program('device-dax-fio.sh') daxctl_devices = find_program('daxctl-devices.sh') daxctl_create = find_program('daxctl-create.sh') + daxctl_famfs = find_program('daxctl-famfs.sh') dm = find_program('dm.sh') mmap_test = find_program('mmap.sh') @@ -226,6 +227,7 @@ if get_option('destructive').enabled() [ 'device-dax-fio.sh', device_dax_fio, 'dax' ], [ 'daxctl-devices.sh', daxctl_devices, 'dax' ], [ 'daxctl-create.sh', daxctl_create, 'dax' ], + [ 'daxctl-famfs.sh', daxctl_famfs, 'dax' ], [ 'dm.sh', dm, 'dax' ], [ 'mmap.sh', mmap_test, 'dax' ], ] -- 2.49.0