Index: mksnap_ffs.c =================================================================== --- mksnap_ffs.c (wersja 193043) +++ mksnap_ffs.c (kopia robocza) @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -55,20 +56,21 @@ 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 syntax. */ + 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 +79,15 @@ * 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,19 +106,26 @@ */ 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); } @@ -125,6 +134,6 @@ usage() { - fprintf(stderr, "usage: mksnap_ffs mountpoint snapshot_name\n"); + fprintf(stderr, "usage: mksnap_ffs snapshot_name\n"); exit(EX_USAGE); } Index: Makefile =================================================================== --- Makefile (wersja 193043) +++ Makefile (kopia robocza) @@ -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 Index: mksnap_ffs.8 =================================================================== --- mksnap_ffs.8 (wersja 193043) +++ mksnap_ffs.8 (kopia robocza) @@ -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 @@ 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