Subject: edquota enhancements
To: None <tech-userlevel@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-userlevel
Date: 12/02/2002 21:53:01
--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi,
I'd like to commit the attached patch to edquota. It adds:
- a -f flag, to restrict operations on only one filesystem, instead of
all quota-enabled filesystems.
- -s and -h flags, to set limits from the command line without edition
of a temporary file. Would make it easier to call edquota from scripts.
Comments ?
--
Manuel Bouyer <bouyer@antioche.eu.org>
NetBSD: 23 ans d'experience feront toujours la difference
--
--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff
? .gdbinit
? edquota
? edquota.cat8
Index: edquota.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/edquota/edquota.8,v
retrieving revision 1.8
diff -u -r1.8 edquota.8
--- edquota.8 2002/01/19 03:11:34 1.8
+++ edquota.8 2002/12/02 20:48:38
@@ -45,15 +45,31 @@
.Nm
.Op Fl u
.Op Fl p Ar proto-username
+.Op Fl f Ar filesystem
.Ar username ...
.Nm ""
.Fl g
.Op Fl p Ar proto-groupname
+.Op Fl f Ar filesystem
.Ar groupname ...
.Nm ""
+.Op Fl u
+.Op Fl s Ar block#/inode#
+.Op Fl h Ar block#/inode#
+.Op Fl f Ar filesystem
+.Ar username ...
+.Nm ""
+.Fl g
+.Op Fl s Ar block#/inode#
+.Op Fl h Ar block#/inode#
+.Op Fl f Ar filesystem
+.Ar groupname ...
+.Nm ""
+.Op Fl f Ar filesystem
.Fl t
.Op Fl u
.Nm ""
+.Op Fl f Ar filesystem
.Fl t
.Fl g
.Sh DESCRIPTION
@@ -63,11 +79,17 @@
.Fl u
flag is specified,
one or more users may be specified on the command line.
-For each user a temporary file is created
-with an ASCII representation of the current
-disk quotas for that user.
+Unless
+.Fl s
+or
+.Fl h
+is used, a temporary file is created for each user with an ASCII
+representation of the current disk quotas for that user.
The list of filesystems with user quotas is determined from
.Pa /etc/fstab .
+By default, quota for all quota-enabled filesystems are edited; the
+.Fl f
+option can be used to restrict it to a single filesystem.
An editor is invoked on the ASCII file.
The editor invoked is
.Xr vi 1
@@ -100,6 +122,14 @@
specified for each user specified.
This is the normal mechanism used to
initialize quotas for groups of users.
+.Pp
+The
+.Fl s
+and
+.Fl h
+flags can be used to change quota limits (soft and hard, respectively)
+without user interaction, for usage in e.g. batch scripts. The argument is
+the new block and inode number limit, separated by a slash.
.Pp
If the
.Fl g
Index: edquota.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/edquota/edquota.c,v
retrieving revision 1.21
diff -u -r1.21 edquota.c
--- edquota.c 2000/04/14 06:26:53 1.21
+++ edquota.c 2002/12/02 20:48:41
@@ -88,7 +88,7 @@
void usage __P((void));
int getentry __P((char *, int));
struct quotause *
- getprivs __P((long, int));
+ getprivs __P((long, int, char *));
void putprivs __P((long, int, struct quotause *));
int editit __P((char *));
int writeprivs __P((struct quotause *, int, char *, int));
@@ -110,6 +110,8 @@
long id, protoid;
int quotatype, tmpfd;
char *protoname;
+ char *soft = NULL, *hard = NULL;
+ char *fs = NULL;
int ch;
int tflag = 0, pflag = 0;
@@ -119,7 +121,7 @@
errx(1, "permission denied");
protoname = NULL;
quotatype = USRQUOTA;
- while ((ch = getopt(argc, argv, "ugtp:")) != -1) {
+ while ((ch = getopt(argc, argv, "ugtp:s:h:f:")) != -1) {
switch(ch) {
case 'p':
protoname = optarg;
@@ -134,6 +136,15 @@
case 't':
tflag++;
break;
+ case 's':
+ soft = optarg;
+ break;
+ case 'h':
+ hard = optarg;
+ break;
+ case 'f':
+ fs = optarg;
+ break;
default:
usage();
}
@@ -141,9 +152,11 @@
argc -= optind;
argv += optind;
if (pflag) {
+ if (soft || hard)
+ usage();
if ((protoid = getentry(protoname, quotatype)) == -1)
exit(1);
- protoprivs = getprivs(protoid, quotatype);
+ protoprivs = getprivs(protoid, quotatype, fs);
for (qup = protoprivs; qup; qup = qup->next) {
qup->dqblk.dqb_btime = 0;
qup->dqblk.dqb_itime = 0;
@@ -155,10 +168,58 @@
}
exit(0);
}
+ if (soft || hard) {
+ struct quotause *qup;
+ u_int32_t softb, hardb, softi, hardi;
+ if (tflag)
+ usage();
+ if (soft) {
+ if (sscanf(soft, "%d/%d", &softb, &softi) != 2)
+ usage();
+ softb = btodb((u_quad_t)softb * 1024);
+ }
+ if (hard) {
+ if (sscanf(hard, "%d/%d", &hardb, &hardi) != 2)
+ usage();
+ hardb = btodb((u_quad_t)hardb * 1024);
+ }
+ for ( ; argc > 0; argc--, argv++) {
+ if ((id = getentry(*argv, quotatype)) == -1)
+ continue;
+ curprivs = getprivs(id, quotatype, fs);
+ for (qup = curprivs; qup; qup = qup->next) {
+ if (soft) {
+ if (softb &&
+ qup->dqblk.dqb_curblocks >= softb &&
+ (qup->dqblk.dqb_bsoftlimit == 0 ||
+ qup->dqblk.dqb_curblocks <
+ qup->dqblk.dqb_bsoftlimit))
+ qup->dqblk.dqb_btime = 0;
+ if (softi &&
+ qup->dqblk.dqb_curinodes >= softi &&
+ (qup->dqblk.dqb_isoftlimit == 0 ||
+ qup->dqblk.dqb_curinodes <
+ qup->dqblk.dqb_isoftlimit))
+ qup->dqblk.dqb_itime = 0;
+ qup->dqblk.dqb_bsoftlimit = softb;
+ qup->dqblk.dqb_isoftlimit = softi;
+ }
+ if (hard) {
+ qup->dqblk.dqb_bhardlimit = hardb;
+ qup->dqblk.dqb_ihardlimit = hardi;
+ }
+ }
+ putprivs(id, quotatype, curprivs);
+ freeprivs(curprivs);
+ }
+ exit(0);
+ }
tmpfd = mkstemp(tmpfil);
fchown(tmpfd, getuid(), getgid());
if (tflag) {
- protoprivs = getprivs(0, quotatype);
+ if (soft || hard)
+ usage();
+ protoprivs = getprivs(0, quotatype, fs);
if (writetimes(protoprivs, tmpfd, quotatype) == 0)
exit(1);
if (editit(tmpfil) && readtimes(protoprivs, tmpfd))
@@ -169,7 +230,7 @@
for ( ; argc > 0; argc--, argv++) {
if ((id = getentry(*argv, quotatype)) == -1)
continue;
- curprivs = getprivs(id, quotatype);
+ curprivs = getprivs(id, quotatype, fs);
if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0)
continue;
if (editit(tmpfil) && readprivs(curprivs, tmpfd))
@@ -184,10 +245,14 @@
void
usage()
{
- fprintf(stderr, "%s%s%s%s",
- "Usage: edquota [-u] [-p username] username ...\n",
- "\tedquota -g [-p groupname] groupname ...\n",
- "\tedquota [-u] -t\n", "\tedquota -g -t\n");
+ fprintf(stderr,
+ "Usage: edquota [-u] [-p username] [-f filesystem] username ...\n"
+ "\tedquota -g [-p groupname] [-f filesystem] groupname ...\n"
+ "\tedquota [-u] [-f filesystem] [-s b#/i#] [-h b#/i#] username ...\n"
+ "\tedquota -g [-f filesystem] [-s b#/i#] [-h b#/i#] groupname ...\n"
+ "\tedquota [-u] [-f filesystem] -t\n"
+ "\tedquota -g [-f filesystem] -t\n"
+ );
exit(1);
}
@@ -229,9 +294,10 @@
* Collect the requested quota information.
*/
struct quotause *
-getprivs(id, quotatype)
+getprivs(id, quotatype, filesys)
long id;
int quotatype;
+ char *filesys;
{
struct fstab *fs;
struct quotause *qup, *quptail;
@@ -246,6 +312,9 @@
qcmd = QCMD(Q_GETQUOTA, quotatype);
while ((fs = getfsent()) != NULL) {
if (strcmp(fs->fs_vfstype, "ffs"))
+ continue;
+ if (filesys && strcmp(fs->fs_spec, filesys) != 0 &&
+ strcmp(fs->fs_file, filesys) != 0)
continue;
if (!hasquota(fs, quotatype, &qfpathname))
continue;
--X1bOJ3K7DJ5YkBrT--