From 322968acf183ab16d952cd3026f6580957b31259 Mon Sep 17 00:00:00 2001 From: wangdi Date: Thu, 3 Nov 2011 23:00:05 -0700 Subject: [PATCH 1/1] LU-819 utils: Fix lfs getstripe -M 1. Fix lfs getstripe -M problem: some typo in llapi_file_fget_mdtidx. 2. Add lfs find -mdt and lfs mdts. 3. Add sanity test to check lfs getstripe -M and lfs find -mdt. Signed-off-by: wangdi Change-Id: I3b327d33c49009149dbed23728416efecb67691c Reviewed-on: http://review.whamcloud.com/1646 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/linux/lustre_lib.h | 4 + lustre/include/lustre/liblustreapi.h | 14 +- lustre/include/lustre/lustre_user.h | 5 +- lustre/include/lustre_lib.h | 3 + lustre/include/obd.h | 1 - lustre/llite/dir.c | 12 +- lustre/llite/file.c | 14 +- lustre/llite/llite_internal.h | 1 + lustre/llite/llite_lib.c | 28 ++- lustre/lmv/lmv_obd.c | 5 +- lustre/tests/sanity.sh | 20 +- lustre/tests/test-framework.sh | 5 + lustre/utils/lfs.c | 79 ++++++-- lustre/utils/liblustreapi.c | 372 ++++++++++++++++++++++++----------- 14 files changed, 403 insertions(+), 160 deletions(-) diff --git a/lustre/include/linux/lustre_lib.h b/lustre/include/linux/lustre_lib.h index 8c853ed..fb476f1 100644 --- a/lustre/include/linux/lustre_lib.h +++ b/lustre/include/linux/lustre_lib.h @@ -68,6 +68,10 @@ #endif #endif +/* This macro is only for compatibility reasons with older Linux Lustre user + * tools. New ioctls should NOT use this macro as the ioctl "size". Instead + * the ioctl should get a "size" argument which is the actual data type used + * by the ioctl, to ensure the ioctl interface is versioned correctly. */ #define OBD_IOC_DATA_TYPE long #define LUSTRE_FATAL_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | \ diff --git a/lustre/include/lustre/liblustreapi.h b/lustre/include/lustre/liblustreapi.h index 2cb4ad9..463f140 100644 --- a/lustre/include/lustre/liblustreapi.h +++ b/lustre/include/lustre/liblustreapi.h @@ -126,6 +126,7 @@ struct find_param { exclude_pattern:1, exclude_type:1, exclude_obd:1, + exclude_mdt:1, have_fileinfo:1, exclude_gid:1, exclude_uid:1, @@ -139,6 +140,7 @@ struct find_param { exclude_mtime:1, exclude_ctime:1, get_mdt_index:1, + get_lmv:1, raw:1; int verbose; @@ -149,11 +151,18 @@ struct find_param { char *print_fmt; - struct obd_uuid *obduuid; + struct obd_uuid *obduuid; int num_obds; int num_alloc_obds; int obdindex; - int *obdindexes; + int *obdindexes; + + struct obd_uuid *mdtuuid; + int num_mdts; + int num_alloc_mdts; + int mdtindex; + int *mdtindexes; + int file_mdtindex; int lumlen; struct lov_user_mds_data *lmd; @@ -180,6 +189,7 @@ extern int llapi_catinfo(char *dir, char *keyword, char *node_name); extern int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid); extern int llapi_file_fget_lov_uuid(int fd, struct obd_uuid *lov_uuid); extern int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count); +extern int llapi_lmv_get_uuids(int fd, struct obd_uuid *uuidp, int *mdt_count); extern int llapi_is_lustre_mnttype(const char *type); extern int llapi_search_ost(char *fsname, char *poolname, char *ostname); extern int llapi_get_obd_count(char *mnt, int *count, int is_mdt); diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 1b2176a..f2a52cb 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -157,7 +157,7 @@ struct obd_statfs { /* see for ioctl numbers 177-210 */ -#define LL_STATFS_MDC 1 +#define LL_STATFS_LMV 1 #define LL_STATFS_LOV 2 #define IOC_MDC_TYPE 'i' @@ -170,6 +170,9 @@ struct obd_statfs { #define LL_IOC_OBD_STATFS IOC_OBD_STATFS #define IOC_MDC_GETSTRIPE IOC_MDC_GETFILESTRIPE + +#define MAX_OBD_NAME 128 /* If this changes, a NEW ioctl must be added */ + #define O_LOV_DELAY_CREATE 0100000000 /* hopefully this does not conflict */ #define LL_FILE_IGNORE_LOCK 0x00000001 diff --git a/lustre/include/lustre_lib.h b/lustre/include/lustre_lib.h index 37dd25d..2a7f3d5 100644 --- a/lustre/include/lustre_lib.h +++ b/lustre/include/lustre_lib.h @@ -492,7 +492,10 @@ static inline void obd_ioctl_freedata(char *buf, int len) #define OBD_IOC_BRW_WRITE _IOWR('f', 126, OBD_IOC_DATA_TYPE) #define OBD_IOC_NAME2DEV _IOWR('f', 127, OBD_IOC_DATA_TYPE) #define OBD_IOC_UUID2DEV _IOWR('f', 130, OBD_IOC_DATA_TYPE) + #define OBD_IOC_GETNAME _IOWR('f', 131, OBD_IOC_DATA_TYPE) +#define OBD_IOC_GETMDNAME _IOR('f', 131, char[MAX_OBD_NAME]) +#define OBD_IOC_GETDTNAME OBD_IOC_GETNAME #define OBD_IOC_LOV_GET_CONFIG _IOWR('f', 132, OBD_IOC_DATA_TYPE) #define OBD_IOC_CLIENT_RECOVER _IOW ('f', 133, OBD_IOC_DATA_TYPE) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 8f9d603..870c844 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1046,7 +1046,6 @@ struct obd_llog_group { }; /* corresponds to one of the obd's */ -#define MAX_OBD_NAME 128 #define OBD_DEVICE_MAGIC 0XAB5CD6EF #define OBD_DEV_BY_DEVNAME 0xffffd0de diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 392dce1..27edd96 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -1477,15 +1477,9 @@ out_free: OBD_FREE_PTR(qctl); RETURN(rc); } - case OBD_IOC_GETNAME: { - struct obd_device *obd = class_exp2obd(sbi->ll_dt_exp); - if (!obd) - RETURN(-EFAULT); - if (cfs_copy_to_user((void *)arg, obd->obd_name, - strlen(obd->obd_name) + 1)) - RETURN (-EFAULT); - RETURN(0); - } + case OBD_IOC_GETDTNAME: + case OBD_IOC_GETMDNAME: + RETURN(ll_get_obd_name(inode, cmd, arg)); case LL_IOC_FLUSHCTX: RETURN(ll_flush_ctx(inode)); #ifdef CONFIG_FS_POSIX_ACL diff --git a/lustre/llite/file.c b/lustre/llite/file.c index b4c0028..34ce73a 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1849,17 +1849,9 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd, RETURN(0); } - case OBD_IOC_GETNAME: { - struct obd_device *obd = - class_exp2obd(ll_i2sbi(inode)->ll_dt_exp); - if (!obd) - RETURN(-EFAULT); - if (cfs_copy_to_user((void *)arg, obd->obd_name, - strlen(obd->obd_name) + 1)) - RETURN(-EFAULT); - RETURN(0); - } - + case OBD_IOC_GETDTNAME: + case OBD_IOC_GETMDNAME: + RETURN(ll_get_obd_name(inode, cmd, arg)); default: { int err; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index ef654c9..950856e 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -815,6 +815,7 @@ struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data, const char *name, int namelen, int mode, __u32 opc, void *data); void ll_finish_md_op_data(struct md_op_data *op_data); +int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg); /* llite/llite_nfs.c */ extern struct export_operations lustre_export_operations; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index a17429d..4e49985 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -2137,7 +2137,7 @@ int ll_obd_statfs(struct inode *inode, void *arg) GOTO(out_statfs, rc = -EINVAL); memcpy(&type, data->ioc_inlbuf1, sizeof(__u32)); - if (type == LL_STATFS_MDC) + if (type == LL_STATFS_LMV) exp = sbi->ll_md_exp; else if (type == LL_STATFS_LOV) exp = sbi->ll_dt_exp; @@ -2272,3 +2272,29 @@ int ll_show_options(struct seq_file *seq, struct vfsmount *vfs) RETURN(0); } + +/** + * Get obd name by cmd, and copy out to user space + */ +int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg) +{ + struct ll_sb_info *sbi = ll_i2sbi(inode); + struct obd_device *obd; + ENTRY; + + if (cmd == OBD_IOC_GETDTNAME) + obd = class_exp2obd(sbi->ll_dt_exp); + else if (cmd == OBD_IOC_GETMDNAME) + obd = class_exp2obd(sbi->ll_md_exp); + else + RETURN(-EINVAL); + + if (!obd) + RETURN(-ENOENT); + + if (cfs_copy_to_user((void *)arg, obd->obd_name, + strlen(obd->obd_name) + 1)) + RETURN(-EFAULT); + + RETURN(0); +} diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index daefddd..d897826 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1110,10 +1110,11 @@ static int lmv_setup(struct obd_device *obd, struct lustre_cfg *lcfg) lprocfs_obd_setup(obd, lvars.obd_vars); #ifdef LPROCFS { - rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd_status", + rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd", 0444, &lmv_proc_target_fops, obd); if (rc) - CWARN("Error adding target_obd_stats file (%d)\n", rc); + CWARN("%s: error adding LMV target_obd file: rc = %d\n", + obd->obd_name, rc); } #endif rc = fld_client_init(&lmv->lmv_fld, obd->obd_name, diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index cde9086..02f0d6f 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -3375,9 +3375,9 @@ test_56i() { mkdir -p $DIR/$tdir UUID=$(ostuuid_from_index 0 $DIR/$tdir) OUT=$($LFIND -obd $UUID $DIR/$tdir) - [ "$OUT" ] && error "$LFIND returned directory '$OUT'" || true + [ "$OUT" ] && error "$LFIND -obd returned directory '$OUT'" || true } -run_test 56i "check 'lfs find -ost UUID' skips directories =======" +run_test 56i "check 'lfs find -obd UUID' skips directories =======" test_56j() { setup_56_special $NUMFILES $NUMDIRS @@ -3538,6 +3538,22 @@ test_56r() { run_test 56r "check lfs find -size works ==========================" +test_56v() { + local FIND_MDT_IDX=0 + + TDIR=${tdir}g + rm -rf $TDIR + setup_56 $NUMFILES $NUMDIRS + + UUID=$(mdtuuid_from_index $FIND_MDT_IDX $DIR/$TDIR) + for file in $($LFIND -mdt $UUID $DIR/$TDIR); do + file_mdt_idx=$($GETSTRIPE -M $file) + [ $file_mdt_idx -eq $FIND_MDT_IDX ] || + error "wrong lfind -m not match getstripe -M" + done +} +run_test 56v "check 'lfs find -mdt match with lfs getstripe -M' =======" + test_57a() { # note test will not do anything if MDS is not local remote_mds_nodsh && skip "remote MDS with nodsh" && return diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 4c52a29..ad6ad36 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -3439,6 +3439,11 @@ index_from_ostuuid() $LFS osts $2 | sed -ne "/${1}/s/\(.*\): .* .*$/\1/p" } +mdtuuid_from_index() +{ + $LFS mdts $2 | awk '/^'$1'/ { print $2 }' +} + remote_node () { local node=$1 [ "$node" != "$(hostname)" ] diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 2bc71a1..c2f45eb 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -85,6 +85,7 @@ static int lfs_setstripe(int argc, char **argv); static int lfs_find(int argc, char **argv); static int lfs_getstripe(int argc, char **argv); static int lfs_osts(int argc, char **argv); +static int lfs_mdts(int argc, char **argv); static int lfs_df(int argc, char **argv); static int lfs_getname(int argc, char **argv); static int lfs_check(int argc, char **argv); @@ -145,8 +146,9 @@ command_t cmdlist[] = { "usage: find ...\n" " [[!] --atime|-A [+-]N] [[!] --mtime|-M [+-]N] [[!] --ctime|-C [+-]N]\n" " [--maxdepth|-D N] [[!] --name|-n ] [--print0|-P]\n" - " [--print|-p] [[!] --obd|-O ] [[!] --size|-s [+-]N[bkMGTP]]\n" - " [[!] --type|-t ] [[!] --gid|-g|--group|-G |]\n" + " [--print|-p] [[!] --obd|-O ] [[!] --mdt|-m ]\n" + " [[!] --gid|-g|--group|-G |]\n" " [[!] --uid|-u|--user|-U |]\n" " [[!] --pool ]\n" "\t !: used before an option indicates 'NOT' the requested attribute\n" @@ -166,6 +168,8 @@ command_t cmdlist[] = { "obsolete, HEAD does not support it anymore.\n"}, {"osts", lfs_osts, 0, "list OSTs connected to client " "[for specified path only]\n" "usage: osts [path]"}, + {"mdts", lfs_mdts, 0, "list MDTs connected to client " + "[for specified path only]\n" "usage: mdts [path]"}, {"df", lfs_df, 0, "report filesystem disk space usage or inodes usage" "of each MDS and all OSDs or a batch belonging to a specific pool .\n" @@ -506,6 +510,7 @@ static int lfs_find(int argc, char **argv) {"gid", required_argument, 0, 'g'}, {"group", required_argument, 0, 'G'}, {"mtime", required_argument, 0, 'M'}, + {"mdt", required_argument, 0, 'm'}, {"name", required_argument, 0, 'n'}, /* --obd is considered as a new option. */ {"obd", required_argument, 0, 'O'}, @@ -535,8 +540,8 @@ static int lfs_find(int argc, char **argv) optind = 0; /* when getopt_long_only() hits '!' it returns 1, puts "!" in optarg */ - while ((c = getopt_long_only(argc,argv,"-A:C:D:g:G:M:n:O:Ppqrs:t:u:U:v", - long_opts, NULL)) >= 0) { + while ((c = getopt_long_only(argc, argv, "-A:C:D:g:G:M:m:n:O:" + "Ppqrs:t:u:U:v", long_opts, NULL)) >= 0) { xtime = NULL; xsign = NULL; if (neg_opt) @@ -659,6 +664,7 @@ static int lfs_find(int argc, char **argv) param.pattern = (char *)optarg; param.exclude_pattern = !!neg_opt; break; + case 'm': case 'O': { char *buf, *token, *next, *p; int len = 1; @@ -680,29 +686,42 @@ static int lfs_find(int argc, char **argv) token++; } } - - param.num_alloc_obds += len; - tmp = realloc(param.obduuid, - param.num_alloc_obds * - sizeof(*param.obduuid)); - if (tmp == NULL) { - ret = -ENOMEM; - free(buf); - goto err; + if (c == 'O') { + param.exclude_obd = !!neg_opt; + param.num_alloc_obds += len; + tmp = realloc(param.obduuid, + param.num_alloc_obds * + sizeof(*param.obduuid)); + if (tmp == NULL) + GOTO(err_free, ret = -ENOMEM); + param.obduuid = tmp; + } else { + param.exclude_mdt = !!neg_opt; + param.num_alloc_mdts += len; + tmp = realloc(param.mdtuuid, + param.num_alloc_mdts * + sizeof(*param.mdtuuid)); + if (tmp == NULL) + GOTO(err_free, ret = -ENOMEM); + param.mdtuuid = tmp; } - param.obduuid = tmp; - for (token = buf; token && *token; token = next) { + char *uuid; + if (c == 'O') + uuid = + param.obduuid[param.num_obds++].uuid; + else + uuid = + param.mdtuuid[param.num_mdts++].uuid; p = strchr(token, ','); next = 0; if (p) { *p = 0; next = p+1; } - strcpy((char *)¶m.obduuid[param.num_obds++].uuid, - token); + strcpy((char *)uuid, token); } - +err_free: if (buf) free(buf); break; @@ -812,6 +831,9 @@ err: if (param.obduuid && param.num_alloc_obds) free(param.obduuid); + if (param.mdtuuid && param.num_alloc_mdts) + free(param.mdtuuid); + return ret; } @@ -894,6 +916,8 @@ static int lfs_getstripe(int argc, char **argv) } break; case 'M': + if (!(param.verbose & VERBOSE_DETAIL)) + param.maxdepth = 0; param.get_mdt_index = 1; break; case 'R': @@ -929,7 +953,7 @@ static int lfs_getstripe(int argc, char **argv) return rc; } -static int lfs_osts(int argc, char **argv) +static int lfs_tgts(int argc, char **argv) { char mntdir[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'}; struct find_param param; @@ -951,6 +975,9 @@ static int lfs_osts(int argc, char **argv) continue; memset(¶m, 0, sizeof(param)); + if (!strcmp(argv[0], "mdts")) + param.get_lmv = 1; + rc = llapi_ostlist(mntdir, ¶m); if (rc) { fprintf(stderr, "error: %s: failed on %s\n", @@ -964,6 +991,16 @@ static int lfs_osts(int argc, char **argv) return rc; } +static int lfs_osts(int argc, char **argv) +{ + return lfs_tgts(argc, argv); +} + +static int lfs_mdts(int argc, char **argv) +{ + return lfs_tgts(argc, argv); +} + #define COOK(value) \ ({ \ int radix = 0; \ @@ -1071,7 +1108,7 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow, int cooked) struct obd_statfs stat_buf, sum = { .os_bsize = 1 }; struct obd_uuid uuid_buf; char *poolname = NULL; - struct ll_stat_type types[] = { { LL_STATFS_MDC, "MDT" }, + struct ll_stat_type types[] = { { LL_STATFS_LMV, "MDT" }, { LL_STATFS_LOV, "OST" }, { 0, NULL } }; struct ll_stat_type *tp; @@ -1125,7 +1162,7 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow, int cooked) ishow, cooked, tp->st_name, index, rc); if (rc == 0) { - if (tp->st_op == LL_STATFS_MDC) { + if (tp->st_op == LL_STATFS_LMV) { sum.os_ffree += stat_buf.os_ffree; sum.os_files += stat_buf.os_files; } else /* if (tp->st_op == LL_STATFS_LOV) */ { diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index f7e012b..719ab51 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -1373,6 +1373,16 @@ int llapi_file_fget_lov_uuid(int fd, struct obd_uuid *lov_name) return rc; } +int llapi_file_fget_lmv_uuid(int fd, struct obd_uuid *lov_name) +{ + int rc = ioctl(fd, OBD_IOC_GETMDNAME, lov_name); + if (rc) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "error: can't get lmv name."); + } + return rc; +} + int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid) { int fd, rc; @@ -1390,27 +1400,38 @@ int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid) return rc; } +enum tgt_type { + LOV_TYPE = 1, + LMV_TYPE +}; /* * If uuidp is NULL, return the number of available obd uuids. * If uuidp is non-NULL, then it will return the uuids of the obds. If * there are more OSTs then allocated to uuidp, then an error is returned with * the ost_count set to number of available obd uuids. */ -int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) +static int llapi_get_target_uuids(int fd, struct obd_uuid *uuidp, + int *ost_count, enum tgt_type type) { - struct obd_uuid lov_name; + struct obd_uuid name; char buf[1024]; FILE *fp; int rc = 0, index = 0; /* Get the lov name */ - rc = llapi_file_fget_lov_uuid(fd, &lov_name); - if (rc) - return rc; + if (type == LOV_TYPE) { + rc = llapi_file_fget_lov_uuid(fd, &name); + if (rc) + return rc; + } else { + rc = llapi_file_fget_lmv_uuid(fd, &name); + if (rc) + return rc; + } /* Now get the ost uuids from /proc */ - snprintf(buf, sizeof(buf), "/proc/fs/lustre/lov/%s/target_obd", - lov_name.uuid); + snprintf(buf, sizeof(buf), "/proc/fs/lustre/%s/%s/target_obd", + type == LOV_TYPE ? "lov" : "lmv", name.uuid); fp = fopen(buf, "r"); if (fp == NULL) { rc = -errno; @@ -1435,6 +1456,11 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) return rc; } +int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count) +{ + return llapi_get_target_uuids(fd, uuidp, ost_count, LOV_TYPE); +} + int llapi_get_obd_count(char *mnt, int *count, int is_mdt) { DIR *root; @@ -1483,7 +1509,7 @@ int llapi_uuid_match(char *real_uuid, char *search_uuid) * returned in param->obdindex */ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param) { - struct obd_uuid lov_uuid; + struct obd_uuid obd_uuid; char uuid[sizeof(struct obd_uuid)]; char buf[1024]; FILE *fp; @@ -1492,8 +1518,11 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param) if (param->got_uuids) return rc; - /* Get the lov name */ - rc = llapi_file_fget_lov_uuid(dirfd(dir), &lov_uuid); + /* Get the lov/lmv name */ + if (param->get_lmv) + rc = llapi_file_fget_lmv_uuid(dirfd(dir), &obd_uuid); + else + rc = llapi_file_fget_lov_uuid(dirfd(dir), &obd_uuid); if (rc) { if (rc != -ENOTTY) { llapi_error(LLAPI_MSG_ERROR, rc, @@ -1507,8 +1536,8 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param) param->got_uuids = 1; /* Now get the ost uuids from /proc */ - snprintf(buf, sizeof(buf), "/proc/fs/lustre/lov/%s/target_obd", - lov_uuid.uuid); + snprintf(buf, sizeof(buf), "/proc/fs/lustre/%s/%s/target_obd", + param->get_lmv ? "lmv" : "lov", obd_uuid.uuid); fp = fopen(buf, "r"); if (fp == NULL) { rc = -errno; @@ -1517,7 +1546,8 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param) } if (!param->obduuid && !param->quiet && !param->obds_printed) - llapi_printf(LLAPI_MSG_NORMAL, "OBDS:\n"); + llapi_printf(LLAPI_MSG_NORMAL, "%s:\n", + param->get_lmv ? "MDTS" : "OBDS:"); while (fgets(buf, sizeof(buf), fp) != NULL) { if (sscanf(buf, "%d: %s", &index, uuid) < 2) @@ -1550,14 +1580,17 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param) /* In this case, param->obduuid will be an array of obduuids and * obd index for all these obduuids will be returned in * param->obdindexes */ -static int setup_obd_indexes(DIR *dir, char *path, struct find_param *param) +static int setup_indexes(DIR *dir, char *path, struct obd_uuid *obduuids, + int num_obds, int **obdindexes, int *obdindex, + enum tgt_type type) { int ret, obdcount, obd_valid = 0, obdnum, i; struct obd_uuid *uuids = NULL; char buf[16]; + int *indexes; - ret = get_param_obdvar(NULL, path, "lov", "numobd", - buf, sizeof(buf)); + ret = get_param_obdvar(NULL, path, type == LOV_TYPE ? "lov" : "lmv", + "numobd", buf, sizeof(buf)); if (ret) return ret; @@ -1568,8 +1601,7 @@ static int setup_obd_indexes(DIR *dir, char *path, struct find_param *param) return -ENOMEM; retry_get_uuids: - ret = llapi_lov_get_uuids(dirfd(dir), uuids, - &obdcount); + ret = llapi_get_target_uuids(dirfd(dir), uuids, &obdcount, type); if (ret) { struct obd_uuid *uuids_temp; @@ -1583,39 +1615,63 @@ retry_get_uuids: } llapi_error(LLAPI_MSG_ERROR, ret, "get ost uuid failed"); - return ret; + goto out_free; } - param->obdindexes = malloc(param->num_obds * sizeof(param->obdindex)); - if (param->obdindexes == NULL) - return -ENOMEM; + indexes = malloc(num_obds * sizeof(*obdindex)); + if (indexes == NULL) { + ret = -ENOMEM; + goto out_free; + } - for (obdnum = 0; obdnum < param->num_obds; obdnum++) { + for (obdnum = 0; obdnum < num_obds; obdnum++) { for (i = 0; i < obdcount; i++) { if (llapi_uuid_match(uuids[i].uuid, - param->obduuid[obdnum].uuid)) { - param->obdindexes[obdnum] = i; + obduuids[obdnum].uuid)) { + indexes[obdnum] = i; obd_valid++; break; } } if (i >= obdcount) { - param->obdindexes[obdnum] = OBD_NOT_FOUND; + indexes[obdnum] = OBD_NOT_FOUND; llapi_err_noerrno(LLAPI_MSG_ERROR, "error: %s: unknown obduuid: %s", - __func__, - param->obduuid[obdnum].uuid); + __func__, obduuids[obdnum].uuid); ret = -EINVAL; } } if (obd_valid == 0) - param->obdindex = OBD_NOT_FOUND; + *obdindex = OBD_NOT_FOUND; else - param->obdindex = obd_valid; + *obdindex = obd_valid; - param->got_uuids = 1; + *obdindexes = indexes; +out_free: + if (uuids) + free(uuids); + + return ret; +} + +static int setup_target_indexes(DIR *dir, char *path, struct find_param *param) +{ + int ret = 0; + if (param->mdtuuid) { + ret = setup_indexes(dir, path, param->mdtuuid, param->num_mdts, + ¶m->mdtindexes, ¶m->mdtindex, LMV_TYPE); + if (ret) + return ret; + } + if (param->obduuid) { + ret = setup_indexes(dir, path, param->obduuid, param->num_obds, + ¶m->obdindexes, ¶m->obdindex, LOV_TYPE); + if (ret) + return ret; + } + param->got_uuids = 1; return ret; } @@ -2154,6 +2210,104 @@ static int find_time_check(lstat_t *st, struct find_param *param, int mds) return rc; } +/** + * Check whether the stripes matches the indexes user provided + * 1 : matched + * 0 : Unmatched + */ +static int check_obd_match(struct find_param *param) +{ + lstat_t *st = ¶m->lmd->lmd_st; + struct lov_user_ost_data_v1 *lmm_objects; + int i, j; + + if (param->obduuid && param->obdindex == OBD_NOT_FOUND) + return 0; + + if (!S_ISREG(st->st_mode)) + return 0; + + /* Only those files should be accepted, which have a + * stripe on the specified OST. */ + if (!param->lmd->lmd_lmm.lmm_stripe_count) + return 0; + + if (param->lmd->lmd_lmm.lmm_magic == + LOV_USER_MAGIC_V3) { + struct lov_user_md_v3 *lmmv3 = (void *)¶m->lmd->lmd_lmm; + + lmm_objects = lmmv3->lmm_objects; + } else if (param->lmd->lmd_lmm.lmm_magic == LOV_USER_MAGIC_V1) { + lmm_objects = param->lmd->lmd_lmm.lmm_objects; + } else { + llapi_err_noerrno(LLAPI_MSG_ERROR, "%s:Unknown magic: 0x%08X\n", + __func__, param->lmd->lmd_lmm.lmm_magic); + return -EINVAL; + } + + for (i = 0; i < param->lmd->lmd_lmm.lmm_stripe_count; i++) { + for (j = 0; j < param->num_obds; j++) { + if (param->obdindexes[j] == + lmm_objects[i].l_ost_idx) { + if (param->exclude_obd) + return 0; + return 1; + } + } + } + + if (param->exclude_obd) + return 1; + return 0; +} + +static int check_mdt_match(struct find_param *param) +{ + int i; + + if (param->mdtuuid && param->mdtindex == OBD_NOT_FOUND) + return 0; + + /* FIXME: For striped dir, we should get stripe information and check */ + for (i = 0; i < param->num_mdts; i++) { + if (param->mdtindexes[i] == param->file_mdtindex) + if (param->exclude_mdt) + return 0; + return 1; + } + + if (param->exclude_mdt) + return 1; + return 0; +} + +/** + * Check whether the obd is active or not, if it is + * not active, just print the object affected by this + * failed target + **/ +static int print_failed_tgt(struct find_param *param, char *path, int type) +{ + struct obd_statfs stat_buf; + struct obd_uuid uuid_buf; + int ret; + + LASSERT(type == LL_STATFS_LOV || type == LL_STATFS_LMV); + + memset(&stat_buf, 0, sizeof(struct obd_statfs)); + memset(&uuid_buf, 0, sizeof(struct obd_uuid)); + ret = llapi_obd_statfs(path, type, + param->obdindex, &stat_buf, + &uuid_buf); + if (ret) { + llapi_printf(LLAPI_MSG_NORMAL, + "obd_uuid: %s failed %s ", + param->obduuid->uuid, + strerror(errno)); + } + return ret; +} + static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data, cfs_dirent_t *de) { @@ -2192,21 +2346,56 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, } } - ret = 0; /* Request MDS for the stat info if some of these parameters need * to be compared. */ - if (param->obduuid || param->check_uid || param->check_gid || - param->check_pool || param->atime || param->ctime || - param->mtime || param->check_size) + if (param->obduuid || param->mdtuuid || param->check_uid || + param->check_gid || param->check_pool || param->atime || + param->ctime || param->mtime || param->check_size) decision = 0; + if (param->type && checked_type == 0) decision = 0; if (param->have_fileinfo == 0 && decision == 0) { ret = get_lmd_info(path, parent, dir, param->lmd, - param->lumlen); + param->lumlen); + if (ret == 0) { + if (dir) { + ret = llapi_file_fget_mdtidx(dirfd(dir), + ¶m->file_mdtindex); + } else { + int fd; + lstat_t tmp_st; + + ret = lstat_f(path, &tmp_st); + if (ret) { + ret = -errno; + llapi_error(LLAPI_MSG_ERROR, ret, + "error: %s: lstat failed" + "for %s", __func__, path); + return ret; + } + if (S_ISREG(tmp_st.st_mode)) { + fd = open(path, O_RDONLY); + if (fd > 0) { + ret = llapi_file_fget_mdtidx(fd, + ¶m->file_mdtindex); + close(fd); + } else { + ret = fd; + } + } else { + /* For special inode, it assumes to + * reside on the same MDT with the + * parent */ + fd = dirfd(parent); + ret = llapi_file_fget_mdtidx(fd, + ¶m->file_mdtindex); + } + } + } if (ret) { if (ret == -ENOTTY) lustre_fs = 0; @@ -2227,18 +2416,18 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, } /* Prepare odb. */ - if (param->obduuid) { + if (param->obduuid || param->mdtuuid) { if (lustre_fs && param->got_uuids && param->st_dev != st->st_dev) { /* A lustre/lustre mount point is crossed. */ param->got_uuids = 0; param->obds_printed = 0; - param->obdindex = OBD_NOT_FOUND; + param->obdindex = param->mdtindex = OBD_NOT_FOUND; } if (lustre_fs && !param->got_uuids) { - ret = setup_obd_indexes(dir ? dir : parent, path, - param); + ret = setup_target_indexes(dir ? dir : parent, path, + param); if (ret) return ret; @@ -2246,59 +2435,36 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, } else if (!lustre_fs && param->got_uuids) { /* A lustre/non-lustre mount point is crossed. */ param->got_uuids = 0; - param->obdindex = OBD_NOT_FOUND; + param->obdindex = param->mdtindex = OBD_NOT_FOUND; } } - /* If an OBD UUID is specified but no one matches, skip this file. */ - if (param->obduuid && param->obdindex == OBD_NOT_FOUND) + if ((param->obduuid && param->obdindex == OBD_NOT_FOUND) || + (param->mdtuuid && param->mdtindex == OBD_NOT_FOUND)) goto decided; - /* If a OST UUID is given, and some OST matches, check it here. */ - if (param->obdindex != OBD_NOT_FOUND) { - if (!S_ISREG(st->st_mode)) - goto decided; - - /* Only those files should be accepted, which have a - * stripe on the specified OST. */ - if (!param->lmd->lmd_lmm.lmm_stripe_count) { - goto decided; - } else { - int i, j; - struct lov_user_ost_data_v1 *lmm_objects; - - if (param->lmd->lmd_lmm.lmm_magic == - LOV_USER_MAGIC_V3) { - struct lov_user_md_v3 *lmmv3 = - (void *)¶m->lmd->lmd_lmm; - - lmm_objects = lmmv3->lmm_objects; + /* If a OST or MDT UUID is given, and some OST matches, + * check it here. */ + if (param->obdindex != OBD_NOT_FOUND || + param->mdtindex != OBD_NOT_FOUND) { + if (param->obduuid) { + if (check_obd_match(param)) { + /* If no mdtuuid is given, we are done. + * Otherwise, fall through to the mdtuuid + * check below. */ + if (!param->mdtuuid) + goto obd_matches; } else { - lmm_objects = param->lmd->lmd_lmm.lmm_objects; - } - - for (i = 0; - i < param->lmd->lmd_lmm.lmm_stripe_count; i++) { - for (j = 0; j < param->num_obds; j++) { - if (param->obdindexes[j] == - lmm_objects[i].l_ost_idx) { - if (param->exclude_obd) - goto decided; - break; - } - } - /* If an OBD matches, just break */ - if (j != param->num_obds) - break; - } - - if (i == param->lmd->lmd_lmm.lmm_stripe_count) { - if (!param->exclude_obd) - goto decided; + goto decided; } } + if (param->mdtuuid) { + if (check_mdt_match(param)) + goto obd_matches; + goto decided; + } } - +obd_matches: if (param->check_uid) { if (st->st_uid == param->uid) { if (param->exclude_uid) @@ -2362,30 +2528,16 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, while (!decision) { /* For regular files with the stripe the decision may have not * been taken yet if *time or size is to be checked. */ - LASSERT(S_ISREG(st->st_mode) && - param->lmd->lmd_lmm.lmm_stripe_count); - - if (param->obdindex != OBD_NOT_FOUND) { - /* Check whether the obd is active or not, if it is - * not active, just print the object affected by this - * failed ost - * */ - struct obd_statfs stat_buf; - struct obd_uuid uuid_buf; - - memset(&stat_buf, 0, sizeof(struct obd_statfs)); - memset(&uuid_buf, 0, sizeof(struct obd_uuid)); - ret = llapi_obd_statfs(path, LL_STATFS_LOV, - param->obdindex, &stat_buf, - &uuid_buf); - if (ret) { - llapi_printf(LLAPI_MSG_NORMAL, - "obd_uuid: %s failed %s ", - param->obduuid->uuid, - strerror(errno)); - break; - } - } + LASSERT((S_ISREG(st->st_mode) && + param->lmd->lmd_lmm.lmm_stripe_count) || + param->mdtindex != OBD_NOT_FOUND); + + if (param->obdindex != OBD_NOT_FOUND) + print_failed_tgt(param, path, LL_STATFS_LOV); + + if (param->mdtindex != OBD_NOT_FOUND) + print_failed_tgt(param, path, LL_STATFS_LMV); + if (dir) { ret = ioctl(dirfd(dir), IOC_LOV_GETINFO, (void *)param->lmd); @@ -2451,7 +2603,7 @@ int llapi_find(char *path, struct find_param *param) */ int llapi_file_fget_mdtidx(int fd, int *mdtidx) { - if (ioctl(fd, LL_IOC_GET_MDTIDX, &mdtidx) < 0) + if (ioctl(fd, LL_IOC_GET_MDTIDX, mdtidx) < 0) return -errno; return 0; } @@ -2502,7 +2654,7 @@ static int cb_get_mdt_index(char *path, DIR *parent, DIR *d, void *data, return ret; } - if (param->quiet) + if (param->quiet || !(param->verbose & VERBOSE_DETAIL)) llapi_printf(LLAPI_MSG_NORMAL, "%d\n", mdtidx); else llapi_printf(LLAPI_MSG_NORMAL, "%s MDT index: %d\n", -- 1.8.3.1