From patchwork Fri Apr 3 14:04:38 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2101 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225178; bh=WUquslnPlqi7xjAA4yjMwIZmqnk5XcSp1j8Q1E/p/RQ=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=XsqrEwFmkRePsK/4OnRUsLxso74tsJjrpCpJMcXN8wKQjdY8ePbFIcNCOTNB0GCrA MNe3DUoY8x3WlGr1rHAFZ4O3AtWrXzZgD4xYlZWQMxFHdB6bfJCXltH9v7Wq933G3f n4cGccteUfIWGaqS4eF3M3Qt/zJxDc+gP7PXNOOitg1lIIO9Tgngg1N4+B76AEG2B5 lraVo/lMcRzfASJbHEDug1mPMr7vq63zsiBJy4dPguyrmapeRdrKLi3eaJjE+hZbx1 NiZXpa+oWFqdywxPTrRGJP6x2pq2zBqRnUqwPVbpbft8mg0BHV9qB+HadDApyewgjp PcsTtA7WSlZ/Q== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 308466A364 for ; Fri, 3 Apr 2026 08:06:18 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id oZ9hXtziMnpD for ; Fri, 3 Apr 2026 08:06:18 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225175; bh=WUquslnPlqi7xjAA4yjMwIZmqnk5XcSp1j8Q1E/p/RQ=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=K8RDwbQSSEa2JJRehvNoOf/jolwGF0M60gdLisEblARmfYGflVH2wq7m/HRqo6Qu+ 8Dxbnc3D/WJkE7IQhHVPX2ibWn0I8H0FEm3R8V+DiKxdx6x1yyFLFoPr/wTs1cZSSY gnKjX6SvXlP55G515QoK9/jIlsi/iejx+ARa5pNsONE3r4n8OKBH+RPqrPJMCKNwQu rBn6HEJ9iVQ4sTlbFaEBiosa6SDDZkABDB0mpJ37LkCOpvSi3I2+YM5dev981Mmz76 p3iVnvB/w6QKx7S8z0dMuekNyjGnZAQNVSUEdY43l3WpNgs09/J/GwVwuwrSuDz3n0 itNXoW4w8bQCQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 15E2367EE6 for ; Fri, 3 Apr 2026 08:06:15 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225172; bh=hfNPGy2v7gfAB9QMjd+oXYSGpsc8j2dcEHxkJgdObhM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NzAGlHAzj02S8EqG7dCCYz0syoxlsvUXkSW0tnMPkqsiR3mLFIxYP+0k1L8rVACby 73vbu1tpaVsQLyEdVcRPgqF775DJ3jCpxjkaYrKKj61217JM6rweaTX1URgonLsjGo 0EXdkqPd+WI8BIZEARq+4zt1fuc/XtnvkTmFV594SbLIPpiw8wIWHEq7M90p/4i7Ks LIhmQZ+1kYgQdU3re8yAGPqNygH7tzf0gNfh32Sa0FcVS5BZrENraXVo/ryqugtDdJ 5iLYmMdXiIa3WJtnLnlZp8tG1+lC/iRRcjgj7qVZUSdPcRzOGBKSdURwxBMWhSmOZP L1Owjv2KTJecg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 1E00B6A377; Fri, 3 Apr 2026 08:06:12 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id ktAtozG7t14W; Fri, 3 Apr 2026 08:06:12 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225167; bh=wfj9jwKRUj6096mp6mKQUj2GQIOeF/ls60Lti2f/dAU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ITBCxfxNyO26T8EvglnijAM98h1Eg264qZhHYKfCpKecnNxRBOTy2libSrhJvR8ci a2E853WV5daijoml5asHyFJbAP4vTXJlEQFOy4TJjqepb2ihKGD8lWcmdsfl/0cIEF pz3sUCK0NOaQjuTYJQiq6iC/o1CciP60/p2l8XcVaPhVDPRNXqA+JG++VqUo0rLNcM PuYo3/g3zcROqYcBoVE7oKQHTQ1wpig08M3Z7Mcva59JszPqYnybZYkLum4eYywuSE mbpLNbDlhkrjNMqd2akl+ee3wWPLg6k3Ae5cG9hb5RhH5spTyKHUcyK9ixzjT07iKa cRwOASQD01cdQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id A014F6A35D; Fri, 3 Apr 2026 08:06:07 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Fri, 3 Apr 2026 08:04:38 -0600 Message-ID: <20260403140523.1998228-17-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260403140523.1998228-1-sjg@u-boot.org> References: <20260403140523.1998228-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: DGHOZ3IUEID6ASJYMONPLZ2J6Y2ZAB5J X-Message-ID-Hash: DGHOZ3IUEID6ASJYMONPLZ2J6Y2ZAB5J X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 16/34] vfs: cmd: Add commands for mount, umount, ls and load List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add standalone VFS commands for mount, umount, ls and load that replace the legacy filesystem commands with versions using absolute paths through the virtual filesystem layer. Mark the legacy ext and ext4l tests with buildconfigspec('cmd_fs_legacy') since the VFS commands replace the legacy syntax. Signed-off-by: Simon Glass --- cmd/Kconfig | 2 +- cmd/Makefile | 2 +- cmd/fs.c | 262 +++++++++++++++++++++++++++ fs/fs-uclass.c | 15 ++ fs/vfs.c | 81 ++++++--- include/fs.h | 14 ++ test/py/tests/test_fs/test_basic.py | 3 +- test/py/tests/test_fs/test_ext.py | 3 +- test/py/tests/test_fs/test_ext4l.py | 5 +- test/py/tests/test_fs/test_fs_cmd.py | 3 +- test/py/tests/test_fs/test_fs_fat.py | 3 +- 11 files changed, 362 insertions(+), 31 deletions(-) create mode 100644 cmd/fs.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 60ebb56de00..58e3f473bf3 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2990,7 +2990,7 @@ config CMD_FS_LEGACY config CMD_VFS bool "fs - virtual filesystem commands" depends on VFS - default y if SANDBOX + default VFS help Provides the 'fs' command with mount, umount and ls subcommands for the virtual filesystem layer. diff --git a/cmd/Makefile b/cmd/Makefile index 412a3096d0e..a4958843b40 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -94,7 +94,7 @@ obj-$(CONFIG_CMD_FPGA) += fpga.o obj-$(CONFIG_CMD_LUKS) += luks.o obj-$(CONFIG_CMD_FPGAD) += fpgad.o obj-$(CONFIG_CMD_FS_LEGACY) += fs_legacy.o -obj-$(CONFIG_CMD_VFS) += vfs.o +obj-$(CONFIG_CMD_VFS) += vfs.o fs.o obj-$(CONFIG_CMD_FUSE) += fuse.o obj-$(CONFIG_CMD_FWU_METADATA) += fwu_mdata.o obj-$(CONFIG_CMD_GETTIME) += gettime.o diff --git a/cmd/fs.c b/cmd/fs.c new file mode 100644 index 00000000000..21fe6ba3655 --- /dev/null +++ b/cmd/fs.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * VFS-based filesystem commands - mount, umount, ls, load + * + * These replace the legacy commands in cmd/fs_legacy.c with versions that + * use absolute paths through the virtual filesystem layer. + * + * Copyright 2026 Simon Glass + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int do_load(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], + int fstype); +int do_fs_types(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]); + +static int mount_handler(int argc, char *const argv[]) +{ + struct udevice *vfs, *fsdev, *dir, *mnt; + const char *subpath; + int ret; + + vfs = vfs_root(); + if (!vfs) + return -ENXIO; + + if (argc < 2) { + vfs_print_mounts(); + return 0; + } + + if (argc < 3) + return -EINVAL; + + /* Check if already mounted */ + ret = vfs_find_mount(vfs, argv[2], &mnt, &subpath); + if (!ret && mnt && !*subpath) + return -EBUSY; + + ret = uclass_get_device_by_name(UCLASS_FS, argv[1], &fsdev); + if (ret) + return ret; + + ret = vfs_resolve(vfs, argv[2], &dir); + if (ret) + return ret; + + return vfs_mount(vfs, dir, fsdev); +} + +static int do_mount(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + ret = mount_handler(argc, argv); + if (ret) { + printf("mount failed: %dE\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + mount, 3, 1, do_mount, + "mount a filesystem", + "[ ]\n" + " - With no args, list all mounts\n" + " - Mount device 'dev' at 'mountpoint'" +); + +static int umount_handler(const char *path) +{ + struct udevice *vfs; + + vfs = vfs_root(); + if (!vfs) + return -ENXIO; + + return vfs_umount_path(vfs, path); +} + +static int do_umount(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + if (argc < 2) + return CMD_RET_USAGE; + + ret = umount_handler(argv[1]); + if (ret) { + printf("Error: %dE\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + umount, 2, 1, do_umount, + "unmount a filesystem", + "\n" + " - Unmount the filesystem at 'mountpoint'" +); + +static int do_cd(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *path = argc >= 2 ? argv[1] : "/"; + int ret; + + ret = vfs_chdir(path); + if (ret) { + printf("Error: %dE\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + cd, 2, 1, do_cd, + "change working directory", + "[]\n" + " - Change to 'path' in the VFS (default /)" +); + +static int do_pwd(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + printf("%s\n", vfs_getcwd()); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + pwd, 1, 1, do_pwd, + "print working directory", + "\n - Print the current VFS working directory" +); + +static int do_ls(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *path = argc >= 2 ? argv[1] : NULL; + int ret; + + ret = vfs_ls(path); + if (ret) { + printf("Error: %dE\n", ret); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + ls, 2, 1, do_ls, + "list files in a directory (default cwd)", + "[]\n" + " - List files at 'path' in the VFS (default cwd)" +); + + +static int do_vfs_load(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct file_uc_priv *uc_priv; + ulong addr, bytes = 0; + struct udevice *fil; + long len_read; + loff_t pos = 0; + void *buf; + int ret; + + if (argc < 3) + return CMD_RET_USAGE; + + addr = hextoul(argv[1], NULL); + if (argc >= 4) + bytes = hextoul(argv[3], NULL); + if (argc >= 5) + pos = hextoull(argv[4], NULL); + + ret = vfs_open_file(argv[2], DIR_O_RDONLY, &fil); + if (ret) { + printf("Error: %dE\n", ret); + return CMD_RET_FAILURE; + } + + uc_priv = dev_get_uclass_priv(fil); + if (!bytes) + bytes = uc_priv->size - pos; + + buf = map_sysmem(addr, bytes); + len_read = file_read_at(fil, buf, pos, bytes); + unmap_sysmem(buf); + + if (len_read < 0) { + printf("Read failed: %ldE\n", len_read); + return CMD_RET_FAILURE; + } + + env_set_hex("fileaddr", addr); + env_set_hex("filesize", len_read); + + printf("%ld bytes read\n", len_read); + + return CMD_RET_SUCCESS; +} + +static int do_load_vfs(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + char *endp; + + /* + * Detect legacy syntax: load [ ...] + * If argv[1] is not a pure hex number, assume legacy syntax. + */ + if (argc >= 2) { + hextoul(argv[1], &endp); + if (*endp) + return do_load(cmdtp, flag, argc, argv, FS_TYPE_ANY); + } + + return do_vfs_load(cmdtp, flag, argc, argv); +} + +static int do_fstypes(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + return do_fs_types(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD( + fstypes, 1, 1, do_fstypes, + "List supported filesystem types", "" +); + +U_BOOT_CMD( + load, 7, 0, do_load_vfs, + "load binary file from a filesystem", + " [bytes [pos]]\n" + " - Load binary file from 'path' in the VFS to address 'addr'.\n" + " 'bytes' gives the size to load in bytes.\n" + " If 'bytes' is 0 or omitted, the file is read until the end.\n" + " 'pos' gives the file byte position to start reading from.\n" + " If 'pos' is 0 or omitted, the file is read from the start.\n" + "load [ [ [ [bytes [pos]]]]]\n" + " - Legacy: load from block device interface" +); diff --git a/fs/fs-uclass.c b/fs/fs-uclass.c index 2525067f166..4492ff60522 100644 --- a/fs/fs-uclass.c +++ b/fs/fs-uclass.c @@ -46,6 +46,21 @@ int fs_split_path(const char *fname, char **subdirp, const char **leafp) return 0; } +void fs_split_path_inplace(char *fname, const char **dirp, const char **leafp) +{ + char *last_slash; + + last_slash = strrchr(fname, '/'); + if (last_slash) { + *leafp = last_slash + 1; + *last_slash = '\0'; + *dirp = fname; + } else { + *leafp = fname; + *dirp = ""; + } +} + int fs_lookup_dir(struct udevice *dev, const char *path, struct udevice **dirp) { struct fs_ops *ops = fs_get_ops(dev); diff --git a/fs/vfs.c b/fs/vfs.c index 79b1ca0ef89..0cce5872735 100644 --- a/fs/vfs.c +++ b/fs/vfs.c @@ -408,8 +408,57 @@ static int vfs_resolve_mount(const char *path, char *resolved, int size, return vfs_find_mount(vfs, path, mntp, subpathp); } -int vfs_resolve(struct udevice *vfs, const char *path, - struct udevice **dirp) +/** + * vfs_resolve_dir() - Resolve a path to its parent directory and leaf name + * + * Resolves the mount, splits the subpath into directory and leaf, and + * looks up the directory device. + * + * @path: Absolute or relative VFS path + * @dirp: Returns the UCLASS_DIR device for the parent directory + * @leafp: Returns allocated copy of the leaf filename (caller must free) + * Return: 0 if OK, -ve on error + */ +static int vfs_resolve_dir(const char *path, struct udevice **dirp, + char **leafp) +{ + char resolved[FILE_MAX_PATH_LEN]; + struct udevice *mnt; + struct vfsmount *mnt_priv; + const char *subpath, *dirpart, *leaf; + char *sub; + int ret; + + ret = vfs_resolve_mount(path, resolved, sizeof(resolved), + &mnt, &subpath); + if (ret) + return log_msg_ret("vdm", ret); + + if (!mnt) + return log_msg_ret("vdr", -ENOENT); + + mnt_priv = dev_get_uclass_priv(mnt); + + /* + * Split in place - subpath points into resolved[], so we can + * modify it. After the split, dirpart is the directory portion + * and leaf points to the leaf filename. + */ + sub = (char *)subpath; + fs_split_path_inplace(sub, &dirpart, &leaf); + + ret = fs_lookup_dir(mnt_priv->target, dirpart, dirp); + if (ret) + return log_msg_ret("vdd", ret); + + *leafp = strdup(leaf); + if (!*leafp) + return log_msg_ret("vdl", -ENOMEM); + + return 0; +} + +int vfs_resolve(struct udevice *vfs, const char *path, struct udevice **dirp) { struct udevice *cur_fs, *best; const char *remain; @@ -501,34 +550,18 @@ void vfs_print_mounts(void) int vfs_open_file(const char *path, enum dir_open_flags_t oflags, struct udevice **filp) { - struct udevice *vfs, *mnt, *dir; - const char *subpath, *leaf; - struct vfsmount *mnt_priv; - char *dirpath; + struct udevice *dir; + char *leaf; int ret; - vfs = vfs_root(); - if (!vfs) - return log_msg_ret("voi", -ENXIO); - - ret = vfs_find_mount(vfs, path, &mnt, &subpath); - if (ret) - return log_msg_ret("vom", ret); - - mnt_priv = dev_get_uclass_priv(mnt); - - ret = fs_split_path(subpath, &dirpath, &leaf); - if (ret) - return log_msg_ret("vos", ret); - - ret = fs_lookup_dir(mnt_priv->target, dirpath, &dir); - free(dirpath); + ret = vfs_resolve_dir(path, &dir, &leaf); if (ret) - return log_msg_ret("vod", ret); + return log_msg_ret("vof", ret); ret = dir_open_file(dir, leaf, oflags, filp); + free(leaf); if (ret) - return log_msg_ret("vof", ret); + return log_msg_ret("voo", ret); return 0; } diff --git a/include/fs.h b/include/fs.h index c6b6323be3e..efca9b80611 100644 --- a/include/fs.h +++ b/include/fs.h @@ -122,4 +122,18 @@ int fs_lookup_dir(struct udevice *dev, const char *path, struct udevice **dirp); */ int fs_split_path(const char *fname, char **subdirp, const char **leafp); +/** + * fs_split_path_inplace() - Split a path into directory and leaf in place + * + * Modifies @fname by null-terminating at the last '/'. Sets @dirp to + * point to the directory part and @leafp to the leaf. If there is no + * '/', @dirp is set to "" and @leafp points to @fname unchanged. + * + * @fname: Path to split (modified in place when it contains '/') + * @dirp: Returns pointer to the directory part + * @leafp: Returns pointer to the leaf filename + */ +void fs_split_path_inplace(char *fname, const char **dirp, + const char **leafp); + #endif diff --git a/test/py/tests/test_fs/test_basic.py b/test/py/tests/test_fs/test_basic.py index 174e2e074f4..17e197df894 100644 --- a/test/py/tests/test_fs/test_basic.py +++ b/test/py/tests/test_fs/test_basic.py @@ -16,7 +16,8 @@ from fstest_defs import SMALL_FILE, BIG_FILE from fstest_helpers import assert_fs_integrity -@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('sandbox') +@pytest.mark.boardspec('!sandbox') @pytest.mark.slow class TestFsBasic: """Test basic filesystem operations via C unit tests.""" diff --git a/test/py/tests/test_fs/test_ext.py b/test/py/tests/test_fs/test_ext.py index 41f126e7876..a72e13a87bc 100644 --- a/test/py/tests/test_fs/test_ext.py +++ b/test/py/tests/test_fs/test_ext.py @@ -26,7 +26,8 @@ def str2fat(long_filename): name = '%s~1' % name[:6] return '%-8s %s' % (name, ext) -@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('sandbox') +@pytest.mark.boardspec('!sandbox') @pytest.mark.slow class TestFsExt(object): def test_fs_ext1(self, ubman, fs_obj_ext): diff --git a/test/py/tests/test_fs/test_ext4l.py b/test/py/tests/test_fs/test_ext4l.py index 0930ebd01ea..eb332d1b154 100644 --- a/test/py/tests/test_fs/test_ext4l.py +++ b/test/py/tests/test_fs/test_ext4l.py @@ -15,7 +15,8 @@ from tempfile import NamedTemporaryFile import pytest -@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('sandbox') +@pytest.mark.buildconfigspec('fs_ext4l') class TestExt4l: """Test ext4l filesystem operations.""" @@ -79,6 +80,7 @@ class TestExt4l: with ubman.log.section('Test ext4l msgs'): ubman.run_ut('fs', 'fs_test_ext4l_msgs', fs_image=ext4_image) + @pytest.mark.boardspec('!sandbox') def test_ls(self, ubman, ext4_image): """Test that ext4l can list directory contents.""" with ubman.log.section('Test ext4l ls'): @@ -114,6 +116,7 @@ class TestExt4l: with ubman.log.section('Test ext4l statfs'): ubman.run_ut('fs', 'fs_test_ext4l_statfs', fs_image=ext4_image) + @pytest.mark.boardspec('!sandbox') def test_fsinfo(self, ubman, ext4_image): """Test that fsinfo command displays filesystem statistics.""" with ubman.log.section('Test ext4l fsinfo'): diff --git a/test/py/tests/test_fs/test_fs_cmd.py b/test/py/tests/test_fs/test_fs_cmd.py index c925547c7bc..336300afe3d 100644 --- a/test/py/tests/test_fs/test_fs_cmd.py +++ b/test/py/tests/test_fs/test_fs_cmd.py @@ -4,7 +4,8 @@ import pytest -@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('sandbox') +@pytest.mark.boardspec('!sandbox') @pytest.mark.buildconfigspec('cmd_fs_generic') def test_fstypes(ubman): """Test that `fstypes` prints a result which includes `sandbox`.""" diff --git a/test/py/tests/test_fs/test_fs_fat.py b/test/py/tests/test_fs/test_fs_fat.py index b61d8ab9eac..8028213dae3 100644 --- a/test/py/tests/test_fs/test_fs_fat.py +++ b/test/py/tests/test_fs/test_fs_fat.py @@ -11,7 +11,8 @@ This test verifies fat specific file system behaviour. import pytest import re -@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('sandbox') +@pytest.mark.boardspec('!sandbox') @pytest.mark.slow class TestFsFat(object): def test_fs_fat1(self, ubman, fs_obj_fat):