Whamcloud - gitweb
LU-12521 llapi: add separate fsname and instance API 51/35451/10
authorAndreas Dilger <adilger@whamcloud.com>
Tue, 9 Jul 2019 18:47:19 +0000 (12:47 -0600)
committerOleg Drokin <green@whamcloud.com>
Thu, 23 Jan 2020 05:31:04 +0000 (05:31 +0000)
The llapi_getname() function returns the combined fsname and client
instance as one string, which is fine when using the entire string,
but the output cannot be safely parsed into separate fsname and
instance strings in all cases.

Introduce new llapi_get_fsname() and llapi_get_instance() functions
that return only the fsname and instance strings, since the source
string returned from the kernel can be unambiguously separated before
it is returned in a combined string via llapi_getname().

Fix the lfs_getname() '-n' and '-i' options to use the new routines
rather than parsing the output from llapi_getname().

Add man pages for these functions.

Fixes: 2a4821b836c8 ("LU-12159 utils: improve lfs getname functionality")
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: Iaf5846a0ae147a428f66ec8a1d0251e7e12540e5
Reviewed-on: https://review.whamcloud.com/35451
Reviewed-by: Olaf Faaland-LLNL <faaland1@llnl.gov>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
13 files changed:
lustre/doc/Makefile.am
lustre/doc/lfs-getname.1
lustre/doc/llapi_get_fsname.3 [new file with mode: 0644]
lustre/doc/llapi_get_fsname_instance.3 [new file with mode: 0644]
lustre/doc/llapi_get_instance.3 [new file with mode: 0644]
lustre/doc/llapi_getname.3 [new file with mode: 0644]
lustre/include/lustre/lustreapi.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/llite_lib.c
lustre/obdclass/obd_config.c
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/liblustreapi_util.c

index 2c5bb47..03a83a6 100644 (file)
@@ -85,10 +85,14 @@ MANFILES =                                  \
        llapi_file_create_foreign.3             \
        llapi_file_get_stripe.3                 \
        llapi_file_open.3                       \
+       llapi_get_fsname.3                      \
+       llapi_get_fsname_instance.3             \
+       llapi_get_instance.3                    \
        llapi_get_lum_dir.3                     \
        llapi_get_lum_dir_fd.3                  \
        llapi_get_lum_file.3                    \
-       llapi_get_lum_file_fd.3         \
+       llapi_get_lum_file_fd.3                 \
+       llapi_getname.3                         \
        llapi_group_lock.3                      \
        llapi_group_unlock.3                    \
        llapi_heat_get.3                        \
index dd43fb2..d5974aa 100644 (file)
@@ -30,14 +30,20 @@ is used with a single
 .I pathname
 then the instance ID is printed without the mountpoint.
 .SH EXAMPLES
-.TP
 .B $ lfs getname
+.br
 myth-ffff880428703400 /myth
 .br
 testfs-ffff937009271000 /mnt/testfs
-.TP
+.P
 .B $ lfs getname -n /mnt/testfs
+.br
 testfs
+.P
+.B $ lfs getname -i /mnt/testfs
+.br
+ffff937009271000
 .SH SEE ALSO
 .BR lfs (1),
+.BR llapi_getname (3),
 .BR lustre (7)
diff --git a/lustre/doc/llapi_get_fsname.3 b/lustre/doc/llapi_get_fsname.3
new file mode 100644 (file)
index 0000000..b594ff7
--- /dev/null
@@ -0,0 +1 @@
+.so man3/llapi_get_fsname_instance.3
diff --git a/lustre/doc/llapi_get_fsname_instance.3 b/lustre/doc/llapi_get_fsname_instance.3
new file mode 100644 (file)
index 0000000..180bcaa
--- /dev/null
@@ -0,0 +1,97 @@
+.TH lustreapi 3 "2019 Jul 10" "Lustre User API"
+.SH NAME
+llapi_get_fsname_instance - get the client filesystem name and instance
+.br
+llapi_get_fsname - get the filesystem fsname from path
+.br
+llapi_get_instance - get the client filesystem instance from path
+.br
+llapi_getname - get the client filesystem identifier from path
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/stat.h>
+.B #include <fcntl.h>
+.B #include <lustre/lustreapi.h>
+.sp
+.BI "int llapi_getname(const char *" path ", char *" name ", size_t " namelen );
+.sp
+.BI "int llapi_get_fsname_instance(const char *" path ", char *" fsname ,
+.BI                                    size_t " fsname_len" ", char *" instance ,
+.BI                                    size_t " instance_len" );
+.sp
+.BI "int llapi_get_fsname(const char *" path ", char *" fsname ,
+.BI                                    size_t " fsname_len" );
+.sp
+.BI "int llapi_get_instance(const char *" path ", char *" instance ,
+.BI                                    size_t " instance_len" );
+.SH DESCRIPTION
+.LP
+.B llapi_get_fsname_instance()
+retrieves the filesystem fsname and instance for the specified
+.I path
+and stores them in the
+.I fsname
+and
+.I instance
+buffers respectively, each of which can respectively hold at least
+.I fsname_len
+(at least
+.B LUSTRE_MAXFSNAME
+bytes), and
+.I instance_len
+(at least
+.B LUSTRE_MAXINSTANCE
+bytes).
+If only the fsname or instance identifier is needed, then the respective
+.BR llapi_get_fsname (3)
+or
+.BR llapi_get_instance (3)
+function can be used.  The
+.BR llapi_getname (3)
+function returns the combined
+.IR fsname - instance
+string.
+.P
+The filesystem
+.I fsname
+is a short name like
+.RB ' testfs '
+or
+.RB ' lfs2g '
+used to identify the filesystem on the clients and servers for mounting
+and configuration.  The
+.I instance
+is a client-unique temporary identifier like
+.RB ' ffff8803c9c0f000 '
+that differentiates multiple mounts of the same filesystem on the same
+client.  The instance is not guaranteed to be unique between different clients,
+nor is it expected to be the same for repeated mounts on the same client.
+.P
+The filesystem identifier is used in client-side parameters, like
+.BI mdc. fsname -MDT0000-mdc- instance .max_rpcs_in_flight
+for MDC and OSC devices, or
+.BI llite. fsname - instance .max_cached_mb
+and similar for llite tunable values and statistics.
+.SH RETURN VALUES
+.TP
+.B 0
+on success, or
+.TP
+-ve
+error code on failure and sets errno appropriately.
+.SH ERRORS
+.TP 15
+.SM EINVAL
+Invalid filesystem information found.
+.TP
+.SM ENAMETOOLONG
+The
+.IR fsname_len ,
+.IR instance_len ,
+or
+.I namelen
+buffer length was not large enough to hold the string.
+.SH SEE ALSO
+.BR lfs-getname (1),
+.BR lustreapi (7)
diff --git a/lustre/doc/llapi_get_instance.3 b/lustre/doc/llapi_get_instance.3
new file mode 100644 (file)
index 0000000..b594ff7
--- /dev/null
@@ -0,0 +1 @@
+.so man3/llapi_get_fsname_instance.3
diff --git a/lustre/doc/llapi_getname.3 b/lustre/doc/llapi_getname.3
new file mode 100644 (file)
index 0000000..3dda6e5
--- /dev/null
@@ -0,0 +1 @@
+.so man3/llapi_get_fsname_instance.3
\ No newline at end of file
index 5efe265..8db1450 100644 (file)
@@ -404,7 +404,11 @@ int llapi_parse_size(const char *optarg, unsigned long long *size,
 int llapi_search_mounts(const char *pathname, int index, char *mntdir,
                        char *fsname);
 int llapi_search_fsname(const char *pathname, char *fsname);
-int llapi_getname(const char *path, char *buf, size_t size);
+int llapi_get_fsname_instance(const char *path, char *fsname, size_t fsname_len,
+                             char *instance, size_t instance_len);
+int llapi_get_instance(const char *path, char *instance, size_t instance_len);
+int llapi_get_fsname(const char *path, char *fsname, size_t fsname_len);
+int llapi_getname(const char *path, char *name, size_t namelen);
 int llapi_search_fileset(const char *pathname, char *fileset);
 
 int llapi_search_rootpath(char *pathname, const char *fsname);
index f90725a..7b694fc 100644 (file)
@@ -1146,6 +1146,7 @@ static inline char *obd_uuid2str(const struct obd_uuid *uuid)
 }
 
 #define LUSTRE_MAXFSNAME 8
+#define LUSTRE_MAXINSTANCE 16
 
 /* Extract fsname from uuid (or target name) of a target
    e.g. (myfs-OST0007_UUID -> myfs)
index 6bd2032..cda5ee0 100644 (file)
@@ -1060,7 +1060,7 @@ int ll_fill_super(struct super_block *sb)
        char    *profilenm = get_profile_name(sb);
        struct config_llog_instance *cfg;
        /* %p for void* in printf needs 16+2 characters: 0xffffffffffffffff */
-       const int instlen = 16 + 2;
+       const int instlen = LUSTRE_MAXINSTANCE + 2;
        unsigned long cfg_instance = ll_get_cfg_instance(sb);
        char name[MAX_STRING_SIZE];
        int md_len = 0;
index 7ca2643..e7457ff 100644 (file)
@@ -1766,7 +1766,8 @@ int class_config_llog_handler(const struct lu_env *env,
                if (cfg->cfg_instance &&
                    lcfg->lcfg_command != LCFG_SPTLRPC_CONF &&
                    LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
-                       inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) + 16 + 4;
+                       inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
+                               LUSTRE_MAXINSTANCE + 4;
                        OBD_ALLOC(inst_name, inst_len);
                        if (!inst_name)
                                GOTO(out, rc = -ENOMEM);
index 2edb399..da2477e 100644 (file)
@@ -6203,43 +6203,33 @@ static int lfs_df(int argc, char **argv)
        return rc;
 }
 
-static int print_instance(const char *mntdir, char *fsname, size_t fsnamelen,
+static int print_instance(const char *mntdir, char *buf, size_t buflen,
                          bool opt_instance, bool opt_fsname, bool opt_mntdir)
 {
-       char *buf = fsname;
-
-       /* llapi_search_mounts() fills "fsname", but that is not called if
-        * explicit paths are specified on the command-line
-        */
-       if (opt_instance || (opt_fsname && fsname[0] == '\0')) {
-               int rc = llapi_getname(mntdir, fsname, fsnamelen);
+       int rc = 0;
 
-               if (rc < 0) {
-                       fprintf(stderr, "cannot get instance for '%s': %s\n",
-                               mntdir, strerror(-rc));
-                       return rc;
-               }
-               buf = fsname;
-               if (!opt_instance) {
-                       /* print only the fsname name */
-                       buf = strchr(fsname, '-');
-                       if (buf)
-                               *buf = '\0';
-                       buf = fsname;
-               } else if (!opt_fsname) {
-                       /* print only the instance name */
-                       buf = strchr(fsname, '-');
-                       if (buf)
-                               buf++;
-                       else
-                               buf = fsname;
-               }
+       if (opt_fsname == opt_instance) { /* both true or both false */
+               rc = llapi_getname(mntdir, buf, buflen);
        } else if (opt_fsname) {
-               /* print only the fsname */
-               buf = fsname;
+               /* llapi_search_mounts() fills @buf with fsname, but that is not
+                * called if explicit paths are specified on the command-line
+                */
+               if (buf[0] == '\0')
+                       rc = llapi_get_fsname(mntdir, buf, buflen);
+       } else /* if (opt_instance) */ {
+               rc = llapi_get_instance(mntdir, buf, buflen);
+       }
+
+       if (rc < 0) {
+               fprintf(stderr, "cannot get instance for '%s': %s\n",
+                       mntdir, strerror(-rc));
+               return rc;
        }
 
-       printf("%s %s\n", buf, opt_mntdir ? mntdir : "");
+       if (opt_mntdir)
+               printf("%s %s\n", buf, mntdir);
+       else
+               printf("%s\n", buf);
 
        return 0;
 }
@@ -6269,10 +6259,6 @@ static int lfs_getname(int argc, char **argv)
                }
        }
 
-       /* If neither option is given, print both instance and fsname */
-       if (!opt_instance && !opt_fsname)
-               opt_instance = opt_fsname = true;
-
        if (optind == argc) { /* no paths specified, get all paths. */
                char mntdir[PATH_MAX] = "", path[PATH_MAX] = "";
                int index = 0;
index 4238208..96d5aa2 100644 (file)
@@ -1475,40 +1475,6 @@ int llapi_search_rootpath(char *pathname, const char *fsname)
        return get_root_path(WANT_PATH, (char *)fsname, NULL, pathname, -1);
 }
 
-int llapi_getname(const char *path, char *buf, size_t size)
-{
-       struct obd_uuid uuid_buf;
-       char *uuid = uuid_buf.uuid;
-       char *cfg_instance;
-       int rc, len, fsname_len;
-
-       memset(&uuid_buf, 0, sizeof(uuid_buf));
-       rc = llapi_file_get_lov_uuid(path, &uuid_buf);
-       if (rc)
-               return rc;
-
-       /*
-        * We want to turn testfs-clilov-ffff88002738bc00 into
-        * testfs-ffff88002738bc00 in a portable way that doesn't depend
-        * on what is after "-clilov-" as it may change in the future.
-        * Unfortunately, the "fsname" part may contain a dash, so we
-        * can't just skip to the first dash, and the "instance" may be a
-        * UUID in the future, so we can't necessarily go to the last dash.
-        */
-       cfg_instance = strstr(uuid, "-clilov-");
-       if (!cfg_instance)
-               return -EINVAL;
-
-       fsname_len = cfg_instance - uuid;
-       cfg_instance += strlen("-clilov-");
-       len = snprintf(buf, size, "%.*s-%s", fsname_len, uuid, cfg_instance);
-
-       if (len >= size)
-               rc = -ENAMETOOLONG;
-
-       return rc;
-}
-
 /**
  * Get the list of pool members.
  * \param poolname    string of format \<fsname\>.\<poolname\>
index 59f7e98..c19674e 100644 (file)
@@ -311,3 +311,79 @@ retry_open:
 
        return rc ? -errno : 0;
 }
+
+int llapi_get_fsname_instance(const char *path, char *fsname, size_t fsname_len,
+                             char *instance, size_t instance_len)
+{
+       struct obd_uuid uuid_buf;
+       char *uuid = uuid_buf.uuid;
+       char *ptr;
+       int rc;
+
+       memset(&uuid_buf, 0, sizeof(uuid_buf));
+       rc = llapi_file_get_lov_uuid(path, &uuid_buf);
+       if (rc)
+               return rc;
+
+       /*
+        * We want to turn fs-foo-clilov-ffff88002738bc00 into 'fs-foo' and
+        * 'ffff88002738bc00' in a portable way that doesn't depend on what is
+        * after "-clilov-" as it may change to a UUID string in the future.
+        * Unfortunately, the "fsname" part may contain a dash, so we can't
+        * just skip to the first dash, and if the "instance" is a UUID in the
+        * future we can't necessarily go to the last dash either.
+        */
+       ptr = strstr(uuid, "-clilov-");
+       if (!ptr || (!fsname && !instance)) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       *ptr = '\0';
+       ptr += strlen("-clilov-");
+       if (instance) {
+               snprintf(instance, instance_len, "%s", ptr);
+               if (strlen(ptr) >= instance_len)
+                       rc = -ENAMETOOLONG;
+       }
+
+       if (fsname) {
+               snprintf(fsname, fsname_len, "%s", uuid);
+               if (strlen(uuid) >= fsname_len)
+                       rc = -ENAMETOOLONG;
+       }
+
+out:
+       errno = -rc;
+       return rc;
+}
+
+int llapi_getname(const char *path, char *name, size_t namelen)
+{
+       char fsname[16];
+       char instance[40];
+       int rc;
+
+       rc = llapi_get_fsname_instance(path, fsname, sizeof(fsname),
+                                      instance, sizeof(instance));
+       if (rc)
+               return rc;
+
+       snprintf(name, namelen, "%s-%s", fsname, instance);
+       if (strlen(fsname) + 1 + strlen(instance) >= namelen) {
+               rc = -ENAMETOOLONG;
+               errno = -rc;
+       }
+
+       return rc;
+}
+
+int llapi_get_instance(const char *path, char *instance, size_t instance_len)
+{
+       return llapi_get_fsname_instance(path, NULL, 0, instance, instance_len);
+}
+
+int llapi_get_fsname(const char *path, char *fsname, size_t fsname_len)
+{
+       return llapi_get_fsname_instance(path, fsname, fsname_len, NULL, 0);
+}