]> git.ipfire.org Git - thirdparty/mdadm.git/blame - mapfile.c
tests/06name: adjust for homehost
[thirdparty/mdadm.git] / mapfile.c
CommitLineData
8382f19b
NB
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:
1522c538
NB
36 * Device id - mdX or mdpX where X is a number.
37 * metadata - 0.90 1.0 1.1 1.2 ddf ...
8382f19b
NB
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
47int 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");
35e3446b 56 subdir = 0;
8382f19b
NB
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);
1522c538 65 fprintf(f, "%s ", mel->metadata);
8382f19b
NB
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
ad5bc697
N
89
90static int lfd = -1;
91static int lsubdir = 0;
92int map_lock(struct map_ent **melp)
93{
94 if (lfd < 0) {
95 lfd = open("/var/run/mdadm/map.lock", O_CREAT|O_RDWR, 0600);
96 if (lfd < 0) {
97 lfd = open("/var/run/mdadm.map.lock", O_CREAT|O_RDWR, 0600);
98 lsubdir = 0;
99 } else
100 lsubdir = 1;
101 if (lfd < 0)
102 return -1;
103 if (lockf(lfd, F_LOCK, 0) != 0) {
104 close(lfd);
105 lfd = -1;
106 return -1;
107 }
108 }
109 if (*melp)
110 map_free(*melp);
111 map_read(melp);
112 return 0;
113}
114
115void map_unlock(struct map_ent **melp)
116{
117 if (lfd >= 0)
118 close(lfd);
119 if (lsubdir)
120 unlink("/var/run/mdadm/map.lock");
121 else
122 unlink("/var/run/mdadm.map.lock");
123 lfd = -1;
124}
125
8382f19b 126void map_add(struct map_ent **melp,
1522c538 127 int devnum, char *metadata, int uuid[4], char *path)
8382f19b
NB
128{
129 struct map_ent *me = malloc(sizeof(*me));
130
131 me->devnum = devnum;
1522c538 132 strcpy(me->metadata, metadata);
8382f19b
NB
133 memcpy(me->uuid, uuid, 16);
134 me->path = strdup(path);
135 me->next = *melp;
136 *melp = me;
137}
138
139void map_read(struct map_ent **melp)
140{
141 FILE *f;
142 char buf[8192];
143 char path[200];
1522c538
NB
144 int devnum, uuid[4];
145 char metadata[30];
8382f19b
NB
146 char nam[4];
147
148 *melp = NULL;
149
150 f = fopen("/var/run/mdadm/map", "r");
151 if (!f)
152 f = fopen("/var/run/mdadm.map", "r");
153 if (!f)
154 return;
155
156 while (fgets(buf, sizeof(buf), f)) {
c5afc314 157 if (sscanf(buf, " %3[mdp]%d %s %x:%x:%x:%x %200s",
1522c538 158 nam, &devnum, metadata, uuid, uuid+1,
c5afc314
N
159 uuid+2, uuid+3, path) == 8) {
160 if (strncmp(nam, "md", 2) != 0)
161 continue;
162 if (nam[2] == 'p')
8382f19b 163 devnum = -1 - devnum;
1522c538 164 map_add(melp, devnum, metadata, uuid, path);
8382f19b
NB
165 }
166 }
167 fclose(f);
168}
169
170void map_free(struct map_ent *map)
171{
172 while (map) {
173 struct map_ent *mp = map;
174 map = mp->next;
175 free(mp->path);
176 free(mp);
177 }
178}
179
1522c538 180int map_update(struct map_ent **mpp, int devnum, char *metadata,
8382f19b
NB
181 int *uuid, char *path)
182{
183 struct map_ent *map, *mp;
184 int rv;
185
186 if (mpp && *mpp)
187 map = *mpp;
188 else
189 map_read(&map);
190
191 for (mp = map ; mp ; mp=mp->next)
192 if (mp->devnum == devnum) {
1522c538 193 strcpy(mp->metadata, metadata);
8382f19b
NB
194 memcpy(mp->uuid, uuid, 16);
195 free(mp->path);
196 mp->path = strdup(path);
197 break;
198 }
199 if (!mp)
1522c538 200 map_add(&map, devnum, metadata, uuid, path);
a04d5763
N
201 if (mpp)
202 *mpp = NULL;
8382f19b
NB
203 rv = map_write(map);
204 map_free(map);
205 return rv;
206}
207
208void map_delete(struct map_ent **mapp, int devnum)
209{
210 struct map_ent *mp;
211
212 if (*mapp == NULL)
213 map_read(mapp);
214
215 for (mp = *mapp; mp; mp = *mapp) {
216 if (mp->devnum == devnum) {
217 *mapp = mp->next;
218 free(mp->path);
219 free(mp);
220 } else
221 mapp = & mp->next;
222 }
223}
224
225struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4])
226{
227 struct map_ent *mp;
228 if (!*map)
229 map_read(map);
230
231 for (mp = *map ; mp ; mp = mp->next)
232 if (memcmp(uuid, mp->uuid, 16) == 0)
233 return mp;
234 return NULL;
4ccad7b1 235}
8382f19b 236
4ccad7b1
N
237struct map_ent *map_by_devnum(struct map_ent **map, int devnum)
238{
239 struct map_ent *mp;
240 if (!*map)
241 map_read(map);
242
243 for (mp = *map ; mp ; mp = mp->next)
244 if (mp->devnum == devnum)
245 return mp;
246 return NULL;
8382f19b 247}
f2e55ecc
N
248
249struct map_ent *map_by_name(struct map_ent **map, char *name)
250{
251 struct map_ent *mp;
252 if (!*map)
253 map_read(map);
254
255 for (mp = *map ; mp ; mp = mp->next) {
256 if (strncmp(mp->path, "/dev/md/", 8) != 0)
257 continue;
258 if (strcmp(mp->path+8, name) == 0)
259 return mp;
260 }
261 return NULL;
262}