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. 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 */ 22 /* 23 * Copyright 1991-1997,2002 Sun Microsystems, Inc. All rights reserved. 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> 40 41 /* 42 * Read VTOC - return partition number. 43 */ 44 int 45 read_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); 58 /* for disks > 1TB */ 59 case ENOTSUP: 60 return (VT_ENOTSUP); 61 default: 62 return (VT_ERROR); 63 } 64 } 65 66 /* 67 * Sanity-check the vtoc. 68 */ 69 if (vtoc->v_sanity != VTOC_SANE) { 70 return (VT_EINVAL); 71 } 72 73 /* 74 * Convert older-style vtoc's. 75 */ 76 switch (vtoc->v_version) { 77 case 0: 78 /* 79 * No vtoc information. Install default 80 * nparts/sectorsz and version. We are 81 * assuming that the driver returns the 82 * current partition information correctly. 83 */ 84 85 vtoc->v_version = V_VERSION; 86 if (vtoc->v_nparts == 0) 87 vtoc->v_nparts = V_NUMPAR; 88 if (vtoc->v_sectorsz == 0) 89 vtoc->v_sectorsz = DEV_BSIZE; 90 91 break; 92 93 case V_VERSION: 94 break; 95 96 default: 97 return (VT_EINVAL); 98 } 99 100 /* 101 * Return partition number for this file descriptor. 102 */ 103 if (ioctl(fd, DKIOCINFO, (caddr_t)&dki_info) == -1) { 104 switch (errno) { 105 case EIO: 106 return (VT_EIO); 107 case EINVAL: 108 return (VT_EINVAL); 109 default: 110 return (VT_ERROR); 111 } 112 } 113 if (dki_info.dki_partition > V_NUMPAR) { 114 return (VT_EINVAL); 115 } 116 return ((int)dki_info.dki_partition); 117 } 118 119 /* 120 * Write VTOC 121 */ 122 int 123 write_vtoc(int fd, struct vtoc *vtoc) 124 { 125 int i; 126 /* 127 * Sanity-check the vtoc 128 */ 129 if (vtoc->v_sanity != VTOC_SANE || vtoc->v_nparts > V_NUMPAR) { 130 return (-1); 131 } 132 133 /* 134 * since many drivers won't allow opening a device make sure 135 * all partitions aren't being set to zero. If all are zero then 136 * we have no way to set them to something else 137 */ 138 139 for (i = 0; i < (int)vtoc->v_nparts; i++) 140 if (vtoc->v_part[i].p_size > 0) 141 break; 142 if (i == (int)vtoc->v_nparts) 143 return (-1); 144 145 /* 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); 154 /* for disks > 1TB */ 155 case ENOTSUP: 156 return (VT_ENOTSUP); 157 default: 158 return (VT_ERROR); 159 } 160 } 161 return (0); 162 } 163