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