.br
.B lfs check <mds|osts|servers>
.br
-.B lfs df [-i] [-h] [path]
+.B lfs df [-i] [-h] [--pool|-p <fsname>[.<pool>] [path]
.br
.B lfs find [[!] --atime|-A [-+]N] [[!] --mtime|-M [-+]N]
\fB[[!] --ctime|-C [-+]N] [--maxdepth|-D N] [--name|-n pattern]
\fB[--recursive|-r] <dirname|filename>\fR
.br
.B lfs setstripe [--size|-s stripe-size] [--count|-c stripe-cnt]
- \fB[--offset|-o start-ost] [--pool|-p pool-name]
+ \fB[--offset|-o start-ost] [--pool|-p <pool>]
\fB<dir|filename>\fR
.br
.B lfs setstripe -d <dir>
Display the status of MDS or OSTs (as specified in the command) or all the servers (MDS and OSTs)
.TP
.B df
-Report filesystem disk space usage or inodes usage of each MDT/OST.
+Report filesystem disk space usage or inodes usage of each MDT/OST. Can limit
+the scope to a specific OST pool
.TP
.B find
To search the directory tree rooted at the given dir/file name for the files that match the given parameters: \fB--atime\fR (file was last accessed N*24 hours ago), \fB--ctime\fR (file's status was last changed N*24 hours ago), \fB--mtime\fR (file's data was last modified N*24 hours ago), \fB--obd\fR (file has an object on a specific OST or OSTs), \fB--size\fR (file has size in bytes, or \fBk\fRilo-, \fBM\fRega-, \fBG\fRiga-, \fBT\fRera-, \fBP\fReta-, or \fBE\fRxabytes if a suffix is given), \fB--type\fR (file has the type: \fBb\fRlock, \fBc\fRharacter, \fBd\fRirectory, \fBp\fRipe, \fBf\fRile, sym\fBl\fRink, \fBs\fRocket, or \fBD\fRoor (Solaris)), \fB--uid\fR (file has specific numeric user ID), \fB--user\fR (file owned by specific user, numeric user ID allowed), \fB--gid\fR (file has specific group ID), \fB--group\fR (file belongs to specific group, numeric group ID allowed). The option \fB--maxdepth\fR limits find to decend at most N levels of directory tree. The options \fB--print\fR and \fB--print0\fR print full file name, followed by a newline or NUL character correspondingly. Using \fB!\fR before an option negates its meaning (\fIfiles NOT matching the parameter\fR). Using \fB+\fR before a numeric value means \fIfiles with the parameter OR MORE\fR, while \fB-\fR before a numeric value means \fIfiles with the parameter OR LESS\fR.
To list the striping info for a given filename or files in a directory, optionally recursively, for all files in a directory tree: \fB--quiet\fR (don't print object IDs), \fB--verbose\fR (print striping parameters), \fB--recursive\fR (recurse into subdirectories).
.TP
.B setstripe [--size stripe-size] [--count stripe-cnt]
- \fB[--offset start-ost] [--pool pool-name]\fR
+ \fB[--offset start-ost] [--pool <pool>]\fR
.br
To create a new file, or set the directory default, with the specified striping parameters. The
.I stripe-count
is the OST index (base 10, starting at 0) on which to start striping for this file. A
.I start-ost
of -1 allows the MDS to choose the starting index and it is strongly recommended, as this allows space and load balancing to be done by the MDS as needed. The
-.I pool-name
+.I pool
is the name of a predefined pool of OSTs (see
.I lctl
) that will be used for striping. The
.B $ lfs df -i
Lists inode usage per OST and MDT
.TP
+.B lfs df --pool <filesystem>[.<pool>] | <pathname>
+List space or inode usage for a specific OST pool
+.TP
.B $ lfs quota -u bob /mnt/lustre
List quotas of user `bob'
.TP
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_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);
extern int parse_size(char *optarg, unsigned long long *size,
unsigned long long *size_units, int bytes_spec);
run_test 200f "Create files in a pool ==================================="
test_200g() {
+ remote_mgs_nodsh && skip "remote MGS with nodsh" && return
+ TGT=$($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | head -1)
+ res=$($LFS df --pool $FSNAME.$POOL | awk '{print $1}' | grep "$FSNAME-OST ")
+ [ "$res" = "$TGT" ] || echo "Pools OSTS $TGT is not $res that lfs df reports"
+}
+run_test 200g "lfs df a pool ============================================"
+
+test_201a() { # was 200g
remote_mgs_nodsh && skip "remote MGS with nodsh" && return
TGT=$($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | head -1)
do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL | grep $TGT" "" || error "$TGT not removed from $FSNAME.$POOL"
}
-run_test 200g "Remove a target from a pool ============================="
+run_test 201a "Remove a target from a pool ============================="
-test_200h() {
+test_201b() { # was 200h
remote_mgs_nodsh && skip "remote MGS with nodsh" && return
for TGT in $($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | sort -u)
do
# striping on an empty pool should fall back to "pool of everything"
$SETSTRIPE -p $POOL ${POOL_FILE}/$tfile || error "failed to create file with empty pool"
}
-run_test 200h "Remove all targets from a pool =========================="
+run_test 201b "Remove all targets from a pool =========================="
-test_200i() {
+test_201c() { # was 200i
remote_mgs_nodsh && skip "remote MGS with nodsh" && return
do_facet mgs $LCTL pool_destroy $FSNAME.$POOL
# get param should return err once pool is gone
wait_update $HOSTNAME "lctl get_param -n lov.$FSNAME-*.pools.$POOL 2>/dev/null || echo foo" "foo" && return 0
error "Pool $FSNAME.$POOL is not destroyed"
}
-run_test 200i "Remove a pool ============================================"
+run_test 201c "Remove a pool ============================================"
test_212() {
size=`date +%s`
"set the default striping pattern on an existing directory or\n"
"delete the default striping pattern from an existing directory\n"
"usage: setstripe [--size|-s stripe_size] [--offset|-o start_ost]\n"
- " [--count|-c stripe_count] [--pool|-p pool_name]\n"
+ " [--count|-c stripe_count] [--pool|-p <pool>]\n"
" <dir|filename>\n"
" or \n"
" setstripe -d <dir> (to delete default striping)\n"
"\t respectively)\n"
"\tstart_ost: OST index of first stripe (-1 filesystem default)\n"
"\tstripe_count: Number of OSTs to stripe over (0 default, -1 all)\n"
- "\tpool_name: Name of OST pool"},
+ "\tpool: Name of OST pool"},
{"getstripe", lfs_getstripe, 0,
"To list the striping info for a given file or files in a\n"
"directory or recursively for all files in a directory tree.\n"
" [--recursive | -r] <dir|file> ..."},
{"pool_list", lfs_poollist, 0,
"List pools or pool OSTs\n"
- "usage: pool_list <fsname>[.<poolname>] | <pathname>\n"},
+ "usage: pool_list <fsname>[.<pool>] | <pathname>\n"},
{"find", lfs_find, 0,
"To find files that match given parameters recursively in a directory tree.\n"
"usage: find <dir|file> ... \n"
" [--print|-p] [--obd|-O <uuid[s]>] [[!] --size|-s [+-]N[bkMGTP]]\n"
" [[!] --type|-t <filetype>] [[!] --gid|-g N] [[!] --group|-G <name>]\n"
" [[!] --uid|-u N] [[!] --user|-U <name>]\n"
- " [[!] --pool <name>]\n"
+ " [[!] --pool <pool>]\n"
"\t !: used before an option indicates 'NOT' the requested attribute\n"
"\t -: used before an value indicates 'AT MOST' the requested value\n"
"\t +: used before an option indicates 'AT LEAST' the requested value\n"},
{"osts", lfs_osts, 0, "osts"},
{"df", lfs_df, 0,
"report filesystem disk space usage or inodes usage"
- "of each MDS/OSD.\n"
- "Usage: df [-i] [-h] [path]"},
+ "of each MDS and all OSDs or a batch belonging to a specific pool .\n"
+ "Usage: df [-i] [-h] [--pool|-p <fsname>[.<pool>] [path]"},
#ifdef HAVE_SYS_QUOTA_H
{"quotachown",lfs_quotachown, 0,
"Change files' owner or group on the specified filesystem.\n"
return 0;
}
-static int mntdf(char *mntdir, int ishow, int cooked)
+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;
__u32 index;
int rc;
+ if (pool) {
+ poolname = strchr(pool, '.');
+ if (poolname != NULL) {
+ if (strncmp(fsname, pool, strlen(fsname))) {
+ fprintf(stderr, "filesystem name incorrect\n");
+ return -ENODEV;
+ }
+ poolname++;
+ } else
+ poolname = pool;
+ }
+
if (ishow)
printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
"UUID", "Inodes", "IUsed", "IFree",
if (rc == -EAGAIN)
continue;
+ if (llapi_search_ost(fsname, poolname,
+ obd_uuid2str(&uuid_buf)) != 1)
+ continue;
+
if (rc == -ENOTCONN || rc == -ETIMEDOUT || rc == -EIO ||
rc == -ENODATA || rc == 0) {
showdf(mntdir, &stat_buf, obd_uuid2str(&uuid_buf),
char *mntdir = NULL;
int ishow = 0, cooked = 0;
int c, rc = 0;
+ char fsname[PATH_MAX], *pool_name = NULL;
+ struct option long_opts[] = {
+ {"pool", required_argument, 0, 'p'},
+ {0, 0, 0, 0}
+ };
optind = 0;
- while ((c = getopt(argc, argv, "ih")) != -1) {
+ while ((c = getopt_long(argc, argv, "ihp:", long_opts, NULL)) != -1) {
switch (c) {
case 'i':
ishow = 1;
case 'h':
cooked = 1;
break;
+ case 'p':
+ pool_name = optarg;
+ break;
default:
return CMD_HELP;
}
fprintf(stderr, "error: invalid path '%s': %s\n",
path, strerror(-rc));
} else {
- rc = llapi_search_mounts(rpath, 0, mntdir, NULL);
+ rc = llapi_search_mounts(rpath, 0, mntdir, fsname);
if (rc == 0 && mntdir[0] != '\0') {
- rc = mntdf(mntdir, ishow, cooked);
+ rc = mntdf(mntdir, fsname, pool_name,
+ ishow, cooked);
printf("\n");
}
}
} else {
int index = 0;
- while (llapi_search_mounts(NULL, index++, mntdir, NULL) == 0) {
- rc = mntdf(mntdir, ishow, cooked);
+ while (llapi_search_mounts(NULL, index++, mntdir, fsname)==0) {
+ rc = mntdf(mntdir, fsname, pool_name,
+ ishow, cooked);
if (rc)
break;
printf("\n");
* if ostname is NULL, returns 1 if pool is not empty and 0 if pool empty
* if ostname is not NULL, returns 1 if OST is in pool and 0 if not
*/
-static int search_ost(char *fsname, char *poolname, char *ostname)
+int llapi_search_ost(char *fsname, char *poolname, char *ostname)
{
FILE *fd;
char buffer[PATH_MAX + 1];
{
int rc;
- rc = search_ost(fsname, poolname, ostname);
+ rc = llapi_search_ost(fsname, poolname, ostname);
if (rc < 0 && (cmd != LCFG_POOL_NEW)) {
fprintf(stderr, "Pool %s.%s not found\n",
fsname, poolname);
ostname, fsname, poolname);
return -EEXIST;
}
- rc = search_ost(fsname, NULL, ostname);
+ rc = llapi_search_ost(fsname, NULL, ostname);
if (rc == 0) {
fprintf(stderr, "OST %s is not part of the '%s' fs.\n",
ostname, fsname);
switch (cmd) {
case LCFG_POOL_NEW: {
do {
- rc = search_ost(fsname, poolname, NULL);
+ rc = llapi_search_ost(fsname, poolname, NULL);
if (rc == -ENODEV)
return rc;
if (rc < 0)
}
case LCFG_POOL_DEL: {
do {
- rc = search_ost(fsname, poolname, NULL);
+ rc = llapi_search_ost(fsname, poolname, NULL);
if (rc == -ENODEV)
return rc;
if (rc >= 0)
}
case LCFG_POOL_ADD: {
do {
- rc = search_ost(fsname, poolname, ostname);
+ rc = llapi_search_ost(fsname, poolname, ostname);
if (rc == -ENODEV)
return rc;
if (rc != 1)
}
case LCFG_POOL_REM: {
do {
- rc = search_ost(fsname, poolname, ostname);
+ rc = llapi_search_ost(fsname, poolname, ostname);
if (rc == -ENODEV)
return rc;
if (rc == 1)