Whamcloud - gitweb
LU-9767 utils: validate filesystem name for mkfs.lustre 70/28070/7
authorJames Simmons <uja.ornl@yahoo.com>
Mon, 21 Aug 2017 03:24:20 +0000 (23:24 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 28 Aug 2017 06:24:54 +0000 (06:24 +0000)
The patch "LU-6401 uapi: turn lustre_param.h into a proper
UAPI header" removed various user land functions used to
validate poolnames and file system names were removed. The
checks instead were enforced on the kernel side to ensure
any possible user land software directly interfacing to the
kernel wouldn't be able to break things badly. For the case
of formating the backend file system no kernel interaction
doesn't happen until it tries to mount the MDT/OST/MGT which
is very late in the process. So for this case lets add back
the file system name verification to mkfs.lustre to warn
users long before they try to mount anything.

Secondly we remove the verify_poolname() in lfs.c since
it duplicates extract_fsname_poolname() in obd.c. Their
is no need to do the same test twice. The function
pool_cmd() calls the ioctl for pool handling which in
turn returns an error code. Use this error code to notify
the user what mistake they did for their pool command.
For the MGS kernel code mgs_extract_fs_pool() was checking
MTI_NAME_MAXLEN instead of LUSTRE_MAXFSNAME. Also use
LUSTRE_MAXFSNAME instead of the raw number in the function
server_name2fsname() located in obd_mount.c.

Change-Id: If094644e56a70b6dd8e6b0378adc8736911aeef1
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-on: https://review.whamcloud.com/28070
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/mgs/mgs_handler.c
lustre/obdclass/obd_mount.c
lustre/utils/lfs.c
lustre/utils/mkfs_lustre.c
lustre/utils/obd.c

index 83c45d3..17c985a 100644 (file)
@@ -687,6 +687,8 @@ static inline char *obd_uuid2str(const struct obd_uuid *uuid)
        return (char *)(uuid->uuid);
 }
 
+#define LUSTRE_MAXFSNAME 8
+
 /* Extract fsname from uuid (or target name) of a target
    e.g. (myfs-OST0007_UUID -> myfs)
    see also deuuidify. */
index dc13c3d..d50b594 100644 (file)
@@ -762,7 +762,7 @@ static int mgs_extract_fs_pool(char *arg, char *fsname, char *poolname)
                return -EINVAL;
 
        /* or too long */
-       if (len > MTI_NAME_MAXLEN)
+       if (len > LUSTRE_MAXFSNAME)
                return -ENAMETOOLONG;
 
        strncpy(fsname, arg, len);
index 6388b87..362d8c1 100644 (file)
@@ -693,7 +693,7 @@ int server_name2fsname(const char *svname, char *fsname, const char **endptr)
 {
        const char *dash;
 
-       dash = svname + strnlen(svname, 8); /* max fsname length is 8 */
+       dash = svname + strnlen(svname, LUSTRE_MAXFSNAME);
        for (; dash > svname && *dash != '-' && *dash != ':'; dash--)
                ;
        if (dash == svname)
index d758248..36a67f3 100644 (file)
@@ -1009,23 +1009,6 @@ static int parse_targets(__u32 *osts, int size, int offset, char *arg)
        return rc < 0 ? rc : nr;
 }
 
-static int verify_pool_name(char *prog_name, char *pool_name)
-{
-       char *ptr;
-
-       if (pool_name == NULL)
-               return 0;
-
-       ptr = strchr(pool_name, '.');
-       if (ptr != NULL && ptr == pool_name) {
-               fprintf(stderr, "error: %s: fsname is empty in pool name '%s'\n",
-                       prog_name, pool_name);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 struct lfs_setstripe_args {
        unsigned long long       lsa_comp_end;
        unsigned long long       lsa_stripe_size;
@@ -1549,8 +1532,7 @@ static int lfs_setstripe(int argc, char **argv)
                                lsa.lsa_stripe_off = osts[0];
                        break;
                case 'p':
-                       result = verify_pool_name(argv[0], optarg);
-                       if (result)
+                       if (optarg == NULL)
                                goto error;
                        lsa.lsa_pool_name = optarg;
                        break;
index a9faace..0b48ad8 100644 (file)
@@ -62,7 +62,7 @@
 #include <ctype.h>
 #include <linux/lnet/nidstr.h>
 #include <linux/lnet/lnetctl.h>
-#include <linux/lustre/lustre_param.h>
+#include <linux/lustre/lustre_user.h>
 #include <linux/lustre/lustre_ver.h>
 
 #include "mount_utils.h"
@@ -518,9 +518,31 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
                        ldd->ldd_flags &= ~LDD_F_NEED_INDEX;
                        break;
                }
-               case 'L':
+               case 'L': {
+                       const char *tmp;
+                       size_t len;
+
+                       len = strlen(optarg);
+                       if (len < 1 || len > LUSTRE_MAXFSNAME) {
+                               fprintf(stderr, "%s: filesystem name must be "
+                                       "1-%d chars\n", progname, LUSTRE_MAXFSNAME);
+                               return 1;
+                       }
+
+                       for (tmp = optarg; *tmp != '\0'; ++tmp) {
+                               if (isalnum(*tmp) || *tmp == '_' || *tmp == '-')
+                                       continue;
+                               else
+                                       break;
+                       }
+                       if (*tmp != '\0') {
+                               fprintf(stderr, "%s: char '%c' not allowed in "
+                                       "filesystem name\n", progname, *tmp);
+                               return 1;
+                       }
                        strscpy(new_fsname, optarg, sizeof(new_fsname));
                        break;
+               }
                case 'm': {
                        char *nids = convert_hostnames(optarg);
 
index db5d248..33b67ca 100644 (file)
@@ -3149,8 +3149,24 @@ static int pool_cmd(enum lcfg_command_type cmd,
 out:
         if (rc)
                 rc = -errno;
+       switch (rc) {
+       case -ENAMETOOLONG:
+               fprintf(stderr, "error: %s: either the pool or file "
+                       "system name is too long (max pool name len "
+                       "is %d and file system name is %d)\n",
+                       jt_cmdname(cmdname), LOV_MAXPOOLNAME,
+                       LUSTRE_MAXFSNAME);
+               break;
+       case -EINVAL:
+               fprintf(stderr, "error: %s can contain only "
+                       "alphanumeric characters, underscores, and "
+                       "dashes besides the required '.'\n",
+                       jt_cmdname(cmdname));
+       default:
+               break;
+       }
        free(lcfg);
-        return rc;
+       return rc;
 }
 
 /**