From d23768d8ace32ecf5ba880a86fecb600dbc18aa5 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 16 Sep 2009 16:06:07 +0200 Subject: [PATCH] libblkid: add SUN partitions support Signed-off-by: Karel Zak --- shlibs/blkid/src/partitions/Makefile.am | 3 +- shlibs/blkid/src/partitions/partitions.c | 1 + shlibs/blkid/src/partitions/partitions.h | 1 + shlibs/blkid/src/partitions/sun.c | 168 +++++++++++++++++++++++ 4 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 shlibs/blkid/src/partitions/sun.c diff --git a/shlibs/blkid/src/partitions/Makefile.am b/shlibs/blkid/src/partitions/Makefile.am index 34d82f49..3901173a 100644 --- a/shlibs/blkid/src/partitions/Makefile.am +++ b/shlibs/blkid/src/partitions/Makefile.am @@ -11,4 +11,5 @@ libblkid_partitions_la_SOURCES = partitions.c \ aix.h \ bsd.c \ unixware.c \ - solaris_x86.c + solaris_x86.c \ + sun.c diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c index 10e4c017..130f21a4 100644 --- a/shlibs/blkid/src/partitions/partitions.c +++ b/shlibs/blkid/src/partitions/partitions.c @@ -103,6 +103,7 @@ static void partitions_free_data(blkid_probe pr, void *data); static const struct blkid_idinfo *idinfos[] = { &aix_pt_idinfo, + &sun_pt_idinfo, &bsd_pt_idinfo, &unixware_pt_idinfo, &solaris_x86_pt_idinfo diff --git a/shlibs/blkid/src/partitions/partitions.h b/shlibs/blkid/src/partitions/partitions.h index ca720828..ba8356e9 100644 --- a/shlibs/blkid/src/partitions/partitions.h +++ b/shlibs/blkid/src/partitions/partitions.h @@ -39,5 +39,6 @@ extern const struct blkid_idinfo aix_pt_idinfo; extern const struct blkid_idinfo bsd_pt_idinfo; extern const struct blkid_idinfo unixware_pt_idinfo; extern const struct blkid_idinfo solaris_x86_pt_idinfo; +extern const struct blkid_idinfo sun_pt_idinfo; #endif /* BLKID_PARTITIONS_H */ diff --git a/shlibs/blkid/src/partitions/sun.c b/shlibs/blkid/src/partitions/sun.c new file mode 100644 index 00000000..4ff000f3 --- /dev/null +++ b/shlibs/blkid/src/partitions/sun.c @@ -0,0 +1,168 @@ +/* + * sun (solaris-sparc) partition parsing code + * + * Copyright (C) 2009 Karel Zak + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include +#include +#include +#include +#include + +#include "partitions.h" + +/* Supported VTOC setting */ +#define SUN_VTOC_SANITY 0x600DDEEE /* magic number */ +#define SUN_VTOC_VERSION 1 + +#define SUN_MAXPARTITIONS 8 + +/* Partition IDs */ +#define SUN_TAG_WHOLEDISK 0x05 + +struct sun_disklabel { + unsigned char info[128]; /* Informative text string */ + + struct sun_vtoc { + uint32_t version; /* version */ + char volume[8]; /* volume name */ + uint16_t nparts; /* num of partitions */ + + struct sun_info { /* partition information */ + uint16_t id; + uint16_t flags; + } __attribute__ ((packed)) infos[8]; + + uint16_t padding; /* padding */ + uint32_t bootinfo[3]; /* info needed by mboot */ + uint32_t sanity; /* magic number */ + uint32_t reserved[10]; /* padding */ + uint32_t timestamp[8]; /* partition timestamp */ + } __attribute__ ((packed)) vtoc; + + uint32_t write_reinstruct; /* sectors to skip, writes */ + uint32_t read_reinstruct; /* sectors to skip, reads */ + unsigned char spare[148]; /* padding */ + uint16_t rspeed; /* disk rotational speed */ + uint16_t pcylcount; /* physical cylinder count */ + uint16_t sparecyl; /* extra sects per cylinder */ + uint16_t obs1; + uint16_t obs2; + uint16_t ilfact; /* interleave factor */ + uint16_t ncyl; /* data cylinder count */ + uint16_t nacyl; /* alt. cylinder count */ + uint16_t ntrks; /* tracks per cylinder <---- */ + uint16_t nsect; /* sectors per track <---- */ + uint16_t obs3; + uint16_t obs4; + + struct sun_partition { /* partitions */ + uint32_t start_cylinder; + uint32_t num_sectors; + } __attribute__ ((packed)) partitions[8]; + + uint16_t magic; /* magic number */ + uint16_t csum; /* label xor'd checksum */ +} __attribute__ ((packed)); + + +uint16_t count_checksum(struct sun_disklabel *label) +{ + uint16_t *ptr = ((uint16_t *) (label + 1)) - 1; + uint16_t sum; + + for (sum = 0; ptr >= ((uint16_t *) label);) + sum ^= *ptr--; + + return sum; +} + +static int probe_sun_pt(blkid_probe pr, const struct blkid_idmag *mag) +{ + struct sun_disklabel *l; + struct sun_partition *p; + struct sun_info *infos = NULL; + blkid_parttable tab = NULL; + blkid_partlist ls; + uint16_t nparts; + blkid_loff_t spc; + int i; + + l = (struct sun_disklabel *) blkid_probe_get_sector(pr, 0); + if (!l) + goto nothing; + + if (count_checksum(l)) { + DBG(DEBUG_LOWPROBE, printf( + "detected corrupted sun disk label -- ignore\n")); + goto nothing; + } + + if (blkid_partitions_need_typeonly(pr)) + /* caller does not ask for details about partitions */ + return 0; + + ls = blkid_probe_get_partlist(pr); + if (!ls) + goto err; + + tab = blkid_partlist_new_parttable(ls, "sun", 0); + if (!tab) + goto err; + + /* default number of partitions */ + nparts = SUN_MAXPARTITIONS; + + /* sectors per cylinder (partition offset is in cylinders...) */ + spc = be16_to_cpu(l->ntrks) * be16_to_cpu(l->nsect); + + if ((be32_to_cpu(l->vtoc.sanity) == SUN_VTOC_SANITY) && + (be32_to_cpu(l->vtoc.version) == SUN_VTOC_VERSION) && + (be16_to_cpu(l->vtoc.nparts) <= SUN_MAXPARTITIONS)) { + + nparts = be16_to_cpu(l->vtoc.nparts); + infos = l->vtoc.infos; /* for partition type */ + } + + for (i = 0, p = l->partitions; i < nparts; i++, p++) { + + blkid_loff_t start; + blkid_loff_t size; + uint16_t type = infos ? be16_to_cpu(infos[i].id) : 0; + + start = be32_to_cpu(p->start_cylinder) * spc; + size = be32_to_cpu(p->num_sectors); + + if (type == SUN_TAG_WHOLEDISK || !size) + continue; + + if (!blkid_partlist_add_partition(ls, tab, type, start, size)) + goto err; + } + return 0; + +nothing: + return 1; +err: + return -1; +} + + +const struct blkid_idinfo sun_pt_idinfo = +{ + .name = "sun", + .probefunc = probe_sun_pt, + .magics = + { + { + .magic = "\xDA\xBE", /* big-endian magic string */ + .len = 2, + .sboff = offsetof(struct sun_disklabel, magic) + }, + { NULL } + } +}; + -- 2.39.5