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 */