diff options
author | NeilBrown <neilb@suse.de> | 2008-11-04 20:50:39 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2008-11-04 20:50:39 +1100 |
commit | ad5bc697ad9bb52616c34b022fb014e890be6a2d (patch) | |
tree | c8c8905f29d993f4b3bcf7f449c249c4d9f21337 /mapfile.c | |
parent | 7e6c6cb26790e4b0de2e8694cca655db26bee11a (diff) | |
download | mdadm-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.c | 37 |
1 files changed, 37 insertions, 0 deletions
@@ -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) { |