2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * @(#)restore.c 8.3 (Berkeley) 9/13/94
30 * $FreeBSD: src/sbin/restore/restore.c,v 1.7.2.1 2002/03/01 21:32:28 iedowse Exp $
33 #include <sys/types.h>
35 #include <vfs/ufs/dinode.h>
43 static char *keyval(int);
46 * This implements the 't' option.
47 * List entries on the tape.
50 listfile(char *name
, ufs1_ino_t ino
, int type
)
52 long descend
= hflag
? GOOD
: FAIL
;
54 if (TSTINO(ino
, dumpmap
) == 0)
56 vprintf(stdout
, "%s", type
== LEAF
? "leaf" : "dir ");
57 fprintf(stdout
, "%10d\t%s\n", ino
, name
);
62 * This implements the 'x' option.
63 * Request that new entries be extracted.
66 addfile(char *name
, ufs1_ino_t ino
, int type
)
69 long descend
= hflag
? GOOD
: FAIL
;
72 if (TSTINO(ino
, dumpmap
) == 0) {
73 dprintf(stdout
, "%s: not on the tape\n", name
);
76 if (ino
== UFS_WINO
&& command
== 'i' && !vflag
)
79 sprintf(buf
, "./%u", ino
);
82 genliteraldir(name
, ino
);
88 if (strcmp(name
, myname(ep
)) == 0) {
94 ep
= addentry(name
, ino
, type
);
102 * This is used by the 'i' option to undo previous requests made by addfile.
103 * Delete entries from the request queue.
107 deletefile(char *name
, ufs1_ino_t ino
, int type __unused
)
109 long descend
= hflag
? GOOD
: FAIL
;
112 if (TSTINO(ino
, dumpmap
) == 0)
114 ep
= lookupname(name
);
117 ep
->e_flags
|= REMOVED
;
118 if (ep
->e_type
!= NODE
)
125 * The following four routines implement the incremental
126 * restore algorithm. The first removes old entries, the second
127 * does renames and calculates the extraction list, the third
128 * cleans up link names missed by the first two, and the final
129 * one deletes old directories.
131 * Directories cannot be immediately deleted, as they may have
132 * other files in them which need to be moved out first. As
133 * directories to be deleted are found, they are put on the
134 * following deletion list. After all deletions and renames
135 * are done, this list is actually deleted.
137 static struct entry
*removelist
;
140 * Remove invalid whiteouts from the old tree.
141 * Remove unneeded leaves from the old tree.
142 * Remove directories from the lookup chains.
145 removeoldleaves(void)
147 struct entry
*ep
, *nextep
;
148 ufs1_ino_t i
, mydirino
;
150 vprintf(stdout
, "Mark entries to be removed.\n");
151 if ((ep
= lookupino(UFS_WINO
))) {
152 vprintf(stdout
, "Delete whiteouts\n");
153 for ( ; ep
!= NULL
; ep
= nextep
) {
154 nextep
= ep
->e_links
;
155 mydirino
= ep
->e_parent
->e_ino
;
157 * We remove all whiteouts that are in directories
158 * that have been removed or that have been dumped.
160 if (TSTINO(mydirino
, usedinomap
) &&
161 !TSTINO(mydirino
, dumpmap
))
167 for (i
= UFS_ROOTINO
+ 1; i
< maxino
; i
++) {
171 if (TSTINO(i
, usedinomap
))
173 for ( ; ep
!= NULL
; ep
= ep
->e_links
) {
174 dprintf(stdout
, "%s: REMOVE\n", myname(ep
));
175 if (ep
->e_type
== LEAF
) {
180 deleteino(ep
->e_ino
);
181 ep
->e_next
= removelist
;
189 * For each directory entry on the incremental tape, determine which
190 * category it falls into as follows:
191 * KEEP - entries that are to be left alone.
192 * NEW - new entries to be added.
193 * EXTRACT - files that must be updated with new contents.
194 * LINK - new links to be added.
195 * Renames are done at the same time.
198 nodeupdates(char *name
, ufs1_ino_t ino
, int type
)
200 struct entry
*ep
, *np
, *ip
;
205 # define ONTAPE 0x1 /* inode is on the tape */
206 # define INOFND 0x2 /* inode already exists */
207 # define NAMEFND 0x4 /* name already exists */
208 # define MODECHG 0x8 /* mode of inode changed */
211 * This routine is called once for each element in the
212 * directory hierarchy, with a full path name.
213 * The "type" value is incorrectly specified as LEAF for
214 * directories that are not on the dump tape.
216 * Check to see if the file is on the tape.
218 if (TSTINO(ino
, dumpmap
))
221 * Check to see if the name exists, and if the name is a link.
223 np
= lookupname(name
);
226 ip
= lookupino(np
->e_ino
);
228 panic("corrupted symbol table\n");
233 * Check to see if the inode exists, and if one of its links
234 * corresponds to the name (if one was found).
239 for (ep
= ip
->e_links
; ep
!= NULL
; ep
= ep
->e_links
) {
247 * If both a name and an inode are found, but they do not
248 * correspond to the same file, then both the inode that has
249 * been found and the inode corresponding to the name that
250 * has been found need to be renamed. The current pathname
251 * is the new name for the inode that has been found. Since
252 * all files to be deleted have already been removed, the
253 * named file is either a now unneeded link, or it must live
254 * under a new name in this dump level. If it is a link, it
255 * can be removed. If it is not a link, it is given a
256 * temporary name in anticipation that it will be renamed
257 * when it is later found by inode number.
259 if (((key
& (INOFND
|NAMEFND
)) == (INOFND
|NAMEFND
)) && ip
!= np
) {
260 if (lookuptype
== LINK
) {
264 dprintf(stdout
, "name/inode conflict, mktempname %s\n",
271 if ((key
& ONTAPE
) &&
272 (((key
& INOFND
) && ip
->e_type
!= type
) ||
273 ((key
& NAMEFND
) && np
->e_type
!= type
)))
277 * Decide on the disposition of the file based on its flags.
278 * Note that we have already handled the case in which
279 * a name and inode are found that correspond to different files.
280 * Thus if both NAMEFND and INOFND are set then ip == np.
285 * A previously existing file has been found.
286 * Mark it as KEEP so that other links to the inode can be
287 * detected, and so that it will not be reclaimed by the search
288 * for unreferenced names.
292 dprintf(stdout
, "[%s] %s: %s\n", keyval(key
), name
,
297 * A file on the tape has a name which is the same as a name
298 * corresponding to a different file in the previous dump.
299 * Since all files to be deleted have already been removed,
300 * this file is either a now unneeded link, or it must live
301 * under a new name in this dump level. If it is a link, it
302 * can simply be removed. If it is not a link, it is given a
303 * temporary name in anticipation that it will be renamed
304 * when it is later found by inode number (see INOFND case
305 * below). The entry is then treated as a new file.
308 case ONTAPE
|NAMEFND
|MODECHG
:
309 if (lookuptype
== LINK
) {
318 * A previously non-existent file.
319 * Add it to the file system, and request its extraction.
320 * If it is a directory, create it immediately.
321 * (Since the name is unused there can be no conflict)
324 ep
= addentry(name
, ino
, type
);
327 ep
->e_flags
|= NEW
|KEEP
;
328 dprintf(stdout
, "[%s] %s: %s\n", keyval(key
), name
,
333 * A file with the same inode number, but a different
334 * name has been found. If the other name has not already
335 * been found (indicated by the KEEP flag, see above) then
336 * this must be a new name for the file, and it is renamed.
337 * If the other name has been found then this must be a
338 * link to the file. Hard links to directories are not
339 * permitted, and are either deleted or converted to
340 * symbolic links. Finally, if the file is on the tape,
341 * a request is made to extract it.
344 if (type
== LEAF
&& (ip
->e_flags
& KEEP
) == 0)
345 ip
->e_flags
|= EXTRACT
;
348 if ((ip
->e_flags
& KEEP
) == 0) {
349 renameit(myname(ip
), name
);
352 dprintf(stdout
, "[%s] %s: %s\n", keyval(key
), name
,
356 if (ip
->e_type
== NODE
) {
359 "deleted hard link %s to directory %s\n",
363 ep
= addentry(name
, ino
, type
|LINK
);
365 dprintf(stdout
, "[%s] %s: %s|LINK\n", keyval(key
), name
,
370 * A previously known file which is to be updated. If it is a link,
371 * then all names referring to the previous file must be removed
372 * so that the subset of them that remain can be recreated.
374 case ONTAPE
|INOFND
|NAMEFND
:
375 if (lookuptype
== LINK
) {
378 ep
= addentry(name
, ino
, type
|LINK
);
381 ep
->e_flags
|= NEW
|KEEP
;
382 dprintf(stdout
, "[%s] %s: %s|LINK\n", keyval(key
), name
,
386 if (type
== LEAF
&& lookuptype
!= LINK
)
387 np
->e_flags
|= EXTRACT
;
389 dprintf(stdout
, "[%s] %s: %s\n", keyval(key
), name
,
394 * An inode is being reused in a completely different way.
395 * Normally an extract can simply do an "unlink" followed
396 * by a "creat". Here we must do effectively the same
397 * thing. The complications arise because we cannot really
398 * delete a directory since it may still contain files
399 * that we need to rename, so we delete it from the symbol
400 * table, and put it on the list to be deleted eventually.
401 * Conversely if a directory is to be created, it must be
402 * done immediately, rather than waiting until the
405 case ONTAPE
|INOFND
|MODECHG
:
406 case ONTAPE
|INOFND
|NAMEFND
|MODECHG
:
407 if (ip
->e_flags
& KEEP
) {
408 badentry(ip
, "cannot KEEP and change modes");
411 if (ip
->e_type
== LEAF
) {
412 /* changing from leaf to node */
413 for (ip
= lookupino(ino
); ip
!= NULL
; ip
= ip
->e_links
) {
414 if (ip
->e_type
!= LEAF
)
415 badentry(ip
, "NODE and LEAF links to same inode");
419 ip
= addentry(name
, ino
, type
);
422 /* changing from node to leaf */
423 if ((ip
->e_flags
& TMPNAME
) == 0)
425 deleteino(ip
->e_ino
);
426 ip
->e_next
= removelist
;
428 ip
= addentry(name
, ino
, type
);
430 ip
->e_flags
|= NEW
|KEEP
;
431 dprintf(stdout
, "[%s] %s: %s\n", keyval(key
), name
,
436 * A hard link to a directory that has been removed.
440 dprintf(stdout
, "[%s] %s: Extraneous name\n", keyval(key
),
446 * If we find a directory entry for a file that is not on
447 * the tape, then we must have found a file that was created
448 * while the dump was in progress. Since we have no contents
449 * for it, we discard the name knowing that it will be on the
450 * next incremental tape.
453 fprintf(stderr
, "%s: (inode %d) not found on tape\n",
458 * If any of these arise, something is grievously wrong with
459 * the current state of the symbol table.
461 case INOFND
|NAMEFND
|MODECHG
:
462 case NAMEFND
|MODECHG
:
464 fprintf(stderr
, "[%s] %s: inconsistent state\n", keyval(key
),
469 * These states "cannot" arise for any state of the symbol table.
474 panic("[%s] %s: impossible state\n", keyval(key
), name
);
481 * Calculate the active flags in a key.
486 static char keybuf
[32];
488 strcpy(keybuf
, "|NIL");
491 strcat(keybuf
, "|ONTAPE");
493 strcat(keybuf
, "|INOFND");
495 strcat(keybuf
, "|NAMEFND");
497 strcat(keybuf
, "|MODECHG");
502 * Find unreferenced link names.
507 struct entry
*ep
, *np
;
510 vprintf(stdout
, "Find unreferenced names.\n");
511 for (i
= UFS_ROOTINO
; i
< maxino
; i
++) {
513 if (ep
== NULL
|| ep
->e_type
== LEAF
|| TSTINO(i
, dumpmap
) == 0)
515 for (np
= ep
->e_entries
; np
!= NULL
; np
= np
->e_sibling
) {
516 if (np
->e_flags
== 0) {
518 "%s: remove unreferenced name\n",
526 * Any leaves remaining in removed directories is unreferenced.
528 for (ep
= removelist
; ep
!= NULL
; ep
= ep
->e_next
) {
529 for (np
= ep
->e_entries
; np
!= NULL
; np
= np
->e_sibling
) {
530 if (np
->e_type
== LEAF
) {
531 if (np
->e_flags
!= 0)
532 badentry(np
, "unreferenced with flags");
534 "%s: remove unreferenced name\n",
544 * Remove old nodes (directories).
545 * Note that this routine runs in O(N*D) where:
546 * N is the number of directory entries to be removed.
547 * D is the maximum depth of the tree.
548 * If N == D this can be quite slow. If the list were
549 * topologically sorted, the deletion could be done in
555 struct entry
*ep
, **prev
;
558 vprintf(stdout
, "Remove old nodes (directories).\n");
562 for (ep
= removelist
; ep
!= NULL
; ep
= *prev
) {
563 if (ep
->e_entries
!= NULL
) {
573 for (ep
= removelist
; ep
!= NULL
; ep
= ep
->e_next
)
574 badentry(ep
, "cannot remove, non-empty");
578 * This is the routine used to extract files for the 'r' command.
579 * Extract new leaves.
582 createleaves(const char *symtabfile
)
588 if (command
== 'R') {
589 vprintf(stdout
, "Continue extraction of new leaves\n");
591 vprintf(stdout
, "Extract new leaves.\n");
592 dumpsymtable(symtabfile
, volno
);
594 first
= lowerbnd(UFS_ROOTINO
);
596 while (curfile
.ino
< maxino
) {
597 first
= lowerbnd(first
);
599 * If the next available file is not the one which we
600 * expect then we have missed one or more files. Since
601 * we do not request files that were not on the tape,
602 * the lost files must have been due to a tape read error,
603 * or a file that was removed while the dump was in progress.
605 while (first
< curfile
.ino
) {
606 ep
= lookupino(first
);
608 panic("%d: bad first\n", first
);
609 fprintf(stderr
, "%s: not found on tape\n", myname(ep
));
610 ep
->e_flags
&= ~(NEW
|EXTRACT
);
611 first
= lowerbnd(first
);
614 * If we find files on the tape that have no corresponding
615 * directory entries, then we must have found a file that
616 * was created while the dump was in progress. Since we have
617 * no name for it, we discard it knowing that it will be
618 * on the next incremental tape.
620 if (first
!= curfile
.ino
) {
621 fprintf(stderr
, "expected next file %d, got %d\n",
626 ep
= lookupino(curfile
.ino
);
628 panic("unknown file on tape\n");
629 if ((ep
->e_flags
& (NEW
|EXTRACT
)) == 0)
630 badentry(ep
, "unexpected file on tape");
632 * If the file is to be extracted, then the old file must
633 * be removed since its type may change from one leaf type
634 * to another (e.g. "file" to "character special").
636 if ((ep
->e_flags
& EXTRACT
) != 0) {
638 ep
->e_flags
&= ~REMOVED
;
640 extractfile(myname(ep
));
641 ep
->e_flags
&= ~(NEW
|EXTRACT
);
643 * We checkpoint the restore after every tape reel, so
644 * as to simplify the amount of work required by the
648 if (curvol
!= volno
) {
649 dumpsymtable(symtabfile
, volno
);
657 * This is the routine used to extract files for the 'x' and 'i' commands.
658 * Efficiently extract a subset of the files on a tape.
663 ufs1_ino_t first
, next
, last
;
667 vprintf(stdout
, "Extract requested files\n");
668 curfile
.action
= SKIP
;
672 first
= lowerbnd(UFS_ROOTINO
);
673 last
= upperbnd(maxino
- 1);
676 first
= lowerbnd(first
);
677 last
= upperbnd(last
);
679 * Check to see if any files remain to be extracted
684 * Reject any volumes with inodes greater than the last
685 * one needed, so that we can quickly skip backwards to
686 * a volume containing useful inodes. We can't do this
687 * if there are no further volumes available (curfile.ino
688 * >= maxino) or if we are already at the first tape.
690 if (curfile
.ino
> last
&& curfile
.ino
< maxino
&& volno
> 1) {
691 curfile
.action
= SKIP
;
698 * Decide on the next inode needed.
699 * Skip across the inodes until it is found
700 * or a volume change is encountered
702 if (curfile
.ino
< maxino
) {
703 next
= lowerbnd(curfile
.ino
);
704 while (next
> curfile
.ino
&& volno
== curvol
)
706 if (volno
!= curvol
) {
713 * No further volumes or inodes available. Set
714 * `next' to the first inode, so that a warning
715 * is emitted below for each missing file.
720 * If the current inode is greater than the one we were
721 * looking for then we missed the one we were looking for.
722 * Since we only attempt to extract files listed in the
723 * dump map, the lost files must have been due to a tape
724 * read error, or a file that was removed while the dump
725 * was in progress. Thus we report all requested files
726 * between the one we were looking for, and the one we
727 * found as missing, and delete their request flags.
729 while (next
< curfile
.ino
) {
730 ep
= lookupino(next
);
732 panic("corrupted symbol table\n");
733 fprintf(stderr
, "%s: not found on tape\n", myname(ep
));
735 next
= lowerbnd(next
);
738 * The current inode is the one that we are looking for,
739 * so extract it per its requested name.
741 if (next
== curfile
.ino
&& next
<= last
) {
742 ep
= lookupino(next
);
744 panic("corrupted symbol table\n");
745 extractfile(myname(ep
));
759 struct entry
*np
, *ep
;
763 if ((ep
= lookupino(UFS_WINO
))) {
764 vprintf(stdout
, "Add whiteouts\n");
765 for ( ; ep
!= NULL
; ep
= ep
->e_links
) {
766 if ((ep
->e_flags
& NEW
) == 0)
768 addwhiteout(myname(ep
));
772 vprintf(stdout
, "Add links\n");
773 for (i
= UFS_ROOTINO
; i
< maxino
; i
++) {
777 for (np
= ep
->e_links
; np
!= NULL
; np
= np
->e_links
) {
778 if ((np
->e_flags
& NEW
) == 0)
780 strcpy(name
, myname(ep
));
781 if (ep
->e_type
== NODE
) {
782 linkit(name
, myname(np
), SYMLINK
);
784 linkit(name
, myname(np
), HARDLINK
);
792 * Check the symbol table.
793 * We do this to insure that all the requested work was done, and
794 * that no temporary names remain.
802 vprintf(stdout
, "Check the symbol table.\n");
803 for (i
= UFS_WINO
; i
< maxino
; i
++) {
804 for (ep
= lookupino(i
); ep
!= NULL
; ep
= ep
->e_links
) {
805 ep
->e_flags
&= ~KEEP
;
806 if (ep
->e_type
== NODE
)
807 ep
->e_flags
&= ~(NEW
|EXISTED
);
808 if (ep
->e_flags
!= 0)
809 badentry(ep
, "incomplete operations");
815 * Compare with the directory structure on the tape
816 * A paranoid check that things are as they should be.
819 verifyfile(char *name
, ufs1_ino_t ino
, int type
)
821 struct entry
*np
, *ep
;
824 ep
= lookupname(name
);
826 fprintf(stderr
, "Warning: missing name %s\n", name
);
832 for ( ; np
!= NULL
; np
= np
->e_links
)
836 panic("missing inumber %ju\n", (uintmax_t)ino
);
837 if (ep
->e_type
== LEAF
&& type
!= LEAF
)
838 badentry(ep
, "type should be LEAF");