Whamcloud - gitweb
EX-3658 pumount: refine exit statuses
authorJohn L. Hammond <jhammond@whamcloud.com>
Thu, 26 Aug 2021 15:26:04 +0000 (10:26 -0500)
committerJohn L. Hammond <jhammond@whamcloud.com>
Mon, 20 Sep 2021 13:24:43 +0000 (13:24 +0000)
   0  Unmount succeeded and no processes using FS remained.
   1  Unmount succeeded but one or more processes using FS remained.
   2  Unmount failed or some other major error occurred.
   3  An invalid option or argument was supplied.

Add sanity-pumount 57a-c to verify.

Test-Parameters: trivial testlist=sanity-pumount clientextra_install_params="--packages pumount"
Signed-off-by: John L. Hammond <jhammond@whamcloud.com>
Change-Id: I7d0d67129af08d5c56ab5e676d4d92b3a14f2d9d
Reviewed-on: https://review.whamcloud.com/44758
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/44958
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/tests/sanity-pumount.sh
pumount/pumount.c

index 1519758..75a1003 100755 (executable)
@@ -708,6 +708,7 @@ test_57a() {
        local file=$DIR/$tfile
        local fd
        local pid
+       local status
 
        init_pumount_env
 
@@ -716,12 +717,36 @@ test_57a() {
        pid=$!
        exec {fd}>&-
 
-       ! pumount --signal=$SIGCHLD "$MOUNT1" || error "pumount should fail"
+       status=0
+       pumount --signal=$SIGCHLD "$MOUNT1" || status=$?
+       ((status == 1)) || error "pumount exited with status $status, expected 1"
+
        ! mountpoint --quiet "$MOUNT1" || error "'$MOUNT1' still in mountinfo"
        kill_wait_signaled $pid $SIGTERM $SIGTERM
        check_unmount_complete "$MOUNT1"
 }
-run_test 57a "pumount fails when processes remain"
+run_test 57a "pumount fails with status 1 when processes remain"
+
+test_57b() {
+       local status
+
+       init_pumount_env
+       umount_client "$MOUNT2"
+       
+       status=0
+       pumount "$MOUNT2" || status=$?
+       ((status == 2)) || error "pumount exited with status $status, expected 2"
+}
+run_test 57b "pumount fails with status 2 when umount fails"
+
+test_57c() {
+       local status
+
+       status=0
+       pumount || status=$?
+       ((status == 3)) || error "pumount exited with status $status, expected 3"
+}
+run_test 57c "pumount fails with status 3 on invalid usage"
 
 log "cleanup: ======================================================"
 
index 0d39430..bba34af 100644 (file)
 #include <sys/mount.h>
 #include <linux/types.h>
 
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0])))
+#endif
+
 #ifdef VERSION
 # define PU_VERSION VERSION
 #else
@@ -29,7 +33,28 @@ static const char pu_program_name[] = "pumount";
 static const char pu_version[] = PU_VERSION;
 static bool pu_debug;
 
-#define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0])))
+enum {
+       PU_DEF_SCAN_COUNT_MAX = 10,
+       PU_DEF_SIGNAL = SIGKILL, /* XXX Hard coded in help message. */
+       PU_EXIT_SUCCESS = 0, /* See the help message. */
+       PU_EXIT_PROCESSES_REMAINED = 1,
+       PU_EXIT_FAILURE = 2,
+       PU_EXIT_TRY_HELP = 3,
+       PU_FILEID_LUSTRE = 0x97, /* From linux/exportfs.h */
+       PU_FILEID_INVALID = 0xff, /* ... */
+       PU_MOUNT_ID_FAKE = INT_MAX,
+};
+
+struct pu_fid {
+       __u64 f_seq;
+       __u32 f_oid;
+       __u32 f_ver;
+};
+
+struct pu_lustre_nfs_fid {
+       struct pu_fid lnf_child;
+       struct pu_fid lnf_parent;
+};
 
 #define PU_DEBUG(fmt, args...)                                         \
        do {                                                            \
@@ -49,8 +74,8 @@ static bool pu_debug;
 
 #define PU_FATAL(fmt, args...)                     \
        do {                                        \
-               PU_ERROR("fatal: "fmt, ##args);             \
-               exit(EXIT_FAILURE);                 \
+               PU_ERROR("fatal: "fmt, ##args);     \
+               exit(PU_EXIT_FAILURE);              \
        } while (0)
 
 #define OOM() \
@@ -60,8 +85,8 @@ static bool pu_debug;
        do {                                                            \
                fprintf(stderr,                                         \
                        "Try '%s --help' for more information.\n",      \
-                       pu_program_name);                       \
-               exit(2);                                                \
+                       pu_program_name);                               \
+               exit(PU_EXIT_TRY_HELP);                                 \
        } while (0)
 
 #define TRY_HELP(fmt, args...)                                         \
@@ -402,23 +427,6 @@ out:
        return rc;
 }
 
-struct pu_fid {
-       __u64 f_seq;
-       __u32 f_oid;
-       __u32 f_ver;
-};
-
-struct pu_lustre_nfs_fid {
-       struct pu_fid lnf_child;
-       struct pu_fid lnf_parent;
-};
-
-enum {
-       PU_MOUNT_ID_FAKE = INT_MAX,
-       PU_FILEID_LUSTRE = 0x97, /* From linux/exportfs.h */
-       PU_FILEID_INVALID = 0xff, /* ... */
-};
-
 static int pu_name_to_handle(int dirfd, const char *path, struct file_handle **phandle, int *mount_id, int flags)
 {
        struct file_handle *handle = NULL;
@@ -753,7 +761,7 @@ static struct option options[] = {
        { NULL },
 };
 
-void usage(void)
+static void print_help(void)
 {
        printf(
 "Usage pumount [OPTION]... DIRECTORY\n"
@@ -768,9 +776,9 @@ void usage(void)
 "  --no-open           do not open DIRECTORY\n"
 "  --no-signal         do not send signals\n"
 "  --no-umount         do not unmount FS\n"
-"  -p, --print         print users of FS\n"
-"  --scan-count=COUNT  scan for users at most COUNT times\n" /* ... (default %d) */
-"  --signal=SIG        send SIG to users of FS (default SIGKILL)\n"
+"  -p, --print         print uses of FS\n"
+"  --scan-count=COUNT  scan for processes at most COUNT times (default %d)\n"
+"  --signal=SIG        send SIG to processes using FS (default SIGKILL)\n" /* XXX */
 "  --version           print version information and exit\n"
 "\n"
 "Operation:\n"
@@ -829,10 +837,16 @@ void usage(void)
 "python  8942    0       lustre  [0x200000404:0x3:0x0]   /lustre/fs0a12/client/projects/EGGS\\040V7\\040FINAL.xls\n"
 "\n"
 "Exit status:\n"
-"   0  Unmount succeeded and no users remained.\n"
-"   1  Unmount failed or users remained or other error.\n"
-"   2  An invalid option or argument was supplied.\n");
-/* TODO (maybe) add more statuses about users remaining, minor errors. ... */
+"   %d  Unmount succeeded and no processes using FS remained.\n"
+"   %d  Unmount succeeded but one or more processes using FS remained.\n"
+"   %d  Unmount failed or some other major error occurred.\n"
+"   %d  An invalid option or argument was supplied.\n",
+PU_DEF_SCAN_COUNT_MAX,
+PU_EXIT_SUCCESS,
+PU_EXIT_PROCESSES_REMAINED,
+PU_EXIT_FAILURE,
+PU_EXIT_TRY_HELP
+);
 }
 
 int main(int argc, char *argv[])
@@ -849,10 +863,10 @@ int main(int argc, char *argv[])
        bool do_print = false;
        bool do_signal = true;
        bool do_umount = true;
-       int sig = SIGKILL;
+       int sig = PU_DEF_SIGNAL;
        int umount2_flags = MNT_DETACH;
        int proc_count;
-       int scan_count_max = 4;
+       int scan_count_max = PU_DEF_SCAN_COUNT_MAX;
        int scan_count;
        int use_count = 0;
        int err_count = 0;
@@ -875,8 +889,8 @@ int main(int argc, char *argv[])
                        umount2_flags |= MNT_FORCE;
                        break;
                case 'h':
-                       usage();
-                       exit(EXIT_SUCCESS);
+                       print_help();
+                       exit(PU_EXIT_SUCCESS);
                case 'l':
                        /* Already implied. */
                        break;
@@ -895,25 +909,24 @@ int main(int argc, char *argv[])
                case PU_OPT_SCAN_COUNT:
                        rc = pu_strtoi(optarg, &scan_count_max, 0, INT_MAX);
                        if (rc < 0)
-                               PU_FATAL("invalid scan-count '%s'\n", optarg);
+                               TRY_HELP("invalid scan-count '%s'\n", optarg);
                        break;
                case PU_OPT_SIGNAL:
                        rc = pu_str_to_signal(optarg, &sig);
                        if (rc < 0)
-                               PU_FATAL("invalid signal '%s'\n", optarg);
+                               TRY_HELP("invalid signal '%s'\n", optarg);
                        break;
                case PU_OPT_VERSION:
                        printf("%s %s\n", pu_program_name, pu_version);
-                       exit(EXIT_SUCCESS);
+                       exit(PU_EXIT_SUCCESS);
                case '?':
                        TRY_HELP_1();
                }
        }
 
-       if (optind + 1 != argc) {
+       if (optind + 1 != argc)
                TRY_HELP("usage: %s [OPTION]... DIRECTORY\n",
                         pu_program_name);
-       }
 
        mount_point = argv[optind];
 
@@ -1039,7 +1052,7 @@ int main(int argc, char *argv[])
                        if (puc->puc_use_count == 0)
                                goto next;
 
-                       PU_DEBUG("found process %d, comm '%s' with %d usesN of mount %d\n",
+                       PU_DEBUG("found process %d, comm '%s' with %d uses of mount %d\n",
                                 pid, puc_comm(puc), puc->puc_use_count, mount_id);
 
                        proc_count += 1;
@@ -1074,11 +1087,13 @@ int main(int argc, char *argv[])
                         proc_count, proc_count == 1 ? "" : "es",
                         mount_point, mount_id,
                         scan_count, scan_count == 1 ? "" : "s");
-               status = EXIT_FAILURE;
+               status = PU_EXIT_PROCESSES_REMAINED;
        } else {
-               status = EXIT_SUCCESS;
+               status = PU_EXIT_SUCCESS;
        }
 
+       PU_DEBUG_D(status);
+
        /* If there are no other users of FS then the real umount
         * should happen in the close of mount_dirfd. */
        pu_close(&mount_dirfd);