diff options
| author | Conrad Meyer <cem@FreeBSD.org> | 2019-08-13 20:06:55 +0000 |
|---|---|---|
| committer | Conrad Meyer <cem@FreeBSD.org> | 2019-08-13 20:06:55 +0000 |
| commit | ac8e5d02cf9fcbe09e2077499804d791fc70122a (patch) | |
| tree | 3a1a68a83211a29345db78bfc84b0c3f831b5a6a /sbin/sunlabel | |
| parent | ba084c18dee217c29f87bbf53b496c0be5dd9c2d (diff) | |
Notes
Diffstat (limited to 'sbin/sunlabel')
| -rw-r--r-- | sbin/sunlabel/Makefile | 4 | ||||
| -rw-r--r-- | sbin/sunlabel/sun_disklabel.h | 125 | ||||
| -rw-r--r-- | sbin/sunlabel/sunlabel.c | 3 | ||||
| -rw-r--r-- | sbin/sunlabel/sunlabel_enc.c | 184 |
4 files changed, 312 insertions, 4 deletions
diff --git a/sbin/sunlabel/Makefile b/sbin/sunlabel/Makefile index 0cf449743ec85..05ae28c0da204 100644 --- a/sbin/sunlabel/Makefile +++ b/sbin/sunlabel/Makefile @@ -1,9 +1,7 @@ # $FreeBSD$ -.PATH: ${SRCTOP}/sys/geom - PROG= sunlabel -SRCS= sunlabel.c geom_sunlabel_enc.c +SRCS= sunlabel.c sunlabel_enc.c MAN= sunlabel.8 .if ${MACHINE_CPUARCH} == "sparc64" diff --git a/sbin/sunlabel/sun_disklabel.h b/sbin/sunlabel/sun_disklabel.h new file mode 100644 index 0000000000000..942e1d3d11c26 --- /dev/null +++ b/sbin/sunlabel/sun_disklabel.h @@ -0,0 +1,125 @@ +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 2004,2005 Joerg Wunsch + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * 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. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * @(#)sun_disklabel.h 8.1 (Berkeley) 6/11/93 + * $NetBSD: disklabel.h,v 1.2 1998/08/22 14:55:28 mrg Exp $ + * + * $FreeBSD$ + */ + +#ifndef _SYS_SUN_DISKLABEL_H_ +#define _SYS_SUN_DISKLABEL_H_ + +/* + * SunOS/Solaris disk label layout (partial). + * + * Suns disk label format contains a lot of historical baggage which we + * ignore entirely. The structure below contains the relevant bits and the + * _enc/_dec functions encode/decode only these fields. + */ + +#define SUN_DKMAGIC 55998 +#define SUN_NPART 8 +#define SUN_RAWPART 2 +#define SUN_SIZE 512 +#define SUN_VTOC_VERSION 1 +#define SUN_VTOC_SANE 0x600DDEEE /* SVR4-compatible VTOC is "sane". */ +#define SUN_VOLNAME_LEN 8 +/* + * XXX: I am actually not sure if this should be "16 sectors" or "8192 bytes". + * XXX: Considering that Sun went to the effort of getting 512 byte compatible + * XXX: CDROM drives produced my guess is that Sun computers stand little or + * XXX: even no chance of running, much less booting on !=512 byte media. + * XXX: Define this is in terms of bytes since that is easier for us. + */ +#define SUN_BOOTSIZE 8192 + +/* partition info */ +struct sun_dkpart { + u_int32_t sdkp_cyloffset; /* starting cylinder */ + u_int32_t sdkp_nsectors; /* number of sectors */ +}; + +struct sun_vtoc_info { + u_int16_t svtoc_tag; /* partition tag */ + u_int16_t svtoc_flag; /* partition flags */ +}; + +/* known partition tag values */ +#define VTOC_UNASSIGNED 0x00 +#define VTOC_BOOT 0x01 +#define VTOC_ROOT 0x02 +#define VTOC_SWAP 0x03 +#define VTOC_USR 0x04 +#define VTOC_BACKUP 0x05 /* "c" partition, covers entire disk */ +#define VTOC_STAND 0x06 +#define VTOC_VAR 0x07 +#define VTOC_HOME 0x08 +#define VTOC_ALTSCTR 0x09 /* alternate sector partition */ +#define VTOC_CACHE 0x0a /* Solaris cachefs partition */ +#define VTOC_VXVM_PUB 0x0e /* VxVM public region */ +#define VTOC_VXVM_PRIV 0x0f /* VxVM private region */ + +/* VTOC partition flags */ +#define VTOC_UNMNT 0x01 /* unmountable partition */ +#define VTOC_RONLY 0x10 /* partition is read/only */ + +struct sun_disklabel { + char sl_text[128]; + + /* SVR4 VTOC information */ + u_int32_t sl_vtoc_vers; /* == SUN_VTOC_VERSION */ + char sl_vtoc_volname[SUN_VOLNAME_LEN]; + u_int16_t sl_vtoc_nparts; /* == SUN_NPART */ + struct sun_vtoc_info sl_vtoc_map[SUN_NPART]; /* partition tag/flag */ + u_int32_t sl_vtoc_sane; /* == SUN_VTOC_SANE */ + + /* Sun label information */ + u_int16_t sl_rpm; /* rotational speed */ + u_int16_t sl_pcylinders; /* number of physical cyls */ + u_int16_t sl_sparespercyl; /* spare sectors per cylinder */ + u_int16_t sl_interleave; /* interleave factor */ + u_int16_t sl_ncylinders; /* data cylinders */ + u_int16_t sl_acylinders; /* alternate cylinders */ + u_int16_t sl_ntracks; /* tracks per cylinder */ + u_int16_t sl_nsectors; /* sectors per track */ + struct sun_dkpart sl_part[SUN_NPART]; /* partition layout */ + u_int16_t sl_magic; /* == SUN_DKMAGIC */ +}; + +int sunlabel_dec(void const *pp, struct sun_disklabel *sl); +void sunlabel_enc(void *pp, struct sun_disklabel *sl); + +#endif /* _SYS_SUN_DISKLABEL_H_ */ diff --git a/sbin/sunlabel/sunlabel.c b/sbin/sunlabel/sunlabel.c index d1d5cea42d45b..c4f59b1170c6e 100644 --- a/sbin/sunlabel/sunlabel.c +++ b/sbin/sunlabel/sunlabel.c @@ -75,7 +75,6 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/disk.h> #include <sys/ioctl.h> -#include <sys/sun_disklabel.h> #include <sys/wait.h> #include <ctype.h> @@ -89,6 +88,8 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> +#include "sun_disklabel.h" + #define _PATH_TMPFILE "/tmp/EdDk.XXXXXXXXXX" #define _PATH_BOOT "/boot/boot1" diff --git a/sbin/sunlabel/sunlabel_enc.c b/sbin/sunlabel/sunlabel_enc.c new file mode 100644 index 0000000000000..4146442589e5f --- /dev/null +++ b/sbin/sunlabel/sunlabel_enc.c @@ -0,0 +1,184 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2003 Jake Burkholder + * Copyright (c) 2003 Poul-Henning Kamp + * Copyright (c) 2004,2005 Joerg Wunsch + * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. + */ +/* Functions to encode or decode struct sun_disklabel into a bytestream + * of correct endianness and packing. + * + * NB! This file must be usable both in kernel and userland. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/endian.h> +#include <sys/errno.h> +#ifdef _KERNEL +#include <sys/systm.h> +#else +#include <string.h> +#endif +#include "sun_disklabel.h" + +#define SL_TEXT 0x0 +#define SL_TEXT_SIZEOF 0x80 +#define SL_VTOC_VERS 0x80 +#define SL_VTOC_VOLNAME 0x84 +#define SL_VTOC_NPART 0x8c +#define SL_VTOC_MAP 0x8e +#define SL_VTOC_SANITY 0xbc +#define SL_RPM 0x1a4 +#define SL_PCYLINDERS 0x1a6 +#define SL_SPARESPERCYL 0x1a8 +#define SL_INTERLEAVE 0x1ae +#define SL_NCYLINDERS 0x1b0 +#define SL_ACYLINDERS 0x1b2 +#define SL_NTRACKS 0x1b4 +#define SL_NSECTORS 0x1b6 +#define SL_PART 0x1bc +#define SL_MAGIC 0x1fc +#define SL_CKSUM 0x1fe + +#define SDKP_CYLOFFSET 0 +#define SDKP_NSECTORS 0x4 +#define SDKP_SIZEOF 0x8 /* size of a partition entry */ + +#define SVTOC_TAG 0 +#define SVTOC_FLAG 0x2 +#define SVTOC_SIZEOF 0x4 /* size of a VTOC tag/flag entry */ + +/* + * Decode the relevant fields of a sun disk label, and return zero if the + * magic and checksum works out OK. + */ +int +sunlabel_dec(void const *pp, struct sun_disklabel *sl) +{ + const uint8_t *p; + size_t i; + u_int u; + uint32_t vtocsane; + uint16_t npart; + + p = pp; + for (i = 0; i < sizeof(sl->sl_text); i++) + sl->sl_text[i] = p[SL_TEXT + i]; + sl->sl_rpm = be16dec(p + SL_RPM); + sl->sl_pcylinders = be16dec(p + SL_PCYLINDERS); + sl->sl_sparespercyl = be16dec(p + SL_SPARESPERCYL); + sl->sl_interleave = be16dec(p + SL_INTERLEAVE); + sl->sl_ncylinders = be16dec(p + SL_NCYLINDERS); + sl->sl_acylinders = be16dec(p + SL_ACYLINDERS); + sl->sl_ntracks = be16dec(p + SL_NTRACKS); + sl->sl_nsectors = be16dec(p + SL_NSECTORS); + for (i = 0; i < SUN_NPART; i++) { + sl->sl_part[i].sdkp_cyloffset = be32dec(p + SL_PART + + (i * SDKP_SIZEOF) + SDKP_CYLOFFSET); + sl->sl_part[i].sdkp_nsectors = be32dec(p + SL_PART + + (i * SDKP_SIZEOF) + SDKP_NSECTORS); + } + sl->sl_magic = be16dec(p + SL_MAGIC); + vtocsane = be32dec(p + SL_VTOC_SANITY); + npart = be16dec(p + SL_VTOC_NPART); + if (vtocsane == SUN_VTOC_SANE && npart == SUN_NPART) { + /* + * Seems we've got SVR4-compatible VTOC information + * as well, decode it. + */ + sl->sl_vtoc_sane = vtocsane; + sl->sl_vtoc_vers = be32dec(p + SL_VTOC_VERS); + memcpy(sl->sl_vtoc_volname, p + SL_VTOC_VOLNAME, + SUN_VOLNAME_LEN); + sl->sl_vtoc_nparts = SUN_NPART; + for (i = 0; i < SUN_NPART; i++) { + sl->sl_vtoc_map[i].svtoc_tag = be16dec(p + + SL_VTOC_MAP + (i * SVTOC_SIZEOF) + SVTOC_TAG); + sl->sl_vtoc_map[i].svtoc_flag = be16dec(p + + SL_VTOC_MAP + (i * SVTOC_SIZEOF) + SVTOC_FLAG); + } + } + for (i = u = 0; i < SUN_SIZE; i += 2) + u ^= be16dec(p + i); + if (u == 0 && sl->sl_magic == SUN_DKMAGIC) + return (0); + else + return (EINVAL); +} + +/* + * Encode the relevant fields into a sun disklabel, compute new checksum. + */ +void +sunlabel_enc(void *pp, struct sun_disklabel *sl) +{ + uint8_t *p; + size_t i; + u_int u; + + p = pp; + for (i = 0; i < SL_TEXT_SIZEOF; i++) + p[SL_TEXT + i] = sl->sl_text[i]; + be16enc(p + SL_RPM, sl->sl_rpm); + be16enc(p + SL_PCYLINDERS, sl->sl_pcylinders); + be16enc(p + SL_SPARESPERCYL, sl->sl_sparespercyl); + be16enc(p + SL_INTERLEAVE, sl->sl_interleave); + be16enc(p + SL_NCYLINDERS, sl->sl_ncylinders); + be16enc(p + SL_ACYLINDERS, sl->sl_acylinders); + be16enc(p + SL_NTRACKS, sl->sl_ntracks); + be16enc(p + SL_NSECTORS, sl->sl_nsectors); + for (i = 0; i < SUN_NPART; i++) { + be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_CYLOFFSET, + sl->sl_part[i].sdkp_cyloffset); + be32enc(p + SL_PART + (i * SDKP_SIZEOF) + SDKP_NSECTORS, + sl->sl_part[i].sdkp_nsectors); + } + be16enc(p + SL_MAGIC, sl->sl_magic); + if (sl->sl_vtoc_sane == SUN_VTOC_SANE + && sl->sl_vtoc_nparts == SUN_NPART) { + /* + * Write SVR4-compatible VTOC elements. + */ + be32enc(p + SL_VTOC_VERS, sl->sl_vtoc_vers); + be32enc(p + SL_VTOC_SANITY, SUN_VTOC_SANE); + memcpy(p + SL_VTOC_VOLNAME, sl->sl_vtoc_volname, + SUN_VOLNAME_LEN); + be16enc(p + SL_VTOC_NPART, SUN_NPART); + for (i = 0; i < SUN_NPART; i++) { + be16enc(p + SL_VTOC_MAP + (i * SVTOC_SIZEOF) + + SVTOC_TAG, + sl->sl_vtoc_map[i].svtoc_tag); + be16enc(p + SL_VTOC_MAP + (i * SVTOC_SIZEOF) + + SVTOC_FLAG, + sl->sl_vtoc_map[i].svtoc_flag); + } + } + for (i = u = 0; i < SUN_SIZE; i += 2) + u ^= be16dec(p + i); + be16enc(p + SL_CKSUM, u); +} |
