]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Remove race for starting container devices.
authorJes Sorensen <Jes.Sorensen@redhat.com>
Sat, 22 Oct 2011 00:29:47 +0000 (11:29 +1100)
committerNeilBrown <neilb@suse.de>
Sat, 22 Oct 2011 00:29:47 +0000 (11:29 +1100)
This moves the lock handling out of Incremental_container() and relies
on the caller holding the lock. This prevents conflict with a
follow-on mdadm comment which may try and launch the device in
parallel.

This involves replacing a call to "Incremental" with an
unrolled version with just the case that calls Incremental_container
and so needs a call to ->load_container.

Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Incremental.c

index b90089bb39210d960b27a664dcbaa84623a6b05d..1b010e9a655ea5467e0818e28ca22495fd83e5ca 100644 (file)
@@ -139,10 +139,16 @@ int Incremental(char *devname, int verbose, int runstop,
                        rv = st->ss->load_container(st, dfd, NULL);
 
                close(dfd);
-               if (!rv && st->ss->container_content)
-                       return Incremental_container(st, devname, homehost,
-                                                    verbose, runstop, autof,
-                                                    freeze_reshape);
+               if (!rv && st->ss->container_content) {
+                       if (map_lock(&map))
+                               fprintf(stderr, Name ": failed to get "
+                                       "exclusive lock on mapfile\n");
+                       rv = Incremental_container(st, devname, homehost,
+                                                  verbose, runstop, autof,
+                                                  freeze_reshape);
+                       map_unlock(&map);
+                       return rv;
+               }
 
                fprintf(stderr, Name ": %s is not part of an md array.\n",
                        devname);
@@ -440,7 +446,6 @@ int Incremental(char *devname, int verbose, int runstop,
        if (info.array.level == LEVEL_CONTAINER) {
                int devnum = devnum; /* defined and used iff ->external */
                /* Try to assemble within the container */
-               map_unlock(&map);
                sysfs_uevent(&info, "change");
                if (verbose >= 0)
                        fprintf(stderr, Name
@@ -449,11 +454,15 @@ int Incremental(char *devname, int verbose, int runstop,
                wait_for(chosen_name, mdfd);
                if (st->ss->external)
                        devnum = fd2devnum(mdfd);
+               if (st->ss->load_container)
+                       rv = st->ss->load_container(st, mdfd, NULL);
                close(mdfd);
                sysfs_free(sra);
-               rv = Incremental(chosen_name, verbose, runstop,
-                                NULL, homehost, require_homehost, autof,
-                                freeze_reshape);
+               if (!rv)
+                       rv = Incremental_container(st, chosen_name, homehost,
+                                                  verbose, runstop, autof,
+                                                  freeze_reshape);
+               map_unlock(&map);
                if (rv == 1)
                        /* Don't fail the whole -I if a subarray didn't
                         * have enough devices to start yet
@@ -1463,16 +1472,12 @@ static int Incremental_container(struct supertype *st, char *devname,
                trustworthy = FOREIGN;
 
        list = st->ss->container_content(st, NULL);
-       if (map_lock(&map))
-               fprintf(stderr, Name ": failed to get exclusive lock on "
-                       "mapfile\n");
        /* do not assemble arrays that might have bad blocks */
        if (list && list->array.state & (1<<MD_SB_BBM_ERRORS)) {
                fprintf(stderr, Name ": BBM log found in metadata. "
                                        "Cannot activate array(s).\n");
                /* free container data and exit */
                sysfs_free(list);
-               map_unlock(&map);
                return 2;
        }
 
@@ -1536,7 +1541,6 @@ static int Incremental_container(struct supertype *st, char *devname,
                                        fprintf(stderr, Name ": array %s/%s is "
                                                "explicitly ignored by mdadm.conf\n",
                                                match->container, match->member);
-                               map_unlock(&map);
                                return 2;
                        }
                        if (match)
@@ -1552,7 +1556,6 @@ static int Incremental_container(struct supertype *st, char *devname,
                if (mdfd < 0) {
                        fprintf(stderr, Name ": failed to open %s: %s.\n",
                                chosen_name, strerror(errno));
-                       map_unlock(&map);
                        return 2;
                }
 
@@ -1607,7 +1610,6 @@ static int Incremental_container(struct supertype *st, char *devname,
                        close(sfd);
        }
        domain_free(domains);
-       map_unlock(&map);
        return 0;
 }