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.
This commit is contained in:
Kirk McKusick 2003-11-04 07:34:32 +00:00
parent 09c01e4542
commit 524ee1107f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122037

View File

@ -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);
}
/*