~xnox/ubuntu/quantal/mdadm/merge

« back to all changes in this revision

Viewing changes to super-gpt.c

  • Committer: Dmitrijs Ledkovs
  • Author(s): Clint Byrum
  • Date: 2011-12-16 11:06:12 UTC
  • mfrom: (1.1.26 sid)
  • Revision ID: dmitrijs.ledkovs@canonical.com-20111216110612-f91bfvyfvxc1t0rq
Tags: 3.2.2-1ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Call checks in local-premount to avoid race condition with udev
    and opening a degraded array.
  - d/initramfs/mdadm-functions: Record in /run when boot-degraded 
    question has been asked so that it is only asked once
  - pass --test to mdadm to enable result codes for degraded arrays. 
  - Build udeb with -O2 on ppc64, working around a link error.
  - debian/control: we need udev and util-linux in the right version. We
    also remove the build dependency from quilt and docbook-to-man as both
    are not used in Ubuntus mdadm.
  - debian/initramfs/hook: kept the Ubuntus version for handling the absence
    of active raid arrays in <initramfs>/etc/mdadm/mdadm.conf
  - debian/initramfs/script.local-top.DEBIAN, debian/mdadm-startall,
    debian/mdadm.raid.DEBIAN: removed. udev does its job now instead.
  - debian/mdadm-startall.sgml, debian/mdadm-startall.8: documentation of
    unused startall script
  - debian/mdadm.config, debian/mdadm.postinst - let udev do the handling
    instead. Resolved merge conflict by keeping Ubuntu's version.
  - debian/mdadm.postinst, debian/mdadm.config, initramfs/init-premount:
    boot-degraded enablement; maintain udev starting of RAID devices;
    init-premount hook script for the initramfs, to provide information at
    boot
  - debian/mkconf.in is the older mkconf. Kept the Ubuntu version.
  - debian/rules: Kept Ubuntus version for installing apport hooks, not
    installing un-used startall script and for adding a udev rule
    corresponding to mdadm.
  - debian/install-rc, check.d/_numbers, check.d/root_on_raid: Ubuntu partman
    installer changes
  - debian/presubj: Dropped this unused bug reporting file. Instead use
    source_mdadm.py act as an apport hook for bug handling.
  - rename debian/mdadm.vol_id.udev to debian/mdadm.mdadm-blkid.udev so that
    the rules file ends up with a more reasonable name
  - d/p/debian-changes-3.1.4-1+8efb9d1ubuntu4: mdadm udev rule
    incrementally adds mdadm member when detected. Starting such an
    array in degraded mode is possible by mdadm -IRs. Using mdadm
    -ARs without stopping the array first does nothing when no
    mdarray-unassociated device is available. Using mdadm -IRs to
    start a previously partially assembled array through incremental
    mode. Keeping the mdadm -ARs for assembling arrays which were for
    some reason not assembled through incremental mode (i.e through
    mdadm's udev rule).
* Disabling -fno-strict-aliasing as according to debian bug 375876 it
  has been unnecessary since mdadm 2.5.2
* Dropped changes:
  - applied upstream
  - d/rules: fix FTBFS by adding -Wno-unused-but-set-variable to
    compiler flags until upstream solves the issue. (fixed upstream)
  - d/control: add dependency on initscripts >= 2.88dsf-13.3 to ensure
    /run exists per http://wiki.debian.org/ReleaseGoals/RunDirectory
    (change also done in debian)
* d/rules: add 'man' to build mdadm.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * mdadm - manage Linux "md" devices aka RAID arrays.
 
3
 *
 
4
 * Copyright (C) 2010 Neil Brown <neilb@suse.de>
 
5
 *
 
6
 *
 
7
 *    This program is free software; you can redistribute it and/or modify
 
8
 *    it under the terms of the GNU General Public License as published by
 
9
 *    the Free Software Foundation; either version 2 of the License, or
 
10
 *    (at your option) any later version.
 
11
 *
 
12
 *    This program is distributed in the hope that it will be useful,
 
13
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 *    GNU General Public License for more details.
 
16
 *
 
17
 *    You should have received a copy of the GNU General Public License
 
18
 *    along with this program; if not, write to the Free Software
 
19
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 *
 
21
 *    Author: Neil Brown
 
22
 *    Email: <neil@brown.name>
 
23
 *
 
24
 */
 
25
 
 
26
/*
 
27
 * 'gpt' is a pseudo metadata type for devices which have a
 
28
 * GPT partition table.
 
29
 *
 
30
 * Obviously arrays cannot be created or assembled for this type.
 
31
 * It is used to allow a new bare device to have an partition table
 
32
 * added so the member partitions can then be included in other
 
33
 * arrays as relevant.
 
34
 *
 
35
 * The meaning operations are:
 
36
 * examine_super, but not brief_examine_super or export_examine
 
37
 * load_super
 
38
 * store_super
 
39
 */
 
40
 
 
41
#include "mdadm.h"
 
42
#include "part.h"
 
43
 
 
44
static void free_gpt(struct supertype *st)
 
45
{
 
46
        free(st->sb);
 
47
        st->sb = NULL;
 
48
}
 
49
 
 
50
#ifndef MDASSEMBLE
 
51
static void examine_gpt(struct supertype *st, char *homehost)
 
52
{
 
53
        struct GPT *gpt = st->sb + 512;
 
54
        struct GPT_part_entry *gpe = st->sb + 1024;
 
55
        unsigned int i;
 
56
 
 
57
        printf("    GPT Magic : %llx\n", (unsigned long long)__le64_to_cpu(gpt->magic));
 
58
        printf(" GPT Revision : %ld\n", (long)__le32_to_cpu(gpt->revision));
 
59
        for (i = 0; i < __le32_to_cpu(gpt->part_cnt); i++) {
 
60
                printf("  Partition[%02d] : %12llu sectors at %12llu\n",
 
61
                       i,
 
62
                       (unsigned long long)__le64_to_cpu(gpe[i].starting_lba),
 
63
                       (unsigned long long)__le64_to_cpu(gpe[i].ending_lba)-
 
64
                       (unsigned long long)__le64_to_cpu(gpe[i].starting_lba)
 
65
                       +1
 
66
                        );
 
67
        }
 
68
}
 
69
#endif /* MDASSEMBLE */
 
70
 
 
71
static int load_gpt(struct supertype *st, int fd, char *devname)
 
72
{
 
73
        struct MBR *super;
 
74
        struct GPT *gpt_head;
 
75
        int to_read;
 
76
 
 
77
        free_gpt(st);
 
78
 
 
79
        if (posix_memalign((void**)&super, 512, 32*512) != 0) {
 
80
                fprintf(stderr, Name ": %s could not allocate superblock\n",
 
81
                        __func__);
 
82
                return 1;
 
83
        }
 
84
 
 
85
        ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */
 
86
 
 
87
        lseek(fd, 0, 0);
 
88
        if (read(fd, super, sizeof(*super)) != sizeof(*super)) {
 
89
        no_read:
 
90
                if (devname)
 
91
                        fprintf(stderr, Name ": Cannot read partition table on %s\n",
 
92
                                devname);
 
93
                free(super);
 
94
                return 1;
 
95
        }
 
96
 
 
97
        if (super->magic != MBR_SIGNATURE_MAGIC ||
 
98
            super->parts[0].part_type != MBR_GPT_PARTITION_TYPE) {
 
99
        not_found:
 
100
                if (devname)
 
101
                        fprintf(stderr, Name ": No partition table found on %s\n",
 
102
                                devname);
 
103
                free(super);
 
104
                return 1;
 
105
        }
 
106
        /* Seem to have GPT, load the header */
 
107
        gpt_head = (struct GPT*)(super+1);
 
108
        if (read(fd, gpt_head, sizeof(*gpt_head)) != sizeof(*gpt_head))
 
109
                goto no_read;
 
110
        if (gpt_head->magic != GPT_SIGNATURE_MAGIC)
 
111
                goto not_found;
 
112
        if (__le32_to_cpu(gpt_head->part_cnt) >= 128)
 
113
                goto not_found;
 
114
 
 
115
        to_read = __le32_to_cpu(gpt_head->part_cnt) * sizeof(struct GPT_part_entry);
 
116
        to_read =  ((to_read+511)/512) * 512;
 
117
        if (read(fd, gpt_head+1, to_read) != to_read)
 
118
                goto no_read;
 
119
 
 
120
        st->sb = super;
 
121
 
 
122
        if (st->ss == NULL) {
 
123
                st->ss = &gpt;
 
124
                st->minor_version = 0;
 
125
                st->max_devs = 1;
 
126
                st->info = NULL;
 
127
        }
 
128
        return 0;
 
129
}
 
130
 
 
131
static int store_gpt(struct supertype *st, int fd)
 
132
{
 
133
        /* FIXME should I save the boot loader */
 
134
        /* need to write two copies! */
 
135
        /* FIXME allow for blocks != 512 bytes
 
136
         *etc
 
137
         */
 
138
        struct MBR *super = st->sb;
 
139
        struct GPT *gpt;
 
140
        int to_write;
 
141
 
 
142
        gpt = (struct GPT*)(super+1);
 
143
 
 
144
        to_write = __le32_to_cpu(gpt->part_cnt) * sizeof(struct GPT_part_entry);
 
145
        to_write =  ((to_write+511)/512) * 512;
 
146
 
 
147
        lseek(fd, 0, 0);
 
148
        if (write(fd, st->sb, to_write) != to_write)
 
149
                return 4;
 
150
 
 
151
        fsync(fd);
 
152
        ioctl(fd, BLKRRPART, 0);
 
153
        return 0;
 
154
}
 
155
 
 
156
static void getinfo_gpt(struct supertype *st, struct mdinfo *info, char *map)
 
157
{
 
158
        struct GPT *gpt = st->sb + 512;
 
159
        struct GPT_part_entry *gpe = st->sb + 1024;
 
160
        unsigned int i;
 
161
 
 
162
        memset(&info->array, 0, sizeof(info->array));
 
163
        memset(&info->disk, 0, sizeof(info->disk));
 
164
        strcpy(info->text_version, "gpt");
 
165
        strcpy(info->name, "gpt");
 
166
        info->component_size = 0;
 
167
 
 
168
        for (i = 0; i < __le32_to_cpu(gpt->part_cnt); i++) {
 
169
                unsigned long long last =
 
170
                        (unsigned long long)__le64_to_cpu(gpe[i].ending_lba);
 
171
                if (last > info->component_size)
 
172
                        info->component_size = last;
 
173
        }
 
174
}
 
175
 
 
176
static struct supertype *match_metadata_desc(char *arg)
 
177
{
 
178
        struct supertype *st = malloc(sizeof(*st));
 
179
 
 
180
        if (!st)
 
181
                return st;
 
182
        if (strcmp(arg, "gpt") != 0)
 
183
                return NULL;
 
184
 
 
185
        st->ss = &gpt;
 
186
        st->info = NULL;
 
187
        st->minor_version = 0;
 
188
        st->max_devs = 1;
 
189
        st->sb = NULL;
 
190
        return st;
 
191
}
 
192
 
 
193
#ifndef MDASSEMBLE
 
194
static int validate_geometry(struct supertype *st, int level,
 
195
                             int layout, int raiddisks,
 
196
                             int *chunk, unsigned long long size,
 
197
                             char *subdev, unsigned long long *freesize,
 
198
                             int verbose)
 
199
{
 
200
        fprintf(stderr, Name ": gpt metadata cannot be used this way\n");
 
201
        return 0;
 
202
}
 
203
#endif
 
204
 
 
205
struct superswitch gpt = {
 
206
#ifndef MDASSEMBLE
 
207
        .examine_super = examine_gpt,
 
208
        .validate_geometry = validate_geometry,
 
209
#endif
 
210
        .match_metadata_desc = match_metadata_desc,
 
211
        .load_super = load_gpt,
 
212
        .store_super = store_gpt,
 
213
        .getinfo_super = getinfo_gpt,
 
214
        .free_super = free_gpt,
 
215
        .name = "gpt",
 
216
};