diff mbox series

[v3] syscalls/newmount: new test case for new mount API

Message ID 20191209160227.16125-1-zlang@redhat.com
State Changes Requested
Delegated to: Petr Vorel
Headers show
Series [v3] syscalls/newmount: new test case for new mount API | expand

Commit Message

Zorro Lang Dec. 9, 2019, 4:02 p.m. UTC
Linux supports new mount syscalls from 5.2, so add new test cases
to cover these new API. This newmount01 case make sure new API -
fsopen(), fsconfig(), fsmount() and move_mount() can mount a
filesystem, then can be unmounted.

Signed-off-by: Zorro Lang <zlang@redhat.com>
---

Hi,

V3 test passed on ext2/3/4 and xfs[1], on upstream mainline kernel. Thanks
all your review points:)
But I have a question, how to test other filesystems, likes nfs, cifs?

Thanks,
Zorro

 configure.ac                                  |   1 +
 include/lapi/newmount.h                       |  95 +++++++++++++++
 include/lapi/syscalls/aarch64.in              |   4 +
 include/lapi/syscalls/powerpc64.in            |   4 +
 include/lapi/syscalls/s390x.in                |   4 +
 include/lapi/syscalls/x86_64.in               |   4 +
 m4/ltp-newmount.m4                            |  10 ++
 runtest/syscalls                              |   2 +
 testcases/kernel/syscalls/newmount/.gitignore |   1 +
 testcases/kernel/syscalls/newmount/Makefile   |   9 ++
 .../kernel/syscalls/newmount/newmount01.c     | 114 ++++++++++++++++++
 11 files changed, 248 insertions(+)
 create mode 100644 include/lapi/newmount.h
 create mode 100644 m4/ltp-newmount.m4
 create mode 100644 testcases/kernel/syscalls/newmount/.gitignore
 create mode 100644 testcases/kernel/syscalls/newmount/Makefile
 create mode 100644 testcases/kernel/syscalls/newmount/newmount01.c

Comments

Zorro Lang Dec. 26, 2019, 7:23 a.m. UTC | #1
On Tue, Dec 10, 2019 at 12:02:27AM +0800, Zorro Lang wrote:
> Linux supports new mount syscalls from 5.2, so add new test cases
> to cover these new API. This newmount01 case make sure new API -
> fsopen(), fsconfig(), fsmount() and move_mount() can mount a
> filesystem, then can be unmounted.
> 
> Signed-off-by: Zorro Lang <zlang@redhat.com>
> ---
> 
> Hi,
> 
> V3 test passed on ext2/3/4 and xfs[1], on upstream mainline kernel. Thanks
> all your review points:)
> But I have a question, how to test other filesystems, likes nfs, cifs?

Ping.

It's been several weeks passed. Is there more review points?

Thanks,
Zorro

> 
> Thanks,
> Zorro
> 
>  configure.ac                                  |   1 +
>  include/lapi/newmount.h                       |  95 +++++++++++++++
>  include/lapi/syscalls/aarch64.in              |   4 +
>  include/lapi/syscalls/powerpc64.in            |   4 +
>  include/lapi/syscalls/s390x.in                |   4 +
>  include/lapi/syscalls/x86_64.in               |   4 +
>  m4/ltp-newmount.m4                            |  10 ++
>  runtest/syscalls                              |   2 +
>  testcases/kernel/syscalls/newmount/.gitignore |   1 +
>  testcases/kernel/syscalls/newmount/Makefile   |   9 ++
>  .../kernel/syscalls/newmount/newmount01.c     | 114 ++++++++++++++++++
>  11 files changed, 248 insertions(+)
>  create mode 100644 include/lapi/newmount.h
>  create mode 100644 m4/ltp-newmount.m4
>  create mode 100644 testcases/kernel/syscalls/newmount/.gitignore
>  create mode 100644 testcases/kernel/syscalls/newmount/Makefile
>  create mode 100644 testcases/kernel/syscalls/newmount/newmount01.c
> 
> diff --git a/configure.ac b/configure.ac
> index 50d14967d..28f840c51 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -229,6 +229,7 @@ LTP_CHECK_MADVISE
>  LTP_CHECK_MKDTEMP
>  LTP_CHECK_MMSGHDR
>  LTP_CHECK_MREMAP_FIXED
> +LTP_CHECK_NEWMOUNT
>  LTP_CHECK_NOMMU_LINUX
>  LTP_CHECK_PERF_EVENT
>  LTP_CHECK_PRCTL_SUPPORT
> diff --git a/include/lapi/newmount.h b/include/lapi/newmount.h
> new file mode 100644
> index 000000000..13f9fbb9c
> --- /dev/null
> +++ b/include/lapi/newmount.h
> @@ -0,0 +1,95 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
> + * Author: Zorro Lang <zlang@redhat.com>
> + */
> +
> +#ifndef NEWMOUNT_H__
> +#define NEWMOUNT_H__
> +
> +#include <stdint.h>
> +#include <unistd.h>
> +#include "config.h"
> +#include "lapi/syscalls.h"
> +
> +#if !defined(HAVE_FSOPEN)
> +static inline int fsopen(const char *fs_name, unsigned int flags)
> +{
> +	return tst_syscall(__NR_fsopen, fs_name, flags);
> +}
> +
> +/*
> + * fsopen() flags.
> + */
> +#define FSOPEN_CLOEXEC		0x00000001
> +#endif	/* HAVE_FSOPEN */
> +
> +#if !defined(HAVE_FSCONFIG)
> +static inline int fsconfig(int fsfd, unsigned int cmd,
> +                           const char *key, const void *val, int aux)
> +{
> +	return tst_syscall(__NR_fsconfig, fsfd, cmd, key, val, aux);
> +}
> +
> +/*
> + * The type of fsconfig() call made.
> + */
> +enum fsconfig_command {
> +	FSCONFIG_SET_FLAG	= 0,    /* Set parameter, supplying no value */
> +	FSCONFIG_SET_STRING	= 1,    /* Set parameter, supplying a string value */
> +	FSCONFIG_SET_BINARY	= 2,    /* Set parameter, supplying a binary blob value */
> +	FSCONFIG_SET_PATH	= 3,    /* Set parameter, supplying an object by path */
> +	FSCONFIG_SET_PATH_EMPTY	= 4,    /* Set parameter, supplying an object by (empty) path */
> +	FSCONFIG_SET_FD		= 5,    /* Set parameter, supplying an object by fd */
> +	FSCONFIG_CMD_CREATE	= 6,    /* Invoke superblock creation */
> +	FSCONFIG_CMD_RECONFIGURE = 7,   /* Invoke superblock reconfiguration */
> +};
> +#endif	/* HAVE_FSCONFIG */
> +
> +#if !defined(HAVE_FSMOUNT)
> +static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
> +{
> +	return tst_syscall(__NR_fsmount, fsfd, flags, ms_flags);
> +}
> +
> +/*
> + * fsmount() flags.
> + */
> +#define FSMOUNT_CLOEXEC		0x00000001
> +
> +/*
> + * Mount attributes.
> + */
> +#define MOUNT_ATTR_RDONLY	0x00000001 /* Mount read-only */
> +#define MOUNT_ATTR_NOSUID	0x00000002 /* Ignore suid and sgid bits */
> +#define MOUNT_ATTR_NODEV	0x00000004 /* Disallow access to device special files */
> +#define MOUNT_ATTR_NOEXEC	0x00000008 /* Disallow program execution */
> +#define MOUNT_ATTR__ATIME	0x00000070 /* Setting on how atime should be updated */
> +#define MOUNT_ATTR_RELATIME	0x00000000 /* - Update atime relative to mtime/ctime. */
> +#define MOUNT_ATTR_NOATIME	0x00000010 /* - Do not update access times. */
> +#define MOUNT_ATTR_STRICTATIME	0x00000020 /* - Always perform atime updates */
> +#define MOUNT_ATTR_NODIRATIME	0x00000080 /* Do not update directory access times */
> +#endif	/* HAVE_FSMOUNT */
> +
> +#if !defined(HAVE_MOVE_MOUNT)
> +static inline int move_mount(int from_dfd, const char *from_pathname,
> +                             int to_dfd, const char *to_pathname,
> +                             unsigned int flags)
> +{
> +	return tst_syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd,
> +	                   to_pathname, flags);
> +}
> +
> +/*
> + * move_mount() flags.
> + */
> +#define MOVE_MOUNT_F_SYMLINKS		0x00000001 /* Follow symlinks on from path */
> +#define MOVE_MOUNT_F_AUTOMOUNTS		0x00000002 /* Follow automounts on from path */
> +#define MOVE_MOUNT_F_EMPTY_PATH		0x00000004 /* Empty from path permitted */
> +#define MOVE_MOUNT_T_SYMLINKS		0x00000010 /* Follow symlinks on to path */
> +#define MOVE_MOUNT_T_AUTOMOUNTS		0x00000020 /* Follow automounts on to path */
> +#define MOVE_MOUNT_T_EMPTY_PATH		0x00000040 /* Empty to path permitted */
> +#define MOVE_MOUNT__MASK		0x00000077
> +#endif	/* HAVE_MOVE_MOUNT */
> +
> +#endif /* NEWMOUNT_H__ */
> diff --git a/include/lapi/syscalls/aarch64.in b/include/lapi/syscalls/aarch64.in
> index 0e00641bc..5b9e1d9a4 100644
> --- a/include/lapi/syscalls/aarch64.in
> +++ b/include/lapi/syscalls/aarch64.in
> @@ -270,4 +270,8 @@ pkey_mprotect 288
>  pkey_alloc 289
>  pkey_free 290
>  pidfd_send_signal 424
> +move_mount 429
> +fsopen 430
> +fsconfig 431
> +fsmount 432
>  _sysctl 1078
> diff --git a/include/lapi/syscalls/powerpc64.in b/include/lapi/syscalls/powerpc64.in
> index 660165d7a..3aaed64e0 100644
> --- a/include/lapi/syscalls/powerpc64.in
> +++ b/include/lapi/syscalls/powerpc64.in
> @@ -359,3 +359,7 @@ pidfd_send_signal 424
>  pkey_mprotect 386
>  pkey_alloc 384
>  pkey_free 385
> +move_mount 429
> +fsopen 430
> +fsconfig 431
> +fsmount 432
> diff --git a/include/lapi/syscalls/s390x.in b/include/lapi/syscalls/s390x.in
> index 7d632d1dc..bd427555a 100644
> --- a/include/lapi/syscalls/s390x.in
> +++ b/include/lapi/syscalls/s390x.in
> @@ -341,3 +341,7 @@ pkey_mprotect 384
>  pkey_alloc 385
>  pkey_free 386
>  pidfd_send_signal 424
> +move_mount 429
> +fsopen 430
> +fsconfig 431
> +fsmount 432
> diff --git a/include/lapi/syscalls/x86_64.in b/include/lapi/syscalls/x86_64.in
> index b1cbd4f2f..94f0b562e 100644
> --- a/include/lapi/syscalls/x86_64.in
> +++ b/include/lapi/syscalls/x86_64.in
> @@ -320,3 +320,7 @@ pkey_alloc 330
>  pkey_free 331
>  statx 332
>  pidfd_send_signal 424
> +move_mount 429
> +fsopen 430
> +fsconfig 431
> +fsmount 432
> diff --git a/m4/ltp-newmount.m4 b/m4/ltp-newmount.m4
> new file mode 100644
> index 000000000..e13a6f0b1
> --- /dev/null
> +++ b/m4/ltp-newmount.m4
> @@ -0,0 +1,10 @@
> +dnl SPDX-License-Identifier: GPL-2.0-or-later
> +dnl Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
> +
> +AC_DEFUN([LTP_CHECK_NEWMOUNT],[
> +AC_CHECK_FUNCS(fsopen,,)
> +AC_CHECK_FUNCS(fsconfig,,)
> +AC_CHECK_FUNCS(fsmount,,)
> +AC_CHECK_FUNCS(move_mount,,)
> +AC_CHECK_HEADER(sys/mount.h,,,)
> +])
> diff --git a/runtest/syscalls b/runtest/syscalls
> index 15dbd9971..fac1c62d2 100644
> --- a/runtest/syscalls
> +++ b/runtest/syscalls
> @@ -794,6 +794,8 @@ nanosleep01 nanosleep01
>  nanosleep02 nanosleep02
>  nanosleep04 nanosleep04
>  
> +newmount01 newmount01
> +
>  nftw01 nftw01
>  nftw6401 nftw6401
>  
> diff --git a/testcases/kernel/syscalls/newmount/.gitignore b/testcases/kernel/syscalls/newmount/.gitignore
> new file mode 100644
> index 000000000..dc78edd5b
> --- /dev/null
> +++ b/testcases/kernel/syscalls/newmount/.gitignore
> @@ -0,0 +1 @@
> +/newmount01
> diff --git a/testcases/kernel/syscalls/newmount/Makefile b/testcases/kernel/syscalls/newmount/Makefile
> new file mode 100644
> index 000000000..7d0920df6
> --- /dev/null
> +++ b/testcases/kernel/syscalls/newmount/Makefile
> @@ -0,0 +1,9 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +#
> +# Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
> +
> +top_srcdir		?= ../../../..
> +
> +include $(top_srcdir)/include/mk/testcases.mk
> +
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/syscalls/newmount/newmount01.c b/testcases/kernel/syscalls/newmount/newmount01.c
> new file mode 100644
> index 000000000..464ecb699
> --- /dev/null
> +++ b/testcases/kernel/syscalls/newmount/newmount01.c
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
> + * Author: Zorro Lang <zlang@redhat.com>
> + *
> + * Use new mount API (fsopen, fsconfig, fsmount, move_mount) to mount
> + * a filesystem without any specified mount options.
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <sys/mount.h>
> +
> +#include "tst_test.h"
> +#include "tst_safe_macros.h"
> +#include "lapi/newmount.h"
> +
> +#define LINELENGTH 256
> +#define MNTPOINT "newmount_point"
> +static int sfd, mfd;
> +static int is_mounted = 0;
> +
> +static int ismount(char *mntpoint)
> +{
> +	int ret = 0;
> +	FILE *file;
> +	char line[LINELENGTH];
> +
> +	file = fopen("/proc/mounts", "r");
> +	if (file == NULL)
> +		tst_brk(TFAIL | TTERRNO, "Open /proc/mounts failed");
> +
> +	while (fgets(line, LINELENGTH, file) != NULL) {
> +		if (strstr(line, mntpoint) != NULL) {
> +			ret = 1;
> +			break;
> +		}
> +	}
> +	fclose(file);
> +	return ret;
> +}
> +
> +static void cleanup(void)
> +{
> +	if (is_mounted) {
> +		TEST(tst_umount(MNTPOINT));
> +		if (TST_RET != 0)
> +			tst_brk(TFAIL | TTERRNO, "umount failed in cleanup");
> +	}
> +}
> +
> +static void test_newmount(void)
> +{
> +	TEST(fsopen(tst_device->fs_type, FSOPEN_CLOEXEC));
> +	if (TST_RET < 0) {
> +		tst_brk(TFAIL | TTERRNO,
> +		        "fsopen %s", tst_device->fs_type);
> +	}
> +	sfd = TST_RET;
> +	tst_res(TPASS, "fsopen %s", tst_device->fs_type);
> +
> +	TEST(fsconfig(sfd, FSCONFIG_SET_STRING, "source", tst_device->dev, 0));
> +	if (TST_RET < 0) {
> +		tst_brk(TFAIL | TTERRNO,
> +		        "fsconfig set source to %s", tst_device->dev);
> +	}
> +	tst_res(TPASS, "fsconfig set source to %s", tst_device->dev);
> +
> +
> +	TEST(fsconfig(sfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0));
> +	if (TST_RET < 0) {
> +		tst_brk(TFAIL | TTERRNO,
> +		        "fsconfig create superblock");
> +	}
> +	tst_res(TPASS, "fsconfig create superblock");
> +
> +	TEST(fsmount(sfd, FSMOUNT_CLOEXEC, 0));
> +	if (TST_RET < 0) {
> +		tst_brk(TFAIL | TTERRNO, "fsmount");
> +	}
> +	mfd = TST_RET;
> +	tst_res(TPASS, "fsmount");
> +	SAFE_CLOSE(sfd);
> +
> +	TEST(move_mount(mfd, "", AT_FDCWD, MNTPOINT, MOVE_MOUNT_F_EMPTY_PATH));
> +	if (TST_RET < 0) {
> +		tst_brk(TFAIL | TTERRNO, "move_mount attach to mount point");
> +	}
> +	is_mounted = 1;
> +	tst_res(TPASS, "move_mount attach to mount point");
> +	SAFE_CLOSE(mfd);
> +
> +	if (ismount(MNTPOINT)) {
> +		tst_res(TPASS, "new mount works");
> +		TEST(tst_umount(MNTPOINT));
> +		if (TST_RET != 0)
> +			tst_brk(TFAIL | TTERRNO, "umount failed");
> +		is_mounted = 0;
> +	} else {
> +		tst_res(TFAIL, "new mount fails");
> +	}
> +}
> +
> +static struct tst_test test = {
> +	.test_all	= test_newmount,
> +	.cleanup	= cleanup,
> +	.needs_root	= 1,
> +	.mntpoint	= MNTPOINT,
> +	.needs_device	= 1,
> +	.format_device	= 1,
> +	.all_filesystems = 1,
> +};
> -- 
> 2.20.1
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
Petr Vorel Jan. 3, 2020, 3:34 p.m. UTC | #2
Hi Zorro,

> > V3 test passed on ext2/3/4 and xfs[1], on upstream mainline kernel. Thanks
> > all your review points:)
> > But I have a question, how to test other filesystems, likes nfs, cifs?

> Ping.

> It's been several weeks passed. Is there more review points?
Sorry for a delay, that's how it works in open source projects (we're also
just contributors).
But you could speed up the review yourself, if you have carefully read reviews
and address suggestions :).

I like you use .all_filesystems = 1 as I suggested in [1], but I warned that it
breaks nfs.
newmount01.c:58: FAIL: fsopen ntfs: ENODEV (19)

Fortunately this does not need any patch for filtering nfs as TST_FS_SKIP_FUSE
is enough for it - add this to struct tst_test:
.dev_fs_flags = TST_FS_SKIP_FUSE

Not sure if just fsopen() is affected, but it probably does not make sense to test
just fsopen() and fsconfig().

There are some issues Xu found in v2 [2], which you didn't address:

> > +AC_DEFUN([LTP_CHECK_NEWMOUNT],[
> > +AC_CHECK_FUNCS(fsopen,,)
> > +AC_CHECK_FUNCS(fsconfig,,)
> > +AC_CHECK_FUNCS(fsmount,,)
> > +AC_CHECK_FUNCS(move_mount,,)
> > +AC_CHECK_HEADER(sys/mount.h,,,)
> > +])
> You use m4 to check them. But it seems that you don't use those macros
> in your cases.
> + I told you in v1 to move AC_CHECK_FUNCS and AC_CHECK_HEADER into configure.ac
> (there is sorted list you add things you need), we use m4/ltp-*.m4 files only
> for complex checks.
> 
> > +#include "tst_safe_macros.h"
> "tst_test.h" has included "tst_safe_macros.h"
=> simply just remove it.

> > +static int sfd, mfd;
> > +static int is_mounted = 0;
> static int sfd, mfd, is_mounted;
(static is always 0).

There are also Cyril's suggestions and objections [3]:

> > +static void setup(void)
> > +{
> > +	SAFE_MKFS(tst_device->dev, tst_device->fs_type, NULL, NULL);
>
> Why aren't we just setting .format_device in the test structure?

> > +static void cleanup(void)
> > +{
> > +	if (mount_flag == 1) {
> > +		TEST(tst_umount(MNTPOINT));
> > +		if (TST_RET != 0)
> > +			tst_brk(TBROK | TTERRNO, "umount failed");
>
> The library already produces TWARN if we fail to umount the device, so I
> would say that there is no need to TBROK here, the TBROK will be
> converted to TWARN anyways since it's in the cleanup...

He also noted, that umount must be done in test:
> > +	SAFE_CLOSE(mfd);
> We have to umount the device here, otherwise it would be mounted for
> each test iteration with -i.

Another reason for tst_umount() in test is for me that it looks a bit strange
for me to perform testing in cleanup function.

+ his objections against else blocks and struct test_cases (I fully agree with it).

[1] https://lists.linux.it/pipermail/ltp/2019-November/014619.html
[2] https://lists.linux.it/pipermail/ltp/2019-December/014702.html
[3] https://lists.linux.it/pipermail/ltp/2019-December/014654.html

Kind regards,
Petr
Cyril Hrubis Jan. 6, 2020, 3:55 p.m. UTC | #3
Hi!
> Ping.
> 
> It's been several weeks passed. Is there more review points?

Just FYI, most of the Europe takes time off starting at mid-December up
until New Year due to Christmass and since most of the LTP patch
reviewers are located in Europe there is very little review done during
that period. As for LTP we are going to produce release soon as well, so
I can't promise I can have a look this or even the next week. Please be
patient.
Zorro Lang Jan. 13, 2020, 3:31 p.m. UTC | #4
On Thu, Dec 26, 2019 at 03:23:38PM +0800, Zorro Lang wrote:
> On Tue, Dec 10, 2019 at 12:02:27AM +0800, Zorro Lang wrote:
> > Linux supports new mount syscalls from 5.2, so add new test cases
> > to cover these new API. This newmount01 case make sure new API -
> > fsopen(), fsconfig(), fsmount() and move_mount() can mount a
> > filesystem, then can be unmounted.
> > 
> > Signed-off-by: Zorro Lang <zlang@redhat.com>
> > ---
> > 
> > Hi,
> > 
> > V3 test passed on ext2/3/4 and xfs[1], on upstream mainline kernel. Thanks
> > all your review points:)
> > But I have a question, how to test other filesystems, likes nfs, cifs?
> 
> Ping.
> 
> It's been several weeks passed. Is there more review points?

ping again ... is there anything block this patch review?

Thanks,
Zorro

> 
> Thanks,
> Zorro
> 
> > 
> > Thanks,
> > Zorro
> > 
> >  configure.ac                                  |   1 +
> >  include/lapi/newmount.h                       |  95 +++++++++++++++
> >  include/lapi/syscalls/aarch64.in              |   4 +
> >  include/lapi/syscalls/powerpc64.in            |   4 +
> >  include/lapi/syscalls/s390x.in                |   4 +
> >  include/lapi/syscalls/x86_64.in               |   4 +
> >  m4/ltp-newmount.m4                            |  10 ++
> >  runtest/syscalls                              |   2 +
> >  testcases/kernel/syscalls/newmount/.gitignore |   1 +
> >  testcases/kernel/syscalls/newmount/Makefile   |   9 ++
> >  .../kernel/syscalls/newmount/newmount01.c     | 114 ++++++++++++++++++
> >  11 files changed, 248 insertions(+)
> >  create mode 100644 include/lapi/newmount.h
> >  create mode 100644 m4/ltp-newmount.m4
> >  create mode 100644 testcases/kernel/syscalls/newmount/.gitignore
> >  create mode 100644 testcases/kernel/syscalls/newmount/Makefile
> >  create mode 100644 testcases/kernel/syscalls/newmount/newmount01.c
> > 
> > diff --git a/configure.ac b/configure.ac
> > index 50d14967d..28f840c51 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -229,6 +229,7 @@ LTP_CHECK_MADVISE
> >  LTP_CHECK_MKDTEMP
> >  LTP_CHECK_MMSGHDR
> >  LTP_CHECK_MREMAP_FIXED
> > +LTP_CHECK_NEWMOUNT
> >  LTP_CHECK_NOMMU_LINUX
> >  LTP_CHECK_PERF_EVENT
> >  LTP_CHECK_PRCTL_SUPPORT
> > diff --git a/include/lapi/newmount.h b/include/lapi/newmount.h
> > new file mode 100644
> > index 000000000..13f9fbb9c
> > --- /dev/null
> > +++ b/include/lapi/newmount.h
> > @@ -0,0 +1,95 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
> > + * Author: Zorro Lang <zlang@redhat.com>
> > + */
> > +
> > +#ifndef NEWMOUNT_H__
> > +#define NEWMOUNT_H__
> > +
> > +#include <stdint.h>
> > +#include <unistd.h>
> > +#include "config.h"
> > +#include "lapi/syscalls.h"
> > +
> > +#if !defined(HAVE_FSOPEN)
> > +static inline int fsopen(const char *fs_name, unsigned int flags)
> > +{
> > +	return tst_syscall(__NR_fsopen, fs_name, flags);
> > +}
> > +
> > +/*
> > + * fsopen() flags.
> > + */
> > +#define FSOPEN_CLOEXEC		0x00000001
> > +#endif	/* HAVE_FSOPEN */
> > +
> > +#if !defined(HAVE_FSCONFIG)
> > +static inline int fsconfig(int fsfd, unsigned int cmd,
> > +                           const char *key, const void *val, int aux)
> > +{
> > +	return tst_syscall(__NR_fsconfig, fsfd, cmd, key, val, aux);
> > +}
> > +
> > +/*
> > + * The type of fsconfig() call made.
> > + */
> > +enum fsconfig_command {
> > +	FSCONFIG_SET_FLAG	= 0,    /* Set parameter, supplying no value */
> > +	FSCONFIG_SET_STRING	= 1,    /* Set parameter, supplying a string value */
> > +	FSCONFIG_SET_BINARY	= 2,    /* Set parameter, supplying a binary blob value */
> > +	FSCONFIG_SET_PATH	= 3,    /* Set parameter, supplying an object by path */
> > +	FSCONFIG_SET_PATH_EMPTY	= 4,    /* Set parameter, supplying an object by (empty) path */
> > +	FSCONFIG_SET_FD		= 5,    /* Set parameter, supplying an object by fd */
> > +	FSCONFIG_CMD_CREATE	= 6,    /* Invoke superblock creation */
> > +	FSCONFIG_CMD_RECONFIGURE = 7,   /* Invoke superblock reconfiguration */
> > +};
> > +#endif	/* HAVE_FSCONFIG */
> > +
> > +#if !defined(HAVE_FSMOUNT)
> > +static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
> > +{
> > +	return tst_syscall(__NR_fsmount, fsfd, flags, ms_flags);
> > +}
> > +
> > +/*
> > + * fsmount() flags.
> > + */
> > +#define FSMOUNT_CLOEXEC		0x00000001
> > +
> > +/*
> > + * Mount attributes.
> > + */
> > +#define MOUNT_ATTR_RDONLY	0x00000001 /* Mount read-only */
> > +#define MOUNT_ATTR_NOSUID	0x00000002 /* Ignore suid and sgid bits */
> > +#define MOUNT_ATTR_NODEV	0x00000004 /* Disallow access to device special files */
> > +#define MOUNT_ATTR_NOEXEC	0x00000008 /* Disallow program execution */
> > +#define MOUNT_ATTR__ATIME	0x00000070 /* Setting on how atime should be updated */
> > +#define MOUNT_ATTR_RELATIME	0x00000000 /* - Update atime relative to mtime/ctime. */
> > +#define MOUNT_ATTR_NOATIME	0x00000010 /* - Do not update access times. */
> > +#define MOUNT_ATTR_STRICTATIME	0x00000020 /* - Always perform atime updates */
> > +#define MOUNT_ATTR_NODIRATIME	0x00000080 /* Do not update directory access times */
> > +#endif	/* HAVE_FSMOUNT */
> > +
> > +#if !defined(HAVE_MOVE_MOUNT)
> > +static inline int move_mount(int from_dfd, const char *from_pathname,
> > +                             int to_dfd, const char *to_pathname,
> > +                             unsigned int flags)
> > +{
> > +	return tst_syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd,
> > +	                   to_pathname, flags);
> > +}
> > +
> > +/*
> > + * move_mount() flags.
> > + */
> > +#define MOVE_MOUNT_F_SYMLINKS		0x00000001 /* Follow symlinks on from path */
> > +#define MOVE_MOUNT_F_AUTOMOUNTS		0x00000002 /* Follow automounts on from path */
> > +#define MOVE_MOUNT_F_EMPTY_PATH		0x00000004 /* Empty from path permitted */
> > +#define MOVE_MOUNT_T_SYMLINKS		0x00000010 /* Follow symlinks on to path */
> > +#define MOVE_MOUNT_T_AUTOMOUNTS		0x00000020 /* Follow automounts on to path */
> > +#define MOVE_MOUNT_T_EMPTY_PATH		0x00000040 /* Empty to path permitted */
> > +#define MOVE_MOUNT__MASK		0x00000077
> > +#endif	/* HAVE_MOVE_MOUNT */
> > +
> > +#endif /* NEWMOUNT_H__ */
> > diff --git a/include/lapi/syscalls/aarch64.in b/include/lapi/syscalls/aarch64.in
> > index 0e00641bc..5b9e1d9a4 100644
> > --- a/include/lapi/syscalls/aarch64.in
> > +++ b/include/lapi/syscalls/aarch64.in
> > @@ -270,4 +270,8 @@ pkey_mprotect 288
> >  pkey_alloc 289
> >  pkey_free 290
> >  pidfd_send_signal 424
> > +move_mount 429
> > +fsopen 430
> > +fsconfig 431
> > +fsmount 432
> >  _sysctl 1078
> > diff --git a/include/lapi/syscalls/powerpc64.in b/include/lapi/syscalls/powerpc64.in
> > index 660165d7a..3aaed64e0 100644
> > --- a/include/lapi/syscalls/powerpc64.in
> > +++ b/include/lapi/syscalls/powerpc64.in
> > @@ -359,3 +359,7 @@ pidfd_send_signal 424
> >  pkey_mprotect 386
> >  pkey_alloc 384
> >  pkey_free 385
> > +move_mount 429
> > +fsopen 430
> > +fsconfig 431
> > +fsmount 432
> > diff --git a/include/lapi/syscalls/s390x.in b/include/lapi/syscalls/s390x.in
> > index 7d632d1dc..bd427555a 100644
> > --- a/include/lapi/syscalls/s390x.in
> > +++ b/include/lapi/syscalls/s390x.in
> > @@ -341,3 +341,7 @@ pkey_mprotect 384
> >  pkey_alloc 385
> >  pkey_free 386
> >  pidfd_send_signal 424
> > +move_mount 429
> > +fsopen 430
> > +fsconfig 431
> > +fsmount 432
> > diff --git a/include/lapi/syscalls/x86_64.in b/include/lapi/syscalls/x86_64.in
> > index b1cbd4f2f..94f0b562e 100644
> > --- a/include/lapi/syscalls/x86_64.in
> > +++ b/include/lapi/syscalls/x86_64.in
> > @@ -320,3 +320,7 @@ pkey_alloc 330
> >  pkey_free 331
> >  statx 332
> >  pidfd_send_signal 424
> > +move_mount 429
> > +fsopen 430
> > +fsconfig 431
> > +fsmount 432
> > diff --git a/m4/ltp-newmount.m4 b/m4/ltp-newmount.m4
> > new file mode 100644
> > index 000000000..e13a6f0b1
> > --- /dev/null
> > +++ b/m4/ltp-newmount.m4
> > @@ -0,0 +1,10 @@
> > +dnl SPDX-License-Identifier: GPL-2.0-or-later
> > +dnl Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
> > +
> > +AC_DEFUN([LTP_CHECK_NEWMOUNT],[
> > +AC_CHECK_FUNCS(fsopen,,)
> > +AC_CHECK_FUNCS(fsconfig,,)
> > +AC_CHECK_FUNCS(fsmount,,)
> > +AC_CHECK_FUNCS(move_mount,,)
> > +AC_CHECK_HEADER(sys/mount.h,,,)
> > +])
> > diff --git a/runtest/syscalls b/runtest/syscalls
> > index 15dbd9971..fac1c62d2 100644
> > --- a/runtest/syscalls
> > +++ b/runtest/syscalls
> > @@ -794,6 +794,8 @@ nanosleep01 nanosleep01
> >  nanosleep02 nanosleep02
> >  nanosleep04 nanosleep04
> >  
> > +newmount01 newmount01
> > +
> >  nftw01 nftw01
> >  nftw6401 nftw6401
> >  
> > diff --git a/testcases/kernel/syscalls/newmount/.gitignore b/testcases/kernel/syscalls/newmount/.gitignore
> > new file mode 100644
> > index 000000000..dc78edd5b
> > --- /dev/null
> > +++ b/testcases/kernel/syscalls/newmount/.gitignore
> > @@ -0,0 +1 @@
> > +/newmount01
> > diff --git a/testcases/kernel/syscalls/newmount/Makefile b/testcases/kernel/syscalls/newmount/Makefile
> > new file mode 100644
> > index 000000000..7d0920df6
> > --- /dev/null
> > +++ b/testcases/kernel/syscalls/newmount/Makefile
> > @@ -0,0 +1,9 @@
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +#
> > +# Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
> > +
> > +top_srcdir		?= ../../../..
> > +
> > +include $(top_srcdir)/include/mk/testcases.mk
> > +
> > +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> > diff --git a/testcases/kernel/syscalls/newmount/newmount01.c b/testcases/kernel/syscalls/newmount/newmount01.c
> > new file mode 100644
> > index 000000000..464ecb699
> > --- /dev/null
> > +++ b/testcases/kernel/syscalls/newmount/newmount01.c
> > @@ -0,0 +1,114 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
> > + * Author: Zorro Lang <zlang@redhat.com>
> > + *
> > + * Use new mount API (fsopen, fsconfig, fsmount, move_mount) to mount
> > + * a filesystem without any specified mount options.
> > + */
> > +
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <unistd.h>
> > +#include <errno.h>
> > +#include <sys/mount.h>
> > +
> > +#include "tst_test.h"
> > +#include "tst_safe_macros.h"
> > +#include "lapi/newmount.h"
> > +
> > +#define LINELENGTH 256
> > +#define MNTPOINT "newmount_point"
> > +static int sfd, mfd;
> > +static int is_mounted = 0;
> > +
> > +static int ismount(char *mntpoint)
> > +{
> > +	int ret = 0;
> > +	FILE *file;
> > +	char line[LINELENGTH];
> > +
> > +	file = fopen("/proc/mounts", "r");
> > +	if (file == NULL)
> > +		tst_brk(TFAIL | TTERRNO, "Open /proc/mounts failed");
> > +
> > +	while (fgets(line, LINELENGTH, file) != NULL) {
> > +		if (strstr(line, mntpoint) != NULL) {
> > +			ret = 1;
> > +			break;
> > +		}
> > +	}
> > +	fclose(file);
> > +	return ret;
> > +}
> > +
> > +static void cleanup(void)
> > +{
> > +	if (is_mounted) {
> > +		TEST(tst_umount(MNTPOINT));
> > +		if (TST_RET != 0)
> > +			tst_brk(TFAIL | TTERRNO, "umount failed in cleanup");
> > +	}
> > +}
> > +
> > +static void test_newmount(void)
> > +{
> > +	TEST(fsopen(tst_device->fs_type, FSOPEN_CLOEXEC));
> > +	if (TST_RET < 0) {
> > +		tst_brk(TFAIL | TTERRNO,
> > +		        "fsopen %s", tst_device->fs_type);
> > +	}
> > +	sfd = TST_RET;
> > +	tst_res(TPASS, "fsopen %s", tst_device->fs_type);
> > +
> > +	TEST(fsconfig(sfd, FSCONFIG_SET_STRING, "source", tst_device->dev, 0));
> > +	if (TST_RET < 0) {
> > +		tst_brk(TFAIL | TTERRNO,
> > +		        "fsconfig set source to %s", tst_device->dev);
> > +	}
> > +	tst_res(TPASS, "fsconfig set source to %s", tst_device->dev);
> > +
> > +
> > +	TEST(fsconfig(sfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0));
> > +	if (TST_RET < 0) {
> > +		tst_brk(TFAIL | TTERRNO,
> > +		        "fsconfig create superblock");
> > +	}
> > +	tst_res(TPASS, "fsconfig create superblock");
> > +
> > +	TEST(fsmount(sfd, FSMOUNT_CLOEXEC, 0));
> > +	if (TST_RET < 0) {
> > +		tst_brk(TFAIL | TTERRNO, "fsmount");
> > +	}
> > +	mfd = TST_RET;
> > +	tst_res(TPASS, "fsmount");
> > +	SAFE_CLOSE(sfd);
> > +
> > +	TEST(move_mount(mfd, "", AT_FDCWD, MNTPOINT, MOVE_MOUNT_F_EMPTY_PATH));
> > +	if (TST_RET < 0) {
> > +		tst_brk(TFAIL | TTERRNO, "move_mount attach to mount point");
> > +	}
> > +	is_mounted = 1;
> > +	tst_res(TPASS, "move_mount attach to mount point");
> > +	SAFE_CLOSE(mfd);
> > +
> > +	if (ismount(MNTPOINT)) {
> > +		tst_res(TPASS, "new mount works");
> > +		TEST(tst_umount(MNTPOINT));
> > +		if (TST_RET != 0)
> > +			tst_brk(TFAIL | TTERRNO, "umount failed");
> > +		is_mounted = 0;
> > +	} else {
> > +		tst_res(TFAIL, "new mount fails");
> > +	}
> > +}
> > +
> > +static struct tst_test test = {
> > +	.test_all	= test_newmount,
> > +	.cleanup	= cleanup,
> > +	.needs_root	= 1,
> > +	.mntpoint	= MNTPOINT,
> > +	.needs_device	= 1,
> > +	.format_device	= 1,
> > +	.all_filesystems = 1,
> > +};
> > -- 
> > 2.20.1
> > 
> > 
> > -- 
> > Mailing list info: https://lists.linux.it/listinfo/ltp
> > 
>
Petr Vorel Jan. 14, 2020, 8 a.m. UTC | #5
Hi Zorro,

> > Ping.

> > It's been several weeks passed. Is there more review points?

> ping again ... is there anything block this patch review?
Yes, preparing a release and generally lack of time (we don't work on LTP full
time). FYI: patch queue [1]. You can help review other patches, so that pile
gets smaller.

Thanks for your patience and your help to LTP.

Kind regards,
Petr

[1] https://patchwork.ozlabs.org/project/ltp/list/
Petr Vorel Jan. 14, 2020, 8:14 a.m. UTC | #6
Hi Zorro,

> > It's been several weeks passed. Is there more review points?

> ping again ... is there anything block this patch review?
Here are my comments to your v3 review [1]. Some of them are now irrelevant
as you're fixed them in v3 (Cyril ones from v1).

So it might be just .dev_fs_flags = TST_FS_SKIP_FUSE and tiny style fixes like
is_mounted = 0. I wanted to fix them myself and merge, but didn't find a time.
Sending v4 where you fix/implement suggestions generally helps speedup merging
(as I already told you) :).

The real question is whether to merge this before release. I'd like it to be in
the release, but it depends on other maintainers opinion.
Cyril, Jan, Li? WDYT?

Kind regards,
Petr

[1] https://patchwork.ozlabs.org/patch/1206389/#2333978
Zorro Lang Jan. 14, 2020, 9:36 a.m. UTC | #7
On Tue, Jan 14, 2020 at 09:14:49AM +0100, Petr Vorel wrote:
> Hi Zorro,
> 
> > > It's been several weeks passed. Is there more review points?
> 
> > ping again ... is there anything block this patch review?
> Here are my comments to your v3 review [1]. Some of them are now irrelevant
> as you're fixed them in v3 (Cyril ones from v1).

Wow, now I know why I didn't get any response for such long time. The emails
from you and Cyril were all sent to mail list, not to/cc me. I didn't pay so
much attention to the mail list. Sorry about that.

> 
> So it might be just .dev_fs_flags = TST_FS_SKIP_FUSE and tiny style fixes like
> is_mounted = 0. I wanted to fix them myself and merge, but didn't find a time.
> Sending v4 where you fix/implement suggestions generally helps speedup merging
> (as I already told you) :).

I'll read your review points, and send a V4 tonight.

Thanks,
Zorro

> 
> The real question is whether to merge this before release. I'd like it to be in
> the release, but it depends on other maintainers opinion.
> Cyril, Jan, Li? WDYT?
> 
> Kind regards,
> Petr
> 
> [1] https://patchwork.ozlabs.org/patch/1206389/#2333978
>
Petr Vorel Jan. 14, 2020, 9:58 a.m. UTC | #8
Hi Zorro,

> > > ping again ... is there anything block this patch review?
> > Here are my comments to your v3 review [1]. Some of them are now irrelevant
> > as you're fixed them in v3 (Cyril ones from v1).

> Wow, now I know why I didn't get any response for such long time. The emails
> from you and Cyril were all sent to mail list, not to/cc me. I didn't pay so
> much attention to the mail list. Sorry about that.
OK good :). I'm sorry to forget to Cc you in some of my replies (I usually pay
attention to Cc people). It's also safer to look at ML or patchwork as this
sometimes happen :).

> > So it might be just .dev_fs_flags = TST_FS_SKIP_FUSE and tiny style fixes like
> > is_mounted = 0. I wanted to fix them myself and merge, but didn't find a time.
> > Sending v4 where you fix/implement suggestions generally helps speedup merging
> > (as I already told you) :).

> I'll read your review points, and send a V4 tonight.
Thanks a lot!

Kind regards,
Petr
Zorro Lang Jan. 15, 2020, 9:01 a.m. UTC | #9
On Tue, Jan 14, 2020 at 10:58:04AM +0100, Petr Vorel wrote:
> Hi Zorro,
> 
> > > > ping again ... is there anything block this patch review?
> > > Here are my comments to your v3 review [1]. Some of them are now irrelevant
> > > as you're fixed them in v3 (Cyril ones from v1).
> 
> > Wow, now I know why I didn't get any response for such long time. The emails
> > from you and Cyril were all sent to mail list, not to/cc me. I didn't pay so
> > much attention to the mail list. Sorry about that.
> OK good :). I'm sorry to forget to Cc you in some of my replies (I usually pay
> attention to Cc people). It's also safer to look at ML or patchwork as this
> sometimes happen :).
> 
> > > So it might be just .dev_fs_flags = TST_FS_SKIP_FUSE and tiny style fixes like

Hi,

About the TST_FS_SKIP_FUSE flag I have below questions:

1) About ntfs and vfat test
You said below content in [1]:

  I like you use .all_filesystems = 1 as I suggested in [1], but I warned that it
  breaks nfs.
  newmount01.c:58: FAIL: fsopen ntfs: ENODEV (19)

  Fortunately this does not need any patch for filtering nfs as TST_FS_SKIP_FUSE
  is enough for it - add this to struct tst_test:
  .dev_fs_flags = TST_FS_SKIP_FUSE

  Not sure if just fsopen() is affected, but it probably does not make sense to test
  just fsopen() and fsconfig().

Actually if you fsopen("ntfs", ...), it doesn't test FUSE. It's testing linux
kernel ntfs:
  # lsmod |grep ntfs
  ntfs                  819200  0

Similar for vfat:
  # lsmod |grep fat
  vfat                   45056  0
  fat                   274432  1 vfat

And from my test on linux 5.5-rc4, the ntfs and vfat can test passed:
  ...
  tst_test.c:1278: INFO: Testing on vfat
  tst_mkfs.c:90: INFO: Formatting /dev/loop0 with vfat opts='' extra opts=''
  tst_test.c:1217: INFO: Timeout per run is 0h 05m 00s
  newmount01.c:62: PASS: fsopen vfat
  newmount01.c:69: PASS: fsconfig set source to /dev/loop0
  newmount01.c:77: PASS: fsconfig create superblock
  newmount01.c:84: PASS: fsmount
  newmount01.c:92: PASS: move_mount attach to mount point
  newmount01.c:96: PASS: new mount works
  tst_test.c:1278: INFO: Testing on ntfs
  tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ntfs opts='' extra opts=''
  The partition start sector was not specified for /dev/loop0 and it could not be obtained automatically.  It has been set to 0.
  The number of sectors per track was not specified for /dev/loop0 and it could not be obtained automatically.  It has been set to 0.
  The number of heads was not specified for /dev/loop0 and it could not be obtained automatically.  It has been set to 0.
  To boot from a device, Windows needs the 'partition start sector', the 'sectors per track' and the 'number of heads' to be set.
  Windows will not be able to boot from this device.
  tst_test.c:1217: INFO: Timeout per run is 0h 05m 00s
  newmount01.c:62: PASS: fsopen ntfs
  newmount01.c:69: PASS: fsconfig set source to /dev/loop0
  newmount01.c:77: PASS: fsconfig create superblock
  newmount01.c:84: PASS: fsmount
  newmount01.c:92: PASS: move_mount attach to mount point
  newmount01.c:96: PASS: new mount works

You hit that error, maybe due to your current kernel didn't build these fs
modules, but your system has mkfs.ntfs* tool.

2) About if this case supports FUSE:

This current code of this case can't do a FUSE mount, due to if we want to mount
a fs through FUSE, we need to do more things, something likes:
  fd = open(/dev/fuse, ...)
  fsfd = fsopen("fuse", ...);
  ...
  fsconfig(fsfd, FSCONFIG_SET_FD, "fd", NULL, fd);
  ...
  (more)
  ...

It's not a simple mount as general localfs mount does. So I didn't do that.
If need, I'd like to write another case to cover that.

3) About the TST_FS_SKIP_FUSE flag:

If you want to skip ntfs and vfat test by set .dev_fs_flags = TST_FS_SKIP_FUSE
for this case. I think it doesn't work. The reason as I said above. Actually
if the current kernel support ntfs and vfat (build them), and we have mkfs.ntfs
and mkfs.vfat tools, then this case can test it.

But if we have the tools, but don't have the kernel support. The case will fail
as you hit.

Thanks,
Zorro


[1] https://patchwork.ozlabs.org/patch/1206389/#2333978

> > > is_mounted = 0. I wanted to fix them myself and merge, but didn't find a time.
> > > Sending v4 where you fix/implement suggestions generally helps speedup merging
> > > (as I already told you) :).
> 
> > I'll read your review points, and send a V4 tonight.
> Thanks a lot!
> 
> Kind regards,
> Petr
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp
>
Petr Vorel Jan. 16, 2020, 11:08 a.m. UTC | #10
Hi Zorro,

> About the TST_FS_SKIP_FUSE flag I have below questions:

> 1) About ntfs and vfat test
> You said below content in [1]:

>   I like you use .all_filesystems = 1 as I suggested in [1], but I warned that it
>   breaks nfs.
>   newmount01.c:58: FAIL: fsopen ntfs: ENODEV (19)

>   Fortunately this does not need any patch for filtering nfs as TST_FS_SKIP_FUSE
>   is enough for it - add this to struct tst_test:
>   .dev_fs_flags = TST_FS_SKIP_FUSE

>   Not sure if just fsopen() is affected, but it probably does not make sense to test
>   just fsopen() and fsconfig().

> Actually if you fsopen("ntfs", ...), it doesn't test FUSE. It's testing linux
> kernel ntfs:
>   # lsmod |grep ntfs
>   ntfs                  819200  0

> Similar for vfat:
>   # lsmod |grep fat
>   vfat                   45056  0
>   fat                   274432  1 vfat

> And from my test on linux 5.5-rc4, the ntfs and vfat can test passed:
>   ...
>   tst_test.c:1278: INFO: Testing on vfat
>   tst_mkfs.c:90: INFO: Formatting /dev/loop0 with vfat opts='' extra opts=''
>   tst_test.c:1217: INFO: Timeout per run is 0h 05m 00s
>   newmount01.c:62: PASS: fsopen vfat
>   newmount01.c:69: PASS: fsconfig set source to /dev/loop0
>   newmount01.c:77: PASS: fsconfig create superblock
>   newmount01.c:84: PASS: fsmount
>   newmount01.c:92: PASS: move_mount attach to mount point
>   newmount01.c:96: PASS: new mount works
>   tst_test.c:1278: INFO: Testing on ntfs
>   tst_mkfs.c:90: INFO: Formatting /dev/loop0 with ntfs opts='' extra opts=''
>   The partition start sector was not specified for /dev/loop0 and it could not be obtained automatically.  It has been set to 0.
>   The number of sectors per track was not specified for /dev/loop0 and it could not be obtained automatically.  It has been set to 0.
>   The number of heads was not specified for /dev/loop0 and it could not be obtained automatically.  It has been set to 0.
>   To boot from a device, Windows needs the 'partition start sector', the 'sectors per track' and the 'number of heads' to be set.
>   Windows will not be able to boot from this device.
>   tst_test.c:1217: INFO: Timeout per run is 0h 05m 00s
>   newmount01.c:62: PASS: fsopen ntfs
>   newmount01.c:69: PASS: fsconfig set source to /dev/loop0
>   newmount01.c:77: PASS: fsconfig create superblock
>   newmount01.c:84: PASS: fsmount
>   newmount01.c:92: PASS: move_mount attach to mount point
>   newmount01.c:96: PASS: new mount works

> You hit that error, maybe due to your current kernel didn't build these fs
> modules, but your system has mkfs.ntfs* tool.
You're right (CONFIG_NTFS_FS not set, but mkfs.ntfs).
Sorry for a wrong suggestion.

The rest I'll reply at v4 of your post.

> 2) About if this case supports FUSE:

> This current code of this case can't do a FUSE mount, due to if we want to mount
> a fs through FUSE, we need to do more things, something likes:
>   fd = open(/dev/fuse, ...)
>   fsfd = fsopen("fuse", ...);
>   ...
>   fsconfig(fsfd, FSCONFIG_SET_FD, "fd", NULL, fd);
>   ...
>   (more)
>   ...

> It's not a simple mount as general localfs mount does. So I didn't do that.
> If need, I'd like to write another case to cover that.

> 3) About the TST_FS_SKIP_FUSE flag:

> If you want to skip ntfs and vfat test by set .dev_fs_flags = TST_FS_SKIP_FUSE
> for this case. I think it doesn't work. The reason as I said above. Actually
> if the current kernel support ntfs and vfat (build them), and we have mkfs.ntfs
> and mkfs.vfat tools, then this case can test it.

> But if we have the tools, but don't have the kernel support. The case will fail
> as you hit.

Kind regards,
Petr
diff mbox series

Patch

diff --git a/configure.ac b/configure.ac
index 50d14967d..28f840c51 100644
--- a/configure.ac
+++ b/configure.ac
@@ -229,6 +229,7 @@  LTP_CHECK_MADVISE
 LTP_CHECK_MKDTEMP
 LTP_CHECK_MMSGHDR
 LTP_CHECK_MREMAP_FIXED
+LTP_CHECK_NEWMOUNT
 LTP_CHECK_NOMMU_LINUX
 LTP_CHECK_PERF_EVENT
 LTP_CHECK_PRCTL_SUPPORT
diff --git a/include/lapi/newmount.h b/include/lapi/newmount.h
new file mode 100644
index 000000000..13f9fbb9c
--- /dev/null
+++ b/include/lapi/newmount.h
@@ -0,0 +1,95 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+ * Author: Zorro Lang <zlang@redhat.com>
+ */
+
+#ifndef NEWMOUNT_H__
+#define NEWMOUNT_H__
+
+#include <stdint.h>
+#include <unistd.h>
+#include "config.h"
+#include "lapi/syscalls.h"
+
+#if !defined(HAVE_FSOPEN)
+static inline int fsopen(const char *fs_name, unsigned int flags)
+{
+	return tst_syscall(__NR_fsopen, fs_name, flags);
+}
+
+/*
+ * fsopen() flags.
+ */
+#define FSOPEN_CLOEXEC		0x00000001
+#endif	/* HAVE_FSOPEN */
+
+#if !defined(HAVE_FSCONFIG)
+static inline int fsconfig(int fsfd, unsigned int cmd,
+                           const char *key, const void *val, int aux)
+{
+	return tst_syscall(__NR_fsconfig, fsfd, cmd, key, val, aux);
+}
+
+/*
+ * The type of fsconfig() call made.
+ */
+enum fsconfig_command {
+	FSCONFIG_SET_FLAG	= 0,    /* Set parameter, supplying no value */
+	FSCONFIG_SET_STRING	= 1,    /* Set parameter, supplying a string value */
+	FSCONFIG_SET_BINARY	= 2,    /* Set parameter, supplying a binary blob value */
+	FSCONFIG_SET_PATH	= 3,    /* Set parameter, supplying an object by path */
+	FSCONFIG_SET_PATH_EMPTY	= 4,    /* Set parameter, supplying an object by (empty) path */
+	FSCONFIG_SET_FD		= 5,    /* Set parameter, supplying an object by fd */
+	FSCONFIG_CMD_CREATE	= 6,    /* Invoke superblock creation */
+	FSCONFIG_CMD_RECONFIGURE = 7,   /* Invoke superblock reconfiguration */
+};
+#endif	/* HAVE_FSCONFIG */
+
+#if !defined(HAVE_FSMOUNT)
+static inline int fsmount(int fsfd, unsigned int flags, unsigned int ms_flags)
+{
+	return tst_syscall(__NR_fsmount, fsfd, flags, ms_flags);
+}
+
+/*
+ * fsmount() flags.
+ */
+#define FSMOUNT_CLOEXEC		0x00000001
+
+/*
+ * Mount attributes.
+ */
+#define MOUNT_ATTR_RDONLY	0x00000001 /* Mount read-only */
+#define MOUNT_ATTR_NOSUID	0x00000002 /* Ignore suid and sgid bits */
+#define MOUNT_ATTR_NODEV	0x00000004 /* Disallow access to device special files */
+#define MOUNT_ATTR_NOEXEC	0x00000008 /* Disallow program execution */
+#define MOUNT_ATTR__ATIME	0x00000070 /* Setting on how atime should be updated */
+#define MOUNT_ATTR_RELATIME	0x00000000 /* - Update atime relative to mtime/ctime. */
+#define MOUNT_ATTR_NOATIME	0x00000010 /* - Do not update access times. */
+#define MOUNT_ATTR_STRICTATIME	0x00000020 /* - Always perform atime updates */
+#define MOUNT_ATTR_NODIRATIME	0x00000080 /* Do not update directory access times */
+#endif	/* HAVE_FSMOUNT */
+
+#if !defined(HAVE_MOVE_MOUNT)
+static inline int move_mount(int from_dfd, const char *from_pathname,
+                             int to_dfd, const char *to_pathname,
+                             unsigned int flags)
+{
+	return tst_syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd,
+	                   to_pathname, flags);
+}
+
+/*
+ * move_mount() flags.
+ */
+#define MOVE_MOUNT_F_SYMLINKS		0x00000001 /* Follow symlinks on from path */
+#define MOVE_MOUNT_F_AUTOMOUNTS		0x00000002 /* Follow automounts on from path */
+#define MOVE_MOUNT_F_EMPTY_PATH		0x00000004 /* Empty from path permitted */
+#define MOVE_MOUNT_T_SYMLINKS		0x00000010 /* Follow symlinks on to path */
+#define MOVE_MOUNT_T_AUTOMOUNTS		0x00000020 /* Follow automounts on to path */
+#define MOVE_MOUNT_T_EMPTY_PATH		0x00000040 /* Empty to path permitted */
+#define MOVE_MOUNT__MASK		0x00000077
+#endif	/* HAVE_MOVE_MOUNT */
+
+#endif /* NEWMOUNT_H__ */
diff --git a/include/lapi/syscalls/aarch64.in b/include/lapi/syscalls/aarch64.in
index 0e00641bc..5b9e1d9a4 100644
--- a/include/lapi/syscalls/aarch64.in
+++ b/include/lapi/syscalls/aarch64.in
@@ -270,4 +270,8 @@  pkey_mprotect 288
 pkey_alloc 289
 pkey_free 290
 pidfd_send_signal 424
+move_mount 429
+fsopen 430
+fsconfig 431
+fsmount 432
 _sysctl 1078
diff --git a/include/lapi/syscalls/powerpc64.in b/include/lapi/syscalls/powerpc64.in
index 660165d7a..3aaed64e0 100644
--- a/include/lapi/syscalls/powerpc64.in
+++ b/include/lapi/syscalls/powerpc64.in
@@ -359,3 +359,7 @@  pidfd_send_signal 424
 pkey_mprotect 386
 pkey_alloc 384
 pkey_free 385
+move_mount 429
+fsopen 430
+fsconfig 431
+fsmount 432
diff --git a/include/lapi/syscalls/s390x.in b/include/lapi/syscalls/s390x.in
index 7d632d1dc..bd427555a 100644
--- a/include/lapi/syscalls/s390x.in
+++ b/include/lapi/syscalls/s390x.in
@@ -341,3 +341,7 @@  pkey_mprotect 384
 pkey_alloc 385
 pkey_free 386
 pidfd_send_signal 424
+move_mount 429
+fsopen 430
+fsconfig 431
+fsmount 432
diff --git a/include/lapi/syscalls/x86_64.in b/include/lapi/syscalls/x86_64.in
index b1cbd4f2f..94f0b562e 100644
--- a/include/lapi/syscalls/x86_64.in
+++ b/include/lapi/syscalls/x86_64.in
@@ -320,3 +320,7 @@  pkey_alloc 330
 pkey_free 331
 statx 332
 pidfd_send_signal 424
+move_mount 429
+fsopen 430
+fsconfig 431
+fsmount 432
diff --git a/m4/ltp-newmount.m4 b/m4/ltp-newmount.m4
new file mode 100644
index 000000000..e13a6f0b1
--- /dev/null
+++ b/m4/ltp-newmount.m4
@@ -0,0 +1,10 @@ 
+dnl SPDX-License-Identifier: GPL-2.0-or-later
+dnl Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
+
+AC_DEFUN([LTP_CHECK_NEWMOUNT],[
+AC_CHECK_FUNCS(fsopen,,)
+AC_CHECK_FUNCS(fsconfig,,)
+AC_CHECK_FUNCS(fsmount,,)
+AC_CHECK_FUNCS(move_mount,,)
+AC_CHECK_HEADER(sys/mount.h,,,)
+])
diff --git a/runtest/syscalls b/runtest/syscalls
index 15dbd9971..fac1c62d2 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -794,6 +794,8 @@  nanosleep01 nanosleep01
 nanosleep02 nanosleep02
 nanosleep04 nanosleep04
 
+newmount01 newmount01
+
 nftw01 nftw01
 nftw6401 nftw6401
 
diff --git a/testcases/kernel/syscalls/newmount/.gitignore b/testcases/kernel/syscalls/newmount/.gitignore
new file mode 100644
index 000000000..dc78edd5b
--- /dev/null
+++ b/testcases/kernel/syscalls/newmount/.gitignore
@@ -0,0 +1 @@ 
+/newmount01
diff --git a/testcases/kernel/syscalls/newmount/Makefile b/testcases/kernel/syscalls/newmount/Makefile
new file mode 100644
index 000000000..7d0920df6
--- /dev/null
+++ b/testcases/kernel/syscalls/newmount/Makefile
@@ -0,0 +1,9 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/newmount/newmount01.c b/testcases/kernel/syscalls/newmount/newmount01.c
new file mode 100644
index 000000000..464ecb699
--- /dev/null
+++ b/testcases/kernel/syscalls/newmount/newmount01.c
@@ -0,0 +1,114 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+ * Author: Zorro Lang <zlang@redhat.com>
+ *
+ * Use new mount API (fsopen, fsconfig, fsmount, move_mount) to mount
+ * a filesystem without any specified mount options.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mount.h>
+
+#include "tst_test.h"
+#include "tst_safe_macros.h"
+#include "lapi/newmount.h"
+
+#define LINELENGTH 256
+#define MNTPOINT "newmount_point"
+static int sfd, mfd;
+static int is_mounted = 0;
+
+static int ismount(char *mntpoint)
+{
+	int ret = 0;
+	FILE *file;
+	char line[LINELENGTH];
+
+	file = fopen("/proc/mounts", "r");
+	if (file == NULL)
+		tst_brk(TFAIL | TTERRNO, "Open /proc/mounts failed");
+
+	while (fgets(line, LINELENGTH, file) != NULL) {
+		if (strstr(line, mntpoint) != NULL) {
+			ret = 1;
+			break;
+		}
+	}
+	fclose(file);
+	return ret;
+}
+
+static void cleanup(void)
+{
+	if (is_mounted) {
+		TEST(tst_umount(MNTPOINT));
+		if (TST_RET != 0)
+			tst_brk(TFAIL | TTERRNO, "umount failed in cleanup");
+	}
+}
+
+static void test_newmount(void)
+{
+	TEST(fsopen(tst_device->fs_type, FSOPEN_CLOEXEC));
+	if (TST_RET < 0) {
+		tst_brk(TFAIL | TTERRNO,
+		        "fsopen %s", tst_device->fs_type);
+	}
+	sfd = TST_RET;
+	tst_res(TPASS, "fsopen %s", tst_device->fs_type);
+
+	TEST(fsconfig(sfd, FSCONFIG_SET_STRING, "source", tst_device->dev, 0));
+	if (TST_RET < 0) {
+		tst_brk(TFAIL | TTERRNO,
+		        "fsconfig set source to %s", tst_device->dev);
+	}
+	tst_res(TPASS, "fsconfig set source to %s", tst_device->dev);
+
+
+	TEST(fsconfig(sfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0));
+	if (TST_RET < 0) {
+		tst_brk(TFAIL | TTERRNO,
+		        "fsconfig create superblock");
+	}
+	tst_res(TPASS, "fsconfig create superblock");
+
+	TEST(fsmount(sfd, FSMOUNT_CLOEXEC, 0));
+	if (TST_RET < 0) {
+		tst_brk(TFAIL | TTERRNO, "fsmount");
+	}
+	mfd = TST_RET;
+	tst_res(TPASS, "fsmount");
+	SAFE_CLOSE(sfd);
+
+	TEST(move_mount(mfd, "", AT_FDCWD, MNTPOINT, MOVE_MOUNT_F_EMPTY_PATH));
+	if (TST_RET < 0) {
+		tst_brk(TFAIL | TTERRNO, "move_mount attach to mount point");
+	}
+	is_mounted = 1;
+	tst_res(TPASS, "move_mount attach to mount point");
+	SAFE_CLOSE(mfd);
+
+	if (ismount(MNTPOINT)) {
+		tst_res(TPASS, "new mount works");
+		TEST(tst_umount(MNTPOINT));
+		if (TST_RET != 0)
+			tst_brk(TFAIL | TTERRNO, "umount failed");
+		is_mounted = 0;
+	} else {
+		tst_res(TFAIL, "new mount fails");
+	}
+}
+
+static struct tst_test test = {
+	.test_all	= test_newmount,
+	.cleanup	= cleanup,
+	.needs_root	= 1,
+	.mntpoint	= MNTPOINT,
+	.needs_device	= 1,
+	.format_device	= 1,
+	.all_filesystems = 1,
+};