static char sccsid
[] = "@(#)disklabel.c 5.1 (Berkeley) %G%";
/* from static char sccsid[] = "@(#)disklabel.c 1.2 (Symmetric) 11/28/85"; */
#include <sys/disklabel.h>
* Disklabel: read and write disklabels.
* The label is usually placed on one of the first sectors of the disk.
* Many machines (VAX 11/750) also place a bootstrap in the same area,
* in which case the label is embedded in the bootstrap.
* The bootstrap source must leave space at the proper offset
* for the label on such machines.
#define BBSIZE 8192 /* size of boot area, with label */
#define BOOT /* also have bootstrap in "boot area" */
#define BOOTDIR "/usr/mdec" /* source of boot binaries */
char namebuf
[BBSIZE
], *np
= namebuf
;
struct disklabel
*readlabel(), *getbootarea();
register struct disklabel
*lp
;
char *name
= 0, *asciifile
, *type
;
while (argc
> 1 && argv
[1][0] == '-') {
if (strcmp(argv
[1], "-e") == 0) {
} else if (strcmp(argv
[1], "-w") == 0) {
if (argc
< 2 || argc
> 6) {
fprintf(stderr
, "%s%s%s%s",
"usage: disklabel disk (to read label)\n",
"or disklabel disk type [ packid ] [ xxboot bootxx ] (to write label)\n",
"or disklabel -e disk (to edit label)\n",
"or disklabel -w disk protofile [ xxboot bootxx ] (to restore label)\n"
"usage: disklabel disk (to read label)\n",
"or disklabel disk type [ packid ] (to write label)\n",
"or disklabel -e disk (to edit label)\n",
"or disklabel -w disk protofile (to restore label)\n"
sprintf(np
, "/dev/r%sc", dkname
);
np
+= strlen(specname
) + 1;
f
= open(specname
, op
== READ
? O_RDONLY
: O_RDWR
);
if (f
< 0 && errno
== ENOENT
&& dkname
[0] != '/') {
sprintf(specname
, "/dev/r%s", dkname
);
np
= namebuf
+ strlen(specname
) + 1;
f
= open(specname
, op
== READ
? O_RDONLY
: O_RDWR
);
if (argc
== 4 || argc
== 6) {
lp
= readlabel(f
, bootarea
);
writelabel(f
, bootarea
, lp
);
makelabel(type
, name
, &lab
);
lp
= getbootarea(bootarea
, &lab
);
writelabel(f
, bootarea
, lp
);
lab
.d_secsize
= DEV_BSIZE
; /* XXX */
lab
.d_bbsize
= BBSIZE
; /* XXX */
lp
= getbootarea(bootarea
, &lab
);
t
= open(asciifile
, O_RDONLY
);
writelabel(f
, bootarea
, lp
);
makelabel(type
, name
, lp
)
register struct disklabel
*lp
;
register struct disklabel
*dp
;
dp
= getdiskbyname(type
);
fprintf(stderr
, "%s: unknown disk type\n", type
);
strncpy(lp
->d_name
, name
, sizeof(lp
->d_name
));
register struct disklabel
*lp
;
lp
->d_magic2
= DISKMAGIC
;
lp
->d_checksum
= dkcksum(lp
);
lseek(f
, (off_t
)0, L_SET
);
if (write(f
, boot
, lp
->d_bbsize
) < lp
->d_bbsize
)
alt
= lp
->d_ncylinders
* lp
->d_secpercyl
- lp
->d_nsectors
;
for (i
= 1; i
< 11 && i
< lp
->d_nsectors
; i
+= 2) {
lseek(f
, (off_t
)(alt
+ i
) * lp
->d_secsize
, L_SET
);
if (write(f
, boot
, lp
->d_secsize
) < lp
->d_secsize
) {
fprintf(stderr
, "alternate label %d ", i
/2);
if (ioctl(f
, DIOCSDINFO
, lp
) < 0)
Perror("ioctl DIOCSDINFO");
* Read disklabel from disk.
* If boot is given, need bootstrap too.
* If boot not needed, could use ioctl to get label.
register struct disklabel
*lp
;
u_long magic
= htonl(DISKMAGIC
);
if (read(f
, boot
, BBSIZE
) < BBSIZE
)
for (lp
= (struct disklabel
*)(boot
+ LABELOFFSET
);
lp
<= (struct disklabel
*)(boot
+ BBSIZE
-
sizeof(struct disklabel
));
lp
= (struct disklabel
*)((char *)lp
+ 128))
if (lp
->d_magic
== magic
&& lp
->d_magic2
== magic
)
if (lp
> (struct disklabel
*)(boot
+ BBSIZE
-
sizeof(struct disklabel
)) ||
lp
->d_magic
!= magic
|| lp
->d_magic2
!= magic
||
"Bad pack magic number (label is damaged, or pack is unlabeled)\n");
register struct disklabel
*dp
;
if ((p
= rindex(dkname
, '/')) == NULL
)
while (*p
&& !isdigit(*p
))
sprintf(np
, "%s/%sboot", BOOTDIR
, dkbasename
);
if (access(np
, F_OK
) < 0 && dkbasename
[0] == 'r')
sprintf(xxboot
, "%s/%sboot", BOOTDIR
, dkbasename
);
np
+= strlen(xxboot
) + 1;
sprintf(bootxx
, "%s/boot%s", BOOTDIR
, dkbasename
);
np
+= strlen(bootxx
) + 1;
b
= open(xxboot
, O_RDONLY
);
if (read(b
, boot
, dp
->d_secsize
) < 0)
b
= open(bootxx
, O_RDONLY
);
if (read(b
, &boot
[dp
->d_secsize
], dp
->d_bbsize
-dp
->d_secsize
) < 0)
lp
= (struct disklabel
*)(boot
+ (LABELSECTOR
* dp
->d_secsize
) +
for (p
= (char *)lp
; p
< (char *)lp
+ sizeof(struct disklabel
); p
++)
"Bootstrap doesn't leave room for disk label\n");
register struct disklabel
*lp
;
register struct partition
*pp
;
fprintf(f
, "# %s:\n", specname
);
if ((unsigned) lp
->d_type
< DKMAXTYPES
)
fprintf(f
, "type: %s\n", dktypenames
[lp
->d_type
]);
fprintf(f
, "type: %d\n", lp
->d_type
);
fprintf(f
, "disk: %.*s\n", sizeof(lp
->d_typename
), lp
->d_typename
);
fprintf(f
, "label: %.*s\n", sizeof(lp
->d_name
), lp
->d_name
);
if (lp
->d_flags
& D_REMOVABLE
)
fprintf(f
, "removeable ");
if (lp
->d_flags
& D_BADSECT
)
fprintf(f
, "bytes/sector: %d\n", lp
->d_secsize
);
fprintf(f
, "sectors/track: %d\n", lp
->d_nsectors
);
fprintf(f
, "tracks/cylinder: %d\n", lp
->d_ntracks
);
fprintf(f
, "cylinders: %d\n", lp
->d_ncylinders
);
fprintf(f
, "interleave: %d\n", lp
->d_interleave
);
fprintf(f
, "trackskew: %d\n", lp
->d_trackskew
);
fprintf(f
, "cylinderskew: %d\n", lp
->d_cylskew
);
fprintf(f
, "headswitch: %d\t\t# milliseconds\n", lp
->d_headswitch
);
fprintf(f
, "track-to-track seek: %d\t# milliseconds\n", lp
->d_trkseek
);
fprintf(f
, "drivedata: ");
for (i
= NDDATA
- 1; i
>= 0; i
--)
fprintf(f
, "%d ", lp
->d_drivedata
[j
]);
fprintf(f
, "\n\n%d partitions:\n", lp
->d_npartitions
);
fprintf(f
, "#\t size offset fstype\n");
for (i
= 0; i
< lp
->d_npartitions
; i
++, pp
++) {
fprintf(f
, "\t%c: %8d %8d ", 'a' + i
,
pp
->p_size
, pp
->p_offset
);
if ((unsigned) pp
->p_fstype
< FSMAXTYPES
)
fprintf(f
, "%8.8s", fstypenames
[pp
->p_fstype
]);
fprintf(f
, "%8d", pp
->p_fstype
);
fprintf(f
, "\t# (Cyl. %4d",
pp
->p_offset
/ lp
->d_secpercyl
);
if (pp
->p_offset
% lp
->d_secpercyl
)
pp
->p_size
+ lp
->d_secpercyl
- 1) /
if (pp
->p_size
% lp
->d_secpercyl
)
fprintf(stderr
, "sorry, not yet\n");
* Read an ascii label in from fd f,
* in the same format as that put out by display(),
register struct disklabel
*lp
;
fprintf(stderr
, "sorry, not yet\n");
fprintf(stderr
, "disklabel: "); perror(op
);