From be6cb79265bae3d269565cc8ac60385b03d3449c Mon Sep 17 00:00:00 2001 From: yangsheng Date: Wed, 15 Jul 2009 15:27:53 +0000 Subject: [PATCH] Branch b1_8 b=19205 i=adilger, Jacques-Charles 'lfs df' for pool support. --- lustre/doc/lfs.1 | 14 +++++++---- lustre/include/lustre/liblustreapi.h | 1 + lustre/tests/sanity.sh | 19 ++++++++++---- lustre/utils/lfs.c | 49 +++++++++++++++++++++++++++--------- lustre/utils/obd.c | 14 +++++------ 5 files changed, 68 insertions(+), 29 deletions(-) diff --git a/lustre/doc/lfs.1 b/lustre/doc/lfs.1 index baf9906..baef846 100644 --- a/lustre/doc/lfs.1 +++ b/lustre/doc/lfs.1 @@ -7,7 +7,7 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the .br .B lfs check .br -.B lfs df [-i] [-h] [path] +.B lfs df [-i] [-h] [--pool|-p [.] [path] .br .B lfs find [[!] --atime|-A [-+]N] [[!] --mtime|-M [-+]N] \fB[[!] --ctime|-C [-+]N] [--maxdepth|-D N] [--name|-n pattern] @@ -23,7 +23,7 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the \fB[--recursive|-r] \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 ] \fB\fR .br .B lfs setstripe -d @@ -76,7 +76,8 @@ The various options supported by lctl are listed and explained below: 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. @@ -88,7 +89,7 @@ List all the OSTs for the filesystem 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 ]\fR .br To create a new file, or set the directory default, with the specified striping parameters. The .I stripe-count @@ -105,7 +106,7 @@ of 0 means to use the filesystem-wide default stripe size (default 1MB). The 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 @@ -184,6 +185,9 @@ Lists space usage per OST and MDT in human readable format. .B $ lfs df -i Lists inode usage per OST and MDT .TP +.B lfs df --pool [.] | +List space or inode usage for a specific OST pool +.TP .B $ lfs quotachown -i /mnt/lustre Change file owner and group .TP diff --git a/lustre/include/lustre/liblustreapi.h b/lustre/include/lustre/liblustreapi.h index 43a5ea7..8138208 100644 --- a/lustre/include/lustre/liblustreapi.h +++ b/lustre/include/lustre/liblustreapi.h @@ -161,6 +161,7 @@ extern int llapi_file_get_lov_uuid(const char *path, struct obd_uuid *lov_uuid); extern int llapi_file_fget_lov_uuid(int fd, struct obd_uuid *lov_uuid); extern int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count); extern int llapi_is_lustre_mnttype(const char *type); +extern int llapi_search_ost(char *fsname, char *poolname, char *ostname); extern int llapi_search_mounts(const char *pathname, int index, char *mntdir, char *fsname); extern int parse_size(char *optarg, unsigned long long *size, diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 48802dd..bc2e746 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -6039,13 +6039,22 @@ run_test 200f "Create files in a pool ===================================" test_200g() { test_pools || return 0 + + 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_200za() { # was 200g + test_pools || return 0 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 200za "Remove a target from a pool =============================" -test_200h() { +test_200zb() { # was 200h test_pools || return 0 for TGT in $($LCTL get_param -n lov.$FSNAME-*.pools.$POOL | sort -u) do @@ -6057,16 +6066,16 @@ test_200h() { $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 200zb "Remove all targets from a pool ==========================" -test_200i() { +test_200zc() { # was 200i test_pools || return 0 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 200zc "Remove a pool ============================================" # # tests that do cleanup/setup should be run at the end diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 10518bd..e17e199 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -105,7 +105,7 @@ command_t cmdlist[] = { "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 ]\n" " \n" " or \n" " setstripe -d (to delete default striping)\n" @@ -114,7 +114,7 @@ command_t cmdlist[] = { "\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" @@ -124,7 +124,7 @@ command_t cmdlist[] = { " [--recursive | -r] ..."}, {"pool_list", lfs_poollist, 0, "List pools or pool OSTs\n" - "usage: pool_list [.] | \n"}, + "usage: pool_list [.] | \n"}, {"find", lfs_find, 0, "To find files that match given parameters recursively in a directory tree.\n" "usage: find ... \n" @@ -133,7 +133,7 @@ command_t cmdlist[] = { " [--print|-p] [--obd|-O ] [[!] --size|-s [+-]N[bkMGTP]]\n" " [[!] --type|-t ] [[!] --gid|-g N] [[!] --group|-G ]\n" " [[!] --uid|-u N] [[!] --user|-U ]\n" - " [[!] --pool ]\n" + " [[!] --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"}, @@ -152,8 +152,8 @@ command_t cmdlist[] = { {"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 [.] [path]"}, #ifdef HAVE_SYS_QUOTA_H {"quotachown",lfs_quotachown, 0, "Change files' owner or group on the specified filesystem.\n" @@ -976,13 +976,26 @@ static int showdf(char *mntdir, struct obd_statfs *stat, 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", @@ -1030,6 +1043,10 @@ static int mntdf(char *mntdir, int ishow, int cooked) 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), @@ -1059,9 +1076,14 @@ static int lfs_df(int argc, char **argv) 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; @@ -1069,6 +1091,9 @@ static int lfs_df(int argc, char **argv) case 'h': cooked = 1; break; + case 'p': + pool_name = optarg; + break; default: return CMD_HELP; } @@ -1093,16 +1118,16 @@ static int lfs_df(int argc, char **argv) return rc; } - 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)) { + rc = mntdf(mntdir, fsname, pool_name, ishow, cooked); if (rc) break; printf("\n"); diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index 5b8f7ca..8e78102 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -2581,7 +2581,7 @@ static int find_poolpath(char *fsname, char *poolname, char *poolpath) * 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[MAXPATHLEN + 1]; @@ -2631,7 +2631,7 @@ static int check_pool_cmd(enum lcfg_command_type cmd, { int rc; - rc = search_ost(fsname, poolname, ostname); + rc = llapi_search_ost(fsname, poolname, NULL); if (rc < 0 && (cmd != LCFG_POOL_NEW)) { fprintf(stderr, "Pool %s.%s not found\n", fsname, poolname); @@ -2664,7 +2664,7 @@ static int check_pool_cmd(enum lcfg_command_type cmd, 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); @@ -2701,7 +2701,7 @@ static int check_pool_cmd_result(enum lcfg_command_type cmd, 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) @@ -2720,7 +2720,7 @@ static int check_pool_cmd_result(enum lcfg_command_type cmd, } 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) @@ -2739,7 +2739,7 @@ static int check_pool_cmd_result(enum lcfg_command_type cmd, } 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) @@ -2758,7 +2758,7 @@ static int check_pool_cmd_result(enum lcfg_command_type cmd, } 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) -- 1.8.3.1