157298Shibler /* 257298Shibler * Copyright (c) 1992 University of Utah. 3*63165Sbostic * Copyright (c) 1982, 1986, 1988, 1993 4*63165Sbostic * The Regents of the University of California. All rights reserved. 557298Shibler * 657298Shibler * This code is derived from software contributed to Berkeley by 757298Shibler * the Systems Programming Group of the University of Utah Computer 857298Shibler * Science Department. 957298Shibler * 1057298Shibler * %sccs.include.redist.c% 1157298Shibler * 1257298Shibler * from: Utah $Hdr: label.c 1.1 92/12/05$ 1357298Shibler * 14*63165Sbostic * @(#)label.c 8.1 (Berkeley) 06/10/93 1557298Shibler */ 1657298Shibler 1757298Shibler /* 1857298Shibler * Derived from routines in ufs/ufs/ufs_disksubr.c. 1957298Shibler */ 2057298Shibler 2157298Shibler #include <sys/param.h> 2257298Shibler #include <sys/disklabel.h> 2360329Smckusick #include <stand.att/saio.h> 2457298Shibler 2557298Shibler /* 2657298Shibler * Attempt to read a disk label from a device using the indicated stategy 2757298Shibler * routine. Returns NULL on success and an error string on failure. 2857298Shibler */ 2957298Shibler char * readdisklabel(io,strat,lp)3057298Shiblerreaddisklabel(io, strat, lp) 3157298Shibler struct iob *io; 3257298Shibler int (*strat)(); 3357298Shibler register struct disklabel *lp; 3457298Shibler { 3557298Shibler struct iob liob; 3657298Shibler struct disklabel *dlp; 3757298Shibler char *msg = NULL; 3857298Shibler 3957298Shibler liob.i_adapt = io->i_adapt; 4057298Shibler liob.i_ctlr = io->i_ctlr; 4157298Shibler liob.i_unit = io->i_unit; 4257298Shibler liob.i_part = 2; 4357298Shibler liob.i_boff = 0; 4457298Shibler liob.i_cyloff = 0; 4557298Shibler liob.i_bn = LABELSECTOR; 4657298Shibler liob.i_ma = liob.i_buf; 4757298Shibler liob.i_cc = lp->d_secsize ? lp->d_secsize : DEV_BSIZE; 4857298Shibler if ((*strat)(&liob, F_READ) == -1) 4957298Shibler return ("I/O error"); 5057298Shibler 5157298Shibler for (dlp = (struct disklabel *)liob.i_buf; 5257298Shibler dlp <= (struct disklabel *)(liob.i_buf+DEV_BSIZE-sizeof(*dlp)); 5357298Shibler dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { 5457298Shibler if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { 5557298Shibler if (msg == NULL) 5657298Shibler msg = "no disk label"; 5757298Shibler } else if (dlp->d_npartitions > MAXPARTITIONS || dkcksum(dlp)) 5857298Shibler msg = "disk label corrupted"; 5957298Shibler else { 6057298Shibler *lp = *dlp; 6157298Shibler msg = NULL; 6257298Shibler break; 6357298Shibler } 6457298Shibler } 6557298Shibler return (msg); 6657298Shibler } 6757298Shibler 6857298Shibler /* 6957298Shibler * Compute checksum for disk label. 7057298Shibler */ dkcksum(lp)7157298Shiblerdkcksum(lp) 7257298Shibler register struct disklabel *lp; 7357298Shibler { 7457298Shibler register u_short *start, *end; 7557298Shibler register u_short sum = 0; 7657298Shibler 7757298Shibler start = (u_short *)lp; 7857298Shibler end = (u_short *)&lp->d_partitions[lp->d_npartitions]; 7957298Shibler while (start < end) 8057298Shibler sum ^= *start++; 8157298Shibler return (sum); 8257298Shibler } 83