Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/bouyer-quota2]: src/usr.sbin/edquota Add -c option, which clears quota e...
details: https://anonhg.NetBSD.org/src/rev/ee6ed446fa91
branches: bouyer-quota2
changeset: 761114:ee6ed446fa91
user: bouyer <bouyer%NetBSD.org@localhost>
date: Mon Feb 07 20:31:20 2011 +0000
description:
Add -c option, which clears quota entries for the specified users/groups
diffstat:
usr.sbin/edquota/edquota.8 | 22 ++++++++-
usr.sbin/edquota/edquota.c | 118 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 135 insertions(+), 5 deletions(-)
diffs (238 lines):
diff -r 6e1f9af3d67b -r ee6ed446fa91 usr.sbin/edquota/edquota.8
--- a/usr.sbin/edquota/edquota.8 Mon Feb 07 20:30:39 2011 +0000
+++ b/usr.sbin/edquota/edquota.8 Mon Feb 07 20:31:20 2011 +0000
@@ -29,7 +29,7 @@
.\" SUCH DAMAGE.
.\"
.\" from: @(#)edquota.8 8.2 (Berkeley) 4/27/95
-.\" $NetBSD: edquota.8,v 1.12.50.1 2011/02/06 22:18:38 bouyer Exp $
+.\" $NetBSD: edquota.8,v 1.12.50.2 2011/02/07 20:31:20 bouyer Exp $
.\"
.Dd February 6, 2011
.Dt EDQUOTA 8
@@ -74,6 +74,20 @@
.Op Fl t Ar block grace time/inode grace time
.Ar -d |
.Ar groupname ...
+.Nm
+.Op Fl D
+.Op Fl H
+.Op Fl u
+.Fl c
+.Op Fl f Ar filesystem
+.Ar username ...
+.Nm
+.Op Fl D
+.Op Fl H
+.Fl g
+.Fl c
+.Op Fl f Ar filesystem
+.Ar groupname ...
.Sh DESCRIPTION
.Nm
is a quota editor.
@@ -165,6 +179,12 @@
per-user/group grace time. To edit the filesystem-wide grace time, use
.Fl d .
.Pp
+On quota2-enabled filesystems, the
+.Fl c
+flag cause edquota to clear quota entries for the specified users or groups.
+If disk or inode usages is not 0, limits are reverted to the default quota.
+If disk and inode usages are 0, the existing quota entries are freed.
+.Pp
The
.Fl D
flag cause edquota to print to the standard error property lists sent to
diff -r 6e1f9af3d67b -r ee6ed446fa91 usr.sbin/edquota/edquota.c
--- a/usr.sbin/edquota/edquota.c Mon Feb 07 20:30:39 2011 +0000
+++ b/usr.sbin/edquota/edquota.c Mon Feb 07 20:31:20 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: edquota.c,v 1.29.16.9 2011/02/06 22:18:38 bouyer Exp $ */
+/* $NetBSD: edquota.c,v 1.29.16.10 2011/02/07 20:31:20 bouyer Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -41,7 +41,7 @@
#if 0
static char sccsid[] = "from: @(#)edquota.c 8.3 (Berkeley) 4/27/95";
#else
-__RCSID("$NetBSD: edquota.c,v 1.29.16.9 2011/02/06 22:18:38 bouyer Exp $");
+__RCSID("$NetBSD: edquota.c,v 1.29.16.10 2011/02/07 20:31:20 bouyer Exp $");
#endif
#endif /* not lint */
@@ -113,6 +113,7 @@
void freeprivs(struct quotause *);
int alldigits(const char *);
int hasquota(struct fstab *, int, char **);
+static void clearpriv(int, char **, const char *, int);
int Hflag = 0;
int Dflag = 0;
@@ -131,6 +132,7 @@
char *fs = NULL;
int ch;
int pflag = 0;
+ int cflag = 0;
if (argc < 2)
usage();
@@ -138,7 +140,7 @@
errx(1, "permission denied");
protoname = NULL;
quotatype = USRQUOTA;
- while ((ch = getopt(argc, argv, "DHdugp:s:h:t:f:")) != -1) {
+ while ((ch = getopt(argc, argv, "DHcdugp:s:h:t:f:")) != -1) {
switch(ch) {
case 'D':
Dflag++;
@@ -146,6 +148,9 @@
case 'H':
Hflag++;
break;
+ case 'c':
+ cflag++;
+ break;
case 'd':
dflag++;
break;
@@ -179,7 +184,7 @@
argv += optind;
if (pflag) {
- if (soft || hard || grace || dflag)
+ if (soft || hard || grace || dflag || cflag)
usage();
if ((protoid = getentry(protoname, quotatype)) == -1)
exit(1);
@@ -200,6 +205,9 @@
u_int64_t softb, hardb, softi, hardi;
time_t graceb, gracei;
char *str;
+
+ if (cflag)
+ usage();
if (soft) {
str = strsep(&soft, "/");
if (str[0] == '\0' || soft == NULL || soft[0] == '\0')
@@ -283,6 +291,12 @@
}
exit(0);
}
+ if (cflag) {
+ if (dflag)
+ usage();
+ clearpriv(argc, argv, fs, quotatype);
+ exit(0);
+ }
tmpfd = mkstemp(tmpfil);
fchown(tmpfd, getuid(), getgid());
if (dflag) {
@@ -316,6 +330,8 @@
" edquota [-D] [-H] -g [-p groupname] [-f filesystem] -d | groupname ...\n"
" edquota [-D] [-u] [-f filesystem] [-s b#/i#] [-h b#/i#] [-t t#/t#] \\\n\t-d | username ...\n"
" edquota [-D] -g [-f filesystem] [-s b#/i#] [-h b#/i#] [-t t#/t#] \\\n\t-d | groupname ...\n"
+ " edquota [-D] [-H] [-u] -c [-f filesystem] username ...\n"
+ " edquota [-D] [-H] -g -c [-f filesystem] groupname ...\n"
);
exit(1);
}
@@ -1060,3 +1076,97 @@
qfextension[type]);
return (1);
}
+
+static void
+clearpriv(int argc, char **argv, const char *filesys, int quotatype)
+{
+ prop_array_t cmds, datas;
+ prop_dictionary_t protodict, dict, data, cmd;
+ struct plistref pref;
+ bool ret;
+ struct statvfs *fst;
+ int nfst, i, error;
+ int8_t error8;
+ int id;
+
+ /* build a generic command */
+ protodict = quota2_prop_create();
+ cmds = prop_array_create();
+ datas = prop_array_create();
+ if (protodict == NULL || cmds == NULL || datas == NULL) {
+ errx(1, "can't allocate proplist");
+ }
+
+ for ( ; argc > 0; argc--, argv++) {
+ if ((id = getentry(*argv, quotatype)) == -1)
+ continue;
+ data = prop_dictionary_create();
+ if (data == NULL)
+ errx(1, "can't allocate proplist");
+
+ ret = prop_dictionary_set_uint32(data, "id", id);
+ if (!ret)
+ err(1, "prop_dictionary_set(id)");
+ if (!prop_array_add_and_rel(datas, data))
+ err(1, "prop_array_add(data)");
+ }
+ if (!quota2_prop_add_command(cmds, "clear", qfextension[quotatype],
+ datas))
+ err(1, "prop_add_command");
+
+ if (!prop_dictionary_set(protodict, "commands", cmds))
+ err(1, "prop_dictionary_set(command)");
+
+ /* now loop over quota-enabled filesystems */
+ nfst = getmntinfo(&fst, MNT_WAIT);
+ if (nfst == 0)
+ errx(2, "no filesystems mounted!");
+
+ for (i = 0; i < nfst; i++) {
+ if (strcmp(fst[i].f_fstypename, "ffs") != 0 ||
+ (fst[i].f_flag & ST_QUOTA) == 0)
+ continue;
+ if (filesys && strcmp(fst[i].f_mntonname, filesys) != 0 &&
+ strcmp(fst[i].f_mntfromname, filesys) != 0)
+ continue;
+ if (Dflag) {
+ fprintf(stderr, "message to kernel for %s:\n%s\n",
+ fst[i].f_mntonname,
+ prop_dictionary_externalize(protodict));
+ }
+
+ if (!prop_dictionary_send_syscall(protodict, &pref))
+ err(1, "prop_dictionary_send_syscall");
+ if (quotactl(fst[i].f_mntonname, &pref) != 0)
+ err(1, "quotactl");
+
+ if ((error = prop_dictionary_recv_syscall(&pref, &dict)) != 0) {
+ errx(1, "prop_dictionary_recv_syscall: %s\n",
+ strerror(error));
+ }
+
+ if (Dflag) {
+ fprintf(stderr, "reply from kernel for %s:\n%s\n",
+ fst[i].f_mntonname,
+ prop_dictionary_externalize(dict));
+ }
+ if ((error = quota2_get_cmds(dict, &cmds)) != 0) {
+ errx(1, "quota2_get_cmds: %s\n",
+ strerror(error));
+ }
+ /* only one command, no need to iter */
+ cmd = prop_array_get(cmds, 0);
+ if (cmd == NULL)
+ err(1, "prop_array_get(cmd)");
+
+ if (!prop_dictionary_get_int8(cmd, "return", &error8))
+ err(1, "prop_get(return)");
+ if (error8) {
+ fprintf(stderr, "clear %s quota entries on %s: %s\n",
+ qfextension[quotatype], fst[i].f_mntonname,
+ strerror(error8));
+ }
+ prop_object_release(dict);
+ }
+ prop_object_release(protodict);
+}
Home |
Main Index |
Thread Index |
Old Index