Whamcloud - gitweb
LU-16076 utils: enhance 'lfs check' command
authorLei Feng <flei@whamcloud.com>
Mon, 8 Aug 2022 02:59:25 +0000 (10:59 +0800)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 27 Oct 2022 03:17:31 +0000 (03:17 +0000)
Add optional argument to 'lfs check' command so that only the
servers related to the specified lustre file system is checked.

lustre-change: https://review.whamcloud.com/48155
lustre-commit: f5ca6853b8d8b918b0228af31fa8249be49d3000

Signed-off-by: Lei Feng <flei@whamcloud.com>
Test-Parameters: trivial testlist=sanityn env=ONLY=113
Change-Id: I826a8e822af0a290f06ffaadadf1bb7f86899d99
Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/48935
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/doc/lfs.1
lustre/tests/sanityn.sh
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/liblustreapi_fid.c
lustre/utils/liblustreapi_hsm.c
lustre/utils/liblustreapi_pcc.c
lustre/utils/lustreapi_internal.h

index 2ca2c42..a864cfb 100644 (file)
@@ -7,7 +7,7 @@ lfs \- client utility for Lustre-specific file layout and other attributes
 .br
 .B lfs changelog_clear <\fImdtname\fR> <\fIid\fR> <\fIendrec\fR>
 .br
-.B lfs check \fR<\fBmgts\fR|\fBmdts\fR|\fBosts\fR|\fBall\fR>
+.B lfs check \fR<\fBmgts\fR|\fBmdts\fR|\fBosts\fR|\fBall\fR> [\fIpath\fR]
 .br
 .B lfs data_version \fR[\fB-nrw\fR] \fB<\fIfilename\fR>
 .br
@@ -155,9 +155,10 @@ interest to a particular consumer <id>, potentially allowing the MDT to
 free up disk space. An <endrec> of 0 indicates the current last record.
 Changelog consumers must be registered on the MDT node using \fBlctl\fR.
 .TP
-.B check <mgts|mdts|osts|all>
+.B check <mgts|mdts|osts|all> [path]
 Display the status of the MGTs, MDTs or OSTs (as specified in the command) or
-all the servers (MGTs, MDTs and OSTs).
+all the servers (MGTs, MDTs and OSTs). If \fBpath\fR is provided, display
+the status of the lustre file system mounted at specified \fBpath\fR only.
 .TP
 .B data_version [-nrw] <filename>
 Display the current version of file data. If -n is specified, the data version
index 76fe8f3..55a1d05 100755 (executable)
@@ -514,7 +514,7 @@ test_16d() {
 
        $LFS setstripe -c -1 $file1 # b=10919
        $LCTL set_param ldlm.namespaces.*.lru_size=clear
-       
+
        # direct write on one client and direct read from another
        dd if=/dev/urandom of=$file1 bs=1M count=100 oflag=direct
        dd if=$file2 of=$tmpfile iflag=direct bs=1M
@@ -5762,6 +5762,40 @@ test_109() {
 
 run_test 109 "Race with several mount instances on 1 node"
 
+test_113 () {
+       (( MDS1_VERSION >= $(version_code 2.14.0) )) ||
+               skip "Need server version at least 2.14.0"
+
+       local instance
+       local nid
+
+       instance=$($LFS getname -i $DIR1) ||
+               error "cannot get instance of $DIR1"
+
+       $LFS check osts $DIR1 | grep $instance ||
+               error "cannot find OSTs of instance $instance"
+
+       $LFS check osts $DIR1 | grep -v $instance
+       if (( $? == 0 )); then
+               error "find OSTs other than instance $instance"
+       fi
+
+       $LFS check osts | grep $instance ||
+               error "cannot find other OSTs"
+
+       nid=$(df $DIR2 | tail -1 | sed 's%:/.*%%') ||
+               error "cannot parse nid for $DIR2"
+
+       $LFS check mgts $DIR2 | grep MGC$nid ||
+               error "cannot find mgc of $nid"
+
+       $LFS check mgts $DIR2 | grep -v MGC$nid
+       if (( $? == 0 )); then
+               error "find MGTs other than nid $nid"
+       fi
+}
+run_test 113 "check servers of specified fs"
+
 log "cleanup: ======================================================"
 
 # kill and wait in each test only guarentee script finish, but command in script
index f7ab8ae..47de646 100644 (file)
@@ -533,8 +533,8 @@ command_t cmdlist[] = {
         "\t ^: used before a flag indicates to exclude it\n"},
        {"check", lfs_check, 0,
         "Display the status of MGTs, MDTs or OSTs (as specified in the command)\n"
-        "or all the servers (MGTs, MDTs and OSTs).\n"
-        "usage: check <mgts|osts|mdts|all>"},
+        "or all the servers (MGTs, MDTs and OSTs) [for specified path only].\n"
+        "usage: check {mgts|osts|mdts|all} [path]"},
        {"osts", lfs_osts, 0, "list OSTs connected to client "
         "[for specified path only]\n" "usage: osts [path]"},
        {"mdts", lfs_mdts, 0, "list MDTs connected to client "
@@ -7111,7 +7111,7 @@ static int lfs_getname(int argc, char **argv)
 
 static int lfs_check(int argc, char **argv)
 {
-       char mntdir[PATH_MAX] = {'\0'};
+       char mntdir[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
        int num_types = 1;
        char *obd_types[3];
        char obd_type1[4];
@@ -7119,7 +7119,7 @@ static int lfs_check(int argc, char **argv)
        char obd_type3[4];
        int rc;
 
-       if (argc != 2) {
+       if (argc < 2 || argc > 3) {
                fprintf(stderr, "%s check: server type must be specified\n",
                        progname);
                return CMD_HELP;
@@ -7148,7 +7148,14 @@ static int lfs_check(int argc, char **argv)
                return CMD_HELP;
        }
 
-       rc = llapi_search_mounts(NULL, 0, mntdir, NULL);
+       if (argc >= 3 && !realpath(argv[2], path)) {
+               rc = -errno;
+               fprintf(stderr, "error: invalid path '%s': %s\n",
+                       argv[2], strerror(-rc));
+               return rc;
+       }
+
+       rc = llapi_search_mounts(path, 0, mntdir, NULL);
        if (rc < 0 || mntdir[0] == '\0') {
                fprintf(stderr,
                        "%s check: cannot find mounted Lustre filesystem: %s\n",
@@ -7156,7 +7163,7 @@ static int lfs_check(int argc, char **argv)
                return rc;
        }
 
-       rc = llapi_target_check(num_types, obd_types, mntdir);
+       rc = llapi_target_check(num_types, obd_types, path);
        if (rc)
                fprintf(stderr, "%s check: cannot check target '%s': %s\n",
                        progname, argv[1], strerror(-rc));
index 9f7a695..c72b8b5 100644 (file)
@@ -84,6 +84,8 @@
 #include "lstddef.h"
 
 #define FORMATTED_BUF_LEN      1024
+#define MAX_LINE_LEN           256
+#define MAX_INSTANCE_LEN       32
 
 static int llapi_msg_level = LLAPI_MSG_MAX;
 const char *liblustreapi_cmd;
@@ -1300,7 +1302,8 @@ out:
  * Find the fsname, the full path, and/or an open fd.
  * Either the fsname or path must not be NULL
  */
-int get_root_path(int want, char *fsname, int *outfd, char *path, int index)
+int get_root_path(int want, char *fsname, int *outfd, char *path, int index,
+                 char *nid)
 {
        struct mntent mnt;
        char buf[PATH_MAX], mntdir[PATH_MAX];
@@ -1391,11 +1394,15 @@ int get_root_path(int want, char *fsname, int *outfd, char *path, int index)
                                rc = -errno;
                                llapi_error(LLAPI_MSG_ERROR, rc,
                                            "cannot open '%s'", mntdir);
-
                        } else {
                                *outfd = fd;
                        }
                }
+               if ((want & WANT_NID) && nid) {
+                       ptr_end = strchr(mnt.mnt_fsname, ':');
+                       strncpy(nid, mnt.mnt_fsname, ptr_end - mnt.mnt_fsname);
+                       nid[ptr_end - mnt.mnt_fsname] = '\0';
+               }
        } else if (want & WANT_ERROR)
                llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "'%s' not on a mounted Lustre filesystem",
@@ -1429,7 +1436,7 @@ int llapi_search_mounts(const char *pathname, int index, char *mntdir,
 
        if (fsname)
                want |= WANT_FSNAME;
-       return get_root_path(want, fsname, NULL, mntdir, idx);
+       return get_root_path(want, fsname, NULL, mntdir, idx, NULL);
 }
 
 /* Given a path, find the corresponding Lustre fsname */
@@ -1500,7 +1507,8 @@ int llapi_search_fsname(const char *pathname, char *fsname)
                        }
                }
        }
-       rc = get_root_path(WANT_FSNAME | WANT_ERROR, fsname, NULL, path, -1);
+       rc = get_root_path(WANT_FSNAME | WANT_ERROR, fsname, NULL, path, -1,
+                          NULL);
        free(path);
        return rc;
 }
@@ -1512,7 +1520,8 @@ int llapi_search_rootpath(char *pathname, const char *fsname)
         * clear it for safety
         */
        pathname[0] = 0;
-       return get_root_path(WANT_PATH, (char *)fsname, NULL, pathname, -1);
+       return get_root_path(WANT_PATH, (char *)fsname, NULL, pathname, -1,
+                            NULL);
 }
 
 /**
@@ -6541,10 +6550,27 @@ free_path:
        return rc;
 }
 
+struct check_target_filter {
+       char *nid;
+       char *instance;
+};
+
 static void do_target_check(char *obd_type_name, char *obd_name,
                            char *obd_uuid, void *args)
 {
        int rc;
+       struct check_target_filter *filter = args;
+
+       if (filter != NULL) {
+               /* check nid if obd type is mgc */
+               if (strcmp(obd_type_name, "mgc") == 0) {
+                       if (strcmp(obd_name + 3, filter->nid) != 0)
+                               return;
+               }
+               /* check instance for other types of device (osc/mdc) */
+               else if (strstr(obd_name, filter->instance) == NULL)
+                       return;
+       }
 
        rc = llapi_ping(obd_type_name, obd_name);
        if (rc == ENOTCONN)
@@ -6557,7 +6583,29 @@ static void do_target_check(char *obd_type_name, char *obd_name,
 
 int llapi_target_check(int type_num, char **obd_type, char *dir)
 {
-       return llapi_target_iterate(type_num, obd_type, NULL, do_target_check);
+       char nid[MAX_LINE_LEN], instance[MAX_INSTANCE_LEN];
+       struct check_target_filter filter = {NULL, NULL};
+       int rc;
+
+       if (dir == NULL || dir[0] == '\0')
+               return llapi_target_iterate(type_num, obd_type, NULL,
+                                           do_target_check);
+
+       rc = get_root_path(WANT_NID | WANT_ERROR, NULL, NULL, dir, -1, nid);
+       if (rc) {
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "cannot get nid of path '%s'", dir);
+               return rc;
+       }
+       filter.nid = nid;
+
+       rc = llapi_get_instance(dir, instance, ARRAY_SIZE(instance));
+       if (rc)
+               return rc;
+       filter.instance = instance;
+
+       return llapi_target_iterate(type_num, obd_type, &filter,
+                                   do_target_check);
 }
 
 #undef MAX_STRING_SIZE
index 578c6e6..be439bf 100644 (file)
@@ -215,10 +215,10 @@ int llapi_fid2path(const char *path_or_device, const char *fidstr, char *path,
 
        if (*path_or_device == '/')
                rc = get_root_path(WANT_FD, NULL, &mnt_fd,
-                                  (char *)path_or_device, -1);
+                                  (char *)path_or_device, -1, NULL);
        else
                rc = get_root_path(WANT_FD, (char *)path_or_device,
-                                  &mnt_fd, NULL, -1);
+                                  &mnt_fd, NULL, -1, NULL);
 
        if (rc < 0)
                goto out;
index ba99cd3..9f99ecf 100644 (file)
@@ -1592,7 +1592,7 @@ int llapi_hsm_request(const char *path, const struct hsm_user_request *request)
        int rc;
        int fd;
 
-       rc = get_root_path(WANT_FD, NULL, &fd, (char *)path, -1);
+       rc = get_root_path(WANT_FD, NULL, &fd, (char *)path, -1, NULL);
        if (rc)
                return rc;
 
index 8ea726e..d5a26ac 100644 (file)
@@ -304,7 +304,7 @@ int llapi_pcc_detach_fid(const char *mntpath, const struct lu_fid *fid,
        int fd;
        struct lu_pcc_detach_fid detach;
 
-       rc = get_root_path(WANT_FD, NULL, &fd, (char *)mntpath, -1);
+       rc = get_root_path(WANT_FD, NULL, &fd, (char *)mntpath, -1, NULL);
        if (rc) {
                llapi_error(LLAPI_MSG_ERROR, rc, "cannot get root path: %s",
                            mntpath);
index aea7c2f..fcd08ae 100644 (file)
@@ -51,6 +51,8 @@
 #define WANT_FD     0x4
 #define WANT_INDEX  0x8
 #define WANT_ERROR  0x10
+#define WANT_DEV    0x20
+#define WANT_NID    0x40
 
 /* Define a fixed 4096-byte encryption unit size */
 #define LUSTRE_ENCRYPTION_BLOCKBITS   12
@@ -62,7 +64,8 @@
 #define PROC_MOUNTS "/proc/mounts"
 #endif
 
-int get_root_path(int want, char *fsname, int *outfd, char *path, int index);
+int get_root_path(int want, char *fsname, int *outfd, char *path, int index,
+                 char *nid);
 int llapi_ioctl_pack(struct obd_ioctl_data *data, char **pbuf, int max_len);
 int llapi_ioctl_unpack(struct obd_ioctl_data *data, char *pbuf, int max_len);
 int sattr_cache_get_defaults(const char *const fsname,