Support VTOC volume names. This can be useful to distinguish multiple

disks in a system.  Solaris' format(1m) displays the volume names in
the disk overview.

MFC after:	1 month
This commit is contained in:
Joerg Wunsch 2005-03-30 09:33:10 +00:00
parent 04d114aa99
commit 3328bbeef2
4 changed files with 73 additions and 8 deletions

View File

@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 1, 2004
.Dd March 30, 2005
.Dt SUNLABEL 8
.Os
.Sh NAME
@ -238,7 +238,7 @@ be written to disk.
The label presented for editing is the same as the standard
printout, with some added hints about the possible options to
specify the sector size and starting cylinder.
There are two areas in the template that can be edited:
The following areas in the template that can be edited:
.Bl -tag -width indent
.It Sy Textual label, geometry emulation
The line
@ -266,6 +266,15 @@ The product
.D1 Em (CC + 2) * HH * SS
must be less than or equal to the total number of sectors of the
disk (which is given as a hint in a comment field).
.It Sy Volume name
The volume name (if present) is introduced by the string
.Dq "volume name:" .
It can be up to 8 characters long, and might be useful to distinguish
different disks in a system.
Note that volume names require the VTOC elements to be present, so
any of the VTOC constraints described below need to be obeyed as well
if a volume name is to be set.
Setting an empty volume name will delete it from the label.
.It Sy Partition entries
Partition entries start with a letter from
.Ql a

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 2003 Jake Burkholder.
* Copyright (c) 2004 Joerg Wunsch.
* Copyright (c) 2004,2005 Joerg Wunsch.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -541,6 +541,7 @@ parse_label(struct sun_disklabel *sl, const char *file)
char tag[32];
char buf[128];
char text[128];
char volname[SUN_VOLNAME_LEN + 1];
struct sun_disklabel sl1;
char *bp;
const char *what;
@ -631,6 +632,33 @@ parse_label(struct sun_disklabel *sl, const char *file)
text, cyl, alt, hd, sec);
continue;
}
if (strncmp(bp, "volume name:", strlen("volume name:")) == 0) {
wantvtoc = 1; /* Volume name requires VTOC. */
bp += strlen("volume name:");
#if SUN_VOLNAME_LEN != 8
# error "scanf field width does not match SUN_VOLNAME_LEN"
#endif
/*
* We set the field length to one more than
* SUN_VOLNAME_LEN to allow detecting an
* overflow.
*/
memset(volname, 0, sizeof volname);
rv = sscanf(bp, " %9[^\n]", volname);
if (rv != 1) {
/* Clear the volume name. */
memset(sl1.sl_vtoc_volname, 0,
SUN_VOLNAME_LEN);
} else {
memcpy(sl1.sl_vtoc_volname, volname,
SUN_VOLNAME_LEN);
if (volname[SUN_VOLNAME_LEN] != '\0')
warnx(
"%s, line %d: volume name longer than %d characters, truncating",
file, line + 1, SUN_VOLNAME_LEN);
}
continue;
}
if (strlen(bp) < 2 || bp[1] != ':') {
line++;
continue;
@ -742,9 +770,11 @@ parse_offset(struct sun_disklabel *sl, int part, char *offset)
static void
print_label(struct sun_disklabel *sl, const char *disk, FILE *out)
{
int i;
int i, j;
int havevtoc;
uintmax_t secpercyl;
/* Long enough to hex-encode each character. */
char volname[4 * SUN_VOLNAME_LEN + 1];
havevtoc = sl->sl_vtoc_sane == SUN_VTOC_SANE;
secpercyl = sl->sl_nsectors * sl->sl_ntracks;
@ -763,11 +793,25 @@ print_label(struct sun_disklabel *sl, const char *disk, FILE *out)
"# max sectors/unit (including alt cylinders): %ju\n",
(uintmax_t)mediasize / sectorsize);
fprintf(out,
"sectors/unit: %ju\n"
"sectors/unit: %ju\n",
secpercyl * sl->sl_ncylinders);
if (havevtoc && sl->sl_vtoc_volname[0] != '\0') {
for (i = j = 0; i < SUN_VOLNAME_LEN; i++) {
if (sl->sl_vtoc_volname[i] == '\0')
break;
if (isprint(sl->sl_vtoc_volname[i]))
volname[j++] = sl->sl_vtoc_volname[i];
else
j += sprintf(volname + j, "\\x%02X",
sl->sl_vtoc_volname[i]);
}
volname[j] = '\0';
fprintf(out, "volume name: %s\n", volname);
}
fprintf(out,
"\n"
"%d partitions:\n"
"#\n",
secpercyl * sl->sl_ncylinders,
SUN_NPART);
if (!hflag) {
fprintf(out, "# Size is in %s.", cflag? "cylinders": "sectors");

View File

@ -1,7 +1,7 @@
/*-
* Copyright (c) 2003 Jake Burkholder
* Copyright (c) 2003 Poul-Henning Kamp
* Copyright (c) 2004 Joerg Wunsch
* Copyright (c) 2004,2005 Joerg Wunsch
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -38,10 +38,16 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/sun_disklabel.h>
#ifdef _KERNEL
#include <sys/systm.h>
#else
#include <string.h>
#endif
#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
@ -105,6 +111,8 @@ sunlabel_dec(void const *pp, struct sun_disklabel *sl)
*/
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 +
@ -156,6 +164,8 @@ sunlabel_enc(void *pp, struct sun_disklabel *sl)
*/
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)

View File

@ -1,7 +1,7 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2004, Joerg Wunsch
* 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
@ -54,6 +54,7 @@
#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
@ -98,6 +99,7 @@ struct sun_disklabel {
/* 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 */