From d747431e06c903f9e8638bd48d28505a79749c9f Mon Sep 17 00:00:00 2001 From: pjd Date: Fri, 29 May 2009 19:18:41 +0000 Subject: - Move from mount(2) to nmount(2). This should allow to convert MNT_SNAPSHOT flag from a mount flag to FS-specific flag. - Simplify usage. Instead of 'mksnap_ffs /mnt/foo /mnt/foo/snap' allow to give only one argument: 'mksnap_ffs /mnt/foo/snap'. Old usage is also accepted for now. - Add an example of how to mount a snapshot. --- sbin/mksnap_ffs/Makefile | 5 ++++ sbin/mksnap_ffs/mksnap_ffs.8 | 21 ++++++++------ sbin/mksnap_ffs/mksnap_ffs.c | 68 ++++++++++++++++++++++++-------------------- 3 files changed, 54 insertions(+), 40 deletions(-) (limited to 'sbin') diff --git a/sbin/mksnap_ffs/Makefile b/sbin/mksnap_ffs/Makefile index 3c08f56..40b56b4 100644 --- a/sbin/mksnap_ffs/Makefile +++ b/sbin/mksnap_ffs/Makefile @@ -1,8 +1,13 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/../mount + PROG= mksnap_ffs +SRCS= mksnap_ffs.c getmntopts.c MAN= mksnap_ffs.8 +CFLAGS+=-I${.CURDIR}/../mount + .if defined(NOSUID) BINMODE=550 .else diff --git a/sbin/mksnap_ffs/mksnap_ffs.8 b/sbin/mksnap_ffs/mksnap_ffs.8 index 3bd5d9e..8361722 100644 --- a/sbin/mksnap_ffs/mksnap_ffs.8 +++ b/sbin/mksnap_ffs/mksnap_ffs.8 @@ -34,7 +34,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 19, 2003 +.Dd May 29, 2009 .Dt MKSNAP_FFS 8 .Os .Sh NAME @@ -42,19 +42,12 @@ .Nd take a file system snapshot .Sh SYNOPSIS .Nm -.Ar mountpoint .Ar snapshot_name .Sh DESCRIPTION The .Nm utility creates a snapshot named -.Ar snapshot_name -on the file system mounted at -.Ar mountpoint . -The -.Ar snapshot_name -argument must be contained within the file system mounted at -.Ar mountpoint . +.Ar snapshot_name . .Pp The group ownership of the file is set to .Dq Li operator ; @@ -64,9 +57,19 @@ The mode of the snapshot is set to be readable by the owner or members of the .Dq Li operator group. +.Sh EXAMPLES +Create a snapshot of +.Pa /usr/home +file system and mount the snapshot elsewhere: +.Bd -literal -offset indent +mksnap_ffs /usr/home/snapshot +mdconfig -a -t vnode -o readonly -f /usr/home/snapshot +mount -o ro /dev/md0 /mnt/ +.Ed .Sh SEE ALSO .Xr chmod 2 , .Xr chown 8 , +.Xr mdconfig 8, .Xr mount 8 .Sh CAVEATS The disk full situation is not handled gracefully and may diff --git a/sbin/mksnap_ffs/mksnap_ffs.c b/sbin/mksnap_ffs/mksnap_ffs.c index a7ff957..fb26ebd 100644 --- a/sbin/mksnap_ffs/mksnap_ffs.c +++ b/sbin/mksnap_ffs/mksnap_ffs.c @@ -44,31 +44,38 @@ #include #include #include +#include #include #include #include #include #include -void usage(void); +static void +usage(void) +{ + + errx(EX_USAGE, "usage: mksnap_ffs snapshot_name"); +} int main(int argc, char **argv) { - char *dir, *cp, path[PATH_MAX]; + char errmsg[255], path[PATH_MAX]; + char *cp, *snapname; struct statfs stfsbuf; - struct ufs_args args; struct group *grp; struct stat stbuf; - int fd; + struct iovec *iov; + int fd, iovlen; - if (argc != 3) + if (argc == 2) + snapname = argv[1]; + else if (argc == 3) + snapname = argv[2]; /* Old usage. */ + else usage(); - dir = argv[1]; - memset(&args, 0, sizeof args); - args.fspec = argv[2]; - /* * Check that the user running this program has permission * to create and remove a snapshot file from the directory @@ -77,15 +84,15 @@ main(int argc, char **argv) * will not be able to remove the snapshot when they are * done with it. */ - if (strlen(args.fspec) >= PATH_MAX) - errx(1, "pathname too long %s", args.fspec); - cp = strrchr(args.fspec, '/'); + if (strlen(snapname) >= PATH_MAX) + errx(1, "pathname too long %s", snapname); + cp = strrchr(snapname, '/'); if (cp == NULL) { strlcpy(path, ".", PATH_MAX); - } else if (cp == args.fspec) { + } else if (cp == snapname) { strlcpy(path, "/", PATH_MAX); } else { - strlcpy(path, args.fspec, cp - args.fspec + 1); + strlcpy(path, snapname, cp - snapname + 1); } if (statfs(path, &stfsbuf) < 0) err(1, "%s", path); @@ -104,27 +111,26 @@ main(int argc, char **argv) */ if ((grp = getgrnam("operator")) == NULL) errx(1, "Cannot retrieve operator gid"); - if (mount("ufs", dir, MNT_UPDATE | MNT_SNAPSHOT | stfsbuf.f_flags, - &args) < 0) - err(1, "Cannot create %s", args.fspec); - if ((fd = open(args.fspec, O_RDONLY)) < 0) - err(1, "Cannot open %s", args.fspec); + + build_iovec(&iov, &iovlen, "fstype", "ffs", 4); + build_iovec(&iov, &iovlen, "from", snapname, (size_t)-1); + build_iovec(&iov, &iovlen, "fspath", stfsbuf.f_mntonname, (size_t)-1); + build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg)); + build_iovec(&iov, &iovlen, "update", NULL, 0); + build_iovec(&iov, &iovlen, "snapshot", NULL, 0); + + if (nmount(iov, iovlen, stfsbuf.f_flags) < 0) + err(1, "Cannot create snapshot %s: %s", snapname, errmsg); + if ((fd = open(snapname, O_RDONLY)) < 0) + err(1, "Cannot open %s", snapname); if (fstat(fd, &stbuf) != 0) - err(1, "Cannot stat %s", args.fspec); + err(1, "Cannot stat %s", snapname); if ((stbuf.st_flags & SF_SNAPSHOT) == 0) - errx(1, "File %s is not a snapshot", args.fspec); + errx(1, "File %s is not a snapshot", snapname); if (fchown(fd, -1, grp->gr_gid) != 0) - err(1, "Cannot chown %s", args.fspec); + err(1, "Cannot chown %s", snapname); if (fchmod(fd, S_IRUSR | S_IRGRP) != 0) - err(1, "Cannot chmod %s", args.fspec); + err(1, "Cannot chmod %s", snapname); exit(EXIT_SUCCESS); } - -void -usage() -{ - - fprintf(stderr, "usage: mksnap_ffs mountpoint snapshot_name\n"); - exit(EX_USAGE); -} -- cgit v1.1