]> git.ipfire.org Git - thirdparty/mdadm.git/blame - mapfile.c
Replace sysarray with mdinfo
[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:
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
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");
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
89void 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
103void 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
131void 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
141int 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
169void 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
186struct 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}