Message ID | 1637832900-4753-1-git-send-email-xuyang2018.jy@fujitsu.com |
---|---|
State | Changes Requested |
Headers | show |
Series | syscalls/statx01: Add stx_mnt_id check | expand |
Hi! > +static int file_fd = -1; > + > +#ifdef HAVE_STRUCT_STATX_STX_MNT_ID > +static void test_mnt_id(struct statx *buf) > +{ > + FILE *file; > + char line[PATH_MAX]; > + int pid; > + unsigned int line_mjr, line_mnr, mnt_id; Shouldn't we check the STATX_MNT_ID bit here before we event attempt to continue? Otherwise if we compile the test with headers where stx_mnt_id is defined then run it on old kernel there will be garbage in the stx_mnt_id field. > + file = SAFE_FOPEN("/proc/self/mountinfo", "r"); > + > + while (fgets(line, sizeof(line), file)) { > + if (sscanf(line, "%d %*d %d:%d", &mnt_id, &line_mjr, &line_mnr) != 3) > + continue; > + > + if (line_mjr == buf->stx_dev_major && line_mnr == buf->stx_dev_minor) > + break; > + } > + > + SAFE_FCLOSE(file); > + > + if (buf->stx_mnt_id == mnt_id) > + tst_res(TPASS, > + "statx.stx_mnt_id equals to mount_id(%d) in /proc/self/mountinfo", > + mnt_id); > + else > + tst_res(TFAIL, > + "statx.stx_mnt_id(%d) is different from mount_id(%d) in /proc/self/mountinfo", > + buf->stx_mnt_id, mnt_id); > + > + pid = getpid(); > + snprintf(line, PATH_MAX, "/proc/%d/fdinfo/%d", pid, file_fd); > + TST_ASSERT_FILE_INT(line, "mnt_id:", buf->stx_mnt_id); > +} > +#endif > + > static void test_normal_file(void) > { > struct statx buff; > @@ -106,6 +146,11 @@ static void test_normal_file(void) > tst_res(TFAIL, "stx_nlink(%u) is different from expected(1)", > buff.stx_nlink); > > +#ifdef HAVE_STRUCT_STATX_STX_MNT_ID > + test_mnt_id(&buff); > +#else > + tst_res(TCONF, "stx_mnt_id was not supported until linux 5.8."); This is confusing at best, if we end up here we were missing the structure member during compilation regardless the kernel version. So this message really should be: "stx_mnt_id not defined in struct statx"
Hi Cyril > Hi! >> +static int file_fd = -1; >> + >> +#ifdef HAVE_STRUCT_STATX_STX_MNT_ID >> +static void test_mnt_id(struct statx *buf) >> +{ >> + FILE *file; >> + char line[PATH_MAX]; >> + int pid; >> + unsigned int line_mjr, line_mnr, mnt_id; > > Shouldn't we check the STATX_MNT_ID bit here before we event attempt to > continue? Otherwise if we compile the test with headers where stx_mnt_id > is defined then run it on old kernel there will be garbage in the > stx_mnt_id field. Agree. > >> + file = SAFE_FOPEN("/proc/self/mountinfo", "r"); >> + >> + while (fgets(line, sizeof(line), file)) { >> + if (sscanf(line, "%d %*d %d:%d",&mnt_id,&line_mjr,&line_mnr) != 3) >> + continue; >> + >> + if (line_mjr == buf->stx_dev_major&& line_mnr == buf->stx_dev_minor) >> + break; >> + } >> + >> + SAFE_FCLOSE(file); >> + >> + if (buf->stx_mnt_id == mnt_id) >> + tst_res(TPASS, >> + "statx.stx_mnt_id equals to mount_id(%d) in /proc/self/mountinfo", >> + mnt_id); >> + else >> + tst_res(TFAIL, >> + "statx.stx_mnt_id(%d) is different from mount_id(%d) in /proc/self/mountinfo", >> + buf->stx_mnt_id, mnt_id); >> + >> + pid = getpid(); >> + snprintf(line, PATH_MAX, "/proc/%d/fdinfo/%d", pid, file_fd); >> + TST_ASSERT_FILE_INT(line, "mnt_id:", buf->stx_mnt_id); >> +} >> +#endif >> + >> static void test_normal_file(void) >> { >> struct statx buff; >> @@ -106,6 +146,11 @@ static void test_normal_file(void) >> tst_res(TFAIL, "stx_nlink(%u) is different from expected(1)", >> buff.stx_nlink); >> >> +#ifdef HAVE_STRUCT_STATX_STX_MNT_ID >> + test_mnt_id(&buff); >> +#else >> + tst_res(TCONF, "stx_mnt_id was not supported until linux 5.8."); > > This is confusing at best, if we end up here we were missing the > structure member during compilation regardless the kernel version. > > So this message really should be: > > "stx_mnt_id not defined in struct statx" Will do it in v2. Best Regards Yang Xu > >
diff --git a/configure.ac b/configure.ac index 9101617ea..4751b14d2 100644 --- a/configure.ac +++ b/configure.ac @@ -152,6 +152,10 @@ AC_CHECK_FUNCS(mkdtemp,[],AC_MSG_ERROR(mkdtemp() not found!)) AC_CHECK_MEMBERS([struct fanotify_event_info_fid.fsid.__val],,,[#include <sys/fanotify.h>]) AC_CHECK_MEMBERS([struct perf_event_mmap_page.aux_head],,,[#include <linux/perf_event.h>]) AC_CHECK_MEMBERS([struct sigaction.sa_sigaction],[],[],[#include <signal.h>]) +AC_CHECK_MEMBERS([struct statx.stx_mnt_id],,,[ +#define _GNU_SOURCE +#include <sys/stat.h> +]) AC_CHECK_MEMBERS([struct utsname.domainname],,,[ #define _GNU_SOURCE diff --git a/testcases/kernel/syscalls/statx/statx01.c b/testcases/kernel/syscalls/statx/statx01.c index bf7d21c5d..6d0e7d590 100644 --- a/testcases/kernel/syscalls/statx/statx01.c +++ b/testcases/kernel/syscalls/statx/statx01.c @@ -17,6 +17,7 @@ * 4) blocks * 5) size * 6) nlink + * 7) mnt_id * * A file is created and metadata values are set with * predefined values. @@ -39,9 +40,11 @@ #include <stdio.h> #include <sys/types.h> #include <sys/sysmacros.h> +#include <unistd.h> #include "tst_test.h" #include "tst_safe_macros.h" #include "lapi/stat.h" +#include "tst_safe_stdio.h" #include <string.h> #include <inttypes.h> @@ -54,6 +57,43 @@ #define MAJOR 8 #define MINOR 1 +static int file_fd = -1; + +#ifdef HAVE_STRUCT_STATX_STX_MNT_ID +static void test_mnt_id(struct statx *buf) +{ + FILE *file; + char line[PATH_MAX]; + int pid; + unsigned int line_mjr, line_mnr, mnt_id; + + file = SAFE_FOPEN("/proc/self/mountinfo", "r"); + + while (fgets(line, sizeof(line), file)) { + if (sscanf(line, "%d %*d %d:%d", &mnt_id, &line_mjr, &line_mnr) != 3) + continue; + + if (line_mjr == buf->stx_dev_major && line_mnr == buf->stx_dev_minor) + break; + } + + SAFE_FCLOSE(file); + + if (buf->stx_mnt_id == mnt_id) + tst_res(TPASS, + "statx.stx_mnt_id equals to mount_id(%d) in /proc/self/mountinfo", + mnt_id); + else + tst_res(TFAIL, + "statx.stx_mnt_id(%d) is different from mount_id(%d) in /proc/self/mountinfo", + buf->stx_mnt_id, mnt_id); + + pid = getpid(); + snprintf(line, PATH_MAX, "/proc/%d/fdinfo/%d", pid, file_fd); + TST_ASSERT_FILE_INT(line, "mnt_id:", buf->stx_mnt_id); +} +#endif + static void test_normal_file(void) { struct statx buff; @@ -106,6 +146,11 @@ static void test_normal_file(void) tst_res(TFAIL, "stx_nlink(%u) is different from expected(1)", buff.stx_nlink); +#ifdef HAVE_STRUCT_STATX_STX_MNT_ID + test_mnt_id(&buff); +#else + tst_res(TCONF, "stx_mnt_id was not supported until linux 5.8."); +#endif } static void test_device_file(void) @@ -137,7 +182,6 @@ static void test_device_file(void) buff.stx_rdev_minor, MINOR); } - struct tcase { void (*tfunc)(void); } tcases[] = { @@ -153,7 +197,6 @@ static void run(unsigned int i) static void setup(void) { char data_buff[SIZE]; - int file_fd; umask(0); @@ -161,15 +204,21 @@ static void setup(void) file_fd = SAFE_OPEN(TESTFILE, O_RDWR|O_CREAT, MODE); SAFE_WRITE(1, file_fd, data_buff, sizeof(data_buff)); - SAFE_CLOSE(file_fd); SAFE_MKNOD(DEVICEFILE, S_IFBLK | 0777, makedev(MAJOR, MINOR)); } +static void cleanup(void) +{ + if (file_fd > -1) + SAFE_CLOSE(file_fd); +} + static struct tst_test test = { .test = run, .tcnt = ARRAY_SIZE(tcases), .setup = setup, + .cleanup = cleanup, .min_kver = "4.11", .needs_devfs = 1, .mntpoint = MNTPOINT,
This member was added since linux 5.8. We compare this value with the value in two places. 1.the mount_id filed in /proc/self/mountinfo 2.the mnt_id field in /proc/pid/fdinfo/fd Reference url: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fa2fcf4 https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/?id=728009a47497b6 Signed-off-by: Yang Xu <xuyang2018.jy@fujitsu.com> --- configure.ac | 4 ++ testcases/kernel/syscalls/statx/statx01.c | 55 +++++++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-)