From 337233e0c5e538c34dea3977e20d52cbdf8f8619 Mon Sep 17 00:00:00 2001 From: bobijam Date: Thu, 22 Mar 2007 06:00:31 +0000 Subject: [PATCH] Branch HEAD b=10997 r=adilger Description: lfs setstripe use optional parameters instead of postional parameters. --- lustre/ChangeLog | 5 + lustre/doc/lfs.1 | 11 +- lustre/doc/lfs.lyx | 501 +++++++++++++++++++++++---------------- lustre/tests/Makefile.am | 4 + lustre/tests/ll_getstripe_info.c | 57 +++++ lustre/tests/sanity.sh | 19 ++ lustre/utils/lfs.c | 126 ++++++++-- 7 files changed, 493 insertions(+), 230 deletions(-) create mode 100644 lustre/tests/ll_getstripe_info.c diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 1200829..fd6b5f1 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -245,6 +245,11 @@ Description: versioning check is incomplete Details : Checking the version difference of client vs. server, report error if the gap is too big. +Severity : enhancement +Bugzilla : 10997 +Description: lfs setstripe use optional parameters instead of postional + parameters. + ------------------------------------------------------------------------------ TBD Cluster File Systems, Inc. diff --git a/lustre/doc/lfs.1 b/lustre/doc/lfs.1 index 959d7b5..bd673da 100644 --- a/lustre/doc/lfs.1 +++ b/lustre/doc/lfs.1 @@ -13,7 +13,11 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the .B lfs getstripe [--obd|-O ] [--quiet|-q] [--verbose|-v] \fB[--recursive|-r] \fR .br -.B lfs setstripe +.B lfs setstripe +.br +.B lfs setstripe [--size|-s stripe-size] [--index|-i start-ost] [--count|-c stripe-cnt] +.br +.B lfs setstripe -d .br .B lfs quotachown [-i] .br @@ -28,8 +32,6 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the .br .B lfs quota [-o obd_uuid] [-u|-g] .br -.B lfs setstripe -.br .B lfs check .br .B lfs df [-i] [-h] [path] @@ -90,6 +92,9 @@ Quit the interactive lfs session .B $ lfs setstripe /mnt/lustre/file1 131072 -1 2 This creats a file striped on two OSTs with 128kB on each stripe. .TP +.B $ lfs setstripe -d /mnt/lustre/dir +This deletes a default stripe pattern on dir. New files will use the default striping pattern created therein. +.TP .B $ lfs find /mnt/lustre/file1 Lists the object allocation of a given file .TP diff --git a/lustre/doc/lfs.lyx b/lustre/doc/lfs.lyx index 3b4588f..a6f2ebb 100644 --- a/lustre/doc/lfs.lyx +++ b/lustre/doc/lfs.lyx @@ -1,160 +1,194 @@ -#LyX 1.3 created this file. For more info see http://www.lyx.org/ -\lyxformat 221 +#LyX 1.4.4 created this file. For more info see http://www.lyx.org/ +\lyxformat 245 +\begin_document +\begin_header \textclass amsart \language english \inputencoding auto \fontscheme times \graphics default \paperfontsize default -\spacing single +\spacing single \papersize letterpaper -\paperpackage a4 -\use_geometry 0 -\use_amsmath 0 -\use_natbib 0 -\use_numerical_citations 0 +\use_geometry false +\use_amsmath 1 +\cite_engine basic +\use_bibtopic false \paperorientation portrait \secnumdepth 3 \tocdepth 3 \paragraph_separation skip \defskip medskip \quotes_language english -\quotes_times 2 \papercolumns 1 \papersides 1 \paperpagestyle default +\tracking_changes false +\output_changes true +\end_header -\layout Section +\begin_body +\begin_layout Section LFS -\layout Subsection +\end_layout +\begin_layout Subsection NAME -\layout Description +\end_layout +\begin_layout Description lfs Lustre utility to create a file with specific striping pattern and manipulat e disk quotas -\layout Subsection +\end_layout +\begin_layout Subsection SYNOPSIS -\layout Standard +\end_layout +\begin_layout Standard -\series bold +\series bold lfs -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ find [--atime|-A N] [--mtime|-M N] [--ctime|-C N] [--maxdepth|-D N] [--print0 |-P] [--print|-p] [--obd|-O ] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ find [--quiet|-q] [--verbose|-v] [--recursive|-r] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ getstripe [--obd|-O ] [--quiet|-q] [--verbose|-v] [--recursive|-r] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ setstripe -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace \space{} +setstripe [--size|-s stripe_size] [--index|-i start_ost] + [--count|-c stripe_cnt] +\end_layout + +\begin_layout Standard + +\series bold +lfs\InsetSpace ~ setstripe -d -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ check -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ quotachog [-i] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ quotacheck [-ug] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ quotaon [-ugf] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ quotaoff [-ug] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ setquota [-u|-g] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ quota [-o obd_uuid] [-u|-g] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ df [-i] [-h] [path] -\layout Standard +\end_layout +\begin_layout Standard -\series bold -lfs\SpecialChar ~ +\series bold +lfs\InsetSpace ~ help -\layout Subsection +\end_layout +\begin_layout Subsection DESCRIPTION -\layout Standard +\end_layout +\begin_layout Standard This utility can be used to create a new file with a specific striping pattern, determine the default striping pattern, gather the extended attributes (object numbers and location) for a specific file, and manipulate disk quotas. It can be invoked interactively without any arguments or in a non-interactive mode with one of the arguements listed and explained below: -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold setstripe -\series default +\series default To create a new file with a specific striping pattern -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold find -\series default +\series default To search the directory tree rooted at the given dir/file name for the files that match the given parameters: --atime (file was last accessed N*24 hours ago), --ctime (file's status was last changed N*24 hours ago), @@ -164,293 +198,354 @@ find tree. The options --print and --print0 print full file name, followed by a newline and null character correspondingly. -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold find -\series default +\series default To list the striping info for a given filename or files in a directory or recursively for all files in a directory tree use one of the following options: [--quiet|-q] [--verbose|-v] [--recursive|-r]. If one of these options is given find works in old (obsolete, please use getstripe instead) mode. -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold getstripe -\series default +\series default To list the striping info for given filename or files in a directory or recursively for all files in a directory tree. It can also be used to list the files that have objects on a specific OST. -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold check -\series default +\series default Display the status of MDS or OSTs (as specified in the command) or all the servers (MDS and OSTs) -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold osts -\series default +\series default List all the OSTs for the filesystem -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold quotachog -\series default +\series default Change files' owner and group on OSTs of the specified filesystem -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold quotacheck -\series default +\series default Scan the specified filesystem for disk usage, and create or update quota files -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold quotaon -\series default +\series default Turn filesystem quotas on -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold quotaoff -\series default +\series default Turn filesystem quotas off -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold setquota -\series default +\series default Set filesystem quotas -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold quota -\series default +\series default Display disk usage and limits -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold df -\series default +\series default Report filesystem disk space usage or inodes usage of each MDS/OSD. -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold help -\series default +\series default Provides brief help on the various arguments -\layout List -\labelwidthstring 00.00.0000 +\end_layout +\begin_layout List +\labelwidthstring 00.00.0000 -\series bold +\series bold exit/quit -\series default +\series default Quit the interactive lfs session -\layout Subsection +\end_layout +\begin_layout Subsection EXAMPLES -\layout Description +\end_layout +\begin_layout Description This creates a file striped on one OST -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs setstripe /mnt/lustre/file1 131072 0 1 -\layout Description +\end_layout +\begin_layout Description This creates a default stripe pattern on and existing dir for all new files created therein. -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs setstripe /mnt/lustre/dir 131072 0 1 -\layout Description +\end_layout +\begin_layout Description This deletes a default stripe pattern on dir. New files will use the default striping pattern. created therein. -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs setstripe -d /mnt/lustre/dir -\layout Description +\end_layout +\begin_layout Description Listing the extended attributes of a given file -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs find /mnt/lustre/foo1 -\layout LyX-Code +\end_layout +\begin_layout LyX-Code OBDS: -\layout LyX-Code +\end_layout +\begin_layout LyX-Code 0: OST_localhost_UUID -\layout LyX-Code +\end_layout +\begin_layout LyX-Code /mnt/lustre/foo1 -\layout LyX-Code +\end_layout +\begin_layout LyX-Code obdidx objid objid group -\layout LyX-Code +\end_layout +\begin_layout LyX-Code 0 1 0x1 0 -\layout Description +\end_layout +\begin_layout Description Listing the extended attributes of all files in a given directory -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs find /mnt/lustre/ -\layout Description +\end_layout +\begin_layout Description Recursively list the extended attributes of all files in a given directory tree -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs find -r /mnt/lustre/ -\layout Description +\end_layout +\begin_layout Description List all the files that have objects on a specific OST -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs find -r --obd OST2_UUID /mnt/lustre/ -\layout Description +\end_layout +\begin_layout Description Check the status of all servers(mds, osts) -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs check servers -\layout LyX-Code +\end_layout +\begin_layout LyX-Code OSC_localhost.localdomain_OST_localhost_mds1 active. -\layout LyX-Code +\end_layout +\begin_layout LyX-Code OSC_localhost.localdomain_OST_localhost_MNT_localhost active. -\layout LyX-Code +\end_layout +\begin_layout LyX-Code MDC_localhost.localdomain_mds1_MNT_localhost active. -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ -\layout Description +\end_layout +\begin_layout Description List all the OSTs -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ lfs osts -\layout LyX-Code +\end_layout +\begin_layout LyX-Code OBDS: -\layout LyX-Code +\end_layout +\begin_layout LyX-Code 0: OST_localhost_UUID -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $ -\layout Description +\end_layout -Change\SpecialChar ~ -file\SpecialChar ~ -owner\SpecialChar ~ -and\SpecialChar ~ +\begin_layout Description +Change\InsetSpace ~ +file\InsetSpace ~ +owner\InsetSpace ~ +and\InsetSpace ~ group -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $lfs quotachog -i /mnt/lustre -\layout Description +\end_layout -Quotacheck\SpecialChar ~ -for\SpecialChar ~ -user\SpecialChar ~ -and\SpecialChar ~ +\begin_layout Description +Quotacheck\InsetSpace ~ +for\InsetSpace ~ +user\InsetSpace ~ +and\InsetSpace ~ group -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $lfs quotacheck -ug /mnt/lustre -\layout Description - -Turn\SpecialChar ~ -quotas\SpecialChar ~ -of\SpecialChar ~ -user\SpecialChar ~ -and\SpecialChar ~ -group\SpecialChar ~ +\end_layout + +\begin_layout Description +Turn\InsetSpace ~ +quotas\InsetSpace ~ +of\InsetSpace ~ +user\InsetSpace ~ +and\InsetSpace ~ +group\InsetSpace ~ on -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $lfs quotaon -ug /mnt/lustre -\layout Description - -Turn\SpecialChar ~ -quotas\SpecialChar ~ -of\SpecialChar ~ -user\SpecialChar ~ -and\SpecialChar ~ -group\SpecialChar ~ +\end_layout + +\begin_layout Description +Turn\InsetSpace ~ +quotas\InsetSpace ~ +of\InsetSpace ~ +user\InsetSpace ~ +and\InsetSpace ~ +group\InsetSpace ~ off -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $lfs quotaoff -ug /mnt/lustre -\layout Description - -Set\SpecialChar ~ -quotas\SpecialChar ~ -of\SpecialChar ~ -user\SpecialChar ~ -`bob':\SpecialChar ~ -1GB\SpecialChar ~ -block\SpecialChar ~ -quota\SpecialChar ~ -and\SpecialChar ~ -10,000\SpecialChar ~ -file\SpecialChar ~ +\end_layout + +\begin_layout Description +Set\InsetSpace ~ +quotas\InsetSpace ~ +of\InsetSpace ~ +user\InsetSpace ~ +`bob':\InsetSpace ~ +1GB\InsetSpace ~ +block\InsetSpace ~ +quota\InsetSpace ~ +and\InsetSpace ~ +10,000\InsetSpace ~ +file\InsetSpace ~ quota -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $lfs setquota -u bob 0 1000000 0 10000 /mnt/lustre -\layout Description +\end_layout -List\SpecialChar ~ -quotas\SpecialChar ~ -of\SpecialChar ~ -user\SpecialChar ~ +\begin_layout Description +List\InsetSpace ~ +quotas\InsetSpace ~ +of\InsetSpace ~ +user\InsetSpace ~ `bob' -\layout LyX-Code +\end_layout +\begin_layout LyX-Code $lfs quota -u bob /mnt/lustre -\layout Subsection +\end_layout +\begin_layout Subsection BUGS -\layout Standard +\end_layout +\begin_layout Standard None are known. -\the_end +\end_layout + +\end_body +\end_document diff --git a/lustre/tests/Makefile.am b/lustre/tests/Makefile.am index 0f167e0..0b4a915 100644 --- a/lustre/tests/Makefile.am +++ b/lustre/tests/Makefile.am @@ -28,6 +28,7 @@ noinst_PROGRAMS += small_write multiop sleeptest ll_sparseness_verify cmknod noinst_PROGRAMS += ll_sparseness_write mrename ll_dirstripe_verify mkdirmany rmdirmany noinst_PROGRAMS += openfilleddirunlink rename_many memhog iopentest1 iopentest2 noinst_PROGRAMS += mmap_sanity flock_test writemany random-reads flocks_test +noinst_PROGRAMS += ll_getstripe_info if MPITESTS noinst_PROGRAMS += parallel_grouplock write_append_truncate createmany_mpi endif @@ -39,6 +40,9 @@ stat_SOURCES = stat.c stat_fs.h # mkdirdeep_LDADD=-L$(top_builddir)/lnet/utils -lptlctl $(LIBREADLINE) mmap_sanity_SOURCES= mmap_sanity.c +LIBLUSTREAPI := $(top_builddir)/lustre/utils/liblustreapi.a +ll_getstripe_info_LDADD=$(LIBLUSTREAPI) + if MPITESTS LAM_LD_FLAGS=-L/opt/lam/lib -lmpi -llam -lpthread write_append_truncate_SOURCES=write_append_truncate.c diff --git a/lustre/tests/ll_getstripe_info.c b/lustre/tests/ll_getstripe_info.c new file mode 100644 index 0000000..b8df70c --- /dev/null +++ b/lustre/tests/ll_getstripe_info.c @@ -0,0 +1,57 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * ll_getstripe_info : + * - get file's stripe info. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define MAX_LOV_UUID_COUNT 1000 + +int main(int argc, char** argv) +{ + struct lov_user_md *lum_file = NULL; + int rc; + int lum_size; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + lum_size = lov_mds_md_size(MAX_LOV_UUID_COUNT); + + if ((lum_file = (struct lov_user_md *)malloc(lum_size)) == NULL) { + fprintf(stderr, "unable to allocate memory for ioctl's"); + rc = errno; + goto cleanup; + } + + rc = llapi_file_get_stripe(argv[1], lum_file); + if (rc) { + rc = errno; + goto cleanup; + } + + /* stripe_size stripe_count stripe_offset */ + printf("%d %d %d\n", + lum_file->lmm_stripe_size, + lum_file->lmm_stripe_count, + lum_file->lmm_objects[0].l_ost_idx); + +cleanup: + if (lum_file != NULL) + free(lum_file); + + return rc; +} diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 03ec592..4a7bc92 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -38,6 +38,7 @@ GETSTRIPE=${GETSTRIPE:-"$LFS getstripe"} LSTRIPE=${LSTRIPE:-"$LFS setstripe"} LFIND=${LFIND:-"$LFS find"} LVERIFY=${LVERIFY:-ll_dirstripe_verify} +LSTRIPEINFO=${LSTRIPEINFO:-ll_getstripe_info} LCTL=${LCTL:-lctl} MCREATE=${MCREATE:-mcreate} OPENFILE=${OPENFILE:-openfile} @@ -1123,6 +1124,24 @@ test_27t() { # bug 10864 } run_test 27t "check that utils parse path correctly" +test_27x() { # bug 10997 + mkdir -p $DIR/d27w || error "mkdir failed" + $LSTRIPE $DIR/d27w/f0 -s 65536 || error "lstripe failed" + size=`$LSTRIPEINFO $DIR/d27w/f0 | awk {'print $1'}` + [ $size -ne 65536 ] && error "stripe size $size != 65536" || true + + [ "$OSTCOUNT" -lt "2" ] && echo "skipping multiple stripe count/offset test" && return + for i in `seq 1 $OSTCOUNT`; do + offset=$(($i-1)) + $LSTRIPE $DIR/d27w/f$i -c $i -i $offset || error "lstripe -c $i -i $offset failed" + count=`$LSTRIPEINFO $DIR/d27w/f$i | awk {'print $2'}` + index=`$LSTRIPEINFO $DIR/d27w/f$i | awk {'print $3'}` + [ $count -ne $i ] && error "stripe count $count != $i" || true + [ $index -ne $offset ] && error "stripe offset $index != $offset" || true + done +} +run_test 27x "check lfs setstripe -c -s -i options =============" + test_28() { mkdir $DIR/d28 $CREATETEST $DIR/d28/ct || error diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index abda085..05f2919 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -75,12 +75,16 @@ command_t cmdlist[] = { "Create a new file with a specific striping pattern or\n" "set the default striping pattern on an existing directory or\n" "delete the default striping pattern from an existing directory\n" - "usage: setstripe \n" + "usage: setstripe \n" + " or \n" + " setstripe [--size|-s stripe_size]\n" + " [--index|-i stripe_index]\n" + " [--count|-c stripe_count]\n" " or \n" " setstripe -d (to delete default striping)\n" - "\tstripe size: Number of bytes on each OST (0 filesystem default)\n" - "\tstripe start: OST index of first stripe (-1 filesystem default)\n" - "\tstripe count: Number of OSTs to stripe over (0 default, -1 all)"}, + "\tstripe_size: Number of bytes on each OST (0 filesystem default)\n" + "\tstripe_index: OST index of first stripe (-1 filesystem default)\n" + "\tstripe_count: Number of OSTs to stripe over (0 default, -1 all)"}, {"getstripe", lfs_getstripe, 0, "To list the striping info for a given filename or files in a\n" "directory or recursively for all files in a directory tree.\n" @@ -148,42 +152,116 @@ static int lfs_setstripe(int argc, char **argv) long st_size; int st_offset, st_count; char *end; + int c; + int delete = 0; + char *stripe_size_arg = NULL; + char *stripe_off_arg = NULL; + char *stripe_count_arg = NULL; - if (argc != 5 && argc != 3) - return CMD_HELP; + struct option long_opts[] = { + {"size", required_argument, 0, 's'}, + {"count", required_argument, 0, 'c'}, + {"index", required_argument, 0, 'i'}, + {"delete", no_argument, 0, 'd'}, + {0, 0, 0, 0} + }; + st_size = 0; + st_offset = -1; + st_count = 0; + if (argc == 3 && strcmp(argv[1], "-d") == 0) { + /* for compatibility with the existing positional parameter + * usage */ + fname = argv[2]; + optind = 2; + } else if (argc == 5 && + (argv[2][0] != '-' || isdigit(argv[2][1])) && + (argv[3][0] != '-' || isdigit(argv[3][1])) && + (argv[4][0] != '-' || isdigit(argv[4][1])) ) { + /* for compatibility with the existing positional parameter + * usage */ + fname = argv[1]; + stripe_size_arg = argv[2]; + stripe_off_arg = argv[3]; + stripe_count_arg = argv[4]; + optind = 4; + } else { + while ((c = getopt_long(argc, argv, "c:di:s:", + long_opts, NULL)) >= 0) + { + switch (c) { + case 0: + /* Long options. */ + break; + case 'c': + stripe_count_arg = optarg; + break; + case 'd': + /* delete the default striping pattern */ + delete = 1; + break; + case 'i': + stripe_off_arg = optarg; + break; + case 's': + stripe_size_arg = optarg; + break; + case '?': + return CMD_HELP; + default: + fprintf(stderr, "error: %s: option '%s' " + "unrecognized\n", + argv[0], argv[optind - 1]); + return CMD_HELP; + } + } - if (argc == 3) { - if (strcmp(argv[1], "-d") != 0) + if (optind < argc) + fname = argv[optind]; + else return CMD_HELP; - fname = argv[2]; - st_size = 0; - st_offset = -1; - st_count = 0; - } else { - fname = argv[1]; + if (delete && + (stripe_size_arg != NULL || stripe_off_arg != NULL || + stripe_count_arg != NULL)) { + fprintf(stderr, "error: %s: cannot specify -d with " + "-s, -c or -i options\n", + argv[0]); + return CMD_HELP; + } + } + + if (optind != argc - 1) { + fprintf(stderr, "error: %s: only 1 filename|dirname can be " + "specified: '%s'\n", + argv[0], argv[argc-1]); + return CMD_HELP; + } - /* get the stripe size */ - st_size = strtoul(argv[2], &end, 0); + /* get the stripe size */ + if (stripe_size_arg != NULL) { + st_size = strtoul(stripe_size_arg, &end, 0); if (*end != '\0') { fprintf(stderr, "error: %s: bad stripe size '%s'\n", - argv[0], argv[2]); + argv[0], stripe_size_arg); return CMD_HELP; } - - /* get the stripe offset */ - st_offset = strtoul(argv[3], &end, 0); + } + /* get the stripe offset */ + if (stripe_off_arg != NULL) { + st_offset = strtoul(stripe_off_arg, &end, 0); if (*end != '\0') { fprintf(stderr, "error: %s: bad stripe offset '%s'\n", - argv[0], argv[3]); + argv[0], stripe_off_arg); return CMD_HELP; } - /* get the stripe count */ - st_count = strtoul(argv[4], &end, 0); + } + /* get the stripe count */ + if (stripe_count_arg != NULL) { + st_count = strtoul(stripe_count_arg, &end, 0); if (*end != '\0') { fprintf(stderr, "error: %s: bad stripe count '%s'\n", - argv[0], argv[4]); + argv[0], stripe_count_arg); return CMD_HELP; } } -- 1.8.3.1