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 (the "License"). 6 * You may not use this file except in compliance with the License. 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 /* 23 * Copyright 2014 Garrett D'Amore <garrett@damore.org> 24 * 25 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 30 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 31 /* All Rights Reserved */ 32 33 34 #ifndef _SYS_VTOC_H 35 #define _SYS_VTOC_H 36 37 #include <sys/dklabel.h> 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /* 44 * Note: the VTOC is not implemented fully, nor in the manner 45 * that AT&T implements it. AT&T puts the vtoc structure 46 * into a sector, usually the second sector (pdsector is first). 47 * 48 * Sun incorporates the tag, flag, version, and volume vtoc fields into 49 * its Disk Label, which already has some vtoc-equivalent fields. 50 * Upon reading the vtoc with read_vtoc(), the following exceptions 51 * occur: 52 * v_bootinfo [all] returned as zero 53 * v_sanity returned as VTOC_SANE 54 * if Disk Label was sane 55 * v_sectorsz returned as 512 56 * v_reserved [all] retunred as zero 57 * timestamp [all] returned as zero 58 * 59 * See dklabel.h, read_vtoc(), and write_vtoc(). 60 */ 61 62 #define V_NUMPAR NDKMAP /* The number of partitions */ 63 /* (from dkio.h) */ 64 65 #define VTOC_SANE 0x600DDEEE /* Indicates a sane VTOC */ 66 #define V_VERSION 0x01 /* layout version number */ 67 #define V_EXTVERSION V_VERSION /* extvtoc layout version number */ 68 69 /* 70 * Partition identification tags 71 */ 72 #define V_UNASSIGNED 0x00 /* unassigned partition */ 73 #define V_BOOT 0x01 /* Boot partition */ 74 #define V_ROOT 0x02 /* Root filesystem */ 75 #define V_SWAP 0x03 /* Swap filesystem */ 76 #define V_USR 0x04 /* Usr filesystem */ 77 #define V_BACKUP 0x05 /* full disk */ 78 #define V_STAND 0x06 /* Stand partition */ 79 #define V_VAR 0x07 /* Var partition */ 80 #define V_HOME 0x08 /* Home partition */ 81 #define V_ALTSCTR 0x09 /* Alternate sector partition */ 82 #define V_CACHE 0x0a /* Cache (cachefs) partition */ 83 84 /* Tags for EFI/GPT labels */ 85 #define V_RESERVED 0x0b /* SMI reserved data */ 86 #define V_SYSTEM 0x0c /* EFI/GPT system partition */ 87 #define V_BIOS_BOOT 0x18 /* BIOS Boot partition */ 88 89 #define V_UNKNOWN 0xff /* Unknown partition */ 90 91 /* 92 * Partition permission flags 93 */ 94 #define V_UNMNT 0x01 /* Unmountable partition */ 95 #define V_RONLY 0x10 /* Read only */ 96 97 /* 98 * error codes for reading & writing vtoc 99 */ 100 #define VT_ERROR (-2) /* errno supplies specific error */ 101 #define VT_EIO (-3) /* I/O error accessing vtoc */ 102 #define VT_EINVAL (-4) /* illegal value in vtoc or request */ 103 #define VT_ENOTSUP (-5) /* VTOC op. not supported */ 104 #define VT_ENOSPC (-6) /* requested space not found */ 105 #define VT_EOVERFLOW (-7) /* VTOC op. data struct limited */ 106 107 struct partition { 108 ushort_t p_tag; /* ID tag of partition */ 109 ushort_t p_flag; /* permission flags */ 110 daddr_t p_start; /* start sector no of partition */ 111 long p_size; /* # of blocks in partition */ 112 }; 113 114 struct vtoc { 115 unsigned long v_bootinfo[3]; /* info needed by mboot (unsupported) */ 116 unsigned long v_sanity; /* to verify vtoc sanity */ 117 unsigned long v_version; /* layout version */ 118 char v_volume[LEN_DKL_VVOL]; /* volume name */ 119 ushort_t v_sectorsz; /* sector size in bytes */ 120 ushort_t v_nparts; /* number of partitions */ 121 unsigned long v_reserved[10]; /* free space */ 122 struct partition v_part[V_NUMPAR]; /* partition headers */ 123 time_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */ 124 char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ 125 }; 126 127 struct extpartition { 128 ushort_t p_tag; /* ID tag of partition */ 129 ushort_t p_flag; /* permission flags */ 130 ushort_t p_pad[2]; 131 diskaddr_t p_start; /* start sector no of partition */ 132 diskaddr_t p_size; /* # of blocks in partition */ 133 }; 134 135 136 struct extvtoc { 137 uint64_t v_bootinfo[3]; /* info needed by mboot (unsupported) */ 138 uint64_t v_sanity; /* to verify vtoc sanity */ 139 uint64_t v_version; /* layout version */ 140 char v_volume[LEN_DKL_VVOL]; /* volume name */ 141 ushort_t v_sectorsz; /* sector size in bytes */ 142 ushort_t v_nparts; /* number of partitions */ 143 ushort_t pad[2]; 144 uint64_t v_reserved[10]; 145 struct extpartition v_part[V_NUMPAR]; /* partition headers */ 146 uint64_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */ 147 char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ 148 }; 149 150 #ifdef _KERNEL 151 #define extvtoctovtoc(extv, v) \ 152 { \ 153 int i; \ 154 v.v_bootinfo[0] = (unsigned long)extv.v_bootinfo[0]; \ 155 v.v_bootinfo[1] = (unsigned long)extv.v_bootinfo[1]; \ 156 v.v_bootinfo[2] = (unsigned long)extv.v_bootinfo[2]; \ 157 v.v_sanity = (unsigned long)extv.v_sanity; \ 158 v.v_version = (unsigned long)extv.v_version; \ 159 bcopy(extv.v_volume, v.v_volume, LEN_DKL_VVOL); \ 160 v.v_sectorsz = extv.v_sectorsz; \ 161 v.v_nparts = extv.v_nparts; \ 162 for (i = 0; i < 10; i++) \ 163 v.v_reserved[i] = (unsigned long)extv.v_reserved[i]; \ 164 for (i = 0; i < V_NUMPAR; i++) { \ 165 v.v_part[i].p_tag = extv.v_part[i].p_tag; \ 166 v.v_part[i].p_flag = extv.v_part[i].p_flag; \ 167 v.v_part[i].p_start = (daddr_t)extv.v_part[i].p_start; \ 168 v.v_part[i].p_size = (long)extv.v_part[i].p_size; \ 169 v.timestamp[i] = (time_t)extv.timestamp[i]; \ 170 } \ 171 bcopy(extv.v_asciilabel, v.v_asciilabel, LEN_DKL_ASCII); \ 172 } 173 174 #define vtoctoextvtoc(v, extv) \ 175 { \ 176 int i; \ 177 extv.v_bootinfo[0] = (uint64_t)v.v_bootinfo[0]; \ 178 extv.v_bootinfo[1] = (uint64_t)v.v_bootinfo[1]; \ 179 extv.v_bootinfo[2] = (uint64_t)v.v_bootinfo[2]; \ 180 extv.v_sanity = (uint64_t)v.v_sanity; \ 181 extv.v_version = (uint64_t)v.v_version; \ 182 bcopy(v.v_volume, extv.v_volume, LEN_DKL_VVOL); \ 183 extv.v_sectorsz = v.v_sectorsz; \ 184 extv.v_nparts = v.v_nparts; \ 185 for (i = 0; i < 10; i++) \ 186 extv.v_reserved[i] = (uint64_t)v.v_reserved[i]; \ 187 for (i = 0; i < V_NUMPAR; i++) { \ 188 extv.v_part[i].p_tag = v.v_part[i].p_tag; \ 189 extv.v_part[i].p_flag = v.v_part[i].p_flag; \ 190 extv.v_part[i].p_start = \ 191 (diskaddr_t)(unsigned long)v.v_part[i].p_start; \ 192 extv.v_part[i].p_size = \ 193 (diskaddr_t)(unsigned long)v.v_part[i].p_size; \ 194 extv.timestamp[i] = (uint64_t)v.timestamp[i]; \ 195 } \ 196 bcopy(v.v_asciilabel, extv.v_asciilabel, LEN_DKL_ASCII); \ 197 } 198 #endif /* _KERNEL */ 199 200 #if defined(_SYSCALL32) 201 struct partition32 { 202 uint16_t p_tag; /* ID tag of partition */ 203 uint16_t p_flag; /* permission flags */ 204 daddr32_t p_start; /* start sector no of partition */ 205 int32_t p_size; /* # of blocks in partition */ 206 }; 207 208 struct vtoc32 { 209 uint32_t v_bootinfo[3]; /* info needed by mboot (unsupported) */ 210 uint32_t v_sanity; /* to verify vtoc sanity */ 211 uint32_t v_version; /* layout version */ 212 char v_volume[LEN_DKL_VVOL]; /* volume name */ 213 uint16_t v_sectorsz; /* sector size in bytes */ 214 uint16_t v_nparts; /* number of partitions */ 215 uint32_t v_reserved[10]; /* free space */ 216 struct partition32 v_part[V_NUMPAR]; /* partition headers */ 217 time32_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */ 218 char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ 219 }; 220 221 #define vtoc32tovtoc(v32, v) \ 222 { \ 223 int i; \ 224 v.v_bootinfo[0] = v32.v_bootinfo[0]; \ 225 v.v_bootinfo[1] = v32.v_bootinfo[1]; \ 226 v.v_bootinfo[2] = v32.v_bootinfo[2]; \ 227 v.v_sanity = v32.v_sanity; \ 228 v.v_version = v32.v_version; \ 229 bcopy(v32.v_volume, v.v_volume, LEN_DKL_VVOL); \ 230 v.v_sectorsz = v32.v_sectorsz; \ 231 v.v_nparts = v32.v_nparts; \ 232 v.v_version = v32.v_version; \ 233 for (i = 0; i < 10; i++) \ 234 v.v_reserved[i] = v32.v_reserved[i]; \ 235 for (i = 0; i < V_NUMPAR; i++) { \ 236 v.v_part[i].p_tag = (ushort_t)v32.v_part[i].p_tag; \ 237 v.v_part[i].p_flag = (ushort_t)v32.v_part[i].p_flag; \ 238 v.v_part[i].p_start = (unsigned)v32.v_part[i].p_start; \ 239 v.v_part[i].p_size = (unsigned)v32.v_part[i].p_size; \ 240 } \ 241 for (i = 0; i < V_NUMPAR; i++) \ 242 v.timestamp[i] = (time_t)v32.timestamp[i]; \ 243 bcopy(v32.v_asciilabel, v.v_asciilabel, LEN_DKL_ASCII); \ 244 } 245 246 #define vtoc32toextvtoc(v32, extv) \ 247 { \ 248 int i; \ 249 extv.v_bootinfo[0] = v32.v_bootinfo[0]; \ 250 extv.v_bootinfo[1] = v32.v_bootinfo[1]; \ 251 extv.v_bootinfo[2] = v32.v_bootinfo[2]; \ 252 extv.v_sanity = v32.v_sanity; \ 253 extv.v_version = v32.v_version; \ 254 bcopy(v32.v_volume, extv.v_volume, LEN_DKL_VVOL); \ 255 extv.v_sectorsz = v32.v_sectorsz; \ 256 extv.v_nparts = v32.v_nparts; \ 257 extv.v_version = v32.v_version; \ 258 for (i = 0; i < 10; i++) \ 259 extv.v_reserved[i] = v32.v_reserved[i]; \ 260 for (i = 0; i < V_NUMPAR; i++) { \ 261 extv.v_part[i].p_tag = (ushort_t)v32.v_part[i].p_tag; \ 262 extv.v_part[i].p_flag = (ushort_t)v32.v_part[i].p_flag; \ 263 extv.v_part[i].p_start = (diskaddr_t)v32.v_part[i].p_start; \ 264 extv.v_part[i].p_size = (diskaddr_t)v32.v_part[i].p_size; \ 265 extv.timestamp[i] = (time_t)v32.timestamp[i]; \ 266 } \ 267 bcopy(v32.v_asciilabel, extv.v_asciilabel, LEN_DKL_ASCII); \ 268 } 269 270 271 #define vtoctovtoc32(v, v32) \ 272 { \ 273 int i; \ 274 v32.v_bootinfo[0] = v.v_bootinfo[0]; \ 275 v32.v_bootinfo[1] = v.v_bootinfo[1]; \ 276 v32.v_bootinfo[2] = v.v_bootinfo[2]; \ 277 v32.v_sanity = v.v_sanity; \ 278 v32.v_version = v.v_version; \ 279 bcopy(v.v_volume, v32.v_volume, LEN_DKL_VVOL); \ 280 v32.v_sectorsz = v.v_sectorsz; \ 281 v32.v_nparts = v.v_nparts; \ 282 v32.v_version = v.v_version; \ 283 for (i = 0; i < 10; i++) \ 284 v32.v_reserved[i] = v.v_reserved[i]; \ 285 for (i = 0; i < V_NUMPAR; i++) { \ 286 v32.v_part[i].p_tag = (ushort_t)v.v_part[i].p_tag; \ 287 v32.v_part[i].p_flag = (ushort_t)v.v_part[i].p_flag; \ 288 v32.v_part[i].p_start = (unsigned)v.v_part[i].p_start; \ 289 v32.v_part[i].p_size = (unsigned)v.v_part[i].p_size; \ 290 } \ 291 for (i = 0; i < V_NUMPAR; i++) { \ 292 if (v.timestamp[i] > TIME32_MAX) \ 293 v32.timestamp[i] = TIME32_MAX; \ 294 else \ 295 v32.timestamp[i] = (time32_t)v.timestamp[i]; \ 296 } \ 297 bcopy(v.v_asciilabel, v32.v_asciilabel, LEN_DKL_ASCII); \ 298 } 299 300 #define extvtoctovtoc32(extv, v32) \ 301 { \ 302 int i; \ 303 v32.v_bootinfo[0] = extv.v_bootinfo[0]; \ 304 v32.v_bootinfo[1] = extv.v_bootinfo[1]; \ 305 v32.v_bootinfo[2] = extv.v_bootinfo[2]; \ 306 v32.v_sanity = extv.v_sanity; \ 307 v32.v_version = extv.v_version; \ 308 bcopy(extv.v_volume, v32.v_volume, LEN_DKL_VVOL); \ 309 v32.v_sectorsz = extv.v_sectorsz; \ 310 v32.v_nparts = extv.v_nparts; \ 311 v32.v_version = extv.v_version; \ 312 for (i = 0; i < 10; i++) \ 313 v32.v_reserved[i] = extv.v_reserved[i]; \ 314 for (i = 0; i < V_NUMPAR; i++) { \ 315 v32.v_part[i].p_tag = (ushort_t)extv.v_part[i].p_tag; \ 316 v32.v_part[i].p_flag = (ushort_t)extv.v_part[i].p_flag; \ 317 v32.v_part[i].p_start = (unsigned)extv.v_part[i].p_start; \ 318 v32.v_part[i].p_size = (unsigned)extv.v_part[i].p_size; \ 319 } \ 320 for (i = 0; i < V_NUMPAR; i++) { \ 321 if (extv.timestamp[i] > TIME32_MAX) \ 322 v32.timestamp[i] = TIME32_MAX; \ 323 else \ 324 v32.timestamp[i] = (time32_t)extv.timestamp[i]; \ 325 } \ 326 bcopy(extv.v_asciilabel, v32.v_asciilabel, LEN_DKL_ASCII); \ 327 } 328 329 330 #endif /* _SYSCALL32 */ 331 332 /* 333 * These defines are the mode parameter for the checksum routines. 334 */ 335 #define CK_CHECKSUM 0 /* check checksum */ 336 #define CK_MAKESUM 1 /* generate checksum */ 337 338 extern int read_vtoc(int, struct vtoc *); 339 extern int write_vtoc(int, struct vtoc *); 340 extern int read_extvtoc(int, struct extvtoc *); 341 extern int write_extvtoc(int, struct extvtoc *); 342 343 #ifdef __cplusplus 344 } 345 #endif 346 347 #endif /* _SYS_VTOC_H */ 348