Whamcloud - gitweb
LU-5030 utils: migrate most lustre utils to use cfs_get_paths() 62/17462/14
authorJames Simmons <uja.ornl@yahoo.com>
Mon, 18 Jan 2016 14:39:43 +0000 (09:39 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 25 Jan 2016 01:57:25 +0000 (01:57 +0000)
Move all the lustre test applications and utilities
except for the code to handle lctl [s|get]_param
to use cfs_get_paths() instead of accessing the
proc file system directly. This automatically
enables support for sysfs used in the upstream
client.

Change-Id: Iecb4a269c00ac8a5e0633d69d0370e9881ee6e33
Signed-off-by: Dmitry Eremin <dmitry.eremin@intel.com>
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Signed-off-by: Wang Chao <chao.ornl@gmail.com>
Reviewed-on: http://review.whamcloud.com/17462
Tested-by: Jenkins
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/tests/Makefile.am
lustre/tests/ll_dirstripe_verify.c
lustre/tests/llapi_hsm_test.c
lustre/tests/mmap_sanity.c
lustre/utils/gss/Makefile.am
lustre/utils/gss/gssd_proc.c
lustre/utils/gss/lgss_keyring.c
lustre/utils/l_getidentity.c
lustre/utils/obd.c

index ec096ad..07e5dcf 100644 (file)
@@ -88,6 +88,7 @@ nobase_test_DATA = $(nobase_noinst_DATA)
 endif # TESTS
 
 mmap_sanity_SOURCES= mmap_sanity.c
+mmap_sanity_LDADD=$(LIBCFS)
 
 multiop_LDADD=$(LIBLUSTREAPI) $(LIBCFS) $(PTHREAD_LIBS)
 llapi_layout_test_LDADD=$(LIBLUSTREAPI)
index f3de1db..0cdddeb 100644 (file)
 #include <errno.h>
 #include <dirent.h>
 
+#include <libcfs/util/param.h>
 #include <lustre/lustreapi.h>
 
 #define MAX_LOV_UUID_COUNT      1000
-union {
-        struct obd_uuid uuid;
-        char name[0];
-} lov;
-#define lov_uuid lov.uuid
-#define lov_name lov.name
 
 /* Returns bytes read on success and a negative value on failure.
  * If zero bytes are read it will be treated as failure as such
@@ -96,44 +91,33 @@ int read_proc_entry(char *proc_path, char *buf, int len)
        return rc;
 }
 
-int compare(struct lov_user_md *lum_dir, struct lov_user_md *lum_file1,
-            struct lov_user_md *lum_file2)
+int compare(struct obd_uuid *puuid, struct lov_user_md *lum_dir,
+           struct lov_user_md *lum_file1, struct lov_user_md *lum_file2)
 {
-        int stripe_count = 0, min_stripe_count = 0, def_stripe_count = 1;
-        int stripe_size = 0;
-        int stripe_offset = -1;
-        int ost_count;
-        char buf[128];
-        char lov_path[PATH_MAX];
-        char tmp_path[PATH_MAX];
-        int i;
-        FILE *fp;
-
-       fp = popen("\\ls -d  /proc/fs/lustre/lov/*clilov* | head -1", "r");
-       if (fp == NULL) {
-               llapi_error(LLAPI_MSG_ERROR, -errno,
-                           "open(lustre/lov/*clilov*) failed");
+       int stripe_count = 0, min_stripe_count = 0, def_stripe_count = 1;
+       int stripe_size = 0;
+       int stripe_offset = -1;
+       int ost_count;
+       char buf[128];
+       glob_t path;
+       int i;
+
+       if (cfs_get_param_paths(&path, "lov/%s/stripecount", puuid->uuid) != 0)
                return 2;
-        }
-
-       if (fscanf(fp, "%s", lov_path) < 1) {
-               llapi_error(LLAPI_MSG_ERROR, -EINVAL,
-                           "read(lustre/lov/*clilov*) failed");
-               pclose(fp);
-               return 3;
-       }
-
-        pclose(fp);
-
-        snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/stripecount",
-                 lov_path);
-        if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
+       if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
+               cfs_free_param_data(&path);
                 return 5;
-        def_stripe_count = (short)atoi(buf);
+       }
+       cfs_free_param_data(&path);
+       def_stripe_count = (short)atoi(buf);
 
-        snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/numobd", lov_path);
-        if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
+       if (cfs_get_param_paths(&path, "lov/%s/numobd", puuid->uuid) != 0)
+               return 2;
+       if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
+               cfs_free_param_data(&path);
                 return 6;
+       }
+       cfs_free_param_data(&path);
         ost_count = atoi(buf);
 
         if (lum_dir == NULL) {
@@ -175,10 +159,14 @@ int compare(struct lov_user_md *lum_dir, struct lov_user_md *lum_file1,
         if (lum_dir != NULL)
                 stripe_size = (int)lum_dir->lmm_stripe_size;
         if (stripe_size == 0) {
-                snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/stripesize",
-                         lov_path);
-                if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
-                        return 5;
+               if (cfs_get_param_paths(&path, "lov/%s/stripesize",
+                                       puuid->uuid) != 0)
+                       return 2;
+               if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
+                       cfs_free_param_data(&path);
+                       return 5;
+               }
+               cfs_free_param_data(&path);
 
                 stripe_size = atoi(buf);
         }
@@ -221,17 +209,17 @@ int compare(struct lov_user_md *lum_dir, struct lov_user_md *lum_file1,
 
 int main(int argc, char **argv)
 {
-        DIR * dir;
-        struct lov_user_md *lum_dir, *lum_file1 = NULL, *lum_file2 = NULL;
-        int rc;
-        int lum_size;
+       struct lov_user_md *lum_dir, *lum_file1 = NULL, *lum_file2 = NULL;
+       struct obd_uuid uuid;
+       int lum_size, rc;
+       DIR *dir;
 
-        if (argc < 3) {
-                llapi_err_noerrno(LLAPI_MSG_ERROR,
-                                "Usage: %s <dirname> <filename1> [filename2]\n",
-                                argv[0]);
-                return 1;
-        }
+       if (argc < 3) {
+               llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                 "Usage: %s <dirname> <filename1> [filename2]\n",
+                                 argv[0]);
+               return 1;
+       }
 
        dir = opendir(argv[1]);
        if (dir == NULL) {
@@ -264,7 +252,7 @@ int main(int argc, char **argv)
        }
 
        /* XXX should be llapi_lov_getname() */
-       rc = llapi_file_get_lov_uuid(argv[1], &lov_uuid);
+       rc = llapi_file_get_lov_uuid(argv[1], &uuid);
        if (rc) {
                llapi_error(LLAPI_MSG_ERROR, rc,
                            "error: can't get lov name for %s",
@@ -306,16 +294,16 @@ int main(int argc, char **argv)
                }
        }
 
-       rc = compare(lum_dir, lum_file1, lum_file2);
+       rc = compare(&uuid, lum_dir, lum_file1, lum_file2);
 
 cleanup:
-        closedir(dir);
-        if (lum_dir != NULL)
-                free(lum_dir);
-        if (lum_file1 != NULL)
-                free(lum_file1);
-        if (lum_file2 != NULL)
-                free(lum_file2);
+       closedir(dir);
+       if (lum_dir != NULL)
+               free(lum_dir);
+       if (lum_file1 != NULL)
+               free(lum_file1);
+       if (lum_file2 != NULL)
+               free(lum_file2);
 
-        return rc;
+       return rc;
 }
index 0ea6652..4f414e1 100644 (file)
@@ -29,7 +29,7 @@
 
 /* The purpose of this test is to check some HSM functions. HSM must
  * be enabled before running it:
- *   echo enabled > /proc/fs/lustre/mdt/lustre-MDT0000/hsm_control
+ *   lctl set_param mdt.$FSNAME-MDT0000.hsm_control=enabled
  */
 
 /* All tests return 0 on success and non zero on error. The program will
index edd2cfd..2224f95 100644 (file)
@@ -39,6 +39,7 @@
 #include <sys/wait.h>
 #include <sys/time.h>
 #include <sys/mman.h>
+#include <limits.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -47,6 +48,8 @@
 #include <string.h>
 #include <errno.h>
 
+#include <libcfs/util/param.h>
+
 char *dir = NULL, *dir2 = NULL;
 long page_size;
 char mmap_sanity[256];
@@ -437,62 +440,56 @@ out_close:
         return rc;
 }
 
-static int cancel_lru_locks(char *prefix)
+static int cancel_lru_locks(char *filter)
 {
-        char cmd[256], line[1024];
-        FILE *file;
-        pid_t child;
-        int len = 1024, rc = 0;
-
-        child = fork();
-        if (child < 0)
-                return -errno;
-        else if (child) {
-                int status;
-                rc = waitpid(child, &status, WNOHANG);
-                if (rc == child)
-                        rc = 0;
-                return rc;
-        }
-
-        if (prefix)
-                sprintf(cmd,
-                        "ls /proc/fs/lustre/ldlm/namespaces/*-%s-*/lru_size",
-                        prefix);
-        else
-                sprintf(cmd, "ls /proc/fs/lustre/ldlm/namespaces/*/lru_size");
-
-        file = popen(cmd, "r");
-        if (file == NULL) {
-                perror("popen()");
-                return -errno;
-        }
-
-        while (fgets(line, len, file)) {
-                FILE *f;
-
-                if (!strlen(line))
-                        continue;
-                /* trim newline character */
-                *(line + strlen(line) - 1) = '\0';
-                f = fopen(line, "w");
-                if (f == NULL) {
-                        perror("fopen()");
-                        rc = -errno;
-                        break;
-                }
-                rc = fwrite("clear", strlen("clear") + 1, 1, f);
-                if (rc < 1) {
-                        perror("fwrite()");
-                        rc = -errno;
-                        fclose(f);
-                        break;
-                }
-                fclose(f);
-        }
-
-        pclose(file);
-        _exit(rc);
+       glob_t paths;
+       pid_t child;
+       int rc, i;
+
+       child = fork();
+       if (child < 0)
+               return -errno;
+       else if (child) {
+               int status;
+
+               rc = waitpid(child, &status, WNOHANG);
+               if (rc == child)
+                       rc = 0;
+               return rc;
+       }
+
+       if (filter != NULL)
+               rc = cfs_get_param_paths(&paths,
+                                       "ldlm/namespaces/*-%s-*/lru_size",
+                                       filter);
+       else
+               rc = cfs_get_param_paths(&paths,
+                                       "ldlm/namespaces/*/lru_size");
+       if (rc != 0)
+               return -EINVAL;
+
+       for (i = 0; i < paths.gl_pathc; i++) {
+               FILE *f = fopen(paths.gl_pathv[i], "r");
+               if (f == NULL) {
+                       rc = -errno;
+                       fprintf(stderr, "cannot open '%s': %s\n",
+                               paths.gl_pathv[i], strerror(errno));
+                       break;
+               }
+
+               rc = fwrite("clear", strlen("clear") + 1, 1, f);
+               if (rc < 1) {
+                       rc = -errno;
+                       fprintf(stderr, "fwrite failed for '%s': %s\n",
+                               paths.gl_pathv[i], strerror(errno));
+                       fclose(f);
+                       break;
+               }
+               fclose(f);
+       }
+
+       cfs_free_param_data(&paths);
+       _exit(rc);
 }
 
 /* don't dead lock while read/write file to/from the buffer which
index 1ac6868..b6db05f 100644 (file)
@@ -3,8 +3,7 @@
 AM_CFLAGS := -fPIC \
             -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 -DLUSTRE_UTILS=1
 
-LIBCFS := $(top_builddir)/libcfs/libcfs/libcfsutil.a \
-         $(top_builddir)/libcfs/libcfs/libcfs.a
+LIBCFS := $(top_builddir)/libcfs/libcfs/libcfs.a
 
 sbin_PROGRAMS = lsvcgssd l_idmap
 
index e30d6e8..10768ca 100644 (file)
@@ -64,6 +64,8 @@
 # include <netdb.h>
 #endif
 
+#include <libcfs/util/param.h>
+
 #include "gssd.h"
 #include "err_util.h"
 #include "gss_util.h"
@@ -631,13 +633,13 @@ int do_negotiation(struct lustre_gss_data *lgd,
                   struct lustre_gss_init_res *gr,
                   int timeout)
 {
-       char *file = "/proc/fs/lustre/sptlrpc/gss/init_channel";
        struct lgssd_ioctl_param param;
        struct passwd *pw;
-       int fd, ret;
        char outbuf[8192];
        unsigned int *p;
-       int res;
+       glob_t path;
+       int fd;
+       int rc;
 
        pw = getpwuid(lgd->lgd_uid);
        if (!pw) {
@@ -656,21 +658,23 @@ int do_negotiation(struct lustre_gss_data *lgd,
        param.reply_buf_size = sizeof(outbuf);
        param.reply_buf = outbuf;
 
-       fd = open(file, O_RDWR);
-       if (fd < 0) {
-               printerr(0, "can't open file %s\n", file);
+       if (cfs_get_param_paths(&path, "sptlrpc/gss/init_channel") != 0)
                return -1;
-       }
 
-       ret = write(fd, &param, sizeof(param));
+       fd = open(path.gl_pathv[0], O_RDWR);
+       if (fd < 0) {
+               printerr(0, "can't open file %s\n", path.gl_pathv[0]);
+               rc = -1;
+               goto out_params;
+       }
 
-       if (ret != sizeof(param)) {
+       rc = write(fd, &param, sizeof(param));
+       if (rc != sizeof(param)) {
                printerr(0, "lustre ioctl err: %d\n", strerror(errno));
-               close(fd);
-               return -1;
+               rc = -1;
+               goto out_fd;
        }
        if (param.status) {
-               close(fd);
                printerr(0, "status: %d (%s)\n",
                         param.status, strerror((int)param.status));
                if (param.status == -ETIMEDOUT) {
@@ -684,10 +688,10 @@ int do_negotiation(struct lustre_gss_data *lgd,
                        lgd->lgd_rpc_err = param.status;
                        lgd->lgd_gss_err = 0;
                }
-               return -1;
+               rc = -1;
+               goto out_fd;
        }
        p = (unsigned int *)outbuf;
-       res = *p++;
        gr->gr_major = *p++;
        gr->gr_minor = *p++;
        gr->gr_win = *p++;
@@ -704,8 +708,12 @@ int do_negotiation(struct lustre_gss_data *lgd,
 
        printerr(2, "do_negotiation: receive handle len %d, token len %d\n",
                 gr->gr_ctx.length, gr->gr_token.length);
+       rc = 0;
+out_fd:
        close(fd);
-       return 0;
+out_params:
+       cfs_free_param_data(&path);
+       return rc;
 }
 
 static
index 0b6aa54..c50f4b8 100644 (file)
@@ -51,6 +51,7 @@
 #include <keyutils.h>
 #include <gssapi/gssapi.h>
 
+#include <libcfs/util/param.h>
 #include <libcfs/util/string.h>
 #include "lsupport.h"
 #include "lgss_utils.h"
@@ -117,17 +118,17 @@ struct keyring_upcall_param {
  * child process: gss negotiation       *
  ****************************************/
 
-#define INIT_CHANNEL    "/proc/fs/lustre/sptlrpc/gss/init_channel"
-
 int do_nego_rpc(struct lgss_nego_data *lnd,
                 gss_buffer_desc *gss_token,
                 struct lgss_init_res *gr)
 {
-        struct lgssd_ioctl_param  param;
-        struct passwd            *pw;
-        int                       fd, ret, res;
-        char                      outbuf[8192];
-        unsigned int             *p;
+       struct lgssd_ioctl_param param;
+       struct passwd *pw;
+       int fd, ret, res;
+       char outbuf[8192];
+       unsigned int *p;
+       glob_t path;
+       int rc;
 
         logmsg(LL_TRACE, "start negotiation rpc\n");
 
@@ -149,23 +150,28 @@ int do_nego_rpc(struct lgss_nego_data *lnd,
         param.reply_buf_size = sizeof(outbuf);
         param.reply_buf = outbuf;
 
-        logmsg(LL_TRACE, "to open " INIT_CHANNEL "\n");
+       rc = cfs_get_param_paths(&path, "sptlrpc/gss/init_channel");
+       if (rc != 0)
+               return rc;
+
+       logmsg(LL_TRACE, "to open %s\n", path.gl_pathv[0]);
 
-        fd = open(INIT_CHANNEL, O_WRONLY);
+       fd = open(path.gl_pathv[0], O_WRONLY);
         if (fd < 0) {
-                logmsg(LL_ERR, "can't open " INIT_CHANNEL "\n");
-                return -EACCES;
+               logmsg(LL_ERR, "can't open %s\n", path.gl_pathv[0]);
+               rc = -EACCES;
+               goto out_params;
         }
 
-        logmsg(LL_TRACE, "to down-write\n");
+       logmsg(LL_TRACE, "to down-write\n");
 
-        ret = write(fd, &param, sizeof(param));
-        if (ret != sizeof(param)) {
+       ret = write(fd, &param, sizeof(param));
+       close(fd);
+       if (ret != sizeof(param)) {
                logmsg(LL_ERR, "lustre ioctl err: %s\n", strerror(errno));
-                close(fd);
-                return -EACCES;
-        }
-        close(fd);
+               rc = -EACCES;
+               goto out_params;
+       }
 
         logmsg(LL_TRACE, "do_nego_rpc: to parse reply\n");
         if (param.status) {
@@ -177,10 +183,11 @@ int do_nego_rpc(struct lgss_nego_data *lnd,
                  * returning -ERESTART
                  */
                 if (param.status == -ETIMEDOUT)
-                        return -ERESTART;
-                else
-                        return param.status;
-        }
+                       rc = -ERESTART;
+               else
+                       rc = param.status;
+               goto out_params;
+       }
 
         p = (unsigned int *)outbuf;
         res = *p++;
@@ -200,7 +207,9 @@ int do_nego_rpc(struct lgss_nego_data *lnd,
 
        logmsg(LL_DEBUG, "do_nego_rpc: receive handle len %zu, token len %zu, "
               "res %d\n", gr->gr_ctx.length, gr->gr_token.length, res);
-       return 0;
+out_params:
+       cfs_free_param_data(&path);
+       return rc;
 }
 
 /*
@@ -605,26 +614,31 @@ static int parse_callout_info(const char *coinfo,
        return 0;
 }
 
-#define LOG_LEVEL_PATH  "/proc/fs/lustre/sptlrpc/gss/lgss_keyring/debug_level"
-
 static void set_log_level()
 {
-        FILE         *file;
-        unsigned int  level;
-
-        file = fopen(LOG_LEVEL_PATH, "r");
-        if (file == NULL)
-                return;
-
-        if (fscanf(file, "%u", &level) != 1)
-                goto out;
-
-        if (level >= LL_MAX)
-                goto out;
-
-        lgss_set_loglevel(level);
+       unsigned int level;
+       glob_t path;
+       FILE *file;
+
+       if (cfs_get_param_paths(&path,
+                               "sptlrpc/gss/lgss_keyring/debug_level") != 0)
+               return;
+       file = fopen(path.gl_pathv[0], "r");
+       if (file == NULL) {
+               cfs_free_param_data(&path);
+               return;
+       }
+
+       if (fscanf(file, "%u", &level) != 1)
+               goto out;
+
+       if (level >= LL_MAX)
+               goto out;
+
+       lgss_set_loglevel(level);
 out:
-        fclose(file);
+       cfs_free_param_data(&path);
+       fclose(file);
 }
 
 /****************************************
index 46bd22c..10842a2 100644 (file)
@@ -48,6 +48,7 @@
 #include <libgen.h>
 #include <syslog.h>
 
+#include <libcfs/util/param.h>
 #include <libcfs/util/string.h>
 #include <lnet/nidstr.h>
 #include <lustre/lustre_user.h>
@@ -74,11 +75,11 @@ static char *progname;
 
 static void usage(void)
 {
-        fprintf(stderr,
-                "\nusage: %s {mdtname} {uid}\n"
-                "Normally invoked as an upcall from Lustre, set via:\n"
-                "/proc/fs/lustre/mdt/${mdtname}/identity_upcall\n",
-                progname);
+       fprintf(stderr,
+               "\nusage: %s {mdtname} {uid}\n"
+               "Normally invoked as an upcall from Lustre, set via:\n"
+               "lctl set_param mdt.${mdtname}.identity_upcall={path to upcall}\n",
+               progname);
 }
 
 static int compare_u32(const void *v1, const void *v2)
@@ -418,11 +419,11 @@ static void show_result(struct identity_downcall_data *data)
 
 int main(int argc, char **argv)
 {
-        char *end;
-        struct identity_downcall_data *data = NULL;
-        char procname[1024];
-        unsigned long uid;
-        int fd, rc = -EINVAL, size, maxgroups;
+       char *end;
+       struct identity_downcall_data *data = NULL;
+       glob_t path;
+       unsigned long uid;
+       int fd, rc = -EINVAL, size, maxgroups;
 
         progname = basename(argv[0]);
         if (argc != 3) {
@@ -472,26 +473,33 @@ downcall:
                 goto out;
         }
 
-        snprintf(procname, sizeof(procname),
-                 "/proc/fs/lustre/mdt/%s/identity_info", argv[1]);
-        fd = open(procname, O_WRONLY);
-        if (fd < 0) {
-                errlog("can't open file %s: %s\n", procname, strerror(errno));
-                rc = -1;
-                goto out;
-        }
+       rc = cfs_get_param_paths(&path, "mdt/%s/identity_info", argv[1]);
+       if (rc != 0) {
+               rc = -errno;
+               goto out;
+       }
 
-        rc = write(fd, data, size);
-        close(fd);
-        if (rc != size) {
-                errlog("partial write ret %d: %s\n", rc, strerror(errno));
-                rc = -1;
-        } else {
-                rc = 0;
-        }
+       fd = open(path.gl_pathv[0], O_WRONLY);
+       if (fd < 0) {
+               errlog("can't open file '%s':%s\n", path.gl_pathv[0],
+                      strerror(errno));
+               rc = -errno;
+               goto out_params;
+       }
+
+       rc = write(fd, data, size);
+       close(fd);
+       if (rc != size) {
+               errlog("partial write ret %d: %s\n", rc, strerror(errno));
+               rc = -1;
+       } else {
+               rc = 0;
+       }
 
+out_params:
+       cfs_free_param_data(&path);
 out:
-        if (data != NULL)
-                free(data);
-        return rc;
+       if (data != NULL)
+               free(data);
+       return rc;
 }
index 09a050c..96b2e86 100644 (file)
@@ -53,7 +53,6 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
-#include <glob.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdbool.h>
@@ -65,6 +64,7 @@
 
 #include "obdctl.h"
 #include <libcfs/util/ioctl.h>
+#include <libcfs/util/param.h>
 #include <libcfs/util/parser.h>
 #include <libcfs/util/string.h>
 
@@ -79,7 +79,6 @@
 #include <lustre_param.h>
 
 #define MAX_STRING_SIZE 128
-#define DEVICES_LIST "/proc/fs/lustre/devices"
 
 #if HAVE_LIBPTHREAD
 #include <sys/ipc.h>
@@ -944,52 +943,52 @@ int jt_get_version(int argc, char **argv)
 
 static void print_obd_line(char *s)
 {
-        char buf[MAX_STRING_SIZE];
-        char obd_name[MAX_OBD_NAME];
-        FILE *fp = NULL;
-        char *ptr;
-
-       snprintf(buf, sizeof(buf), " %%*d %%*s osc %%%zus %%*s %%*d ",
-                sizeof(obd_name) - 1);
+       const char *param = "osc/%s/ost_conn_uuid";
+       char buf[MAX_STRING_SIZE];
+       char obd_name[MAX_OBD_NAME];
+       FILE *fp = NULL;
+       glob_t path;
+       char *ptr;
+retry:
+       /* obd device type is the first 3 characters of param name */
+       snprintf(buf, sizeof(buf), " %%*d %%*s %.3s %%%zus %%*s %%*d ",
+                param, sizeof(obd_name) - 1);
        if (sscanf(s, buf, obd_name) == 0)
-                goto try_mdc;
-        snprintf(buf, sizeof(buf),
-                 "/proc/fs/lustre/osc/%s/ost_conn_uuid", obd_name);
-        if ((fp = fopen(buf, "r")) == NULL)
-                goto try_mdc;
-        goto got_one;
-
+               goto try_mdc;
+       if (cfs_get_param_paths(&path, param, obd_name) != 0)
+               goto try_mdc;
+       fp = fopen(path.gl_pathv[0], "r");
+       if (fp == NULL) {
+               /* need to free path data before retry */
+               cfs_free_param_data(&path);
 try_mdc:
-       snprintf(buf, sizeof(buf), " %%*d %%*s mdc %%%zus %%*s %%*d ",
-                sizeof(obd_name) - 1);
-       if (sscanf(s, buf, obd_name) == 0)
-                goto fail;
-        snprintf(buf, sizeof(buf),
-                 "/proc/fs/lustre/mdc/%s/mds_conn_uuid", obd_name);
-        if ((fp = fopen(buf, "r")) == NULL)
-                goto fail;
-
-got_one:
-        /* should not ignore fgets(3)'s return value */
-        if (!fgets(buf, sizeof(buf), fp)) {
-                fprintf(stderr, "reading from %s: %s", buf, strerror(errno));
-                fclose(fp);
-                return;
-        }
-        fclose(fp);
-
-        /* trim trailing newlines */
-        ptr = strrchr(buf, '\n');
-        if (ptr) *ptr = '\0';
-        ptr = strrchr(s, '\n');
-        if (ptr) *ptr = '\0';
+               if (param[0] == 'o') { /* failed with osc, try mdc */
+                       param = "mdc/%s/mds_conn_uuid";
+                       goto retry;
+               }
+               buf[0] = '\0';
+               goto fail_print;
+       }
 
-        printf("%s %s\n", s, buf);
-        return;
+       /* should not ignore fgets(3)'s return value */
+       if (!fgets(buf, sizeof(buf), fp)) {
+               fprintf(stderr, "reading from %s: %s", buf, strerror(errno));
+               goto fail_close;
+       }
 
-fail:
-        printf("%s", s);
-        return;
+fail_close:
+       fclose(fp);
+       cfs_free_param_data(&path);
+
+       /* trim trailing newlines */
+       ptr = strrchr(buf, '\n');
+       if (ptr)
+               *ptr = '\0';
+fail_print:
+       ptr = strrchr(s, '\n');
+       if (ptr)
+               *ptr = '\0';
+       printf("%s%s%s\n", s, buf[0] ? " " : "", buf);
 }
 
 /* get device list by ioctl */
@@ -1032,10 +1031,10 @@ int jt_obd_list_ioctl(int argc, char **argv)
 
 int jt_obd_list(int argc, char **argv)
 {
-        int rc;
-        char buf[MAX_STRING_SIZE];
-        FILE *fp = NULL;
-        int print_obd = 0;
+       char buf[MAX_STRING_SIZE];
+       int print_obd = 0;
+       glob_t path;
+       FILE *fp;
 
         if (argc > 2)
                 return CMD_HELP;
@@ -1046,10 +1045,14 @@ int jt_obd_list(int argc, char **argv)
                         return CMD_HELP;
         }
 
-        fp = fopen(DEVICES_LIST, "r");
+       if (cfs_get_param_paths(&path, "devices") != 0)
+               return -errno;
+
+       fp = fopen(path.gl_pathv[0], "r");
         if (fp == NULL) {
-                fprintf(stderr, "error: %s: %s opening "DEVICES_LIST"\n",
-                        jt_cmdname(argv[0]), strerror(rc =  errno));
+               fprintf(stderr, "error: %s: %s opening %s\n",
+                       jt_cmdname(argv[0]), strerror(errno), path.gl_pathv[0]);
+               cfs_free_param_data(&path);
                 return jt_obd_list_ioctl(argc, argv);
         }
 
@@ -1059,6 +1062,7 @@ int jt_obd_list(int argc, char **argv)
                 else
                         printf("%s", buf);
 
+       cfs_free_param_data(&path);
         fclose(fp);
         return 0;
 }