summaryrefslogtreecommitdiffstats
path: root/sbin/newfs
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2003-11-04 07:34:32 +0000
committermckusick <mckusick@FreeBSD.org>2003-11-04 07:34:32 +0000
commitf692f640895d645706322a61176089c98dee8fb2 (patch)
tree6f3aa13f518b935b5b70ee59a98ad4ad352cc8ac /sbin/newfs
parent8cecbe74983913d60c797d1c6082e062de4b3b13 (diff)
downloadFreeBSD-src-f692f640895d645706322a61176089c98dee8fb2.zip
FreeBSD-src-f692f640895d645706322a61176089c98dee8fb2.tar.gz
Create a .snap directory mode 770 group operator in the root of
a new filesystem. Dump and fsck will create snapshots in this directory rather than in the root for two reasons: 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/newfs')
-rw-r--r--sbin/newfs/mkfs.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index 80ed645..1c117e6 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -49,6 +49,7 @@ static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95";
__FBSDID("$FreeBSD$");
#include <err.h>
+#include <grp.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
@@ -700,19 +701,30 @@ initcg(int cylno, time_t utime)
/*
* initialize the file system
*/
-#define PREDEFDIR 2
+#define ROOTLINKCNT 3
struct direct root_dir[] = {
{ ROOTINO, sizeof(struct direct), DT_DIR, 1, "." },
{ ROOTINO, sizeof(struct direct), DT_DIR, 2, ".." },
+ { ROOTINO + 1, sizeof(struct direct), DT_DIR, 5, ".snap" },
+};
+
+#define SNAPLINKCNT 2
+
+struct direct snap_dir[] = {
+ { ROOTINO + 1, sizeof(struct direct), DT_DIR, 1, "." },
+ { ROOTINO, sizeof(struct direct), DT_DIR, 2, ".." },
};
void
fsinit(time_t utime)
{
union dinode node;
+ struct group *grp;
memset(&node, 0, sizeof node);
+ if ((grp = getgrnam("operator")) == NULL)
+ errx(35, "Cannot retrieve operator gid");
if (sblock.fs_magic == FS_UFS1_MAGIC) {
/*
* initialize the node
@@ -724,13 +736,27 @@ fsinit(time_t utime)
* create the root directory
*/
node.dp1.di_mode = IFDIR | UMASK;
- node.dp1.di_nlink = PREDEFDIR;
- node.dp1.di_size = makedir(root_dir, PREDEFDIR);
+ node.dp1.di_nlink = ROOTLINKCNT;
+ node.dp1.di_size = makedir(root_dir, ROOTLINKCNT);
+ node.dp1.di_db[0] = alloc(sblock.fs_fsize, node.dp1.di_mode);
+ node.dp1.di_blocks =
+ btodb(fragroundup(&sblock, node.dp1.di_size));
+ wtfs(fsbtodb(&sblock, node.dp1.di_db[0]), sblock.fs_fsize,
+ iobuf);
+ iput(&node, ROOTINO);
+ /*
+ * create the .snap directory
+ */
+ node.dp1.di_mode |= 020;
+ node.dp1.di_gid = grp->gr_gid;
+ node.dp1.di_nlink = SNAPLINKCNT;
+ node.dp1.di_size = makedir(snap_dir, SNAPLINKCNT);
node.dp1.di_db[0] = alloc(sblock.fs_fsize, node.dp1.di_mode);
node.dp1.di_blocks =
btodb(fragroundup(&sblock, node.dp1.di_size));
wtfs(fsbtodb(&sblock, node.dp1.di_db[0]), sblock.fs_fsize,
iobuf);
+ iput(&node, ROOTINO + 1);
} else {
/*
* initialize the node
@@ -743,15 +769,28 @@ fsinit(time_t utime)
* create the root directory
*/
node.dp2.di_mode = IFDIR | UMASK;
- node.dp2.di_nlink = PREDEFDIR;
- node.dp2.di_size = makedir(root_dir, PREDEFDIR);
+ node.dp2.di_nlink = ROOTLINKCNT;
+ node.dp2.di_size = makedir(root_dir, ROOTLINKCNT);
+ node.dp2.di_db[0] = alloc(sblock.fs_fsize, node.dp2.di_mode);
+ node.dp2.di_blocks =
+ btodb(fragroundup(&sblock, node.dp2.di_size));
+ wtfs(fsbtodb(&sblock, node.dp2.di_db[0]), sblock.fs_fsize,
+ iobuf);
+ iput(&node, ROOTINO);
+ /*
+ * create the .snap directory
+ */
+ node.dp2.di_mode |= 020;
+ node.dp2.di_gid = grp->gr_gid;
+ node.dp2.di_nlink = SNAPLINKCNT;
+ node.dp2.di_size = makedir(snap_dir, SNAPLINKCNT);
node.dp2.di_db[0] = alloc(sblock.fs_fsize, node.dp2.di_mode);
node.dp2.di_blocks =
btodb(fragroundup(&sblock, node.dp2.di_size));
wtfs(fsbtodb(&sblock, node.dp2.di_db[0]), sblock.fs_fsize,
iobuf);
+ iput(&node, ROOTINO + 1);
}
- iput(&node, ROOTINO);
}
/*
OpenPOWER on IntegriCloud