#endif
#include <poll.h>
#include <time.h>
+#include <inttypes.h>
#include <libcfs/util/ioctl.h>
#include <libcfs/util/param.h>
char *mdt_hash_name[] = { "none",
LMV_HASH_NAME_ALL_CHARS,
- LMV_HASH_NAME_FNV_1A_64 };
+ LMV_HASH_NAME_FNV_1A_64,
+};
struct lustre_foreign_type lu_foreign_types[] = {
{.lft_type = LU_FOREIGN_TYPE_NONE, .lft_name = "none"},
int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset,
int stripe_count, int stripe_pattern)
{
- int page_size, rc;
+ static int page_size;
+ int rc = 0;
- /* 64 KB is the largest common page size I'm aware of (on ia64), but
- * check the local page size just in case. */
- page_size = LOV_MIN_STRIPE_SIZE;
- if (getpagesize() > page_size) {
- page_size = getpagesize();
- llapi_err_noerrno(LLAPI_MSG_WARN,
- "warning: your page size (%u) is "
- "larger than expected (%u)", page_size,
- LOV_MIN_STRIPE_SIZE);
+ if (page_size == 0) {
+ /* 64 KB is the largest common page size (on ia64/PPC/ARM),
+ * but check the local page size just in case. The page_size
+ * will not change for the lifetime of this process at least.
+ */
+ page_size = LOV_MIN_STRIPE_SIZE;
+ if (getpagesize() > page_size) {
+ page_size = getpagesize();
+ llapi_err_noerrno(LLAPI_MSG_WARN,
+ "warning: page size (%u) larger than expected (%u)",
+ page_size, LOV_MIN_STRIPE_SIZE);
+ }
}
if (!llapi_stripe_size_is_aligned(stripe_size)) {
rc = -EINVAL;
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;
+ (unsigned long long)stripe_size, page_size);
+ goto out;
}
if (!llapi_stripe_index_is_valid(stripe_offset)) {
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe offset %d",
stripe_offset);
- return rc;
+ goto out;
}
if (!llapi_stripe_count_is_valid(stripe_count)) {
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc, "error: bad stripe count %d",
stripe_count);
- return rc;
+ goto out;
}
if (llapi_stripe_size_is_too_big(stripe_size)) {
rc = -EINVAL;
llapi_error(LLAPI_MSG_ERROR, rc,
- "warning: stripe size 4G or larger "
- "is not currently supported and would wrap");
- return rc;
+ "error: stripe size '%llu' over 4GB limit",
+ (unsigned long long)stripe_size);
+ goto out;
}
- return 0;
+
+out:
+ errno = -rc;
+ return rc;
}
int llapi_dir_stripe_limit_check(int stripe_offset, int stripe_count,
return get_param_lmv(path, "uuid", buf, bufsize);
}
-/*
- * if pool is NULL, search tgtname in target_obd
- * if pool is not NULL:
- * if pool not found returns errno < 0
- * if tgtname is NULL, returns 1 if pool is not empty and 0 if pool empty
- * if tgtname is not NULL, returns 1 if OST is in pool and 0 if not
- */
-int llapi_search_tgt(char *fsname, char *poolname, char *tgtname, bool is_mdt)
-{
- char buffer[PATH_MAX];
- size_t len = 0;
- glob_t param;
- FILE *fd;
- int rc;
-
- /* You need one or the other */
- if (poolname == NULL && fsname == NULL)
- return -EINVAL;
-
- if (tgtname != NULL)
- len = strlen(tgtname);
-
- if (poolname == NULL && len == 0)
- return -EINVAL;
-
- /* Search by poolname and fsname if is not NULL */
- if (poolname != NULL) {
- rc = poolpath(¶m, fsname, NULL);
- if (rc == 0) {
- snprintf(buffer, sizeof(buffer), "%s/%s",
- param.gl_pathv[0], poolname);
- }
- } else if (fsname != NULL) {
- rc = get_lustre_param_path(is_mdt ? "lmv" : "lov", fsname,
- FILTER_BY_FS_NAME,
- "target_obd", ¶m);
- if (rc == 0) {
- strncpy(buffer, param.gl_pathv[0],
- sizeof(buffer) - 1);
- }
- } else {
- return -EINVAL;
- }
- cfs_free_param_data(¶m);
- if (rc)
- return rc;
-
- fd = fopen(buffer, "r");
- if (fd == NULL)
- return -errno;
-
- while (fgets(buffer, sizeof(buffer), fd) != NULL) {
- if (poolname == NULL) {
- char *ptr;
- /* Search for an tgtname in the list of targets
- * Line format is IDX: fsname-OST/MDTxxxx_UUID STATUS */
- ptr = strchr(buffer, ' ');
- if ((ptr != NULL) &&
- (strncmp(ptr + 1, tgtname, len) == 0)) {
- fclose(fd);
- return 1;
- }
- } else {
- /* Search for an tgtname in a pool,
- * (or an existing non-empty pool if no tgtname) */
- if ((tgtname == NULL) ||
- (strncmp(buffer, tgtname, len) == 0)) {
- fclose(fd);
- return 1;
- }
- }
- }
- fclose(fd);
- return 0;
-}
-
-int llapi_search_ost(char *fsname, char *poolname, char *ostname)
-{
- return llapi_search_tgt(fsname, poolname, ostname, false);
-}
-
/**
* Open a Lustre file.
*
int fd, rc;
if (foreign_lov == NULL) {
- llapi_error(LLAPI_MSG_ERROR, -EINVAL,
+ rc = -EINVAL;
+ llapi_error(LLAPI_MSG_ERROR, rc,
"foreign LOV EA content must be provided");
- return -EINVAL;
+ goto out_err;
}
len = strlen(foreign_lov);
if (len > XATTR_SIZE_MAX - offsetof(struct lov_foreign_md, lfm_value) ||
len <= 0) {
- llapi_error(LLAPI_MSG_ERROR, -EINVAL,
+ rc = -EINVAL;
+ llapi_error(LLAPI_MSG_ERROR, rc,
"foreign LOV EA size %zu (must be 0 < len < %zu)",
len, XATTR_SIZE_MAX -
offsetof(struct lov_foreign_md, lfm_value));
- return -EINVAL;
+ goto out_err;
}
lfm = malloc(len + offsetof(struct lov_foreign_md, lfm_value));
if (lfm == NULL) {
- llapi_error(LLAPI_MSG_ERROR, -ENOMEM,
+ rc = -ENOMEM;
+ llapi_error(LLAPI_MSG_ERROR, rc,
"failed to allocate lov_foreign_md");
- return -ENOMEM;
+ goto out_err;
}
fd = open(name, O_WRONLY|O_CREAT|O_LOV_DELAY_CREATE, mode);
if (fd == -1) {
- perror("open()");
- rc = -errno;
+ fd = -errno;
+ llapi_error(LLAPI_MSG_ERROR, fd, "open '%s' failed", name);
goto out_free;
}
if (ioctl(fd, LL_IOC_LOV_SETSTRIPE, lfm) != 0) {
char *errmsg = "stripe already set";
- char fsname[MAX_OBD_NAME + 1] = { 0 };
rc = -errno;
- if (errno != EEXIST && errno != EALREADY)
+ if (errno == ENOTTY)
+ errmsg = "not on a Lustre filesystem";
+ else if (errno == EEXIST || errno == EALREADY)
+ errmsg = "stripe already set";
+ else
errmsg = strerror(errno);
llapi_err_noerrno(LLAPI_MSG_ERROR,
"setstripe error for '%s': %s", name, errmsg);
- /* Make sure we are on a Lustre file system */
- if (rc == -ENOTTY && llapi_search_fsname(name, fsname))
- llapi_error(LLAPI_MSG_ERROR, rc,
- "'%s' is not on a Lustre filesystem",
- name);
-
close(fd);
fd = rc;
}
free(lfm);
return fd;
+
+out_err:
+ errno = -rc;
+ return rc;
}
int llapi_file_create(const char *name, unsigned long long stripe_size,
FILE *fp;
int idx = 0, len = 0, mntlen, fd;
int rc = -ENODEV;
+ int fsnamelen, mountlen;
/* get the mount point */
fp = setmntent(PROC_MOUNTS, "r");
ptr_end++;
/* Check the fsname for a match, if given */
+ mountlen = ptr_end - ptr;
if (!(want & WANT_FSNAME) && fsname != NULL &&
- (strlen(fsname) > 0) &&
- (strncmp(ptr, fsname, ptr_end - ptr) != 0))
- continue;
+ (fsnamelen = strlen(fsname)) > 0 &&
+ (fsnamelen != mountlen ||
+ (strncmp(ptr, fsname, mountlen) != 0)))
+ continue;
/* If the path isn't set return the first one we find */
if (path == NULL || strlen(path) == 0) {
strncpy(mntdir, mnt.mnt_dir, sizeof(mntdir) - 1);
- mntdir[strlen(mnt.mnt_dir)] = '\0';
+ mntdir[sizeof(mntdir) - 1] = '\0';
if ((want & WANT_FSNAME) && fsname != NULL) {
- strncpy(fsname, ptr, ptr_end - ptr);
- fsname[ptr_end - ptr] = '\0';
+ strncpy(fsname, ptr, mountlen);
+ fsname[mountlen] = '\0';
}
rc = 0;
break;
/* Otherwise find the longest matching path */
} else if ((strlen(path) >= mntlen) && (mntlen >= len) &&
(strncmp(mnt.mnt_dir, path, mntlen) == 0)) {
- strncpy(mntdir, mnt.mnt_dir, sizeof(mntdir));
- mntdir[strlen(mnt.mnt_dir)] = '\0';
+ strncpy(mntdir, mnt.mnt_dir, sizeof(mntdir) - 1);
+ mntdir[sizeof(mntdir) - 1] = '\0';
len = mntlen;
if ((want & WANT_FSNAME) && fsname != NULL) {
- strncpy(fsname, ptr, ptr_end - ptr);
- fsname[ptr_end - ptr] = '\0';
+ strncpy(fsname, ptr, mountlen);
+ fsname[mountlen] = '\0';
}
rc = 0;
}
int llapi_get_poollist(const char *name, char **poollist, int list_size,
char *buffer, int buffer_size)
{
- char rname[PATH_MAX];
glob_t pathname;
char *fsname;
- char *ptr;
- DIR *dir;
+ char *ptr;
+ DIR *dir;
struct dirent *pool;
- int rc = 0;
- unsigned int nb_entries = 0;
- unsigned int used = 0;
- unsigned int i;
+ int rc = 0;
+ unsigned int nb_entries = 0;
+ unsigned int used = 0;
+ unsigned int i;
/* initialize output array */
- for (i = 0; i < list_size; i++)
- poollist[i] = NULL;
-
- /* is name a pathname ? */
- ptr = strchr(name, '/');
- if (ptr != NULL) {
- /* only absolute pathname is supported */
- if (*name != '/')
- return -EINVAL;
+ for (i = 0; i < list_size; i++)
+ poollist[i] = NULL;
- if (!realpath(name, rname)) {
- rc = -errno;
- llapi_error(LLAPI_MSG_ERROR, rc, "invalid path '%s'",
- name);
- return rc;
- }
+ /* is name a pathname ? */
+ ptr = strchr(name, '/');
+ if (ptr != NULL) {
+ char fsname_buf[MAXNAMLEN];
+
+ /* We will need fsname for printing later */
+ rc = llapi_getname(name, fsname_buf, sizeof(fsname_buf));
+ if (rc)
+ return rc;
- fsname = strdup(rname);
+ ptr = strrchr(fsname_buf, '-');
+ if (ptr)
+ *ptr = '\0';
+
+ fsname = strdup(fsname_buf);
if (!fsname)
return -ENOMEM;
-
- rc = poolpath(&pathname, NULL, rname);
} else {
/* name is FSNAME */
fsname = strdup(name);
if (!fsname)
return -ENOMEM;
- rc = poolpath(&pathname, fsname, NULL);
}
+
+ rc = poolpath(&pathname, fsname, NULL);
if (rc != 0) {
llapi_error(LLAPI_MSG_ERROR, rc,
"Lustre filesystem '%s' not found", name);
static char *layout2name(__u32 layout_pattern)
{
- if (layout_pattern == LOV_PATTERN_MDT)
+ if (layout_pattern & LOV_PATTERN_F_RELEASED)
+ return "released";
+ else if (layout_pattern == LOV_PATTERN_MDT)
return "mdt";
else if (layout_pattern == LOV_PATTERN_RAID0)
return "raid0";
- else if (layout_pattern == (LOV_PATTERN_RAID0 | LOV_PATTERN_F_RELEASED))
- return "released";
+ else if (layout_pattern ==
+ (LOV_PATTERN_RAID0 | LOV_PATTERN_OVERSTRIPING))
+ return "raid0,overstriped";
else
return "unknown";
}
LDF_INDENT = 0x0004,
LDF_SKIP_OBJS = 0x0008,
LDF_YAML = 0x0010,
+ LDF_EXTENSION = 0x0020,
};
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
bool indent = flags & LDF_INDENT;
bool yaml = flags & LDF_YAML;
bool skip_objs = flags & LDF_SKIP_OBJS;
+ bool extension = flags & LDF_EXTENSION;
char *prefix = is_dir ? "" : "lmm_";
char *separator = "";
char *space = indent ? " " : "";
ver = (__u32)(lmm_oi_id(&lum->lmm_oi) >> 32);
if (yaml)
llapi_printf(LLAPI_MSG_NORMAL, DFID_NOBRACE"\n",
- seq, oid, ver);
+ (unsigned long long)seq, oid, ver);
else
llapi_printf(LLAPI_MSG_NORMAL, DFID"\n",
- seq, oid, ver);
+ (unsigned long long)seq, oid, ver);
}
if (verbose & VERBOSE_STRIPE_COUNT) {
" stripe count.");
} else {
llapi_printf(LLAPI_MSG_NORMAL, "%d",
- lum->lmm_stripe_count ==
- (typeof(lum->lmm_stripe_count))(-1)
- ? -1 : lum->lmm_stripe_count);
+ extension ? 0 :
+ (__s16)lum->lmm_stripe_count);
}
} else {
llapi_printf(LLAPI_MSG_NORMAL, "%hd",
+ extension ? 0 :
(__s16)lum->lmm_stripe_count);
}
if (!yaml && is_dir)
separator = "\n";
}
- if (verbose & VERBOSE_STRIPE_SIZE) {
+ if (((verbose & VERBOSE_STRIPE_SIZE) && !extension) ||
+ ((verbose & VERBOSE_EXT_SIZE) && extension)) {
llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
- if (verbose & ~VERBOSE_STRIPE_SIZE)
+ if (verbose & ~VERBOSE_EXT_SIZE && extension)
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%sextension_size: ",
+ space, prefix);
+ if (verbose & ~VERBOSE_STRIPE_SIZE && !extension)
llapi_printf(LLAPI_MSG_NORMAL, "%s%sstripe_size: ",
space, prefix);
if (is_dir && !is_raw && lum->lmm_stripe_size == 0) {
"Cannot determine default"
" stripe size.");
} else {
- llapi_printf(LLAPI_MSG_NORMAL, "%u",
- lum->lmm_stripe_size);
+ /* Extension size is in KiB */
+ llapi_printf(LLAPI_MSG_NORMAL, "%llu",
+ extension ?
+ (unsigned long long)(lum->lmm_stripe_size * SEL_UNIT_SIZE) :
+ (unsigned long long)lum->lmm_stripe_size);
}
if (!yaml && is_dir)
separator = " ";
else
llapi_printf(LLAPI_MSG_NORMAL, "%#x", type);
+ if (flags & LMV_HASH_FLAG_SPACE)
+ llapi_printf(LLAPI_MSG_NORMAL, ",space");
if (flags & LMV_HASH_FLAG_MIGRATION)
llapi_printf(LLAPI_MSG_NORMAL, ",migrating");
- if (flags & LMV_HASH_FLAG_DEAD)
- llapi_printf(LLAPI_MSG_NORMAL, ",dead");
if (flags & LMV_HASH_FLAG_BAD_TYPE)
llapi_printf(LLAPI_MSG_NORMAL, ",bad_type");
if (flags & LMV_HASH_FLAG_LOST_LMV)
"%4slcme_timestamp: ", " ");
if (yaml) {
llapi_printf(LLAPI_MSG_NORMAL, "%llu",
- entry->lcme_timestamp);
+ (unsigned long long)entry->lcme_timestamp);
} else {
time_t stamp = entry->lcme_timestamp;
char *date_str = asctime(localtime(&stamp));
llapi_printf(LLAPI_MSG_NORMAL,
"%4slcme_extent.e_start: ", " ");
llapi_printf(LLAPI_MSG_NORMAL, "%llu",
- entry->lcme_extent.e_start);
+ (unsigned long long)entry->lcme_extent.e_start);
separator = "\n";
}
llapi_printf(LLAPI_MSG_NORMAL, "%s", "EOF");
else
llapi_printf(LLAPI_MSG_NORMAL, "%llu",
- entry->lcme_extent.e_end);
+ (unsigned long long)entry->lcme_extent.e_end);
separator = "\n";
}
struct lov_user_md_v1 *v1;
char pool_name[LOV_MAXPOOLNAME + 1];
int obdindex = param->fp_obd_index;
- int i, j, match;
+ int i, j, match, ext;
bool obdstripe = false;
__u16 mirror_index = 0;
__u16 mirror_id = 0;
*/
if (entry->lcme_flags & LCME_FL_INIT)
continue;
- else
- break;
+
+ if (param->fp_verbose & VERBOSE_EXT_SIZE) {
+ if (entry->lcme_flags & LCME_FL_EXTENSION)
+ /* moved back below */
+ i++;
+ else
+ continue;
+ }
+ break;
}
if (entry->lcme_flags & LCME_FL_INIT) {
objects = lov_v1v3_objects(v1);
lov_v1v3_pool_name(v1, pool_name);
+ ext = entry->lcme_flags & LCME_FL_EXTENSION ? LDF_EXTENSION : 0;
lov_dump_user_lmm_v1v3(v1, pool_name, objects, path, obdindex,
param->fp_max_depth, param->fp_verbose,
- flags);
+ flags | ext);
}
if (print_last_init_comp(param)) {
/**
objects = lov_v1v3_objects(v1);
lov_v1v3_pool_name(v1, pool_name);
+ entry = &comp_v1->lcm_entries[i];
+ ext = entry->lcme_flags & LCME_FL_EXTENSION ? LDF_EXTENSION : 0;
lov_dump_user_lmm_v1v3(v1, pool_name, objects, path, obdindex,
param->fp_max_depth, param->fp_verbose,
- flags);
+ flags | ext);
}
}
{
struct lov_comp_md_v1 *comp_v1 = NULL;
struct lov_user_md_v1 *v1 = ¶m->fp_lmd->lmd_lmm;
+ __u32 stripe_size = 0;
int ret, i, count = 1;
if (v1->lmm_magic == LOV_USER_MAGIC_FOREIGN)
return param->fp_exclude_stripe_size ? 1 : -1;
+ ret = param->fp_exclude_stripe_size ? 1 : -1;
if (v1->lmm_magic == LOV_USER_MAGIC_COMP_V1) {
comp_v1 = (struct lov_comp_md_v1 *)v1;
count = comp_v1->lcm_entry_count;
- ret = param->fp_exclude_stripe_size ? 1 : -1;
}
for (i = 0; i < count; i++) {
- if (comp_v1)
+ struct lov_comp_md_entry_v1 *ent;
+
+ if (comp_v1) {
v1 = lov_comp_entry(comp_v1, i);
- ret = find_value_cmp(v1->lmm_stripe_size, param->fp_stripe_size,
- param->fp_stripe_size_sign,
- param->fp_exclude_stripe_size,
- param->fp_stripe_size_units, 0);
- /* If any stripe_size matches */
+ ent = &comp_v1->lcm_entries[i];
+ if (ent->lcme_flags & LCME_FL_EXTENSION)
+ continue;
+ if (!(ent->lcme_flags & LCME_FL_INIT))
+ continue;
+ }
+ stripe_size = v1->lmm_stripe_size;
+ }
+
+ ret = find_value_cmp(stripe_size, param->fp_stripe_size,
+ param->fp_stripe_size_sign,
+ param->fp_exclude_stripe_size,
+ param->fp_stripe_size_units, 0);
+
+ return ret;
+}
+
+static int find_check_ext_size(struct find_param *param)
+{
+ struct lov_comp_md_v1 *comp_v1;
+ struct lov_user_md_v1 *v1;
+ int ret, i;
+
+ ret = param->fp_exclude_ext_size ? 1 : -1;
+ comp_v1 = (struct lov_comp_md_v1 *)¶m->fp_lmd->lmd_lmm;
+ if (comp_v1->lcm_magic != LOV_USER_MAGIC_COMP_V1)
+ return ret;
+
+ for (i = 0; i < comp_v1->lcm_entry_count; i++) {
+ struct lov_comp_md_entry_v1 *ent;
+
+ v1 = lov_comp_entry(comp_v1, i);
+
+ ent = &comp_v1->lcm_entries[i];
+ if (!(ent->lcme_flags & LCME_FL_EXTENSION))
+ continue;
+
+ ret = find_value_cmp(v1->lmm_stripe_size, param->fp_ext_size,
+ param->fp_ext_size_sign,
+ param->fp_exclude_ext_size,
+ param->fp_ext_size_units, 0);
+ /* If any ext_size matches */
if (ret != -1)
break;
}
}
for (i = 0; i < count; i++) {
- if (comp_v1)
+ if (comp_v1) {
+ struct lov_comp_md_entry_v1 *ent;
+
v1 = lov_comp_entry(comp_v1, i);
- stripe_count += v1->lmm_stripe_count;
+
+ ent = &comp_v1->lcm_entries[i];
+ if (!(ent->lcme_flags & LCME_FL_INIT))
+ continue;
+
+ if (ent->lcme_flags & LCME_FL_EXTENSION)
+ continue;
+ }
+ stripe_count = v1->lmm_stripe_count;
}
return stripe_count;
param->fp_check_comp_count || param->fp_check_comp_end ||
param->fp_check_comp_start || param->fp_check_comp_flags ||
param->fp_check_mirror_count || param->fp_check_foreign ||
- param->fp_check_mirror_state ||
+ param->fp_check_mirror_state || param->fp_check_ext_size ||
param->fp_check_projid;
}
goto decided;
}
+ if (param->fp_check_ext_size) {
+ decision = find_check_ext_size(param);
+ if (decision == -1)
+ goto decided;
+ }
+
if (param->fp_check_stripe_count) {
decision = find_value_cmp(stripe_count, param->fp_stripe_count,
param->fp_stripe_count_sign,
/* Is this a lustre fs? */
int llapi_is_lustre_mnttype(const char *type)
{
- return (strcmp(type, "lustre") == 0 || strcmp(type,"lustre_lite") == 0);
+ return strcmp(type, "lustre") == 0 || strcmp(type, "lustre_tgt") == 0;
}
/* Is this a lustre client fs? */