Subject: Re: restore and schg flag
To: None <tech-userlevel@NetBSD.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: tech-userlevel
Date: 10/12/2004 00:06:18
--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Mon, Oct 11, 2004 at 10:33:52PM +0200, Manuel Bouyer wrote:
> [...]
>
> My idea for this is to defer this work to mtree. I'll add a -M<file> flag to
> restore, which, when set, will cause restore to not set the file flags
> (either for files or directory), but instead write (append, so that we can
> have in a single file the output of a multilevel restore) a mtree file in the
> format of /etc/mtree/*. Then the user can run mtree against this file
> to restore the flags. I can't think of a better way to handle all the
> corner cases *chg or *appnd can create for restore.
>
> Comments ?
Here is a patch. It works in my case, at last:
#/tmp/restore -M /tmp/mtree -rvf ../wd0a.0
[...]
#/tmp/restore -M /tmp/mtree -rvf ../wd0a.1
[...]
# sort /tmp/mtree | mtree -e -i -u
testdir:
flags ("uchg" is not "none", modified to "uchg")
We need to process the file though sort, because mtree needs to have the specs
for a directory before the files in this directory. But it works very well
for my test cases.
Should I update the man page, and commit this ?
--
Manuel Bouyer <bouyer@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--
--y0ulUmNC+osPPQO6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff
? .gdbinit
? restore
? restore.cat8
Index: dirs.c
===================================================================
RCS file: /cvsroot/src/sbin/restore/dirs.c,v
retrieving revision 1.40
diff -u -r1.40 dirs.c
--- dirs.c 5 Nov 2003 22:27:16 -0000 1.40
+++ dirs.c 11 Oct 2004 22:00:46 -0000
@@ -649,7 +649,12 @@
(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;
}
Index: extern.h
===================================================================
RCS file: /cvsroot/src/sbin/restore/extern.h,v
retrieving revision 1.9
diff -u -r1.9 extern.h
--- extern.h 7 Aug 2003 10:04:37 -0000 1.9
+++ extern.h 11 Oct 2004 22:00:46 -0000
@@ -99,6 +99,8 @@
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 */
Index: main.c
===================================================================
RCS file: /cvsroot/src/sbin/restore/main.c,v
retrieving revision 1.23
diff -u -r1.23 main.c
--- main.c 7 Aug 2003 10:04:37 -0000 1.23
+++ main.c 11 Oct 2004 22:00:46 -0000
@@ -77,6 +77,8 @@
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 @@
if ((tmpdir = getenv("TMPDIR")) == NULL)
tmpdir = _PATH_TMP;
obsolete(&argc, &argv);
- while ((ch = getopt(argc, argv, "b:cdf:himNRrs:tuvxy")) != -1)
+ while ((ch = getopt(argc, argv, "b:cdf:himM:NRrs:tuvxy")) != -1)
switch(ch) {
case 'b':
/* Change default tape blocksize. */
@@ -140,6 +142,11 @@
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);
@@ -293,20 +300,20 @@
const char *progname = getprogname();
(void)fprintf(stderr,
- "usage: %s -i [-cdhmvyN] [-b blocksize] [-f file] [-s fileno]\n",
- progname);
+ "usage: %s -i [-cdhmvyN] [-b blocksize] [-f file] [-s fileno] "
+ "[-M mtreefile]\n", progname);
(void)fprintf(stderr,
- "\t%s -R [-cdvyN] [-b blocksize] [-f file] [-s fileno]\n",
- progname);
+ "\t%s -R [-cdvyN] [-b blocksize] [-f file] [-s fileno] "
+ "[-M mtreefile]\n", progname);
(void)fprintf(stderr,
- "\t%s -r [-cdvyN] [-b blocksize] [-f file] [-s fileno]\n",
- progname);
+ "\t%s -r [-cdvyN] [-b blocksize] [-f file] [-s fileno] "
+ "[-M mtreefile]\n", progname);
(void)fprintf(stderr,
- "\t%s -t [-cdhvy] [-b blocksize] [-f file] [-s fileno] [file ...]\n",
- progname);
+ "\t%s -t [-cdhvy] [-b blocksize] [-f file] [-s fileno] "
+ "[-M mtreefile] [file ...]\n", progname);
(void)fprintf(stderr,
- "\t%s -x [-cdhmvyN] [-b blocksize] [-f file] [-s fileno] [file ...]\n",
- progname);
+ "\t%s -x [-cdhmvyN] [-b blocksize] [-f file] [-s fileno] "
+ "[-M mtreefile] [file ...]\n", progname);
exit(1);
}
Index: restore.h
===================================================================
RCS file: /cvsroot/src/sbin/restore/restore.h,v
retrieving revision 1.14
diff -u -r1.14 restore.h
--- restore.h 7 Aug 2003 10:04:38 -0000 1.14
+++ restore.h 11 Oct 2004 22:00:46 -0000
@@ -65,6 +65,7 @@
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 */
/*
* Each file in the file system is described by one of these entries
Index: tape.c
===================================================================
RCS file: /cvsroot/src/sbin/restore/tape.c,v
retrieving revision 1.49
diff -u -r1.49 tape.c
--- tape.c 7 Aug 2003 10:04:38 -0000 1.49
+++ tape.c 11 Oct 2004 22:00:46 -0000
@@ -52,6 +52,7 @@
#include <ufs/ufs/dinode.h>
#include <protocols/dumprestore.h>
+#include <err.h>
#include <errno.h>
#include <paths.h>
#include <setjmp.h>
@@ -542,6 +543,21 @@
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
@@ -615,7 +631,11 @@
(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);
@@ -642,7 +662,13 @@
(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:
@@ -665,7 +691,11 @@
(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:
@@ -689,7 +719,11 @@
(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);
}
Index: utilities.c
===================================================================
RCS file: /cvsroot/src/sbin/restore/utilities.c,v
retrieving revision 1.17
diff -u -r1.17 utilities.c
--- utilities.c 7 Aug 2003 10:04:38 -0000 1.17
+++ utilities.c 11 Oct 2004 22:00:46 -0000
@@ -44,6 +44,7 @@
#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 @@
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");
+}
--y0ulUmNC+osPPQO6--