]> git.ipfire.org Git - thirdparty/mdadm.git/blob - mapfile.c
Factor common code into new "start_mdmon".
[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, " md%1[p]%d %s %x:%x:%x:%x %200s",
121 nam, &devnum, metadata, uuid, uuid+1,
122 uuid+2, uuid+3, path) == 9) {
123 if (nam[0] == 'p')
124 devnum = -1 - devnum;
125 map_add(melp, devnum, metadata, 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, char *metadata,
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 strcpy(mp->metadata, metadata);
155 memcpy(mp->uuid, uuid, 16);
156 free(mp->path);
157 mp->path = strdup(path);
158 break;
159 }
160 if (!mp)
161 map_add(&map, devnum, metadata, uuid, path);
162 *mpp = NULL;
163 rv = map_write(map);
164 map_free(map);
165 return rv;
166 }
167
168 void map_delete(struct map_ent **mapp, int devnum)
169 {
170 struct map_ent *mp;
171
172 if (*mapp == NULL)
173 map_read(mapp);
174
175 for (mp = *mapp; mp; mp = *mapp) {
176 if (mp->devnum == devnum) {
177 *mapp = mp->next;
178 free(mp->path);
179 free(mp);
180 } else
181 mapp = & mp->next;
182 }
183 }
184
185 struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4])
186 {
187 struct map_ent *mp;
188 if (!*map)
189 map_read(map);
190
191 for (mp = *map ; mp ; mp = mp->next)
192 if (memcmp(uuid, mp->uuid, 16) == 0)
193 return mp;
194 return NULL;
195
196 }