X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fliblustreapi.c;h=d3c99c65808b6591acb136ef30db00251c8eb33d;hp=b2842c8948bc02f6e1a15fce19b47365bb657d2f;hb=281671b5ee43c2aea5d5b708aadf10fd1df45b16;hpb=27f77f5de6fe27611c9f819f8cdaba89d70f15d9 diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index b2842c8..d3c99c6 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2013, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -69,54 +69,12 @@ #endif #include -#include +#include #include -#include -#include #include +#include #include "lustreapi_internal.h" -static unsigned llapi_dir_filetype_table[] = { - [DT_UNKNOWN]= 0, - [DT_FIFO]= S_IFIFO, - [DT_CHR] = S_IFCHR, - [DT_DIR] = S_IFDIR, - [DT_BLK] = S_IFBLK, - [DT_REG] = S_IFREG, - [DT_LNK] = S_IFLNK, - [DT_SOCK]= S_IFSOCK, -#if defined(DT_DOOR) && defined(S_IFDOOR) - [DT_DOOR]= S_IFDOOR, -#endif -}; - -#if defined(DT_DOOR) && defined(S_IFDOOR) -static const int DT_MAX = DT_DOOR; -#else -static const int DT_MAX = DT_SOCK; -#endif - -static unsigned llapi_filetype_dir_table[] = { - [0]= DT_UNKNOWN, - [S_IFIFO]= DT_FIFO, - [S_IFCHR] = DT_CHR, - [S_IFDIR] = DT_DIR, - [S_IFBLK] = DT_BLK, - [S_IFREG] = DT_REG, - [S_IFLNK] = DT_LNK, - [S_IFSOCK]= DT_SOCK, -#if defined(DT_DOOR) && defined(S_IFDOOR) - [S_IFDOOR]= DT_DOOR, -#endif -}; - -#if defined(DT_DOOR) && defined(S_IFDOOR) -static const int S_IFMAX = DT_DOOR; -#else -static const int S_IFMAX = DT_SOCK; -#endif - -/* liblustreapi message level */ static int llapi_msg_level = LLAPI_MSG_MAX; void llapi_msg_set_level(int level) @@ -130,48 +88,97 @@ void llapi_msg_set_level(int level) llapi_msg_level = level; } -/* llapi_error will preserve errno */ -void llapi_error(int level, int _rc, char *fmt, ...) +static void error_callback_default(enum llapi_message_level level, int err, + const char *fmt, va_list ap) +{ + vfprintf(stderr, fmt, ap); + if (level & LLAPI_MSG_NO_ERRNO) + fprintf(stderr, "\n"); + else + fprintf(stderr, ": %s (%d)\n", strerror(err), err); +} + +static void info_callback_default(enum llapi_message_level level, int err, + const char *fmt, va_list ap) { - va_list args; - int tmp_errno = errno; - /* to protect using errno as _rc argument */ - int rc = abs(_rc); + vfprintf(stdout, fmt, ap); +} - if ((level & LLAPI_MSG_MASK) > llapi_msg_level) - return; +static llapi_log_callback_t llapi_error_callback = error_callback_default; +static llapi_log_callback_t llapi_info_callback = info_callback_default; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - if (level & LLAPI_MSG_NO_ERRNO) - fprintf(stderr, "\n"); - else - fprintf(stderr, ": %s (%d)\n", strerror(rc), rc); - errno = tmp_errno; +/* llapi_error will preserve errno */ +void llapi_error(enum llapi_message_level level, int err, const char *fmt, ...) +{ + va_list args; + int tmp_errno = errno; + + if ((level & LLAPI_MSG_MASK) > llapi_msg_level) + return; + + va_start(args, fmt); + llapi_error_callback(level, abs(err), fmt, args); + va_end(args); + errno = tmp_errno; } /* llapi_printf will preserve errno */ -void llapi_printf(int level, char *fmt, ...) +void llapi_printf(enum llapi_message_level level, const char *fmt, ...) +{ + va_list args; + int tmp_errno = errno; + + if ((level & LLAPI_MSG_MASK) > llapi_msg_level) + return; + + va_start(args, fmt); + llapi_info_callback(level, 0, fmt, args); + va_end(args); + errno = tmp_errno; +} + +/** + * Set a custom error logging function. Passing in NULL will reset the logging + * callback to its default value. + * + * This function returns the value of the old callback. + */ +llapi_log_callback_t llapi_error_callback_set(llapi_log_callback_t cb) +{ + llapi_log_callback_t old = llapi_error_callback; + + if (cb != NULL) + llapi_error_callback = cb; + else + llapi_error_callback = error_callback_default; + + return old; +} + +/** + * Set a custom info logging function. Passing in NULL will reset the logging + * callback to its default value. + * + * This function returns the value of the old callback. + */ +llapi_log_callback_t llapi_info_callback_set(llapi_log_callback_t cb) { - va_list args; - int tmp_errno = errno; + llapi_log_callback_t old = llapi_info_callback; - if ((level & LLAPI_MSG_MASK) > llapi_msg_level) - return; + if (cb != NULL) + llapi_info_callback = cb; + else + llapi_info_callback = info_callback_default; - va_start(args, fmt); - vfprintf(stdout, fmt, args); - va_end(args); - errno = tmp_errno; + return old; } /** * size_units is to be initialized (or zeroed) by caller. */ -int parse_size(char *optarg, unsigned long long *size, - unsigned long long *size_units, int bytes_spec) +int llapi_parse_size(const char *optarg, unsigned long long *size, + unsigned long long *size_units, int bytes_spec) { char *end; @@ -241,14 +248,14 @@ int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset, "larger than expected (%u)", page_size, LOV_MIN_STRIPE_SIZE); } - if (stripe_size < 0 || (stripe_size & (LOV_MIN_STRIPE_SIZE - 1))) { + if ((stripe_size & (LOV_MIN_STRIPE_SIZE - 1))) { rc = -EINVAL; - llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe_size %lu, " + llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe_size %llu, " "must be an even multiple of %d bytes", stripe_size, page_size); return rc; } - if (stripe_offset < -1 || stripe_offset > MAX_OBD_DEVICES) { + if (stripe_offset < -1) { rc = -EINVAL; llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe offset %d", stripe_offset); @@ -331,6 +338,24 @@ static int find_poolpath(char *fsname, char *poolname, char *poolpath) return 0; } +/* + * Trim a trailing newline from a string, if it exists. + */ +int llapi_chomp_string(char *buf) +{ + if (!buf || !*buf) + return 0; + + while (buf[1]) + buf++; + + if (*buf != '\n') + return 0; + + *buf = '\0'; + return '\n'; +} + /** * return a parameter string for a specific device type or mountpoint * @@ -348,7 +373,7 @@ static int find_poolpath(char *fsname, char *poolname, char *poolpath) * Return 0 for success, with a NUL-terminated string in \param result. * Return -ve value for error. */ -static int get_param(const char *param_path, char *result, +int get_param(const char *param_path, char *result, unsigned int result_size) { char file[PATH_MAX + 1], pattern[PATH_MAX + 1], buf[result_size]; @@ -358,7 +383,7 @@ static int get_param(const char *param_path, char *result, snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s", param_path); rc = first_match(pattern, file); - if (rc) + if (rc != 0 || result == NULL) return rc; fp = fopen(file, "r"); @@ -416,7 +441,12 @@ static int get_param_obdvar(const char *fsname, const char *file_path, return rc; } } else if (fsname) { - strcpy(fs, fsname); + if (strlen(fsname) > sizeof(fs)-1) { + if (fp != NULL) + fclose(fp); + return -E2BIG; + } + strncpy(fs, fsname, sizeof(fs)); } if (fp == NULL) { @@ -436,9 +466,14 @@ static int get_param_obdvar(const char *fsname, const char *file_path, tmp += strlen(obd_type) + 1; if (strcmp(tmp, fs)) continue; - strcpy(dev, tmp); + if (strlen(tmp) > sizeof(dev)-1) { + fclose(fp); + return -E2BIG; + } + strncpy(dev, tmp, sizeof(dev)); tmp = strchr(dev, ' '); - *tmp = '\0'; + if (tmp != NULL) + *tmp = '\0'; break; } } @@ -450,16 +485,100 @@ static int get_param_obdvar(const char *fsname, const char *file_path, return get_param(devices, value, val_len); } -static int get_mds_md_size(char *path) +/* + * TYPE one of llite, lmv, lov. + * /proc/fs/lustre/TYPE/INST the directory of interest. + */ +static int get_param_cli(const char *type, const char *inst, + const char *param, char *buf, size_t buf_size) { - int lumlen = lov_mds_md_size(LOV_MAX_STRIPE_COUNT, LOV_MAGIC_V3); - char buf[16]; + char param_path[PATH_MAX + 1]; + FILE *param_file = NULL; + int rc; + + snprintf(param_path, sizeof(param_path), + "/proc/fs/lustre/%s/%s/%s", type, inst, param); + + param_file = fopen(param_path, "r"); + if (param_file == NULL) { + rc = -errno; + goto out; + } + + if (fgets(buf, buf_size, param_file) == NULL) { + rc = -errno; + goto out; + } + + rc = 0; +out: + if (param_file != NULL) + fclose(param_file); + + return rc; +} + +static int get_param_llite(const char *path, + const char *param, char *buf, size_t buf_size) +{ + char inst[80]; + int rc; + + rc = llapi_getname(path, inst, sizeof(inst)); + if (rc != 0) + return rc; + + return get_param_cli("llite", inst, param, buf, buf_size); +} - /* Now get the maxea from llite proc */ - if (!get_param_obdvar(NULL, path, "llite", "max_easize", - buf, sizeof(buf))) - lumlen = atoi(buf); - return lumlen; +static int get_param_lov(const char *path, + const char *param, char *buf, size_t buf_size) +{ + struct obd_uuid uuid; + int rc; + + rc = llapi_file_get_lov_uuid(path, &uuid); + if (rc != 0) + return rc; + + return get_param_cli("lov", uuid.uuid, param, buf, buf_size); +} + +static int get_param_lmv(const char *path, + const char *param, char *buf, size_t buf_size) +{ + struct obd_uuid uuid; + int rc; + + rc = llapi_file_get_lmv_uuid(path, &uuid); + if (rc != 0) + return rc; + + return get_param_cli("lmv", uuid.uuid, param, buf, buf_size); +} + +static int get_mds_md_size(const char *path) +{ + int md_size = lov_user_md_size(LOV_MAX_STRIPE_COUNT, LOV_USER_MAGIC_V3); + char buf[80]; + int rc; + + /* Get the max ea size from llite proc. */ + rc = get_param_llite(path, "max_easize", buf, sizeof(buf)); + if (rc != 0) + goto out; + + rc = atoi(buf); + if (rc > 0) + md_size = rc; + +out: + return md_size; +} + +int llapi_get_agent_uuid(char *path, char *buf, size_t bufsize) +{ + return get_param_lmv(path, "uuid", buf, bufsize); } /* @@ -478,10 +597,14 @@ int llapi_search_ost(char *fsname, char *poolname, char *ostname) if (ostname != NULL) len = strlen(ostname); - if (poolname == NULL) - rc = find_target_obdpath(fsname, buffer); - else + if (poolname == NULL) { + if (len == 0) + rc = -EINVAL; + else + rc = find_target_obdpath(fsname, buffer); + } else { rc = find_poolpath(fsname, poolname, buffer); + } if (rc) return rc; @@ -515,12 +638,11 @@ int llapi_search_ost(char *fsname, char *poolname, char *ostname) } int llapi_file_open_pool(const char *name, int flags, int mode, - unsigned long long stripe_size, int stripe_offset, - int stripe_count, int stripe_pattern, char *pool_name) + unsigned long long stripe_size, int stripe_offset, + int stripe_count, int stripe_pattern, char *pool_name) { - struct lov_user_md_v3 lum = { 0 }; - int fd, rc = 0; - int isdir = 0; + struct lov_user_md_v3 lum = { 0 }; + int fd, rc = 0; /* Make sure we have a good pool */ if (pool_name != NULL) { @@ -559,11 +681,14 @@ int llapi_file_open_pool(const char *name, int flags, int mode, } } - fd = open(name, flags | O_LOV_DELAY_CREATE, mode); - if (fd < 0 && errno == EISDIR) { - fd = open(name, O_DIRECTORY | O_RDONLY); - isdir++; - } +retry_open: + fd = open(name, flags | O_LOV_DELAY_CREATE, mode); + if (fd < 0) { + if (errno == EISDIR && !(flags & O_DIRECTORY)) { + flags = O_DIRECTORY | O_RDONLY; + goto retry_open; + } + } if (fd < 0) { rc = -errno; @@ -648,12 +773,53 @@ int llapi_file_create_pool(const char *name, unsigned long long stripe_size, return 0; } -/** - * In DNE phase I, only stripe_offset will be used in this function. - * stripe_count, stripe_pattern and pool_name will be supported later. - */ +int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset, + int stripe_count, int stripe_pattern, + const char *pool_name) +{ + struct lmv_user_md lum = { 0 }; + int fd; + int rc = 0; + + lum.lum_magic = LMV_USER_MAGIC; + lum.lum_stripe_offset = stripe_offset; + lum.lum_stripe_count = stripe_count; + lum.lum_hash_type = stripe_pattern; + if (pool_name != NULL) { + if (strlen(pool_name) >= sizeof(lum.lum_pool_name)) { + llapi_err_noerrno(LLAPI_MSG_ERROR, + "error LL_IOC_LMV_SET_DEFAULT_STRIPE '%s'" + ": too large pool name: %s", name, pool_name); + return -E2BIG; + } + strncpy(lum.lum_pool_name, pool_name, strlen(pool_name)); + } + + fd = open(name, O_DIRECTORY | O_RDONLY); + if (fd < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name); + return rc; + } + + rc = ioctl(fd, LL_IOC_LMV_SET_DEFAULT_STRIPE, &lum); + if (rc < 0) { + char *errmsg = "stripe already set"; + rc = -errno; + if (errno != EEXIST && errno != EALREADY) + errmsg = strerror(errno); + + llapi_err_noerrno(LLAPI_MSG_ERROR, + "error on LL_IOC_LMV_SETSTRIPE '%s' (%d): %s", + name, fd, errmsg); + } + close(fd); + return rc; +} + int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, - int stripe_count, int stripe_pattern, char *pool_name) + int stripe_count, int stripe_pattern, + const char *pool_name) { struct lmv_user_md lmu = { 0 }; struct obd_ioctl_data data = { 0 }; @@ -680,13 +846,13 @@ int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, llapi_err_noerrno(LLAPI_MSG_ERROR, "error LL_IOC_LMV_SETSTRIPE '%s' : too large" "pool name: %s", name, pool_name); - GOTO(out, rc = -E2BIG); + rc = -E2BIG; + goto out; } memcpy(lmu.lum_pool_name, pool_name, strlen(pool_name)); } filename = basename(namepath); - lmu.lum_type = LMV_STRIPE_TYPE; dir = dirname(dirpath); data.ioc_inlbuf1 = (char *)filename; @@ -698,14 +864,14 @@ int llapi_dir_create_pool(const char *name, int flags, int stripe_offset, llapi_error(LLAPI_MSG_ERROR, rc, "error: LL_IOC_LMV_SETSTRIPE pack failed '%s'.", name); - GOTO(out, rc); + goto out; } fd = open(dir, O_DIRECTORY | O_RDONLY); if (fd < 0) { rc = -errno; llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name); - GOTO(out, rc); + goto out; } if (ioctl(fd, LL_IOC_LMV_SETSTRIPE, buf)) { @@ -748,7 +914,7 @@ int llapi_direntry_remove(char *dname) rc = -errno; llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", filename); - GOTO(out, rc); + goto out; } if (ioctl(fd, LL_IOC_REMOVE_ENTRY, filename)) { @@ -799,10 +965,11 @@ int get_root_path(int want, char *fsname, int *outfd, char *path, int index) mntlen = strlen(mnt.mnt_dir); ptr = strrchr(mnt.mnt_fsname, '/'); - if (!ptr && !len) { - rc = -EINVAL; - break; - } + /* thanks to the call to llapi_is_lustre_mnt() above, + * we are sure that mnt.mnt_fsname contains ":/", + * so ptr should never be NULL */ + if (ptr == NULL) + continue; ptr++; /* Check the fsname for a match, if given */ @@ -1107,10 +1274,14 @@ int llapi_get_poollist(const char *name, char **poollist, int list_size, " a Lustre filesystem", name); return rc; } - strcpy(fsname, rname); + if (strlen(rname) > sizeof(fsname)-1) + return -E2BIG; + strncpy(fsname, rname, sizeof(fsname)); } else { /* name is FSNAME */ - strcpy(fsname, name); + if (strlen(name) > sizeof(fsname)-1) + return -E2BIG; + strncpy(fsname, name, sizeof(fsname)); rc = poolpath(fsname, NULL, pathname); } if (rc != 0) { @@ -1233,18 +1404,23 @@ err: return rc; } -typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d, +typedef int (semantic_func_t)(char *path, DIR *parent, DIR **d, void *data, struct dirent64 *de); #define OBD_NOT_FOUND (-1) static int common_param_init(struct find_param *param, char *path) { - param->lumlen = get_mds_md_size(path); + int lumlen = get_mds_md_size(path); + + if (lumlen < PATH_MAX + 1) + lumlen = PATH_MAX + 1; + + param->lumlen = lumlen; param->lmd = malloc(sizeof(lstat_t) + param->lumlen); if (param->lmd == NULL) { llapi_error(LLAPI_MSG_ERROR, -ENOMEM, - "error: allocation of %d bytes for ioctl", + "error: allocation of %zu bytes for ioctl", sizeof(lstat_t) + param->lumlen); return -ENOMEM; } @@ -1261,7 +1437,8 @@ static int common_param_init(struct find_param *param, char *path) param->got_uuids = 0; param->obdindexes = NULL; param->obdindex = OBD_NOT_FOUND; - param->mdtindex = OBD_NOT_FOUND; + if (!param->migrate) + param->mdtindex = OBD_NOT_FOUND; return 0; } @@ -1277,12 +1454,13 @@ static void find_param_fini(struct find_param *param) free(param->fp_lmv_md); } -static int cb_common_fini(char *path, DIR *parent, DIR *d, void *data, +static int cb_common_fini(char *path, DIR *parent, DIR **dirp, void *data, struct dirent64 *de) { - struct find_param *param = (struct find_param *)data; - param->depth--; - return 0; + struct find_param *param = data; + param->fp_depth--; + + return 0; } /* set errno upon failure */ @@ -1309,8 +1487,12 @@ static int cb_get_dirstripe(char *path, DIR *d, struct find_param *param) int ret = 0; lmv->lum_stripe_count = param->fp_lmv_count; - lmv->lum_magic = LMV_MAGIC_V1; + if (param->get_default_lmv) + lmv->lum_magic = LMV_USER_MAGIC; + else + lmv->lum_magic = LMV_MAGIC_V1; ret = ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, lmv); + return ret; } @@ -1332,8 +1514,6 @@ static int get_lmd_info(char *path, DIR *parent, DIR *dir, /* retrieve needed file info */ strncpy((char *)lmd, fname, lumlen); ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO, (void *)lmd); - } else { - return ret; } if (ret) { @@ -1368,14 +1548,6 @@ static int get_lmd_info(char *path, DIR *parent, DIR *dir, return ret; } -int llapi_mds_getfileinfo(char *path, DIR *parent, - struct lov_user_mds_data *lmd) -{ - int lumlen = get_mds_md_size(path); - - return get_lmd_info(path, parent, NULL, lmd, lumlen); -} - static int llapi_semantic_traverse(char *path, int size, DIR *parent, semantic_func_t sem_init, semantic_func_t sem_fini, void *data, @@ -1398,15 +1570,19 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, } else if (!d && !parent) { /* ENOTDIR. Open the parent dir. */ p = opendir_parent(path); - if (!p) - GOTO(out, ret = -errno); + if (!p) { + ret = -errno; + goto out; + } } - if (sem_init && (ret = sem_init(path, parent ?: p, d, data, de))) - goto err; + if (sem_init && (ret = sem_init(path, parent ?: p, &d, data, de))) + goto err; - if (!d || (param->get_lmv && !param->recursive)) - GOTO(out, ret = 0); + if (!d || (param->get_lmv && !param->recursive)) { + ret = 0; + goto out; + } while ((dent = readdir64(d)) != NULL) { param->have_fileinfo = 0; @@ -1431,12 +1607,11 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, if (dent->d_type == DT_UNKNOWN) { lstat_t *st = ¶m->lmd->lmd_st; - ret = llapi_mds_getfileinfo(path, d, param->lmd); - if (ret == 0) { - dent->d_type = - llapi_filetype_dir_table[st->st_mode & - S_IFMT]; - } + ret = get_lmd_info(path, d, NULL, param->lmd, + param->lumlen); + if (ret == 0) + dent->d_type = IFTODT(st->st_mode); + if (ret == -ENOENT) continue; } @@ -1467,8 +1642,8 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent, out: path[len] = 0; - if (sem_fini) - sem_fini(path, parent, d, data, de); + if (sem_fini) + sem_fini(path, parent, &d, data, de); err: if (d) closedir(d); @@ -1498,7 +1673,8 @@ static int param_callback(char *path, semantic_func_t sem_init, ret = common_param_init(param, buf); if (ret) goto out; - param->depth = 0; + + param->fp_depth = 0; ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, sem_init, sem_fini, param, NULL); @@ -1545,6 +1721,23 @@ int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid) return rc; } +int llapi_file_get_lmv_uuid(const char *path, struct obd_uuid *lov_uuid) +{ + int fd, rc; + + fd = open(path, O_RDONLY); + if (fd < 0) { + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, "error opening %s", path); + return rc; + } + + rc = llapi_file_fget_lmv_uuid(fd, lov_uuid); + + close(fd); + return rc; +} + enum tgt_type { LOV_TYPE = 1, LMV_TYPE @@ -1729,15 +1922,18 @@ 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; + int ret, obdcount, obd_valid = 0, obdnum; + long i; struct obd_uuid *uuids = NULL; char buf[16]; int *indexes; - ret = get_param_obdvar(NULL, path, type == LOV_TYPE ? "lov" : "lmv", - "numobd", buf, sizeof(buf)); - if (ret) - return ret; + if (type == LOV_TYPE) + ret = get_param_lov(path, "numobd", buf, sizeof(buf)); + else + ret = get_param_lmv(path, "numobd", buf, sizeof(buf)); + if (ret != 0) + return ret; obdcount = atoi(buf); uuids = (struct obd_uuid *)malloc(obdcount * @@ -2018,11 +2214,11 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, int raw, char *pool_name) { char *prefix = is_dir ? "" : "lmm_"; - char nl = is_dir ? ' ' : '\n'; + char *seperator = ""; int rc; - if (is_dir && ostid_seq(&lum->lmm_oi) == FID_SEQ_LOV_DEFAULT) { - lum->lmm_oi.oi_seq = FID_SEQ_OST_MDT0; + if (is_dir && lmm_oi_seq(&lum->lmm_oi) == FID_SEQ_LOV_DEFAULT) { + lmm_oi_set_seq(&lum->lmm_oi, 0); if (verbose & VERBOSE_DETAIL) llapi_printf(LLAPI_MSG_NORMAL, "(Default) "); } @@ -2034,9 +2230,9 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, llapi_printf(LLAPI_MSG_NORMAL, "lmm_magic: 0x%08X\n", lum->lmm_magic); llapi_printf(LLAPI_MSG_NORMAL, "lmm_seq: "LPX64"\n", - ostid_seq(&lum->lmm_oi)); + lmm_oi_seq(&lum->lmm_oi)); llapi_printf(LLAPI_MSG_NORMAL, "lmm_object_id: "LPX64"\n", - ostid_id(&lum->lmm_oi)); + lmm_oi_id(&lum->lmm_oi)); } if (verbose & VERBOSE_COUNT) { @@ -2050,25 +2246,27 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, &scount, NULL, NULL); if (rc == 0) - llapi_printf(LLAPI_MSG_NORMAL, "%d%c", - scount, nl); + llapi_printf(LLAPI_MSG_NORMAL, "%d", + scount); else llapi_error(LLAPI_MSG_ERROR, rc, "Cannot determine default" " stripe count."); } else { - llapi_printf(LLAPI_MSG_NORMAL, "%d%c", + llapi_printf(LLAPI_MSG_NORMAL, "%d", lum->lmm_stripe_count == (typeof(lum->lmm_stripe_count))(-1) - ? -1 : lum->lmm_stripe_count, nl); + ? -1 : lum->lmm_stripe_count); } } else { - llapi_printf(LLAPI_MSG_NORMAL, "%hd%c", - (__s16)lum->lmm_stripe_count, nl); + llapi_printf(LLAPI_MSG_NORMAL, "%hd", + (__s16)lum->lmm_stripe_count); } + seperator = is_dir ? " " : "\n"; } if (verbose & VERBOSE_SIZE) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); if (verbose & ~VERBOSE_SIZE) llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_size: ", prefix); @@ -2077,53 +2275,62 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path, rc = sattr_cache_get_defaults(NULL, path, NULL, &ssize, NULL); if (rc == 0) - llapi_printf(LLAPI_MSG_NORMAL, "%u%c", ssize, - nl); + llapi_printf(LLAPI_MSG_NORMAL, "%u", ssize); else llapi_error(LLAPI_MSG_ERROR, rc, "Cannot determine default" " stripe size."); } else { - llapi_printf(LLAPI_MSG_NORMAL, "%u%c", - lum->lmm_stripe_size, nl); + llapi_printf(LLAPI_MSG_NORMAL, "%u", + lum->lmm_stripe_size); } + seperator = is_dir ? " " : "\n"; } - if ((verbose & VERBOSE_DETAIL) && !is_dir) { - llapi_printf(LLAPI_MSG_NORMAL, "lmm_stripe_pattern: %x%c", - lum->lmm_pattern, nl); - } + if ((verbose & VERBOSE_LAYOUT) && !is_dir) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); + if (verbose & ~VERBOSE_LAYOUT) + llapi_printf(LLAPI_MSG_NORMAL, "%spattern: ", + prefix); + llapi_printf(LLAPI_MSG_NORMAL, "%.x", lum->lmm_pattern); + seperator = "\n"; + } if ((verbose & VERBOSE_GENERATION) && !is_dir) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); if (verbose & ~VERBOSE_GENERATION) llapi_printf(LLAPI_MSG_NORMAL, "%slayout_gen: ", prefix); - llapi_printf(LLAPI_MSG_NORMAL, "%u%c", - (int)lum->lmm_layout_gen, nl); + llapi_printf(LLAPI_MSG_NORMAL, "%u", + (int)lum->lmm_layout_gen); + seperator = "\n"; } if (verbose & VERBOSE_OFFSET) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); if (verbose & ~VERBOSE_OFFSET) llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_offset: ", prefix); if (is_dir) - llapi_printf(LLAPI_MSG_NORMAL, "%d%c", + llapi_printf(LLAPI_MSG_NORMAL, "%d", lum->lmm_stripe_offset == (typeof(lum->lmm_stripe_offset))(-1) ? -1 : - lum->lmm_stripe_offset, nl); + lum->lmm_stripe_offset); else - llapi_printf(LLAPI_MSG_NORMAL, "%u%c", - objects[0].l_ost_idx, nl); + llapi_printf(LLAPI_MSG_NORMAL, "%u", + objects[0].l_ost_idx); + seperator = is_dir ? " " : "\n"; } if ((verbose & VERBOSE_POOL) && (pool_name != NULL)) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); if (verbose & ~VERBOSE_POOL) llapi_printf(LLAPI_MSG_NORMAL, "%spool: ", prefix); - llapi_printf(LLAPI_MSG_NORMAL, "%s%c", pool_name, nl); + llapi_printf(LLAPI_MSG_NORMAL, "%s", pool_name); } - if (is_dir && (verbose != VERBOSE_OBJID)) + if (!is_dir || (is_dir && (verbose != VERBOSE_OBJID))) llapi_printf(LLAPI_MSG_NORMAL, "\n"); } @@ -2147,15 +2354,16 @@ void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name, lov_dump_user_lmm_header(lum, path, objects, is_dir, header, depth, raw, pool_name); - if (!is_dir && (header & VERBOSE_OBJID)) { + if (!is_dir && (header & VERBOSE_OBJID) && + !(lum->lmm_pattern & LOV_PATTERN_F_RELEASED)) { if (obdstripe == 1) llapi_printf(LLAPI_MSG_NORMAL, "\tobdidx\t\t objid\t\t objid\t\t group\n"); for (i = 0; i < lum->lmm_stripe_count; i++) { int idx = objects[i].l_ost_idx; - long long oid = objects[i].l_object_id; - long long gr = objects[i].l_object_seq; + long long oid = ostid_id(&objects[i].l_ost_oi); + long long gr = ostid_seq(&objects[i].l_ost_oi); if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx)) { char fmt[48]; sprintf(fmt, "%s%s%s\n", @@ -2179,6 +2387,7 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, struct lmv_user_mds_data *objects = lum->lum_objects; char *prefix = lum->lum_magic == LMV_USER_MAGIC ? "(Default)" : ""; int i, obdstripe = 0; + char *seperator = ""; if (obdindex != OBD_NOT_FOUND) { for (i = 0; i < lum->lum_stripe_count; i++) { @@ -2201,36 +2410,38 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, verbose = VERBOSE_OBJID; } - if (lum->lum_magic == LMV_USER_MAGIC) - verbose &= ~VERBOSE_OBJID; - if (depth && path && ((verbose != VERBOSE_OBJID))) - llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path); + llapi_printf(LLAPI_MSG_NORMAL, "%s%s\n", prefix, path); if (verbose & VERBOSE_COUNT) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); if (verbose & ~VERBOSE_COUNT) llapi_printf(LLAPI_MSG_NORMAL, "lmv_stripe_count: "); - llapi_printf(LLAPI_MSG_NORMAL, "%u\n", + llapi_printf(LLAPI_MSG_NORMAL, "%u", (int)lum->lum_stripe_count); + seperator = "\n"; } if (verbose & VERBOSE_OFFSET) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); if (verbose & ~VERBOSE_OFFSET) llapi_printf(LLAPI_MSG_NORMAL, "lmv_stripe_offset: "); - llapi_printf(LLAPI_MSG_NORMAL, "%d\n", + llapi_printf(LLAPI_MSG_NORMAL, "%d", (int)lum->lum_stripe_offset); + seperator = "\n"; } - if (verbose & VERBOSE_OBJID) { - if ((obdstripe == 1)) + if (verbose & VERBOSE_OBJID && lum->lum_magic != LMV_USER_MAGIC) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); + if (obdstripe == 1 && lum->lum_stripe_count > 0) llapi_printf(LLAPI_MSG_NORMAL, - "\tmdtidx\t\t FID[seq:oid:ver]\n"); + "mdtidx\t\t FID[seq:oid:ver]\n"); for (i = 0; i < lum->lum_stripe_count; i++) { int idx = objects[i].lum_mds; struct lu_fid *fid = &objects[i].lum_fid; if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx)) llapi_printf(LLAPI_MSG_NORMAL, - "\t%6u\t\t "DFID"\t\t%s\n", + "%6u\t\t "DFID"\t\t%s\n", idx, PFID(fid), obdindex == idx ? " *" : ""); } @@ -2238,19 +2449,23 @@ void lmv_dump_user_lmm(struct lmv_user_md *lum, char *pool_name, } if ((verbose & VERBOSE_POOL) && (pool_name[0] != '\0')) { + llapi_printf(LLAPI_MSG_NORMAL, "%s", seperator); if (verbose & ~VERBOSE_POOL) llapi_printf(LLAPI_MSG_NORMAL, "%slmv_pool: ", prefix); llapi_printf(LLAPI_MSG_NORMAL, "%s%c ", pool_name, ' '); + seperator = "\n"; } - llapi_printf(LLAPI_MSG_NORMAL, "\n"); + + if (!(verbose & VERBOSE_OBJID)) + llapi_printf(LLAPI_MSG_NORMAL, "\n"); } void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) { __u32 magic; - if (param->get_lmv) + if (param->get_lmv || param->get_default_lmv) magic = (__u32)param->fp_lmv_md->lum_magic; else magic = *(__u32 *)¶m->lmd->lmd_lmm; /* lum->lmm_magic */ @@ -2260,7 +2475,7 @@ void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) lov_dump_user_lmm_v1v3(¶m->lmd->lmd_lmm, NULL, param->lmd->lmd_lmm.lmm_objects, path, is_dir, - param->obdindex, param->maxdepth, + param->obdindex, param->fp_max_depth, param->verbose, param->raw); break; case LOV_USER_MAGIC_V3: { @@ -2273,7 +2488,7 @@ void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) objects = lmmv3->lmm_objects; lov_dump_user_lmm_v1v3(¶m->lmd->lmd_lmm, pool_name, objects, path, is_dir, - param->obdindex, param->maxdepth, + param->obdindex, param->fp_max_depth, param->verbose, param->raw); break; } @@ -2285,7 +2500,7 @@ void llapi_lov_dump_user_lmm(struct find_param *param, char *path, int is_dir) lum = (struct lmv_user_md *)param->fp_lmv_md; strncpy(pool_name, lum->lum_pool_name, LOV_MAXPOOLNAME); lmv_dump_user_lmm(lum, pool_name, path, - param->obdindex, param->maxdepth, + param->obdindex, param->fp_max_depth, param->verbose); break; } @@ -2423,46 +2638,46 @@ static int find_value_cmp(unsigned long long file, unsigned long long limit, * updated timestamps. */ static int find_time_check(lstat_t *st, struct find_param *param, int mds) { - int ret; - int rc = 1; - - /* Check if file is accepted. */ - if (param->atime) { - ret = find_value_cmp(st->st_atime, param->atime, - param->asign, param->exclude_atime, - 24 * 60 * 60, mds); - if (ret < 0) - return ret; - rc = ret; - } - - if (param->mtime) { - ret = find_value_cmp(st->st_mtime, param->mtime, - param->msign, param->exclude_mtime, - 24 * 60 * 60, mds); - if (ret < 0) - return ret; - - /* If the previous check matches, but this one is not yet clear, - * we should return 0 to do an RPC on OSTs. */ - if (rc == 1) - rc = ret; - } + int rc = 1; + int rc2; + + /* Check if file is accepted. */ + if (param->fp_atime) { + rc2 = find_value_cmp(st->st_atime, param->fp_atime, + param->fp_asign, param->fp_exclude_atime, + 24 * 60 * 60, mds); + if (rc2 < 0) + return rc2; + rc = rc2; + } - if (param->ctime) { - ret = find_value_cmp(st->st_ctime, param->ctime, - param->csign, param->exclude_ctime, - 24 * 60 * 60, mds); - if (ret < 0) - return ret; + if (param->fp_mtime) { + rc2 = find_value_cmp(st->st_mtime, param->fp_mtime, + param->fp_msign, param->fp_exclude_mtime, + 24 * 60 * 60, mds); + if (rc2 < 0) + return rc2; + + /* If the previous check matches, but this one is not yet clear, + * we should return 0 to do an RPC on OSTs. */ + if (rc == 1) + rc = rc2; + } - /* If the previous check matches, but this one is not yet clear, - * we should return 0 to do an RPC on OSTs. */ - if (rc == 1) - rc = ret; - } + if (param->fp_ctime) { + rc2 = find_value_cmp(st->st_ctime, param->fp_ctime, + param->fp_csign, param->fp_exclude_ctime, + 24 * 60 * 60, mds); + if (rc2 < 0) + return rc2; + + /* If the previous check matches, but this one is not yet clear, + * we should return 0 to do an RPC on OSTs. */ + if (rc == 1) + rc = rc2; + } - return rc; + return rc; } /** @@ -2524,12 +2739,10 @@ static int check_mdt_match(struct find_param *param) 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; - } + for (i = 0; i < param->num_mdts; i++) { + if (param->mdtindexes[i] == param->file_mdtindex) + return !param->exclude_mdt; + } if (param->exclude_mdt) return 1; @@ -2563,10 +2776,11 @@ static int print_failed_tgt(struct find_param *param, char *path, int type) return ret; } -static int cb_find_init(char *path, DIR *parent, DIR *dir, +static int cb_find_init(char *path, DIR *parent, DIR **dirp, void *data, struct dirent64 *de) { struct find_param *param = (struct find_param *)data; + DIR *dir = dirp == NULL ? NULL : *dirp; int decision = 1; /* 1 is accepted; -1 is rejected. */ lstat_t *st = ¶m->lmd->lmd_st; int lustre_fs = 1; @@ -2588,30 +2802,32 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, goto decided; } - /* See if we can check the file type from the dirent. */ - if (param->type && de != NULL && de->d_type != DT_UNKNOWN && - de->d_type < DT_MAX) { - checked_type = 1; - if (llapi_dir_filetype_table[de->d_type] == param->type) { - if (param->exclude_type) - goto decided; - } else { - if (!param->exclude_type) - goto decided; - } - } + /* See if we can check the file type from the dirent. */ + if (param->fp_type != 0 && de != NULL && de->d_type != DT_UNKNOWN) { + checked_type = 1; + + if (DTTOIF(de->d_type) == param->fp_type) { + if (param->fp_exclude_type) + goto decided; + } else { + if (!param->fp_exclude_type) + goto decided; + } + } ret = 0; /* Request MDS for the stat info if some of these parameters need * to be compared. */ - if (param->obduuid || param->mdtuuid || param->check_uid || - param->check_gid || param->check_pool || param->atime || - param->ctime || param->mtime || param->check_size || - param->check_stripecount || param->check_stripesize) - decision = 0; - - if (param->type && checked_type == 0) + if (param->obduuid || param->mdtuuid || + param->fp_check_uid || param->fp_check_gid || + param->fp_atime || param->fp_mtime || param->fp_ctime || + param->check_pool || param->check_size || + param->check_stripecount || param->check_stripesize || + param->check_layout) + decision = 0; + + if (param->fp_type != 0 && checked_type == 0) decision = 0; if (param->have_fileinfo == 0 && decision == 0) { @@ -2661,20 +2877,20 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, } } - if (param->type && !checked_type) { - if ((st->st_mode & S_IFMT) == param->type) { - if (param->exclude_type) - goto decided; - } else { - if (!param->exclude_type) - goto decided; - } - } + if (param->fp_type && !checked_type) { + if ((st->st_mode & S_IFMT) == param->fp_type) { + if (param->fp_exclude_type) + goto decided; + } else { + if (!param->fp_exclude_type) + goto decided; + } + } /* Prepare odb. */ if (param->obduuid || param->mdtuuid) { if (lustre_fs && param->got_uuids && - param->st_dev != st->st_dev) { + param->fp_dev != st->st_dev) { /* A lustre/lustre mount point is crossed. */ param->got_uuids = 0; param->obds_printed = 0; @@ -2687,7 +2903,7 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, if (ret) return ret; - param->st_dev = st->st_dev; + param->fp_dev = st->st_dev; } else if (!lustre_fs && param->got_uuids) { /* A lustre/non-lustre mount point is crossed. */ param->got_uuids = 0; @@ -2714,6 +2930,18 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, goto decided; } + if (param->check_layout) { + __u32 found; + + found = (param->lmd->lmd_lmm.lmm_pattern & param->layout); + if ((param->lmd->lmd_lmm.lmm_pattern == 0xFFFFFFFF) || + (found && param->exclude_layout) || + (!found && !param->exclude_layout)) { + decision = -1; + goto decided; + } + } + /* If an OBD UUID is specified but none matches, skip this file. */ if ((param->obduuid && param->obdindex == OBD_NOT_FOUND) || (param->mdtuuid && param->mdtindex == OBD_NOT_FOUND)) @@ -2741,25 +2969,25 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, } } obd_matches: - if (param->check_uid) { - if (st->st_uid == param->uid) { - if (param->exclude_uid) - goto decided; - } else { - if (!param->exclude_uid) - goto decided; + if (param->fp_check_uid) { + if (st->st_uid == param->fp_uid) { + if (param->fp_exclude_uid) + goto decided; + } else { + if (!param->fp_exclude_uid) + goto decided; } } - if (param->check_gid) { - if (st->st_gid == param->gid) { - if (param->exclude_gid) - goto decided; - } else { - if (!param->exclude_gid) - goto decided; - } - } + if (param->fp_check_gid) { + if (st->st_gid == param->fp_gid) { + if (param->fp_exclude_gid) + goto decided; + } else { + if (!param->fp_exclude_gid) + goto decided; + } + } if (param->check_pool) { struct lov_user_md_v3 *lmmv3 = (void *)¶m->lmd->lmd_lmm; @@ -2780,9 +3008,9 @@ obd_matches: } } - /* Check the time on mds. */ - decision = 1; - if (param->atime || param->ctime || param->mtime) { + /* Check the time on mds. */ + decision = 1; + if (param->fp_atime || param->fp_mtime || param->fp_ctime) { int for_mds; for_mds = lustre_fs ? (S_ISREG(st->st_mode) && @@ -2860,11 +3088,89 @@ obd_matches: decided: /* Do not get down anymore? */ - if (param->depth == param->maxdepth) - return 1; + if (param->fp_depth == param->fp_max_depth) + return 1; - param->depth++; - return 0; + param->fp_depth++; + + return 0; +} + +static int cb_mv_init(char *path, DIR *parent, DIR **dirp, + void *param_data, struct dirent64 *de) +{ + struct find_param *param = (struct find_param *)param_data; + DIR *dir = parent; + char raw[OBD_MAX_IOCTL_BUFFER] = {'\0'}; + char *rawbuf = raw; + struct obd_ioctl_data data = { 0 }; + int fd; + int ret; + char *filename; + + LASSERT(parent != NULL || dirp != NULL); + if (dirp != NULL) + closedir(*dirp); + + if (parent == NULL) { + dir = opendir_parent(path); + if (dir == NULL) { + *dirp = NULL; + ret = -errno; + llapi_error(LLAPI_MSG_ERROR, ret, + "can not open %s\n", path); + return ret; + } + } + + fd = dirfd(dir); + + filename = basename(path); + data.ioc_inlbuf1 = (char *)filename; + data.ioc_inllen1 = strlen(filename) + 1; + data.ioc_inlbuf2 = (char *)¶m->mdtindex; + data.ioc_inllen2 = sizeof(param->mdtindex); + ret = obd_ioctl_pack(&data, &rawbuf, sizeof(raw)); + if (ret != 0) { + llapi_error(LLAPI_MSG_ERROR, ret, + "llapi_obd_statfs: error packing ioctl data"); + goto out; + } + + ret = ioctl(fd, LL_IOC_MIGRATE, rawbuf); + if (ret != 0) { + ret = -errno; + fprintf(stderr, "%s migrate failed %d\n", path, ret); + goto out; + } else if (param->verbose & VERBOSE_DETAIL) { + fprintf(stdout, "migrate %s to MDT%d\n", path, param->mdtindex); + } + +out: + if (dirp != NULL) { + /* If the directory is being migration, we need + * close the directory after migration, + * so the old directory cache will be cleanup + * on the client side, and re-open to get the + * new directory handle */ + *dirp = opendir(path); + if (dirp == NULL) { + ret = -errno; + llapi_error(LLAPI_MSG_ERROR, ret, + "%s: Failed to open '%s'", __func__, path); + return ret; + } + } + + if (parent == NULL) + closedir(dir); + + return ret; +} + +int llapi_mv(char *path, struct find_param *param) +{ + return param_callback(path, cb_mv_init, cb_common_fini, param); } int llapi_find(char *path, struct find_param *param) @@ -2884,10 +3190,11 @@ int llapi_file_fget_mdtidx(int fd, int *mdtidx) return 0; } -static int cb_get_mdt_index(char *path, DIR *parent, DIR *d, void *data, +static int cb_get_mdt_index(char *path, DIR *parent, DIR **dirp, void *data, struct dirent64 *de) { struct find_param *param = (struct find_param *)data; + DIR *d = dirp == NULL ? NULL : *dirp; int ret = 0; int mdtidx; @@ -2943,18 +3250,20 @@ static int cb_get_mdt_index(char *path, DIR *parent, DIR *d, void *data, path, mdtidx); out: - /* Do not get down anymore? */ - if (param->depth == param->maxdepth) - return 1; + /* Do not get down anymore? */ + if (param->fp_depth == param->fp_max_depth) + return 1; - param->depth++; - return 0; + param->fp_depth++; + + return 0; } -static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data, +static int cb_getstripe(char *path, DIR *parent, DIR **dirp, void *data, struct dirent64 *de) { struct find_param *param = (struct find_param *)data; + DIR *d = dirp == NULL ? NULL : *dirp; int ret = 0; LASSERT(parent != NULL || d != NULL); @@ -2967,7 +3276,7 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data, } if (d) { - if (param->get_lmv) { + if (param->get_lmv || param->get_default_lmv) { ret = cb_get_dirstripe(path, d, param); } else { ret = ioctl(dirfd(d), LL_IOC_LOV_GETSTRIPE, @@ -2999,14 +3308,35 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data, * a check later on in the code path. * The object_seq needs to be set for the "(Default)" * prefix to be displayed. */ - struct lov_user_md *lmm = ¶m->lmd->lmd_lmm; - lmm->lmm_magic = LOV_MAGIC_V1; - if (!param->raw) - lmm->lmm_oi.oi_seq = FID_SEQ_LOV_DEFAULT; - lmm->lmm_stripe_count = 0; - lmm->lmm_stripe_size = 0; - lmm->lmm_stripe_offset = -1; - goto dump; + if (param->get_default_lmv) { + struct lmv_user_md *lum = param->fp_lmv_md; + + lum->lum_magic = LMV_USER_MAGIC; + lum->lum_stripe_count = 0; + lum->lum_stripe_offset = -1; + goto dump; + } else if (param->get_lmv) { + struct lmv_user_md *lum = param->fp_lmv_md; + int mdtidx; + + ret = llapi_file_fget_mdtidx(dirfd(d), &mdtidx); + if (ret != 0) + goto err_out; + lum->lum_magic = LMV_MAGIC_V1; + lum->lum_stripe_count = 0; + lum->lum_stripe_offset = mdtidx; + goto dump; + } else { + struct lov_user_md *lmm = ¶m->lmd->lmd_lmm; + lmm->lmm_magic = LOV_USER_MAGIC_V1; + if (!param->raw) + ostid_set_seq(&lmm->lmm_oi, + FID_SEQ_LOV_DEFAULT); + lmm->lmm_stripe_count = 0; + lmm->lmm_stripe_size = 0; + lmm->lmm_stripe_offset = -1; + goto dump; + } } else if (errno == ENODATA && parent != NULL) { if (!param->obduuid && !param->mdtuuid) llapi_printf(LLAPI_MSG_NORMAL, @@ -3024,11 +3354,12 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data, __func__, path); } else { ret = -errno; - llapi_error(LLAPI_MSG_ERROR, ret, - "error: %s: %s failed for %s", - __func__, d ? "LL_IOC_LOV_GETSTRIPE" : - "IOC_MDC_GETFILESTRIPE", path); - } +err_out: + llapi_error(LLAPI_MSG_ERROR, ret, + "error: %s: %s failed for %s", + __func__, d ? "LL_IOC_LOV_GETSTRIPE" : + "IOC_MDC_GETFILESTRIPE", path); + } return ret; } @@ -3038,12 +3369,13 @@ dump: llapi_lov_dump_user_lmm(param, path, d ? 1 : 0); out: - /* Do not get down anymore? */ - if (param->depth == param->maxdepth) - return 1; + /* Do not get down anymore? */ + if (param->fp_depth == param->fp_max_depth) + return 1; - param->depth++; - return 0; + param->fp_depth++; + + return 0; } int llapi_getstripe(char *path, struct find_param *param) @@ -3083,18 +3415,20 @@ int llapi_obd_statfs(char *path, __u32 type, __u32 index, if (errno == EISDIR) fd = open(path, O_DIRECTORY | O_RDONLY); - if (fd < 0) { - rc = errno ? -errno : -EBADF; - llapi_error(LLAPI_MSG_ERROR, rc, "error: %s: opening '%s'", - __func__, path); - return rc; - } - rc = ioctl(fd, IOC_OBD_STATFS, (void *)rawbuf); - if (rc) - rc = errno ? -errno : -EINVAL; + if (fd < 0) { + rc = errno ? -errno : -EBADF; + llapi_error(LLAPI_MSG_ERROR, rc, "error: %s: opening '%s'", + __func__, path); + /* If we can't even open a file on the filesystem (e.g. with + * -ESHUTDOWN), force caller to exit or it will loop forever. */ + return -ENODEV; + } + rc = ioctl(fd, IOC_OBD_STATFS, (void *)rawbuf); + if (rc) + rc = errno ? -errno : -EINVAL; - close(fd); - return rc; + close(fd); + return rc; } #define MAX_STRING_SIZE 128 @@ -3216,7 +3550,7 @@ int llapi_quotacheck(char *mnt, int check_type) return rc; } - rc = ioctl(dirfd(root), LL_IOC_QUOTACHECK, check_type); + rc = ioctl(dirfd(root), OBD_IOC_QUOTACHECK, check_type); if (rc < 0) rc = -errno; @@ -3238,7 +3572,7 @@ int llapi_poll_quotacheck(char *mnt, struct if_quotacheck *qchk) } while (1) { - rc = ioctl(dirfd(root), LL_IOC_POLL_QUOTACHECK, qchk); + rc = ioctl(dirfd(root), OBD_IOC_POLL_QUOTACHECK, qchk); if (!rc) break; sleep(poll_intvl); @@ -3262,7 +3596,7 @@ int llapi_quotactl(char *mnt, struct if_quotactl *qctl) return rc; } - rc = ioctl(dirfd(root), LL_IOC_QUOTACTL, qctl); + rc = ioctl(dirfd(root), OBD_IOC_QUOTACTL, qctl); if (rc < 0) rc = -errno; @@ -3270,10 +3604,11 @@ int llapi_quotactl(char *mnt, struct if_quotactl *qctl) return rc; } -static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data, +static int cb_quotachown(char *path, DIR *parent, DIR **dirp, void *data, struct dirent64 *de) { struct find_param *param = (struct find_param *)data; + DIR *d = dirp == NULL ? NULL : *dirp; lstat_t *st; int rc; @@ -3365,7 +3700,9 @@ static int rmtacl_notify(int ops) close(fd); if (rc < 0) { rc = -errno; - llapi_error(LLAPI_MSG_ERROR, rc, "ioctl %d\n", fd); + llapi_error(LLAPI_MSG_ERROR, rc, + "ioctl RMTACL on '%s' err %d\n", + mnt->mnt_dir, rc); goto out; } @@ -3672,7 +4009,8 @@ int root_ioctl(const char *mdtname, int opc, void *data, int *mdtidxp, { char fsname[20]; char *ptr; - int fd, index, rc; + int fd, rc; + long index; /* Take path, fsname, or MDTname. Assume MDT0000 in the former cases. Open root and parse mdt index. */ @@ -3766,7 +4104,7 @@ int llapi_changelog_start(void **priv, int flags, const char *device, startrec, flags); /* Only the kernel reference keeps the write side open */ close(cp->kuc.lk_wfd); - cp->kuc.lk_wfd = 0; + cp->kuc.lk_wfd = LK_NOFD; if (rc < 0) { /* frees and clears priv */ llapi_changelog_fini(priv); @@ -3821,24 +4159,24 @@ static inline int changelog_extend_rec(struct changelog_ext_rec *ext) */ int llapi_changelog_recv(void *priv, struct changelog_ext_rec **rech) { - struct changelog_private *cp = (struct changelog_private *)priv; - struct kuc_hdr *kuch; - int rc = 0; + struct changelog_private *cp = (struct changelog_private *)priv; + struct kuc_hdr *kuch; + int rc = 0; - if (!cp || (cp->magic != CHANGELOG_PRIV_MAGIC)) - return -EINVAL; - if (rech == NULL) - return -EINVAL; - kuch = malloc(CR_MAXSIZE + sizeof(*kuch)); - if (kuch == NULL) - return -ENOMEM; + if (!cp || (cp->magic != CHANGELOG_PRIV_MAGIC)) + return -EINVAL; + if (rech == NULL) + return -EINVAL; + kuch = malloc(KUC_CHANGELOG_MSG_MAXSIZE); + if (kuch == NULL) + return -ENOMEM; repeat: - rc = libcfs_ukuc_msg_get(&cp->kuc, (char *)kuch, - CR_MAXSIZE + sizeof(*kuch), - KUC_TRANSPORT_CHANGELOG); - if (rc < 0) - goto out_free; + rc = libcfs_ukuc_msg_get(&cp->kuc, (char *)kuch, + KUC_CHANGELOG_MSG_MAXSIZE, + KUC_TRANSPORT_CHANGELOG); + if (rc < 0) + goto out_free; if ((kuch->kuc_transport != KUC_TRANSPORT_CHANGELOG) || ((kuch->kuc_msgtype != CL_RECORD) && @@ -3892,7 +4230,7 @@ int llapi_changelog_free(struct changelog_ext_rec **rech) int llapi_changelog_clear(const char *mdtname, const char *idstr, long long endrec) { - int id; + long id; if (endrec < 0) { llapi_err_noerrno(LLAPI_MSG_ERROR, @@ -4061,9 +4399,12 @@ int llapi_get_version(char *buffer, int buffer_size, * this value to verify if file data was modified. This only checks the file * data, not metadata. * - * \param flags If set to LL_DV_NOFLUSH, the data version will be read - * directly from OST without regard to possible dirty cache on - * client nodes. + * \param flags 0: no flush pages, usually used it the process has already + * taken locks; + * LL_DV_RD_FLUSH: OSTs will take LCK_PR to flush dirty pages + * from clients; + * LL_DV_WR_FLUSH: OSTs will take LCK_PW to flush all caching + * pages from clients. * * \retval 0 on success. * \retval -errno on error. @@ -4092,12 +4433,12 @@ int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags) * - file modes are rw-------, if user wants another one it must use fchmod() * \param directory Directory where the file is created * \param idx MDT index on which the file is created - * \param flags Std open flags + * \param open_flags Standard open flags * * \retval 0 on success. * \retval -errno on error. */ -int llapi_create_volatile_idx(char *directory, int idx, int mode) +int llapi_create_volatile_idx(char *directory, int idx, int open_flags) { char file_path[PATH_MAX]; char filename[PATH_MAX]; @@ -4115,18 +4456,23 @@ int llapi_create_volatile_idx(char *directory, int idx, int mode) close(fd); if (rc < sizeof(random)) { llapi_error(LLAPI_MSG_ERROR, errno, - "Cannot read %d bytes from /dev/urandom\n", + "cannot read %zu bytes from /dev/urandom", sizeof(random)); return -errno; } if (idx == -1) - sprintf(filename, LUSTRE_VOLATILE_HDR"::%.4X", random); + snprintf(filename, sizeof(filename), + LUSTRE_VOLATILE_HDR"::%.4X", random); else - sprintf(filename, LUSTRE_VOLATILE_IDX"%.4X", 0, random); + snprintf(filename, sizeof(filename), + LUSTRE_VOLATILE_HDR":%.4X:%.4X", idx, random); - sprintf(file_path, "%s/%s", directory, filename); + rc = snprintf(file_path, sizeof(file_path), + "%s/%s", directory, filename); + if (rc >= sizeof(file_path)) + return -E2BIG; - fd = open(file_path, O_RDWR|O_CREAT|mode, S_IRUSR|S_IWUSR); + fd = open(file_path, O_RDWR | O_CREAT | open_flags, S_IRUSR | S_IWUSR); if (fd < 0) { llapi_error(LLAPI_MSG_ERROR, errno, "Cannot create volatile file %s in %s\n", @@ -4169,30 +4515,31 @@ int llapi_swap_layouts(const char *path1, const char *path2, { int fd1, fd2, rc; - fd1 = open(path1, O_WRONLY); + fd1 = open(path1, O_WRONLY | O_LOV_DELAY_CREATE); if (fd1 < 0) { - llapi_error(LLAPI_MSG_ERROR, -errno, - "error: cannot open for write %s", - path1); - return -errno; + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "error: cannot open '%s' for write", path1); + goto out; } - fd2 = open(path2, O_WRONLY); + fd2 = open(path2, O_WRONLY | O_LOV_DELAY_CREATE); if (fd2 < 0) { - llapi_error(LLAPI_MSG_ERROR, -errno, - "error: cannot open for write %s", - path2); - close(fd1); - return -errno; + rc = -errno; + llapi_error(LLAPI_MSG_ERROR, rc, + "error: cannot open '%s' for write", path2); + goto out_close; } rc = llapi_fswap_layouts(fd1, fd2, dv1, dv2, flags); if (rc < 0) llapi_error(LLAPI_MSG_ERROR, rc, - "error: cannot swap layouts between %s and %s\n", - path1, path2); + "error: cannot swap layout between '%s' and '%s'\n", + path1, path2); - close(fd1); close(fd2); +out_close: + close(fd1); +out: return rc; }