]> git.ipfire.org Git - thirdparty/mdadm.git/blob - mapfile.c
Merge branch 'master' into devel-3.0
[thirdparty/mdadm.git] / mapfile.c
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 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
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, "%s ", mel->metadata);
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, char *metadata, int uuid[4], char *path)
91 {
92 struct map_ent *me = malloc(sizeof(*me));
93
94 me->devnum = devnum;
95 strcpy(me->metadata, metadata);
96 memcpy(me->uuid, uuid, 16);
97 me->path = strdup(path);
98 me->next = *melp;
99 *melp = me;
100 }
101
102 void map_read(struct map_ent **melp)
103 {
104 FILE *f;
105 char buf[8192];
106 char path[200];
107 int devnum, uuid[4];
108 char metadata[30];
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, " %3[mdp]%d %s %x:%x:%x:%x %200s",
121 nam, &devnum, metadata, uuid, uuid+1,
122 uuid+2, uuid+3, path) == 8) {
123 if (strncmp(nam, "md", 2) != 0)
124 continue;
125 if (nam[2] == 'p')
126 devnum = -1 - devnum;
127 map_add(melp, devnum, metadata, uuid, path);
128 }
129 }
130 fclose(f);
131 }
132
133 void map_free(struct map_ent *map)
134 {
135 while (map) {
136 struct map_ent *mp = map;
137 map = mp->next;
138 free(mp->path);
139 free(mp);
140 }
141 }
142
143 int map_update(struct map_ent **mpp, int devnum, char *metadata,
144 int *uuid, char *path)
145 {
146 struct map_ent *map, *mp;
147 int rv;
148
149 if (mpp && *mpp)
150 map = *mpp;
151 else
152 map_read(&map);
153
154 for (mp = map ; mp ; mp=mp->next)
155 if (mp->devnum == devnum) {
156 strcpy(mp->metadata, metadata);
157 memcpy(mp->uuid, uuid, 16);
158 free(mp->path);
159 mp->path = strdup(path);
160 break;
161 }
162 if (!mp)
163 map_add(&map, devnum, metadata, uuid, path);
164 *mpp = NULL;
165 rv = map_write(map);
166 map_free(map);
167 return rv;
168 }
169
170 void map_delete(struct map_ent **mapp, int devnum)
171 {
172 struct map_ent *mp;
173
174 if (*mapp == NULL)
175 map_read(mapp);
176
177 for (mp = *mapp; mp; mp = *mapp) {
178 if (mp->devnum == devnum) {
179 *mapp = mp->next;
180 free(mp->path);
181 free(mp);
182 } else
183 mapp = & mp->next;
184 }
185 }
186
187 struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4])
188 {
189 struct map_ent *mp;
190 if (!*map)
191 map_read(map);
192
193 for (mp = *map ; mp ; mp = mp->next)
194 if (memcmp(uuid, mp->uuid, 16) == 0)
195 return mp;
196 return NULL;
197
198 }