Whamcloud - gitweb
LU-18076 lfs: get client UUID by "lfs getname -u" 37/56437/7
authorEmoly Liu <emoly@whamcloud.com>
Thu, 10 Oct 2024 14:43:28 +0000 (22:43 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 22 Jan 2025 18:41:49 +0000 (18:41 +0000)
This patch is to get client UUID from the mountpoint by command
"lfs getname -u" directly. Functions llapi_file_get_type_uuid()
and llapi_file_fget_type_uuid() are added, and the man page
lfs-getname.1 is updated as well.
Also, function get_client_uuid() in test-framework.sh is modified
to verify this patch.

Signed-off-by: Emoly Liu <emoly@whamcloud.com>
Change-Id: I8f7db964adf209e19c29a240608881b38e068ded
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56437
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Zhenyu Xu <bobijam@hotmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/doc/lfs-getname.1
lustre/include/lustre/lustreapi.h
lustre/include/uapi/linux/lustre/lustre_ioctl.h
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/tests/test-framework.sh
lustre/utils/lfs.c
lustre/utils/liblustreapi.c

index c64a7ca..ece8509 100644 (file)
@@ -6,6 +6,7 @@ lfs-getname \- retrieve the filesystem name and instance ID
 .RB [ --help | -h ]
 .RB [ --instance | -i ]
 .RB [ --fsname | -n ]
+.RB [ --uuid | -u ]
 .RI [ PATHNAME ...]
 .YS
 .SH DESCRIPTION
@@ -19,6 +20,13 @@ and instance ID for these mount points.
 .BR -h ", " --help
 Print usage message.
 .TP
+.BR -i ", " --instance
+Only show the mount instance ID for each filesystem.  If
+.B -i
+is used with a single
+.I PATHNAME
+then the instance ID is printed without the mountpoint.
+.TP
 .BR -n ", " --fsname
 Print only the Lustre filesystem name for each filesystem.  If
 .B -n
@@ -26,12 +34,14 @@ is used with a single
 .I PATHNAME
 then the filesystem name is printed without the mountpoint.
 .TP
-.BR -i ", " --instance
-Only show the mount instance ID for each filesystem.  If
-.B -i
+.BR -u ", " --uuid
+Print only the UUID for this client filesystem mountpoint. Note that 
+this is not a common UUID suitable for mounting the filesystem with,
+but rather a unique identifier for this specific mount instance. If
+.B -u
 is used with a single
 .I PATHNAME
-then the instance ID is printed without the mountpoint.
+then the uuid is printed without the mountpoint.
 .SH EXAMPLES
 .EX
 .B # lfs getname
@@ -43,6 +53,9 @@ testfs
 .P
 .B # lfs getname -i /mnt/testfs
 ffff937009271000
+.P
+.B # lfs getname -u /mnt/testfs
+78adbfe8-1c12-4bd2-a485-69afa166677e
 .EE
 .SH AVAILABILITY
 .B lfs getname
index a8e4951..614e498 100644 (file)
@@ -466,6 +466,15 @@ int llapi_file_fget_lov_uuid(int fd, struct obd_uuid *lov_uuid);
 int llapi_file_fget_lmv_uuid(int fd, struct obd_uuid *lov_uuid);
 int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count);
 int llapi_lmv_get_uuids(int fd, struct obd_uuid *uuidp, int *mdt_count);
+enum tgt_type {
+       LOV_TYPE = 1,
+       LMV_TYPE = 2,
+       CLI_TYPE = 3,
+};
+int llapi_file_get_type_uuid(const char *path, enum tgt_type type,
+                       struct obd_uuid *uuid);
+int llapi_file_fget_type_uuid(int fd, enum tgt_type type,
+                       struct obd_uuid *uuid);
 int llapi_is_lustre_mnttype(const char *type);
 int llapi_search_tgt(const char *fsname, const char *poolname,
                     const char *tgtname, bool is_mdt);
index 13d2c28..f0ebed1 100644 (file)
@@ -142,6 +142,7 @@ static inline __u32 obd_ioctl_packlen(struct obd_ioctl_data *data)
 #define OBD_IOC_BRW_WRITE      _IOWR('f', 126, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_NAME2DEV       _IOWR('f', 127, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_GETDTNAME      _IOR('f', 127, char[MAX_OBD_NAME])
+#define OBD_IOC_GETUUID                _IOR('f', 127, char[UUID_MAX])
 /* ioctl codes 128-143 are reserved for fsverity */
 #define OBD_IOC_UUID2DEV       _IOWR('f', 130, OBD_IOC_DATA_TYPE)
 #define OBD_IOC_GETMDNAME      _IOR('f', 131, char[MAX_OBD_NAME])
index ba40b0b..edc08d2 100644 (file)
@@ -1560,6 +1560,7 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
                                      void *data);
 void ll_finish_md_op_data(struct md_op_data *op_data);
 int ll_get_obd_name(struct inode *inode, unsigned int cmd, void __user *arg);
+int ll_get_sb_uuid(struct inode *inode, void __user *arg);
 void ll_compute_rootsquash_state(struct ll_sb_info *sbi);
 ssize_t ll_copy_user_md(const struct lov_user_md __user *md,
                        struct lov_user_md **kbuf);
index 969700c..db159cb 100644 (file)
@@ -3488,6 +3488,8 @@ int ll_iocontrol(struct inode *inode, struct file *file,
        case OBD_IOC_GETDTNAME:
        case OBD_IOC_GETMDNAME:
                RETURN(ll_get_obd_name(inode, cmd, uarg));
+       case OBD_IOC_GETUUID:
+               RETURN(ll_get_sb_uuid(inode, uarg));
        default:
                RETURN(-ENOTTY);
        }
@@ -4085,6 +4087,22 @@ int ll_get_obd_name(struct inode *inode, unsigned int cmd, void __user *uarg)
        RETURN(0);
 }
 
+/*
+ * Get sb uuid and copy out to user space
+ */
+int ll_get_sb_uuid(struct inode *inode, void __user *uarg)
+{
+       struct ll_sb_info *sbi = ll_i2sbi(inode);
+
+       ENTRY;
+
+       if (copy_to_user(uarg, sbi->ll_sb_uuid.uuid,
+                        sizeof(sbi->ll_sb_uuid.uuid)))
+               RETURN(-EFAULT);
+
+       RETURN(0);
+}
+
 struct dname_buf {
        struct work_struct db_work;
        struct dentry *db_dentry;
index 7ecec66..73d6d60 100755 (executable)
@@ -4321,10 +4321,7 @@ replay_barrier_nosync() {
 get_client_uuid() {
        local mntpnt=${1:-$MOUNT}
 
-       local name=$($LFS getname $mntpnt | cut -d' ' -f1)
-       local uuid=$($LCTL get_param -n llite.$name.uuid)
-
-       echo -n $uuid
+       echo -n $($LFS getname -u $mntpnt)
 }
 
 mds_evict_client() {
index 851bc80..a101f99 100755 (executable)
@@ -439,20 +439,21 @@ command_t cmdlist[] = {
        {"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) [for specified path only].\n"
-        "usage: check {mgts|osts|mdts|all} [path]"},
+        "usage: check {mgts|osts|mdts|all} [PATH]"},
        {"osts", lfs_osts, 0, "list OSTs connected to client "
-        "[for specified path only]\n" "usage: osts [path]"},
+        "[for specified path only]\n" "usage: osts [PATH]"},
        {"mdts", lfs_mdts, 0, "list MDTs connected to client "
-        "[for specified path only]\n" "usage: mdts [path]"},
+        "[for specified path only]\n" "usage: mdts [PATH]"},
        {"df", lfs_df, 0,
         "report filesystem disk space usage or inodes usage "
         "of each MDS and all OSDs or a batch belonging to a specific pool.\n"
         "Usage: df [--inodes|-i] [--human-readable|-h] [--lazy|-l]\n"
         "[--mdt|-m] [--ost|-o]\n"
-        "[--pool|-p <fsname>[.<pool>]] [path]"},
+        "[--pool|-p FSNAME[.POOL]] [PATH]"},
        {"getname", lfs_getname, 0,
         "list instances and specified mount points [for specified path only]\n"
-        "Usage: getname [--help|-h] [--instance|-i] [--fsname|-n] [path ...]"},
+        "Usage: getname [--help|-h] [--instance|-i] [--fsname|-n] [--uuid|-u]\n"
+        "               [PATH ...]"},
 #ifdef HAVE_SYS_QUOTA_H
        {"setquota", lfs_setquota, 0, "Set filesystem quotas.\n"
         "usage: setquota [-t] {-u|-U|-g|-G|-p|-P ID} {-b|-B|-i|-I LIMIT}\n"
@@ -8162,11 +8163,17 @@ static int lfs_df(int argc, char **argv)
 }
 
 static int print_instance(const char *mntdir, char *buf, size_t buflen,
-                         bool opt_instance, bool opt_fsname, bool opt_mntdir)
+                         bool opt_instance, bool opt_fsname, bool opt_uuid,
+                         bool opt_mntdir)
 {
+       struct obd_uuid uuid;
+       char *tmp = buf;
        int rc = 0;
 
-       if (opt_fsname == opt_instance) { /* both true or both false */
+       if (opt_uuid) {
+               rc = llapi_file_get_type_uuid(mntdir, CLI_TYPE, &uuid);
+               tmp = uuid.uuid;
+       } else if (opt_fsname == opt_instance) { /* both true or both false */
                rc = llapi_getname(mntdir, buf, buflen);
        } else if (opt_fsname) {
                /*
@@ -8186,9 +8193,9 @@ static int print_instance(const char *mntdir, char *buf, size_t buflen,
        }
 
        if (opt_mntdir)
-               printf("%s %s\n", buf, mntdir);
+               printf("%s %s\n", tmp, mntdir);
        else
-               printf("%s\n", buf);
+               printf("%s\n", tmp);
 
        return 0;
 }
@@ -8199,12 +8206,13 @@ static int lfs_getname(int argc, char **argv)
        { .val = 'h',   .name = "help",         .has_arg = no_argument },
        { .val = 'i',   .name = "instance",     .has_arg = no_argument },
        { .val = 'n',   .name = "fsname",       .has_arg = no_argument },
+       { .val = 'u',   .name = "uuid",         .has_arg = no_argument },
        { .name = NULL} };
-       bool opt_instance = false, opt_fsname = false;
-       char fsname[PATH_MAX] = "";
+       bool opt_instance = false, opt_fsname = false, opt_uuid = false;
+       char fsname[PATH_MAX] = { 0 };
        int rc = 0, rc2, c;
 
-       while ((c = getopt_long(argc, argv, "hin", long_opts, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "hinu", long_opts, NULL)) != -1) {
                switch (c) {
                case 'i':
                        opt_instance = true;
@@ -8212,6 +8220,9 @@ static int lfs_getname(int argc, char **argv)
                case 'n':
                        opt_fsname = true;
                        break;
+               case 'u':
+                       opt_uuid = true;
+                       break;
                default:
                        fprintf(stderr, "%s: unrecognized option '%s'\n",
                                progname, argv[optind - 1]);
@@ -8222,26 +8233,26 @@ static int lfs_getname(int argc, char **argv)
        }
 
        if (optind == argc) { /* no paths specified, get all paths. */
-               char mntdir[PATH_MAX] = "", path[PATH_MAX] = "";
+               char mntdir[PATH_MAX] = { 0 };
+               char path[PATH_MAX] = { 0 };
                int index = 0;
 
                while (!llapi_search_mounts(path, index++, mntdir, fsname)) {
                        rc2 = print_instance(mntdir, fsname, sizeof(fsname),
-                                            opt_instance, opt_fsname, true);
+                                            opt_instance, opt_fsname, opt_uuid,
+                                            true);
                        if (!rc)
                                rc = rc2;
                        path[0] = fsname[0] = mntdir[0] = '\0';
                }
        } else { /* paths specified, only attempt to search these. */
-               bool opt_mntdir;
+               bool opt_mntdir = ((argc - optind) != 1);
 
                /* if only one path is given, print only requested info */
-               opt_mntdir = argc - optind > 1 || (opt_instance == opt_fsname);
-
                for (; optind < argc; optind++) {
                        rc2 = print_instance(argv[optind], fsname,
                                             sizeof(fsname), opt_instance,
-                                            opt_fsname, opt_mntdir);
+                                            opt_fsname, opt_uuid, opt_mntdir);
                        if (!rc)
                                rc = rc2;
                        fsname[0] = '\0';
index 27f2de7..326b7ce 100644 (file)
@@ -490,37 +490,22 @@ int llapi_chomp_string(char *buf)
 }
 
 /*
- * Wrapper to grab parameter settings for lov.*-clilov-*.* values
+ * Wrapper to grab parameter settings for {lov,lmv}.*-clilov-*.* values
  */
-static int get_param_lov(const char *path, const char *param,
-                        char *buf, size_t buf_size)
+static int get_param_tgt(const char *path, enum tgt_type type,
+                        const char *param, char *buf, size_t buf_size)
 {
+       const char *typestr = type == LOV_TYPE ? "lov" : "lmv";
        struct obd_uuid uuid;
        int rc;
 
-       rc = llapi_file_get_lov_uuid(path, &uuid);
+       rc = llapi_file_get_type_uuid(path, type, &uuid);
        if (rc != 0)
                return rc;
 
-       return get_lustre_param_value("lov", uuid.uuid, FILTER_BY_EXACT, param,
-                                     buf, buf_size);
-}
-
-/*
- * Wrapper to grab parameter settings for lmv.*-clilov-*.* values
- */
-static int get_param_lmv(const char *path, const char *param,
-                        char *buf, size_t buf_size)
-{
-       struct obd_uuid uuid;
-       int rc;
-
-       rc = llapi_file_get_lmv_uuid(path, &uuid);
-       if (rc != 0)
-               return rc;
-
-       return get_lustre_param_value("lmv", uuid.uuid, FILTER_BY_EXACT, param,
-                              buf, buf_size);
+       rc = get_lustre_param_value(typestr, uuid.uuid, FILTER_BY_EXACT, param,
+                                   buf, buf_size);
+       return rc;
 }
 
 static int get_mds_md_size(const char *path)
@@ -544,7 +529,7 @@ static int get_mds_md_size(const char *path)
 
 int llapi_get_agent_uuid(char *path, char *buf, size_t bufsize)
 {
-       return get_param_lmv(path, "uuid", buf, bufsize);
+       return get_param_tgt(path, LMV_TYPE, "uuid", buf, bufsize);
 }
 
 /**
@@ -2268,10 +2253,52 @@ int llapi_file_get_lmv_uuid(const char *path, struct obd_uuid *lov_uuid)
        return rc;
 }
 
-enum tgt_type {
-       LOV_TYPE = 1,
-       LMV_TYPE
-};
+int llapi_file_fget_type_uuid(int fd, enum tgt_type type, struct obd_uuid *uuid)
+{
+       unsigned int cmd = 0;
+       int rc;
+
+       if (type == LOV_TYPE)
+               cmd = OBD_IOC_GETDTNAME;
+       else if (type == LMV_TYPE)
+               cmd = OBD_IOC_GETMDNAME;
+       else if (type == CLI_TYPE)
+               cmd = OBD_IOC_GETUUID;
+
+       rc = llapi_ioctl(fd, cmd, uuid);
+       if (rc) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc, "cannot get uuid");
+       }
+
+       return rc;
+}
+
+int llapi_file_get_type_uuid(const char *path, enum tgt_type type,
+                       struct obd_uuid *uuid)
+{
+       int fd, rc;
+
+       /* do not follow faked symlinks */
+       fd = open(path, O_RDONLY | O_NONBLOCK | O_NOFOLLOW);
+       if (fd < 0) {
+               /* real symlink should have failed with ELOOP so retry without
+                * O_NOFOLLOW just in case
+                */
+               fd = open(path, O_RDONLY | O_NONBLOCK);
+               if (fd < 0) {
+                       rc = -errno;
+                       llapi_error(LLAPI_MSG_ERROR, rc, "cannot open '%s'",
+                                   path);
+                       return rc;
+               }
+       }
+
+       rc = llapi_file_fget_type_uuid(fd, type, uuid);
+
+       close(fd);
+       return rc;
+}
 
 /*
  * If uuidp is NULL, return the number of available obd uuids.
@@ -2289,10 +2316,7 @@ static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp, int *indices,
        FILE *fp;
 
        /* Get the lov name */
-       if (type == LOV_TYPE)
-               rc = llapi_file_fget_lov_uuid(fd, &name);
-       else
-               rc = llapi_file_fget_lmv_uuid(fd, &name);
+       rc = llapi_file_fget_type_uuid(fd, type, &name);
        if (rc != 0)
                return rc;
 
@@ -2400,15 +2424,13 @@ static int setup_obd_uuid(int fd, char *dname, struct find_param *param)
        char format[32];
        int rc = 0;
        FILE *fp;
+       enum tgt_type type = param->fp_get_lmv ? LMV_TYPE : LOV_TYPE;
 
        if (param->fp_got_uuids)
                return rc;
 
        /* Get the lov/lmv name */
-       if (param->fp_get_lmv)
-               rc = llapi_file_fget_lmv_uuid(fd, &obd_uuid);
-       else
-               rc = llapi_file_fget_lov_uuid(fd, &obd_uuid);
+       rc = llapi_file_fget_type_uuid(fd, type, &obd_uuid);
        if (rc) {
                if (rc != -ENOTTY) {
                        llapi_error(LLAPI_MSG_ERROR, rc,
@@ -2492,10 +2514,7 @@ static int setup_indexes(int d, char *path, struct obd_uuid *obduuids,
        char buf[16];
        long i;
 
-       if (type == LOV_TYPE)
-               ret = get_param_lov(path, "numobd", buf, sizeof(buf));
-       else
-               ret = get_param_lmv(path, "numobd", buf, sizeof(buf));
+       ret = get_param_tgt(path, type, "numobd", buf, sizeof(buf));
        if (ret != 0)
                return ret;