Skip to content
Snippets Groups Projects
Commit 7d91dc70 authored by Andrew Perepechko's avatar Andrew Perepechko
Browse files

Branch b1_6

b=13915
i=johann
i=tianzy

patch 13584

implementation of "lfs quota -t" and "lfs setquota -t" time format string
parent e43ae2d4
No related branches found
No related tags found
No related merge requests found
......@@ -29,6 +29,8 @@ lfs \- Lustre utility to create a file with specific striping pattern, find the
.B lfs setquota [-u|-g] <name> <block-softlimit> <block-hardlimit>
\fB<inode-softlimit> <inode-hardlimit> <filesystem>\fR
.br
.B lfs setquota -t [ -u | -g ] <block-grace> <inode-grace> <filesystem>
.br
.B lfs quota [-o obd_uuid] [-u|-g] <name> <filesystem>
.br
.B lfs check <mds| osts| servers>
......@@ -69,9 +71,15 @@ To turn filesystem quotas off. Options specify quota for users (-u) groups (-g)
.B setquota [-u|-g] <name> <block-softlimit> <block-hardlimit> <inode-softlimit> <inode-hardlimit> <filesystem>
To set filesystem quotas for users or groups. Limits are specific as blocks and inodes, see EXAMPLES
.TP
.B setquota -t [ -u | -g ] <block-grace> <inode-grace> <filesystem>
To set filesystem quota grace times for users or groups. Grace time is specified in "XXwXXdXXhXXmXXs" format or as an integer seconds value, see EXAMPLES
.TP
.B quota [-o obd_uuid] [-u|-g] <name> <filesystem>
To display disk usage and limits, either for the full filesystem, or for objects on a specific obd. A user or group name must be specified.
.TP
.B quota -t [-u|-g] <filesystem>
To display block and inode grace times for user (-u) or group (-g) quotas
.TP
.B check
Display the status of MDS or OSTs (as specified in the command) or all the servers (MDS and OSTs)
.TP
......@@ -121,9 +129,15 @@ Turn quotas of user and group off
.B $ lfs setquota -u bob 0 1000000 0 10000 /mnt/lustre
Set quotas of user `bob': 1GB block quota and 10,000 file quota
.TP
.B $ lfs setquota -t -u 1000 1w4d /mnt/lustre
Set grace times for user quotas: 1000 seconds for block quotas, 1 week and 4 days for inode quotas
.TP
.B $ lfs quota -u bob /mnt/lustre
List quotas of user `bob'
.TP
.B $ lfs quota -t -u /mnt/lustre
Show grace times for user quotas on /mnt/lustre
.TP
.B $ lfs check servers
Check the status of all servers (MDT, OST)
.TP
......
......@@ -134,6 +134,13 @@ setquota [-u|-g] <name> <block-softlimit> <block-hardlimit> <inode-softlimit>
\begin_layout Standard
\series bold
lfs\InsetSpace ~
setquota -t [-u|-g] <block-grace> <inode-grace> <filesystem>
\end_layout
\begin_layout Standard
\series bold
lfs\InsetSpace ~
quota [-o obd_uuid] [-u|-g] <name> <filesystem>
......@@ -519,6 +526,32 @@ quota
$lfs setquota -u bob 0 1000000 0 10000 /mnt/lustre
\end_layout
\begin_layout Description
Set\InsetSpace ~
grace\InsetSpace ~
times\InsetSpace ~
for\InsetSpace ~
user\InsetSpace ~
quotas:\InsetSpace ~
1000\InsetSpace ~
seconds\InsetSpace ~
for\InsetSpace ~
block\InsetSpace ~
quotas,\InsetSpace ~
1\InsetSpace ~
week\InsetSpace ~
and\InsetSpace ~
4\InsetSpace ~
days\InsetSpace ~
for\InsetSpace ~
inode\InsetSpace ~
quotas
\end_layout
\begin_layout LyX-Code
$lfs setquota -t -u 1000 1w4d /mnt/lustre
\end_layout
\begin_layout Description
List\InsetSpace ~
quotas\InsetSpace ~
......
......@@ -435,6 +435,32 @@ test_4() {
}
run_test 4 "File soft limit (start timer, timer goes off, stop timer) ==="
test_4a() {
GR_STR1="1w3d"
GR_STR2="1000s"
GR_STR3="5s"
GR_STR4="1w2d3h4m5s"
GR_STR5="5c"
GR_STR6="1111111111111111"
# test of valid grace strings handling
echo " Valid grace strings test"
$LFS setquota -t -u $GR_STR1 $GR_STR2 $DIR
$LFS quota -u -t $DIR | grep "Block grace time: $GR_STR1"
$LFS setquota -t -g $GR_STR3 $GR_STR4 $DIR
$LFS quota -g -t $DIR | grep "Inode grace time: $GR_STR4"
# test of invalid grace strings handling
echo " Invalid grace strings test"
! $LFS setquota -t -u $GR_STR4 $GR_STR5 $DIR
! $LFS setquota -t -g $GR_STR4 $GR_STR6 $DIR
# cleanup
$LFS setquota -t -u $MAX_DQ_TIME $MAX_IQ_TIME $DIR
$LFS setquota -t -g $MAX_DQ_TIME $MAX_IQ_TIME $DIR
}
run_test 4a "Grace time strings handling ==="
# chown & chgrp (chown & chgrp successfully even out of block/file quota)
test_5() {
BLIMIT=$(( $BUNIT_SZ * $((OSTCOUNT + 1)) * 10)) # 10 bunits on each server
......
......@@ -1317,6 +1317,65 @@ do { \
} \
} while (0)
#define ADD_OVERFLOW(a,b) ((a + b) < a) ? (a = ULONG_MAX) : (a = a + b)
/* Convert format time string "XXwXXdXXhXXmXXs" into seconds value
* returns the value or ULONG_MAX on integer overflow or incorrect format
* Notes:
* 1. the order of specifiers is arbitrary (may be: 5w3s or 3s5w)
* 2. specifiers may be encountered multiple times (2s3s is 5 seconds)
* 3. empty integer value is interpreted as 0
*/
static unsigned long str2sec(const char* timestr) {
const char spec[] = "smhdw";
const unsigned long mult[] = {1, 60, 60*60, 24*60*60, 7*24*60*60};
unsigned long val = 0;
char *tail;
if (strpbrk(timestr, spec) == NULL) {
/* no specifiers inside the time string,
should treat it as an integer value */
val = strtoul(timestr, &tail, 10);
return *tail ? ULONG_MAX : val;
}
/* format string is XXwXXdXXhXXmXXs */
while (*timestr) {
unsigned long v;
int ind;
char* ptr;
v = strtoul(timestr, &tail, 10);
if (v == ULONG_MAX || *tail == '\0')
/* value too large (ULONG_MAX or more)
or missing specifier */
goto error;
ptr = strchr(spec, *tail);
if (ptr == NULL)
/* unknown specifier */
goto error;
ind = ptr - spec;
/* check if product will overflow the type */
if (!(v < ULONG_MAX / mult[ind]))
goto error;
ADD_OVERFLOW(val, mult[ind] * v);
if (val == ULONG_MAX)
goto error;
timestr = tail + 1;
}
return val;
error:
return ULONG_MAX;
}
int lfs_setquota(int argc, char **argv)
{
int c;
......@@ -1381,8 +1440,14 @@ int lfs_setquota(int argc, char **argv)
if (optind + 3 != argc)
return CMD_HELP;
ARG2INT(dqi->dqi_bgrace, argv[optind++], "block-grace");
ARG2INT(dqi->dqi_igrace, argv[optind++], "inode-grace");
if ((dqi->dqi_bgrace = str2sec(argv[optind++])) == ULONG_MAX) {
fprintf(stderr, "error: bad %s: %s\n", "block-grace", argv[optind - 1]);
return CMD_HELP;
}
if ((dqi->dqi_igrace = str2sec(argv[optind++])) == ULONG_MAX) {
fprintf(stderr, "error: bad %s: %s\n", "inode-grace", argv[optind - 1]);
return CMD_HELP;
}
}
mnt = argv[optind];
......@@ -1410,19 +1475,29 @@ static inline char *type2name(int check_type)
}
static void grace2str(time_t seconds,char *buf)
/* Converts seconds value into format string
* result is returned in buf
* Notes:
* 1. result is in descenting order: 1w2d3h4m5s
* 2. zero fields are not filled (except for p. 3): 5d1s
* 3. zero seconds value is presented as "0s"
*/
static void sec2str(time_t seconds, char *buf)
{
uint minutes, hours, days;
minutes = (seconds + 30) / 60;
hours = minutes / 60;
minutes %= 60;
days = hours / 24;
hours %= 24;
if (days >= 2)
snprintf(buf, 40, "%ddays", days);
else
snprintf(buf, 40, "%02d:%02d", hours + days * 24, minutes);
const char spec[] = "smhdw";
const unsigned long mult[] = {1, 60, 60*60, 24*60*60, 7*24*60*60};
unsigned long c;
char* tail = buf;
int i;
for (i = sizeof(mult) / sizeof(mult[0]) - 1 ; i >= 0; i--) {
c = seconds / mult[i];
if (c > 0 || (i == 0 && buf == tail))
tail += snprintf(tail, 40-(tail-buf), "%lu%c", c, spec[i]);
seconds %= mult[i];
}
}
......@@ -1436,7 +1511,7 @@ static void diff2str(time_t seconds, char *buf, time_t now)
strcpy(buf, "none");
return;
}
grace2str(seconds - now, buf);
sec2str(seconds - now, buf);
}
static void print_quota_title(char *name, struct if_quotactl *qctl)
......@@ -1523,8 +1598,8 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int ost_only)
char bgtimebuf[40];
char igtimebuf[40];
grace2str(qctl->qc_dqinfo.dqi_bgrace, bgtimebuf);
grace2str(qctl->qc_dqinfo.dqi_igrace, igtimebuf);
sec2str(qctl->qc_dqinfo.dqi_bgrace, bgtimebuf);
sec2str(qctl->qc_dqinfo.dqi_igrace, igtimebuf);
printf("Block grace time: %s; Inode grace time: %s\n",
bgtimebuf, igtimebuf);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment