* one that we can.
*/
#include "mdadm.h"
+#include <sys/file.h>
#include <ctype.h>
-#define mapnames(base) { #base, #base ".new", #base ".lock"}
+#define mapnames(base) { base, base ".new", base ".lock"}
char *mapname[3][3] = {
- mapnames(/var/run/mdadm/map),
- mapnames(/var/run/mdadm.map),
- mapnames(/dev/.mdadm.map)
+ mapnames(VAR_RUN "/map"),
+ mapnames("/var/run/mdadm.map"),
+ mapnames(ALT_RUN "/map")
};
int mapmode[3] = { O_RDONLY, O_RDWR|O_CREAT, O_RDWR|O_CREAT | O_TRUNC };
lf = open_map(2, &lwhich);
if (lf == NULL)
return -1;
- if (lockf(fileno(lf), F_LOCK, 0) != 0) {
+ if (flock(fileno(lf), LOCK_EX) != 0) {
fclose(lf);
lf = NULL;
return -1;
void map_unlock(struct map_ent **melp)
{
- if (lf)
+ if (lf) {
+ flock(fileno(lf), LOCK_UN);
fclose(lf);
+ }
unlink(mapname[lwhich][2]);
lf = NULL;
}
return NULL;
}
+/* sets the proper subarray and container_dev according to the metadata
+ * version super_by_fd does this automatically, this routine is meant as
+ * a supplement for guess_super()
+ */
+static void set_member_info(struct supertype *st, struct mdstat_ent *ent)
+{
+
+ st->subarray[0] = '\0';
+
+ if (ent->metadata_version == NULL ||
+ strncmp(ent->metadata_version, "external:", 9) != 0)
+ return;
+
+ if (is_subarray(&ent->metadata_version[9])) {
+ char version[strlen(ent->metadata_version)+1];
+ char *subarray;
+ char *name = &version[10];
+
+ strcpy(version, ent->metadata_version);
+ subarray = strrchr(version, '/');
+ name = &version[10];
+
+ if (!subarray)
+ return;
+ *subarray++ = '\0';
+
+ st->container_dev = devname2devnum(name);
+ strncpy(st->subarray, subarray, sizeof(st->subarray));
+ }
+}
+
void RebuildMap(void)
{
struct mdstat_ent *mdstat = mdstat_read(0, 0);
st = guess_super(dfd);
if ( st == NULL)
ok = -1;
- else
+ else {
+ set_member_info(st, md);
ok = st->ss->load_super(st, dfd, NULL);
+ }
close(dfd);
if (ok != 0)
continue;