]>
git.ipfire.org Git - thirdparty/mdadm.git/blob - mapfile.c
2 * mapfile - manage /var/run/mdadm.map. Part of:
3 * mdadm - manage Linux "md" devices aka RAID arrays.
5 * Copyright (C) 2006 Neil Brown <neilb@suse.de>
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.
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.
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
23 * Email: <neilb@suse.de>
27 * QVB Post Office, NSW 1230
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.
35 * The map file is line based with space separated fields. The fields are:
36 * Device id - mdX or mdpX where X is a number.
37 * metadata - 0.90 1.0 1.1 1.2 ddf ...
38 * UUID - uuid of the array
39 * path - path where device created: /dev/md/home
47 int map_write(struct map_ent
*mel
)
53 f
= fopen("/var/run/mdadm/map.new", "w");
55 f
= fopen("/var/run/mdadm.map.new", "w");
60 for (; mel
; mel
= mel
->next
) {
64 fprintf(f
, "mdp%d ", -1-mel
->devnum
);
66 fprintf(f
, "md%d ", mel
->devnum
);
67 fprintf(f
, "%s ", mel
->metadata
);
68 fprintf(f
, "%08x:%08x:%08x:%08x ", mel
->uuid
[0],
69 mel
->uuid
[1], mel
->uuid
[2], mel
->uuid
[3]);
70 fprintf(f
, "%s\n", mel
->path
);
77 unlink("/var/run/mdadm/map.new");
79 unlink("/var/run/mdadm.map.new");
83 return rename("/var/run/mdadm/map.new",
84 "/var/run/mdadm/map") == 0;
86 return rename("/var/run/mdadm.map.new",
87 "/var/run/mdadm.map") == 0;
92 static int lsubdir
= 0;
93 int map_lock(struct map_ent
**melp
)
96 lfd
= open("/var/run/mdadm/map.lock", O_CREAT
|O_RDWR
, 0600);
98 lfd
= open("/var/run/mdadm.map.lock", O_CREAT
|O_RDWR
, 0600);
104 if (lockf(lfd
, F_LOCK
, 0) != 0) {
116 void map_unlock(struct map_ent
**melp
)
121 unlink("/var/run/mdadm/map.lock");
123 unlink("/var/run/mdadm.map.lock");
127 void map_add(struct map_ent
**melp
,
128 int devnum
, char *metadata
, int uuid
[4], char *path
)
130 struct map_ent
*me
= malloc(sizeof(*me
));
133 strcpy(me
->metadata
, metadata
);
134 memcpy(me
->uuid
, uuid
, 16);
135 me
->path
= strdup(path
);
141 void map_read(struct map_ent
**melp
)
152 f
= fopen("/var/run/mdadm/map", "r");
154 f
= fopen("/var/run/mdadm.map", "r");
157 f
= fopen("/var/run/mdadm/map", "r");
160 f
= fopen("/var/run/mdadm.map", "r");
164 while (fgets(buf
, sizeof(buf
), f
)) {
165 if (sscanf(buf
, " %3[mdp]%d %s %x:%x:%x:%x %200s",
166 nam
, &devnum
, metadata
, uuid
, uuid
+1,
167 uuid
+2, uuid
+3, path
) == 8) {
168 if (strncmp(nam
, "md", 2) != 0)
171 devnum
= -1 - devnum
;
172 map_add(melp
, devnum
, metadata
, uuid
, path
);
178 void map_free(struct map_ent
*map
)
181 struct map_ent
*mp
= map
;
188 int map_update(struct map_ent
**mpp
, int devnum
, char *metadata
,
189 int *uuid
, char *path
)
191 struct map_ent
*map
, *mp
;
199 for (mp
= map
; mp
; mp
=mp
->next
)
200 if (mp
->devnum
== devnum
) {
201 strcpy(mp
->metadata
, metadata
);
202 memcpy(mp
->uuid
, uuid
, 16);
204 mp
->path
= strdup(path
);
208 map_add(&map
, devnum
, metadata
, uuid
, path
);
216 void map_delete(struct map_ent
**mapp
, int devnum
)
223 for (mp
= *mapp
; mp
; mp
= *mapp
) {
224 if (mp
->devnum
== devnum
) {
233 struct map_ent
*map_by_uuid(struct map_ent
**map
, int uuid
[4])
239 for (mp
= *map
; mp
; mp
= mp
->next
) {
240 if (memcmp(uuid
, mp
->uuid
, 16) != 0)
242 if (!mddev_busy(mp
->devnum
)) {
251 struct map_ent
*map_by_devnum(struct map_ent
**map
, int devnum
)
257 for (mp
= *map
; mp
; mp
= mp
->next
) {
258 if (mp
->devnum
!= devnum
)
260 if (!mddev_busy(mp
->devnum
)) {
269 struct map_ent
*map_by_name(struct map_ent
**map
, char *name
)
275 for (mp
= *map
; mp
; mp
= mp
->next
) {
276 if (strncmp(mp
->path
, "/dev/md/", 8) != 0)
278 if (strcmp(mp
->path
+8, name
) != 0)
280 if (!mddev_busy(mp
->devnum
)) {
289 void RebuildMap(void)
291 struct mdstat_ent
*mdstat
= mdstat_read(0, 0);
292 struct mdstat_ent
*md
;
293 struct map_ent
*map
= NULL
;
294 int mdp
= get_mdp_major();
296 for (md
= mdstat
; md
; md
= md
->next
) {
297 struct mdinfo
*sra
= sysfs_read(-1, md
->devnum
, GET_DEVS
);
300 for (sd
= sra
->devs
; sd
; sd
= sd
->next
) {
304 struct supertype
*st
;
308 sprintf(dn
, "%d:%d", sd
->disk
.major
, sd
->disk
.minor
);
309 dfd
= dev_open(dn
, O_RDONLY
);
312 st
= guess_super(dfd
);
316 ok
= st
->ss
->load_super(st
, dfd
, NULL
);
320 st
->ss
->getinfo_super(st
, &info
);
322 path
= map_dev(MD_MAJOR
, md
->devnum
, 0);
324 path
= map_dev(mdp
, (-1-md
->devnum
)<< 6, 0);
325 map_add(&map
, md
->devnum
,
327 info
.uuid
, path
? : "/unknown");
328 st
->ss
->free_super(st
);
335 for (md
= mdstat
; md
; md
= md
->next
) {
336 struct mdinfo
*sra
= sysfs_read(-1, md
->devnum
, GET_VERSION
);
337 sysfs_uevent(sra
, "change");