~ubuntu-branches/ubuntu/quantal/mdadm/quantal-proposed

« back to all changes in this revision

Viewing changes to mapfile.c

  • Committer: Package Import Robot
  • Author(s): Scott James Remnant
  • Date: 2007-07-11 10:31:39 UTC
  • mfrom: (1.1.6)
  • mto: (1.4.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 25.
  • Revision ID: package-import@ubuntu.com-20070711103139-ih7oxwxsal9ndbej
Tags: upstream-2.6.2
ImportĀ upstreamĀ versionĀ 2.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * mapfile - manage /var/run/mdadm.map. Part of:
 
3
 * mdadm - manage Linux "md" devices aka RAID arrays.
 
4
 *
 
5
 * Copyright (C) 2006 Neil Brown <neilb@suse.de>
 
6
 *
 
7
 *
 
8
 *    This program is free software; you can redistribute it and/or modify
 
9
 *    it under the terms of the GNU General Public License as published by
 
10
 *    the Free Software Foundation; either version 2 of the License, or
 
11
 *    (at your option) any later version.
 
12
 *
 
13
 *    This program is distributed in the hope that it will be useful,
 
14
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 *    GNU General Public License for more details.
 
17
 *
 
18
 *    You should have received a copy of the GNU General Public License
 
19
 *    along with this program; if not, write to the Free Software
 
20
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
 *
 
22
 *    Author: Neil Brown
 
23
 *    Email: <neilb@suse.de>
 
24
 *    Paper: Neil Brown
 
25
 *           Novell Inc
 
26
 *           GPO Box Q1283
 
27
 *           QVB Post Office, NSW 1230
 
28
 *           Australia
 
29
 */
 
30
 
 
31
/* /var/run/mdadm.map is used to track arrays being created in --incremental
 
32
 * more.  It particularly allows lookup from UUID to array device, but
 
33
 * also allows the array device name to be easily found.
 
34
 *
 
35
 * The map file is line based with space separated fields.  The fields are:
 
36
 *  Device id  -  mdX or mdpX  where is a number.
 
37
 *  metadata   -  0.90 1.0 1.1 1.2
 
38
 *  UUID       -  uuid of the array
 
39
 *  path       -  path where device created: /dev/md/home
 
40
 *
 
41
 */
 
42
 
 
43
 
 
44
#include "mdadm.h"
 
45
 
 
46
 
 
47
int map_write(struct map_ent *mel)
 
48
{
 
49
        FILE *f;
 
50
        int err;
 
51
        int subdir = 1;
 
52
 
 
53
        f = fopen("/var/run/mdadm/map.new", "w");
 
54
        if (!f) {
 
55
                f = fopen("/var/run/mdadm.map.new", "w");
 
56
                subdir = 1;
 
57
        }
 
58
        if (!f)
 
59
                return 0;
 
60
        while (mel) {
 
61
                if (mel->devnum < 0)
 
62
                        fprintf(f, "mdp%d ", -1-mel->devnum);
 
63
                else
 
64
                        fprintf(f, "md%d ", mel->devnum);
 
65
                fprintf(f, "%d.%d ", mel->major, mel->minor);
 
66
                fprintf(f, "%08x:%08x:%08x:%08x ", mel->uuid[0],
 
67
                        mel->uuid[1], mel->uuid[2], mel->uuid[3]);
 
68
                fprintf(f, "%s\n", mel->path);
 
69
                mel = mel->next;
 
70
        }
 
71
        fflush(f);
 
72
        err = ferror(f);
 
73
        fclose(f);
 
74
        if (err) {
 
75
                if (subdir)
 
76
                        unlink("/var/run/mdadm/map.new");
 
77
                else
 
78
                        unlink("/var/run/mdadm.map.new");
 
79
                return 0;
 
80
        }
 
81
        if (subdir)
 
82
                return rename("/var/run/mdadm/map.new",
 
83
                              "/var/run/mdadm/map") == 0;
 
84
        else
 
85
                return rename("/var/run/mdadm.map.new",
 
86
                              "/var/run/mdadm.map") == 0;
 
87
}
 
88
 
 
89
void map_add(struct map_ent **melp,
 
90
            int devnum, int major, int minor, int uuid[4], char *path)
 
91
{
 
92
        struct map_ent *me = malloc(sizeof(*me));
 
93
 
 
94
        me->devnum = devnum;
 
95
        me->major = major;
 
96
        me->minor = minor;
 
97
        memcpy(me->uuid, uuid, 16);
 
98
        me->path = strdup(path);
 
99
        me->next = *melp;
 
100
        *melp = me;
 
101
}
 
102
 
 
103
void map_read(struct map_ent **melp)
 
104
{
 
105
        FILE *f;
 
106
        char buf[8192];
 
107
        char path[200];
 
108
        int devnum, major, minor, uuid[4];
 
109
        char nam[4];
 
110
 
 
111
        *melp = NULL;
 
112
 
 
113
        f = fopen("/var/run/mdadm/map", "r");
 
114
        if (!f)
 
115
                f = fopen("/var/run/mdadm.map", "r");
 
116
        if (!f)
 
117
                return;
 
118
 
 
119
        while (fgets(buf, sizeof(buf), f)) {
 
120
                if (sscanf(buf, " md%1[p]%d %d.%d %x:%x:%x:%x %200s",
 
121
                           nam, &devnum, &major, &minor, uuid, uuid+1,
 
122
                           uuid+2, uuid+3, path) == 9) {
 
123
                        if (nam[0] == 'p')
 
124
                                devnum = -1 - devnum;
 
125
                        map_add(melp, devnum, major, minor, uuid, path);
 
126
                }
 
127
        }
 
128
        fclose(f);
 
129
}
 
130
 
 
131
void map_free(struct map_ent *map)
 
132
{
 
133
        while (map) {
 
134
                struct map_ent *mp = map;
 
135
                map = mp->next;
 
136
                free(mp->path);
 
137
                free(mp);
 
138
        }
 
139
}
 
140
 
 
141
int map_update(struct map_ent **mpp, int devnum, int major, int minor,
 
142
               int *uuid, char *path)
 
143
{
 
144
        struct map_ent *map, *mp;
 
145
        int rv;
 
146
 
 
147
        if (mpp && *mpp)
 
148
                map = *mpp;
 
149
        else
 
150
                map_read(&map);
 
151
 
 
152
        for (mp = map ; mp ; mp=mp->next)
 
153
                if (mp->devnum == devnum) {
 
154
                        mp->major = major;
 
155
                        mp->minor = minor;
 
156
                        memcpy(mp->uuid, uuid, 16);
 
157
                        free(mp->path);
 
158
                        mp->path = strdup(path);
 
159
                        break;
 
160
                }
 
161
        if (!mp)
 
162
                map_add(&map, devnum, major, minor, uuid, path);
 
163
        *mpp = NULL;
 
164
        rv = map_write(map);
 
165
        map_free(map);
 
166
        return rv;
 
167
}
 
168
 
 
169
void map_delete(struct map_ent **mapp, int devnum)
 
170
{
 
171
        struct map_ent *mp;
 
172
 
 
173
        if (*mapp == NULL)
 
174
                map_read(mapp);
 
175
 
 
176
        for (mp = *mapp; mp; mp = *mapp) {
 
177
                if (mp->devnum == devnum) {
 
178
                        *mapp = mp->next;
 
179
                        free(mp->path);
 
180
                        free(mp);
 
181
                } else
 
182
                        mapp = & mp->next;
 
183
        }
 
184
}
 
185
 
 
186
struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4])
 
187
{
 
188
        struct map_ent *mp;
 
189
        if (!*map)
 
190
                map_read(map);
 
191
 
 
192
        for (mp = *map ; mp ; mp = mp->next)
 
193
                if (memcmp(uuid, mp->uuid, 16) == 0)
 
194
                        return mp;
 
195
        return NULL;
 
196
 
 
197
}