Add support for non-native byte order FFS. The dump is in filesystem byte

order, restore already knows how to byteswap dumps.
This commit is contained in:
bouyer 1998-03-18 16:54:56 +00:00
parent 08371645ee
commit 34ccbd430c
6 changed files with 142 additions and 86 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.18 1997/10/10 19:48:01 christos Exp $
# $NetBSD: Makefile,v 1.19 1998/03/18 16:54:56 bouyer Exp $
# @(#)Makefile 8.1 (Berkeley) 6/5/93
# dump.h header file
@ -16,10 +16,15 @@
PROG= dump
LINKS= ${BINDIR}/dump ${BINDIR}/rdump
CPPFLAGS+=-DRDUMP
SRCS= itime.c main.c optr.c dumprmt.c tape.c traverse.c unctime.c
SRCS= itime.c main.c optr.c dumprmt.c tape.c traverse.c unctime.c \
ffs_bswap.c
DPADD= ${LIBUTIL}
LDADD+= -lutil
BINGRP= tty
BINMODE=2555
MAN= dump.8
MLINKS+=dump.8 rdump.8
.PATH: ${.CURDIR}/../../sys/ufs/ffs
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: dump.h,v 1.13 1997/09/16 06:41:20 lukem Exp $ */
/* $NetBSD: dump.h,v 1.14 1998/03/18 16:54:56 bouyer Exp $ */
/*-
* Copyright (c) 1980, 1993
@ -87,6 +87,35 @@ char sblock_buf[MAXBSIZE];
long dev_bsize; /* block size of underlying disk device */
int dev_bshift; /* log2(dev_bsize) */
int tp_bshift; /* log2(TP_BSIZE) */
int needswap; /* file system in swapped byte order */
/* some inline functs to help the byte-swapping mess */
static __inline u_int16_t iswap16 __P((u_int16_t));
static __inline u_int32_t iswap32 __P((u_int32_t));
static __inline u_int64_t iswap64 __P((u_int64_t));
static __inline u_int16_t iswap16(x)
u_int16_t x;
{
if (needswap)
return bswap16(x);
else return x;
}
static __inline u_int32_t iswap32(x)
u_int32_t x;
{
if (needswap)
return bswap32(x);
else return x;
}
static __inline u_int64_t iswap64(x)
u_int64_t x;
{
if (needswap)
return bswap64(x);
else return x;
}
#ifndef __P
#include <sys/cdefs.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: itime.c,v 1.5 1997/09/15 07:58:04 lukem Exp $ */
/* $NetBSD: itime.c,v 1.6 1998/03/18 16:54:56 bouyer Exp $ */
/*-
* Copyright (c) 1980, 1993
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)itime.c 8.1 (Berkeley) 6/5/93";
#else
__RCSID("$NetBSD: itime.c,v 1.5 1997/09/15 07:58:04 lukem Exp $");
__RCSID("$NetBSD: itime.c,v 1.6 1998/03/18 16:54:56 bouyer Exp $");
#endif
#endif /* not lint */
@ -162,9 +162,9 @@ getdumptime()
continue;
if (ddp->dd_level >= level)
continue;
if (ddp->dd_ddate <= spcl.c_ddate)
if (ddp->dd_ddate <= iswap32(spcl.c_ddate))
continue;
spcl.c_ddate = ddp->dd_ddate;
spcl.c_ddate = iswap32(ddp->dd_ddate);
lastlevel = ddp->dd_level;
}
}
@ -212,7 +212,7 @@ putdumptime()
found:
(void) strncpy(dtwalk->dd_name, fname, sizeof (dtwalk->dd_name));
dtwalk->dd_level = level;
dtwalk->dd_ddate = spcl.c_date;
dtwalk->dd_ddate = iswap32(spcl.c_date);
ITITERATE(i, dtwalk) {
dumprecout(df, dtwalk);
@ -223,7 +223,7 @@ putdumptime()
quit("ftruncate (%s): %s\n", dumpdates, strerror(errno));
(void) fclose(df);
msg("level %c dump on %s", level,
spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
spcl.c_date == 0 ? "the epoch\n" : ctime(&dtwalk->dd_ddate));
}
static void

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.17 1997/09/18 03:03:56 lukem Exp $ */
/* $NetBSD: main.c,v 1.18 1998/03/18 16:54:56 bouyer Exp $ */
/*-
* Copyright (c) 1980, 1991, 1993, 1994
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1991, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/1/95";
#else
__RCSID("$NetBSD: main.c,v 1.17 1997/09/18 03:03:56 lukem Exp $");
__RCSID("$NetBSD: main.c,v 1.18 1998/03/18 16:54:56 bouyer Exp $");
#endif
#endif /* not lint */
@ -60,6 +60,7 @@ __RCSID("$NetBSD: main.c,v 1.17 1997/09/18 03:03:56 lukem Exp $");
#else
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <ufs/ffs/ffs_extern.h>
#endif
#include <protocols/dumprestore.h>
@ -111,7 +112,7 @@ main(argc, argv)
int ch;
int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
ino_t maxino;
time_t tnow;
time_t tnow, date;
int dirlist;
char *toplevel;
int just_estimate = 0;
@ -352,23 +353,6 @@ main(argc, argv)
}
(void)strncpy(spcl.c_label, "none", sizeof(spcl.c_label) - 1);
(void)gethostname(spcl.c_host, NAMELEN);
spcl.c_level = level - '0';
spcl.c_type = TS_TAPE;
if (!Tflag)
getdumptime(); /* /etc/dumpdates snarfed */
msg("Date of this level %c dump: %s", level,
spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
msg("Date of last level %c dump: %s", lastlevel,
spcl.c_ddate == 0 ? "the epoch\n" : ctime(&spcl.c_ddate));
msg("Dumping ");
if (dt != NULL && dirlist != 0)
msgtail("a subset of ");
msgtail("%s (%s) ", disk, spcl.c_filesys);
if (host)
msgtail("to %s on host %s\n", tape, host);
else
msgtail("to %s\n", tape);
if ((diskfd = open(disk, O_RDONLY)) < 0) {
msg("Cannot open %s\n", disk);
@ -378,7 +362,34 @@ main(argc, argv)
sblock = (struct fs *)sblock_buf;
bread(SBOFF, (char *) sblock, SBSIZE);
if (sblock->fs_magic != FS_MAGIC)
quit("bad sblock magic number\n");
if (sblock->fs_magic == bswap32(FS_MAGIC)) {
ffs_sb_swap(sblock, sblock, 0);
needswap = 1;
} else
quit("bad sblock magic number\n");
spcl.c_level = iswap32(level - '0');
spcl.c_type = iswap32(TS_TAPE);
spcl.c_date = iswap32(spcl.c_date);
spcl.c_ddate = iswap32(spcl.c_ddate);
if (!Tflag)
getdumptime(); /* /etc/dumpdates snarfed */
date = iswap32(spcl.c_date);
msg("Date of this level %c dump: %s", level,
spcl.c_date == 0 ? "the epoch\n" : ctime(&date));
date = iswap32(spcl.c_ddate);
msg("Date of last level %c dump: %s", lastlevel,
spcl.c_ddate == 0 ? "the epoch\n" : ctime(&date));
msg("Dumping ");
if (dt != NULL && dirlist != 0)
msgtail("a subset of ");
msgtail("%s (%s) ", disk, spcl.c_filesys);
if (host)
msgtail("to %s on host %s\n", tape, host);
else
msgtail("to %s\n", tape);
dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1);
dev_bshift = ffs(dev_bsize) - 1;
if (dev_bsize != (1 << dev_bshift))
@ -388,7 +399,7 @@ main(argc, argv)
quit("TP_BSIZE (%d) is not a power of 2", TP_BSIZE);
#ifdef FS_44INODEFMT
if (sblock->fs_inodefmt >= FS_44INODEFMT)
spcl.c_flags |= DR_NEWINODEFMT;
spcl.c_flags = iswap32(iswap32(spcl.c_flags) | DR_NEWINODEFMT);
#endif
maxino = sblock->fs_ipg * sblock->fs_ncg;
mapsize = roundup(howmany(maxino, NBBY), TP_BSIZE);
@ -397,7 +408,7 @@ main(argc, argv)
dumpinomap = (char *)calloc((unsigned) mapsize, sizeof(char));
tapesize = 3 * (howmany(mapsize * sizeof(char), TP_BSIZE) + 1);
nonodump = spcl.c_level < honorlevel;
nonodump = iswap32(spcl.c_level) < honorlevel;
(void)signal(SIGINFO, statussig);
@ -511,18 +522,19 @@ main(argc, argv)
(void)dumpino(dp, ino);
}
spcl.c_type = TS_END;
spcl.c_type = iswap32(TS_END);
for (i = 0; i < ntrec; i++)
writeheader(maxino - 1);
if (pipeout)
msg("%ld tape blocks\n",spcl.c_tapea);
msg("%ld tape blocks\n",iswap32(spcl.c_tapea));
else
msg("%ld tape blocks on %d volume%s\n",
spcl.c_tapea, spcl.c_volume,
(spcl.c_volume == 1) ? "" : "s");
iswap32(spcl.c_tapea), iswap32(spcl.c_volume),
(iswap32(spcl.c_volume) == 1) ? "" : "s");
tnow = do_stats();
date = iswap32(spcl.c_date);
msg("Date of this level %c dump: %s", level,
spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date));
spcl.c_date == 0 ? "the epoch\n" : ctime(&date));
msg("Date this dump completed: %s", ctime(&tnow));
msg("Average transfer rate: %ld KB/s\n", xferrate / tapeno);
putdumptime();

View File

@ -1,4 +1,4 @@
/* $NetBSD: tape.c,v 1.15 1997/09/16 08:37:01 mrg Exp $ */
/* $NetBSD: tape.c,v 1.16 1998/03/18 16:54:56 bouyer Exp $ */
/*-
* Copyright (c) 1980, 1991, 1993
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)tape.c 8.4 (Berkeley) 5/1/95";
#else
__RCSID("$NetBSD: tape.c,v 1.15 1997/09/16 08:37:01 mrg Exp $");
__RCSID("$NetBSD: tape.c,v 1.16 1998/03/18 16:54:56 bouyer Exp $");
#endif
#endif /* not lint */
@ -188,9 +188,9 @@ writerec(dp, isspcl)
slp->req[trecno].count = 1;
*(union u_spcl *)(*(nextblock)++) = *(union u_spcl *)dp;
if (isspcl)
lastspclrec = spcl.c_tapea;
lastspclrec = iswap32(spcl.c_tapea);
trecno++;
spcl.c_tapea++;
spcl.c_tapea = iswap32(iswap32(spcl.c_tapea) +1);
if (trecno >= ntrec)
flushtape();
}
@ -208,7 +208,7 @@ dumpblock(blkno, size)
slp->req[trecno].dblk = dblkno;
slp->req[trecno].count = avail;
trecno += avail;
spcl.c_tapea += avail;
spcl.c_tapea = iswap32(iswap32(spcl.c_tapea) + avail);
if (trecno >= ntrec)
flushtape();
dblkno += avail << (tp_bshift - dev_bshift);
@ -260,7 +260,7 @@ do_stats()
(void)time(&tnow);
ttaken = tnow - tstart_volume;
blocks = spcl.c_tapea - tapea_volume;
blocks = iswap32(spcl.c_tapea) - tapea_volume;
msg("Volume %d completed at: %s", tapeno, ctime(&tnow));
if (ttaken > 0) {
msg("Volume %d took %d:%02d:%02d\n", tapeno,
@ -292,7 +292,7 @@ statussig(notused)
(void)snprintf(msgbuf, sizeof(msgbuf),
"%3.2f%% done at %ld KB/s, finished in %d:%02d\n",
(blockswritten * 100.0) / tapesize,
(long)((spcl.c_tapea - tapea_volume) / (tnow - tstart_volume)),
(long)((iswap32(spcl.c_tapea) - tapea_volume) / (tnow - tstart_volume)),
(int)(deltat / 3600), (int)((deltat % 3600) / 60));
write(STDERR_FILENO, msgbuf, strlen(msgbuf));
}
@ -352,13 +352,13 @@ flushtape()
}
blks = 0;
if (spcl.c_type != TS_END) {
for (i = 0; i < spcl.c_count; i++)
if (iswap32(spcl.c_type) != TS_END) {
for (i = 0; i < iswap32(spcl.c_count); i++)
if (spcl.c_addr[i] != 0)
blks++;
}
slp->count = lastspclrec + blks + 1 - spcl.c_tapea;
slp->tapea = spcl.c_tapea;
slp->count = lastspclrec + blks + 1 - iswap32(spcl.c_tapea);
slp->tapea = iswap32(spcl.c_tapea);
slp->firstrec = lastfirstrec + ntrec;
slp->inode = curino;
nextblock = slp->tblock;
@ -491,10 +491,10 @@ rollforward()
q->count = 1;
trecno = 0;
nextblock = tslp->tblock;
savedtapea = spcl.c_tapea;
spcl.c_tapea = slp->tapea;
savedtapea = iswap32(spcl.c_tapea);
spcl.c_tapea = iswap32(slp->tapea);
startnewtape(0);
spcl.c_tapea = savedtapea;
spcl.c_tapea = iswap32(savedtapea);
lastspclrec = savedtapea - 1;
}
size = (char *)ntb - (char *)q;
@ -577,7 +577,7 @@ startnewtape(top)
interrupt_save = signal(SIGINT, SIG_IGN);
parentpid = getpid();
tapea_volume = spcl.c_tapea;
tapea_volume = iswap32(spcl.c_tapea);
(void)time(&tstart_volume);
restore_check_point:
@ -680,17 +680,17 @@ restore_check_point:
blocksthisvol = 0;
if (top)
newtape++; /* new tape signal */
spcl.c_count = slp->count;
spcl.c_count = iswap32(slp->count);
/*
* measure firstrec in TP_BSIZE units since restore doesn't
* know the correct ntrec value...
*/
spcl.c_firstrec = slp->firstrec;
spcl.c_volume++;
spcl.c_type = TS_TAPE;
spcl.c_flags |= DR_NEWHEADER;
spcl.c_firstrec = iswap32(slp->firstrec);
spcl.c_volume = iswap32(iswap32(spcl.c_volume) + 1);
spcl.c_type = iswap32(TS_TAPE);
spcl.c_flags = iswap32(iswap32(spcl.c_flags) | DR_NEWHEADER);
writeheader((ino_t)slp->inode);
spcl.c_flags &=~ DR_NEWHEADER;
spcl.c_flags = iswap32(iswap32(spcl.c_flags) & ~ DR_NEWHEADER);
msg("Volume %d started at: %s", tapeno, ctime(&tstart_volume));
if (tapeno > 1)
msg("Volume %d begins with blocks from inode %d\n",

View File

@ -1,4 +1,4 @@
/* $NetBSD: traverse.c,v 1.19 1997/09/16 06:41:23 lukem Exp $ */
/* $NetBSD: traverse.c,v 1.20 1998/03/18 16:54:57 bouyer Exp $ */
/*-
* Copyright (c) 1980, 1988, 1991, 1993
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)traverse.c 8.7 (Berkeley) 6/15/95";
#else
__RCSID("$NetBSD: traverse.c,v 1.19 1997/09/16 06:41:23 lukem Exp $");
__RCSID("$NetBSD: traverse.c,v 1.20 1998/03/18 16:54:57 bouyer Exp $");
#endif
#endif /* not lint */
@ -55,6 +55,7 @@ __RCSID("$NetBSD: traverse.c,v 1.19 1997/09/16 06:41:23 lukem Exp $");
#include <ufs/ufs/dir.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <ufs/ffs/ffs_extern.h>
#endif
#include <protocols/dumprestore.h>
@ -130,10 +131,10 @@ blockest(dp)
/* The WANTTODUMP macro decides whether a file should be dumped. */
#ifdef UF_NODUMP
#define WANTTODUMP(dp) \
(CHANGEDSINCE(dp, spcl.c_ddate) && \
(CHANGEDSINCE(dp, iswap32(spcl.c_ddate)) && \
(nonodump || ((dp)->di_flags & UF_NODUMP) != UF_NODUMP))
#else
#define WANTTODUMP(dp) CHANGEDSINCE(dp, spcl.c_ddate)
#define WANTTODUMP(dp) CHANGEDSINCE(dp, iswap32(spcl.c_ddate))
#endif
/*
@ -300,7 +301,7 @@ mapdirs(maxino, tapesize)
filesize = dp->di_size;
for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) {
if (dp->di_db[i] != 0)
ret |= searchdir(ino, dp->di_db[i],
ret |= searchdir(ino, iswap32(dp->di_db[i]),
(long)dblksize(sblock, dp, i),
filesize);
if (ret & HASDUMPEDFILE)
@ -345,12 +346,13 @@ dirindir(ino, blkno, ind_level, filesize)
int i;
daddr_t idblk[MAXNINDIR];
bread(fsbtodb(sblock, blkno), (char *)idblk, (int)sblock->fs_bsize);
bread(fsbtodb(sblock, iswap32(blkno)), (char *)idblk,
(int)sblock->fs_bsize);
if (ind_level <= 0) {
for (i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
blkno = idblk[i];
if (blkno != 0)
ret |= searchdir(ino, blkno, sblock->fs_bsize,
ret |= searchdir(ino, iswap32(blkno), sblock->fs_bsize,
*filesize);
if (ret & HASDUMPEDFILE)
*filesize = 0;
@ -393,7 +395,7 @@ searchdir(ino, blkno, size, filesize)
msg("corrupted directory, inumber %d\n", ino);
break;
}
loc += dp->d_reclen;
loc += iswap16(dp->d_reclen);
if (dp->d_ino == 0)
continue;
if (dp->d_name[0] == '.') {
@ -402,12 +404,12 @@ searchdir(ino, blkno, size, filesize)
if (dp->d_name[1] == '.' && dp->d_name[2] == '\0')
continue;
}
if (TSTINO(dp->d_ino, dumpinomap)) {
if (TSTINO(iswap32(dp->d_ino), dumpinomap)) {
ret |= HASDUMPEDFILE;
if (ret & HASSUBDIRS)
break;
}
if (TSTINO(dp->d_ino, dumpdirmap)) {
if (TSTINO(iswap32(dp->d_ino), dumpdirmap)) {
ret |= HASSUBDIRS;
if (ret & HASDUMPEDFILE)
break;
@ -435,8 +437,11 @@ dumpino(dp, ino)
dumpmap(dumpinomap, TS_BITS, ino);
}
CLRINO(ino, dumpinomap);
spcl.c_dinode = *dp;
spcl.c_type = TS_INODE;
if (needswap)
ffs_dinode_swap(dp, &spcl.c_dinode);
else
spcl.c_dinode = *dp;
spcl.c_type = iswap32(TS_INODE);
spcl.c_count = 0;
switch (dp->di_mode & IFMT) {
@ -458,7 +463,7 @@ dumpino(dp, ino)
dp->di_blocks == 0) {
#endif
spcl.c_addr[0] = 1;
spcl.c_count = 1;
spcl.c_count = iswap32(1);
writeheader(ino);
memmove(buf, dp->di_shortlink, (u_long)dp->di_size);
buf[dp->di_size] = '\0';
@ -512,7 +517,8 @@ dmpindir(ino, blk, ind_level, size)
daddr_t idblk[MAXNINDIR];
if (blk != 0)
bread(fsbtodb(sblock, blk), (char *)idblk, (int) sblock->fs_bsize);
bread(fsbtodb(sblock, iswap32(blk)), (char *)idblk,
(int) sblock->fs_bsize);
else
memset(idblk, 0, (int)sblock->fs_bsize);
if (ind_level <= 0) {
@ -556,16 +562,16 @@ blksout(blkp, frags, ino)
spcl.c_addr[j - i] = 1;
else
spcl.c_addr[j - i] = 0;
spcl.c_count = count - i;
spcl.c_count = iswap32(count - i);
writeheader(ino);
bp = &blkp[i / tbperdb];
for (j = i; j < count; j += tbperdb, bp++)
if (*bp != 0)
if (j + tbperdb <= count)
dumpblock(*bp, (int)sblock->fs_bsize);
dumpblock(iswap32(*bp), (int)sblock->fs_bsize);
else
dumpblock(*bp, (count - j) * TP_BSIZE);
spcl.c_type = TS_ADDR;
dumpblock(iswap32(*bp), (count - j) * TP_BSIZE);
spcl.c_type = iswap32(TS_ADDR);
}
}
@ -581,10 +587,10 @@ dumpmap(map, type, ino)
int i;
char *cp;
spcl.c_type = type;
spcl.c_count = howmany(mapsize * sizeof(char), TP_BSIZE);
spcl.c_type = iswap32(type);
spcl.c_count = iswap32(howmany(mapsize * sizeof(char), TP_BSIZE));
writeheader(ino);
for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
for (i = 0, cp = map; i < iswap32(spcl.c_count); i++, cp += TP_BSIZE)
writerec(cp, 0);
}
@ -597,19 +603,19 @@ writeheader(ino)
{
int32_t sum, cnt, *lp;
spcl.c_inumber = ino;
spcl.c_magic = NFS_MAGIC;
spcl.c_inumber = iswap32(ino);
spcl.c_magic = iswap32(NFS_MAGIC);
spcl.c_checksum = 0;
lp = (int32_t *)&spcl;
sum = 0;
cnt = sizeof(union u_spcl) / (4 * sizeof(int32_t));
while (--cnt >= 0) {
sum += *lp++;
sum += *lp++;
sum += *lp++;
sum += *lp++;
sum += iswap32(*lp++);
sum += iswap32(*lp++);
sum += iswap32(*lp++);
sum += iswap32(*lp++);
}
spcl.c_checksum = CHECKSUM - sum;
spcl.c_checksum = iswap32(CHECKSUM - sum);
writerec((char *)&spcl, 1);
}
@ -619,12 +625,16 @@ getino(inum)
{
static daddr_t minino, maxino;
static struct dinode inoblock[MAXINOPB];
int i;
curino = inum;
if (inum >= minino && inum < maxino)
return (&inoblock[inum - minino]);
bread(fsbtodb(sblock, ino_to_fsba(sblock, inum)), (char *)inoblock,
(int)sblock->fs_bsize);
if (needswap)
for (i = 0; i < MAXINOPB; i++)
ffs_dinode_swap(&inoblock[i], &inoblock[i]);
minino = inum - (inum % INOPB(sblock));
maxino = minino + INOPB(sblock);
return (&inoblock[inum - minino]);