1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2020 Red Hat, Inc. All rights reserved. 4 * Author: Zorro Lang <zlang@redhat.com> 5 * 6 * Basic fsmount() test. 7 */ 8 9#include "tst_test.h" 10#include "lapi/fsmount.h" 11 12#define MNTPOINT "mntpoint" 13 14#define TCASE_ENTRY(_flags, _attrs) {.name = "Flag " #_flags ", Attr " #_attrs, .flags = _flags, .attrs = _attrs} 15 16static struct tcase { 17 char *name; 18 unsigned int flags; 19 unsigned int attrs; 20} tcases[] = { 21 TCASE_ENTRY(0, MOUNT_ATTR_RDONLY), 22 TCASE_ENTRY(0, MOUNT_ATTR_NOSUID), 23 TCASE_ENTRY(0, MOUNT_ATTR_NODEV), 24 TCASE_ENTRY(0, MOUNT_ATTR_NOEXEC), 25 TCASE_ENTRY(0, MOUNT_ATTR_RELATIME), 26 TCASE_ENTRY(0, MOUNT_ATTR_NOATIME), 27 TCASE_ENTRY(0, MOUNT_ATTR_STRICTATIME), 28 TCASE_ENTRY(0, MOUNT_ATTR_NODIRATIME), 29 TCASE_ENTRY(FSMOUNT_CLOEXEC, MOUNT_ATTR_RDONLY), 30 TCASE_ENTRY(FSMOUNT_CLOEXEC, MOUNT_ATTR_NOSUID), 31 TCASE_ENTRY(FSMOUNT_CLOEXEC, MOUNT_ATTR_NODEV), 32 TCASE_ENTRY(FSMOUNT_CLOEXEC, MOUNT_ATTR_NOEXEC), 33 TCASE_ENTRY(FSMOUNT_CLOEXEC, MOUNT_ATTR_RELATIME), 34 TCASE_ENTRY(FSMOUNT_CLOEXEC, MOUNT_ATTR_NOATIME), 35 TCASE_ENTRY(FSMOUNT_CLOEXEC, MOUNT_ATTR_STRICTATIME), 36 TCASE_ENTRY(FSMOUNT_CLOEXEC, MOUNT_ATTR_NODIRATIME), 37}; 38 39static void run(unsigned int n) 40{ 41 struct tcase *tc = &tcases[n]; 42 int sfd, mfd; 43 44 TEST(sfd = fsopen(tst_device->fs_type, FSOPEN_CLOEXEC)); 45 if (sfd == -1) { 46 tst_res(TFAIL | TTERRNO, "fsopen() on %s failed", 47 tst_device->fs_type); 48 return; 49 } 50 51 TEST(fsconfig(sfd, FSCONFIG_SET_STRING, "source", tst_device->dev, 0)); 52 if (TST_RET == -1) { 53 SAFE_CLOSE(sfd); 54 tst_res(TFAIL | TTERRNO, 55 "fsconfig(FSCONFIG_SET_STRING) failed to set source to %s", tst_device->dev); 56 return; 57 } 58 59 TEST(fsconfig(sfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0)); 60 if (TST_RET == -1) { 61 SAFE_CLOSE(sfd); 62 tst_res(TFAIL | TTERRNO, "fsconfig(FSCONFIG_CMD_CREATE) failed"); 63 return; 64 } 65 66 TEST(mfd = fsmount(sfd, tc->flags, tc->attrs)); 67 SAFE_CLOSE(sfd); 68 69 if (mfd == -1) { 70 tst_res(TFAIL | TTERRNO, 71 "fsmount() failed to create a mount object"); 72 return; 73 } 74 75 TEST(move_mount(mfd, "", AT_FDCWD, MNTPOINT, MOVE_MOUNT_F_EMPTY_PATH)); 76 SAFE_CLOSE(mfd); 77 78 if (TST_RET == -1) { 79 tst_res(TFAIL | TTERRNO, 80 "move_mount() failed to attach to the mount point"); 81 return; 82 } 83 84 if (tst_is_mounted_at_tmpdir(MNTPOINT)) { 85 SAFE_UMOUNT(MNTPOINT); 86 tst_res(TPASS, "%s: fsmount() passed", tc->name); 87 } 88} 89 90static struct tst_test test = { 91 .tcnt = ARRAY_SIZE(tcases), 92 .test = run, 93 .setup = fsopen_supported_by_kernel, 94 .needs_root = 1, 95 .mntpoint = MNTPOINT, 96 .format_device = 1, 97 .all_filesystems = 1, 98 .skip_filesystems = (const char *const []){"fuse", NULL}, 99}; 100