Add scan_ffs(8) from OpenBSD, it was modified to support FFSv2
for NetBSD (with different blocksizes). Utility to find FFSv1 and FFSv2 partitions on disks, useful to recover lost disklabels. Reviewed by christos.
This commit is contained in:
parent
ec4bb683de
commit
b67b8509c2
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.555 2005/06/07 14:27:42 is Exp $
|
||||
# $NetBSD: mi,v 1.556 2005/06/15 18:06:19 xtraeme Exp $
|
||||
. base-sys-root
|
||||
./altroot base-sys-root
|
||||
./bin base-sys-root
|
||||
|
@ -191,6 +191,7 @@
|
|||
./sbin/rrestore base-netutil-root
|
||||
./sbin/rtsol base-netutil-root use_inet6
|
||||
./sbin/savecore base-sysutil-root
|
||||
./sbin/scan_ffs base-sysutil-root
|
||||
./sbin/scsictl base-sysutil-root
|
||||
./sbin/setkey base-netutil-root
|
||||
./sbin/shutdown base-sysutil-root
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.791 2005/05/31 11:39:03 christos Exp $
|
||||
# $NetBSD: mi,v 1.792 2005/06/15 18:06:19 xtraeme Exp $
|
||||
./etc/mtree/set.man man-sys-root
|
||||
./usr/share/info/am-utils.info man-amd-info info
|
||||
./usr/share/info/as.info man-computil-info bfd,info
|
||||
|
@ -2102,6 +2102,7 @@
|
|||
./usr/share/man/cat8/savecore.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/sbmips/MAKEDEV.0 man-obsolete obsolete
|
||||
./usr/share/man/cat8/sbmips/makedev.0 man-obsolete obsolete
|
||||
./usr/share/man/cat8/scan_ffs.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/scsictl.0 man-sysutil-catman .cat
|
||||
./usr/share/man/cat8/sendmail.0 man-sendmail-catman sendmail,.cat
|
||||
./usr/share/man/cat8/sesd.0 man-sysutil-catman .cat
|
||||
|
@ -4334,6 +4335,7 @@
|
|||
./usr/share/man/man8/savecore.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/sbmips/MAKEDEV.8 man-obsolete obsolete
|
||||
./usr/share/man/man8/sbmips/makedev.8 man-obsolete obsolete
|
||||
./usr/share/man/man8/scan_ffs.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/scsictl.8 man-sysutil-man .man
|
||||
./usr/share/man/man8/sendmail.8 man-sendmail-man sendmail,.man
|
||||
./usr/share/man/man8/sesd.8 man-sysutil-man .man
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.93 2005/05/01 07:26:29 lukem Exp $
|
||||
# $NetBSD: Makefile,v 1.94 2005/06/15 18:06:19 xtraeme Exp $
|
||||
# @(#)Makefile 8.5 (Berkeley) 3/31/94
|
||||
|
||||
# Not ported: XNSrouted enpload scsiformat startslip
|
||||
|
@ -10,8 +10,8 @@ SUBDIR= atactl badsect bim brconfig ccdconfig disklabel dkctl dmesg \
|
|||
drvctl edlabel fastboot fdisk fsck fsirand ifconfig init ldconfig \
|
||||
lmcctl mbrlabel mknod modload modunload mount newbtconf nologin \
|
||||
pdisk ping pppoectl raidctl reboot rcorder rndctl route routed \
|
||||
savecore scsictl shutdown slattach swapctl sysctl ttyflags umount \
|
||||
veriexecctl vinum wdogctl wsconsctl
|
||||
savecore scan_ffs scsictl shutdown slattach swapctl sysctl ttyflags \
|
||||
umount veriexecctl vinum wdogctl wsconsctl
|
||||
|
||||
# support for various file systems
|
||||
SUBDIR+= fsck_ext2fs
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
# $NetBSD: Makefile,v 1.1 2005/06/15 18:06:19 xtraeme Exp $
|
||||
|
||||
PROG= scan_ffs
|
||||
SRCS= scan_ffs.c
|
||||
|
||||
MAN= scan_ffs.8
|
||||
|
||||
WARNS= 3
|
||||
LDADD= -lutil
|
||||
DPADD= ${LIBUTIL}
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -0,0 +1,91 @@
|
|||
.\" $NetBSD: scan_ffs.8,v 1.1 2005/06/15 18:06:19 xtraeme Exp $
|
||||
.\" OpenBSD: scan_ffs.8,v 1.13 2004/12/14 00:04:21 jmc Exp
|
||||
.\"
|
||||
.\" Copyright (c) 2005 Juan Romero Pardines
|
||||
.\" Copyright (c) 1997 Niklas Hallqvist, Tobias Weingartner
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" .TH scanffs 8
|
||||
.Dd Juny 7, 2005
|
||||
.Dt SCANFFS 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm scanffs
|
||||
.Nd finding FFSv1/FFSv2 partitions on a disk
|
||||
.Sh SYNOPSIS
|
||||
.Nm scanffs
|
||||
.Op Fl lv
|
||||
.Op Fl s Ar start
|
||||
.Op Fl e Ar end
|
||||
.Ar device
|
||||
.Sh DESCRIPTION
|
||||
This program will take a raw disk device that covers the whole disk,
|
||||
and will find all possible FFSv1/FFSv2 partitions with different block
|
||||
sizes on the disk.
|
||||
It will show the filesystem type (FFSv1 or FFSv2), size and offset.
|
||||
Also it has an option to show the values with a disklabel-alike
|
||||
output.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl l
|
||||
This will make
|
||||
.Nm
|
||||
print out a string looking much like the input to disklabel.
|
||||
With a little massaging, this output can usually be used in the disklabel edit.
|
||||
.Pp
|
||||
.It Fl v
|
||||
Tell
|
||||
.Nm
|
||||
to be verbose about what it is doing, and what it has found.
|
||||
.Pp
|
||||
.It Fl s Ar start
|
||||
Tell
|
||||
.Nm
|
||||
where to start searching for filesystems.
|
||||
This makes it easier to skip swap
|
||||
partitions, or other large non-UFS/FFS partitions.
|
||||
.Pp
|
||||
.It Fl e Ar end
|
||||
Ditto for telling
|
||||
.Nm
|
||||
where to stop.
|
||||
It will default to max sectors on the disk if it wasn't specified.
|
||||
.Pp
|
||||
.It Ar device
|
||||
This specifies which device
|
||||
.Nm
|
||||
should use to scan for filesystems.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr disklabel 8
|
||||
.Sh HISTORY
|
||||
The scan_ffs program first appeared in OpenBSD 2.3.
|
||||
.Sh AUTHORS
|
||||
Niklas Hallqvist and Tobias Weingartner for the OpenBSD Project.
|
||||
.Pp
|
||||
Juan Romero Pardines for the NetBSD Project.
|
||||
.Sh BUGS
|
||||
Currently it won't find FFSv1 partitions with fragsize/blocksize
|
||||
greater than 2048/16384, and FFSv2 partitions with fragsize/blocksize
|
||||
greater than 8192/65536.
|
|
@ -0,0 +1,288 @@
|
|||
/* $NetBSD: scan_ffs.c,v 1.1 2005/06/15 18:06:19 xtraeme Exp $ */
|
||||
/* $OpenBSD: scan_ffs.c,v 1.11 2004/02/16 19:13:03 deraadt Exp$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005 Juan Romero Pardines
|
||||
* Copyright (c) 1998 Niklas Hallqvist, Tobias Weingartner
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Currently it can detect:
|
||||
* o FFSv1 with fragsize/blocksize: 512/4096, 1024/8192, 2048/16384.
|
||||
* o FFSv2 with fragsize/blocksize: 512/4096, 1024/8192, 2048/16384,
|
||||
* 4096/32768, 8192/65536.
|
||||
* TODO:
|
||||
* o Detect FFSv1 partitions with fsize/bsize > 2048/16384.
|
||||
* o Detect FFSv2 partitions with fsize/bsize > 8192/65536.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: scan_ffs.c,v 1.1 2005/06/15 18:06:19 xtraeme Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/dkio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <util.h>
|
||||
|
||||
enum { NADA, VERBOSE, LABELS };
|
||||
|
||||
#define SBCOUNT 64 /* XXX should be configurable */
|
||||
|
||||
static void printpart(int, int, int);
|
||||
static void ufsmagic(int);
|
||||
static void usage(void) __attribute__((__noreturn__));
|
||||
static int checkfstype(void);
|
||||
static int ufsscan(int, daddr_t, daddr_t, int);
|
||||
|
||||
static char lastmount[MAXMNTLEN];
|
||||
static char device[MAXPATHLEN];
|
||||
static const char *fstype = NULL;
|
||||
|
||||
static int eflag = 0;
|
||||
static int flags = 0;
|
||||
|
||||
static daddr_t blk, lastblk;
|
||||
|
||||
static struct fs *sb;
|
||||
|
||||
static int
|
||||
checkfstype(void)
|
||||
{
|
||||
switch (sb->fs_magic) {
|
||||
case FS_UFS1_MAGIC:
|
||||
case FS_UFS1_MAGIC_SWAPPED:
|
||||
sb->fs_size = sb->fs_old_size;
|
||||
fstype = "FFSv1";
|
||||
return 1;
|
||||
case FS_UFS2_MAGIC:
|
||||
case FS_UFS2_MAGIC_SWAPPED:
|
||||
fstype = "FFSv2";
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
printpart(int flag, int ffsize, int n)
|
||||
{
|
||||
|
||||
int fsrv = checkfstype();
|
||||
|
||||
if (flag == VERBOSE) {
|
||||
(void)printf("block: %" PRIu64" "
|
||||
"id %x,%x size %" PRIu64"\n",
|
||||
blk + (n / 512), sb->fs_id[0],
|
||||
sb->fs_id[1], sb->fs_size);
|
||||
} else if (flag == LABELS) {
|
||||
(void)printf("X: %9" PRIu64 "",
|
||||
(uint64_t)((off_t)sb->fs_size * sb->fs_fsize / 512));
|
||||
if (fsrv == 1) /* FFSv1 */
|
||||
(void)printf(" %9" PRIu64 "",
|
||||
blk + (n / 512)-(2 * SBLOCKSIZE / 512));
|
||||
else if (fsrv == 2) /* FFSv2 */
|
||||
(void)printf(" %9" PRIu64 "",
|
||||
blk + (n / 512)-(ffsize * SBLOCKSIZE / 512 + 128));
|
||||
(void)printf(" 4.2BSD %6d %5d%4d # %s [%s]\n",
|
||||
sb->fs_fsize, sb->fs_bsize,
|
||||
sb->fs_old_cpg, lastmount, fstype);
|
||||
} else {
|
||||
printf("%s ", fstype);
|
||||
if (fsrv == 1) /* FFSv1 */
|
||||
(void)printf("at %" PRIu64 "",
|
||||
blk + (n / 512) - (2 * SBLOCKSIZE / 512));
|
||||
else if (fsrv == 2) /* FFSv2 */
|
||||
(void)printf("at %" PRIu64 "",
|
||||
blk + (n / 512) - (ffsize * SBLOCKSIZE / 512 + 128));
|
||||
(void)printf(" size %" PRIu64 ", last mounted on %s\n",
|
||||
(uint64_t)((off_t)sb->fs_size * sb->fs_fsize / 512),
|
||||
lastmount);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ufsmagic(int n)
|
||||
{
|
||||
int fsrv = checkfstype();
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* It cannot find FFSv1 partitions with fsize/bsize > 2048/16384,
|
||||
* same problem found in the original program that comes from
|
||||
* OpenBSD (scan_ffs(1)).
|
||||
*/
|
||||
if (flags & VERBOSE)
|
||||
printpart(VERBOSE, NADA, n);
|
||||
if (fsrv == 1) { /* FFSv1 */
|
||||
if (((blk + (n / 512)) - lastblk) == (SBLOCKSIZE / 512)) {
|
||||
if (flags & LABELS)
|
||||
printpart(LABELS, NADA, n);
|
||||
else
|
||||
printpart(NADA, NADA, n);
|
||||
}
|
||||
} else if (fsrv == 2) { /* FFSv2 */
|
||||
/*
|
||||
* That checks for FFSv2 partitions with fragsize/blocksize:
|
||||
* 512/4096, 1024/8192, 2048/16384, 4096/32768 and 8192/65536.
|
||||
* Really enough for now.
|
||||
*/
|
||||
if (((blk + (n / 512)) - lastblk) == (SBLOCKSIZE / 512)) {
|
||||
if (flags & LABELS)
|
||||
printpart(LABELS, 1, n);
|
||||
else
|
||||
printpart(NADA, 1, n);
|
||||
} else if (((blk + (n / 512)) - lastblk) == (2 * SBLOCKSIZE / 512)) {
|
||||
if (flags & LABELS)
|
||||
printpart(LABELS, 2, n);
|
||||
else
|
||||
printpart(NADA, 2, n);
|
||||
} else if (((blk + (n / 512)) - lastblk) == (4 * SBLOCKSIZE / 512)) {
|
||||
if (flags & LABELS)
|
||||
printpart(LABELS, 4, n);
|
||||
else
|
||||
printpart(NADA, 4, n);
|
||||
} else if (((blk + (n / 512)) - lastblk) == (8 * SBLOCKSIZE / 512)) {
|
||||
if (flags & LABELS)
|
||||
printpart(LABELS, 8, n);
|
||||
else
|
||||
printpart(NADA, 8, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ufsscan(int fd, daddr_t beg, daddr_t end, int fflags)
|
||||
{
|
||||
|
||||
u_int8_t buf[SBLOCKSIZE * SBCOUNT];
|
||||
int n, fsrv;
|
||||
|
||||
lastblk = -1;
|
||||
memset(lastmount, 0, MAXMNTLEN);
|
||||
|
||||
if (fflags & LABELS)
|
||||
(void)printf("# size offset fstype [fsize bsize cpg]\n");
|
||||
|
||||
for (blk = beg; blk <= ((end < 0) ? blk: end);
|
||||
blk += (SBCOUNT * SBLOCKSIZE / 512)) {
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if (lseek(fd, (off_t)blk * 512, SEEK_SET) < 0)
|
||||
err(1, "lseek");
|
||||
/* NOTREACHED */
|
||||
|
||||
if (read(fd, buf, sizeof(buf)) < 0)
|
||||
err(1, "read");
|
||||
/* NOTREACHED */
|
||||
|
||||
for (n = 0; n < (SBLOCKSIZE * SBCOUNT); n += 512) {
|
||||
sb = (struct fs*)(&buf[n]);
|
||||
fsrv = checkfstype();
|
||||
|
||||
if (fsrv >= 1) { /* found! */
|
||||
ufsmagic(n);
|
||||
/* Update last potential FS SBs seen */
|
||||
lastblk = blk + (n / 512);
|
||||
memcpy(lastmount, sb->fs_fsmnt, MAXMNTLEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s [-lv] [-s start] [-e end] device", getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch, fd;
|
||||
daddr_t end = -1, beg = 0;
|
||||
struct disklabel dl;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
while ((ch = getopt(argc, argv, "e:ls:v")) != -1)
|
||||
switch(ch) {
|
||||
case 'e':
|
||||
eflag = 1;
|
||||
end = atoi(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
flags |= LABELS;
|
||||
break;
|
||||
case 's':
|
||||
beg = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
flags |= VERBOSE;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1)
|
||||
usage();
|
||||
|
||||
fd = opendisk(argv[0], O_RDONLY, device, sizeof(device), 0);
|
||||
|
||||
if (fd < 0)
|
||||
err(1, "%s", device);
|
||||
/* NOTREACHED */
|
||||
|
||||
if (ioctl(fd, DIOCGDINFO, &dl) == -1)
|
||||
warn("couldn't retrieve disklabel.\n");
|
||||
else {
|
||||
(void)printf("Disk: %s\n", dl.d_typename);
|
||||
(void)printf("Total sectors on disk: %" PRIu32 "\n\n",
|
||||
dl.d_secperunit);
|
||||
}
|
||||
|
||||
if (!eflag)
|
||||
end = dl.d_secperunit; /* default to max sectors */
|
||||
|
||||
return (ufsscan(fd, beg, end, flags));
|
||||
}
|
Loading…
Reference in New Issue