From c16f92af14cbd952f4d1108d71a17c7543796ee5 Mon Sep 17 00:00:00 2001 From: kalpak Date: Tue, 1 Jul 2008 04:25:18 +0000 Subject: [PATCH] b=13128 i=adilger i=johann add -gid,-group,-uid-,-user options to lfs find --- lustre/ChangeLog | 4 + lustre/include/lustre/liblustreapi.h | 8 +- lustre/tests/sanity.sh | 46 ++++++++++ lustre/utils/lfs.c | 159 +++++++++++++++++++++++------------ lustre/utils/liblustreapi.c | 20 +++++ 5 files changed, 180 insertions(+), 57 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 2204e41..4918705 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -1132,6 +1132,10 @@ Details : In ldlm_resource_add_lock(), call to ldlm_resource_dump() case of long waiting queue, so change the debug level from D_OTHER to the less frequently used D_INFO. +Severity : enhancement +Bugzilla : 13128 +Description: add -gid, -group, -uid, -user options to lfs find + -------------------------------------------------------------------------------- 2007-08-10 Cluster File Systems, Inc. diff --git a/lustre/include/lustre/liblustreapi.h b/lustre/include/lustre/liblustreapi.h index 235e461..63f5db4 100644 --- a/lustre/include/lustre/liblustreapi.h +++ b/lustre/include/lustre/liblustreapi.h @@ -58,6 +58,8 @@ struct find_param { unsigned long long size; int size_sign; unsigned long long size_units; + uid_t uid; + gid_t gid; unsigned long zeroend:1, recursive:1, @@ -65,7 +67,11 @@ struct find_param { obds_printed:1, exclude_pattern:1, exclude_type:1, - have_fileinfo:1; + have_fileinfo:1, + exclude_gid:1, + exclude_uid:1, + check_gid:1, + check_uid:1; int verbose; int quiet; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index ffa3b55..03831df 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -2564,6 +2564,52 @@ test_56o() { } run_test 56o "check lfs find -mtime for old files ==========================" +test_56p() { + [ $RUNAS_ID -eq $UID ] && skip "RUNAS_ID = UID = $UID -- skipping" && return + + TDIR=$DIR/${tdir}g + rm -rf $TDIR + + setup_56 $NUMFILES $NUMDIRS + + chown $RUNAS_ID $TDIR/file* || error "chown $DIR/${tdir}g/file$i failed" + EXPECTED=$NUMFILES + NUMS="`$LFIND -uid $RUNAS_ID $TDIR | wc -l`" + [ $NUMS -eq $EXPECTED ] || \ + error "lfs find -uid $TDIR wrong: found $NUMS, expected $EXPECTED" + + EXPECTED=$(( ($NUMFILES+1) * $NUMDIRS + 1)) + NUMS="`$LFIND ! -uid $RUNAS_ID $TDIR | wc -l`" + [ $NUMS -eq $EXPECTED ] || \ + error "lfs find ! -uid $TDIR wrong: found $NUMS, expected $EXPECTED" + + echo "lfs find -uid and ! -uid passed." +} +run_test 56p "check lfs find -uid and ! -uid ===============================" + +test_56q() { + [ $RUNAS_ID -eq $UID ] && skip "RUNAS_ID = UID = $UID -- skipping" && return + + TDIR=$DIR/${tdir}g + rm -rf $TDIR + + setup_56 $NUMFILES $NUMDIRS + + chgrp $RUNAS_ID $TDIR/file* || error "chown $DIR/${tdir}g/file$i failed" + EXPECTED=$NUMFILES + NUMS="`$LFIND -gid $RUNAS_ID $TDIR | wc -l`" + [ $NUMS -eq $EXPECTED ] || \ + error "lfs find -gid $TDIR wrong: found $NUMS, expected $EXPECTED" + + EXPECTED=$(( ($NUMFILES+1) * $NUMDIRS + 1)) + NUMS="`$LFIND ! -gid $RUNAS_ID $TDIR | wc -l`" + [ $NUMS -eq $EXPECTED ] || \ + error "lfs find ! -gid $TDIR wrong: found $NUMS, expected $EXPECTED" + + echo "lfs find -gid and ! -gid passed." +} +run_test 56q "check lfs find -gid and ! -gid ===============================" + test_57a() { # note test will not do anything if MDS is not local remote_mds && skip "remote MDS" && return diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 8772c5a..845da41 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -105,7 +105,9 @@ command_t cmdlist[] = { "usage: find ... \n" " [[!] --atime|-A [+-]N] [[!] --mtime|-M [+-]N] [[!] --ctime|-C [+-]N]\n" " [--maxdepth|-D N] [[!] --name|-n ] [--print0|-P]\n" - " [--print|-p] [--obd|-O ] [[!] --type|-t ]\n" + " [--print|-p] [--obd|-O ] [[!] --size|-s [+-]N[bkMGTP]]\n" + " [[!] --type|-t ] [[!] --gid|-g N] [[!] --group|-G ]\n" + " [[!] --uid|-u N] [[!] --user|-U ]\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"}, @@ -326,6 +328,60 @@ static int set_time(time_t *time, time_t *set, char *str) return res; } +static int name2id(unsigned int *id, char *name, int type) +{ + if (type == USRQUOTA) { + struct passwd *entry; + + if (!(entry = getpwnam(name))) { + if (!errno) + errno = ENOENT; + return -1; + } + + *id = entry->pw_uid; + } else { + struct group *entry; + + if (!(entry = getgrnam(name))) { + if (!errno) + errno = ENOENT; + return -1; + } + + *id = entry->gr_gid; + } + + return 0; +} + +static int id2name(char **name, unsigned int id, int type) +{ + if (type == USRQUOTA) { + struct passwd *entry; + + if (!(entry = getpwuid(id))) { + if (!errno) + errno = ENOENT; + return -1; + } + + *name = entry->pw_name; + } else { + struct group *entry; + + if (!(entry = getgrgid(id))) { + if (!errno) + errno = ENOENT; + return -1; + } + + *name = entry->gr_name; + } + + return 0; +} + static int lfs_find(int argc, char **argv) { int new_fashion = 1; @@ -339,6 +395,10 @@ static int lfs_find(int argc, char **argv) {"ctime", required_argument, 0, 'C'}, {"mtime", required_argument, 0, 'M'}, {"maxdepth", required_argument, 0, 'D'}, + {"gid", required_argument, 0, 'g'}, + {"group", required_argument, 0, 'G'}, + {"uid", required_argument, 0, 'u'}, + {"user", required_argument, 0, 'U'}, {"name", required_argument, 0, 'n'}, /* --obd is considered as a new option. */ {"obd", required_argument, 0, 'O'}, @@ -359,11 +419,12 @@ static int lfs_find(int argc, char **argv) time_t *xtime; int *xsign; int isoption; + char *endptr; time(&t); optind = 0; - while ((c = getopt_long_only(argc, argv, "-A:C:D:M:n:PpO:qrs:t:v", + while ((c = getopt_long_only(argc, argv, "-A:C:D:g:G:M:n:PpO:qrs:t:u:U:v", long_opts, NULL)) >= 0) { xtime = NULL; xsign = NULL; @@ -430,6 +491,46 @@ static int lfs_find(int argc, char **argv) new_fashion = 1; param.maxdepth = strtol(optarg, 0, 0); break; + case 'g': + new_fashion = 1; + param.gid = strtol(optarg, &endptr, 10); + if (optarg == endptr) { + fprintf(stderr, "Bad gid: %s\n", optarg); + return CMD_HELP; + } + param.exclude_gid = !!neg_opt; + param.check_gid = 1; + break; + case 'G': + new_fashion = 1; + ret = name2id(¶m.gid, optarg, GRPQUOTA); + if (ret != 0) { + fprintf(stderr, "Group: %s cannot be found.\n", optarg); + return -1; + } + param.exclude_gid = !!neg_opt; + param.check_gid = 1; + break; + case 'u': + new_fashion = 1; + param.uid = strtol(optarg, &endptr, 10); + if (optarg == endptr) { + fprintf(stderr, "Bad uid: %s\n", optarg); + return CMD_HELP; + } + param.exclude_uid = !!neg_opt; + param.check_uid = 1; + break; + case 'U': + new_fashion = 1; + ret = name2id(¶m.uid, optarg, USRQUOTA); + if (ret != 0) { + fprintf(stderr, "User: %s cannot be found.\n", optarg); + return -1; + } + param.exclude_uid = !!neg_opt; + param.check_uid = 1; + break; case 'n': new_fashion = 1; param.pattern = (char *)optarg; @@ -1297,60 +1398,6 @@ static int lfs_quotaoff(int argc, char **argv) return 0; } -static int name2id(unsigned int *id, char *name, int type) -{ - if (type == USRQUOTA) { - struct passwd *entry; - - if (!(entry = getpwnam(name))) { - if (!errno) - errno = ENOENT; - return -1; - } - - *id = entry->pw_uid; - } else { - struct group *entry; - - if (!(entry = getgrnam(name))) { - if (!errno) - errno = ENOENT; - return -1; - } - - *id = entry->gr_gid; - } - - return 0; -} - -static int id2name(char **name, unsigned int id, int type) -{ - if (type == USRQUOTA) { - struct passwd *entry; - - if (!(entry = getpwuid(id))) { - if (!errno) - errno = ENOENT; - return -1; - } - - *name = entry->pw_name; - } else { - struct group *entry; - - if (!(entry = getgrgid(id))) { - if (!errno) - errno = ENOENT; - return -1; - } - - *name = entry->gr_name; - } - - return 0; -} - #define ARG2INT(nr, str, msg) \ do { \ char *endp; \ diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 5e56d7f..a278c31 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -1153,6 +1153,26 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, } } + 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->check_gid) { + if (st->st_gid == param->gid) { + if (param->exclude_gid) + goto decided; + } else { + if (!param->exclude_gid) + goto decided; + } + } + /* Check the time on mds. */ if (!decision) { int for_mds; -- 1.8.3.1