summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Assemble.c3
-rw-r--r--Incremental.c230
-rw-r--r--mdadm.h5
-rw-r--r--mdopen.c80
4 files changed, 54 insertions, 264 deletions
diff --git a/Assemble.c b/Assemble.c
index 742bc08..5179df9 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -209,7 +209,8 @@ int Assemble(struct supertype *st, char *mddev,
}
return Incremental_container(&container, ident->container,
- verbose, runstop, ident->autof);
+ verbose, runstop, ident->autof,
+ LOCAL);
}
#endif
if (devlist == NULL)
diff --git a/Incremental.c b/Incremental.c
index 08960a5..30bca4a 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -48,7 +48,8 @@ int Incremental(char *devname, int verbose, int runstop,
* 2/ Find metadata, reject if none appropriate (check
* version/name from args)
* 3/ Check if there is a match in mdadm.conf
- * 3a/ if not, check for homehost match. If no match, reject.
+ * 3a/ if not, check for homehost match. If no match, assemble as
+ * a 'foreign' array.
* 4/ Determine device number.
* - If in mdadm.conf with std name, use that
* - UUID in /var/run/mdadm.map use that
@@ -85,9 +86,8 @@ int Incremental(char *devname, int verbose, int runstop,
int dfd, mdfd;
char *avail;
int active_disks;
- int uuid_for_name = 0;
+ int trustworthy = FOREIGN;
char *name_to_use;
- char nbuf[64];
struct createinfo *ci = conf_get_create_info();
@@ -144,14 +144,6 @@ int Incremental(char *devname, int verbose, int runstop,
}
close (dfd);
- if (st->ss->container_content && st->loaded_container) {
- /* This is a pre-built container array, so we do something
- * rather different.
- */
- return Incremental_container(st, devname, verbose, runstop,
- autof);
- }
-
memset(&info, 0, sizeof(info));
st->ss->getinfo_super(st, &info);
/* 3/ Check if there is a match in mdadm.conf */
@@ -218,28 +210,15 @@ int Incremental(char *devname, int verbose, int runstop,
* but don't trust the 'name' in the array. Thus a 'random' minor
* number will be assigned, and the device name will be based
* on that. */
- if (!match) {
- if (homehost == NULL ||
- st->ss->match_home(st, homehost) != 1)
- uuid_for_name = 1;
- }
- /* 4/ Determine device number. */
- /* - If in mdadm.conf with std name, get number from name. */
- /* - UUID in /var/run/mdadm.map get number from mapping */
- /* - If name is suggestive, use that. unless in use with */
- /* different uuid. */
- /* - Choose a free, high number. */
- /* - Use a partitioned device unless strong suggestion not to. */
- /* e.g. auto=md */
- mp = map_by_uuid(&map, info.uuid);
-
- if (uuid_for_name && ! mp) {
- name_to_use = fname_from_uuid(st, &info, nbuf, '-');
- if (verbose >= 0)
- fprintf(stderr, Name
- ": not found in mdadm.conf and not identified by homehost"
- " - using uuid based name\n");
- } else
+ if (match)
+ trustworthy = LOCAL;
+ else if (homehost == NULL ||
+ st->ss->match_home(st, homehost) != 1)
+ trustworthy = FOREIGN;
+ name_to_use = strchr(info.name, ':');
+ if (name_to_use)
+ name_to_use++;
+ else
name_to_use = info.name;
/* There are three possible sources for 'autof': command line,
@@ -252,85 +231,35 @@ int Incremental(char *devname, int verbose, int runstop,
if (autof == 0)
autof = ci->autof;
- if (match && (rv = is_standard(match->devname, &devnum))) {
- devnum = (rv > 0) ? (-1-devnum) : devnum;
- } else if (mp != NULL)
- devnum = mp->devnum;
- else {
- /* Have to guess a bit. */
- int use_partitions = 1;
- char *np, *ep;
- char *nm, nbuf[1024];
- struct stat stb2;
-
- if ((autof&7) == 3 || (autof&7) == 5)
- use_partitions = 0;
- if (st->ss->external)
- use_partitions = 0;
- np = strchr(name_to_use, ':');
- if (np)
- np++;
- else
- np = name_to_use;
- devnum = strtoul(np, &ep, 10);
- if (ep > np && *ep == 0) {
- /* This is a number. Let check that it is unused. */
- if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
- devnum = -1;
- } else
- devnum = -1;
-
- if (match)
- nm = match->devname;
- else {
- sprintf(nbuf, "/dev/md/%s", np);
- nm = nbuf;
- }
- if (stat(nm, &stb2) == 0 &&
- S_ISBLK(stb2.st_mode) &&
- major(stb2.st_rdev) == (use_partitions ?
- get_mdp_major() : MD_MAJOR)) {
- if (use_partitions)
- devnum = minor(stb2.st_rdev) >> MdpMinorShift;
- else
- devnum = minor(stb2.st_rdev);
- if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
- devnum = -1;
- }
-
- if (devnum < 0) {
- /* Haven't found anything yet, choose something free */
- devnum = find_free_devnum(use_partitions);
-
- if (devnum == NoMdDev) {
- fprintf(stderr, Name
- ": No spare md devices!!\n");
- return 2;
- }
- } else
- devnum = use_partitions ? (-1-devnum) : devnum;
+ if (st->ss->container_content && st->loaded_container) {
+ /* This is a pre-built container array, so we do something
+ * rather different.
+ */
+ return Incremental_container(st, devname, verbose, runstop,
+ autof, trustworthy);
}
+ /* 4/ Check is array exists.
+ */
+ mp = map_by_uuid(&map, info.uuid);
+ if (mp)
+ mdfd = open_mddev(mp->path, 0);
+ else
+ mdfd = -1;
- mdfd = create_mddev_devnum(match ? match->devname : mp ? mp->path : NULL,
- devnum,
- name_to_use,
- chosen_name, autof >> 3);
if (mdfd < 0) {
- fprintf(stderr, Name ": failed to open %s: %s.\n",
- chosen_name, strerror(errno));
- return 2;
- }
- sysfs_init(&info, mdfd, 0);
-
- /* 5/ Find out if array already exists */
- if (! mddev_busy(devnum)) {
- /* 5a/ if it does not */
- /* - choose a name, from mdadm.conf or 'name' field in array. */
- /* - create the array */
- /* - add the device */
struct mdinfo *sra;
struct mdinfo dinfo;
+ /* Couldn't find an existing array, maybe make a new one */
+ mdfd = create_mddev(mp ? mp->path : match ? match->devname : NULL,
+ info.name, autof, trustworthy, chosen_name);
+
+
+ if (mdfd < 0)
+ return 1;
+
+ sysfs_init(&info, mdfd, 0);
+
if (set_array_info(mdfd, st, &info) != 0) {
fprintf(stderr, Name ": failed to set array info for %s: %s\n",
chosen_name, strerror(errno));
@@ -375,6 +304,9 @@ int Incremental(char *devname, int verbose, int runstop,
struct mdinfo *sra;
struct supertype *st2;
struct mdinfo info2, *d;
+
+ strcpy(chosen_name, mp->path);
+
sra = sysfs_read(mdfd, devnum, (GET_DEVS | GET_STATE));
sprintf(dn, "%d:%d", sra->devs->disk.major,
@@ -430,7 +362,7 @@ int Incremental(char *devname, int verbose, int runstop,
}
/* 6/ Make sure /var/run/mdadm.map contains this array. */
- map_update(&map, devnum,
+ map_update(&map, fd2devnum(mdfd),
info.text_version,
info.uuid, chosen_name);
@@ -502,7 +434,7 @@ int Incremental(char *devname, int verbose, int runstop,
}
sra = sysfs_read(mdfd, devnum, 0);
if ((sra == NULL || active_disks >= info.array.working_disks)
- && uuid_for_name == 0)
+ && trustworthy != FOREIGN)
rv = ioctl(mdfd, RUN_ARRAY, NULL);
else
rv = sysfs_set_str(sra, NULL,
@@ -710,12 +642,11 @@ int IncrementalScan(int verbose)
devs = conf_get_ident(NULL);
for (me = mapl ; me ; me = me->next) {
- char path[1024];
mdu_array_info_t array;
mdu_bitmap_file_t bmf;
struct mdinfo *sra;
- int mdfd = create_mddev_devnum(me->path, me->devnum,
- NULL, path, 0);
+ int mdfd = open_mddev(me->path, 0);
+
if (mdfd < 0)
continue;
if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
@@ -772,7 +703,7 @@ int IncrementalScan(int verbose)
}
int Incremental_container(struct supertype *st, char *devname, int verbose,
- int runstop, int autof)
+ int runstop, int autof, int trustworthy)
{
/* Collect the contents of this container and for each
* array, choose a device name and assemble the array.
@@ -783,29 +714,14 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
for (ra = list ; ra ; ra = ra->next) {
struct mdinfo *dev, *sra;
- int devnum = -1;
int mdfd;
char chosen_name[1024];
- int usepart = 1;
- char *n;
int working = 0, preexist = 0;
struct map_ent *mp, *map = NULL;
- char nbuf[64];
- char *name_to_use;
struct mddev_ident_s *match = NULL;
- if ((autof&7) == 3 || (autof&7) == 5)
- usepart = 0;
-
mp = map_by_uuid(&map, ra->uuid);
- name_to_use = ra->name;
- if (! name_to_use ||
- ! *name_to_use ||
- (*devname != '/' || strncmp("UUID-", strrchr(devname,'/')+1,5) == 0)
- )
- name_to_use = fname_from_uuid(st, ra, nbuf, '-');
-
if (!mp) {
/* Check in mdadm.conf for devices == devname and
@@ -850,57 +766,11 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
}
}
- if (match && is_standard(match->devname, &devnum))
- /* we have devnum now */;
- else if (mp)
- devnum = mp->devnum;
- else if (is_standard(name_to_use, &devnum))
- /* have devnum */;
- else {
- n = name_to_use;
- if (*n == 'd')
- n++;
- if (*n && devnum < 0) {
- devnum = strtoul(n, &n, 10);
- if (devnum >= 0 && (*n == 0 || *n == ' ')) {
- /* Use this devnum */
- usepart = (name_to_use[0] == 'd');
- if (mddev_busy(usepart ? (-1-devnum) : devnum))
- devnum = -1;
- } else
- devnum = -1;
- }
-
- if (devnum < 0) {
- char *nm = name_to_use;
- char nbuf[1024];
- struct stat stb;
- if (strchr(nm, ':'))
- nm = strchr(nm, ':')+1;
- sprintf(nbuf, "/dev/md/%s", nm);
-
- if (stat(nbuf, &stb) == 0 &&
- S_ISBLK(stb.st_mode) &&
- major(stb.st_rdev) == (usepart ?
- get_mdp_major() : MD_MAJOR)){
- if (usepart)
- devnum = minor(stb.st_rdev)
- >> MdpMinorShift;
- else
- devnum = minor(stb.st_rdev);
- if (mddev_busy(usepart ? (-1-devnum) : devnum))
- devnum = -1;
- }
- }
-
- if (devnum >= 0)
- devnum = usepart ? (-1-devnum) : devnum;
- else
- devnum = find_free_devnum(usepart);
- }
- mdfd = create_mddev_devnum(mp ? mp->path : match ? match->devname : NULL,
- devnum, name_to_use,
- chosen_name, autof>>3);
+ mdfd = create_mddev(match ? match->devname : NULL,
+ ra->name,
+ autof,
+ trustworthy,
+ chosen_name);
if (mdfd < 0) {
fprintf(stderr, Name ": failed to open %s: %s.\n",
@@ -959,10 +829,10 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
": %s assembled with %d devices but "
"not started\n",
chosen_name, working);
- close(mdfd);
- map_update(&map, devnum,
+ map_update(&map, fd2devnum(mdfd),
ra->text_version,
ra->uuid, chosen_name);
+ close(mdfd);
}
return 0;
}
diff --git a/mdadm.h b/mdadm.h
index 5e76be7..b94cda3 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -728,7 +728,8 @@ extern int WaitClean(char *dev, int verbose);
extern int Incremental(char *devname, int verbose, int runstop,
struct supertype *st, char *homehost, int autof);
extern int Incremental_container(struct supertype *st, char *devname,
- int verbose, int runstop, int autof);
+ int verbose, int runstop, int autof,
+ int trustworthy);
extern void RebuildMap(void);
extern int IncrementalScan(int verbose);
@@ -808,8 +809,6 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy,
#define FOREIGN 2
#define METADATA 3
extern int open_mddev(char *dev, int report_errors);
-extern int create_mddev_devnum(char *devname, int devnum, char *name,
- char *chosen_name, int parts);
extern int open_container(int fd);
extern int mdmon_running(int devnum);
diff --git a/mdopen.c b/mdopen.c
index 4c0714d..ae3620a 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -360,83 +360,3 @@ int open_mddev(char *dev, int report_errors)
}
return mdfd;
}
-
-
-int create_mddev_devnum(char *devname, int devnum, char *name,
- char *chosen_name, int parts)
-{
- /* Open the md device with number 'devnum', possibly using 'devname',
- * possibly constructing a name with 'name', but in any case, copying
- * the name into 'chosen_name'
- */
- int major_num, minor_num;
- struct stat stb;
- int i;
- struct createinfo *ci = conf_get_create_info();
-
- if (devname)
- strcpy(chosen_name, devname);
- else if (name && *name && name[0] && strchr(name,'/') == NULL) {
- char *n = strchr(name, ':');
- if (n) n++; else n = name;
- if (isdigit(*n) && devnum < 0)
- sprintf(chosen_name, "/dev/md/d%s", n);
- else
- sprintf(chosen_name, "/dev/md/%s", n);
- } else {
- if (devnum >= 0)
- sprintf(chosen_name, "/dev/md%d", devnum);
- else
- sprintf(chosen_name, "/dev/md/d%d", -1-devnum);
- }
- if (devnum >= 0) {
- major_num = MD_MAJOR;
- minor_num = devnum;
- } else {
- major_num = get_mdp_major();
- minor_num = (-1-devnum) << 6;
- }
- if (stat(chosen_name, &stb) == 0) {
- /* It already exists. Check it is right. */
- if ( ! S_ISBLK(stb.st_mode) ||
- stb.st_rdev != makedev(major_num, minor_num)) {
- errno = EEXIST;
- return -1;
- }
- } else {
- /* special case: if --incremental is suggesting a name
- * in /dev/md/, we make sure the directory exists.
- */
- if (strncmp(chosen_name, "/dev/md/", 8) == 0) {
- if (mkdir("/dev/md",0700)==0) {
- if (chown("/dev/md", ci->uid, ci->gid))
- perror("chown /dev/md");
- if (chmod("/dev/md", ci->mode|
- ((ci->mode>>2) & 0111)))
- perror("chmod /dev/md");
- }
- }
-
- if (mknod(chosen_name, S_IFBLK | 0600,
- makedev(major_num, minor_num)) != 0) {
- return -1;
- }
- /* FIXME chown/chmod ?? */
- }
-
- /* Simple locking to avoid --incr being called for the same
- * array multiple times in parallel.
- */
- for (i = 0; i < 25 ; i++) {
- int fd;
-
- fd = open(chosen_name, O_RDWR|O_EXCL);
- if (fd >= 0 || errno != EBUSY) {
- if (devnum < 0)
- make_parts(chosen_name, parts);
- return fd;
- }
- usleep(200000);
- }
- return -1;
-}