blob: 9e7a3e26570a007a2918462c019cd381c64c2c7b [file] [log] [blame]
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
libparted - a library for manipulating disk partitions
Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contributor: Matt Wilson <msw@redhat.com>
*/
#include <config.h>
#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/endian.h>
#if ENABLE_NLS
# include <libintl.h>
# define _(String) dgettext (PACKAGE, String)
#else
# define _(String) (String)
#endif /* ENABLE_NLS */
#define AIX_LABEL_MAGIC 0xc9c2d4c1
static PedDiskType aix_disk_type;
static inline int
aix_label_magic_get (const char *label)
{
return *(unsigned int *)label;
}
static inline void
aix_label_magic_set (char *label, int magic_val)
{
*(unsigned int *)label = magic_val;
}
/* Read a single sector, of length DEV->sector_size, into malloc'd storage.
If the read fails, free the memory and return zero without modifying *BUF.
Otherwise, set *BUF to the new buffer and return 1. */
static int
read_sector (const PedDevice *dev, char **buf)
{
char *b = ped_malloc (dev->sector_size);
PED_ASSERT (b != NULL, return 0);
if (!ped_device_read (dev, b, 0, 1)) {
ped_free (b);
return 0;
}
*buf = b;
return 1;
}
static int
aix_probe (const PedDevice *dev)
{
PED_ASSERT (dev != NULL, return 0);
char *label;
if (!read_sector (dev, &label))
return 0;
unsigned int magic = aix_label_magic_get (label);
ped_free (label);
return magic == AIX_LABEL_MAGIC;
}
#ifndef DISCOVER_ONLY
static int
aix_clobber (PedDevice* dev)
{
PED_ASSERT (dev != NULL, return 0);
if (!aix_probe (dev))
return 0;
char *label;
if (!read_sector (dev, &label))
return 0;
aix_label_magic_set (label, 0);
int result = ped_device_write (dev, label, 0, 1);
ped_free (label);
return result;
}
#endif /* !DISCOVER_ONLY */
static PedDisk*
aix_alloc (const PedDevice* dev)
{
PedDisk* disk;
disk = _ped_disk_alloc (dev, &aix_disk_type);
if (!disk)
return NULL;
return disk;
}
static PedDisk*
aix_duplicate (const PedDisk* disk)
{
PedDisk* new_disk;
new_disk = ped_disk_new_fresh (disk->dev, &aix_disk_type);
if (!new_disk)
return NULL;
return new_disk;
}
static void
aix_free (PedDisk *disk)
{
_ped_disk_free (disk);
}
static int
aix_read (PedDisk* disk)
{
ped_disk_delete_all (disk);
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
PED_EXCEPTION_CANCEL,
_("Support for reading AIX disk labels is "
"is not implemented yet."));
return 0;
}
#ifndef DISCOVER_ONLY
static int
aix_write (const PedDisk* disk)
{
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
PED_EXCEPTION_CANCEL,
_("Support for writing AIX disk labels is "
"is not implemented yet."));
return 0;
}
#endif /* !DISCOVER_ONLY */
static PedPartition*
aix_partition_new (const PedDisk* disk, PedPartitionType part_type,
const PedFileSystemType* fs_type,
PedSector start, PedSector end)
{
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
PED_EXCEPTION_CANCEL,
_("Support for adding partitions to AIX disk "
"labels is not implemented yet."));
return NULL;
}
static PedPartition*
aix_partition_duplicate (const PedPartition* part)
{
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
PED_EXCEPTION_CANCEL,
_("Support for duplicating partitions in AIX "
"disk labels is not implemented yet."));
return NULL;
}
static void
aix_partition_destroy (PedPartition* part)
{
PED_ASSERT (part != NULL, return);
_ped_partition_free (part);
}
static int
aix_partition_set_system (PedPartition* part, const PedFileSystemType* fs_type)
{
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
PED_EXCEPTION_CANCEL,
_("Support for setting system type of partitions "
"in AIX disk labels is not implemented yet."));
return 0;
}
static int
aix_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
{
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
PED_EXCEPTION_CANCEL,
_("Support for setting flags "
"in AIX disk labels is not implemented yet."));
return 0;
}
static int
aix_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
{
return 0;
}
static int
aix_partition_is_flag_available (const PedPartition* part,
PedPartitionFlag flag)
{
return 0;
}
static int
aix_get_max_primary_partition_count (const PedDisk* disk)
{
return 4;
}
static int
aix_partition_align (PedPartition* part, const PedConstraint* constraint)
{
PED_ASSERT (part != NULL, return 0);
return 1;
}
static int
aix_partition_enumerate (PedPartition* part)
{
return 1;
}
static int
aix_alloc_metadata (PedDisk* disk)
{
return 1;
}
static PedDiskOps aix_disk_ops = {
probe: aix_probe,
#ifndef DISCOVER_ONLY
clobber: aix_clobber,
#else
clobber: NULL,
#endif
alloc: aix_alloc,
duplicate: aix_duplicate,
free: aix_free,
read: aix_read,
#ifndef DISCOVER_ONLY
write: aix_write,
#else
write: NULL,
#endif
partition_new: aix_partition_new,
partition_duplicate: aix_partition_duplicate,
partition_destroy: aix_partition_destroy,
partition_set_system: aix_partition_set_system,
partition_set_flag: aix_partition_set_flag,
partition_get_flag: aix_partition_get_flag,
partition_is_flag_available: aix_partition_is_flag_available,
partition_align: aix_partition_align,
partition_enumerate: aix_partition_enumerate,
alloc_metadata: aix_alloc_metadata,
get_max_primary_partition_count:
aix_get_max_primary_partition_count,
partition_set_name: NULL,
partition_get_name: NULL,
};
static PedDiskType aix_disk_type = {
next: NULL,
name: "aix",
ops: &aix_disk_ops,
features: 0
};
void
ped_disk_aix_init ()
{
ped_disk_type_register (&aix_disk_type);
}
void
ped_disk_aix_done ()
{
ped_disk_type_unregister (&aix_disk_type);
}