Add a utility to allow access to the partitions of a

MBR labeled disk (i.e. a disk partitioned by fdisk)
on any platform (including extended partitions).
This commit is contained in:
ws 1998-11-16 18:44:25 +00:00
parent eeb9152be3
commit 2cf75c4c03
5 changed files with 411 additions and 2 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.97 1998/11/02 03:32:03 kim Exp $
# $NetBSD: Makefile,v 1.98 1998/11/16 18:44:25 ws Exp $
# from: @(#)Makefile 5.20 (Berkeley) 6/12/93
#
# not yet done: catman
@ -10,7 +10,7 @@ SUBDIR= ac accton amd apm apmd arp bad144 bootp \
chown chroot chrtbl config cron dbsym dev_mkdb \
dhcp diskpart dumpfs dumplfs edquota eeprom eshconfig greconfig \
grfconfig grfinfo gspa hilinfo inetd iostat ipf iteconfig kgmon \
kvm_mkdb lastlogin lpr map-mbone mdconfig mdsetimage \
kvm_mkdb lastlogin lpr map-mbone mbrlabel mdconfig mdsetimage \
mopd mountd mrinfo mrouted mtrace mtree \
netgroup_mkdb nfsd nfsiod pkg_install portmap pppd pstat \
pwd_mkdb quot quotacheck quotaon rarpd rbootd rdate \

View File

@ -0,0 +1,11 @@
# $NetBSD: Makefile,v 1.1 1998/11/16 18:44:25 ws Exp $
DISKLABELPATH= ${.CURDIR}/../../sbin/disklabel
PROG= mbrlabel
SRCS= mbrlabel.c dkcksum.c
CPPFLAGS+= -I${DISKLABELPATH}
MAN= mbrlabel.8
LDADD+= -lutil
.PATH: ${DISKLABELPATH}
.include <bsd.prog.mk>

View File

@ -0,0 +1,93 @@
.\" Copyright (C) 1998 Wolfgang Solfrank.
.\" Copyright (C) 1998 TooLs GmbH.
.\" 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.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by TooLs GmbH.
.\" 4. The name of TooLs GmbH may not be used to endorse or promote products
.\" derived from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
.\"
.\" $NetBSD: mbrlabel.8,v 1.1 1998/11/16 18:44:26 ws Exp $
.\"
.Dd November 15, 1998
.Dt MBRLABEL 8
.Os NetBSD 1.4
.Sh NAME
.Nm mbrlabel
.Nd generate incore disklabel from MBR label(s) as used on DOS disks
.Sh SYNOPSIS
.Nm
.Ar device
.Sh DESCRIPTION
.Nm
is used to generate an incore disklabel from the MBR label(s) found
on disks that were previously used on DOS/Windows systems (or
other MBR using systems).
.Pp
The
.Nm
utility generates an incore label from the MBR contained in the very first
block of the disk, then walking through every extended partition found
and generating additional partition entries for the disk from the
MBRs found in those extended partitions.
The partitions are sequentially entered into the constructed disklabel
as partitions
.Em a , b
and so on until no more MBR partitions are found or all available
entries in the disklabel are used up.
The raw partition (typically partition
.Em c ,
but
.Em d
on i386) is left alone during this process.
The resulting disklabel is then placed as the incore disklabel for
this disk.
.Sh BUGS
Due to the way disk drivers currently work in
.Nx ,
any incore disklabel is forgotten whenever the last partition of a
disk is closed.
Since typically you wouldn't have a partition open on a disk while
running
.Nm
this lossage will most likely happen, if
.Nm
is used naively.
.Pp
The workaround until the disk drivers are fixed is to keep the
raw partition open until you access the partition(s) of the
disk via e.g.
.Xr mount 8 .
.Pp
E.g. you could use
.Dl sleep 100</dev/rsd0c &
.Dl mbrlabel sd0
.Dl mount -t msdos /dev/sd0a /msdos
to mount a disk containing only one DOS partition.
.Sh SEE ALSO
.Xr disklabel 8
.Sh HISTORY
The
.Nm
command appeared in
.Nx 1.4 .

View File

@ -0,0 +1,238 @@
/* $NetBSD: mbrlabel.c,v 1.1 1998/11/16 18:44:26 ws Exp $ */
/*
* Copyright (C) 1998 Wolfgang Solfrank.
* Copyright (C) 1998 TooLs GmbH.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by TooLs GmbH.
* 4. The name of TooLs GmbH may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
*/
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mbrlabel.c,v 1.1 1998/11/16 18:44:26 ws Exp $");
#endif /* not lint */
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <util.h>
#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/ioctl.h>
#include "mbrlabel.h"
#include "dkcksum.h"
#define FIRSTPART 0
int main __P((int, char **));
void usage __P((void));
void getlabel __P((int));
void setlabel __P((int));
int getparts __P((int, int, u_int32_t));
int nbsdtype __P((int));
u_int32_t getlong __P((void *p));
struct disklabel label;
void
getlabel(sd)
int sd;
{
struct partition save;
if (ioctl(sd, DIOCGDINFO, &label) < 0) {
perror("get label");
exit(1);
}
save = label.d_partitions[RAW_PART];
memset(label.d_partitions, 0, sizeof label.d_partitions);
label.d_partitions[RAW_PART] = save;
/*
* Some ports seem to not set the number of partitions
* correctly, albeit they seem to set the raw partiton ok!
*/
if (label.d_npartitions <= RAW_PART)
label.d_npartitions = RAW_PART + 1;
}
void
setlabel(sd)
int sd;
{
label.d_checksum = 0;
label.d_checksum = dkcksum(&label);
if (ioctl(sd, DIOCSDINFO, &label) < 0) {
perror("set label");
exit(1);
}
}
static struct typetab {
int mbrtype;
int nbsdtype;
} typetable[] = {
{ MBR_NETBSD, FS_BSDFFS },
{ MBR_386BSD, FS_BSDFFS },
{ MBR_FAT12, FS_MSDOS },
{ MBR_FAT16S, FS_MSDOS },
{ MBR_FAT16B, FS_MSDOS },
{ MBR_FAT32, FS_MSDOS },
{ MBR_FAT32L, FS_MSDOS },
{ MBR_FAT16L, FS_MSDOS },
{ MBR_LNXEXT2, FS_EX2FS },
{ 0, 0 }
};
int
nbsdtype(type)
int type;
{
struct typetab *tt;
for (tt = typetable; tt->mbrtype; tt++)
if (tt->mbrtype == type)
return tt->nbsdtype;
return FS_OTHER;
}
u_int32_t
getlong(p)
void *p;
{
unsigned char *cp = p;
return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
}
int
getparts(sd, np, off)
int sd;
int np;
u_int32_t off;
{
unsigned char buf[DEV_BSIZE];
struct mbr_partition *mpart, *epart;
off_t loff = (off_t)off * DEV_BSIZE;
if (lseek(sd, loff, SEEK_SET) != loff) {
perror("seek label");
exit(1);
}
if (read(sd, buf, DEV_BSIZE) != DEV_BSIZE) {
perror("read label");
exit(1);
}
if (buf[0x1fe] != 0x55 || buf[0x1ff] != 0xaa)
return np;
mpart = (void *)(buf + MBRPARTOFF);
for (epart = mpart + NMBRPART; mpart < epart; mpart++) {
switch (mpart->mp_typ) {
case 0:
/* Nothing to do */
break;
case MBR_EXT:
case MBR_EXT_LBA:
/* Will be handled below */
break;
default:
label.d_partitions[np].p_size = getlong(&mpart->mp_size);
label.d_partitions[np].p_offset = getlong(&mpart->mp_start) + off;
label.d_partitions[np].p_fstype = nbsdtype(mpart->mp_typ);
switch (label.d_partitions[np].p_fstype) {
case FS_BSDFFS:
label.d_partitions[np].p_size = 16384;
label.d_partitions[np].p_fsize = 1024;
label.d_partitions[np].p_frag = 8;
label.d_partitions[np].p_cpg = 16;
break;
#ifdef __does_not_happen__
case FS_BSDLFS:
label.d_partitions[np].p_size = 16384;
label.d_partitions[np].p_fsize = 1024;
label.d_partitions[np].p_frag = 8;
label.d_partitions[np].p_sgs = XXX;
break;
#endif
}
np++;
break;
}
if (np >MAXPARTITIONS)
return np;
if (np == RAW_PART)
np++;
}
mpart = (void *)(buf + MBRPARTOFF);
for (epart = mpart + NMBRPART; mpart < epart; mpart++) {
switch (mpart->mp_typ) {
case MBR_EXT:
case MBR_EXT_LBA:
np = getparts(sd, np, getlong(&mpart->mp_start) + off);
break;
default:
break;
}
if (np >MAXPARTITIONS)
return np;
}
return np;
}
void
usage()
{
fprintf(stderr, "Usage: mbrlabel { rawdisk }\n");
exit(1);
}
int
main(argc, argv)
int argc;
char **argv;
{
int sd;
int np;
char name[MAXPATHLEN];
if (argc != 2)
usage();
if ((sd = opendisk(*++argv, O_RDWR, name, MAXPATHLEN, 0)) < 0) {
perror(*argv);
exit(1);
}
getlabel(sd);
np = getparts(sd, FIRSTPART, MBRSECTOR);
if (np > label.d_npartitions)
label.d_npartitions = np;
setlabel(sd);
close(sd);
return 0;
}

View File

@ -0,0 +1,67 @@
/* $NetBSD: mbrlabel.h,v 1.1 1998/11/16 18:44:26 ws Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christopher G. Demetriou.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* 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.
*/
/*
* Mostly stolen from <sys/arch/i386/disklabel.h>.
* This file should most likely be somewhere else in the include hierarchy.
*/
/* DOS partition table -- located in boot block */
#define MBRSECTOR 0 /* MBR relative sector # */
#define MBRPARTOFF 446
#define NMBRPART 4
struct mbr_partition {
unsigned char mp_flag; /* bootstrap flags */
unsigned char mp_shd; /* starting head */
unsigned char mp_ssect; /* starting sector */
unsigned char mp_scyl; /* starting cylinder */
unsigned char mp_typ; /* partition type (see below) */
unsigned char mp_ehd; /* end head */
unsigned char mp_esect; /* end sector */
unsigned char mp_ecyl; /* end cylinder */
unsigned long mp_start; /* absolute starting sector number */
unsigned long mp_size; /* partition size in sectors */
};
/* Known MBR partition types: */
#define MBR_NETBSD 0xa9 /* NetBSD partition type */
#define MBR_386BSD 0xa5 /* 386BSD partition type */
#define MBR_FAT12 0x01 /* 12-bit FAT */
#define MBR_FAT16S 0x04 /* 16-bit FAT, less than 32M */
#define MBR_EXT 0x05 /* extended partition */
#define MBR_FAT16B 0x06 /* 16-bit FAT, more than 32M */
#define MBR_FAT32 0x0b /* 32-bit FAT */
#define MBR_FAT32L 0x0c /* 32-bit FAT, LBA-mapped */
#define MBR_FAT16L 0x0e /* 16-bit FAT, LBA-mapped */
#define MBR_EXT_LBA 0x0f /* extended partition, LBA-mapped */
#define MBR_LNXEXT2 0x83 /* Linux native */