summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjkar8572 <jkar8572>2001-09-04 16:21:58 +0000
committerjkar8572 <jkar8572>2001-09-04 16:21:58 +0000
commitc0144017620cbee64a818ede2ea7d23d04aaff56 (patch)
treeaf0a2b7a4da253dca12865dd74f114a3b21ba885
parent5cf36f5e002247effba3cf51a77e1d3f23c35a7b (diff)
quotacheck(8) now creates backup quotafiles only when -b specified (Preston Brown)
Fixed bug in parsing of passed mountpoints (reported by Preston Brown) More verbose output of quotaon (Preston Brown) quotacheck(8) now automatically chooses vfsv0 quota format when no quota files are found and special filenames are not specified.
-rw-r--r--quotacheck.817
-rw-r--r--quotacheck.c84
-rw-r--r--quotacheck.h1
-rw-r--r--quotacheck_v2.c6
-rw-r--r--quotaon.c16
-rw-r--r--quotasys.c25
6 files changed, 86 insertions, 63 deletions
diff --git a/quotacheck.8 b/quotacheck.8
index 7c5f5b2..1fe707b 100644
--- a/quotacheck.8
+++ b/quotacheck.8
@@ -4,7 +4,7 @@ quotacheck \- scan a filesystem for disk usage, create, check and repair quota f
.SH SYNOPSIS
.B quotacheck
[
-.B \-gucfinvdMmR
+.B \-gubcfinvdMmR
] [
.B \-F
.I quota-format
@@ -19,10 +19,10 @@ examines each filesystem, builds a table of current disk usage, and
compares this table against that recorded in the disk quota file for the
filesystem (this step is ommitted if option
.B -c
-is specified). If any inconsistencies are detected, both the quota file
+is specified). If any inconsistencies are detected, both the quota file
and the current system copy of the incorrect quotas are updated (the
-latter only occurs if an active filesystem is checked). By default,
-only user quotas are checked.
+latter only occurs if an active filesystem is checked which is not advised).
+By default, only user quotas are checked.
.B quotacheck
expects each filesystem to be checked to have quota files named
.I [a]quota.user
@@ -70,6 +70,11 @@ ignore the failure to remount the filesystem read-only with option
.BR \-M .
.SH OPTIONS
.TP
+.B \-b
+Forces
+.B quotacheck
+to make backups of the quota file before writing the new data.
+.TP
.B \-v
.B quotacheck
reports its operation as it progresses. Normally it operates silently.
@@ -91,6 +96,8 @@ or on the filesystems specified are to be checked.
.TP
.B \-c
Don't read existing quota files. Just perform a new scan and save it to disk.
+.B quotacheck
+also skips scanning of old quota files when they are not found.
.TP
.B \-f
Forces checking of filesystems with quotas enabled. This is not
@@ -120,7 +127,7 @@ exits or asks user for input. When this option is set, the first entry found
is always used (this option works in interactive mode too).
.TP
.B \-F \f2format-name\f1
-Check quota quota for specified format (ie. don't perform format
+Check quota for specified format (ie. don't perform format
auto-detection). This is recommended as detection might not work well on
corrupted quota files. Possible format names are:
.B vfsold
diff --git a/quotacheck.c b/quotacheck.c
index f12fadd..5bfb41a 100644
--- a/quotacheck.c
+++ b/quotacheck.c
@@ -8,7 +8,7 @@
* New quota format implementation - Jan Kara <jack@suse.cz> - Sponsored by SuSE CR
*/
-#ident "$Id: quotacheck.c,v 1.17 2001/08/30 10:11:24 jkar8572 Exp $"
+#ident "$Id: quotacheck.c,v 1.18 2001/09/04 16:21:58 jkar8572 Exp $"
#include <dirent.h>
#include <stdio.h>
@@ -286,8 +286,11 @@ static void parse_options(int argcnt, char **argstr)
{
int ret;
- while ((ret = getopt(argcnt, argstr, "VhcvugidnfF:mMRa")) != -1) {
- switch (ret) {
+ while ((ret = getopt(argcnt, argstr, "VhbcvugidnfF:mMRa")) != -1) {
+ switch (ret) {
+ case 'b':
+ flags |= FL_BACKUPS;
+ break;
case 'g':
gwant = 1;
break;
@@ -539,7 +542,7 @@ static int process_file(struct mntent *mnt, int type)
char *qfname = NULL;
int fd = -1, ret;
- debug(FL_DEBUG | FL_VERBOSE, _("Going to check %s quota file of %s\n"), type2name(type),
+ debug(FL_DEBUG, _("Going to check %s quota file of %s\n"), type2name(type),
mnt->mnt_dir);
if (kern_quota_on(mnt->mnt_fsname, type, (1 << cfmt)) > 0) { /* Is quota enabled? */
@@ -605,32 +608,34 @@ static int rename_files(struct mntent *mnt, int type)
if (!(filename = get_qf_name(mnt, type, cfmt)))
die(2, _("Cannot get name of old quotafile on %s.\n"), mnt->mnt_dir);
- debug(FL_DEBUG | FL_VERBOSE, _("Data dumped.\nRenaming old quotafile to %s~\n"), filename);
- if (stat(filename, &st) < 0) { /* File doesn't exist? */
- if (errno == ENOENT) {
- debug(FL_DEBUG | FL_VERBOSE, _("Old file not found.\n"));
- goto rename_new;
+ if (flags & FL_BACKUPS) {
+ debug(FL_DEBUG, _("Data dumped.\nRenaming old quotafile to %s~\n"), filename);
+ if (stat(filename, &st) < 0) { /* File doesn't exist? */
+ if (errno == ENOENT) {
+ debug(FL_DEBUG | FL_VERBOSE, _("Old file not found.\n"));
+ goto rename_new;
+ }
+ errstr(_("Error while searching for old quota file %s: %s\n"),
+ filename, strerror(errno));
+ free(filename);
+ return -1;
+ }
+ mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ /* Backup old file */
+ strcpy(newfilename, filename);
+ /* Make backingup safe */
+ sstrncat(newfilename, "~", PATH_MAX);
+ if (newfilename[strlen(newfilename) - 1] != '~')
+ die(8, _("Name of quota file too long. Contact %s.\n"), MY_EMAIL);
+ if (rename(filename, newfilename) < 0) {
+ errstr(_("Cannot rename old quotafile %s to %s: %s\n"),
+ filename, newfilename, strerror(errno));
+ free(filename);
+ return -1;
}
- errstr(_("Error while searching for old quota file %s: %s\n"),
- filename, strerror(errno));
- free(filename);
- return -1;
- }
- mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
- /* Backup old file */
- strcpy(newfilename, filename);
- /* Make backingup safe */
- sstrncat(newfilename, "~", PATH_MAX);
- if (newfilename[strlen(newfilename) - 1] != '~')
- die(8, _("Name of quota file too long. Contact %s.\n"), MY_EMAIL);
- if (rename(filename, newfilename) < 0) {
- errstr(_("Cannot rename old quotafile %s to %s: %s\n"),
- filename, newfilename, strerror(errno));
- free(filename);
- return -1;
}
- debug(FL_DEBUG | FL_VERBOSE, _("Renaming new quotafile\n"));
- rename_new:
+ debug(FL_DEBUG, _("Renaming new quotafile\n"));
+rename_new:
/* Rename new file to right name */
strcpy(newfilename, filename);
sstrncat(newfilename, ".new", PATH_MAX);
@@ -660,7 +665,7 @@ static int dump_to_file(struct mntent *mnt, int type)
uint i;
struct quota_handle *h;
- debug(FL_DEBUG | FL_VERBOSE, _("Dumping gathered data for %ss.\n"), type2name(type));
+ debug(FL_DEBUG, _("Dumping gathered data for %ss.\n"), type2name(type));
if (!(h = new_io(mnt, type, cfmt))) {
errstr(_("Cannot initialize IO on new quotafile: %s\n"),
strerror(errno));
@@ -684,7 +689,7 @@ static int dump_to_file(struct mntent *mnt, int type)
return -1;
}
if (rename_files(mnt, type) < 0)
- return -1;
+ return -1;
if (cfmt == kern_quota_on(mnt->mnt_fsname, type, 1 << cfmt)) { /* Quota turned on? */
char *filename;
@@ -734,25 +739,21 @@ static void check_dir(struct mntent *mnt)
(NULL, mnt->mnt_dir, mnt->mnt_type, MS_MGC_VAL | MS_REMOUNT | MS_RDONLY,
NULL) < 0 && !(flags & FL_FORCEREMOUNT)) {
if (flags & FL_INTERACTIVE) {
- printf(_
- ("Cannot remount filesystem mounted on %s read-only. Counted values might not be right.\n"),
-mnt->mnt_dir);
+ printf(_("Cannot remount filesystem mounted on %s read-only. Counted values might not be right.\n"), mnt->mnt_dir);
if (!ask_yn(_("Should I continue"), 0)) {
printf(_("As you wish... Canceling check of this file.\n"));
goto out;
}
}
else {
- errstr(
- _("Cannot remount filesystem mounted on %s read-only so counted values might not be right.\n\
-Please stop all programs writing to filesystem or use -m flag to force checking.\n"),
- mnt->mnt_dir);
+ errstr(_("Cannot remount filesystem mounted on %s read-only so counted values might not be right.\n\
+Please stop all programs writing to filesystem or use -m flag to force checking.\n"), mnt->mnt_dir);
goto out;
}
}
else
remounted = 1;
- debug(FL_DEBUG | FL_VERBOSE, _("Filesystem remounted read-only\n"));
+ debug(FL_DEBUG, _("Filesystem remounted read-only\n"));
}
debug(FL_VERBOSE, _("Scanning %s [%s] "), mnt->mnt_fsname, mnt->mnt_dir);
#if defined(EXT2_DIRECT)
@@ -775,7 +776,7 @@ Please stop all programs writing to filesystem or use -m flag to force checking.
if (remounted) {
if (mount(NULL, mnt->mnt_dir, mnt->mnt_type, MS_MGC_VAL | MS_REMOUNT, NULL) < 0)
die(4, _("Cannot remount filesystem %s read-write. cannot write new quota files.\n"), mnt->mnt_dir);
- debug(FL_DEBUG | FL_VERBOSE, _("Filesystem remounted RW.\n"));
+ debug(FL_DEBUG, _("Filesystem remounted RW.\n"));
}
if (ucheck)
dump_to_file(mnt, USRQUOTA);
@@ -814,7 +815,8 @@ static int detect_filename_format(struct mntent *mnt, int type)
snprintf(namebuf, PATH_MAX, "%s/%s.%s", mnt->mnt_dir, basenames[QF_VFSOLD], extensions[type]);
if (!stat(namebuf, &statbuf))
return QF_VFSOLD;
- /* Old quota files don't exist, just return newest format... */
+ /* Old quota files don't exist, just create newest quotafile available */
+ flags |= FL_NEWFILE;
return QF_VFSV0;
}
@@ -849,7 +851,7 @@ static void check_all(void)
mnt->mnt_fsname);
continue;
}
- debug(FL_DEBUG | FL_VERBOSE, _("Detected quota format %s\n"), fmt2name(cfmt));
+ debug(FL_DEBUG, _("Detected quota format %s\n"), fmt2name(cfmt));
}
checked++;
check_dir(mnt);
diff --git a/quotacheck.h b/quotacheck.h
index fd09aad..09a5c09 100644
--- a/quotacheck.h
+++ b/quotacheck.h
@@ -24,6 +24,7 @@
#define FL_NOREMOUNT 128 /* Don't try to remount filesystem RO */
#define FL_ALL 256 /* Scan all mountpoints with quota? */
#define FL_NOROOT 512 /* Scan all mountpoints except root */
+#define FL_BACKUPS 1024 /* Create backup of old quota file? */
extern int flags; /* Options from command line */
extern struct util_dqinfo old_info[MAXQUOTAS]; /* Loaded info from file */
diff --git a/quotacheck_v2.c b/quotacheck_v2.c
index 8c88d79..6ede24e 100644
--- a/quotacheck_v2.c
+++ b/quotacheck_v2.c
@@ -48,7 +48,7 @@ static int check_info(char *filename, int fd, int type)
off_t filesize;
int err;
- debug(FL_VERBOSE, _("Checking quotafile info...\n"));
+ debug(FL_DEBUG, _("Checking quotafile info...\n"));
lseek(fd, V2_DQINFOOFF, SEEK_SET);
err = read(fd, &dinfo, sizeof(struct v2_disk_dqinfo));
@@ -322,7 +322,7 @@ int v2_buffer_file(char *filename, int fd, int type)
return 0;
if (check_info(filename, fd, type) < 0)
return 0;
- debug(FL_DEBUG | FL_VERBOSE, _("Headers of file %s checked. Going to load data...\n"),
+ debug(FL_DEBUG, _("Headers of file %s checked. Going to load data...\n"),
filename);
blocks = old_info[type].u.v2_mdqi.dqi_blocks;
blkbmp = xmalloc((blocks + 7) >> 3);
@@ -341,7 +341,7 @@ int v2_buffer_file(char *filename, int fd, int type)
errstr(_("WARNING - Some data might be changed due to corruption.\n"));
}
else
- debug(FL_DEBUG | FL_VERBOSE, _("Not found any corrupted blocks. Congratulations.\n"));
+ debug(FL_DEBUG, _("Not found any corrupted blocks. Congratulations.\n"));
return ret;
}
diff --git a/quotaon.c b/quotaon.c
index 523242d..f1575b3 100644
--- a/quotaon.c
+++ b/quotaon.c
@@ -34,7 +34,7 @@
#ident "$Copyright: (c) 1980, 1990 Regents of the University of California $"
#ident "$Copyright: All rights reserved. $"
-#ident "$Id: quotaon.c,v 1.7 2001/08/30 10:11:24 jkar8572 Exp $"
+#ident "$Id: quotaon.c,v 1.8 2001/09/04 16:21:58 jkar8572 Exp $"
/*
* Turn quota on/off for a filesystem.
@@ -175,27 +175,27 @@ int main(int argc, char **argv)
/*
* Enable/disable VFS quota on given filesystem
*/
-static int quotaonoff(char *quotadev, char *quotafile, int type, int flags)
+static int quotaonoff(char *quotadev, char *quotadir, char *quotafile, int type, int flags)
{
int qcmd;
if (flags & STATEFLAG_OFF) {
qcmd = QCMD(Q_QUOTAOFF, type);
if (quotactl(qcmd, quotadev, 0, NULL) < 0) {
- errstr(_("quotactl on %s: %s\n"), quotadev, strerror(errno));
+ errstr(_("quotactl on %s [%s]: %s\n"), quotadev, quotadir, strerror(errno));
return 1;
}
if (flags & STATEFLAG_VERBOSE)
- printf(_("%s: %s quotas turned off\n"), quotadev, type2name(type));
+ printf(_("%s [%s]: %s quotas turned off\n"), quotadev, quotadir, type2name(type));
return 0;
}
qcmd = QCMD(Q_QUOTAON, type);
if (quotactl(qcmd, quotadev, 0, (void *)quotafile) < 0) {
- errstr(_("using %s on %s: %s\n"), quotafile, quotadev, strerror(errno));
+ errstr(_("using %s on %s [%s]: %s\n"), quotafile, quotadev, quotadir, strerror(errno));
return 1;
}
if (flags & STATEFLAG_VERBOSE)
- printf(_("%s: %s quotas turned on\n"), quotadev, type2name(type));
+ printf(_("%s [%s]: %s quotas turned on\n"), quotadev, quotadir, type2name(type));
return 0;
}
@@ -233,7 +233,7 @@ int v1_newstate(struct mntent *mnt, int type, char *file, int flags)
if ((flags & STATEFLAG_OFF) && hasmntopt(mnt, MNTOPT_RSQUASH))
errs += quotarsquashonoff(dev, type, flags);
if (hasquota(mnt, type))
- errs += quotaonoff((char *)dev, file, type, flags);
+ errs += quotaonoff((char *)dev, mnt->mnt_dir, file, type, flags);
if ((flags & STATEFLAG_ON) && hasmntopt(mnt, MNTOPT_RSQUASH))
errs += quotarsquashonoff(dev, type, flags);
free((char *)dev);
@@ -251,7 +251,7 @@ int v2_newstate(struct mntent *mnt, int type, char *file, int flags)
if (!dev)
return 1;
if (hasquota(mnt, type))
- errs = quotaonoff((char *)dev, file, type, flags);
+ errs = quotaonoff((char *)dev, mnt->mnt_dir, file, type, flags);
free((char *)dev);
return errs;
}
diff --git a/quotasys.c b/quotasys.c
index 21d3a72..f25a80a 100644
--- a/quotasys.c
+++ b/quotasys.c
@@ -657,27 +657,40 @@ static int process_dirs(int dcnt, char **dirs)
check_dirs = smalloc(sizeof(struct searched_dir) * dcnt);
for (i = 0; i < dcnt; i++) {
if (stat(dirs[i], &st) < 0) {
- errstr(_("Can't stat() given mountpoint %s: %s\n"), dirs[i], strerror(errno));
+ errstr(_("Can't stat() given mountpoint %s: %s\nSkipping...\n"), dirs[i], strerror(errno));
continue;
}
check_dirs[check_dirs_cnt].sd_dir = S_ISDIR(st.st_mode);
if (S_ISDIR(st.st_mode)) {
check_dirs[check_dirs_cnt].sd_dev = st.st_dev;
check_dirs[check_dirs_cnt].sd_ino = st.st_ino;
+ if (!realpath(dirs[i], mntpointbuf)) {
+ errstr(_("Can't resolve path %s: %s\n"), dirs[i], strerror(errno));
+ continue;
+ }
}
- else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
+ else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)) {
+ int mentry;
+
check_dirs[check_dirs_cnt].sd_dev = st.st_rdev;
+ for (mentry = 0; mentry < mnt_entries_cnt && mnt_entries[mentry].me_dev != st.st_rdev; mentry++);
+ if (mentry == mnt_entries_cnt) {
+ errstr(_("Can't find mountpoint for device %s\n"), dirs[i]);
+ continue;
+ }
+ strcpy(mntpointbuf, mnt_entries[mentry].me_dir);
+ }
else {
errstr(_("Specified path %s is not directory nor device.\n"), dirs[i]);
continue;
}
- if (!realpath(dirs[i], mntpointbuf)) {
- errstr(_("Can't resolve path %s: %s\n"), dirs[i], strerror(errno));
- continue;
- }
check_dirs[check_dirs_cnt].sd_name = sstrdup(mntpointbuf);
check_dirs_cnt++;
}
+ if (!check_dirs_cnt) {
+ errstr(_("No correct mountpoint specified.\n"));
+ return -1;
+ }
}
return 0;
}