rdwr_vtoc.c (7c478bd9) rdwr_vtoc.c (342440ec)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22/*
22/*
23 * Copyright 1991-1997,2002 Sun Microsystems, Inc. All rights reserved.
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
24 * Use is subject to license terms.
25 */
26
27#pragma ident "%Z%%M% %I% %E% SMI"
28
29/*LINTLIBRARY*/
30
31
32#include <stdio.h>
33#include <errno.h>
34#include <memory.h>
35#include <unistd.h>
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/dkio.h>
39#include <sys/vtoc.h>
27/*LINTLIBRARY*/
28
29
30#include <stdio.h>
31#include <errno.h>
32#include <memory.h>
33#include <unistd.h>
34#include <sys/types.h>
35#include <sys/param.h>
36#include <sys/dkio.h>
37#include <sys/vtoc.h>
38#include <strings.h>
39#include <limits.h>
40
41/*
40
41/*
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.
45 */
46
47#define libadm_vtoc_copy(vs, vd) \
48 { \
49 int i; \
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; \
66 } \
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; \
71 else \
72 vd->timestamp[i] = (unsigned)vs->timestamp[i]; \
73 bcopy(vs->v_asciilabel, vd->v_asciilabel, LEN_DKL_ASCII); \
74 }
75
76
77/*
42 * Read VTOC - return partition number.
43 */
44int
45read_vtoc(int fd, struct vtoc *vtoc)
46{
47 struct dk_cinfo dki_info;
48
49 /*
50 * Read the vtoc.
51 */
52 if (ioctl(fd, DKIOCGVTOC, (caddr_t)vtoc) == -1) {
53 switch (errno) {
54 case EIO:
55 return (VT_EIO);
56 case EINVAL:
57 return (VT_EINVAL);
78 * Read VTOC - return partition number.
79 */
80int
81read_vtoc(int fd, struct vtoc *vtoc)
82{
83 struct dk_cinfo dki_info;
84
85 /*
86 * Read the vtoc.
87 */
88 if (ioctl(fd, DKIOCGVTOC, (caddr_t)vtoc) == -1) {
89 switch (errno) {
90 case EIO:
91 return (VT_EIO);
92 case EINVAL:
93 return (VT_EINVAL);
58 /* for disks > 1TB */
59 case ENOTSUP:
94 case ENOTSUP:
95 /* GPT labeled or disk > 1TB with no extvtoc support */
60 return (VT_ENOTSUP);
96 return (VT_ENOTSUP);
97 case EOVERFLOW:
98 return (VT_EOVERFLOW);
61 default:
62 return (VT_ERROR);
63 }
64 }
65
66 /*
67 * Sanity-check the vtoc.
68 */

--- 77 unchanged lines hidden (view full) ---

146 * Write the vtoc
147 */
148 if (ioctl(fd, DKIOCSVTOC, (caddr_t)vtoc) == -1) {
149 switch (errno) {
150 case EIO:
151 return (VT_EIO);
152 case EINVAL:
153 return (VT_EINVAL);
99 default:
100 return (VT_ERROR);
101 }
102 }
103
104 /*
105 * Sanity-check the vtoc.
106 */

--- 77 unchanged lines hidden (view full) ---

184 * Write the vtoc
185 */
186 if (ioctl(fd, DKIOCSVTOC, (caddr_t)vtoc) == -1) {
187 switch (errno) {
188 case EIO:
189 return (VT_EIO);
190 case EINVAL:
191 return (VT_EINVAL);
192 case ENOTSUP:
193 /* GPT labeled or disk > 1TB with no extvtoc support */
194 return (VT_ENOTSUP);
195 case EOVERFLOW:
196 return (VT_EOVERFLOW);
197 default:
198 return (VT_ERROR);
199 }
200 }
201 return (0);
202}
203
204int
205read_extvtoc(int fd, struct extvtoc *extvtoc)
206{
207 struct dk_cinfo dki_info;
208 struct vtoc oldvtoc;
209 struct vtoc *oldvtocp = &oldvtoc;
210 int ret;
211
212 /*
213 * Read the vtoc.
214 */
215 if (ioctl(fd, DKIOCGEXTVTOC, (caddr_t)extvtoc) == -1) {
216 switch (errno) {
217 case EIO:
218 return (VT_EIO);
219 case EINVAL:
220 return (VT_EINVAL);
154 /* for disks > 1TB */
155 case ENOTSUP:
156 return (VT_ENOTSUP);
221 /* for disks > 1TB */
222 case ENOTSUP:
223 return (VT_ENOTSUP);
224 case EOVERFLOW:
225 return (VT_EOVERFLOW);
226 case ENOTTY:
227
228 if ((ret = read_vtoc(fd, oldvtocp)) < 0)
229 return (ret);
230
231#ifdef _LP64
232 /*
233 * 64-bit vtoc and extvtoc have the same field sizes
234 * and offsets.
235 */
236 bcopy(oldvtocp, extvtoc, sizeof (struct extvtoc));
237#else
238 bzero(extvtoc, sizeof (struct extvtoc));
239 libadm_vtoc_copy(oldvtocp, extvtoc);
240#endif
241 return (ret);
242
243
157 default:
158 return (VT_ERROR);
159 }
160 }
244 default:
245 return (VT_ERROR);
246 }
247 }
248
249 /*
250 * Sanity-check the vtoc.
251 */
252 if (extvtoc->v_sanity != VTOC_SANE) {
253 return (VT_EINVAL);
254 }
255
256 switch (extvtoc->v_version) {
257 case 0:
258 /*
259 * For pre-version 1 vtoc keep same functionality
260 * as read_vtoc.
261 */
262
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;
268
269 break;
270
271 case V_VERSION:
272 break;
273
274 default:
275 return (VT_EINVAL);
276 }
277
278 /*
279 * Return partition number for this file descriptor.
280 */
281 if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) {
282 switch (errno) {
283 case EIO:
284 return (VT_EIO);
285 case EINVAL:
286 return (VT_EINVAL);
287 default:
288 return (VT_ERROR);
289 }
290 }
291 if (dki_info.dki_partition > V_NUMPAR) {
292 return (VT_EINVAL);
293 }
294 return ((int)dki_info.dki_partition);
295}
296
297/*
298 * Write ext VTOC.
299 */
300int
301write_extvtoc(int fd, struct extvtoc *extvtoc)
302{
303 int i;
304 struct vtoc oldvtoc;
305 struct vtoc *oldvtocp = &oldvtoc;
306 /*
307 * Sanity-check the vtoc
308 */
309 if (extvtoc->v_sanity != VTOC_SANE || extvtoc->v_nparts > V_NUMPAR) {
310 return (-1);
311 }
312
313 /*
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
317 */
318
319 for (i = 0; i < (int)extvtoc->v_nparts; i++)
320 if (extvtoc->v_part[i].p_size > 0)
321 break;
322 if (i == (int)extvtoc->v_nparts)
323 return (-1);
324
325 /*
326 * Write the extvtoc
327 */
328 if (ioctl(fd, DKIOCSEXTVTOC, (caddr_t)extvtoc) == -1) {
329 switch (errno) {
330 case EIO:
331 return (VT_EIO);
332 case EINVAL:
333 return (VT_EINVAL);
334 /* for disks > 1TB */
335 case ENOTSUP:
336 return (VT_ENOTSUP);
337 case EOVERFLOW:
338 return (VT_EOVERFLOW);
339 case ENOTTY:
340#ifdef _LP64
341 /*
342 * 64-bit vtoc and extvtoc have the same field sizes
343 * and offsets.
344 */
345 bcopy(extvtoc, oldvtocp, sizeof (struct vtoc));
346#else
347 bzero(oldvtocp, sizeof (struct vtoc));
348 libadm_vtoc_copy(extvtoc, oldvtocp);
349
350#endif
351 return (write_vtoc(fd, &oldvtoc));
352
353 default:
354 return (VT_ERROR);
355 }
356 }
357
161 return (0);
162}
358 return (0);
359}