summaryrefslogtreecommitdiffstats
path: root/mapfile.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2008-11-04 20:50:39 +1100
committerNeilBrown <neilb@suse.de>2008-11-04 20:50:39 +1100
commitad5bc697ad9bb52616c34b022fb014e890be6a2d (patch)
treec8c8905f29d993f4b3bcf7f449c249c4d9f21337 /mapfile.c
parent7e6c6cb26790e4b0de2e8694cca655db26bee11a (diff)
downloadmdadm-ad5bc697ad9bb52616c34b022fb014e890be6a2d.tar.gz
mdadm-ad5bc697ad9bb52616c34b022fb014e890be6a2d.tar.xz
mdadm-ad5bc697ad9bb52616c34b022fb014e890be6a2d.zip
Incremental: lock against multiple concurrent additions to an array.
In two devices are added via -I to one array at the same time, mdadm can get badly confused. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'mapfile.c')
-rw-r--r--mapfile.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/mapfile.c b/mapfile.c
index a59ea4d..1c2dc52 100644
--- a/mapfile.c
+++ b/mapfile.c
@@ -86,6 +86,43 @@ int map_write(struct map_ent *mel)
"/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)
{