4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
34 #include <sys/types.h>
35 #include <sys/param.h>
42 * To copy each field of vtoc individually for copying extvtoc
43 * to 32 bit vtoc and vs.
44 * Currently bootinfo and timestamp are not really supported.
47 #define libadm_vtoc_copy(vs, vd) \
50 vd->v_bootinfo[0] = (unsigned)vs->v_bootinfo[0]; \
51 vd->v_bootinfo[1] = (unsigned)vs->v_bootinfo[1]; \
52 vd->v_bootinfo[2] = (unsigned)vs->v_bootinfo[2]; \
53 vd->v_sanity = (unsigned)vs->v_sanity; \
54 vd->v_version = (unsigned)vs->v_version; \
55 bcopy(vs->v_volume, vd->v_volume, LEN_DKL_VVOL); \
56 vd->v_sectorsz = vs->v_sectorsz; \
57 vd->v_nparts = vs->v_nparts; \
58 vd->v_version = (unsigned)vs->v_version; \
59 for (i = 0; i < 10; i++) \
60 vd->v_reserved[i] = (unsigned)vs->v_reserved[i];\
61 for (i = 0; i < V_NUMPAR; i++) { \
62 vd->v_part[i].p_tag = vs->v_part[i].p_tag; \
63 vd->v_part[i].p_flag = vs->v_part[i].p_flag; \
64 vd->v_part[i].p_start = (unsigned)vs->v_part[i].p_start;\
65 vd->v_part[i].p_size = (unsigned)vs->v_part[i].p_size; \
67 for (i = 0; i < V_NUMPAR; i++) \
68 if ((sizeof (vd->timestamp[i]) != sizeof (vs->timestamp[i])) &&\
69 (vs->timestamp[i] > INT32_MAX)) \
70 vd->timestamp[i] = INT32_MAX; \
72 vd->timestamp[i] = (unsigned)vs->timestamp[i]; \
73 bcopy(vs->v_asciilabel, vd->v_asciilabel, LEN_DKL_ASCII); \
78 * Read VTOC - return partition number.
81 read_vtoc(int fd
, struct vtoc
*vtoc
)
83 struct dk_cinfo dki_info
;
88 if (ioctl(fd
, DKIOCGVTOC
, (caddr_t
)vtoc
) == -1) {
95 /* GPT labeled or disk > 1TB with no extvtoc support */
98 return (VT_EOVERFLOW
);
105 * Sanity-check the vtoc.
107 if (vtoc
->v_sanity
!= VTOC_SANE
) {
112 * Convert older-style vtoc's.
114 switch (vtoc
->v_version
) {
117 * No vtoc information. Install default
118 * nparts/sectorsz and version. We are
119 * assuming that the driver returns the
120 * current partition information correctly.
123 vtoc
->v_version
= V_VERSION
;
124 if (vtoc
->v_nparts
== 0)
125 vtoc
->v_nparts
= V_NUMPAR
;
126 if (vtoc
->v_sectorsz
== 0)
127 vtoc
->v_sectorsz
= DEV_BSIZE
;
139 * Return partition number for this file descriptor.
141 if (ioctl(fd
, DKIOCINFO
, (caddr_t
)&dki_info
) == -1) {
151 if (dki_info
.dki_partition
> V_NUMPAR
) {
154 return ((int)dki_info
.dki_partition
);
161 write_vtoc(int fd
, struct vtoc
*vtoc
)
165 * Sanity-check the vtoc
167 if (vtoc
->v_sanity
!= VTOC_SANE
|| vtoc
->v_nparts
> V_NUMPAR
) {
172 * since many drivers won't allow opening a device make sure
173 * all partitions aren't being set to zero. If all are zero then
174 * we have no way to set them to something else
177 for (i
= 0; i
< (int)vtoc
->v_nparts
; i
++)
178 if (vtoc
->v_part
[i
].p_size
> 0)
180 if (i
== (int)vtoc
->v_nparts
)
186 if (ioctl(fd
, DKIOCSVTOC
, (caddr_t
)vtoc
) == -1) {
193 /* GPT labeled or disk > 1TB with no extvtoc support */
196 return (VT_EOVERFLOW
);
205 read_extvtoc(int fd
, struct extvtoc
*extvtoc
)
207 struct dk_cinfo dki_info
;
209 struct vtoc
*oldvtocp
= &oldvtoc
;
215 if (ioctl(fd
, DKIOCGEXTVTOC
, (caddr_t
)extvtoc
) == -1) {
221 /* for disks > 1TB */
225 return (VT_EOVERFLOW
);
228 if ((ret
= read_vtoc(fd
, oldvtocp
)) < 0)
233 * 64-bit vtoc and extvtoc have the same field sizes
236 bcopy(oldvtocp
, extvtoc
, sizeof (struct extvtoc
));
238 bzero(extvtoc
, sizeof (struct extvtoc
));
239 libadm_vtoc_copy(oldvtocp
, extvtoc
);
250 * Sanity-check the vtoc.
252 if (extvtoc
->v_sanity
!= VTOC_SANE
) {
256 switch (extvtoc
->v_version
) {
259 * For pre-version 1 vtoc keep same functionality
263 extvtoc
->v_version
= V_VERSION
;
264 if (extvtoc
->v_nparts
== 0)
265 extvtoc
->v_nparts
= V_NUMPAR
;
266 if (extvtoc
->v_sectorsz
== 0)
267 extvtoc
->v_sectorsz
= DEV_BSIZE
;
279 * Return partition number for this file descriptor.
281 if (ioctl(fd
, DKIOCINFO
, (caddr_t
)&dki_info
) == -1) {
291 if (dki_info
.dki_partition
> V_NUMPAR
) {
294 return ((int)dki_info
.dki_partition
);
301 write_extvtoc(int fd
, struct extvtoc
*extvtoc
)
305 struct vtoc
*oldvtocp
= &oldvtoc
;
307 * Sanity-check the vtoc
309 if (extvtoc
->v_sanity
!= VTOC_SANE
|| extvtoc
->v_nparts
> V_NUMPAR
) {
314 * since many drivers won't allow opening a device make sure
315 * all partitions aren't being set to zero. If all are zero then
316 * we have no way to set them to something else
319 for (i
= 0; i
< (int)extvtoc
->v_nparts
; i
++)
320 if (extvtoc
->v_part
[i
].p_size
> 0)
322 if (i
== (int)extvtoc
->v_nparts
)
328 if (ioctl(fd
, DKIOCSEXTVTOC
, (caddr_t
)extvtoc
) == -1) {
334 /* for disks > 1TB */
338 return (VT_EOVERFLOW
);
342 * 64-bit vtoc and extvtoc have the same field sizes
345 bcopy(extvtoc
, oldvtocp
, sizeof (struct vtoc
));
347 bzero(oldvtocp
, sizeof (struct vtoc
));
348 libadm_vtoc_copy(extvtoc
, oldvtocp
);
351 return (write_vtoc(fd
, &oldvtoc
));