From c7cfc3b1292659a495e6f0ee93e3cf93bb69fa5f Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Tue, 1 Jun 2004 20:18:25 +0000 Subject: [PATCH] Add SVR4-compatible VTOC-style elements to the Sun label. The FreeBSD kernel doesn't use them but sunlabel(8) shortly will, and both these files are used by sunlabel(8). --- sys/geom/geom_sunlabel_enc.c | 47 +++++++++++++++++++++++++++++++++++- sys/sys/sun_disklabel.h | 35 +++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/sys/geom/geom_sunlabel_enc.c b/sys/geom/geom_sunlabel_enc.c index d153e11c6222..70899b1bbea7 100644 --- a/sys/geom/geom_sunlabel_enc.c +++ b/sys/geom/geom_sunlabel_enc.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2003 Jake Burkholder * Copyright (c) 2003 Poul-Henning Kamp + * Copyright (c) 2004 Joerg Wunsch * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +41,10 @@ __FBSDID("$FreeBSD$"); #define SL_TEXT 0x0 #define SL_TEXT_SIZEOF 0x80 +#define SL_VTOC_VERS 0x80 +#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 @@ -54,7 +59,11 @@ __FBSDID("$FreeBSD$"); #define SDKP_CYLOFFSET 0 #define SDKP_NSECTORS 0x4 -#define SDKP_SIZEOF 0x8 +#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 @@ -66,6 +75,8 @@ 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++) @@ -85,6 +96,23 @@ sunlabel_dec(void const *pp, struct sun_disklabel *sl) (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); + 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) @@ -121,6 +149,23 @@ sunlabel_enc(void *pp, struct sun_disklabel *sl) 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); + 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); diff --git a/sys/sys/sun_disklabel.h b/sys/sys/sun_disklabel.h index ae1ccb94f7a2..e99239fb1ebf 100644 --- a/sys/sys/sun_disklabel.h +++ b/sys/sys/sun_disklabel.h @@ -1,6 +1,7 @@ /* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. + * Copyright (c) 2004, Joerg Wunsch * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and @@ -51,6 +52,8 @@ #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". */ /* * 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 @@ -66,8 +69,40 @@ struct sun_dkpart { 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 */ + 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 */