Delay creation of array devices for assemble/build/create

We will shortly be feeding more information into the process of
creating array devices, so delay the creation.  Still open them
early if the device already exists.

This involves making sure the autof flag is in the right place
so that it can be found at creation time.

Also, Assemble, Build, and Create now always close 'mdfd'.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2008-11-04 10:35:37 +11:00
parent adf0493cba
commit 7f91af49ad
6 changed files with 181 additions and 129 deletions

View File

@ -50,7 +50,7 @@ static int name_matches(char *found, char *required, char *homehost)
return 0; return 0;
} }
int Assemble(struct supertype *st, char *mddev, int mdfd, int Assemble(struct supertype *st, char *mddev,
mddev_ident_t ident, mddev_ident_t ident,
mddev_dev_t devlist, char *backup_file, mddev_dev_t devlist, char *backup_file,
int readonly, int runstop, int readonly, int runstop,
@ -111,8 +111,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
* START_ARRAY * START_ARRAY
* *
*/ */
int mdfd = -1;
int clean = 0; int clean = 0;
int must_close = 0; int auto_assem = (mddev == NULL);
int old_linux = 0; int old_linux = 0;
int vers = 0; /* Keep gcc quite - it really is initialised */ int vers = 0; /* Keep gcc quite - it really is initialised */
struct { struct {
@ -133,7 +134,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
int change = 0; int change = 0;
int inargv = 0; int inargv = 0;
int bitmap_done; int bitmap_done;
int start_partial_ok = (runstop >= 0) && (force || devlist==NULL || mdfd < 0); int start_partial_ok = (runstop >= 0) &&
(force || devlist==NULL || auto_assem);
unsigned int num_devs; unsigned int num_devs;
mddev_dev_t tmpdev; mddev_dev_t tmpdev;
struct mdinfo info; struct mdinfo info;
@ -146,21 +148,31 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if (get_linux_version() < 2004000) if (get_linux_version() < 2004000)
old_linux = 1; old_linux = 1;
if (mddev != NULL) {
/* We need to create the device */
mdfd = create_mddev(mddev, 1);
if (mdfd < 0)
return 1;
}
if (mdfd >= 0) { if (mdfd >= 0) {
vers = md_get_version(mdfd); vers = md_get_version(mdfd);
if (vers <= 0) { if (vers <= 0) {
fprintf(stderr, Name ": %s appears not to be an md device.\n", mddev); fprintf(stderr, Name ": %s appears not to be an md device.\n", mddev);
close(mdfd);
return 1; return 1;
} }
if (vers < 9000) { if (vers < 9000) {
fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n" fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n"
" Upgrade your kernel or try --build\n"); " Upgrade your kernel or try --build\n");
close(mdfd);
return 1; return 1;
} }
if (ioctl(mdfd, GET_ARRAY_INFO, &info.array)>=0) { if (ioctl(mdfd, GET_ARRAY_INFO, &info.array)>=0) {
fprintf(stderr, Name ": device %s already active - cannot assemble it\n", fprintf(stderr, Name ": device %s already active - cannot assemble it\n",
mddev); mddev);
close(mdfd);
return 1; return 1;
} }
ioctl(mdfd, STOP_ARRAY, NULL); /* just incase it was started but has no content */ ioctl(mdfd, STOP_ARRAY, NULL); /* just incase it was started but has no content */
@ -179,6 +191,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
ident->devices == NULL) { ident->devices == NULL) {
fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n", fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n",
mddev ? mddev : "further assembly"); mddev ? mddev : "further assembly");
if (mdfd >= 0)
close(mdfd);
return 1; return 1;
} }
@ -229,7 +243,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
#endif #endif
if (devlist == NULL) if (devlist == NULL)
devlist = conf_get_devs(); devlist = conf_get_devs();
else if (mdfd >= 0) else if (mddev)
inargv = 1; inargv = 1;
try_again: try_again:
@ -379,6 +393,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
devname); devname);
if (st) if (st)
st->ss->free_super(st); st->ss->free_super(st);
if (mdfd >= 0)
close(mdfd);
return 1; return 1;
} }
@ -424,6 +440,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
devname); devname);
tst->ss->free_super(tst); tst->ss->free_super(tst);
st->ss->free_super(st); st->ss->free_super(st);
if (mdfd >= 0)
close(mdfd);
return 1; return 1;
} }
@ -479,12 +497,11 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
fprintf(stderr, Name ": %s needed for %s...\n", fprintf(stderr, Name ": %s needed for %s...\n",
mddev, tmpdev->devname); mddev, tmpdev->devname);
close(mdfd); close(mdfd);
mdfd = -1; mdfd = -3;
st->ss->free_super(st); st->ss->free_super(st);
free(devices); free(devices);
goto try_again; goto try_again;
} }
must_close = 1;
} }
/* Ok, no bad inconsistancy, we can try updating etc */ /* Ok, no bad inconsistancy, we can try updating etc */
@ -631,7 +648,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
inargv ? "the list" : inargv ? "the list" :
"the\n DEVICE list in mdadm.conf" "the\n DEVICE list in mdadm.conf"
); );
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
if (best[i] == -1 if (best[i] == -1
@ -647,7 +664,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
mddev); mddev);
if (st) if (st)
st->ss->free_super(st); st->ss->free_super(st);
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
@ -791,21 +808,21 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) { if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) {
fprintf(stderr, Name ": Cannot open %s: %s\n", fprintf(stderr, Name ": Cannot open %s: %s\n",
devices[j].devname, strerror(errno)); devices[j].devname, strerror(errno));
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
if (st->ss->load_super(st,fd, NULL)) { if (st->ss->load_super(st,fd, NULL)) {
close(fd); close(fd);
fprintf(stderr, Name ": RAID superblock has disappeared from %s\n", fprintf(stderr, Name ": RAID superblock has disappeared from %s\n",
devices[j].devname); devices[j].devname);
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
close(fd); close(fd);
} }
if (st->sb == NULL) { if (st->sb == NULL) {
fprintf(stderr, Name ": No suitable drives found for %s\n", mddev); fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
st->ss->getinfo_super(st, &info); st->ss->getinfo_super(st, &info);
@ -866,14 +883,14 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if (fd < 0) { if (fd < 0) {
fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n", fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
devices[chosen_drive].devname); devices[chosen_drive].devname);
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
if (st->ss->store_super(st, fd)) { if (st->ss->store_super(st, fd)) {
close(fd); close(fd);
fprintf(stderr, Name ": Could not re-write superblock on %s\n", fprintf(stderr, Name ": Could not re-write superblock on %s\n",
devices[chosen_drive].devname); devices[chosen_drive].devname);
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
close(fd); close(fd);
@ -908,7 +925,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
} }
if (err) { if (err) {
fprintf(stderr, Name ": Failed to restore critical section for reshape, sorry.\n"); fprintf(stderr, Name ": Failed to restore critical section for reshape, sorry.\n");
if (must_close) close(mdfd); close(mdfd);
return err; return err;
} }
} }
@ -926,13 +943,13 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if (rv) { if (rv) {
fprintf(stderr, Name ": failed to set array info for %s: %s\n", fprintf(stderr, Name ": failed to set array info for %s: %s\n",
mddev, strerror(errno)); mddev, strerror(errno));
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
if (ident->bitmap_fd >= 0) { if (ident->bitmap_fd >= 0) {
if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) { if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) {
fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n"); fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n");
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
} else if (ident->bitmap_file) { } else if (ident->bitmap_file) {
@ -941,13 +958,13 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if (bmfd < 0) { if (bmfd < 0) {
fprintf(stderr, Name ": Could not open bitmap file %s\n", fprintf(stderr, Name ": Could not open bitmap file %s\n",
ident->bitmap_file); ident->bitmap_file);
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) { if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev); fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev);
close(bmfd); close(bmfd);
if (must_close) close(mdfd); close(mdfd);
return 1; return 1;
} }
close(bmfd); close(bmfd);
@ -998,8 +1015,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
info.array.raid_disks); info.array.raid_disks);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
if (must_close) close(mdfd);
close(mdfd);
return 0; return 0;
} }
@ -1019,9 +1035,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s"); fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
fprintf(stderr, ".\n"); fprintf(stderr, ".\n");
} }
if (must_close) { close(mdfd);
if (auto_assem) {
int usecs = 1; int usecs = 1;
close(mdfd);
/* There is a nasty race with 'mdadm --monitor'. /* There is a nasty race with 'mdadm --monitor'.
* If it opens this device before we close it, * If it opens this device before we close it,
* it gets an incomplete open on which IO * it gets an incomplete open on which IO
@ -1063,10 +1079,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
"start the array while not clean " "start the array while not clean "
"- consider --force.\n"); "- consider --force.\n");
if (must_close) { if (auto_assem)
ioctl(mdfd, STOP_ARRAY, NULL); ioctl(mdfd, STOP_ARRAY, NULL);
close(mdfd); close(mdfd);
}
return 1; return 1;
} }
if (runstop == -1) { if (runstop == -1) {
@ -1075,7 +1090,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if (okcnt != info.array.raid_disks) if (okcnt != info.array.raid_disks)
fprintf(stderr, " (out of %d)", info.array.raid_disks); fprintf(stderr, " (out of %d)", info.array.raid_disks);
fprintf(stderr, ", but not started.\n"); fprintf(stderr, ", but not started.\n");
if (must_close) close(mdfd); close(mdfd);
return 0; return 0;
} }
if (verbose >= -1) { if (verbose >= -1) {
@ -1100,10 +1115,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
fprintf(stderr, " (use --run to insist).\n"); fprintf(stderr, " (use --run to insist).\n");
} }
} }
if (must_close) { if (auto_assem)
ioctl(mdfd, STOP_ARRAY, NULL); ioctl(mdfd, STOP_ARRAY, NULL);
close(mdfd);
}
return 1; return 1;
} else { } else {
/* The "chosen_drive" is a good choice, and if necessary, the superblock has /* The "chosen_drive" is a good choice, and if necessary, the superblock has
@ -1119,6 +1132,6 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
} }
} }
if (must_close) close(mdfd); close(mdfd);
return 0; return 0;
} }

29
Build.c
View File

@ -33,10 +33,10 @@
#define START_MD _IO (MD_MAJOR, 2) #define START_MD _IO (MD_MAJOR, 2)
#define STOP_MD _IO (MD_MAJOR, 3) #define STOP_MD _IO (MD_MAJOR, 3)
int Build(char *mddev, int mdfd, int chunk, int level, int layout, int Build(char *mddev, int chunk, int level, int layout,
int raiddisks, int raiddisks, mddev_dev_t devlist, int assume_clean,
mddev_dev_t devlist, int assume_clean, char *bitmap_file, int bitmap_chunk, int write_behind,
char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int verbose) int delay, int verbose, int autof)
{ {
/* Build a linear or raid0 arrays without superblocks /* Build a linear or raid0 arrays without superblocks
* We cannot really do any checks, we just do it. * We cannot really do any checks, we just do it.
@ -59,6 +59,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
int bitmap_fd; int bitmap_fd;
unsigned long long size = ~0ULL; unsigned long long size = ~0ULL;
unsigned long long bitmapsize; unsigned long long bitmapsize;
int mdfd;
/* scan all devices, make sure they really are block devices */ /* scan all devices, make sure they really are block devices */
for (dv = devlist; dv; dv=dv->next) { for (dv = devlist; dv; dv=dv->next) {
@ -112,6 +113,10 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
break; break;
} }
/* We need to create the device */
mdfd = create_mddev(mddev, autof);
if (mdfd < 0)
return 1;
vers = md_get_version(mdfd); vers = md_get_version(mdfd);
@ -140,17 +145,17 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
if (ioctl(mdfd, SET_ARRAY_INFO, &array)) { if (ioctl(mdfd, SET_ARRAY_INFO, &array)) {
fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n", fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n",
mddev, strerror(errno)); mddev, strerror(errno));
return 1; goto abort;
} }
} else if (bitmap_file) { } else if (bitmap_file) {
fprintf(stderr, Name ": bitmaps not supported with this kernel\n"); fprintf(stderr, Name ": bitmaps not supported with this kernel\n");
return 1; goto abort;
} }
if (bitmap_file && level <= 0) { if (bitmap_file && level <= 0) {
fprintf(stderr, Name ": bitmaps not meaningful with level %s\n", fprintf(stderr, Name ": bitmaps not meaningful with level %s\n",
map_num(pers, level)?:"given"); map_num(pers, level)?:"given");
return 1; goto abort;
} }
/* now add the devices */ /* now add the devices */
for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) { for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) {
@ -211,7 +216,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
if (bitmap_chunk == UnSet) { if (bitmap_chunk == UnSet) {
fprintf(stderr, Name ": %s cannot be openned.", fprintf(stderr, Name ": %s cannot be openned.",
bitmap_file); bitmap_file);
return 1; goto abort;
} }
#endif #endif
if (vers < 9003) { if (vers < 9003) {
@ -224,20 +229,20 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
bitmapsize = size>>9; /* FIXME wrong for RAID10 */ bitmapsize = size>>9; /* FIXME wrong for RAID10 */
if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk, if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk,
delay, write_behind, bitmapsize, major)) { delay, write_behind, bitmapsize, major)) {
return 1; goto abort;
} }
bitmap_fd = open(bitmap_file, O_RDWR); bitmap_fd = open(bitmap_file, O_RDWR);
if (bitmap_fd < 0) { if (bitmap_fd < 0) {
fprintf(stderr, Name ": %s cannot be openned.", fprintf(stderr, Name ": %s cannot be openned.",
bitmap_file); bitmap_file);
return 1; goto abort;
} }
} }
if (bitmap_fd >= 0) { if (bitmap_fd >= 0) {
if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n", fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n",
mddev, strerror(errno)); mddev, strerror(errno));
return 1; goto abort;
} }
} }
} }
@ -265,6 +270,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
if (verbose >= 0) if (verbose >= 0)
fprintf(stderr, Name ": array %s built and started.\n", fprintf(stderr, Name ": array %s built and started.\n",
mddev); mddev);
close(mdfd);
return 0; return 0;
abort: abort:
@ -272,5 +278,6 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
ioctl(mdfd, STOP_ARRAY, 0); ioctl(mdfd, STOP_ARRAY, 0);
else else
ioctl(mdfd, STOP_MD, 0); ioctl(mdfd, STOP_MD, 0);
close(mdfd);
return 1; return 1;
} }

View File

@ -32,12 +32,12 @@
#include "md_p.h" #include "md_p.h"
#include <ctype.h> #include <ctype.h>
int Create(struct supertype *st, char *mddev, int mdfd, int Create(struct supertype *st, char *mddev,
int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks, int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
char *name, char *homehost, int *uuid, char *name, char *homehost, int *uuid,
int subdevs, mddev_dev_t devlist, int subdevs, mddev_dev_t devlist,
int runstop, int verbose, int force, int assume_clean, int runstop, int verbose, int force, int assume_clean,
char *bitmap_file, int bitmap_chunk, int write_behind, int delay) char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int autof)
{ {
/* /*
* Create a new raid array. * Create a new raid array.
@ -55,6 +55,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
* if runstop==run, or raiddisks disks were used, * if runstop==run, or raiddisks disks were used,
* RUN_ARRAY * RUN_ARRAY
*/ */
int mdfd;
unsigned long long minsize=0, maxsize=0; unsigned long long minsize=0, maxsize=0;
char *mindisc = NULL; char *mindisc = NULL;
char *maxdisc = NULL; char *maxdisc = NULL;
@ -83,20 +84,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
vers = md_get_version(mdfd);
if (vers < 9000) {
fprintf(stderr, Name ": Create requires md driver version 0.90.0 or later\n");
return 1;
} else {
mdu_array_info_t inf;
memset(&inf, 0, sizeof(inf));
ioctl(mdfd, GET_ARRAY_INFO, &inf);
if (inf.working_disks != 0) {
fprintf(stderr, Name ": another array by this name"
" is already running.\n");
return 1;
}
}
if (level == UnSet) { if (level == UnSet) {
/* "ddf" and "imsm" metadata only supports one level - should possibly /* "ddf" and "imsm" metadata only supports one level - should possibly
* push this into metadata handler?? * push this into metadata handler??
@ -433,6 +420,25 @@ int Create(struct supertype *st, char *mddev, int mdfd,
return 1; return 1;
} }
/* We need to create the device */
mdfd = create_mddev(mddev, autof);
if (mdfd < 0)
return 1;
vers = md_get_version(mdfd);
if (vers < 9000) {
fprintf(stderr, Name ": Create requires md driver version 0.90.0 or later\n");
goto abort;
} else {
mdu_array_info_t inf;
memset(&inf, 0, sizeof(inf));
ioctl(mdfd, GET_ARRAY_INFO, &inf);
if (inf.working_disks != 0) {
fprintf(stderr, Name ": another array by this name"
" is already running.\n");
goto abort;
}
}
/* Ok, lets try some ioctls */ /* Ok, lets try some ioctls */
info.array.level = level; info.array.level = level;
@ -524,7 +530,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
} }
} }
if (!st->ss->init_super(st, &info.array, size, name, homehost, uuid)) if (!st->ss->init_super(st, &info.array, size, name, homehost, uuid))
return 1; goto abort;
total_slots = info.array.nr_disks; total_slots = info.array.nr_disks;
sysfs_init(&info, mdfd, 0); sysfs_init(&info, mdfd, 0);
@ -563,13 +569,13 @@ int Create(struct supertype *st, char *mddev, int mdfd,
if (bitmap_file && strcmp(bitmap_file, "internal")==0) { if (bitmap_file && strcmp(bitmap_file, "internal")==0) {
if ((vers%100) < 2) { if ((vers%100) < 2) {
fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n"); fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n");
return 1; goto abort;
} }
if (!st->ss->add_internal_bitmap(st, &bitmap_chunk, if (!st->ss->add_internal_bitmap(st, &bitmap_chunk,
delay, write_behind, delay, write_behind,
bitmapsize, 1, major_num)) { bitmapsize, 1, major_num)) {
fprintf(stderr, Name ": Given bitmap chunk size not supported.\n"); fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
return 1; goto abort;
} }
bitmap_file = NULL; bitmap_file = NULL;
} }
@ -596,7 +602,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
if (container_fd < 0) { if (container_fd < 0) {
fprintf(stderr, Name ": Cannot get exclusive " fprintf(stderr, Name ": Cannot get exclusive "
"open on container - weird.\n"); "open on container - weird.\n");
return 1; goto abort;
} }
if (mdmon_running(st->container_dev)) { if (mdmon_running(st->container_dev)) {
if (verbose) if (verbose)
@ -611,7 +617,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
if (rv) { if (rv) {
fprintf(stderr, Name ": failed to set array info for %s: %s\n", fprintf(stderr, Name ": failed to set array info for %s: %s\n",
mddev, strerror(errno)); mddev, strerror(errno));
return 1; goto abort;
} }
if (bitmap_file) { if (bitmap_file) {
@ -622,18 +628,18 @@ int Create(struct supertype *st, char *mddev, int mdfd,
delay, write_behind, delay, write_behind,
bitmapsize, bitmapsize,
major_num)) { major_num)) {
return 1; goto abort;
} }
bitmap_fd = open(bitmap_file, O_RDWR); bitmap_fd = open(bitmap_file, O_RDWR);
if (bitmap_fd < 0) { if (bitmap_fd < 0) {
fprintf(stderr, Name ": weird: %s cannot be openned\n", fprintf(stderr, Name ": weird: %s cannot be openned\n",
bitmap_file); bitmap_file);
return 1; goto abort;
} }
if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n", fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n",
mddev, strerror(errno)); mddev, strerror(errno));
return 1; goto abort;
} }
} }
@ -681,7 +687,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
fprintf(stderr, Name ": failed to open %s " fprintf(stderr, Name ": failed to open %s "
"after earlier success - aborting\n", "after earlier success - aborting\n",
dv->devname); dv->devname);
return 1; goto abort;
} }
fstat(fd, &stb); fstat(fd, &stb);
inf->disk.major = major(stb.st_rdev); inf->disk.major = major(stb.st_rdev);
@ -709,7 +715,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
"failed: %s\n", "failed: %s\n",
dv->devname, strerror(errno)); dv->devname, strerror(errno));
st->ss->free_super(st); st->ss->free_super(st);
return 1; goto abort;
} }
break; break;
} }
@ -749,7 +755,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n", fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
strerror(errno)); strerror(errno));
Manage_runstop(mddev, mdfd, -1, 0); Manage_runstop(mddev, mdfd, -1, 0);
return 1; goto abort;
} }
} }
if (verbose >= 0) if (verbose >= 0)
@ -764,5 +770,11 @@ int Create(struct supertype *st, char *mddev, int mdfd,
} else { } else {
fprintf(stderr, Name ": not starting array - not enough devices.\n"); fprintf(stderr, Name ": not starting array - not enough devices.\n");
} }
close(mdfd);
return 0; return 0;
abort:
if (mdfd >= 0)
close(mdfd);
return 1;
} }

103
mdadm.c
View File

@ -942,17 +942,36 @@ int main(int argc, char *argv[])
fprintf(stderr, Name ": --super-minor=dev is incompatible with --auto\n"); fprintf(stderr, Name ": --super-minor=dev is incompatible with --auto\n");
exit(2); exit(2);
} }
if (mode == MANAGE || mode == GROW) if (mode == MANAGE || mode == GROW) {
mdfd = open_mddev(devlist->devname, 1); mdfd = open_mddev(devlist->devname, 1);
else if (mdfd < 0)
mdfd = create_mddev(devlist->devname, autof); exit(1);
if (mdfd < 0) } else
/* non-existent device is OK */
mdfd = open_mddev(devlist->devname, 0);
if (mdfd == -2) {
fprintf(stderr, Name ": device %s exists but is not an "
"md array.\n", devlist->devname);
exit(1); exit(1);
}
if ((int)ident.super_minor == -2) { if ((int)ident.super_minor == -2) {
struct stat stb; struct stat stb;
if (mdfd < 0) {
fprintf(stderr, Name ": --super-minor=dev given, and "
"listed device %s doesn't exist.\n",
devlist->devname);
exit(1);
}
fstat(mdfd, &stb); fstat(mdfd, &stb);
ident.super_minor = minor(stb.st_rdev); ident.super_minor = minor(stb.st_rdev);
} }
if (mdfd >= 0 && mode != MANAGE && mode != GROW) {
/* We don't really want this open yet, we just might
* have wanted to check some things
*/
close(mdfd);
mdfd = -1;
}
} }
if (raiddisks) { if (raiddisks) {
@ -985,6 +1004,8 @@ int main(int argc, char *argv[])
} }
} }
ident.autof = autof;
rv = 0; rv = 0;
switch(mode) { switch(mode) {
case MANAGE: case MANAGE:
@ -1008,15 +1029,17 @@ int main(int argc, char *argv[])
fprintf(stderr, Name ": %s not identified in config file.\n", fprintf(stderr, Name ": %s not identified in config file.\n",
devlist->devname); devlist->devname);
rv |= 1; rv |= 1;
close(mdfd); if (mdfd >= 0)
close(mdfd);
} else { } else {
rv |= Assemble(ss, devlist->devname, mdfd, array_ident, if (array_ident->autof == 0)
NULL, backup_file, array_ident->autof = autof;
readonly, runstop, update, homehost, verbose-quiet, force); rv |= Assemble(ss, devlist->devname, array_ident,
close(mdfd); NULL, backup_file,
readonly, runstop, update, homehost, verbose-quiet, force);
} }
} else if (!scan) } else if (!scan)
rv = Assemble(ss, devlist->devname, mdfd, &ident, rv = Assemble(ss, devlist->devname, &ident,
devlist->next, backup_file, devlist->next, backup_file,
readonly, runstop, update, homehost, verbose-quiet, force); readonly, runstop, update, homehost, verbose-quiet, force);
else if (devs_found>0) { else if (devs_found>0) {
@ -1036,16 +1059,11 @@ int main(int argc, char *argv[])
rv |= 1; rv |= 1;
continue; continue;
} }
mdfd = create_mddev(dv->devname, if (array_ident->autof == 0)
array_ident->autof ?array_ident->autof : autof); array_ident->autof = autof;
if (mdfd < 0) { rv |= Assemble(ss, dv->devname, array_ident,
rv |= 1;
continue;
}
rv |= Assemble(ss, dv->devname, mdfd, array_ident,
NULL, backup_file, NULL, backup_file,
readonly, runstop, update, homehost, verbose-quiet, force); readonly, runstop, update, homehost, verbose-quiet, force);
close(mdfd);
} }
} else { } else {
mddev_ident_t array_list = conf_get_ident(NULL); mddev_ident_t array_list = conf_get_ident(NULL);
@ -1064,28 +1082,28 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
for (; array_list; array_list = array_list->next) { for (; array_list; array_list = array_list->next) {
mdu_array_info_t array; mdfd = open_mddev(array_list->devname, 0);
mdfd = create_mddev(array_list->devname, if (mdfd >= 0) {
array_list->autof ? array_list->autof : autof); mdu_array_info_t array;
if (mdfd < 0) { /* skip if already assembled */
rv |= 1; if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0) {
continue; cnt++;
close(mdfd);
continue;
}
} }
if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0) if (array_list->autof == 0)
/* already assembled, skip */ array_list->autof = autof;
cnt++;
else { rv |= Assemble(ss, array_list->devname,
rv |= Assemble(ss, array_list->devname, mdfd, array_list,
array_list, NULL, NULL,
NULL, NULL, readonly, runstop, NULL, homehost, verbose-quiet, force);
readonly, runstop, NULL, homehost, verbose-quiet, force); if (rv == 0) cnt++;
if (rv == 0) cnt++;
}
close(mdfd);
} }
if (homehost) { if (homehost) {
/* Maybe we can auto-assemble something. /* Maybe we can auto-assemble something.
* Repeatedly call Assemble in auto-assmble mode * Repeatedly call Assemble in auto-assemble mode
* until it fails * until it fails
*/ */
int rv2; int rv2;
@ -1095,7 +1113,7 @@ int main(int argc, char *argv[])
mddev_dev_t devlist = conf_get_devs(); mddev_dev_t devlist = conf_get_devs();
acnt = 0; acnt = 0;
do { do {
rv2 = Assemble(ss, NULL, -1, rv2 = Assemble(ss, NULL,
&ident, &ident,
devlist, NULL, devlist, NULL,
readonly, runstop, NULL, homehost, verbose-quiet, force); readonly, runstop, NULL, homehost, verbose-quiet, force);
@ -1116,7 +1134,7 @@ int main(int argc, char *argv[])
do { do {
acnt = 0; acnt = 0;
do { do {
rv2 = Assemble(ss, NULL, -1, rv2 = Assemble(ss, NULL,
&ident, &ident,
NULL, NULL, NULL, NULL,
readonly, runstop, "homehost", homehost, verbose-quiet, force); readonly, runstop, "homehost", homehost, verbose-quiet, force);
@ -1159,9 +1177,10 @@ int main(int argc, char *argv[])
break; break;
} }
} }
rv = Build(devlist->devname, mdfd, chunk, level, layout, rv = Build(devlist->devname, chunk, level, layout,
raiddisks, devlist->next, assume_clean, raiddisks, devlist->next, assume_clean,
bitmap_file, bitmap_chunk, write_behind, delay, verbose-quiet); bitmap_file, bitmap_chunk, write_behind,
delay, verbose-quiet, autof);
break; break;
case CREATE: case CREATE:
if (delay == 0) delay = DEFAULT_BITMAP_DELAY; if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
@ -1176,11 +1195,11 @@ int main(int argc, char *argv[])
break; break;
} }
rv = Create(ss, devlist->devname, mdfd, chunk, level, layout, size<0 ? 0 : size, rv = Create(ss, devlist->devname, chunk, level, layout, size<0 ? 0 : size,
raiddisks, sparedisks, ident.name, homehost, raiddisks, sparedisks, ident.name, homehost,
ident.uuid_set ? ident.uuid : NULL, ident.uuid_set ? ident.uuid : NULL,
devs_found-1, devlist->next, runstop, verbose-quiet, force, assume_clean, devs_found-1, devlist->next, runstop, verbose-quiet, force, assume_clean,
bitmap_file, bitmap_chunk, write_behind, delay); bitmap_file, bitmap_chunk, write_behind, delay, autof);
break; break;
case MISC: case MISC:
if (devmode == 'E') { if (devmode == 'E') {

14
mdadm.h
View File

@ -692,25 +692,25 @@ extern int Grow_restart(struct supertype *st, struct mdinfo *info,
int *fdlist, int cnt, char *backup_file); int *fdlist, int cnt, char *backup_file);
extern int Assemble(struct supertype *st, char *mddev, int mdfd, extern int Assemble(struct supertype *st, char *mddev,
mddev_ident_t ident, mddev_ident_t ident,
mddev_dev_t devlist, char *backup_file, mddev_dev_t devlist, char *backup_file,
int readonly, int runstop, int readonly, int runstop,
char *update, char *homehost, char *update, char *homehost,
int verbose, int force); int verbose, int force);
extern int Build(char *mddev, int mdfd, int chunk, int level, int layout, extern int Build(char *mddev, int chunk, int level, int layout,
int raiddisks, int raiddisks, mddev_dev_t devlist, int assume_clean,
mddev_dev_t devlist, int assume_clean, char *bitmap_file, int bitmap_chunk, int write_behind,
char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int verbose); int delay, int verbose, int autof);
extern int Create(struct supertype *st, char *mddev, int mdfd, extern int Create(struct supertype *st, char *mddev,
int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks, int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
char *name, char *homehost, int *uuid, char *name, char *homehost, int *uuid,
int subdevs, mddev_dev_t devlist, int subdevs, mddev_dev_t devlist,
int runstop, int verbose, int force, int assume_clean, int runstop, int verbose, int force, int assume_clean,
char *bitmap_file, int bitmap_chunk, int write_behind, int delay); char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int autof);
extern int Detail(char *dev, int brief, int export, int test, char *homehost); extern int Detail(char *dev, int brief, int export, int test, char *homehost);
extern int Query(char *dev); extern int Query(char *dev);

View File

@ -55,7 +55,7 @@ mapping_t pers[] = {
#ifndef MDASSEMBLE_AUTO #ifndef MDASSEMBLE_AUTO
/* from mdopen.c */ /* from mdopen.c */
int create_mddev(char *dev, int autof/*unused */) int open_mddev(char *dev, int report_errors/*unused*/)
{ {
int mdfd = open(dev, O_RDWR); int mdfd = open(dev, O_RDWR);
if (mdfd < 0) if (mdfd < 0)
@ -69,6 +69,10 @@ int create_mddev(char *dev, int autof/*unused */)
} }
return mdfd; return mdfd;
} }
int create_mddev(char *dev, int autof/*unused*/)
{
return open_mddev(dev, 0);
}
#endif #endif
int rv; int rv;
@ -86,19 +90,16 @@ int main(int argc, char *argv[]) {
} else } else
for (; array_list; array_list = array_list->next) { for (; array_list; array_list = array_list->next) {
mdu_array_info_t array; mdu_array_info_t array;
mdfd = create_mddev(array_list->devname, array_list->autof); mdfd = open_mddev(array_list->devname, 0);
if (mdfd < 0) { if (mdfd >= 0 && ioctl(mdfd, GET_ARRAY_INFO, &array) == 0) {
rv |= 1; rv |= Manage_ro(array_list->devname, mdfd, -1); /* make it readwrite */
continue; continue;
} }
if (ioctl(mdfd, GET_ARRAY_INFO, &array) < 0) { if (mdfd >= 0)
rv |= Assemble(array_list->st, array_list->devname, mdfd, close(mdfd);
array_list, NULL, NULL, rv |= Assemble(array_list->st, array_list->devname,
readonly, runstop, NULL, NULL, verbose, force); array_list, NULL, NULL,
} else { readonly, runstop, NULL, NULL, verbose, force);
rv |= Manage_ro(array_list->devname, mdfd, -1); /* make it readwrite */
}
close(mdfd);
} }
return rv; return rv;
} }