From d33fff49a1d5a6c0833697476c8493e01beffd86 Mon Sep 17 00:00:00 2001 From: zhanghc Date: Thu, 6 Aug 2009 11:21:19 +0000 Subject: [PATCH] b=19406 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 | 2 + lustre/utils/lfs.c | 159 ++++++++--------------------------- lustre/utils/liblustreapi.c | 100 ++++++++++++++++------ 3 files changed, 114 insertions(+), 147 deletions(-) diff --git a/lustre/include/lustre/liblustreapi.h b/lustre/include/lustre/liblustreapi.h index 611f84c..85b84ec7 100644 --- a/lustre/include/lustre/liblustreapi.h +++ b/lustre/include/lustre/liblustreapi.h @@ -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); diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index ba1306e..3d1726f 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -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(¶m, 0, sizeof(param)); - if (llapi_is_lustre_mnt(mnt)) { - rc = llapi_getstripe(mnt->mnt_dir, ¶m); - 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(¶m, 0, sizeof(param)); + rc = llapi_getstripe(mntdir, ¶m); + 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; diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index be8c444..1532078 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -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; } -- 1.8.3.1