1 /* $NetBSD: svhlabel.c,v 1.4 2007/06/30 02:05:27 rumble Exp $ */
4 * Copyright (C) 2007 Stephen M. Rumble.
5 * Copyright (C) 1998 Wolfgang Solfrank.
6 * Copyright (C) 1998 TooLs GmbH.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by TooLs GmbH.
20 * 4. The name of TooLs GmbH may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/cdefs.h>
37 __RCSID("$NetBSD: svhlabel.c,v 1.4 2007/06/30 02:05:27 rumble Exp $");
50 #include <sys/param.h>
52 #include <sys/disklabel.h>
53 #include <sys/bootblock.h>
54 #include <sys/ioctl.h>
56 #include <fs/efs/efs.h>
57 #include <fs/efs/efs_sb.h>
62 int main(int, char **);
63 static void usage(void);
64 static void getlabel(int);
65 static void setlabel(int, int);
66 static int getparts(int, int);
67 static int is_efs(int, uint32_t);
68 static struct sgi_boot_block
*convert_sgi_boot_block(unsigned char *);
70 struct disklabel label
;
76 if (ioctl(sd
, DIOCGDINFO
, &label
) < 0) {
81 * Some ports seem to not set the number of partitions
82 * correctly, albeit they seem to set the raw partition ok!
84 if (label
.d_npartitions
<= getrawpartition())
85 label
.d_npartitions
= getrawpartition() + 1;
89 setlabel(int sd
, int doraw
)
94 label
.d_checksum
= dkcksum(&label
);
95 if (ioctl(sd
, doraw
? DIOCWDINFO
: DIOCSDINFO
, &label
) < 0) {
100 /* If we haven't written to the disk, don't discard on close */
101 ioctl(sd
, DIOCKLABEL
, &one
);
106 getparts(int sd
, int verbose
)
108 unsigned char buf
[DEV_BSIZE
];
109 struct sgi_boot_block
*vh
;
110 struct partition npe
;
115 if (lseek(sd
, 0, SEEK_SET
) == -1) {
119 if ((i
= read(sd
, buf
, sizeof(buf
))) != DEV_BSIZE
) {
123 vh
= convert_sgi_boot_block(buf
);
125 if (vh
->magic
!= SGI_BOOT_BLOCK_MAGIC
)
128 if (label
.d_secsize
!= SGI_BOOT_BLOCK_BLOCKSIZE
)
130 label
.d_secsize
= SGI_BOOT_BLOCK_BLOCKSIZE
;
132 for (i
= j
= 0; i
< SGI_BOOT_BLOCK_MAXPARTITIONS
; i
++) {
133 if (vh
->partitions
[i
].blocks
== 0)
136 if (j
== MAXPARTITIONS
)
139 switch (vh
->partitions
[i
].type
) {
142 * For some reason, my IRIX CDs list EFS partitions as SYSV!?
145 if (is_efs(sd
, vh
->partitions
[i
].first
)) {
146 npe
.p_fstype
= FS_EFS
;
147 npe
.p_size
= vh
->partitions
[i
].blocks
;
148 npe
.p_offset
= vh
->partitions
[i
].first
;
155 case SGI_PTYPE_VOLUME
:
156 if (label
.d_secperunit
!= (uint32_t)vh
->partitions
[i
].blocks
)
158 label
.d_secperunit
= vh
->partitions
[i
].blocks
;
165 if (j
>= label
.d_npartitions
)
168 if (j
== getrawpartition()) {
169 if (++j
>= label
.d_npartitions
)
173 if (memcmp(&label
.d_partitions
[j
], &npe
, sizeof(npe
)) != 0) {
174 label
.d_partitions
[j
] = npe
;
182 if (label
.d_nsectors
!= 1 || label
.d_ntracks
!= 1 ||
183 label
.d_secpercyl
!= 1 || label
.d_ncylinders
!= label
.d_secperunit
)
185 label
.d_nsectors
= 1;
187 label
.d_secpercyl
= 1;
188 label
.d_ncylinders
= label
.d_secperunit
;
190 i
= getrawpartition();
191 if (label
.d_partitions
[i
].p_fstype
!= FS_UNUSED
||
192 label
.d_partitions
[i
].p_offset
!= 0 ||
193 label
.d_partitions
[i
].p_size
!= label
.d_secperunit
) {
194 label
.d_partitions
[i
].p_fstype
= FS_UNUSED
;
195 label
.d_partitions
[i
].p_offset
= 0;
196 label
.d_partitions
[i
].p_size
= label
.d_secperunit
;
204 is_efs(int sd
, uint32_t blkoff
)
209 if ((oldoff
= lseek(sd
, 0, SEEK_CUR
)) == -1) {
210 perror("is_efs lseek 0");
214 blkoff
*= SGI_BOOT_BLOCK_BLOCKSIZE
;
215 if (lseek(sd
, blkoff
+ (EFS_BB_SB
* EFS_BB_SIZE
), SEEK_SET
) == -1) {
216 perror("is_efs lseek 1");
220 if (read(sd
, &sb
, sizeof(sb
)) != sizeof(sb
)) {
221 perror("is_efs read");
225 if (lseek(sd
, oldoff
, SEEK_SET
) == -1) {
226 perror("is_efs lseek 2");
230 BE32TOH(sb
.sb_magic
);
232 return (sb
.sb_magic
== EFS_SB_MAGIC
|| sb
.sb_magic
== EFS_SB_NEWMAGIC
);
235 static struct sgi_boot_block
*
236 convert_sgi_boot_block(unsigned char *buf
)
238 struct sgi_boot_block
*vh
;
241 vh
= (struct sgi_boot_block
*)buf
;
247 BE16TOH(vh
->dp
.dp_cyls
);
248 BE16TOH(vh
->dp
.dp_shd0
);
249 BE16TOH(vh
->dp
.dp_trks0
);
250 BE16TOH(vh
->dp
.dp_secs
);
251 BE16TOH(vh
->dp
.dp_secbytes
);
252 BE16TOH(vh
->dp
.dp_interleave
);
253 BE32TOH(vh
->dp
.dp_flags
);
254 BE32TOH(vh
->dp
.dp_datarate
);
255 BE32TOH(vh
->dp
.dp_nretries
);
256 BE32TOH(vh
->dp
.dp_mspw
);
257 BE16TOH(vh
->dp
.dp_xgap1
);
258 BE16TOH(vh
->dp
.dp_xsync
);
259 BE16TOH(vh
->dp
.dp_xrdly
);
260 BE16TOH(vh
->dp
.dp_xgap2
);
261 BE16TOH(vh
->dp
.dp_xrgate
);
262 BE16TOH(vh
->dp
.dp_xwcont
);
264 for (i
= 0; i
< SGI_BOOT_BLOCK_MAXVOLDIRS
; i
++) {
265 BE32TOH(vh
->voldir
[i
].block
);
266 BE32TOH(vh
->voldir
[i
].bytes
);
269 for (i
= 0; i
< SGI_BOOT_BLOCK_MAXPARTITIONS
; i
++) {
270 BE32TOH(vh
->partitions
[i
].blocks
);
271 BE32TOH(vh
->partitions
[i
].first
);
272 BE32TOH(vh
->partitions
[i
].type
);
275 BE32TOH(vh
->checksum
);
283 fprintf(stderr
, "usage: %s [-fqrw] rawdisk\n",
290 main(int argc
, char **argv
)
293 char name
[MAXPATHLEN
];
294 int force
; /* force label update */
295 int raw
; /* update on-disk label as well */
296 int verbose
; /* verbose output */
297 int write_it
; /* update in-core label if changed */
303 while ((ch
= getopt(argc
, argv
, "fqrw")) != -1) {
326 if ((sd
= opendisk(argv
[0], write_it
? O_RDWR
: O_RDONLY
, name
,
327 (size_t)MAXPATHLEN
, 1)) < 0) {
332 changed
= getparts(sd
, verbose
);
336 showpartitions(stdout
, &label
, 0);
340 if (! changed
&& ! force
)
341 printf("No change; not updating disk label.\n");
344 printf("Updating in-core %sdisk label.\n",
345 raw
? "and on-disk " : "");
350 printf("Not updating disk label.\n");