More updates to edquota based on feedback from Dag-Erling Smorgrav.
This commit is contained in:
parent
b83b5d3b79
commit
cdab8b664d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/quota64/; revision=188432
@ -101,9 +101,11 @@ struct quotause {
|
|||||||
int alldigits(const char *s);
|
int alldigits(const char *s);
|
||||||
int cvtatos(u_int64_t, char *, u_int64_t *);
|
int cvtatos(u_int64_t, char *, u_int64_t *);
|
||||||
char *cvtstoa(u_int64_t);
|
char *cvtstoa(u_int64_t);
|
||||||
u_int64_t cvtval(u_int64_t, char);
|
u_int64_t cvtblkval(u_int64_t, char, const char *);
|
||||||
|
u_int64_t cvtinoval(u_int64_t, char, const char *);
|
||||||
int editit(char *);
|
int editit(char *);
|
||||||
char *fmthumanval(int64_t);
|
char *fmthumanvalblks(int64_t);
|
||||||
|
char *fmthumanvalinos(int64_t);
|
||||||
void freeprivs(struct quotause *);
|
void freeprivs(struct quotause *);
|
||||||
int getentry(const char *, int);
|
int getentry(const char *, int);
|
||||||
struct quotause *getprivs(long, int, char *);
|
struct quotause *getprivs(long, int, char *);
|
||||||
@ -165,6 +167,12 @@ main(int argc, char *argv[])
|
|||||||
(cp = strsep(&optarg, ":")) != NULL; i++) {
|
(cp = strsep(&optarg, ":")) != NULL; i++) {
|
||||||
if (cp != oldoptarg)
|
if (cp != oldoptarg)
|
||||||
*(cp - 1) = ':';
|
*(cp - 1) = ':';
|
||||||
|
if (i > 0 && !isdigit(*cp)) {
|
||||||
|
warnx("incorrect quota specification: "
|
||||||
|
"%s", oldoptarg);
|
||||||
|
usage();
|
||||||
|
/* Not Reached */
|
||||||
|
}
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
strlcpy(qup->fsname, cp,
|
strlcpy(qup->fsname, cp,
|
||||||
@ -173,34 +181,34 @@ main(int argc, char *argv[])
|
|||||||
case 1:
|
case 1:
|
||||||
lim = strtoll(cp, &endpt, 10);
|
lim = strtoll(cp, &endpt, 10);
|
||||||
qup->dqblk.dqb_bsoftlimit =
|
qup->dqblk.dqb_bsoftlimit =
|
||||||
cvtval(lim, *endpt);
|
cvtblkval(lim, *endpt,
|
||||||
|
"block soft limit");
|
||||||
continue;
|
continue;
|
||||||
case 2:
|
case 2:
|
||||||
lim = strtoll(cp, &endpt, 10);
|
lim = strtoll(cp, &endpt, 10);
|
||||||
qup->dqblk.dqb_bhardlimit =
|
qup->dqblk.dqb_bhardlimit =
|
||||||
cvtval(lim, *endpt);
|
cvtblkval(lim, *endpt,
|
||||||
|
"block hard limit");
|
||||||
continue;
|
continue;
|
||||||
case 3:
|
case 3:
|
||||||
lim = strtoll(cp, &endpt, 10);
|
lim = strtoll(cp, &endpt, 10);
|
||||||
qup->dqblk.dqb_isoftlimit =
|
qup->dqblk.dqb_isoftlimit =
|
||||||
cvtval(lim, *endpt);
|
cvtinoval(lim, *endpt,
|
||||||
|
"inode soft limit");
|
||||||
continue;
|
continue;
|
||||||
case 4:
|
case 4:
|
||||||
lim = strtoll(cp, &endpt, 10);
|
lim = strtoll(cp, &endpt, 10);
|
||||||
qup->dqblk.dqb_ihardlimit =
|
qup->dqblk.dqb_ihardlimit =
|
||||||
cvtval(lim, *endpt);
|
cvtinoval(lim, *endpt,
|
||||||
|
"inode hard limit");
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
warnx("incorrect quota specification: "
|
warnx("incorrect quota specification: "
|
||||||
"%s", oldoptarg);
|
"%s", oldoptarg);
|
||||||
usage();
|
usage();
|
||||||
break; /* XXX: report an error */
|
/* Not Reached */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qup->dqblk.dqb_bsoftlimit =
|
|
||||||
btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024);
|
|
||||||
qup->dqblk.dqb_bhardlimit =
|
|
||||||
btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024);
|
|
||||||
if (protoprivs == NULL) {
|
if (protoprivs == NULL) {
|
||||||
protoprivs = curprivs = qup;
|
protoprivs = curprivs = qup;
|
||||||
} else {
|
} else {
|
||||||
@ -212,6 +220,7 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
|
/* Not Reached */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
@ -518,28 +527,29 @@ writeprivs(struct quotause *quplist, int outfd, char *name, int quotatype)
|
|||||||
fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name);
|
fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name);
|
||||||
for (qup = quplist; qup; qup = qup->next) {
|
for (qup = quplist; qup; qup = qup->next) {
|
||||||
fprintf(fd, "%s: in use: %s, ", qup->fsname,
|
fprintf(fd, "%s: in use: %s, ", qup->fsname,
|
||||||
fmthumanval(qup->dqblk.dqb_curblocks));
|
fmthumanvalblks(qup->dqblk.dqb_curblocks));
|
||||||
fprintf(fd, "limits (soft = %s, ",
|
fprintf(fd, "limits (soft = %s, ",
|
||||||
fmthumanval(qup->dqblk.dqb_bsoftlimit));
|
fmthumanvalblks(qup->dqblk.dqb_bsoftlimit));
|
||||||
fprintf(fd, "hard = %s)\n",
|
fprintf(fd, "hard = %s)\n",
|
||||||
fmthumanval(qup->dqblk.dqb_bhardlimit));
|
fmthumanvalblks(qup->dqblk.dqb_bhardlimit));
|
||||||
fprintf(fd, "%s %llu, limits (soft = %llu, hard = %llu)\n",
|
fprintf(fd, "\tinodes in use: %s, ",
|
||||||
"\tinodes in use:",
|
fmthumanvalinos(qup->dqblk.dqb_curinodes));
|
||||||
qup->dqblk.dqb_curinodes,
|
fprintf(fd, "limits (soft = %s, ",
|
||||||
qup->dqblk.dqb_isoftlimit,
|
fmthumanvalinos(qup->dqblk.dqb_isoftlimit));
|
||||||
qup->dqblk.dqb_ihardlimit);
|
fprintf(fd, "hard = %s)\n",
|
||||||
|
fmthumanvalinos(qup->dqblk.dqb_ihardlimit));
|
||||||
}
|
}
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
fmthumanval(int64_t blocks)
|
fmthumanvalblks(int64_t blocks)
|
||||||
{
|
{
|
||||||
static char numbuf[20];
|
static char numbuf[20];
|
||||||
|
|
||||||
if (hflag) {
|
if (hflag) {
|
||||||
humanize_number(numbuf, sizeof(numbuf) - (blocks < 0 ? 0 : 1),
|
humanize_number(numbuf, blocks < 0 ? 7 : 6,
|
||||||
dbtob(blocks), "", HN_AUTOSCALE, HN_NOSPACE);
|
dbtob(blocks), "", HN_AUTOSCALE, HN_NOSPACE);
|
||||||
return (numbuf);
|
return (numbuf);
|
||||||
}
|
}
|
||||||
@ -547,6 +557,20 @@ fmthumanval(int64_t blocks)
|
|||||||
return(numbuf);
|
return(numbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
fmthumanvalinos(int64_t inos)
|
||||||
|
{
|
||||||
|
static char numbuf[20];
|
||||||
|
|
||||||
|
if (hflag) {
|
||||||
|
humanize_number(numbuf, inos < 0 ? 7 : 6,
|
||||||
|
inos, "", HN_AUTOSCALE, HN_NOSPACE | HN_DIVISOR_1000);
|
||||||
|
return (numbuf);
|
||||||
|
}
|
||||||
|
snprintf(numbuf, sizeof(numbuf), "%llu", inos);
|
||||||
|
return(numbuf);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Merge changes to an ASCII file into a quotause list.
|
* Merge changes to an ASCII file into a quotause list.
|
||||||
*/
|
*/
|
||||||
@ -607,42 +631,48 @@ readprivs(struct quotause *quplist, char *inname)
|
|||||||
warnx("%s:%s: bad format", fsp, cp);
|
warnx("%s:%s: bad format", fsp, cp);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
dqblk.dqb_curblocks = cvtval(curitems, curitemunits);
|
dqblk.dqb_curblocks = cvtblkval(curitems, curitemunits,
|
||||||
dqblk.dqb_bsoftlimit = cvtval(softlimit, softunits);
|
"current block count");
|
||||||
dqblk.dqb_bhardlimit = cvtval(hardlimit, hardunits);
|
dqblk.dqb_bsoftlimit = cvtblkval(softlimit, softunits,
|
||||||
|
"block soft limit");
|
||||||
|
dqblk.dqb_bhardlimit = cvtblkval(hardlimit, hardunits,
|
||||||
|
"block hard limit");
|
||||||
if ((cp = strtok(line2, "\n")) == NULL) {
|
if ((cp = strtok(line2, "\n")) == NULL) {
|
||||||
warnx("%s: %s: bad format", fsp, line2);
|
warnx("%s: %s: bad format", fsp, line2);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
cnt = sscanf(cp,
|
cnt = sscanf(&cp[7],
|
||||||
" in use: %llu%c, limits (soft = %llu%c, hard = %llu%c)",
|
" in use: %llu%c limits (soft = %llu%c, hard = %llu%c)",
|
||||||
&curitems, &curitemunits, &softlimit,
|
&curitems, &curitemunits, &softlimit,
|
||||||
&softunits, &hardlimit, &hardunits);
|
&softunits, &hardlimit, &hardunits);
|
||||||
/*
|
/*
|
||||||
* The next three check for old-style input formats.
|
* The next three check for old-style input formats.
|
||||||
*/
|
*/
|
||||||
if (cnt != 6)
|
if (cnt != 6)
|
||||||
cnt = sscanf(cp,
|
cnt = sscanf(&cp[7],
|
||||||
" in use: %llu%c, limits (soft = %llu%c hard = %llu%c",
|
" in use: %llu%c limits (soft = %llu%c hard = %llu%c",
|
||||||
&curitems, &curitemunits, &softlimit,
|
&curitems, &curitemunits, &softlimit,
|
||||||
&softunits, &hardlimit, &hardunits);
|
&softunits, &hardlimit, &hardunits);
|
||||||
if (cnt != 6)
|
if (cnt != 6)
|
||||||
cnt = sscanf(cp,
|
cnt = sscanf(&cp[7],
|
||||||
" in use: %llu%c, limits (soft = %llu%c hard = %llu%c)",
|
" in use: %llu%c limits (soft = %llu%c hard = %llu%c)",
|
||||||
&curitems, &curitemunits, &softlimit,
|
&curitems, &curitemunits, &softlimit,
|
||||||
&softunits, &hardlimit, &hardunits);
|
&softunits, &hardlimit, &hardunits);
|
||||||
if (cnt != 6)
|
if (cnt != 6)
|
||||||
cnt = sscanf(cp,
|
cnt = sscanf(&cp[7],
|
||||||
" in use: %llu%c, limits (soft = %llu%c, hard = %llu%c",
|
" in use: %llu%c limits (soft = %llu%c, hard = %llu%c",
|
||||||
&curitems, &curitemunits, &softlimit,
|
&curitems, &curitemunits, &softlimit,
|
||||||
&softunits, &hardlimit, &hardunits);
|
&softunits, &hardlimit, &hardunits);
|
||||||
if (cnt != 3) {
|
if (cnt != 6) {
|
||||||
warnx("%s: %s: bad format", fsp, line2);
|
warnx("%s: %s: bad format cnt %d", fsp, &cp[7], cnt);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
dqblk.dqb_curinodes = cvtval(curitems, curitemunits);
|
dqblk.dqb_curinodes = cvtinoval(curitems, curitemunits,
|
||||||
dqblk.dqb_isoftlimit = cvtval(softlimit, softunits);
|
"current inode count");
|
||||||
dqblk.dqb_ihardlimit = cvtval(hardlimit, hardunits);
|
dqblk.dqb_isoftlimit = cvtinoval(softlimit, softunits,
|
||||||
|
"inode soft limit");
|
||||||
|
dqblk.dqb_ihardlimit = cvtinoval(hardlimit, hardunits,
|
||||||
|
"inode hard limit");
|
||||||
for (qup = quplist; qup; qup = qup->next) {
|
for (qup = quplist; qup; qup = qup->next) {
|
||||||
if (strcmp(fsp, qup->fsname))
|
if (strcmp(fsp, qup->fsname))
|
||||||
continue;
|
continue;
|
||||||
@ -669,8 +699,10 @@ readprivs(struct quotause *quplist, char *inname)
|
|||||||
qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit;
|
qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit;
|
||||||
qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit;
|
qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit;
|
||||||
qup->flags |= FOUND;
|
qup->flags |= FOUND;
|
||||||
if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks &&
|
/* Humanized input returns only approximate counts */
|
||||||
dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes)
|
if (hflag ||
|
||||||
|
(dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks &&
|
||||||
|
dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes))
|
||||||
break;
|
break;
|
||||||
warnx("%s: cannot change current allocation", fsp);
|
warnx("%s: cannot change current allocation", fsp);
|
||||||
break;
|
break;
|
||||||
@ -836,7 +868,7 @@ cvtatos(u_int64_t period, char *units, u_int64_t *seconds)
|
|||||||
* Convert a limit to number of disk blocks.
|
* Convert a limit to number of disk blocks.
|
||||||
*/
|
*/
|
||||||
u_int64_t
|
u_int64_t
|
||||||
cvtval(u_int64_t limit, char units)
|
cvtblkval(u_int64_t limit, char units, const char *itemname)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(units) {
|
switch(units) {
|
||||||
@ -872,11 +904,62 @@ cvtval(u_int64_t limit, char units)
|
|||||||
limit *= btodb(1152921504606846976);
|
limit *= btodb(1152921504606846976);
|
||||||
break;
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
errx(2, "No space permitted between value and units\n");
|
errx(2, "No space permitted between value and units for %s\n",
|
||||||
|
itemname);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errx(2, "%llu%c: unknown units, specify K, M, G, T, P, or E\n",
|
errx(2, "%llu%c: unknown units for %s, specify none, K, M, G, T, P, or E\n",
|
||||||
limit, units);
|
limit, units, itemname);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a limit to number of inodes.
|
||||||
|
*/
|
||||||
|
u_int64_t
|
||||||
|
cvtinoval(u_int64_t limit, char units, const char *itemname)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch(units) {
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
case '\0': /* historic behavior */
|
||||||
|
case ',': /* historic behavior */
|
||||||
|
case ')': /* historic behavior */
|
||||||
|
break;
|
||||||
|
case 'K':
|
||||||
|
case 'k':
|
||||||
|
limit *= 1000;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
case 'm':
|
||||||
|
limit *= 1000000;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
case 'g':
|
||||||
|
limit *= 1000000000;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
case 't':
|
||||||
|
limit *= 1000000000000;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
case 'p':
|
||||||
|
limit *= 1000000000000000;
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
case 'e':
|
||||||
|
limit *= 1000000000000000000;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
errx(2, "No space permitted between value and units for %s\n",
|
||||||
|
itemname);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errx(2, "%llu%c: unknown units for %s, specify none, K, M, G, T, P, or E\n",
|
||||||
|
limit, units, itemname);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (limit);
|
return (limit);
|
||||||
|
Loading…
Reference in New Issue
Block a user