From f0534544e3e3aef280ccc5f042e37d42d33b28d3 Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Mon, 13 Nov 2023 11:02:24 +0100 Subject: [PATCH] LU-17173 utils: cleanup lfs flushctx When lfs flushctx is called without mount points, build the list of all mounts first, and then call the ioctl to flush associated contexts. Otherwise fetching the mount points unfortunately refreshes the contexts being flushed, because the mount points are being accessed. Test-Parameters: trivial Test-Parameters: kerberos=true testlist=sanity-krb5 Test-Parameters: testgroup=review-dne-selinux-ssk-part-2 Signed-off-by: Sebastien Buisson Change-Id: I75b9efe4c65ce66f5f692f9e49a28fde705d0140 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/52604 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin Reviewed-by: Aurelien Degremont Reviewed-by: Andreas Dilger --- lustre/utils/Makefile.am | 2 +- lustre/utils/lfs.c | 103 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am index 31e2302..8d1e9cd 100644 --- a/lustre/utils/Makefile.am +++ b/lustre/utils/Makefile.am @@ -76,7 +76,7 @@ lctl_CFLAGS := $(AM_CFLAGS) $(LIBNL3_CFLAGS) -I $(top_builddir)/lnet/utils lctl_LDADD := liblustreapi.la $(PTHREAD_LIBS) $(LIBNL3_LIBS) -lyaml lctl_LDADD += $(top_builddir)/lnet/utils/lnetconfig/liblnetconfig.la -lfs_SOURCES = lfs.c lfs_project.c lfs_project.h +lfs_SOURCES = lfs.c lfs_project.c lfs_project.h callvpe.c callvpe.h lfs_CFLAGS := -fPIC $(AM_CFLAGS) -I $(top_builddir)/lnet/utils lfs_LDADD := liblustreapi.la -lz lfs_LDADD += $(top_builddir)/lnet/utils/lnetconfig/liblnetconfig.la diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 20e42c0..0630646 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -78,6 +78,7 @@ #include #include "lstddef.h" #include +#include "callvpe.h" #ifndef NSEC_PER_SEC # define NSEC_PER_SEC 1000000000UL @@ -9382,10 +9383,10 @@ static int flushctx_ioctl(char *mp) static int lfs_flushctx(int argc, char **argv) { - int kdestroy = 0, reap = 0, c; - char mntdir[PATH_MAX] = {'\0'}; - int index = 0; - int rc = 0; + int kdestroy = 0, reap = 0, c; + char **mnts = NULL, **mnt_ptr; + int mnt_num = 1, index = 0, rc = 0, rc2; + extern char **environ; while ((c = getopt(argc, argv, "kr")) != -1) { switch (c) { @@ -9403,44 +9404,84 @@ static int lfs_flushctx(int argc, char **argv) } } - if (kdestroy) { - rc = system("kdestroy > /dev/null"); - if (rc) { - rc = WEXITSTATUS(rc); - fprintf(stderr, - "error destroying tickets: %d, continuing\n", - rc); - } - } - if (optind >= argc) { - /* flush for all mounted lustre fs. */ - while (!llapi_search_mounts(NULL, index++, mntdir, NULL)) { - /* Check if we have a mount point */ - if (mntdir[0] == '\0') - continue; - - if (flushctx_ioctl(mntdir)) - rc = -1; + /* flush for all lustre mount points */ +again: + mnt_ptr = realloc(mnts, mnt_num * sizeof(char *)); + if (!mnt_ptr) { + mnt_num--; + rc = -ENOMEM; + goto reap; + } + mnts = mnt_ptr; + mnts[mnt_num - 1] = (char *)calloc(PATH_MAX + 1, sizeof(char)); + if (!mnts[mnt_num - 1]) { + rc = -ENOMEM; + goto reap; + } +next: + if (!llapi_search_mounts(NULL, index++, + mnts[mnt_num - 1], NULL)) { - mntdir[0] = '\0'; /* avoid matching in next loop */ + if (*mnts[mnt_num - 1] == '\0') + goto next; + mnt_num++; + goto again; + } else { + *mnts[mnt_num - 1] = '\0'; } + + mnt_ptr = mnts; + index = 0; } else { - /* flush fs as specified */ - while (optind < argc) { - if (flushctx_ioctl(argv[optind++])) - rc = -1; + /* flush for mounts as specified on command line */ + mnt_ptr = argv + optind; + mnt_num = argc - optind; + } + + for (index = 0; index < mnt_num; index++) { + /* Check if we have a mount point */ + if (*mnt_ptr[index] == '\0') + continue; + + rc2 = flushctx_ioctl(mnt_ptr[index]); + if (rc2) { + rc2 = -errno; + fprintf(stderr, + "error flushing contexts on mount point %s: %s\n", + mnt_ptr[index], strerror(errno)); + rc = rc ? rc : rc2; } } +reap: if (reap) { - rc = system("keyctl reap > /dev/null"); - if (rc != 0) { - rc = WEXITSTATUS(rc); - fprintf(stderr, "error reaping keyring: %d\n", rc); + static char *args[] = { "keyctl", "reap", NULL }; + + /* use callvpe to bypass the shell */ + rc2 = callvpe("keyctl", args, environ); + if (rc2) { + rc2 = WEXITSTATUS(rc2); + fprintf(stderr, "error reaping keyring: %d\n", rc2); } } + if (kdestroy) { + static char *args[] = { "kdestroy", NULL }; + + /* use callvpe to bypass the shell */ + rc2 = callvpe("kdestroy", args, environ); + if (rc2) { + rc2 = WEXITSTATUS(rc2); + fprintf(stderr, "error destroying tickets: %d\n", rc2); + } + } + + if (mnts) { + for (index = 0; index < mnt_num; index++) + free(mnts[index]); + free(mnts); + } return rc; } -- 1.8.3.1