diff options
author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2009-05-29 19:18:41 +0000 |
---|---|---|
committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2009-05-29 19:18:41 +0000 |
commit | c8cf3f3d0e48740c32c2b7ea85f7098298b34a52 (patch) | |
tree | c09c007b5c95c0fcfadd855c6aebe7de77bd18e3 | |
parent | b89fed6747c280966ef951a8712a33d8e65d0aab (diff) | |
download | src-c8cf3f3d0e48740c32c2b7ea85f7098298b34a52.tar.gz src-c8cf3f3d0e48740c32c2b7ea85f7098298b34a52.zip |
- 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.
Notes
Notes:
svn path=/head/; revision=193051
-rw-r--r-- | sbin/mksnap_ffs/Makefile | 5 | ||||
-rw-r--r-- | sbin/mksnap_ffs/mksnap_ffs.8 | 21 | ||||
-rw-r--r-- | sbin/mksnap_ffs/mksnap_ffs.c | 68 |
3 files changed, 54 insertions, 40 deletions
diff --git a/sbin/mksnap_ffs/Makefile b/sbin/mksnap_ffs/Makefile index 3c08f565225d..40b56b445da2 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 3bd5d9ef34d7..8361722d8087 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 a7ff9572572b..fb26ebd6c23a 100644 --- a/sbin/mksnap_ffs/mksnap_ffs.c +++ b/sbin/mksnap_ffs/mksnap_ffs.c @@ -44,31 +44,38 @@ #include <fcntl.h> #include <grp.h> #include <limits.h> +#include <mntopts.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sysexits.h> #include <unistd.h> -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); -} |