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

« back to all changes in this revision

Viewing changes to shlibs/blkid/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, const struct blkid_idmag *mag)
84
 
{
85
 
        struct sun_disklabel *l;
86
 
        struct sun_partition *p;
87
 
        blkid_parttable tab = NULL;
88
 
        blkid_partlist ls;
89
 
        uint16_t nparts;
90
 
        blkid_loff_t spc;
91
 
        int i, use_vtoc;
92
 
 
93
 
        l = (struct sun_disklabel *) blkid_probe_get_sector(pr, 0);
94
 
        if (!l)
95
 
                goto nothing;
96
 
 
97
 
        if (count_checksum(l)) {
98
 
                DBG(DEBUG_LOWPROBE, printf(
99
 
                        "detected corrupted sun disk label -- ignore\n"));
100
 
                goto nothing;
101
 
        }
102
 
 
103
 
        if (blkid_partitions_need_typeonly(pr))
104
 
                /* caller does not ask for details about partitions */
105
 
                return 0;
106
 
 
107
 
        ls = blkid_probe_get_partlist(pr);
108
 
        if (!ls)
109
 
                goto err;
110
 
 
111
 
        tab = blkid_partlist_new_parttable(ls, "sun", 0);
112
 
        if (!tab)
113
 
                goto err;
114
 
 
115
 
        /* sectors per cylinder (partition offset is in cylinders...) */
116
 
        spc = be16_to_cpu(l->ntrks) * be16_to_cpu(l->nsect);
117
 
 
118
 
        DBG(DEBUG_LOWPROBE,
119
 
                printf("Sun VTOC sanity=%u version=%u nparts=%u\n",
120
 
                        be32_to_cpu(l->vtoc.sanity),
121
 
                        be32_to_cpu(l->vtoc.version),
122
 
                        be16_to_cpu(l->vtoc.nparts)));
123
 
 
124
 
        /* Check to see if we can use the VTOC table */
125
 
        use_vtoc = ((be32_to_cpu(l->vtoc.sanity) == SUN_VTOC_SANITY) &&
126
 
                    (be32_to_cpu(l->vtoc.version) == SUN_VTOC_VERSION) &&
127
 
                    (be16_to_cpu(l->vtoc.nparts) <= SUN_MAXPARTITIONS));
128
 
 
129
 
        /* Use 8 partition entries if not specified in validated VTOC */
130
 
        nparts = use_vtoc ? be16_to_cpu(l->vtoc.nparts) : SUN_MAXPARTITIONS;
131
 
 
132
 
        /*
133
 
         * So that old Linux-Sun partitions continue to work,
134
 
         * alow the VTOC to be used under the additional condition ...
135
 
         */
136
 
        use_vtoc = use_vtoc || !(l->vtoc.sanity || l->vtoc.version || l->vtoc.nparts);
137
 
 
138
 
        for (i = 0, p = l->partitions; i < nparts; i++, p++) {
139
 
 
140
 
                blkid_loff_t start, size;
141
 
                uint16_t type = 0, flags = 0;
142
 
                blkid_partition par;
143
 
 
144
 
                start = be32_to_cpu(p->start_cylinder) * spc;
145
 
                size = be32_to_cpu(p->num_sectors);
146
 
                if (use_vtoc) {
147
 
                        type = be16_to_cpu(l->vtoc.infos[i].id);
148
 
                        flags = be16_to_cpu(l->vtoc.infos[i].flags);
149
 
                }
150
 
 
151
 
                if (type == SUN_TAG_WHOLEDISK || !size) {
152
 
                        blkid_partlist_increment_partno(ls);
153
 
                        continue;
154
 
                }
155
 
                par = blkid_partlist_add_partition(ls, tab, start, size);
156
 
                if (!par)
157
 
                        goto err;
158
 
 
159
 
                if (type)
160
 
                        blkid_partition_set_type(par, type);
161
 
                if (flags)
162
 
                        blkid_partition_set_flags(par, flags);
163
 
        }
164
 
        return 0;
165
 
 
166
 
nothing:
167
 
        return 1;
168
 
err:
169
 
        return -1;
170
 
}
171
 
 
172
 
 
173
 
const struct blkid_idinfo sun_pt_idinfo =
174
 
{
175
 
        .name           = "sun",
176
 
        .probefunc      = probe_sun_pt,
177
 
        .magics         =
178
 
        {
179
 
                {
180
 
                  .magic = "\xDA\xBE",          /* big-endian magic string */
181
 
                  .len = 2,
182
 
                  .sboff = offsetof(struct sun_disklabel, magic)
183
 
                },
184
 
                { NULL }
185
 
        }
186
 
};
187