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 }