aboutsummaryrefslogtreecommitdiff
path: root/sbin/sunlabel
diff options
context:
space:
mode:
authorConrad Meyer <cem@FreeBSD.org>2019-08-13 20:06:55 +0000
committerConrad Meyer <cem@FreeBSD.org>2019-08-13 20:06:55 +0000
commitac8e5d02cf9fcbe09e2077499804d791fc70122a (patch)
tree3a1a68a83211a29345db78bfc84b0c3f831b5a6a /sbin/sunlabel
parentba084c18dee217c29f87bbf53b496c0be5dd9c2d (diff)
Notes
Diffstat (limited to 'sbin/sunlabel')
-rw-r--r--sbin/sunlabel/Makefile4
-rw-r--r--sbin/sunlabel/sun_disklabel.h125
-rw-r--r--sbin/sunlabel/sunlabel.c3
-rw-r--r--sbin/sunlabel/sunlabel_enc.c184
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);
+}