Whamcloud - gitweb
b=19406
authorzhanghc <zhanghc>
Thu, 6 Aug 2009 11:21:19 +0000 (11:21 +0000)
committerzhanghc <zhanghc>
Thu, 6 Aug 2009 11:21:19 +0000 (11:21 +0000)
fix a bug in search_fsname which doesn't find
the correct mountpoint if there are sevearl Lustre
filesystems mounted within each other

i=adilger@sun.com

lustre/include/lustre/liblustreapi.h
lustre/utils/lfs.c
lustre/utils/liblustreapi.c

index 611f84c..85b84ec 100644 (file)
@@ -168,6 +168,8 @@ extern int llapi_get_obd_count(char *mnt, int *count, int is_mdt);
 extern int parse_size(char *optarg, unsigned long long *size,
                       unsigned long long *size_units, int bytes_spec);
 extern int llapi_path2fid(const char *path, lustre_fid *fid);
+extern int llapi_search_mounts(const char *pathname, int index,
+                               char *mntdir, char *fsname);
 extern int llapi_search_fsname(const char *pathname, char *fsname);
 extern void llapi_ping_target(char *obd_type, char *obd_name,
                               char *obd_uuid, void *args);
index ba1306e..3d1726f 100644 (file)
@@ -906,33 +906,21 @@ static int lfs_getstripe(int argc, char **argv)
 
 static int lfs_osts(int argc, char **argv)
 {
-        FILE *fp;
-        struct mntent *mnt = NULL;
+        char mntdir[PATH_MAX] = {'\0'};
         struct find_param param;
-        int rc=0;
+        int index = 0, rc=0;
 
         if (argc != 1)
                 return CMD_HELP;
 
-        fp = setmntent(MOUNTED, "r");
-
-        if (fp == NULL) {
-                 fprintf(stderr, "%s: setmntent(%s): %s:", argv[0], MOUNTED,
-                        strerror (errno));
-        } else {
-                mnt = getmntent(fp);
-                while (feof(fp) == 0 && ferror(fp) ==0) {
-                        memset(&param, 0, sizeof(param));
-                        if (llapi_is_lustre_mnt(mnt)) {
-                                rc = llapi_getstripe(mnt->mnt_dir, &param);
-                                if (rc)
-                                        fprintf(stderr,
-                                               "error: %s: failed on %s\n",
-                                               argv[0], mnt->mnt_dir);
-                        }
-                        mnt = getmntent(fp);
+        while (llapi_search_mounts(NULL, index++, mntdir, NULL) == 0) {
+                memset(&param, 0, sizeof(param));
+                rc = llapi_getstripe(mntdir, &param);
+                if (rc) {
+                        fprintf(stderr, "error: %s: failed on %s\n",
+                                argv[0], mntdir);
                 }
-                endmntent(fp);
+                memset(mntdir, 0, PATH_MAX);
         }
 
         return rc;
@@ -955,41 +943,6 @@ static int lfs_osts(int argc, char **argv)
 #define RSF     "%5s"
 #define RDF     "%4d%%"
 
-static int path2mnt(char *path, FILE *fp, char *mntdir, int dir_len)
-{
-        char rpath[PATH_MAX] = {'\0'};
-        struct mntent *mnt;
-        int rc, len, out_len = 0;
-
-        if (!realpath(path, rpath)) {
-                rc = -errno;
-                fprintf(stderr, "error: lfs df: invalid path '%s': %s\n",
-                        path, strerror(-rc));
-                return rc;
-        }
-
-        len = 0;
-        mnt = getmntent(fp);
-        while (feof(fp) == 0 && ferror(fp) == 0) {
-                if (llapi_is_lustre_mnt(mnt)) {
-                        len = strlen(mnt->mnt_dir);
-                        if (len > out_len &&
-                            !strncmp(rpath, mnt->mnt_dir, len)) {
-                                out_len = len;
-                                memset(mntdir, 0, dir_len);
-                                strncpy(mntdir, mnt->mnt_dir, dir_len);
-                        }
-                }
-                mnt = getmntent(fp);
-        }
-
-        if (out_len > 0)
-                return 0;
-
-        fprintf(stderr, "error: lfs df: %s isn't mounted on lustre\n", path);
-        return -EINVAL;
-}
-
 static int showdf(char *mntdir, struct obd_statfs *stat,
                   char *uuid, int ishow, int cooked,
                   char *type, int index, int rc)
@@ -1150,9 +1103,7 @@ static int mntdf(char *mntdir, int ishow, int cooked)
 
 static int lfs_df(int argc, char **argv)
 {
-        FILE *fp;
         char *path = NULL;
-        struct mntent *mnt = NULL;
         char *mntdir = NULL;
         int ishow = 0, cooked = 0;
         int c, rc = 0;
@@ -1173,14 +1124,6 @@ static int lfs_df(int argc, char **argv)
         if (optind < argc )
                 path = argv[optind];
 
-        fp = setmntent(MOUNTED, "r");
-        if (fp == NULL) {
-                rc = -errno;
-                fprintf(stderr, "error: %s: open %s failed( %s )\n",
-                        argv[0], MOUNTED, strerror(errno));
-                return rc;
-        }
-
         if ((mntdir = malloc(PATH_MAX)) == NULL) {
                 fprintf(stderr, "error: cannot allocate %d bytes\n",
                         PATH_MAX);
@@ -1189,28 +1132,28 @@ static int lfs_df(int argc, char **argv)
         memset(mntdir, 0, PATH_MAX);
 
         if (path) {
-                rc = path2mnt(path, fp, mntdir, PATH_MAX);
-                if (rc) {
-                        endmntent(fp);
-                        free(mntdir);
-                        return rc;
-                }
+                char rpath[PATH_MAX] = {'\0'};
 
-                rc = mntdf(mntdir, ishow, cooked);
-                printf("\n");
-                endmntent(fp);
-        } else {
-                mnt = getmntent(fp);
-                while (feof(fp) == 0 && ferror(fp) == 0) {
-                        if (llapi_is_lustre_mnt(mnt)) {
-                                rc = mntdf(mnt->mnt_dir, ishow, cooked);
-                                if (rc)
-                                        break;
+                if (!realpath(path, rpath)) {
+                        rc = -errno;
+                        fprintf(stderr, "error: invalid path '%s': %s\n",
+                                        path, strerror(-rc));
+                } else {
+                        rc = llapi_search_mounts(rpath, 0, mntdir, NULL);
+                        if (rc == 0 && mntdir[0] != '\0') {
+                                rc = mntdf(mntdir, ishow, cooked);
                                 printf("\n");
                         }
-                        mnt = getmntent(fp);
                 }
-                endmntent(fp);
+        } else {
+                int index = 0;
+
+                while (llapi_search_mounts(NULL, index++, mntdir, NULL) == 0) {
+                        rc = mntdf(mntdir, ishow, cooked);
+                        if (rc)
+                                break;
+                        printf("\n");
+                }
         }
 
         free(mntdir);
@@ -1220,8 +1163,7 @@ static int lfs_df(int argc, char **argv)
 static int lfs_check(int argc, char **argv)
 {
         int rc;
-        FILE *fp;
-        struct mntent *mnt = NULL;
+        char mntdir[PATH_MAX] = {'\0'};
         int num_types = 1;
         char *obd_types[2];
         char obd_type1[4];
@@ -1247,27 +1189,14 @@ static int lfs_check(int argc, char **argv)
                         return CMD_HELP;
         }
 
-        fp = setmntent(MOUNTED, "r");
-        if (fp == NULL) {
-                 fprintf(stderr, "setmntent(%s): %s:", MOUNTED,
-                        strerror (errno));
-        } else {
-                mnt = getmntent(fp);
-                while (feof(fp) == 0 && ferror(fp) ==0) {
-                        if (llapi_is_lustre_mnt(mnt))
-                                break;
-                        mnt = getmntent(fp);
-                }
-                endmntent(fp);
-        }
-
-        if (!mnt) {
+        rc = llapi_search_mounts(NULL, 0, mntdir, NULL);
+        if (rc < 0 || mntdir[0] == '\0') {
                 fprintf(stderr, "No suitable Lustre mount found\n");
-                return -1;
+                return rc;
         }
 
         rc = llapi_target_iterate(num_types, obd_types,
-                                  mnt->mnt_dir, llapi_ping_target);
+                                  mntdir, llapi_ping_target);
 
         if (rc)
                 fprintf(stderr, "error: %s: %s status failed\n",
@@ -1279,8 +1208,7 @@ static int lfs_check(int argc, char **argv)
 
 static int lfs_catinfo(int argc, char **argv)
 {
-        FILE *fp;
-        struct mntent *mnt = NULL;
+        char mntdir[PATH_MAX] = {'\0'};
         int rc;
 
         if (argc < 2 || (!strcmp(argv[1],"config") && argc < 3))
@@ -1289,25 +1217,12 @@ static int lfs_catinfo(int argc, char **argv)
         if (strcmp(argv[1], "config") && strcmp(argv[1], "deletions"))
                 return CMD_HELP;
 
-        fp = setmntent(MOUNTED, "r");
-        if (fp == NULL) {
-                 fprintf(stderr, "setmntent(%s): %s:", MOUNTED,
-                         strerror(errno));
-        } else {
-                mnt = getmntent(fp);
-                while (feof(fp) == 0 && ferror(fp) == 0) {
-                        if (llapi_is_lustre_mnt(mnt))
-                                break;
-                        mnt = getmntent(fp);
-                }
-                endmntent(fp);
-        }
-
-        if (mnt) {
+        rc = llapi_search_mounts(NULL, 0, mntdir, NULL);
+        if (rc == 0 && mntdir[0] != '\0') {
                 if (argc == 3)
-                        rc = llapi_catinfo(mnt->mnt_dir, argv[1], argv[2]);
+                        rc = llapi_catinfo(mntdir, argv[1], argv[2]);
                 else
-                        rc = llapi_catinfo(mnt->mnt_dir, argv[1], NULL);
+                        rc = llapi_catinfo(mntdir, argv[1], NULL);
         } else {
                 fprintf(stderr, "no lustre_lite mounted.\n");
                 rc = -1;
index be8c444..1532078 100644 (file)
@@ -380,13 +380,16 @@ int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
 #define WANT_PATH   0x1
 #define WANT_FSNAME 0x2
 #define WANT_FD     0x4
-static int get_root_path(int want, char *fsname, int *outfd, char *path)
+#define WANT_INDEX  0x8
+#define WANT_ERROR  0x10
+static int get_root_path(int want, char *fsname, int *outfd, char *path,
+                         int index)
 {
         struct mntent mnt;
-        char buf[PATH_MAX];
-        char *ptr;
+        char buf[PATH_MAX], mntdir[PATH_MAX];
+        char *name = NULL, *ptr;
         FILE *fp;
-        int fd;
+        int idx = 0, len = 0, mntlen, fd;
         int rc = -ENODEV;
 
         /* get the mount point */
@@ -404,27 +407,47 @@ static int get_root_path(int want, char *fsname, int *outfd, char *path)
                 if (!llapi_is_lustre_mnt(&mnt))
                         continue;
 
+                mntlen = strlen(mnt.mnt_dir);
                 ptr = strrchr(mnt.mnt_fsname, '/');
-                if (!ptr) {
+                if (!ptr && !len) {
                         rc = -EINVAL;
                         break;
                 }
                 ptr++;
 
-                /* If path was specified and matches, store the fsname */
-                if ((want & WANT_FSNAME) && (strcmp(mnt.mnt_dir, path) == 0))
-                        strcpy(fsname, ptr);
-                /* Else check the fsname for a match */
-                else if (strcmp(ptr, fsname) != 0)
+                if ((want & WANT_INDEX) && (idx++ != index))
+                        continue; 
+
+                /* Check the fsname for a match */
+                if (!(want & WANT_FSNAME) && fsname != NULL &&
+                    (strlen(fsname) > 0) && (strcmp(ptr, fsname) != 0))
                         continue;
 
-                /* Found it */
-                rc = 0;
-                if (want & WANT_PATH)
-                        strcpy(path, mnt.mnt_dir);
+                /* If the path isn't set return the first one we find */
+                if (path == NULL || strlen(path) == 0) {
+                        strcpy(mntdir, mnt.mnt_dir);
+                        name = ptr;
+                        rc = 0;
+                        break;
+                /* Otherwise find the longest matching path */
+                } else if ((strlen(path) >= mntlen) && (mntlen >= len) &&
+                           (strncmp(mnt.mnt_dir, path, mntlen) == 0)) { 
+                        strcpy(mntdir, mnt.mnt_dir);
+                        mntlen = len;
+                        name = ptr;
+                        rc = 0;
+                }
+        }
+        endmntent(fp);
+
+        /* Found it */
+        if (rc == 0) {
+                if ((want & WANT_FSNAME) && fsname != NULL)
+                        strcpy(fsname, name);
+                if ((want & WANT_PATH) && path != NULL)
+                        strcpy(path, mntdir);
                 if (want & WANT_FD) {
-                        fd = open(mnt.mnt_dir,
-                                  O_RDONLY | O_DIRECTORY | O_NONBLOCK);
+                        fd = open(mntdir, O_RDONLY | O_DIRECTORY | O_NONBLOCK);
                         if (fd < 0) {
                                 perror("open");
                                 rc = -errno;
@@ -432,19 +455,45 @@ static int get_root_path(int want, char *fsname, int *outfd, char *path)
                                 *outfd = fd;
                         }
                 }
-                break;
-        }
-        endmntent(fp);
-        if (rc)
+        } else if (want & WANT_ERROR)
                 llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
                           "can't find fs root for '%s': %d",
                           (want & WANT_PATH) ? fsname : path, rc);
         return rc;
 }
 
+/*
+ * search lustre mounts
+ *
+ * Calling this function will return to the user the mount point, mntdir, and
+ * the file system name, fsname, if the user passed a buffer to this routine.
+ *
+ * The user inputs are pathname and index. If the pathname is supplied then
+ * the value of the index will be ignored. The pathname will return data if
+ * the pathname is located on a lustre mount. Index is used to pick which
+ * mount point you want in the case of multiple mounted lustre file systems.
+ * See function lfs_osts in lfs.c for a example of the index use.
+ */
+int llapi_search_mounts(const char *pathname, int index, char *mntdir,
+                        char *fsname)
+{
+        int want = WANT_PATH, idx = -1;
+
+        if (!pathname) {
+                want |= WANT_INDEX;
+                idx = index;
+        } else
+                strcpy(mntdir, pathname);
+
+        if (fsname)
+                want |= WANT_FSNAME;
+        return get_root_path(want, fsname, NULL, mntdir, idx);
+}
+
 int llapi_search_fsname(const char *pathname, char *fsname)
 {
-        return get_root_path(WANT_FSNAME, fsname, NULL, (char *)pathname);
+        return get_root_path(WANT_FSNAME | WANT_ERROR, fsname, NULL,
+                             (char *)pathname, -1);
 }
 
 /* return the first file matching this pattern */
@@ -477,7 +526,7 @@ static int poolpath(char *fsname, char *pathname, char *pool_pathname)
         char buffer[PATH_MAX];
 
         if (fsname == NULL) {
-                rc = get_root_path(WANT_FSNAME, buffer, NULL, pathname);
+                rc = llapi_search_fsname(pathname, buffer);
                 if (rc != 0)
                         return rc;
                 fsname = buffer;
@@ -2606,7 +2655,7 @@ int llapi_changelog_start(void **priv, int flags, const char *device,
         int rc, fd;
 
         if (device[0] == '/')
-                rc = get_root_path(WANT_FSNAME, mdtname, NULL, (char *)device);
+                rc = llapi_search_fsname(device, mdtname);
         else
                 strncpy(mdtname, device, sizeof(mdtname));
 
@@ -2759,7 +2808,7 @@ int llapi_changelog_clear(const char *mdtname, const char *idstr,
                 ptr = fsname + strlen(fsname) - 8;
                 *ptr = '\0';
                 index = strtol(ptr + 4, NULL, 10);
-                rc = get_root_path(WANT_FD, fsname, &fd, NULL);
+                rc = get_root_path(WANT_FD | WANT_ERROR, fsname, &fd, NULL, -1);
         }
         if (rc < 0) {
                 llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
@@ -2801,7 +2850,8 @@ int llapi_fid2path(const char *device, const char *fidstr, char *buf,
         if (device[0] == '/') {
                 strcpy(path, device);
         } else {
-                rc = get_root_path(WANT_PATH, (char *)device, NULL, path);
+                rc = get_root_path(WANT_PATH | WANT_ERROR, (char *)device,
+                                   NULL, path, -1);
                 if (rc < 0)
                         return rc;
         }