Whamcloud - gitweb
LU-16076 utils: enhance 'lfs check' command 55/48155/13
authorLei Feng <flei@whamcloud.com>
Mon, 8 Aug 2022 02:59:25 +0000 (10:59 +0800)
committerOleg Drokin <green@whamcloud.com>
Sat, 15 Oct 2022 05:56:44 +0000 (05:56 +0000)
Add optional argument to 'lfs check' command so that only the
servers related to the specified lustre file system is checked.

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/fs/lustre-release/+/48155
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Emoly Liu <emoly@whamcloud.com>
Reviewed-by: Jian Yu <yujian@whamcloud.com>
Reviewed-by: Oleg Drokin <green@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 1e3b9c1..d550166 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
@@ -158,9 +158,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 4a9771d..ed2cc2a 100755 (executable)
@@ -510,7 +510,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
@@ -5885,6 +5885,40 @@ test_112() {
 }
 run_test 112 "update max-inherit in default LMV"
 
+test_113 () {
+       (( MDS1_VERSION >= $(version_code 2.15.50) )) ||
+               skip "Need server version at least 2.15.50"
+
+       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 e80814d..3b1d6ea 100644 (file)
@@ -428,8 +428,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 "
@@ -7380,7 +7380,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];
@@ -7388,7 +7388,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;
@@ -7417,7 +7417,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",
@@ -7425,7 +7432,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 c4dc701..5614fbb 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;
@@ -1254,12 +1256,13 @@ static struct {
        dev_t dev;
        char fsname[PATH_MAX];
        char mnt_dir[PATH_MAX];
+       char nid[MAX_LINE_LEN];
 } root_cached = { 0 };
 
 static pthread_rwlock_t root_cached_lock = PTHREAD_RWLOCK_INITIALIZER;
 
 static int get_root_path_fast(int want, char *fsname, int *outfd, char *path,
-                             dev_t *dev)
+                             dev_t *dev, char *nid)
 {
        int rc = -ENODEV;
        int fsnamelen;
@@ -1298,14 +1301,15 @@ static int get_root_path_fast(int want, char *fsname, int *outfd, char *path,
                *dev = root_cached.dev;
        if ((want & WANT_FD) && outfd)
                rc = get_root_fd(root_cached.mnt_dir, outfd);
-
+       if ((want & WANT_NID) && nid)
+               strcpy(nid, root_cached.nid);
 out_unlock:
        pthread_rwlock_unlock(&root_cached_lock);
        return rc;
 }
 
 static int get_root_path_slow(int want, char *fsname, int *outfd, char *path,
-                             int index, dev_t *dev)
+                             int index, dev_t *dev, char *nid)
 {
        struct mntent mnt;
        char buf[PATH_MAX];
@@ -1392,6 +1396,10 @@ static int get_root_path_slow(int want, char *fsname, int *outfd, char *path,
                strncpy(root_cached.mnt_dir, mnt.mnt_dir, mntlen);
                root_cached.mnt_dir[mntlen] = '\0';
                root_cached.dev = devmnt;
+               ptr_end = strchr(mnt.mnt_fsname, ':');
+               strncpy(root_cached.nid, mnt.mnt_fsname,
+                       ptr_end - mnt.mnt_fsname);
+               root_cached.nid[ptr_end - mnt.mnt_fsname] = '\0';
 
                pthread_rwlock_unlock(&root_cached_lock);
        }
@@ -1408,6 +1416,11 @@ static int get_root_path_slow(int want, char *fsname, int *outfd, char *path,
                *dev = devmnt;
        if ((want & WANT_FD) && outfd)
                rc = get_root_fd(mnt.mnt_dir, outfd);
+       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';
+       }
 
 out:
        endmntent(fp);
@@ -1419,14 +1432,15 @@ out:
  * Either the fsname or path must not be NULL
  */
 int get_root_path(int want, char *fsname, int *outfd, char *path, int index,
-                      dev_t *dev)
+                 dev_t *dev, char *nid)
 {
        int rc = -ENODEV;
 
        if (!(want & WANT_INDEX))
-               rc = get_root_path_fast(want, fsname, outfd, path, dev);
+               rc = get_root_path_fast(want, fsname, outfd, path, dev, nid);
        if (rc)
-               rc = get_root_path_slow(want, fsname, outfd, path, index, dev);
+               rc = get_root_path_slow(want, fsname, outfd, path, index, dev,
+                                       nid);
 
        if (!rc || !(want & WANT_ERROR))
                return rc;
@@ -1468,7 +1482,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, NULL);
+       return get_root_path(want, fsname, NULL, mntdir, idx, NULL, NULL);
 }
 
 /* Given a path, find the corresponding Lustre fsname */
@@ -1501,7 +1515,7 @@ int llapi_search_fsname(const char *pathname, char *fsname)
        }
 
        rc = get_root_path(WANT_FSNAME | WANT_ERROR, fsname, NULL, NULL, -1,
-                          &dev);
+                          &dev, NULL);
 
        return rc;
 }
@@ -1517,7 +1531,7 @@ int llapi_search_rootpath(char *pathname, const char *fsname)
         */
        pathname[0] = 0;
        return get_root_path(WANT_PATH, (char *)fsname, NULL, pathname, -1,
-                            NULL);
+                            NULL, NULL);
 }
 
 int llapi_search_rootpath_by_dev(char *pathname, dev_t dev)
@@ -1530,7 +1544,7 @@ int llapi_search_rootpath_by_dev(char *pathname, dev_t dev)
         * clear it for safety
         */
        pathname[0] = 0;
-       return get_root_path(WANT_PATH, NULL, NULL, pathname, -1, &dev);
+       return get_root_path(WANT_PATH, NULL, NULL, pathname, -1, &dev, NULL);
 }
 
 /**
@@ -6694,10 +6708,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)
@@ -6710,7 +6741,30 @@ 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, NULL,
+                          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 8d3f268..cc76ae6 100644 (file)
@@ -224,10 +224,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, NULL);
+                                  (char *)path_or_device, -1, NULL, NULL);
        else
                rc = get_root_path(WANT_FD, (char *)path_or_device,
-                                  &mnt_fd, NULL, -1, NULL);
+                                  &mnt_fd, NULL, -1, NULL, NULL);
 
        if (rc < 0)
                goto out;
index 052e6cd..e634293 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, NULL);
+       rc = get_root_path(WANT_FD, NULL, &fd, (char *)path, -1, NULL, NULL);
        if (rc)
                return rc;
 
index b1652c2..a2ed766 100644 (file)
@@ -212,7 +212,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, NULL);
+       rc = get_root_path(WANT_FD, NULL, &fd, (char *)mntpath, -1, NULL, NULL);
        if (rc) {
                llapi_error(LLAPI_MSG_ERROR, rc, "cannot get root path: %s",
                            mntpath);
index 41b7087..502fb8b 100644 (file)
@@ -51,6 +51,7 @@
 #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
@@ -63,7 +64,7 @@
 #endif
 
 int get_root_path(int want, char *fsname, int *outfd, char *path, int index,
-                 dev_t *dev);
+                 dev_t *dev, 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,