Message ID | 01949a4ba3d2c125a9be8422ec27c8436a53f6a8.1582779464.git.viresh.kumar@linaro.org |
---|---|
State | Changes Requested |
Headers | show |
Series | Add new LTP tests related to fsmount family of syscalls | expand |
> Add tests to check working of fsconfig() syscall. ... > +++ b/testcases/kernel/syscalls/fsconfig/fsconfig01.c ... > +static void run(void) > +{ > + int fd, fsmfd; > + > + TEST(fd = fsopen(tst_device->fs_type, 0)); > + if (fd == -1) > + tst_brk(TBROK | TERRNO, "fsopen() failed"); > + > + TEST(fsconfig(fd, FSCONFIG_SET_FLAG, "rw", NULL, 0)); > + if (TST_RET == -1) { > + tst_res(TFAIL | TERRNO, "fsconfig() failed"); > + goto out; Because there is .test_all (single run), although which is called N times for each filesystem (.all_filesystems = 1), but cleanup is called for each of them it's I'll move SAFE_CLOSE(fd) to cleanup function and use here (and on the rest of calls) return (trying to avoid goto when possible). I'll change it before merge. > + > + TEST(fsmfd = fsmount(fd, 0, 0)); > + if (fsmfd == -1) { > + tst_res(TBROK | TERRNO, "fsmount() failed"); > + goto out; BTW This needs to be now tst_res(TFAIL) (this patchset now does not compile). > + TEST(fsconfig(fd, FSCONFIG_SET_FD, "sync", NULL, 0)); > + if (TST_RET == -1) { > + if (TST_ERR == EOPNOTSUPP) { > + tst_res(TCONF, "fsconfig(): FSCONFIG_SET_FD not supported"); > + } else { > + tst_res(TFAIL | TERRNO, "fsconfig() failed"); > + goto out; > + } > + } I get TCONF for all fsconfig01 results, while I'm using 5.5.5-1-default: tst_test.c:1290: INFO: Testing on ext2 tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext2 opts='' extra opts='' mke2fs 1.45.5 (07-Jan-2020) tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported fsconfig01.c:92: PASS: fsconfig() passed tst_test.c:1290: INFO: Testing on ext3 tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext3 opts='' extra opts='' mke2fs 1.45.5 (07-Jan-2020) tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported fsconfig01.c:92: PASS: fsconfig() passed tst_test.c:1290: INFO: Testing on ext4 tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext4 opts='' extra opts='' mke2fs 1.45.5 (07-Jan-2020) tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported fsconfig01.c:92: PASS: fsconfig() passed tst_test.c:1290: INFO: Testing on xfs tst_mkfs.c:89: INFO: Formatting /dev/loop0 with xfs opts='' extra opts='' tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s fsconfig01.c:92: PASS: fsconfig() passed tst_test.c:1290: INFO: Testing on btrfs tst_mkfs.c:89: INFO: Formatting /dev/loop0 with btrfs opts='' extra opts='' tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported fsconfig01.c:92: PASS: fsconfig() passed tst_test.c:1290: INFO: Testing on vfat tst_mkfs.c:89: INFO: Formatting /dev/loop0 with vfat opts='' extra opts='' tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported fsconfig01.c:92: PASS: fsconfig() passed Not yet merged man page [1] (I reposted David Howells commit) there is explanation for EOPNOTSUPP: The command given by cmd was not valid. First, I suspected "sync" option is wrong. But looking at kernel sources it's really not implemented: fs/fsopen.c if (fc->ops == &legacy_fs_context_ops) { switch (cmd) { case FSCONFIG_SET_BINARY: case FSCONFIG_SET_PATH: case FSCONFIG_SET_PATH_EMPTY: case FSCONFIG_SET_FD: ret = -EOPNOTSUPP; goto out_f; } } fs/fs_context.c /* TODO: Make all filesystems support this unconditionally */ init_fs_context = fc->fs_type->init_fs_context; if (!init_fs_context) init_fs_context = legacy_init_fs_context; ... /* * Initialise a legacy context for a filesystem that doesn't support * fs_context. */ static int legacy_init_fs_context(struct fs_context *fc) { fc->fs_private = kzalloc(sizeof(struct legacy_fs_context), GFP_KERNEL); if (!fc->fs_private) return -ENOMEM; fc->ops = &legacy_fs_context_ops; return 0; } Code coming from v5.1-rc1 f3a09c92018a91ad0981146a4ac59414f814d801 introduce fs_context methods [2]. Other patchsets here [3] shows there is some support for fs_context in VFS. So I wonder how to achieve not end up with legacy context. > +++ b/testcases/kernel/syscalls/fsconfig/fsconfig02.c > + {"set-path-key", &fd, FSCONFIG_SET_PATH, NULL, "/dev/sda1", &aux_fdcwd, EINVAL}, ... > + {"set-path-aux", &fd, FSCONFIG_SET_PATH, "sync", "/dev/sda1", &aux_minus1, EINVAL}, /dev/sda1 is valid on some hosts, but invalid on others. Shouldn't we use /dev/foo instead? ... > + temp_fd = open("testfile", O_RDWR | O_CREAT, 01444); > + if (temp_fd == -1) > + tst_res(TBROK, "Can't obtain temp_fd, open() failed"); Here needs to be now tst_brk(TBROK). Again I'll change it before merge. ... Kind regards, Petr [1] https://marc.info/?l=linux-man&m=158109737907972&w=2 [2] https://patchwork.kernel.org/patch/10820207/ [3] https://patchwork.kernel.org/project/linux-security-module/list/?series=82377
On 28-02-20, 17:01, Petr Vorel wrote: > > + TEST(fsmfd = fsmount(fd, 0, 0)); > > + if (fsmfd == -1) { > > + tst_res(TBROK | TERRNO, "fsmount() failed"); > > + goto out; > BTW This needs to be now tst_res(TFAIL) (this patchset now does not compile). For a minute I thought I failed with my testing :( And then I looked at the recent changes and looks like compilation broke due to the changes you have pushed recently. Right ? > > + TEST(fsconfig(fd, FSCONFIG_SET_FD, "sync", NULL, 0)); > > + if (TST_RET == -1) { > > + if (TST_ERR == EOPNOTSUPP) { > > + tst_res(TCONF, "fsconfig(): FSCONFIG_SET_FD not supported"); > > + } else { > > + tst_res(TFAIL | TERRNO, "fsconfig() failed"); > > + goto out; > > + } > > + } > > I get TCONF for all fsconfig01 results, while I'm using 5.5.5-1-default: s/all/most/ I know, same here. > tst_test.c:1290: INFO: Testing on ext2 > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext2 opts='' extra opts='' > mke2fs 1.45.5 (07-Jan-2020) > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on ext3 > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext3 opts='' extra opts='' > mke2fs 1.45.5 (07-Jan-2020) > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on ext4 > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext4 opts='' extra opts='' > mke2fs 1.45.5 (07-Jan-2020) > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on xfs > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with xfs opts='' extra opts='' > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:92: PASS: fsconfig() passed You didn't get them for xfs :) > tst_test.c:1290: INFO: Testing on btrfs > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with btrfs opts='' extra opts='' > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on vfat > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with vfat opts='' extra opts='' > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > > Not yet merged man page [1] (I reposted David Howells commit) there is > explanation for EOPNOTSUPP: The command given by cmd was not valid. > > First, I suspected "sync" option is wrong. But looking at kernel sources it's > really not implemented: > > fs/fsopen.c > if (fc->ops == &legacy_fs_context_ops) { > switch (cmd) { > case FSCONFIG_SET_BINARY: > case FSCONFIG_SET_PATH: > case FSCONFIG_SET_PATH_EMPTY: > case FSCONFIG_SET_FD: > ret = -EOPNOTSUPP; > goto out_f; > } > } > > fs/fs_context.c > /* TODO: Make all filesystems support this unconditionally */ > init_fs_context = fc->fs_type->init_fs_context; > if (!init_fs_context) > init_fs_context = legacy_init_fs_context; > ... > /* > * Initialise a legacy context for a filesystem that doesn't support > * fs_context. > */ > static int legacy_init_fs_context(struct fs_context *fc) > { > fc->fs_private = kzalloc(sizeof(struct legacy_fs_context), GFP_KERNEL); > if (!fc->fs_private) > return -ENOMEM; > fc->ops = &legacy_fs_context_ops; > return 0; > } Right, I have seen that all earlier and so I knew that the failures here are just fine. > Code coming from v5.1-rc1 f3a09c92018a91ad0981146a4ac59414f814d801 introduce > fs_context methods [2]. Other patchsets here [3] shows there is some support for > fs_context in VFS. So I wonder how to achieve not end up with legacy context. > > > +++ b/testcases/kernel/syscalls/fsconfig/fsconfig02.c > > + {"set-path-key", &fd, FSCONFIG_SET_PATH, NULL, "/dev/sda1", &aux_fdcwd, EINVAL}, > ... > > + {"set-path-aux", &fd, FSCONFIG_SET_PATH, "sync", "/dev/sda1", &aux_minus1, EINVAL}, > /dev/sda1 is valid on some hosts, but invalid on others. Shouldn't we use > /dev/foo instead? Should be fine I think. > ... > > + temp_fd = open("testfile", O_RDWR | O_CREAT, 01444); > > + if (temp_fd == -1) > > + tst_res(TBROK, "Can't obtain temp_fd, open() failed"); > Here needs to be now tst_brk(TBROK). > Again I'll change it before merge. Thanks.
Hi Viresh, > I get TCONF for all fsconfig01 results, while I'm using 5.5.5-1-default: > tst_test.c:1290: INFO: Testing on ext2 > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext2 opts='' extra opts='' > mke2fs 1.45.5 (07-Jan-2020) > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on ext3 > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext3 opts='' extra opts='' > mke2fs 1.45.5 (07-Jan-2020) > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on ext4 > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with ext4 opts='' extra opts='' > mke2fs 1.45.5 (07-Jan-2020) > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on xfs > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with xfs opts='' extra opts='' > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on btrfs > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with btrfs opts='' extra opts='' > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > tst_test.c:1290: INFO: Testing on vfat > tst_mkfs.c:89: INFO: Formatting /dev/loop0 with vfat opts='' extra opts='' > tst_test.c:1227: INFO: Timeout per run is 0h 05m 00s > fsconfig01.c:43: CONF: fsconfig(): FSCONFIG_SET_PATH not supported > fsconfig01.c:53: CONF: fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported > fsconfig01.c:63: CONF: fsconfig(): FSCONFIG_SET_FD not supported > fsconfig01.c:92: PASS: fsconfig() passed > Not yet merged man page [1] (I reposted David Howells commit) there is > explanation for EOPNOTSUPP: The command given by cmd was not valid. > First, I suspected "sync" option is wrong. But looking at kernel sources it's > really not implemented: I'm sorry, I was wrong. I overlooked It's supported, but just by xfs (which is surprising). Kind regards, Petr
diff --git a/runtest/syscalls b/runtest/syscalls index 1f21cc55bf2d..97c0fea2fe57 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -341,6 +341,9 @@ fpathconf01 fpathconf01 fremovexattr01 fremovexattr01 fremovexattr02 fremovexattr02 +fsconfig01 fsconfig01 +fsconfig02 fsconfig02 + fsmount01 fsmount01 fsopen01 fsopen01 diff --git a/testcases/kernel/syscalls/fsconfig/.gitignore b/testcases/kernel/syscalls/fsconfig/.gitignore new file mode 100644 index 000000000000..2bc54b82751b --- /dev/null +++ b/testcases/kernel/syscalls/fsconfig/.gitignore @@ -0,0 +1,2 @@ +/fsconfig01 +/fsconfig02 diff --git a/testcases/kernel/syscalls/fsconfig/Makefile b/testcases/kernel/syscalls/fsconfig/Makefile new file mode 100644 index 000000000000..5ea7d67db123 --- /dev/null +++ b/testcases/kernel/syscalls/fsconfig/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +top_srcdir ?= ../../../.. + +include $(top_srcdir)/include/mk/testcases.mk +include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/fsconfig/fsconfig01.c b/testcases/kernel/syscalls/fsconfig/fsconfig01.c new file mode 100644 index 000000000000..e32b23e9586b --- /dev/null +++ b/testcases/kernel/syscalls/fsconfig/fsconfig01.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org> + * + * Basic fsconfig() test which tries to configure and mount the filesystem as + * well. + */ +#include "tst_test.h" +#include "lapi/fsmount.h" + +#define MNTPOINT "mntpoint" + +static void run(void) +{ + int fd, fsmfd; + + TEST(fd = fsopen(tst_device->fs_type, 0)); + if (fd == -1) + tst_brk(TBROK | TERRNO, "fsopen() failed"); + + TEST(fsconfig(fd, FSCONFIG_SET_FLAG, "rw", NULL, 0)); + if (TST_RET == -1) { + tst_res(TFAIL | TERRNO, "fsconfig() failed"); + goto out; + } + + TEST(fsconfig(fd, FSCONFIG_SET_STRING, "source", tst_device->dev, 0)); + if (TST_RET == -1) { + tst_res(TFAIL | TERRNO, "fsconfig() failed"); + goto out; + } + + TEST(fsconfig(fd, FSCONFIG_SET_PATH, "sync", tst_device->dev, 0)); + if (TST_RET == -1) { + if (TST_ERR == EOPNOTSUPP) { + tst_res(TCONF, "fsconfig(): FSCONFIG_SET_PATH not supported"); + } else { + tst_res(TFAIL | TERRNO, "fsconfig() failed"); + goto out; + } + } + + TEST(fsconfig(fd, FSCONFIG_SET_PATH_EMPTY, "sync", tst_device->dev, 0)); + if (TST_RET == -1) { + if (TST_ERR == EOPNOTSUPP) { + tst_res(TCONF, "fsconfig(): FSCONFIG_SET_PATH_EMPTY not supported"); + } else { + tst_res(TFAIL | TERRNO, "fsconfig() failed"); + goto out; + } + } + + TEST(fsconfig(fd, FSCONFIG_SET_FD, "sync", NULL, 0)); + if (TST_RET == -1) { + if (TST_ERR == EOPNOTSUPP) { + tst_res(TCONF, "fsconfig(): FSCONFIG_SET_FD not supported"); + } else { + tst_res(TFAIL | TERRNO, "fsconfig() failed"); + goto out; + } + } + + TEST(fsconfig(fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0)); + if (TST_RET == -1) { + tst_res(TFAIL | TERRNO, "fsconfig() failed"); + goto out; + } + + TEST(fsmfd = fsmount(fd, 0, 0)); + if (fsmfd == -1) { + tst_res(TBROK | TERRNO, "fsmount() failed"); + goto out; + } + + TEST(move_mount(fsmfd, "", AT_FDCWD, MNTPOINT, + MOVE_MOUNT_F_EMPTY_PATH)); + SAFE_CLOSE(fsmfd); + + if (TST_RET == -1) { + tst_res(TBROK | TERRNO, "move_mount() failed"); + goto out; + } + + if (tst_is_mounted(MNTPOINT)) + tst_res(TPASS, "fsconfig() passed"); + + SAFE_UMOUNT(MNTPOINT); + +out: + SAFE_CLOSE(fd); +} + +static struct tst_test test = { + .test_all = run, + .setup = fsopen_supported_by_kernel, + .needs_root = 1, + .format_device = 1, + .mntpoint = MNTPOINT, + .all_filesystems = 1, + .dev_fs_flags = TST_FS_SKIP_FUSE, +}; diff --git a/testcases/kernel/syscalls/fsconfig/fsconfig02.c b/testcases/kernel/syscalls/fsconfig/fsconfig02.c new file mode 100644 index 000000000000..e6e7b4b9f1de --- /dev/null +++ b/testcases/kernel/syscalls/fsconfig/fsconfig02.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org> + * + * Basic fsconfig() failure tests. + */ +#include "tst_test.h" +#include "lapi/fsmount.h" + +static int fd = -1, temp_fd = -1, invalid_fd = -1; +static int aux_0 = 0, aux_1 = 1, aux_fdcwd = AT_FDCWD, aux_minus1 = -1; + +static struct tcase { + char *name; + int *fd; + unsigned int cmd; + const char *key; + const void *value; + int *aux; + int exp_errno; +} tcases[] = { + {"invalid-fd", &invalid_fd, FSCONFIG_SET_FLAG, "user_xattr", NULL, &aux_0, EINVAL}, + {"invalid-cmd", &fd, 100, "rw", NULL, &aux_0, EOPNOTSUPP}, + {"set-flag-key", &fd, FSCONFIG_SET_FLAG, NULL, NULL, &aux_0, EINVAL}, + {"set-flag-value", &fd, FSCONFIG_SET_FLAG, "rw", "foo", &aux_0, EINVAL}, + {"set-flag-aux", &fd, FSCONFIG_SET_FLAG, "rw", NULL, &aux_1, EINVAL}, + {"set-string-key", &fd, FSCONFIG_SET_STRING, NULL, "#grand.central.org:root.cell.", &aux_0, EINVAL}, + {"set-string-value", &fd, FSCONFIG_SET_STRING, "source", NULL, &aux_0, EINVAL}, + {"set-string-aux", &fd, FSCONFIG_SET_STRING, "source", "#grand.central.org:root.cell.", &aux_1, EINVAL}, + {"set-binary-key", &fd, FSCONFIG_SET_BINARY, NULL, "foo", &aux_1, EINVAL}, + {"set-binary-value", &fd, FSCONFIG_SET_BINARY, "sync", NULL, &aux_1, EINVAL}, + {"set-binary-aux", &fd, FSCONFIG_SET_BINARY, "sync", "foo", &aux_0, EINVAL}, + {"set-path-key", &fd, FSCONFIG_SET_PATH, NULL, "/dev/sda1", &aux_fdcwd, EINVAL}, + {"set-path-value", &fd, FSCONFIG_SET_PATH, "sync", NULL, &aux_fdcwd, EINVAL}, + {"set-path-aux", &fd, FSCONFIG_SET_PATH, "sync", "/dev/sda1", &aux_minus1, EINVAL}, + {"set-path-empty-key", &fd, FSCONFIG_SET_PATH_EMPTY, NULL, "/dev/foo", &aux_fdcwd, EINVAL}, + {"set-path-empty-value", &fd, FSCONFIG_SET_PATH_EMPTY, "sync", NULL, &aux_fdcwd, EINVAL}, + {"set-path-empty-aux", &fd, FSCONFIG_SET_PATH_EMPTY, "sync", "/dev/foo", &aux_minus1, EINVAL}, + {"set-fd-key", &fd, FSCONFIG_SET_FD, NULL, NULL, &temp_fd, EINVAL}, + {"set-fd-value", &fd, FSCONFIG_SET_FD, "sync", "foo", &temp_fd, EINVAL}, + {"set-fd-aux", &fd, FSCONFIG_SET_FD, "sync", NULL, &aux_minus1, EINVAL}, + {"cmd-create-key", &fd, FSCONFIG_CMD_CREATE, "foo", NULL, &aux_0, EINVAL}, + {"cmd-create-value", &fd, FSCONFIG_CMD_CREATE, NULL, "foo", &aux_0, EINVAL}, + {"cmd-create-aux", &fd, FSCONFIG_CMD_CREATE, NULL, NULL, &aux_1, EINVAL}, + {"cmd-reconfigure-key", &fd, FSCONFIG_CMD_RECONFIGURE, "foo", NULL, &aux_0, EINVAL}, + {"cmd-reconfigure-value", &fd, FSCONFIG_CMD_RECONFIGURE, NULL, "foo", &aux_0, EINVAL}, + {"cmd-reconfigure-aux", &fd, FSCONFIG_CMD_RECONFIGURE, NULL, NULL, &aux_1, EINVAL}, +}; + +static void setup(void) +{ + fsopen_supported_by_kernel(); + + TEST(fd = fsopen(tst_device->fs_type, 0)); + if (fd == -1) + tst_brk(TBROK | TERRNO, "fsopen() failed"); + + temp_fd = open("testfile", O_RDWR | O_CREAT, 01444); + if (temp_fd == -1) + tst_res(TBROK, "Can't obtain temp_fd, open() failed"); +} + +static void cleanup(void) +{ + if (temp_fd != -1) + SAFE_CLOSE(temp_fd); + if (fd != -1) + SAFE_CLOSE(fd); +} + +static void run(unsigned int n) +{ + struct tcase *tc = &tcases[n]; + + TEST(fsconfig(*tc->fd, tc->cmd, tc->key, tc->value, *tc->aux)); + + if (TST_RET != -1) { + tst_res(TFAIL, "%s: fsconfig() succeeded unexpectedly (index: %d)", + tc->name, n); + return; + } + + if (tc->exp_errno != TST_ERR) { + tst_res(TFAIL | TTERRNO, "%s: fsconfig() should fail with %s", + tc->name, tst_strerrno(tc->exp_errno)); + return; + } + + tst_res(TPASS | TTERRNO, "%s: fsconfig() failed as expected", tc->name); +} + +static struct tst_test test = { + .tcnt = ARRAY_SIZE(tcases), + .test = run, + .setup = setup, + .cleanup = cleanup, + .needs_root = 1, + .needs_device = 1, +};