Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
| inline |
side by side
LU-64 define LOV default layout as FID_SEQ value
[fs/lustre-release.git]
/
lustre
/
utils
/
liblustreapi.c
diff --git
a/lustre/utils/liblustreapi.c
b/lustre/utils/liblustreapi.c
index
d5292f7
..
dc989a7
100644
(file)
--- a/
lustre/utils/liblustreapi.c
+++ b/
lustre/utils/liblustreapi.c
@@
-592,7
+592,7
@@
int llapi_search_mounts(const char *pathname, int index, char *mntdir,
{
int want = WANT_PATH, idx = -1;
- if (!pathname) {
+ if (!pathname
|| pathname[0] == '\0'
) {
want |= WANT_INDEX;
idx = index;
} else
@@
-606,19
+606,42
@@
int llapi_search_mounts(const char *pathname, int index, char *mntdir,
/* Given a path, find the corresponding Lustre fsname */
int llapi_search_fsname(const char *pathname, char *fsname)
{
- char *path = (char*)pathname, buf[PATH_MAX + 1];
+ char *path;
+ int rc;
- if (pathname[0] != '/') { /* Need a absolute path */
- memset(buf, '\0', sizeof(buf));
- if (realpath(pathname, buf) == NULL) {
- llapi_err(LLAPI_MSG_ERROR, "pathname '%s' cannot expand",
- pathname);
- return -EINVAL;
+ path = realpath(pathname, NULL);
+ if (path == NULL) {
+ char buf[PATH_MAX + 1], *ptr;
+
+ buf[0] = 0;
+ if (pathname[0] != '/') {
+ /* Need an absolute path, but realpath() only works for
+ * pathnames that actually exist. We go through the
+ * extra hurdle of dirname(getcwd() + pathname) in
+ * case the relative pathname contains ".." in it. */
+ if (getcwd(buf, sizeof(buf) - 1) == NULL)
+ return -errno;
+ strcat(buf, "/");
+ }
+ strncat(buf, pathname, sizeof(buf) - strlen(buf));
+ path = realpath(buf, NULL);
+ if (path == NULL) {
+ ptr = strrchr(buf, '/');
+ if (ptr == NULL)
+ return -ENOENT;
+ *ptr = '\0';
+ path = realpath(buf, NULL);
+ if (path == NULL) {
+ llapi_err(LLAPI_MSG_ERROR,
+ "pathname '%s' cannot expand",
+ pathname);
+ return -errno;
+ }
}
- path = buf;
}
- return get_root_path(WANT_FSNAME | WANT_ERROR, fsname, NULL,
- path, -1);
+ rc = get_root_path(WANT_FSNAME | WANT_ERROR, fsname, NULL, path, -1);
+ free(path);
+ return rc;
}
/* return the first file matching this pattern */
@@
-1372,16
+1395,170
@@
int llapi_ostlist(char *path, struct find_param *param)
return ret;
}
+/*
+ * Given a filesystem name, or a pathname of a file on a lustre filesystem,
+ * tries to determine the path to the filesystem's clilov directory under /proc
+ *
+ * fsname is limited to MTI_NAME_MAXLEN in lustre_idl.h
+ * The NUL terminator is compensated by the additional "%s" bytes. */
+#define LOV_LEN (sizeof("/proc/fs/lustre/lov/%s-clilov-*") + MTI_NAME_MAXLEN)
+static int clilovpath(const char *fsname, const char *const pathname,
+ char *clilovpath)
+{
+ int rc;
+ char pattern[LOV_LEN];
+ char buffer[PATH_MAX + 1];
+
+ if (fsname == NULL) {
+ if ((rc = llapi_search_fsname(pathname, buffer)) != 0)
+ return rc;
+ fsname = buffer;
+ }
+
+ snprintf(pattern, sizeof(pattern), "/proc/fs/lustre/lov/%s-clilov-*",
+ fsname);
+
+ if ((rc = first_match(pattern, buffer)) != 0)
+ return rc;
+
+ strncpy(clilovpath, buffer, sizeof(buffer));
+
+ return 0;
+}
+
+/*
+ * Given the path to a stripe attribute proc file, tries to open and
+ * read the attribute and return the value using the attr parameter
+ */
+static int sattr_read_attr(const char *const fpath,
+ unsigned int *attr)
+{
+
+ FILE *f;
+ char line[PATH_MAX + 1];
+ int rc = 0;
+
+ if ((f = fopen(fpath, "r")) == NULL) {
+ llapi_err(LLAPI_MSG_ERROR, "Cannot open '%s'", fpath);
+ return errno;
+ }
+
+ if (fgets(line, sizeof(line), f) != NULL) {
+ *attr = atoi(line);
+ } else {
+ llapi_err(LLAPI_MSG_ERROR, "Cannot read from '%s'", fpath);
+ rc = 1;
+ }
+
+ fclose(f);
+ return rc;
+}
+
+/*
+ * Tries to determine the default stripe attributes for a given filesystem. The
+ * filesystem to check should be specified by fsname, or will be determined
+ * using pathname.
+ */
+static int sattr_get_defaults(const char *const fsname,
+ const char *const pathname,
+ unsigned int *scount,
+ unsigned int *ssize,
+ unsigned int *soffset)
+{
+ int rc;
+ char dpath[PATH_MAX + 1];
+ char fpath[PATH_MAX + 1];
+
+ if ((rc = clilovpath(fsname, pathname, dpath)) != 0)
+ return rc;
+
+ if (scount) {
+ snprintf(fpath, PATH_MAX, "%s/stripecount", dpath);
+ if ((rc = sattr_read_attr(fpath, scount)) != 0)
+ return rc;
+ }
+
+ if (ssize) {
+ snprintf(fpath, PATH_MAX, "%s/stripesize", dpath);
+ if ((rc = sattr_read_attr(fpath, ssize)) != 0)
+ return rc;
+ }
+
+ if (soffset) {
+ snprintf(fpath, PATH_MAX, "%s/stripeoffset", dpath);
+ if ((rc = sattr_read_attr(fpath, soffset)) != 0)
+ return rc;
+ }
+
+ return 0;
+}
+
+/*
+ * Tries to gather the default stripe attributes for a given filesystem. If
+ * the attributes can be determined, they are cached for easy retreival the
+ * next time they are needed. Only a single filesystem's attributes are
+ * cached at a time.
+ */
+static int sattr_cache_get_defaults(const char *const fsname,
+ const char *const pathname,
+ unsigned int *scount,
+ unsigned int *ssize,
+ unsigned int *soffset)
+{
+ static struct {
+ char fsname[PATH_MAX + 1];
+ unsigned int stripecount;
+ unsigned int stripesize;
+ unsigned int stripeoffset;
+ } cache = {
+ .fsname = {'\0'}
+ };
+
+ int rc;
+ char fsname_buf[PATH_MAX + 1];
+ unsigned int tmp[3];
+
+ if (fsname == NULL)
+ llapi_search_fsname(pathname, fsname_buf);
+ else
+ strncpy(fsname_buf, fsname, PATH_MAX);
+
+ if (strncmp(fsname_buf, cache.fsname, PATH_MAX) != 0) {
+ /*
+ * Ensure all 3 sattrs (count, size, and offset) are
+ * successfully retrieved and stored in tmp before writing to
+ * cache.
+ */
+ if ((rc = sattr_get_defaults(fsname_buf, NULL, &tmp[0],
+ &tmp[1], &tmp[2])) != 0)
+ return rc;
+
+ cache.stripecount = tmp[0];
+ cache.stripesize = tmp[1];
+ cache.stripeoffset = tmp[2];
+ strncpy(cache.fsname, fsname_buf, PATH_MAX);
+ }
+
+ if (scount)
+ *scount = cache.stripecount;
+ if (ssize)
+ *ssize = cache.stripesize;
+ if (soffset)
+ *soffset = cache.stripeoffset;
+
+ return 0;
+}
+
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
struct lov_user_ost_data_v1 *objects,
int is_dir, int verbose, int depth,
- char *pool_name)
+
int raw,
char *pool_name)
{
char *prefix = is_dir ? "" : "lmm_";
char nl = is_dir ? ' ' : '\n';
- if (is_dir && lum->lmm_object_seq ==
LOV_OBJECT_GROUP
_DEFAULT) {
- lum->lmm_object_seq =
LOV_OBJECT_GROUP_CLEAR
;
+ if (is_dir && lum->lmm_object_seq ==
FID_SEQ_LOV
_DEFAULT) {
+ lum->lmm_object_seq =
FID_SEQ_OST_MDT0
;
if (verbose & VERBOSE_DETAIL)
llapi_printf(LLAPI_MSG_NORMAL, "(Default) ");
}
@@
-1402,16
+1579,48
@@
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
if (verbose & ~VERBOSE_COUNT)
llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_count: ",
prefix);
- llapi_printf(LLAPI_MSG_NORMAL, "%hd%c",
- (__s16)lum->lmm_stripe_count, nl);
+ if (is_dir) {
+ if (!raw && lum->lmm_stripe_count == 0) {
+ unsigned int scount;
+ if (sattr_cache_get_defaults(NULL, path,
+ &scount, NULL,
+ NULL) == 0)
+ llapi_printf(LLAPI_MSG_NORMAL, "%u%c",
+ scount, nl);
+ else
+ llapi_err(LLAPI_MSG_ERROR,
+ "Cannot determine default"
+ " stripe count.");
+ } else {
+ llapi_printf(LLAPI_MSG_NORMAL, "%d%c",
+ lum->lmm_stripe_count ==
+ (typeof(lum->lmm_stripe_count))(-1)
+ ? -1 : lum->lmm_stripe_count, nl);
+ }
+ } else {
+ llapi_printf(LLAPI_MSG_NORMAL, "%hd%c",
+ (__s16)lum->lmm_stripe_count, nl);
+ }
}
if (verbose & VERBOSE_SIZE) {
if (verbose & ~VERBOSE_SIZE)
llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_size: ",
prefix);
- llapi_printf(LLAPI_MSG_NORMAL, "%u%c", lum->lmm_stripe_size,
- nl);
+ if (is_dir && !raw && lum->lmm_stripe_size == 0) {
+ unsigned int ssize;
+ if (sattr_cache_get_defaults(NULL, path, NULL, &ssize,
+ NULL) == 0)
+ llapi_printf(LLAPI_MSG_NORMAL, "%u%c", ssize,
+ nl);
+ else
+ llapi_err(LLAPI_MSG_ERROR,
+ "Cannot determine default"
+ " stripe size.");
+ } else {
+ llapi_printf(LLAPI_MSG_NORMAL, "%u%c",
+ lum->lmm_stripe_size, nl);
+ }
}
if ((verbose & VERBOSE_DETAIL) && !is_dir) {
@@
-1423,7
+1632,7
@@
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
if (verbose & ~VERBOSE_OFFSET)
llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_offset: ",
prefix);
- if (is_dir)
+ if (is_dir)
llapi_printf(LLAPI_MSG_NORMAL, "%d%c",
lum->lmm_stripe_offset ==
(typeof(lum->lmm_stripe_offset))(-1) ? -1 :
@@
-1434,8
+1643,10
@@
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
}
if ((verbose & VERBOSE_POOL) && (pool_name != NULL)) {
- llapi_printf(LLAPI_MSG_NORMAL, "pool: %s", pool_name);
- is_dir = 1;
+ if (verbose & ~VERBOSE_POOL)
+ llapi_printf(LLAPI_MSG_NORMAL, "%spool: ",
+ prefix);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%c", pool_name, nl);
}
if (is_dir && (verbose != VERBOSE_OBJID))
@@
-1445,7
+1656,7
@@
static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name,
struct lov_user_ost_data_v1 *objects,
char *path, int is_dir,
- int obdindex, int depth, int header)
+ int obdindex, int depth, int header
, int raw
)
{
int i, obdstripe = (obdindex != OBD_NOT_FOUND) ? 0 : 1;
@@
-1459,8
+1670,8
@@
void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name,
}
if (obdstripe == 1)
- lov_dump_user_lmm_header(lum, path, objects, is_dir, header,
depth,
- pool_name);
+ lov_dump_user_lmm_header(lum, path, objects, is_dir, header,
+
depth, raw,
pool_name);
if (!is_dir && (header & VERBOSE_OBJID)) {
if (obdstripe == 1)
@@
-1490,7
+1701,7
@@
void llapi_lov_dump_user_lmm(struct find_param *param,
param->lmd->lmd_lmm.lmm_objects,
path, is_dir,
param->obdindex, param->maxdepth,
- param->verbose);
+ param->verbose
, param->raw
);
break;
case LOV_USER_MAGIC_V3: {
char pool_name[LOV_MAXPOOLNAME + 1];
@@
-1503,7
+1714,7
@@
void llapi_lov_dump_user_lmm(struct find_param *param,
lov_dump_user_lmm_v1v3(¶m->lmd->lmd_lmm, pool_name,
objects, path, is_dir,
param->obdindex, param->maxdepth,
- param->verbose);
+ param->verbose
, param->raw
);
break;
}
default:
@@
-1603,28
+1814,26
@@
int llapi_file_lookup(int dirfd, const char *name)
* Note: 5th actually means that the value is within the interval
* (limit - margin, limit]. */
static int find_value_cmp(unsigned int file, unsigned int limit, int sign,
- unsigned long long margin, int mds)
+
int negopt,
unsigned long long margin, int mds)
{
+ int ret = -1;
+
if (sign > 0) {
- if (file < limit)
- return mds ? 0 : 1;
- }
-
- if (sign == 0) {
- if (file <= limit && file + margin > limit)
- return mds ? 0 : 1;
- if (file + margin <= limit)
- return mds ? 0 : -1;
- }
-
- if (sign < 0) {
- if (file > limit)
- return 1;
- if (mds)
- return 0;
+ if (file <= limit)
+ ret = mds ? 0 : 1;
+ } else if (sign == 0) {
+ if (file <= limit && file + margin >= limit)
+ ret = mds ? 0 : 1;
+ else if (file + margin <= limit)
+ ret = mds ? 0 : -1;
+ } else if (sign < 0) {
+ if (file >= limit)
+ ret = 1;
+ else if (mds)
+ ret = 0;
}
- return
-1
;
+ return
negopt ? ~ret + 1 : ret
;
}
/* Check if the file time matches all the given criteria (e.g. --atime +/-N).
@@
-1642,7
+1851,8
@@
static int find_time_check(lstat_t *st, struct find_param *param, int mds)
/* Check if file is accepted. */
if (param->atime) {
ret = find_value_cmp(st->st_atime, param->atime,
- param->asign, 24 * 60 * 60, mds);
+ param->asign, param->exclude_atime,
+ 24 * 60 * 60, mds);
if (ret < 0)
return ret;
rc = ret;
@@
-1650,7
+1860,8
@@
static int find_time_check(lstat_t *st, struct find_param *param, int mds)
if (param->mtime) {
ret = find_value_cmp(st->st_mtime, param->mtime,
- param->msign, 24 * 60 * 60, mds);
+ param->msign, param->exclude_mtime,
+ 24 * 60 * 60, mds);
if (ret < 0)
return ret;
@@
-1662,7
+1873,8
@@
static int find_time_check(lstat_t *st, struct find_param *param, int mds)
if (param->ctime) {
ret = find_value_cmp(st->st_ctime, param->ctime,
- param->csign, 24 * 60 * 60, mds);
+ param->csign, param->exclude_ctime,
+ 24 * 60 * 60, mds);
if (ret < 0)
return ret;
@@
-1715,7
+1927,7
@@
static int cb_find_init(char *path, DIR *parent, DIR *dir,
/* If a time or OST should be checked, the decision is not taken yet. */
if (param->atime || param->ctime || param->mtime || param->obduuid ||
- param->size)
+ param->
check_
size)
decision = 0;
ret = 0;
@@
-1896,7
+2108,7
@@
obd_matches:
'glimpse-size-ioctl'. */
if (!decision && S_ISREG(st->st_mode) &&
param->lmd->lmd_lmm.lmm_stripe_count &&
- (param->size ||param->atime || param->mtime || param->ctime)) {
+ (param->
check_
size ||param->atime || param->mtime || param->ctime)) {
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
@@
-1949,10
+2161,10
@@
obd_matches:
goto decided;
}
- if (param->size)
+ if (param->
check_
size)
decision = find_value_cmp(st->st_size, param->size,
- param->size_sign, param->
size_units
,
- 0);
+ param->size_sign, param->
exclude_size
,
+
param->size_units,
0);
print_path:
if (decision != -1) {
@@
-2079,7
+2291,23
@@
static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
}
if (ret) {
- if (errno == ENODATA) {
+ if (errno == ENODATA && d != NULL) {
+ /* We need to "fake" the "use the default" values
+ * since the lmm struct is zeroed out at this point.
+ * The magic needs to be set in order to satisfy
+ * 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_object_seq = 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)
llapi_printf(LLAPI_MSG_NORMAL,
"%s has no stripe info\n", path);
@@
-2103,6
+2331,7
@@
static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
return ret;
}
+dump:
if (!param->get_mdt_index)
llapi_lov_dump_user_lmm(param, path, d ? 1 : 0);
@@
-2802,6
+3031,10
@@
static int root_ioctl(const char *mdtname, int opc, void *data, int *mdtidxp,
*mdtidxp = index;
rc = ioctl(fd, opc, data);
+ if (rc == -1)
+ rc = -errno;
+ else
+ rc = 0;
if (rc && want_error)
llapi_err(LLAPI_MSG_ERROR, "ioctl %d err %d", opc, rc);
@@
-2995,10
+3228,9
@@
int llapi_changelog_clear(const char *mdtname, const char *idstr,
int llapi_fid2path(const char *device, const char *fidstr, char *buf,
int buflen, long long *recno, int *linkno)
{
- char path[PATH_MAX];
struct lu_fid fid;
struct getinfo_fid2path *gf;
- int
fd,
rc;
+ int rc;
while (*fidstr == '[')
fidstr++;
@@
-3011,28
+3243,19
@@
int llapi_fid2path(const char *device, const char *fidstr, char *buf,
return -EINVAL;
}
- /* Take path or fsname */
- if (device[0] == '/') {
- strcpy(path, device);
- } else {
- rc = get_root_path(WANT_PATH | WANT_ERROR, (char *)device,
- NULL, path, -1);
- if (rc < 0)
- return rc;
- }
- sprintf(path, "%s/%s/fid/%s", path, dot_lustre_name, fidstr);
- fd = open(path, O_RDONLY | O_NONBLOCK);
- if (fd < 0)
- return -errno;
-
gf = malloc(sizeof(*gf) + buflen);
+ if (gf == NULL)
+ return -ENOMEM;
gf->gf_fid = fid;
gf->gf_recno = *recno;
gf->gf_linkno = *linkno;
gf->gf_pathlen = buflen;
- rc = ioctl(fd, OBD_IOC_FID2PATH, gf);
+
+ /* Take path or fsname */
+ rc = root_ioctl(device, OBD_IOC_FID2PATH, gf, NULL, 0);
if (rc) {
- llapi_err(LLAPI_MSG_ERROR, "ioctl err %d", rc);
+ if (rc != -ENOENT)
+ llapi_err(LLAPI_MSG_ERROR, "ioctl err %d", rc);
} else {
memcpy(buf, gf->gf_path, gf->gf_pathlen);
*recno = gf->gf_recno;
@@
-3040,7
+3263,6
@@
int llapi_fid2path(const char *device, const char *fidstr, char *buf,
}
free(gf);
- close(fd);
return rc;
}