Add an option (-M) to write a mtree specification (which needs to be passed

through sort before being feed to mtree) with file flags, instead of restoring
file flags at the same time as other attributes. Fix various issue with
schg, uchg, sappnd or uappnd flags which cause restore to fail in some case.
Discussed on tech-userlevel:
http://mail-index.netbsd.org/tech-userlevel/2004/10/12/0000.html
This commit is contained in:
bouyer 2004-10-22 22:38:38 +00:00
parent 79308267d4
commit 0a0bd752e8
7 changed files with 129 additions and 21 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dirs.c,v 1.40 2003/11/05 22:27:16 fvdl Exp $ */
/* $NetBSD: dirs.c,v 1.41 2004/10/22 22:38:38 bouyer Exp $ */
/*
* Copyright (c) 1983, 1993
@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)dirs.c 8.7 (Berkeley) 5/1/95";
#else
__RCSID("$NetBSD: dirs.c,v 1.40 2003/11/05 22:27:16 fvdl Exp $");
__RCSID("$NetBSD: dirs.c,v 1.41 2004/10/22 22:38:38 bouyer Exp $");
#endif
#endif /* not lint */
@ -649,7 +649,12 @@ setdirmodes(flags)
(void) utimes(cp, node.mtimep);
(void) chown(cp, node.uid, node.gid);
(void) chmod(cp, node.mode);
(void) chflags(cp, node.flags);
if (Mtreefile) {
writemtree(cp, "dir",
node.uid, node.gid, node.mode,
node.flags);
} else
(void) chflags(cp, node.flags);
}
ep->e_flags &= ~NEW;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.10 2004/07/27 02:17:06 enami Exp $ */
/* $NetBSD: extern.h,v 1.11 2004/10/22 22:38:38 bouyer Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -101,6 +101,8 @@ void swabst __P((u_char *, u_char *));
void treescan __P((char *, ino_t, long (*)(char *, ino_t, int)));
ino_t upperbnd __P((ino_t));
long verifyfile __P((char *, ino_t, int));
void writemtree __P((const char *, const char *, const uid_t,
const gid_t, const mode_t, const u_long));
void xtrnull __P((char *, long));
/* From ../dump/dumprmt.c */

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.26 2004/07/27 14:20:11 wiz Exp $ */
/* $NetBSD: main.c,v 1.27 2004/10/22 22:38:38 bouyer Exp $ */
/*
* Copyright (c) 1983, 1993
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: main.c,v 1.26 2004/07/27 14:20:11 wiz Exp $");
__RCSID("$NetBSD: main.c,v 1.27 2004/10/22 22:38:38 bouyer Exp $");
#endif
#endif /* not lint */
@ -77,6 +77,8 @@ size_t pagesize;
FILE *terminal;
char *tmpdir;
FILE *Mtreefile = NULL;
int main __P((int, char *[]));
static void obsolete __P((int *, char **[]));
static void usage __P((void));
@ -100,7 +102,7 @@ main(argc, argv)
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = _PATH_TMP;
obsolete(&argc, &argv);
while ((ch = getopt(argc, argv, "b:cD:df:himNRrs:tuvxy")) != -1)
while ((ch = getopt(argc, argv, "b:cD:df:himM:NRrs:tuvxy")) != -1)
switch (ch) {
case 'b':
/* Change default tape blocksize. */
@ -146,6 +148,11 @@ main(argc, argv)
case 'N':
Nflag = 1;
break;
case 'M':
Mtreefile = fopen(optarg, "a");
if (Mtreefile == NULL)
err(1, "can't open %s", optarg);
break;
case 's':
/* Dumpnum (skip to) for multifile dump tapes. */
dumpnum = strtol(optarg, &p, 10);
@ -300,19 +307,19 @@ usage()
(void)fprintf(stderr,
"usage: %s -i [-cdhmvyN] [-b bsize] [-D algorithm] "
"[-f file] [-s fileno]\n", progname);
"[-f file] [-s fileno] [-M mtreefile]\n", progname);
(void)fprintf(stderr,
" %s -R [-cdvyN] [-b bsize] [-D algorithm] [-f file] "
"[-s fileno]\n", progname);
"[-s fileno] [-M mtreefile]\n", progname);
(void)fprintf(stderr,
" %s -r [-cdvyN] [-b bsize] [-D algorithm] [-f file] "
"[-s fileno]\n", progname);
"[-s fileno] [-M mtreefile]\n", progname);
(void)fprintf(stderr,
" %s -t [-cdhvy] [-b bsize] [-D algorithm] [-f file]\n"
" [-s fileno] [file ...]\n", progname);
(void)fprintf(stderr,
" %s -x [-cdhmvyN] [-b bsize] [-D algorithm] [-f file]\n"
" [-s fileno] [file ...]\n", progname);
" [-s fileno] [-M mtreefile] [file ...]\n", progname);
exit(1);
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: restore.8,v 1.43 2004/07/27 14:20:11 wiz Exp $
.\" $NetBSD: restore.8,v 1.44 2004/10/22 22:38:38 bouyer Exp $
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -43,6 +43,7 @@
.Op Fl b Ar bsize
.Op Fl D Ar algorithm
.Op Fl f Ar file
.Op Fl M Ar mfile
.Op Fl s Ar fileno
.Nm
.Fl R
@ -50,6 +51,7 @@
.Op Fl b Ar bsize
.Op Fl D Ar algorithm
.Op Fl f Ar file
.Op Fl M Ar mfile
.Op Fl s Ar fileno
.Nm
.Fl r
@ -57,6 +59,7 @@
.Op Fl b Ar bsize
.Op Fl D Ar algorithm
.Op Fl f Ar file
.Op Fl M Ar mfile
.Op Fl s Ar fileno
.Nm
.Fl t
@ -71,6 +74,7 @@
.Op Fl b Ar bsize
.Op Fl D Ar algorithm
.Op Fl f Ar file
.Op Fl M Ar mfile
.Op Fl s Ar fileno
.Op Ar
.Pp
@ -341,6 +345,15 @@ Extract by inode numbers rather than by file name.
This is useful if only a few files are being extracted,
and one wants to avoid regenerating the complete pathname
to the file.
.It Fl M Ar mfile
Do not set the file flags on restore, instead append a
.Xr mtree 8
specification to
.Ar mfile
which can be used later to restore file flags:
.Bd -literal -offset indent
sort mfile | mtree -e -i -u
.Ed
.It Fl s Ar fileno
Read from the specified
.Ar fileno

View File

@ -1,4 +1,4 @@
/* $NetBSD: restore.h,v 1.15 2004/07/27 02:17:06 enami Exp $ */
/* $NetBSD: restore.h,v 1.16 2004/10/22 22:38:38 bouyer Exp $ */
/*
* Copyright (c) 1983, 1993
@ -66,6 +66,7 @@ extern FILE *terminal; /* file descriptor for the terminal input */
extern char *tmpdir; /* where to store temporary files */
extern int oldinofmt; /* reading tape with old format inodes */
extern int Bcvt; /* need byte swapping on inodes and dirs */
extern FILE *Mtreefile; /* file descriptor for the mtree file */
struct digest_desc {
const char *dd_name;

View File

@ -1,4 +1,4 @@
/* $NetBSD: tape.c,v 1.50 2004/07/27 02:17:06 enami Exp $ */
/* $NetBSD: tape.c,v 1.51 2004/10/22 22:38:38 bouyer Exp $ */
/*
* Copyright (c) 1983, 1993
@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95";
#else
__RCSID("$NetBSD: tape.c,v 1.50 2004/07/27 02:17:06 enami Exp $");
__RCSID("$NetBSD: tape.c,v 1.51 2004/10/22 22:38:38 bouyer Exp $");
#endif
#endif /* not lint */
@ -52,6 +52,7 @@ __RCSID("$NetBSD: tape.c,v 1.50 2004/07/27 02:17:06 enami Exp $");
#include <ufs/ufs/dinode.h>
#include <protocols/dumprestore.h>
#include <err.h>
#include <errno.h>
#include <paths.h>
#include <setjmp.h>
@ -588,6 +589,21 @@ printdumpinfo()
spcl.c_level, spcl.c_filesys,
*spcl.c_host? spcl.c_host: "[unknown]", spcl.c_dev);
fprintf(stderr, "Label: %s\n", spcl.c_label);
if (Mtreefile) {
ttime = spcl.c_date;
fprintf(Mtreefile, "#Dump date: %s", ctime(&ttime));
ttime = spcl.c_ddate;
fprintf(Mtreefile, "#Dumped from: %s",
(spcl.c_ddate == 0) ? "the epoch\n" : ctime(&ttime));
fprintf(Mtreefile, "#Level %d dump of %s on %s:%s\n",
spcl.c_level, spcl.c_filesys,
*spcl.c_host? spcl.c_host: "[unknown]", spcl.c_dev);
fprintf(Mtreefile, "#Label: %s\n", spcl.c_label);
fprintf(Mtreefile, "/set uname=root gname=wheel\n");
if (ferror(Mtreefile))
err(1, "error writing to mtree file");
}
}
int
@ -662,7 +678,11 @@ extractfile(name)
(void) lutimes(name, mtimep);
(void) lchown(name, uid, gid);
(void) lchmod(name, mode);
(void) lchflags(name, flags);
if (Mtreefile) {
writemtree(name, "link",
uid, gid, mode, flags);
} else
(void) lchflags(name, flags);
return (GOOD);
}
return (FAIL);
@ -689,7 +709,13 @@ extractfile(name)
(void) utimes(name, mtimep);
(void) chown(name, uid, gid);
(void) chmod(name, mode);
(void) chflags(name, flags);
if (Mtreefile) {
writemtree(name,
((mode & (S_IFBLK | IFCHR)) == IFBLK) ?
"block" : "char",
uid, gid, mode, flags);
} else
(void) chflags(name, flags);
return (GOOD);
case IFIFO:
@ -712,7 +738,11 @@ extractfile(name)
(void) utimes(name, mtimep);
(void) chown(name, uid, gid);
(void) chmod(name, mode);
(void) chflags(name, flags);
if (Mtreefile) {
writemtree(name, "fifo",
uid, gid, mode, flags);
} else
(void) chflags(name, flags);
return (GOOD);
case IFREG:
@ -744,7 +774,11 @@ extractfile(name)
(void) futimes(ofile, mtimep);
(void) fchown(ofile, uid, gid);
(void) fchmod(ofile, mode);
(void) fchflags(ofile, flags);
if (Mtreefile) {
writemtree(name, "file",
uid, gid, mode, flags);
} else
(void) fchflags(ofile, flags);
(void) close(ofile);
return (GOOD);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: utilities.c,v 1.17 2003/08/07 10:04:38 agc Exp $ */
/* $NetBSD: utilities.c,v 1.18 2004/10/22 22:38:38 bouyer Exp $ */
/*
* Copyright (c) 1983, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)utilities.c 8.5 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: utilities.c,v 1.17 2003/08/07 10:04:38 agc Exp $");
__RCSID("$NetBSD: utilities.c,v 1.18 2004/10/22 22:38:38 bouyer Exp $");
#endif
#endif /* not lint */
@ -44,6 +44,7 @@ __RCSID("$NetBSD: utilities.c,v 1.17 2003/08/07 10:04:38 agc Exp $");
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -423,3 +424,48 @@ panic(const char *fmt, ...)
exit(1);
}
}
void
writemtree(const char *name, const char *type,
const uid_t uid, const gid_t gid, const mode_t mode, const u_long flags)
{
char *sep = "";
if ((name[0] != '.') || (name[1] != '/' && name[1] != '\0'))
fprintf(Mtreefile, "./");
fprintf(Mtreefile, "%s type=%s uid=%d gid=%d mode=%#4.4o",
name, type, uid, gid,
mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISTXT));
if (flags != 0)
fprintf(Mtreefile, " flags=");
if (flags & UF_NODUMP) {
fprintf(Mtreefile, "nodump");
sep=",";
}
if (flags & UF_IMMUTABLE) {
fprintf(Mtreefile, "%suchg", sep);
sep=",";
}
if (flags & UF_APPEND) {
fprintf(Mtreefile, "%suappnd", sep);
sep=",";
}
if (flags & UF_OPAQUE) {
fprintf(Mtreefile, "%sopaque", sep);
sep=",";
}
if (flags & SF_ARCHIVED) {
fprintf(Mtreefile, "%sarch", sep);
sep=",";
}
if (flags & SF_IMMUTABLE) {
fprintf(Mtreefile, "%sschg", sep);
sep=",";
}
if (flags & SF_APPEND) {
fprintf(Mtreefile, "%ssappnd", sep);
sep=",";
}
fprintf(Mtreefile, "\n");
if (ferror(Mtreefile))
err(1, "error writing to mtree file");
}