~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to libblkid/src/partitions/sun.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * sun (solaris-sparc) partition parsing code
 
3
 *
 
4
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
 
5
 *
 
6
 * This file may be redistributed under the terms of the
 
7
 * GNU Lesser General Public License.
 
8
 */
 
9
#include <stdio.h>
 
10
#include <string.h>
 
11
#include <stdlib.h>
 
12
#include <stdint.h>
 
13
#include <stddef.h>
 
14
 
 
15
#include "partitions.h"
 
16
 
 
17
/* Supported VTOC setting */
 
18
#define SUN_VTOC_SANITY         0x600DDEEE      /* magic number */
 
19
#define SUN_VTOC_VERSION        1
 
20
 
 
21
#define SUN_MAXPARTITIONS       8
 
22
 
 
23
/* Partition IDs */
 
24
#define SUN_TAG_WHOLEDISK          0x05
 
25
 
 
26
struct sun_disklabel {
 
27
        unsigned char info[128];   /* Informative text string */
 
28
 
 
29
        struct sun_vtoc {
 
30
                uint32_t version;     /* version */
 
31
                char     volume[8];   /* volume name */
 
32
                uint16_t nparts;      /* num of partitions */
 
33
 
 
34
                struct sun_info {     /* partition information */
 
35
                        uint16_t id;  /* tag */
 
36
                        uint16_t flags;
 
37
                } __attribute__ ((packed)) infos[8];
 
38
 
 
39
                uint16_t padding;      /* padding */
 
40
                uint32_t bootinfo[3];  /* info needed by mboot */
 
41
                uint32_t sanity;       /* magic number */
 
42
                uint32_t reserved[10]; /* padding */
 
43
                uint32_t timestamp[8]; /* partition timestamp */
 
44
        } __attribute__ ((packed)) vtoc;
 
45
 
 
46
        uint32_t write_reinstruct;     /* sectors to skip, writes */
 
47
        uint32_t read_reinstruct;      /* sectors to skip, reads */
 
48
        unsigned char spare[148];      /* padding */
 
49
        uint16_t rspeed;               /* disk rotational speed */
 
50
        uint16_t pcylcount;            /* physical cylinder count */
 
51
        uint16_t sparecyl;             /* extra sects per cylinder */
 
52
        uint16_t obs1;
 
53
        uint16_t obs2;
 
54
        uint16_t ilfact;               /* interleave factor */
 
55
        uint16_t ncyl;                 /* data cylinder count */
 
56
        uint16_t nacyl;                /* alt. cylinder count */
 
57
        uint16_t ntrks;                /* tracks per cylinder   <---- */
 
58
        uint16_t nsect;                /* sectors per track     <---- */
 
59
        uint16_t obs3;
 
60
        uint16_t obs4;
 
61
 
 
62
        struct sun_partition {         /* partitions */
 
63
                uint32_t start_cylinder;
 
64
                uint32_t num_sectors;
 
65
        } __attribute__ ((packed)) partitions[8];
 
66
 
 
67
        uint16_t magic;                /* magic number */
 
68
        uint16_t csum;                 /* label xor'd checksum */
 
69
} __attribute__ ((packed));
 
70
 
 
71
 
 
72
uint16_t count_checksum(struct sun_disklabel *label)
 
73
{
 
74
        uint16_t *ptr = ((uint16_t *) (label + 1)) - 1;
 
75
        uint16_t sum;
 
76
 
 
77
        for (sum = 0; ptr >= ((uint16_t *) label);)
 
78
                sum ^= *ptr--;
 
79
 
 
80
        return sum;
 
81
}
 
82
 
 
83
static int probe_sun_pt(blkid_probe pr,
 
84
                const struct blkid_idmag *mag __attribute__((__unused__)))
 
85
{
 
86
        struct sun_disklabel *l;
 
87
        struct sun_partition *p;
 
88
        blkid_parttable tab = NULL;
 
89
        blkid_partlist ls;
 
90
        uint16_t nparts;
 
91
        blkid_loff_t spc;
 
92
        int i, use_vtoc;
 
93
 
 
94
        l = (struct sun_disklabel *) blkid_probe_get_sector(pr, 0);
 
95
        if (!l)
 
96
                goto nothing;
 
97
 
 
98
        if (count_checksum(l)) {
 
99
                DBG(DEBUG_LOWPROBE, printf(
 
100
                        "detected corrupted sun disk label -- ignore\n"));
 
101
                goto nothing;
 
102
        }
 
103
 
 
104
        if (blkid_partitions_need_typeonly(pr))
 
105
                /* caller does not ask for details about partitions */
 
106
                return 0;
 
107
 
 
108
        ls = blkid_probe_get_partlist(pr);
 
109
        if (!ls)
 
110
                goto err;
 
111
 
 
112
        tab = blkid_partlist_new_parttable(ls, "sun", 0);
 
113
        if (!tab)
 
114
                goto err;
 
115
 
 
116
        /* sectors per cylinder (partition offset is in cylinders...) */
 
117
        spc = be16_to_cpu(l->ntrks) * be16_to_cpu(l->nsect);
 
118
 
 
119
        DBG(DEBUG_LOWPROBE,
 
120
                printf("Sun VTOC sanity=%u version=%u nparts=%u\n",
 
121
                        be32_to_cpu(l->vtoc.sanity),
 
122
                        be32_to_cpu(l->vtoc.version),
 
123
                        be16_to_cpu(l->vtoc.nparts)));
 
124
 
 
125
        /* Check to see if we can use the VTOC table */
 
126
        use_vtoc = ((be32_to_cpu(l->vtoc.sanity) == SUN_VTOC_SANITY) &&
 
127
                    (be32_to_cpu(l->vtoc.version) == SUN_VTOC_VERSION) &&
 
128
                    (be16_to_cpu(l->vtoc.nparts) <= SUN_MAXPARTITIONS));
 
129
 
 
130
        /* Use 8 partition entries if not specified in validated VTOC */
 
131
        nparts = use_vtoc ? be16_to_cpu(l->vtoc.nparts) : SUN_MAXPARTITIONS;
 
132
 
 
133
        /*
 
134
         * So that old Linux-Sun partitions continue to work,
 
135
         * alow the VTOC to be used under the additional condition ...
 
136
         */
 
137
        use_vtoc = use_vtoc || !(l->vtoc.sanity || l->vtoc.version || l->vtoc.nparts);
 
138
 
 
139
        for (i = 0, p = l->partitions; i < nparts; i++, p++) {
 
140
 
 
141
                blkid_loff_t start, size;
 
142
                uint16_t type = 0, flags = 0;
 
143
                blkid_partition par;
 
144
 
 
145
                start = be32_to_cpu(p->start_cylinder) * spc;
 
146
                size = be32_to_cpu(p->num_sectors);
 
147
                if (use_vtoc) {
 
148
                        type = be16_to_cpu(l->vtoc.infos[i].id);
 
149
                        flags = be16_to_cpu(l->vtoc.infos[i].flags);
 
150
                }
 
151
 
 
152
                if (type == SUN_TAG_WHOLEDISK || !size) {
 
153
                        blkid_partlist_increment_partno(ls);
 
154
                        continue;
 
155
                }
 
156
                par = blkid_partlist_add_partition(ls, tab, start, size);
 
157
                if (!par)
 
158
                        goto err;
 
159
 
 
160
                if (type)
 
161
                        blkid_partition_set_type(par, type);
 
162
                if (flags)
 
163
                        blkid_partition_set_flags(par, flags);
 
164
        }
 
165
        return 0;
 
166
 
 
167
nothing:
 
168
        return 1;
 
169
err:
 
170
        return -1;
 
171
}
 
172
 
 
173
 
 
174
const struct blkid_idinfo sun_pt_idinfo =
 
175
{
 
176
        .name           = "sun",
 
177
        .probefunc      = probe_sun_pt,
 
178
        .magics         =
 
179
        {
 
180
                {
 
181
                  .magic = "\xDA\xBE",          /* big-endian magic string */
 
182
                  .len = 2,
 
183
                  .sboff = offsetof(struct sun_disklabel, magic)
 
184
                },
 
185
                { NULL }
 
186
        }
 
187
};
 
188