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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * libparted - a library for manipulating disk partitions 28 * 29 * This module recognizes the Solaris x86 VTOC so that the 30 * partition can be identified as "solaris". 31 * 32 * Mark Logan <mark.logan@sun.com> 33 */ 34 35 #include <config.h> 36 37 #include <parted/parted.h> 38 #include <parted/endian.h> 39 #include <parted/debug.h> 40 41 #if ENABLE_NLS 42 #include <libintl.h> 43 #define _(String) dgettext(PACKAGE, String) 44 #else 45 #define _(String) (String) 46 #endif /* ENABLE_NLS */ 47 48 #include <unistd.h> 49 #include <string.h> 50 51 #define BLOCK_SIZES ((int[2]) {512, 0}) 52 53 #define VTOC_SANE 0x600DDEEE 54 #define LEN_DKL_VVOL 8 55 #define V_NUMPAR 16 /* # of logical partitions */ 56 #define LEN_DKL_ASCII 128 /* length of dkl_asciilabel */ 57 58 #define LEN_DKL_PAD \ 59 (512 - \ 60 ((5 * sizeof (uint32_t)) + \ 61 LEN_DKL_VVOL + \ 62 (2 * sizeof (uint16_t)) + \ 63 (10 * sizeof (uint32_t)) + \ 64 (V_NUMPAR * sizeof (struct partition)) + \ 65 (V_NUMPAR * sizeof (uint32_t)) + \ 66 LEN_DKL_ASCII + \ 67 (2 * (sizeof (uint16_t))))) 68 69 #define DKL_MAGIC 0xDABE /* magic number */ 70 71 struct partition { 72 unsigned short p_tag; /* ID tag of partition */ 73 unsigned short p_flag; /* permission flags */ 74 long p_start; /* start sector no of partition */ 75 long p_size; /* # of blocks in partition */ 76 }; 77 78 struct vtoc { 79 unsigned long v_bootinfo[3]; /* info for mboot (unsupported) */ 80 unsigned long v_sanity; /* to verify vtoc sanity */ 81 unsigned long v_version; /* layout version */ 82 char v_volume[LEN_DKL_VVOL]; /* volume name */ 83 unsigned short v_sectorsz; /* sector size in bytes */ 84 unsigned short v_nparts; /* number of partitions */ 85 unsigned long v_reserved[10]; /* free space */ 86 struct partition v_part[V_NUMPAR]; /* partition headers */ 87 int32_t timestamp[V_NUMPAR]; /* partition timestamp (unsupported) */ 88 char v_asciilabel[LEN_DKL_ASCII]; /* for compatibility */ 89 char dkl_pad[LEN_DKL_PAD]; /* unused part of 512 bytes */ 90 uint16_t dkl_magic; /* identifies this label format */ 91 uint16_t dkl_cksum; /* xor checksum of sector */ 92 }; 93 94 static PedGeometry* 95 solaris_x86_probe(PedGeometry* geom) 96 { 97 int8_t buf[512 * 3]; 98 struct vtoc *pvtoc; 99 uint16_t *dkl_magic; 100 101 if (geom->length < 5) 102 return (0); 103 if (!ped_geometry_read(geom, buf, 1, 1)) 104 return (0); 105 106 pvtoc = (struct vtoc *)buf; 107 108 if (pvtoc->v_sanity == VTOC_SANE && pvtoc->dkl_magic == DKL_MAGIC) { 109 PedSector block_size = pvtoc->v_sectorsz / 512; 110 /* 111 * Use the size of the backup slice: 112 */ 113 PedSector block_count = pvtoc->v_part[2].p_size; 114 return ped_geometry_new(geom->dev, geom->start, 115 block_size * block_count); 116 } 117 118 return (NULL); 119 } 120 121 #ifndef DISCOVER_ONLY 122 static int 123 solaris_x86_clobber(PedGeometry* geom) 124 { 125 char buf[512*3]; 126 127 if (!ped_geometry_read(geom, buf, 1, 1)) 128 return (0); 129 130 memset(buf, 0, sizeof (struct vtoc)); 131 132 return (ped_geometry_write(geom, buf, 1, 1)); 133 } 134 #endif /* !DISCOVER_ONLY */ 135 136 static PedFileSystemOps solaris_x86_ops = { 137 .probe = solaris_x86_probe, 138 #ifndef DISCOVER_ONLY 139 .clobber = solaris_x86_clobber, 140 #else 141 .clobber = NULL, 142 #endif 143 .open = NULL, 144 .create = NULL, 145 .close = NULL, 146 .check = NULL, 147 .copy = NULL, 148 .resize = NULL, 149 .get_create_constraint = NULL, 150 .get_resize_constraint = NULL, 151 .get_copy_constraint = NULL 152 }; 153 154 static PedFileSystemType solaris_x86_type = { 155 .next = NULL, 156 .ops = &solaris_x86_ops, 157 .name = "solaris", 158 .block_sizes = BLOCK_SIZES 159 }; 160 161 void 162 ped_file_system_solaris_x86_init() 163 { 164 ped_file_system_type_register(&solaris_x86_type); 165 } 166 167 void 168 ped_file_system_solaris_x86_done() 169 { 170 ped_file_system_type_unregister(&solaris_x86_type); 171 }