int mdfd;
char chosen_name[1024];
int uuid[4] = {0,0,0,0};
+ struct map_ent *map = NULL;
/* scan all devices, make sure they really are block devices */
for (dv = devlist; dv; dv=dv->next) {
}
/* We need to create the device. It can have no name. */
+ map_lock(&map);
mdfd = create_mddev(mddev, NULL, autof, LOCAL,
chosen_name);
- if (mdfd < 0)
+ if (mdfd < 0) {
+ map_unlock(&map);
return 1;
+ }
- map_update(NULL, fd2devnum(mdfd), "none", uuid, chosen_name);
+ map_update(&map, fd2devnum(mdfd), "none", uuid, chosen_name);
+ map_unlock(&map);
vers = md_get_version(mdfd);
int did_default = 0;
unsigned long safe_mode_delay = 0;
char chosen_name[1024];
+ struct map_ent *map = NULL;
int major_num = BITMAP_MAJOR_HI;
}
/* We need to create the device */
+ map_lock(&map);
mdfd = create_mddev(mddev, name, autof, LOCAL, chosen_name);
if (mdfd < 0)
return 1;
" %s metadata\n", info.text_version);
}
- map_update(NULL, fd2devnum(mdfd), info.text_version,
+ map_update(&map, fd2devnum(mdfd), info.text_version,
info.uuid, chosen_name);
+ map_unlock(&map);
if (bitmap_file && vers < 9003) {
major_num = BITMAP_MAJOR_HOSTENDIAN;
int active_disks;
int trustworthy = FOREIGN;
char *name_to_use;
+ mdu_array_info_t ainf;
struct createinfo *ci = conf_get_create_info();
return Incremental_container(st, devname, verbose, runstop,
autof, trustworthy);
}
- /* 4/ Check is array exists.
+ /* 4/ Check if array exists.
*/
+ map_lock(&map);
mp = map_by_uuid(&map, info.uuid);
if (mp)
mdfd = open_mddev(mp->path, 0);
}
info.array.working_disks = 1;
sysfs_free(sra);
+ /* 6/ Make sure /var/run/mdadm.map contains this array. */
+ map_update(&map, fd2devnum(mdfd),
+ info.text_version,
+ info.uuid, chosen_name);
} else {
/* 5b/ if it does */
/* - check one drive in array to make sure metadata is a reasonably */
info.array.working_disks ++;
}
- /* 6/ Make sure /var/run/mdadm.map contains this array. */
- map_update(&map, fd2devnum(mdfd),
- info.text_version,
- info.uuid, chosen_name);
/* 7/ Is there enough devices to possibly start the array? */
/* 7a/ if not, finish with success. */
if (info.array.level == LEVEL_CONTAINER) {
/* Try to assemble within the container */
close(mdfd);
+ map_unlock(&map);
sysfs_uevent(&info, "change");
if (verbose >= 0)
fprintf(stderr, Name
fprintf(stderr, Name
": %s attached to %s, not enough to start (%d).\n",
devname, chosen_name, active_disks);
+ map_unlock(&map);
close(mdfd);
return 0;
}
/* are enough, */
/* + add any bitmap file */
/* + start the array (auto-readonly). */
-{
- mdu_array_info_t ainf;
if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) {
if (verbose >= 0)
fprintf(stderr, Name
": %s attached to %s which is already active.\n",
devname, chosen_name);
- close (mdfd);
+ close(mdfd);
+ map_unlock(&map);
return 0;
}
-}
+
+ map_unlock(&map);
if (runstop > 0 || active_disks >= info.array.working_disks) {
struct mdinfo *sra;
/* Let's try to start it */
struct mdinfo *list = st->ss->container_content(st);
struct mdinfo *ra;
+ struct map_ent *map = NULL;
+
+ map_lock(&map);
for (ra = list ; ra ; ra = ra->next) {
struct mdinfo *dev, *sra;
int mdfd;
char chosen_name[1024];
int working = 0, preexist = 0;
- struct map_ent *mp, *map = NULL;
+ struct map_ent *mp;
struct mddev_ident_s *match = NULL;
mp = map_by_uuid(&map, ra->uuid);
ra->uuid, chosen_name);
close(mdfd);
}
+ map_unlock(&map);
return 0;
}
"/var/run/mdadm.map") == 0;
}
+
+static int lfd = -1;
+static int lsubdir = 0;
+int map_lock(struct map_ent **melp)
+{
+ if (lfd < 0) {
+ lfd = open("/var/run/mdadm/map.lock", O_CREAT|O_RDWR, 0600);
+ if (lfd < 0) {
+ lfd = open("/var/run/mdadm.map.lock", O_CREAT|O_RDWR, 0600);
+ lsubdir = 0;
+ } else
+ lsubdir = 1;
+ if (lfd < 0)
+ return -1;
+ if (lockf(lfd, F_LOCK, 0) != 0) {
+ close(lfd);
+ lfd = -1;
+ return -1;
+ }
+ }
+ if (*melp)
+ map_free(*melp);
+ map_read(melp);
+ return 0;
+}
+
+void map_unlock(struct map_ent **melp)
+{
+ if (lfd >= 0)
+ close(lfd);
+ if (lsubdir)
+ unlink("/var/run/mdadm/map.lock");
+ else
+ unlink("/var/run/mdadm.map.lock");
+ lfd = -1;
+}
+
void map_add(struct map_ent **melp,
int devnum, char *metadata, int uuid[4], char *path)
{
extern void map_free(struct map_ent *map);
extern void map_add(struct map_ent **melp,
int devnum, char *metadata, int uuid[4], char *path);
+extern int map_lock(struct map_ent **melp);
+extern void map_unlock(struct map_ent **melp);
/* various details can be requested */
#define GET_LEVEL 1