1 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- 2 3 libparted - a library for manipulating disk partitions 4 Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 19 Contributor: Matt Wilson <msw@redhat.com> 20 */ 21 22 #include <config.h> 23 24 #include <parted/parted.h> 25 #include <parted/debug.h> 26 #include <parted/endian.h> 27 28 #if ENABLE_NLS 29 # include <libintl.h> 30 # define _(String) dgettext (PACKAGE, String) 31 #else 32 # define _(String) (String) 33 #endif /* ENABLE_NLS */ 34 35 #define AIX_LABEL_MAGIC 0xc9c2d4c1 36 37 static PedDiskType aix_disk_type; 38 39 static inline int 40 aix_label_magic_get (const char *label) 41 { 42 return *(unsigned int *)label; 43 } 44 45 static inline void 46 aix_label_magic_set (char *label, int magic_val) 47 { 48 *(unsigned int *)label = magic_val; 49 } 50 51 /* Read a single sector, of length DEV->sector_size, into malloc'd storage. 52 If the read fails, free the memory and return zero without modifying *BUF. 53 Otherwise, set *BUF to the new buffer and return 1. */ 54 static int 55 read_sector (const PedDevice *dev, char **buf) 56 { 57 char *b = ped_malloc (dev->sector_size); 58 PED_ASSERT (b != NULL, return 0); 59 if (!ped_device_read (dev, b, 0, 1)) { 60 ped_free (b); 61 return 0; 62 } 63 *buf = b; 64 return 1; 65 } 66 67 static int 68 aix_probe (const PedDevice *dev) 69 { 70 PED_ASSERT (dev != NULL, return 0); 71 72 char *label; 73 if (!read_sector (dev, &label)) 74 return 0; 75 unsigned int magic = aix_label_magic_get (label); 76 ped_free (label); 77 return magic == AIX_LABEL_MAGIC; 78 } 79 80 #ifndef DISCOVER_ONLY 81 static int 82 aix_clobber (PedDevice* dev) 83 { 84 PED_ASSERT (dev != NULL, return 0); 85 86 if (!aix_probe (dev)) 87 return 0; 88 89 char *label; 90 if (!read_sector (dev, &label)) 91 return 0; 92 93 aix_label_magic_set (label, 0); 94 int result = ped_device_write (dev, label, 0, 1); 95 ped_free (label); 96 return result; 97 } 98 #endif /* !DISCOVER_ONLY */ 99 100 static PedDisk* 101 aix_alloc (const PedDevice* dev) 102 { 103 PedDisk* disk; 104 105 disk = _ped_disk_alloc (dev, &aix_disk_type); 106 if (!disk) 107 return NULL; 108 109 return disk; 110 } 111 112 static PedDisk* 113 aix_duplicate (const PedDisk* disk) 114 { 115 PedDisk* new_disk; 116 117 new_disk = ped_disk_new_fresh (disk->dev, &aix_disk_type); 118 if (!new_disk) 119 return NULL; 120 121 return new_disk; 122 } 123 124 static void 125 aix_free (PedDisk *disk) 126 { 127 _ped_disk_free (disk); 128 } 129 130 static int 131 aix_read (PedDisk* disk) 132 { 133 ped_disk_delete_all (disk); 134 ped_exception_throw (PED_EXCEPTION_NO_FEATURE, 135 PED_EXCEPTION_CANCEL, 136 _("Support for reading AIX disk labels is " 137 "is not implemented yet.")); 138 return 0; 139 } 140 141 #ifndef DISCOVER_ONLY 142 static int 143 aix_write (const PedDisk* disk) 144 { 145 ped_exception_throw (PED_EXCEPTION_NO_FEATURE, 146 PED_EXCEPTION_CANCEL, 147 _("Support for writing AIX disk labels is " 148 "is not implemented yet.")); 149 return 0; 150 } 151 #endif /* !DISCOVER_ONLY */ 152 153 static PedPartition* 154 aix_partition_new (const PedDisk* disk, PedPartitionType part_type, 155 const PedFileSystemType* fs_type, 156 PedSector start, PedSector end) 157 { 158 ped_exception_throw (PED_EXCEPTION_NO_FEATURE, 159 PED_EXCEPTION_CANCEL, 160 _("Support for adding partitions to AIX disk " 161 "labels is not implemented yet.")); 162 return NULL; 163 } 164 165 static PedPartition* 166 aix_partition_duplicate (const PedPartition* part) 167 { 168 ped_exception_throw (PED_EXCEPTION_NO_FEATURE, 169 PED_EXCEPTION_CANCEL, 170 _("Support for duplicating partitions in AIX " 171 "disk labels is not implemented yet.")); 172 return NULL; 173 } 174 175 static void 176 aix_partition_destroy (PedPartition* part) 177 { 178 PED_ASSERT (part != NULL, return); 179 180 _ped_partition_free (part); 181 } 182 183 static int 184 aix_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type) 185 { 186 ped_exception_throw (PED_EXCEPTION_NO_FEATURE, 187 PED_EXCEPTION_CANCEL, 188 _("Support for setting system type of partitions " 189 "in AIX disk labels is not implemented yet.")); 190 return 0; 191 } 192 193 static int 194 aix_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state) 195 { 196 ped_exception_throw (PED_EXCEPTION_NO_FEATURE, 197 PED_EXCEPTION_CANCEL, 198 _("Support for setting flags " 199 "in AIX disk labels is not implemented yet.")); 200 return 0; 201 } 202 203 static int 204 aix_partition_get_flag (const PedPartition* part, PedPartitionFlag flag) 205 { 206 return 0; 207 } 208 209 210 static int 211 aix_partition_is_flag_available (const PedPartition* part, 212 PedPartitionFlag flag) 213 { 214 return 0; 215 } 216 217 218 static int 219 aix_get_max_primary_partition_count (const PedDisk* disk) 220 { 221 return 4; 222 } 223 224 static int 225 aix_partition_align (PedPartition* part, const PedConstraint* constraint) 226 { 227 PED_ASSERT (part != NULL, return 0); 228 229 return 1; 230 } 231 232 static int 233 aix_partition_enumerate (PedPartition* part) 234 { 235 return 1; 236 } 237 238 static int 239 aix_alloc_metadata (PedDisk* disk) 240 { 241 return 1; 242 } 243 244 static PedDiskOps aix_disk_ops = { 245 .probe = aix_probe, 246 #ifndef DISCOVER_ONLY 247 .clobber = aix_clobber, 248 #else 249 .clobber = NULL, 250 #endif 251 .alloc = aix_alloc, 252 .duplicate = aix_duplicate, 253 .free = aix_free, 254 .read = aix_read, 255 #ifndef DISCOVER_ONLY 256 .write = aix_write, 257 #else 258 .write = NULL, 259 #endif 260 261 .partition_new = aix_partition_new, 262 .partition_duplicate = aix_partition_duplicate, 263 .partition_destroy = aix_partition_destroy, 264 .partition_set_system = aix_partition_set_system, 265 .partition_set_flag = aix_partition_set_flag, 266 .partition_get_flag = aix_partition_get_flag, 267 .partition_is_flag_available = aix_partition_is_flag_available, 268 .partition_align = aix_partition_align, 269 .partition_enumerate = aix_partition_enumerate, 270 .alloc_metadata = aix_alloc_metadata, 271 .get_max_primary_partition_count = 272 aix_get_max_primary_partition_count, 273 274 .partition_set_name = NULL, 275 .partition_get_name = NULL, 276 }; 277 278 static PedDiskType aix_disk_type = { 279 .next = NULL, 280 .name = "aix", 281 .ops = &aix_disk_ops, 282 .features = 0 283 }; 284 285 void 286 ped_disk_aix_init () 287 { 288 ped_disk_type_register (&aix_disk_type); 289 } 290 291 void 292 ped_disk_aix_done () 293 { 294 ped_disk_type_unregister (&aix_disk_type); 295 }