summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2003-10-08 02:14:03 +0000
committermckusick <mckusick@FreeBSD.org>2003-10-08 02:14:03 +0000
commit09fe11f64363ff091f222552c74d94b439b2923c (patch)
tree9ff9904b9662115224d9efcfb1066731c7cf6b13 /sbin/fsck_ffs
parentb86aaed485625ece4fd3999e1b0114ce5844b9c0 (diff)
downloadFreeBSD-src-09fe11f64363ff091f222552c74d94b439b2923c.zip
FreeBSD-src-09fe11f64363ff091f222552c74d94b439b2923c.tar.gz
Create a .snap directory mode 770 group operator in the root of each
filesystem that is checked in background. Create the snapshot in this directory rather than in the root. There are two benefits: 1) For terabyte-sized filesystems, the snapshot may require many minutes to build. Although the filesystem will not be suspended during most of the snapshot build, the snapshot file itself is locked during the entire snapshot build period. Thus, if it is accessed during the period that it is being built, the process trying to access it will block holding its containing directory locked. If the snapshot is in the root, the root will lock and the system will come to a halt until the snapshot finishes. By putting the snapshot in a subdirectory, it is out of the likely path of any process traversing through the root and hence much less likely to cause a lock race to the root. 2) The dump program is usually run by a non-root user running with operator group privilege. Such a user is typically not permitted to create files in the root of a filesystem. By having a directory in group operator with group write access available, such a user will be able to create a snapshot there. Having the dump program create its snapshot in a subdirectory below the root will benefit from point (1) as well. Sponsored by: DARPA & NAI Labs.
Diffstat (limited to 'sbin/fsck_ffs')
-rw-r--r--sbin/fsck_ffs/main.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index beff428..06b4540 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
#include <fstab.h>
+#include <grp.h>
#include <paths.h>
#include <stdint.h>
#include <string.h>
@@ -189,6 +190,8 @@ checkfilesys(char *filesys)
struct dups *dp;
struct statfs *mntp;
struct zlncnt *zlnp;
+ struct stat snapdir;
+ struct group *grp;
ufs2_daddr_t blks;
int cylno, ret;
ino_t files;
@@ -269,8 +272,34 @@ checkfilesys(char *filesys)
close(fsreadfd);
}
if (bkgrdflag) {
- snprintf(snapname, sizeof snapname, "%s/.fsck_snapshot",
+ snprintf(snapname, sizeof snapname, "%s/.snap",
mntp->f_mntonname);
+ if (stat(snapname, &snapdir) < 0) {
+ if (errno != ENOENT) {
+ bkgrdflag = 0;
+ pfatal("CANNOT FIND %s %s: %s, %s\n",
+ "SNAPSHOT DIRECTORY",
+ snapname, strerror(errno),
+ "CANNOT RUN IN BACKGROUND");
+ } else if ((grp = getgrnam("operator")) == 0 ||
+ mkdir(snapname, 0770) < 0 ||
+ chown(snapname, -1, grp->gr_gid) < 0 ||
+ chmod(snapname, 0770) < 0) {
+ bkgrdflag = 0;
+ pfatal("CANNOT CREATE %s %s: %s, %s\n",
+ "SNAPSHOT DIRECTORY",
+ snapname, strerror(errno),
+ "CANNOT RUN IN BACKGROUND");
+ }
+ } else if (!S_ISDIR(snapdir.st_mode)) {
+ bkgrdflag = 0;
+ pfatal("%s IS NOT A DIRECTORY, %s\n", snapname,
+ "CANNOT RUN IN BACKGROUND");
+ }
+ }
+ if (bkgrdflag) {
+ snprintf(snapname, sizeof snapname,
+ "%s/.snap/fsck_snapshot", mntp->f_mntonname);
args.fspec = snapname;
while (mount("ffs", mntp->f_mntonname,
mntp->f_flags | MNT_UPDATE | MNT_SNAPSHOT,
OpenPOWER on IntegriCloud