Discard devnum in favour of devnm

We widely use a "devnum" which is 0 or +ve for md%d devices
and -ve for md_d%d devices.
But I want to be able to use md_%s device names.

So get rid of devnum (a number) and use devnm (a 32char string).
eg.
  md0
  md_d2
  md_home

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2012-11-01 16:14:01 +11:00
parent fdcad551e9
commit 4dd2df0966
29 changed files with 653 additions and 711 deletions

View File

@ -217,7 +217,7 @@ static int select_devices(struct mddev_dev *devlist,
devname);
tmpdev->used = 2;
} else if (auto_assem &&
!conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
!conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)),
tst->ss->match_home(tst, c->homehost) == 1)) {
if (report_mismatch)
pr_err("%s has metadata type %s for which "
@ -243,7 +243,7 @@ static int select_devices(struct mddev_dev *devlist,
tst->ss->name, devname);
tmpdev->used = 2;
} else if (auto_assem && st == NULL &&
!conf_test_metadata(tst->ss->name, (pol = devnum_policy(stb.st_rdev)),
!conf_test_metadata(tst->ss->name, (pol = devid_policy(stb.st_rdev)),
tst->ss->match_home(tst, c->homehost) == 1)) {
if (report_mismatch)
pr_err("%s has metadata type %s for which "
@ -469,7 +469,7 @@ static int select_devices(struct mddev_dev *devlist,
/* Collect domain information from members only */
if (tmpdev && tmpdev->used == 1) {
if (!pol)
pol = devnum_policy(stb.st_rdev);
pol = devid_policy(stb.st_rdev);
domain_merge(&domains, pol, tst?tst->ss->name:NULL);
}
dev_policy_free(pol);
@ -510,7 +510,7 @@ static int select_devices(struct mddev_dev *devlist,
tmpdev->devname, strerror(errno));
tmpdev->used = 2;
} else {
struct dev_policy *pol = devnum_policy(stb.st_rdev);
struct dev_policy *pol = devid_policy(stb.st_rdev);
int dt = domain_test(domains, pol, NULL);
if (inargv && dt != 0)
/* take this spare as domains match
@ -1032,7 +1032,7 @@ static int start_array(int mdfd,
* of the stripe cache - default is 256
*/
if (256 < 4 * (content->array.chunk_size/4096)) {
struct mdinfo *sra = sysfs_read(mdfd, 0, 0);
struct mdinfo *sra = sysfs_read(mdfd, NULL, 0);
if (sra)
sysfs_set_num(sra, NULL,
"stripe_cache_size",
@ -1269,7 +1269,7 @@ try_again:
if (mp) {
struct mdinfo *dv;
/* array already exists. */
pre_exist = sysfs_read(-1, mp->devnum, GET_LEVEL|GET_DEVS);
pre_exist = sysfs_read(-1, mp->devnm, GET_LEVEL|GET_DEVS);
if (pre_exist->array.level != UnSet) {
pr_err("Found some drive for an array that is already active: %s\n",
mp->path);
@ -1302,7 +1302,7 @@ try_again:
strcmp(mddev, chosen_name) != 0)
pr_err("Merging with already-assembled %s\n",
chosen_name);
mdfd = open_dev_excl(mp->devnum);
mdfd = open_dev_excl(mp->devnm);
} else {
int trustworthy = FOREIGN;
name = content->name;
@ -1359,7 +1359,7 @@ try_again:
return 1;
}
if (pre_exist == NULL) {
if (mddev_busy(fd2devnum(mdfd))) {
if (mddev_busy(fd2devnm(mdfd))) {
pr_err("%s already active, cannot restart it!\n",
mddev);
for (tmpdev = devlist ;
@ -1526,7 +1526,7 @@ try_again:
}
st->ss->getinfo_super(st, content, NULL);
#ifndef MDASSEMBLE
sysfs_init(content, mdfd, 0);
sysfs_init(content, mdfd, NULL);
#endif
for (i=0; i<bestcnt; i++) {
int j = best[i];
@ -1665,7 +1665,7 @@ try_again:
/* First, fill in the map, so that udev can find our name
* as soon as we become active.
*/
map_update(&map, fd2devnum(mdfd), content->text_version,
map_update(&map, fd2devnm(mdfd), content->text_version,
content->uuid, chosen_name);
rv = start_array(mdfd, mddev, content,
@ -1726,9 +1726,9 @@ int assemble_container_content(struct supertype *st, int mdfd,
int old_raid_disks;
int start_reshape;
sysfs_init(content, mdfd, 0);
sysfs_init(content, mdfd, NULL);
sra = sysfs_read(mdfd, 0, GET_VERSION);
sra = sysfs_read(mdfd, NULL, GET_VERSION);
if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0) {
if (content->array.major_version == -1 &&
content->array.minor_version == -2 &&
@ -1770,7 +1770,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
if (working + expansion == 0)
return 1;/* Nothing new, don't try to start */
map_update(&map, fd2devnum(mdfd),
map_update(&map, fd2devnm(mdfd),
content->text_version,
content->uuid, chosen_name);
@ -1792,10 +1792,10 @@ int assemble_container_content(struct supertype *st, int mdfd,
return 1;
if (st->ss->external) {
if (!mdmon_running(st->container_dev))
start_mdmon(st->container_dev);
ping_monitor_by_id(st->container_dev);
if (mdmon_running(st->container_dev) &&
if (!mdmon_running(st->container_devnm))
start_mdmon(st->container_devnm);
ping_monitor(st->container_devnm);
if (mdmon_running(st->container_devnm) &&
st->update_tail == NULL)
st->update_tail = &st->updates;
}
@ -1814,9 +1814,9 @@ int assemble_container_content(struct supertype *st, int mdfd,
"readonly");
/* start mdmon if needed. */
if (!err) {
if (!mdmon_running(st->container_dev))
start_mdmon(st->container_dev);
ping_monitor_by_id(st->container_dev);
if (!mdmon_running(st->container_devnm))
start_mdmon(st->container_devnm);
ping_monitor(st->container_devnm);
}
break;
}

View File

@ -115,7 +115,7 @@ int Build(char *mddev, struct mddev_dev *devlist,
}
mddev = chosen_name;
map_update(&map, fd2devnum(mdfd), "none", uuid, chosen_name);
map_update(&map, fd2devnm(mdfd), "none", uuid, chosen_name);
map_unlock(&map);
vers = md_get_version(mdfd);

View File

@ -703,31 +703,31 @@ int Create(struct supertype *st, char *mddev,
total_slots = info.array.nr_disks;
st->ss->getinfo_super(st, &info, NULL);
sysfs_init(&info, mdfd, 0);
sysfs_init(&info, mdfd, NULL);
if (did_default && c->verbose >= 0) {
if (is_subarray(info.text_version)) {
int dnum = devname2devnum(info.text_version+1);
char *path;
int mdp = get_mdp_major();
char devnm[32];
char *ep;
struct mdinfo *mdi;
if (dnum > 0)
path = map_dev(MD_MAJOR, dnum, 1);
else
path = map_dev(mdp, (-1-dnum)<< 6, 1);
mdi = sysfs_read(-1, dnum, GET_VERSION);
strncpy(devnm, info.text_version+1, 32);
devnm[31] = 0;
ep = strchr(devnm, '/');
if (ep)
*ep = 0;
pr_err("Creating array inside "
"%s container %s\n",
mdi?mdi->text_version:"managed", path);
mdi = sysfs_read(-1, devnm, GET_VERSION);
pr_err("Creating array inside %s container %s\n",
mdi?mdi->text_version:"managed", devnm);
sysfs_free(mdi);
} else
pr_err("Defaulting to version"
" %s metadata\n", info.text_version);
}
map_update(&map, fd2devnum(mdfd), info.text_version,
map_update(&map, fd2devnm(mdfd), info.text_version,
info.uuid, chosen_name);
map_unlock(&map);
@ -758,9 +758,9 @@ int Create(struct supertype *st, char *mddev,
s->bitmap_file = NULL;
}
sysfs_init(&info, mdfd, 0);
sysfs_init(&info, mdfd, NULL);
if (st->ss->external && st->container_dev != NoMdDev) {
if (st->ss->external && st->container_devnm[0]) {
/* member */
/* When creating a member, we need to be careful
@ -775,17 +775,17 @@ int Create(struct supertype *st, char *mddev,
*
* For now, fail if it is already running.
*/
container_fd = open_dev_excl(st->container_dev);
container_fd = open_dev_excl(st->container_devnm);
if (container_fd < 0) {
pr_err("Cannot get exclusive "
"open on container - weird.\n");
goto abort;
}
if (mdmon_running(st->container_dev)) {
if (mdmon_running(st->container_devnm)) {
if (c->verbose)
pr_err("reusing mdmon "
"for %s.\n",
devnum2devname(st->container_dev));
st->container_devnm);
st->update_tail = &st->updates;
} else
need_mdmon = 1;
@ -864,7 +864,7 @@ int Create(struct supertype *st, char *mddev,
fd = -1;
else {
if (st->ss->external &&
st->container_dev != NoMdDev)
st->container_devnm[0])
fd = open(dv->devname, O_RDWR);
else
fd = open(dv->devname, O_RDWR|O_EXCL);
@ -932,10 +932,10 @@ int Create(struct supertype *st, char *mddev,
st->ss->getinfo_super(st, &info_new, NULL);
if (st->ss->external && s->level != LEVEL_CONTAINER &&
!same_uuid(info_new.uuid, info.uuid, 0)) {
map_update(&map, fd2devnum(mdfd),
map_update(&map, fd2devnm(mdfd),
info_new.text_version,
info_new.uuid, chosen_name);
me = map_by_devnum(&map, st->container_dev);
me = map_by_devnm(&map, st->container_devnm);
}
if (st->ss->write_init_super(st)) {
@ -948,7 +948,7 @@ int Create(struct supertype *st, char *mddev,
char *path = xstrdup(me->path);
st->ss->getinfo_super(st, &info_new, NULL);
map_update(&map, st->container_dev,
map_update(&map, st->container_devnm,
info_new.text_version,
info_new.uuid, path);
free(path);
@ -1019,11 +1019,11 @@ int Create(struct supertype *st, char *mddev,
}
if (c->verbose >= 0)
pr_err("array %s started.\n", mddev);
if (st->ss->external && st->container_dev != NoMdDev) {
if (st->ss->external && st->container_devnm[0]) {
if (need_mdmon)
start_mdmon(st->container_dev);
start_mdmon(st->container_devnm);
ping_monitor_by_id(st->container_dev);
ping_monitor(st->container_devnm);
close(container_fd);
}
wait_for(chosen_name, mdfd);
@ -1036,7 +1036,7 @@ int Create(struct supertype *st, char *mddev,
abort:
map_lock(&map);
abort_locked:
map_remove(&map, fd2devnum(mdfd));
map_remove(&map, fd2devnm(mdfd));
map_unlock(&map);
if (mdfd >= 0)

View File

@ -88,7 +88,7 @@ int Detail(char *dev, struct context *c)
close(fd);
return rv;
}
sra = sysfs_read(fd, 0, GET_VERSION);
sra = sysfs_read(fd, NULL, GET_VERSION);
st = super_by_fd(fd, &subarray);
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
@ -102,10 +102,11 @@ int Detail(char *dev, struct context *c)
/* This is a subarray of some container.
* We want the name of the container, and the member
*/
int dn = st->container_dev;
int devid = devnm2devid(st->container_devnm);
member = subarray;
container = map_dev_preferred(dev2major(dn), dev2minor(dn), 1, c->prefer);
container = map_dev_preferred(major(devid), minor(devid),
1, c->prefer);
}
/* try to load a superblock */
@ -217,7 +218,7 @@ int Detail(char *dev, struct context *c)
} else {
struct map_ent *mp, *map = NULL;
char nbuf[64];
mp = map_by_devnum(&map, fd2devnum(fd));
mp = map_by_devnm(&map, fd2devnm(fd));
if (mp) {
__fname_from_uuid(mp->uuid, 0, nbuf, ':');
printf("MD_UUID=%s\n", nbuf+5);
@ -306,12 +307,11 @@ int Detail(char *dev, struct context *c)
unsigned long long larray_size;
struct mdstat_ent *ms = mdstat_read(0, 0);
struct mdstat_ent *e;
int devnum = array.md_minor;
if (major(stb.st_rdev) == (unsigned)get_mdp_major())
devnum = -1 - devnum;
char *devnm;
devnm = stat2devnm(&stb);
for (e=ms; e; e=e->next)
if (e->devnum == devnum)
if (strcmp(e->devnm, devnm) == 0)
break;
if (!get_dev_size(fd, NULL, &larray_size))
larray_size = 0;
@ -498,7 +498,7 @@ This is pretty boring
char path[200];
char vbuf[1024];
int nlen = strlen(sra->sys_name);
int dn;
int devid;
if (de->d_name[0] == '.')
continue;
sprintf(path, "/sys/block/%s/md/metadata_version",
@ -510,10 +510,10 @@ This is pretty boring
strncmp(vbuf+10, sra->sys_name, nlen) != 0 ||
vbuf[10+nlen] != '/')
continue;
dn = devname2devnum(de->d_name);
devid = devnm2devid(de->d_name);
printf(" %s", map_dev_preferred(
dev2major(dn),
dev2minor(dn), 1, c->prefer));
major(devid),
minor(devid), 1, c->prefer));
}
if (dir)
closedir(dir);

147
Grow.c
View File

@ -382,7 +382,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
"with %s metadata\n", st->ss->name);
return 1;
}
mdi = sysfs_read(fd, -1, GET_BITMAP_LOCATION);
mdi = sysfs_read(fd, NULL, GET_BITMAP_LOCATION);
if (mdi)
offset_setable = 1;
for (d=0; d< st->max_devs; d++) {
@ -421,7 +421,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
}
if (offset_setable) {
st->ss->getinfo_super(st, mdi, NULL);
sysfs_init(mdi, fd, -1);
sysfs_init(mdi, fd, NULL);
rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
mdi->bitmap_offset);
} else {
@ -533,13 +533,11 @@ static int check_idle(struct supertype *st)
/* Check that all member arrays for this container, or the
* container of this array, are idle
*/
int container_dev = (st->container_dev != NoMdDev
? st->container_dev : st->devnum);
char container[40];
char *container = (st->container_devnm[0]
? st->container_devnm : st->devnm);
struct mdstat_ent *ent, *e;
int is_idle = 1;
fmt_devname(container, container_dev);
ent = mdstat_read(0, 0);
for (e = ent ; e; e = e->next) {
if (!is_container_member(e, container))
@ -555,15 +553,12 @@ static int check_idle(struct supertype *st)
static int freeze_container(struct supertype *st)
{
int container_dev = (st->container_dev != NoMdDev
? st->container_dev : st->devnum);
char container[40];
char *container = (st->container_devnm[0]
? st->container_devnm : st->devnm);
if (!check_idle(st))
return -1;
fmt_devname(container, container_dev);
if (block_monitor(container, 1)) {
pr_err("failed to freeze container\n");
return -2;
@ -574,11 +569,8 @@ static int freeze_container(struct supertype *st)
static void unfreeze_container(struct supertype *st)
{
int container_dev = (st->container_dev != NoMdDev
? st->container_dev : st->devnum);
char container[40];
fmt_devname(container, container_dev);
char *container = (st->container_devnm[0]
? st->container_devnm : st->devnm);
unblock_monitor(container, 1);
}
@ -594,7 +586,7 @@ static int freeze(struct supertype *st)
if (st->ss->external)
return freeze_container(st);
else {
struct mdinfo *sra = sysfs_read(-1, st->devnum, GET_VERSION);
struct mdinfo *sra = sysfs_read(-1, st->devnm, GET_VERSION);
int err;
char buf[20];
@ -616,7 +608,7 @@ static void unfreeze(struct supertype *st)
if (st->ss->external)
return unfreeze_container(st);
else {
struct mdinfo *sra = sysfs_read(-1, st->devnum, GET_VERSION);
struct mdinfo *sra = sysfs_read(-1, st->devnm, GET_VERSION);
if (sra)
sysfs_set_str(sra, NULL, "sync_action", "idle");
@ -1541,7 +1533,6 @@ int Grow_reshape(char *devname, int fd,
int frozen;
int changed = 0;
char *container = NULL;
char container_buf[20];
int cfd = -1;
struct mddev_dev *dv;
@ -1594,16 +1585,15 @@ int Grow_reshape(char *devname, int fd,
* pre-requisite spare devices (mdmon owns final validation)
*/
if (st->ss->external) {
int container_dev;
int rv;
if (subarray) {
container_dev = st->container_dev;
cfd = open_dev_excl(st->container_dev);
container = st->container_devnm;
cfd = open_dev_excl(st->container_devnm);
} else {
container_dev = st->devnum;
container = st->devnm;
close(fd);
cfd = open_dev_excl(st->devnum);
cfd = open_dev_excl(st->devnm);
fd = cfd;
}
if (cfd < 0) {
@ -1613,9 +1603,6 @@ int Grow_reshape(char *devname, int fd,
return 1;
}
fmt_devname(container_buf, container_dev);
container = container_buf;
rv = st->ss->load_container(st, cfd, NULL);
if (rv) {
@ -1646,7 +1633,7 @@ int Grow_reshape(char *devname, int fd,
pr_err("cannot reshape arrays in"
" container with unsupported"
" metadata: %s(%s)\n",
devname, container_buf);
devname, container);
sysfs_free(cc);
free(subarray);
return 1;
@ -1654,7 +1641,7 @@ int Grow_reshape(char *devname, int fd,
}
sysfs_free(cc);
}
if (mdmon_running(container_dev))
if (mdmon_running(container))
st->update_tail = &st->updates;
}
@ -1673,7 +1660,7 @@ int Grow_reshape(char *devname, int fd,
return 1;
}
sra = sysfs_read(fd, 0, GET_LEVEL | GET_DISKS | GET_DEVS
sra = sysfs_read(fd, NULL, GET_LEVEL | GET_DISKS | GET_DEVS
| GET_STATE | GET_VERSION);
if (sra) {
if (st->ss->external && subarray == NULL) {
@ -1803,10 +1790,10 @@ int Grow_reshape(char *devname, int fd,
}
/* make sure mdmon is
* aware of the new level */
if (!mdmon_running(st->container_dev))
start_mdmon(st->container_dev);
if (!mdmon_running(st->container_devnm))
start_mdmon(st->container_devnm);
ping_monitor(container);
if (mdmon_running(st->container_dev) &&
if (mdmon_running(st->container_devnm) &&
st->update_tail == NULL)
st->update_tail = &st->updates;
}
@ -1930,7 +1917,7 @@ size_change_error:
memset(&info, 0, sizeof(info));
info.array = array;
sysfs_init(&info, fd, NoMdDev);
sysfs_init(&info, fd, NULL);
strcpy(info.text_version, sra->text_version);
info.component_size = s->size*2;
info.new_level = s->level;
@ -2193,7 +2180,7 @@ static int raid10_reshape(char *container, int fd, char *devname,
int dir = 0;
int err = 0;
sra = sysfs_read(fd, 0,
sra = sysfs_read(fd, NULL,
GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|GET_CHUNK
);
if (!sra) {
@ -2389,7 +2376,7 @@ static void get_space_after(int fd, struct supertype *st, struct mdinfo *info)
unsigned long long min_space_before = 0, min_space_after = 0;
int first = 1;
sra = sysfs_read(fd, 0, GET_DEVS);
sra = sysfs_read(fd, NULL, GET_DEVS);
if (!sra)
return;
for (sd = sra->devs; sd; sd = sd->next) {
@ -2586,13 +2573,13 @@ static int reshape_array(char *container, int fd, char *devname,
if (reshape.level > 0 && st->ss->external) {
/* make sure mdmon is aware of the new level */
if (mdmon_running(st->container_dev))
if (mdmon_running(container))
flush_mdmon(container);
if (!mdmon_running(st->container_dev))
start_mdmon(st->container_dev);
if (!mdmon_running(container))
start_mdmon(container);
ping_monitor(container);
if (mdmon_running(st->container_dev) &&
if (mdmon_running(container) &&
st->update_tail == NULL)
st->update_tail = &st->updates;
}
@ -2609,7 +2596,7 @@ static int reshape_array(char *container, int fd, char *devname,
struct mdinfo *d;
if (info2) {
sysfs_init(info2, fd, st->devnum);
sysfs_init(info2, fd, st->devnm);
/* When increasing number of devices, we need to set
* new raid_disks before adding these, or they might
* be rejected.
@ -2744,7 +2731,7 @@ started:
&reshape, data_offset,
force, verbose);
}
sra = sysfs_read(fd, 0,
sra = sysfs_read(fd, NULL,
GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|GET_CHUNK|
GET_CACHE);
if (!sra) {
@ -2958,7 +2945,7 @@ started:
delayed = 0;
mds = mdstat_read(0, 0);
for (m = mds; m; m = m->next)
if (m->devnum == devname2devnum(sra->sys_name)) {
if (strcmp(m->devnm, sra->sys_name) == 0) {
if (m->resync &&
m->percent == RESYNC_DELAYED)
delayed = 1;
@ -3025,7 +3012,7 @@ started:
if (st->ss->external) {
/* Re-load the metadata as much could have changed */
int cfd = open_dev(st->container_dev);
int cfd = open_dev(st->container_devnm);
if (cfd >= 0) {
flush_mdmon(container);
st->ss->free_super(st);
@ -3087,7 +3074,7 @@ int reshape_container(char *container, char *devname,
{
struct mdinfo *cc = NULL;
int rv = restart;
int last_devnum = -1;
char last_devnm[32] = "";
/* component_size is not meaningful for a container,
* so pass '0' meaning 'no change'
@ -3144,6 +3131,7 @@ int reshape_container(char *container, char *devname,
int fd;
struct mdstat_ent *mdstat;
char *adev;
int devid;
sysfs_free(cc);
@ -3155,13 +3143,12 @@ int reshape_container(char *container, char *devname,
continue;
subarray = strchr(content->text_version+1, '/')+1;
mdstat = mdstat_by_subdev(subarray,
devname2devnum(container));
mdstat = mdstat_by_subdev(subarray, container);
if (!mdstat)
continue;
if (mdstat->active == 0) {
pr_err("Skipping inactive "
"array md%i.\n", mdstat->devnum);
pr_err("Skipping inactive array %s.\n",
mdstat->devnm);
free_mdstat(mdstat);
mdstat = NULL;
continue;
@ -3171,20 +3158,19 @@ int reshape_container(char *container, char *devname,
if (!content)
break;
adev = map_dev(dev2major(mdstat->devnum),
dev2minor(mdstat->devnum),
0);
devid = devnm2devid(mdstat->devnm);
adev = map_dev(major(devid), minor(devid), 0);
if (!adev)
adev = content->text_version;
fd = open_dev(mdstat->devnum);
fd = open_dev(mdstat->devnm);
if (fd < 0) {
printf(Name ": Device %s cannot be opened for reshape.",
adev);
break;
}
if (last_devnum == mdstat->devnum) {
if (strcmp(last_devnm, mdstat->devnm) == 0) {
/* Do not allow for multiple reshape_array() calls for
* the same array.
* It can happen when reshape_array() returns without
@ -3200,11 +3186,11 @@ int reshape_container(char *container, char *devname,
close(fd);
break;
}
last_devnum = mdstat->devnum;
strcpy(last_devnm, mdstat->devnm);
sysfs_init(content, fd, mdstat->devnum);
sysfs_init(content, fd, mdstat->devnm);
if (mdmon_running(devname2devnum(container)))
if (mdmon_running(container))
flush_mdmon(container);
rv = reshape_array(container, fd, adev, st,
@ -3222,7 +3208,7 @@ int reshape_container(char *container, char *devname,
if (rv)
break;
if (mdmon_running(devname2devnum(container)))
if (mdmon_running(container))
flush_mdmon(container);
}
if (!rv)
@ -4368,7 +4354,6 @@ int Grow_continue_command(char *devname, int fd,
char *subarray = NULL;
struct mdinfo *cc = NULL;
struct mdstat_ent *mdstat = NULL;
char buf[40];
int cfd = -1;
int fd2 = -1;
@ -4427,17 +4412,17 @@ int Grow_continue_command(char *devname, int fd,
}
st->ss->getinfo_super(st, content, NULL);
} else {
int container_dev;
char *container;
if (subarray) {
dprintf("subarray (%s)\n", subarray);
container_dev = st->container_dev;
cfd = open_dev_excl(st->container_dev);
container = st->container_devnm;
cfd = open_dev_excl(st->container_devnm);
} else {
container_dev = st->devnum;
container = st->devnm;
close(fd);
cfd = open_dev_excl(st->devnum);
dprintf("container (%i)\n", container_dev);
cfd = open_dev_excl(st->devnm);
dprintf("container (%s)\n", container);
fd = cfd;
}
if (cfd < 0) {
@ -4446,7 +4431,6 @@ int Grow_continue_command(char *devname, int fd,
ret_val = 1;
goto Grow_continue_command_exit;
}
fmt_devname(buf, container_dev);
/* find in container array under reshape
*/
@ -4482,18 +4466,18 @@ int Grow_continue_command(char *devname, int fd,
pr_err("cannot continue reshape of an array"
" in container with unsupported"
" metadata: %s(%s)\n",
devname, buf);
devname, container);
ret_val = 1;
goto Grow_continue_command_exit;
}
array = strchr(content->text_version+1, '/')+1;
mdstat = mdstat_by_subdev(array, container_dev);
mdstat = mdstat_by_subdev(array, container);
if (!mdstat)
continue;
if (mdstat->active == 0) {
pr_err("Skipping inactive "
"array md%i.\n", mdstat->devnum);
pr_err("Skipping inactive array %s.\n",
mdstat->devnm);
free_mdstat(mdstat);
mdstat = NULL;
continue;
@ -4506,23 +4490,22 @@ int Grow_continue_command(char *devname, int fd,
ret_val = 1;
goto Grow_continue_command_exit;
}
fd2 = open_dev(mdstat->devnum);
fd2 = open_dev(mdstat->devnm);
if (fd2 < 0) {
pr_err("cannot open (md%i)\n",
mdstat->devnum);
pr_err("cannot open (%s)\n", mdstat->devnm);
ret_val = 1;
goto Grow_continue_command_exit;
}
sysfs_init(content, fd2, mdstat->devnum);
sysfs_init(content, fd2, mdstat->devnm);
/* start mdmon in case it is not running
*/
if (!mdmon_running(container_dev))
start_mdmon(container_dev);
ping_monitor(buf);
if (!mdmon_running(container))
start_mdmon(container);
ping_monitor(container);
if (mdmon_running(container_dev))
if (mdmon_running(container))
st->update_tail = &st->updates;
else {
pr_err("No mdmon found. "
@ -4566,16 +4549,14 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
return ret_val;
if (st->ss->external) {
char container[40];
int cfd = open_dev(st->container_dev);
int cfd = open_dev(st->container_devnm);
if (cfd < 0)
return 1;
fmt_devname(container, st->container_dev);
st->ss->load_container(st, cfd, container);
st->ss->load_container(st, cfd, st->container_devnm);
close(cfd);
ret_val = reshape_container(container, NULL, mdfd,
ret_val = reshape_container(st->container_devnm, NULL, mdfd,
st, info, 0, backup_file,
0, 1, freeze_reshape);
} else

View File

@ -291,7 +291,7 @@ int Incremental(char *devname, struct context *c,
mp = map_by_uuid(&map, info.uuid);
if (mp)
mdfd = open_dev(mp->devnum);
mdfd = open_dev(mp->devnm);
else
mdfd = -1;
@ -304,7 +304,7 @@ int Incremental(char *devname, struct context *c,
if (mdfd < 0)
goto out_unlock;
sysfs_init(&info, mdfd, 0);
sysfs_init(&info, mdfd, NULL);
if (set_array_info(mdfd, st, &info) != 0) {
pr_err("failed to set array info for %s: %s\n",
@ -323,8 +323,8 @@ int Incremental(char *devname, struct context *c,
rv = 2;
goto out_unlock;
}
sra = sysfs_read(mdfd, -1, (GET_DEVS | GET_STATE |
GET_OFFSET | GET_SIZE));
sra = sysfs_read(mdfd, NULL, (GET_DEVS | GET_STATE |
GET_OFFSET | GET_SIZE));
if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
/* It really should be 'none' - must be old buggy
@ -339,7 +339,7 @@ int Incremental(char *devname, struct context *c,
}
info.array.working_disks = 1;
/* 6/ Make sure /var/run/mdadm.map contains this array. */
map_update(&map, fd2devnum(mdfd),
map_update(&map, fd2devnm(mdfd),
info.text_version,
info.uuid, chosen_name);
} else {
@ -353,13 +353,13 @@ int Incremental(char *devname, struct context *c,
struct supertype *st2;
struct mdinfo info2, *d;
sra = sysfs_read(mdfd, -1, (GET_DEVS | GET_STATE |
sra = sysfs_read(mdfd, NULL, (GET_DEVS | GET_STATE |
GET_OFFSET | GET_SIZE));
if (mp->path)
strcpy(chosen_name, mp->path);
else
strcpy(chosen_name, devnum2devname(mp->devnum));
strcpy(chosen_name, mp->devnm);
/* It is generally not OK to add non-spare drives to a
* running array as they are probably missing because
@ -460,7 +460,7 @@ int Incremental(char *devname, struct context *c,
/* 7/ Is there enough devices to possibly start the array? */
/* 7a/ if not, finish with success. */
if (info.array.level == LEVEL_CONTAINER) {
int devnum = devnum; /* defined and used iff ->external */
char devnm[32];
/* Try to assemble within the container */
sysfs_uevent(sra, "change");
if (c->verbose >= 0)
@ -469,7 +469,7 @@ int Incremental(char *devname, struct context *c,
info.array.working_disks == 1?"":"s");
wait_for(chosen_name, mdfd);
if (st->ss->external)
devnum = fd2devnum(mdfd);
strcpy(devnm, fd2devnm(mdfd));
if (st->ss->load_container)
rv = st->ss->load_container(st, mdfd, NULL);
close(mdfd);
@ -485,7 +485,7 @@ int Incremental(char *devname, struct context *c,
/* after spare is added, ping monitor for external metadata
* so that it can eg. try to rebuild degraded array */
if (st->ss->external)
ping_monitor_by_id(devnum);
ping_monitor(devnm);
return rv;
}
@ -494,7 +494,7 @@ int Incremental(char *devname, struct context *c,
* things change.
*/
sysfs_free(sra);
sra = sysfs_read(mdfd, -1, (GET_DEVS | GET_STATE |
sra = sysfs_read(mdfd, NULL, (GET_DEVS | GET_STATE |
GET_OFFSET | GET_SIZE));
active_disks = count_active(st, sra, mdfd, &avail, &info);
if (enough(info.array.level, info.array.raid_disks,
@ -771,10 +771,9 @@ static int container_members_max_degradation(struct map_ent *map, struct map_ent
int max_degraded = 0;
for(; map; map = map->next) {
if (!is_subarray(map->metadata) ||
devname2devnum(map->metadata+1) != me->devnum)
if (!metadata_container_matches(map->metadata, me->devnm))
continue;
afd = open_dev(map->devnum);
afd = open_dev(map->devnm);
if (afd < 0)
continue;
/* most accurate information regarding array degradation */
@ -848,12 +847,12 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
}
free(st2);
}
sra = sysfs_read(-1, mp->devnum,
sra = sysfs_read(-1, mp->devnm,
GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
GET_DEGRADED|GET_COMPONENT|GET_VERSION);
if (!sra) {
/* Probably a container - no degraded info */
sra = sysfs_read(-1, mp->devnum,
sra = sysfs_read(-1, mp->devnm,
GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
GET_COMPONENT|GET_VERSION);
if (sra)
@ -894,7 +893,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
/* true for containers, here we must read superblock
* to obtain minimum spare size */
struct supertype *st3 = dup_super(st2);
int mdfd = open_dev(mp->devnum);
int mdfd = open_dev(mp->devnm);
if (mdfd < 0) {
free(st3);
goto next;
@ -977,7 +976,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
}
if (chosen) {
/* add current device to chosen array as a spare */
int mdfd = open_dev(devname2devnum(chosen->sys_name));
int mdfd = open_dev(chosen->sys_name);
if (mdfd >= 0) {
struct mddev_dev devlist;
char devname[20];
@ -1289,7 +1288,7 @@ int IncrementalScan(int verbose)
mdu_array_info_t array;
mdu_bitmap_file_t bmf;
struct mdinfo *sra;
int mdfd = open_dev(me->devnum);
int mdfd = open_dev(me->devnm);
if (mdfd < 0)
continue;
@ -1329,16 +1328,16 @@ int IncrementalScan(int verbose)
/* FIXME check for reshape_active and consider not
* starting array.
*/
sra = sysfs_read(mdfd, 0, 0);
sra = sysfs_read(mdfd, NULL, 0);
if (sra) {
if (sysfs_set_str(sra, NULL,
"array_state", "read-auto") == 0) {
if (verbose >= 0)
pr_err("started array %s\n",
me->path ?: devnum2devname(me->devnum));
me->path ?: me->devnm);
} else {
pr_err("failed to start array %s: %s\n",
me->path ?: devnum2devname(me->devnum),
me->path ?: me->devnm,
strerror(errno));
rv = 1;
}
@ -1355,7 +1354,7 @@ static char *container2devname(char *devname)
if (devname[0] == '/') {
int fd = open(devname, O_RDONLY);
if (fd >= 0) {
mdname = devnum2devname(fd2devnum(fd));
mdname = xstrdup(fd2devnm(fd));
close(fd);
}
} else {
@ -1366,7 +1365,7 @@ static char *container2devname(char *devname)
return mdname;
mp = map_by_uuid(&map, uuid);
if (mp)
mdname = devnum2devname(mp->devnum);
mdname = xstrdup(mp->devnm);
map_free(map);
}
@ -1440,11 +1439,11 @@ static int Incremental_container(struct supertype *st, char *devname,
mp = map_by_uuid(&map, ra->uuid);
if (mp) {
mdfd = open_dev(mp->devnum);
mdfd = open_dev(mp->devnm);
if (mp->path)
strcpy(chosen_name, mp->path);
else
strcpy(chosen_name, devnum2devname(mp->devnum));
strcpy(chosen_name, mp->devnm);
} else {
/* Check in mdadm.conf for container == devname and
@ -1599,7 +1598,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
"of any array\n", devname);
return 1;
}
mdfd = open_dev(ent->devnum);
mdfd = open_dev(ent->devnm);
if (mdfd < 0) {
pr_err("Cannot open array %s!!\n", ent->dev);
free_mdstat(ent);
@ -1608,7 +1607,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
if (id_path) {
struct map_ent *map = NULL, *me;
me = map_by_devnum(&map, ent->devnum);
me = map_by_devnm(&map, ent->devnm);
if (me)
policy_save_path(id_path, me);
map_free(map);
@ -1624,7 +1623,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
struct mdstat_ent *memb;
for (memb = mdstat ; memb ; memb = memb->next)
if (is_container_member(memb, ent->dev)) {
int subfd = open_dev(memb->devnum);
int subfd = open_dev(memb->devnm);
if (subfd >= 0) {
Manage_subdevs(memb->dev, subfd,
&devlist, verbose, 0,

4
Kill.c
View File

@ -107,14 +107,14 @@ int Kill_subarray(char *dev, char *subarray, int verbose)
goto free_super;
}
if (is_subarray_active(subarray, st->devname)) {
if (is_subarray_active(subarray, st->devnm)) {
if (verbose >= 0)
pr_err("Subarray-%s still active, aborting\n",
subarray);
goto free_super;
}
if (mdmon_running(st->devnum))
if (mdmon_running(st->devnm))
st->update_tail = &st->updates;
/* ok we've found our victim, drop the axe */

View File

@ -54,7 +54,7 @@ int Manage_ro(char *devname, int fd, int readonly)
/* If this is an externally-managed array, we need to modify the
* metadata_version so that mdmon doesn't undo our change.
*/
mdi = sysfs_read(fd, -1, GET_LEVEL|GET_VERSION);
mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION);
if (mdi &&
mdi->array.major_version == -1 &&
is_subarray(mdi->text_version)) {
@ -127,12 +127,12 @@ out:
#ifndef MDASSEMBLE
static void remove_devices(int devnum, char *path)
static void remove_devices(char *devnm, char *path)
{
/*
* Remove names at 'path' - possibly with
* partition suffixes - which link to the 'standard'
* name for devnum. These were probably created
* name for devnm. These were probably created
* by mdadm when the array was assembled.
*/
char base[40];
@ -146,10 +146,7 @@ static void remove_devices(int devnum, char *path)
if (!path)
return;
if (devnum >= 0)
sprintf(base, "/dev/md%d", devnum);
else
sprintf(base, "/dev/md_d%d", -1-devnum);
sprintf(base, "/dev/%s", devnm);
be = base + strlen(base);
path2 = xmalloc(strlen(path)+20);
@ -214,19 +211,19 @@ int Manage_runstop(char *devname, int fd, int runstop,
struct map_ent *map = NULL;
struct stat stb;
struct mdinfo *mdi;
int devnum;
char devnm[32];
int err;
int count;
/* If this is an mdmon managed array, just write 'inactive'
* to the array state and let mdmon clear up.
*/
devnum = fd2devnum(fd);
strcpy(devnm, fd2devnm(fd));
/* Get EXCL access first. If this fails, then attempting
* to stop is probably a bad idea.
*/
close(fd);
fd = open(devname, O_RDONLY|O_EXCL);
if (fd < 0 || fd2devnum(fd) != devnum) {
if (fd < 0 || strcmp(fd2devnm(fd), devnm) != 0) {
if (fd >= 0)
close(fd);
if (verbose >= 0)
@ -237,7 +234,7 @@ int Manage_runstop(char *devname, int fd, int runstop,
devname);
return 1;
}
mdi = sysfs_read(fd, -1, GET_LEVEL|GET_VERSION);
mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION);
if (mdi &&
mdi->array.level > 0 &&
is_subarray(mdi->text_version)) {
@ -269,7 +266,7 @@ int Manage_runstop(char *devname, int fd, int runstop,
/* Give monitor a chance to act */
ping_monitor(mdi->text_version);
fd = open_dev_excl(devnum);
fd = open_dev_excl(devnm);
if (fd < 0) {
if (verbose >= 0)
pr_err("failed to completely stop %s"
@ -296,8 +293,8 @@ int Manage_runstop(char *devname, int fd, int runstop,
for (m = mds; m; m = m->next)
if (m->metadata_version &&
strncmp(m->metadata_version, "external:", 9)==0 &&
is_subarray(m->metadata_version+9) &&
devname2devnum(m->metadata_version+10) == devnum) {
metadata_container_matches(m->metadata_version+9,
devnm)) {
if (verbose >= 0)
pr_err("Cannot stop container %s: "
"member %s still active\n",
@ -340,17 +337,17 @@ int Manage_runstop(char *devname, int fd, int runstop,
if (mdi)
sysfs_uevent(mdi, "change");
if (devnum != NoMdDev &&
if (devnm[0] &&
(stat("/dev/.udev", &stb) != 0 ||
check_env("MDADM_NO_UDEV"))) {
struct map_ent *mp = map_by_devnum(&map, devnum);
remove_devices(devnum, mp ? mp->path : NULL);
struct map_ent *mp = map_by_devnm(&map, devnm);
remove_devices(devnm, mp ? mp->path : NULL);
}
if (verbose >= 0)
pr_err("stopped %s\n", devname);
map_lock(&map);
map_remove(&map, devnum);
map_remove(&map, devnm);
map_unlock(&map);
out:
if (mdi)
@ -774,10 +771,12 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
struct mdinfo new_mdi;
struct mdinfo *sra;
int container_fd;
int devnum = fd2devnum(fd);
char devnm[32];
int dfd;
container_fd = open_dev_excl(devnum);
strcpy(devnm, fd2devnm(fd));
container_fd = open_dev_excl(devnm);
if (container_fd < 0) {
pr_err("add failed for %s:"
" could not get exclusive access to container\n",
@ -788,7 +787,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
Kill(dv->devname, NULL, 0, -1, 0);
dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
if (mdmon_running(tst->container_dev))
if (mdmon_running(tst->container_devnm))
tst->update_tail = &tst->updates;
if (tst->ss->add_to_super(tst, &disc, dfd,
dv->devname, INVALID_SECTORS)) {
@ -801,7 +800,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
else
tst->ss->sync_metadata(tst);
sra = sysfs_read(container_fd, -1, 0);
sra = sysfs_read(container_fd, NULL, 0);
if (!sra) {
pr_err("add failed for %s: sysfs_read failed\n",
dv->devname);
@ -825,7 +824,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
sysfs_free(sra);
return -1;
}
ping_monitor_by_id(devnum);
ping_monitor(devnm);
sysfs_free(sra);
close(container_fd);
} else {
@ -858,8 +857,9 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
* get an O_EXCL open on the container
*/
int ret;
int dnum = fd2devnum(fd);
lfd = open_dev_excl(dnum);
char devnm[32];
strcpy(devnm, fd2devnm(fd));
lfd = open_dev_excl(devnm);
if (lfd < 0) {
pr_err("Cannot get exclusive access "
" to container - odd\n");
@ -875,7 +875,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
if (rdev == 0)
ret = -1;
else
ret = sysfs_unique_holder(dnum, rdev);
ret = sysfs_unique_holder(devnm, rdev);
if (ret == 0) {
pr_err("%s is not a member, cannot remove.\n",
dv->devname);
@ -904,7 +904,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
if (err && errno == ENODEV) {
/* Old kernels rejected this if no personality
* is registered */
struct mdinfo *sra = sysfs_read(fd, 0, GET_DEVS);
struct mdinfo *sra = sysfs_read(fd, NULL, GET_DEVS);
struct mdinfo *dv = NULL;
if (sra)
dv = sra->devs;
@ -936,15 +936,14 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
* 'add' event before reconciling this 'remove'
* event.
*/
char *name = devnum2devname(fd2devnum(fd));
char *devnm = fd2devnm(fd);
if (!name) {
if (!devnm) {
pr_err("unable to get container name\n");
return -1;
}
ping_manager(name);
free(name);
ping_manager(devnm);
}
if (lfd >= 0)
close(lfd);
@ -965,7 +964,7 @@ int Manage_replace(struct supertype *tst, int fd, struct mddev_dev *dv,
/* Need to find the device in sysfs and add 'want_replacement' to the
* status.
*/
mdi = sysfs_read(fd, -1, GET_DEVS);
mdi = sysfs_read(fd, NULL, GET_DEVS);
if (!mdi || !mdi->devs) {
pr_err("Cannot find status of %s to enable replacement - strange\n",
devname);
@ -1016,7 +1015,7 @@ int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv,
{
struct mdinfo *mdi, *di;
/* try to set 'slot' for 'rdev' in 'fd' to 'dv->used' */
mdi = sysfs_read(fd, -1, GET_DEVS|GET_STATE);
mdi = sysfs_read(fd, NULL, GET_DEVS|GET_STATE);
if (!mdi || !mdi->devs) {
pr_err("Cannot find status of %s to enable replacement - strange\n",
devname);
@ -1107,7 +1106,7 @@ int Manage_subdevs(char *devname, int fd,
devname);
goto abort;
}
sysfs_init(&info, fd, 0);
sysfs_init(&info, fd, NULL);
/* array.size is only 32 bits and may be truncated.
* So read from sysfs if possible, and record number of sectors
@ -1187,7 +1186,7 @@ int Manage_subdevs(char *devname, int fd,
}
sprintf(dname, "dev-%s", dv->devname);
sysfd = sysfs_open(fd2devnum(fd), dname, "block/dev");
sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");
if (sysfd >= 0) {
char dn[20];
int mj,mn;
@ -1200,7 +1199,7 @@ int Manage_subdevs(char *devname, int fd,
sysfd = -1;
}
if (!found) {
sysfd = sysfs_open(fd2devnum(fd), dname, "state");
sysfd = sysfs_open(fd2devnm(fd), dname, "state");
if (sysfd < 0) {
pr_err("%s does not appear "
"to be a component of %s\n",
@ -1412,7 +1411,7 @@ int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident
goto free_super;
}
if (mdmon_running(st->devnum))
if (mdmon_running(st->devnm))
st->update_tail = &st->updates;
rv = st->ss->update_subarray(st, subarray, update, ident);

View File

@ -32,7 +32,7 @@
struct state {
char *devname;
int devnum; /* to sync with mdstat info */
char devnm[32]; /* to sync with mdstat info */
long utime;
int err;
char *spare_group;
@ -42,9 +42,9 @@ struct state {
int devstate[MAX_DISKS];
dev_t devid[MAX_DISKS];
int percent;
int parent_dev; /* For subarray, devnum of parent.
* For others, NoMdDev
*/
char parent_devnm[32]; /* For subarray, devnm of parent.
* For others, ""
*/
struct supertype *metadata;
struct state *subarray;/* for a container it is a link to first subarray
* for a subarray it is a link to next subarray
@ -177,7 +177,7 @@ int Monitor(struct mddev_dev *devlist,
mdlist->devname);
}
st->next = statelist;
st->devnum = INT_MAX;
st->devnm[0] = 0;
st->percent = RESYNC_UNKNOWN;
st->from_config = 1;
st->expected_spares = mdlist->spare_disks;
@ -192,7 +192,7 @@ int Monitor(struct mddev_dev *devlist,
struct state *st = xcalloc(1, sizeof *st);
st->devname = xstrdup(dv->devname);
st->next = statelist;
st->devnum = INT_MAX;
st->devnm[0] = 0;
st->percent = RESYNC_UNKNOWN;
st->expected_spares = -1;
if (mdlist) {
@ -483,20 +483,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
close(fd);
return 0;
}
if (st->devnum == INT_MAX) {
struct stat stb;
if (fstat(fd, &stb) == 0 &&
(S_IFMT&stb.st_mode)==S_IFBLK) {
if (major(stb.st_rdev) == MD_MAJOR)
st->devnum = minor(stb.st_rdev);
else
st->devnum = -1- (minor(stb.st_rdev)>>6);
}
}
if (st->devnm[0] == 0)
strcpy(st->devnm, fd2devnm(fd));
for (mse2 = mdstat ; mse2 ; mse2=mse2->next)
if (mse2->devnum == st->devnum) {
mse2->devnum = INT_MAX; /* flag it as "used" */
if (strcmp(mse2->devnm, st->devnm) == 0) {
mse2->devnm[0] = 0; /* flag it as "used" */
mse = mse2;
}
@ -566,7 +558,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
* we should report that.
*/
struct mdinfo *sra =
sysfs_read(-1, st->devnum, GET_MISMATCH);
sysfs_read(-1, st->devnm, GET_MISMATCH);
if (sra && sra->mismatch_cnt > 0) {
char cnt[80];
snprintf(cnt, sizeof(cnt),
@ -598,13 +590,17 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
if (mse->metadata_version &&
strncmp(mse->metadata_version, "external:", 9) == 0 &&
is_subarray(mse->metadata_version+9))
st->parent_dev =
devname2devnum(mse->metadata_version+10);
else
st->parent_dev = NoMdDev;
is_subarray(mse->metadata_version+9)) {
char *sl;
strcpy(st->parent_devnm,
mse->metadata_version+10);
sl = strchr(st->parent_devnm, '/');
if (sl)
*sl = 0;
} else
st->parent_devnm[0] = 0;
if (st->metadata == NULL &&
st->parent_dev == NoMdDev)
st->parent_devnm[0] == 0)
st->metadata = super_by_fd(fd, NULL);
close(fd);
@ -664,7 +660,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
int new_found = 0;
for (mse=mdstat; mse; mse=mse->next)
if (mse->devnum != INT_MAX &&
if (mse->devnm[0] &&
(!mse->level || /* retrieve containers */
(strcmp(mse->level, "raid0") != 0 &&
strcmp(mse->level, "linear") != 0))
@ -672,7 +668,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
struct state *st = xcalloc(1, sizeof *st);
mdu_array_info_t array;
int fd;
st->devname = xstrdup(get_md_name(mse->devnum));
st->devname = xstrdup(get_md_name(mse->devnm));
if ((fd = open(st->devname, O_RDONLY)) < 0 ||
ioctl(fd, GET_ARRAY_INFO, &array)< 0) {
/* no such array */
@ -689,16 +685,19 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist,
close(fd);
st->next = *statelist;
st->err = 1;
st->devnum = mse->devnum;
strcpy(st->devnm, mse->devnm);
st->percent = RESYNC_UNKNOWN;
st->expected_spares = -1;
if (mse->metadata_version &&
strncmp(mse->metadata_version, "external:", 9) == 0 &&
is_subarray(mse->metadata_version+9))
st->parent_dev =
devname2devnum(mse->metadata_version+10);
else
st->parent_dev = NoMdDev;
is_subarray(mse->metadata_version+9)) {
char *sl;
strcpy(st->parent_devnm,
mse->metadata_version+10);
sl = strchr(st->parent_devnm, '/');
*sl = 0;
} else
st->parent_devnm[0] = 0;
*statelist = st;
if (test)
alert("TestMessage", st->devname, NULL, info);
@ -779,7 +778,7 @@ static dev_t choose_spare(struct state *from, struct state *to,
dev_size < min_size)
continue;
pol = devnum_policy(from->devid[d]);
pol = devid_policy(from->devid[d]);
if (from->spare_group)
pol_add(&pol, pol_domain,
from->spare_group, NULL);
@ -871,7 +870,7 @@ static void try_spare_migration(struct state *statelist, struct alert_info *info
struct state *to = st;
unsigned long long min_size;
if (to->parent_dev != NoMdDev && !to->parent)
if (to->parent_devnm[0] && !to->parent)
/* subarray monitored without parent container
* we can't move spares here */
continue;
@ -939,11 +938,11 @@ static void link_containers_with_subarrays(struct state *list)
st->subarray = NULL;
}
for (st = list; st; st = st->next)
if (st->parent_dev != NoMdDev)
if (st->parent_devnm[0])
for (cont = list; cont; cont = cont->next)
if (!cont->err &&
cont->parent_dev == NoMdDev &&
cont->devnum == st->parent_dev) {
cont->parent_devnm[0] == 0 &&
strcmp(cont->devnm, st->parent_devnm) == 0) {
st->parent = cont;
st->subarray = cont->subarray;
cont->subarray = st;
@ -955,7 +954,7 @@ static void link_containers_with_subarrays(struct state *list)
int Wait(char *dev)
{
struct stat stb;
int devnum;
char devnm[32];
int rv = 1;
if (stat(dev, &stb) != 0) {
@ -963,14 +962,14 @@ int Wait(char *dev)
strerror(errno));
return 2;
}
devnum = stat2devnum(&stb);
strcpy(devnm, stat2devnm(&stb));
while(1) {
struct mdstat_ent *ms = mdstat_read(1, 0);
struct mdstat_ent *e;
for (e=ms ; e; e=e->next)
if (e->devnum == devnum)
if (strcmp(e->devnm, devnm) == 0)
break;
if (!e || e->percent == RESYNC_NONE) {
@ -979,7 +978,7 @@ int Wait(char *dev)
if (is_subarray(&e->metadata_version[9]))
ping_monitor(&e->metadata_version[9]);
else
ping_monitor_by_id(devnum);
ping_monitor(devnm);
}
free_mdstat(ms);
return rv;
@ -1000,7 +999,7 @@ int WaitClean(char *dev, int sock, int verbose)
int fd;
struct mdinfo *mdi;
int rv = 1;
int devnum;
char devnm[32];
fd = open(dev, O_RDONLY);
if (fd < 0) {
@ -1009,8 +1008,8 @@ int WaitClean(char *dev, int sock, int verbose)
return 1;
}
devnum = fd2devnum(fd);
mdi = sysfs_read(fd, devnum, GET_VERSION|GET_LEVEL|GET_SAFEMODE);
strcpy(devnm, fd2devnm(fd));
mdi = sysfs_read(fd, devnm, GET_VERSION|GET_LEVEL|GET_SAFEMODE);
if (!mdi) {
if (verbose)
pr_err("Failed to read sysfs attributes for "
@ -1038,7 +1037,7 @@ int WaitClean(char *dev, int sock, int verbose)
rv = 0;
if (rv) {
int state_fd = sysfs_open(fd2devnum(fd), NULL, "array_state");
int state_fd = sysfs_open(fd2devnm(fd), NULL, "array_state");
char buf[20];
fd_set fds;
struct timeval tm;

View File

@ -995,7 +995,7 @@ int devname_matches(char *name, char *match)
int conf_name_is_free(char *name)
{
/* Check if this name is already take by an ARRAY entry in
/* Check if this name is already taken by an ARRAY entry in
* the config file.
* It can be taken either by a match on devname, name, or
* even super-minor.

95
lib.c
View File

@ -57,72 +57,59 @@ static int mdp_major = -1;
return mdp_major;
}
void fmt_devname(char *name, int num)
{
if (num >= 0)
sprintf(name, "md%d", num);
else
sprintf(name, "md_d%d", -1-num);
}
char *devnum2devname(int num)
{
char name[100];
fmt_devname(name,num);
return xstrdup(name);
}
int devname2devnum(char *name)
{
char *ep;
int num;
if (strncmp(name, "md_d", 4)==0)
num = -1-strtoul(name+4, &ep, 10);
else
num = strtoul(name+2, &ep, 10);
return num;
}
int stat2devnum(struct stat *st)
char *devid2devnm(int devid)
{
char path[30];
char link[200];
char *cp;
static char devnm[32];
char *cp, *ep;
int n;
if ((S_IFMT & st->st_mode) == S_IFBLK) {
if (major(st->st_rdev) == MD_MAJOR)
return minor(st->st_rdev);
else if (major(st->st_rdev) == (unsigned)get_mdp_major())
return -1- (minor(st->st_rdev)>>MdpMinorShift);
/* must be an extended-minor partition. Look at the
* /sys/dev/block/%d:%d link which must look like
* ../../block/mdXXX/mdXXXpYY
*/
sprintf(path, "/sys/dev/block/%d:%d", major(st->st_rdev),
minor(st->st_rdev));
n = readlink(path, link, sizeof(link)-1);
if (n <= 0)
return NoMdDev;
/* Might be an extended-minor partition or a
* named md device. Look at the
* /sys/dev/block/%d:%d link which must look like
* ../../block/mdXXX/mdXXXpYY
* or
* ...../block/md_FOO
*/
sprintf(path, "/sys/dev/block/%d:%d", major(devid),
minor(devid));
n = readlink(path, link, sizeof(link)-1);
if (n > 0) {
link[n] = 0;
cp = strrchr(link, '/');
if (cp) *cp = 0;
cp = strrchr(link, '/');
if (cp && strncmp(cp, "/md", 3) == 0)
return devname2devnum(cp+1);
cp = strstr(link, "/block/");
if (cp) {
cp += 7;
ep = strchr(cp, '/');
if (ep)
*ep = 0;
strcpy(devnm, cp);
return devnm;
}
}
return NoMdDev;
if (major(devid) == MD_MAJOR)
sprintf(devnm,"md%d", minor(devid));
else if (major(devid) == (unsigned)get_mdp_major())
sprintf(devnm,"md_d%d",
(minor(devid)>>MdpMinorShift));
else
return NULL;
return devnm;
}
int fd2devnum(int fd)
char *stat2devnm(struct stat *st)
{
if ((S_IFMT & st->st_mode) != S_IFBLK)
return NULL;
return devid2devnm(st->st_rdev);
}
char *fd2devnm(int fd)
{
struct stat stb;
if (fstat(fd, &stb) == 0)
return stat2devnum(&stb);
return NoMdDev;
return stat2devnm(&stb);
return NULL;
}

View File

@ -134,7 +134,7 @@ static void free_aa(struct active_array *aa)
/* Note that this doesn't close fds if they are being used
* by a clone. ->container will be set for a clone
*/
dprintf("%s: devnum: %d\n", __func__, aa->devnum);
dprintf("%s: sys_name: %s\n", __func__, aa->info.sys_name);
if (!aa->container)
close_aa(aa);
while (aa->info.devs) {
@ -359,7 +359,7 @@ static void manage_container(struct mdstat_ent *mdstat,
* To see what is removed and what is added.
* These need to be remove from, or added to, the array
*/
mdi = sysfs_read(-1, mdstat->devnum, GET_DEVS);
mdi = sysfs_read(-1, mdstat->devnm, GET_DEVS);
if (!mdi) {
/* invalidate the current count so we can try again */
container->devcnt = -1;
@ -409,10 +409,10 @@ static int disk_init_and_add(struct mdinfo *disk, struct mdinfo *clone,
return -1;
*disk = *clone;
disk->recovery_fd = sysfs_open(aa->devnum, disk->sys_name, "recovery_start");
disk->recovery_fd = sysfs_open(aa->info.sys_name, disk->sys_name, "recovery_start");
if (disk->recovery_fd < 0)
return -1;
disk->state_fd = sysfs_open(aa->devnum, disk->sys_name, "state");
disk->state_fd = sysfs_open(aa->info.sys_name, disk->sys_name, "state");
if (disk->state_fd < 0) {
close(disk->recovery_fd);
return -1;
@ -552,7 +552,7 @@ static void manage_member(struct mdstat_ent *mdstat,
unsigned long long array_size;
struct active_array *newa = NULL;
a->check_reshape = 0;
info = sysfs_read(-1, mdstat->devnum,
info = sysfs_read(-1, mdstat->devnm,
GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE);
if (!info)
goto out2;
@ -631,7 +631,7 @@ static void manage_new(struct mdstat_ent *mdstat,
strcmp(mdstat->level, "linear") == 0)
return;
mdi = sysfs_read(-1, mdstat->devnum,
mdi = sysfs_read(-1, mdstat->devnm,
GET_LEVEL|GET_CHUNK|GET_DISKS|GET_COMPONENT|
GET_DEGRADED|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE);
@ -640,15 +640,14 @@ static void manage_new(struct mdstat_ent *mdstat,
return;
new = xcalloc(1, sizeof(*new));
new->devnum = mdstat->devnum;
strcpy(new->info.sys_name, devnum2devname(new->devnum));
strcpy(new->info.sys_name, mdstat->devnm);
new->prev_state = new->curr_state = new->next_state = inactive;
new->prev_action= new->curr_action= new->next_action= idle;
new->container = container;
inst = to_subarray(mdstat, container->devname);
inst = to_subarray(mdstat, container->devnm);
new->info.array = mdi->array;
new->info.component_size = mdi->component_size;
@ -673,11 +672,11 @@ static void manage_new(struct mdstat_ent *mdstat,
}
}
new->action_fd = sysfs_open(new->devnum, NULL, "sync_action");
new->info.state_fd = sysfs_open(new->devnum, NULL, "array_state");
new->resync_start_fd = sysfs_open(new->devnum, NULL, "resync_start");
new->metadata_fd = sysfs_open(new->devnum, NULL, "metadata_version");
new->sync_completed_fd = sysfs_open(new->devnum, NULL, "sync_completed");
new->action_fd = sysfs_open(new->info.sys_name, NULL, "sync_action");
new->info.state_fd = sysfs_open(new->info.sys_name, NULL, "array_state");
new->resync_start_fd = sysfs_open(new->info.sys_name, NULL, "resync_start");
new->metadata_fd = sysfs_open(new->info.sys_name, NULL, "metadata_version");
new->sync_completed_fd = sysfs_open(new->info.sys_name, NULL, "sync_completed");
dprintf("%s: inst: %d action: %d state: %d\n", __func__, atoi(inst),
new->action_fd, new->info.state_fd);
@ -732,16 +731,16 @@ void manage(struct mdstat_ent *mdstat, struct supertype *container)
for ( ; mdstat ; mdstat = mdstat->next) {
struct active_array *a;
if (mdstat->devnum == container->devnum) {
if (strcmp(mdstat->devnm, container->devnm) == 0) {
manage_container(mdstat, container);
continue;
}
if (!is_container_member(mdstat, container->devname))
if (!is_container_member(mdstat, container->devnm))
/* Not for this array */
continue;
/* Looks like a member of this container */
for (a = container->arrays; a; a = a->next) {
if (mdstat->devnum == a->devnum) {
if (strcmp(mdstat->devnm, a->info.sys_name) == 0) {
if (a->container && a->to_remove == 0)
manage_member(mdstat, a);
break;

View File

@ -88,10 +88,7 @@ int map_write(struct map_ent *mel)
for (; mel; mel = mel->next) {
if (mel->bad)
continue;
if (mel->devnum < 0)
fprintf(f, "mdp%d ", -1-mel->devnum);
else
fprintf(f, "md%d ", mel->devnum);
fprintf(f, "%s ", mel->devnm);
fprintf(f, "%s ", mel->metadata);
fprintf(f, "%08x:%08x:%08x:%08x ", mel->uuid[0],
mel->uuid[1], mel->uuid[2], mel->uuid[3]);
@ -164,11 +161,11 @@ void map_fork(void)
}
void map_add(struct map_ent **melp,
int devnum, char *metadata, int uuid[4], char *path)
char * devnm, char *metadata, int uuid[4], char *path)
{
struct map_ent *me = xmalloc(sizeof(*me));
me->devnum = devnum;
strcpy(me->devnm, devnm);
strcpy(me->metadata, metadata);
memcpy(me->uuid, uuid, 16);
me->path = path ? xstrdup(path) : NULL;
@ -182,9 +179,9 @@ void map_read(struct map_ent **melp)
FILE *f;
char buf[8192];
char path[200];
int devnum, uuid[4];
int uuid[4];
char devnm[32];
char metadata[30];
char nam[4];
*melp = NULL;
@ -198,14 +195,10 @@ void map_read(struct map_ent **melp)
while (fgets(buf, sizeof(buf), f)) {
path[0] = 0;
if (sscanf(buf, " %3[mdp]%d %s %x:%x:%x:%x %200s",
nam, &devnum, metadata, uuid, uuid+1,
if (sscanf(buf, " %s %s %x:%x:%x:%x %200s",
devnm, metadata, uuid, uuid+1,
uuid+2, uuid+3, path) >= 7) {
if (strncmp(nam, "md", 2) != 0)
continue;
if (nam[2] == 'p')
devnum = -1 - devnum;
map_add(melp, devnum, metadata, uuid, path);
map_add(melp, devnm, metadata, uuid, path);
}
}
fclose(f);
@ -221,7 +214,7 @@ void map_free(struct map_ent *map)
}
}
int map_update(struct map_ent **mpp, int devnum, char *metadata,
int map_update(struct map_ent **mpp, char *devnm, char *metadata,
int *uuid, char *path)
{
struct map_ent *map, *mp;
@ -233,7 +226,7 @@ int map_update(struct map_ent **mpp, int devnum, char *metadata,
map_read(&map);
for (mp = map ; mp ; mp=mp->next)
if (mp->devnum == devnum) {
if (strcmp(mp->devnm, devnm) == 0) {
strcpy(mp->metadata, metadata);
memcpy(mp->uuid, uuid, 16);
free(mp->path);
@ -242,7 +235,7 @@ int map_update(struct map_ent **mpp, int devnum, char *metadata,
break;
}
if (!mp)
map_add(&map, devnum, metadata, uuid, path);
map_add(&map, devnm, metadata, uuid, path);
if (mpp)
*mpp = NULL;
rv = map_write(map);
@ -250,7 +243,7 @@ int map_update(struct map_ent **mpp, int devnum, char *metadata,
return rv;
}
void map_delete(struct map_ent **mapp, int devnum)
void map_delete(struct map_ent **mapp, char *devnm)
{
struct map_ent *mp;
@ -258,7 +251,7 @@ void map_delete(struct map_ent **mapp, int devnum)
map_read(mapp);
for (mp = *mapp; mp; mp = *mapp) {
if (mp->devnum == devnum) {
if (strcmp(mp->devnm, devnm) == 0) {
*mapp = mp->next;
free(mp->path);
free(mp);
@ -267,12 +260,12 @@ void map_delete(struct map_ent **mapp, int devnum)
}
}
void map_remove(struct map_ent **mapp, int devnum)
void map_remove(struct map_ent **mapp, char *devnm)
{
if (devnum == NoMdDev)
if (devnm[0] == 0)
return;
map_delete(mapp, devnum);
map_delete(mapp, devnm);
map_write(*mapp);
map_free(*mapp);
}
@ -286,7 +279,7 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4])
for (mp = *map ; mp ; mp = mp->next) {
if (memcmp(uuid, mp->uuid, 16) != 0)
continue;
if (!mddev_busy(mp->devnum)) {
if (!mddev_busy(mp->devnm)) {
mp->bad = 1;
continue;
}
@ -295,16 +288,16 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4])
return NULL;
}
struct map_ent *map_by_devnum(struct map_ent **map, int devnum)
struct map_ent *map_by_devnm(struct map_ent **map, char *devnm)
{
struct map_ent *mp;
if (!*map)
map_read(map);
for (mp = *map ; mp ; mp = mp->next) {
if (mp->devnum != devnum)
if (strcmp(mp->devnm, devnm) != 0)
continue;
if (!mddev_busy(mp->devnum)) {
if (!mddev_busy(mp->devnm)) {
mp->bad = 1;
continue;
}
@ -326,7 +319,7 @@ struct map_ent *map_by_name(struct map_ent **map, char *name)
continue;
if (strcmp(mp->path+8, name) != 0)
continue;
if (!mddev_busy(mp->devnum)) {
if (!mddev_busy(mp->devnm)) {
mp->bad = 1;
continue;
}
@ -360,7 +353,6 @@ void RebuildMap(void)
struct mdstat_ent *mdstat = mdstat_read(0, 0);
struct mdstat_ent *md;
struct map_ent *map = NULL;
int mdp = get_mdp_major();
int require_homehost;
char sys_hostname[256];
char *homehost = conf_get_homehost(&require_homehost);
@ -373,7 +365,7 @@ void RebuildMap(void)
}
for (md = mdstat ; md ; md = md->next) {
struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_DEVS);
struct mdinfo *sra = sysfs_read(-1, md->devnm, GET_DEVS);
struct mdinfo *sd;
if (!sra)
@ -384,6 +376,7 @@ void RebuildMap(void)
char dn[30];
int dfd;
int ok;
int devid;
struct supertype *st;
char *subarray = NULL;
char *path;
@ -412,10 +405,8 @@ void RebuildMap(void)
if (!info)
continue;
if (md->devnum >= 0)
path = map_dev(MD_MAJOR, md->devnum, 0);
else
path = map_dev(mdp, (-1-md->devnum)<< 6, 0);
devid = devnm2devid(md->devnm);
path = map_dev(major(devid), minor(devid), 0);
if (path == NULL ||
strncmp(path, "/dev/md/", 8) != 0) {
/* We would really like a name that provides
@ -489,7 +480,7 @@ void RebuildMap(void)
path = namebuf;
}
}
map_add(&map, md->devnum,
map_add(&map, md->devnm,
info->text_version,
info->uuid, path);
st->ss->free_super(st);
@ -501,7 +492,7 @@ void RebuildMap(void)
/* Only trigger a change if we wrote a new map file */
if (map_write(map))
for (md = mdstat ; md ; md = md->next) {
struct mdinfo *sra = sysfs_read(-1, md->devnum,
struct mdinfo *sra = sysfs_read(-1, md->devnm,
GET_VERSION);
if (sra)
sysfs_uevent(sra, "change");

View File

@ -1457,7 +1457,7 @@ int main(int argc, char *argv[])
rv = 1;
break;
}
sysfs_init(&sra, mdfd, 0);
sysfs_init(&sra, mdfd, NULL);
if (array_size == MAX_SIZE)
err = sysfs_set_str(&sra, NULL, "array_size", "default");
else
@ -1658,12 +1658,12 @@ static int misc_scan(char devmode, struct context *c)
"external:/", 10) == 0;
if (members != member)
continue;
me = map_by_devnum(&map, e->devnum);
me = map_by_devnm(&map, e->devnm);
if (me && me->path
&& strcmp(me->path, "/unknown") != 0)
name = me->path;
else
name = get_md_name(e->devnum);
name = get_md_name(e->devnm);
if (!name) {
pr_err("cannot find device file for %s\n",
@ -1697,7 +1697,7 @@ static int stop_scan(int verbose)
if (!progress) last = 1;
progress = 0; err = 0;
for (e=ms ; e ; e=e->next) {
char *name = get_md_name(e->devnum);
char *name = get_md_name(e->devnm);
int mdfd;
if (!name) {

83
mdadm.h
View File

@ -448,7 +448,7 @@ typedef struct mapping {
struct mdstat_ent {
char *dev;
int devnum;
char devnm[32];
int active;
char *level;
char *pattern; /* U or up, _ for down */
@ -468,30 +468,30 @@ extern struct mdstat_ent *mdstat_read(int hold, int start);
extern void free_mdstat(struct mdstat_ent *ms);
extern void mdstat_wait(int seconds);
extern void mdstat_wait_fd(int fd, const sigset_t *sigmask);
extern int mddev_busy(int devnum);
extern int mddev_busy(char *devnm);
extern struct mdstat_ent *mdstat_by_component(char *name);
extern struct mdstat_ent *mdstat_by_subdev(char *subdev, int container);
extern struct mdstat_ent *mdstat_by_subdev(char *subdev, char *container);
struct map_ent {
struct map_ent *next;
int devnum;
char devnm[32];
char metadata[20];
int uuid[4];
int bad;
char *path;
};
extern int map_update(struct map_ent **mpp, int devnum, char *metadata,
extern int map_update(struct map_ent **mpp, char *devnm, char *metadata,
int uuid[4], char *path);
extern void map_remove(struct map_ent **map, int devnum);
extern void map_remove(struct map_ent **map, char *devnm);
extern struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]);
extern struct map_ent *map_by_devnum(struct map_ent **map, int devnum);
extern struct map_ent *map_by_devnm(struct map_ent **map, char *devnm);
extern struct map_ent *map_by_name(struct map_ent **map, char *name);
extern void map_read(struct map_ent **melp);
extern int map_write(struct map_ent *mel);
extern void map_delete(struct map_ent **mapp, int devnum);
extern void map_delete(struct map_ent **mapp, char *devnm);
extern void map_free(struct map_ent *map);
extern void map_add(struct map_ent **melp,
int devnum, char *metadata, int uuid[4], char *path);
char *devnm, char *metadata, int uuid[4], char *path);
extern int map_lock(struct map_ent **melp);
extern void map_unlock(struct map_ent **melp);
extern void map_fork(void);
@ -518,12 +518,12 @@ enum sysfs_read_flags {
};
/* If fd >= 0, get the array it is open on,
* else use devnum. >=0 -> major9. <0.....
* else use devnm.
*/
extern int sysfs_open(int devnum, char *devname, char *attr);
extern void sysfs_init(struct mdinfo *mdi, int fd, int devnum);
extern int sysfs_open(char *devnm, char *devname, char *attr);
extern void sysfs_init(struct mdinfo *mdi, int fd, char *devnm);
extern void sysfs_free(struct mdinfo *sra);
extern struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options);
extern struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options);
extern int sysfs_attr_match(const char *attr, const char *str);
extern int sysfs_match_word(const char *word, char **list);
extern int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev,
@ -547,7 +547,7 @@ extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
extern int sysfs_set_array(struct mdinfo *info, int vers);
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume);
extern int sysfs_disk_to_scsi_id(int fd, __u32 *id);
extern int sysfs_unique_holder(int devnum, long rdev);
extern int sysfs_unique_holder(char *devnm, long rdev);
extern int sysfs_freeze_array(struct mdinfo *sra);
extern int load_sys(char *path, char *buf);
extern int reshape_prepare_fdlist(char *devname,
@ -925,7 +925,7 @@ struct supertype {
struct superswitch *ss;
int minor_version;
int max_devs;
int container_dev; /* devnum of container */
char container_devnm[32]; /* devnm of container */
void *sb;
void *info;
int ignore_hw_compat; /* used to inform metadata handlers that it should ignore
@ -939,10 +939,9 @@ struct supertype {
/* extra stuff used by mdmon */
struct active_array *arrays;
int sock; /* listen to external programs */
int devnum;
char *devname; /* e.g. md0. This appears in metadata_verison:
* external:/md0/12
*/
char devnm[32]; /* e.g. md0. This appears in metadata_version:
* external:/md0/12
*/
int devcnt;
int retry_soon;
@ -1017,7 +1016,7 @@ extern void policy_free(void);
extern struct dev_policy *path_policy(char *path, char *type);
extern struct dev_policy *disk_policy(struct mdinfo *disk);
extern struct dev_policy *devnum_policy(int dev);
extern struct dev_policy *devid_policy(int devid);
extern void dev_policy_free(struct dev_policy *p);
//extern void pol_new(struct dev_policy **pol, char *name, char *val, char *metadata);
@ -1049,7 +1048,7 @@ extern int domain_test(struct domainlist *dom, struct dev_policy *pol,
const char *metadata);
extern struct domainlist *domain_from_array(struct mdinfo *mdi,
const char *metadata);
extern void domainlist_add_dev(struct domainlist **dom, int devnum,
extern void domainlist_add_dev(struct domainlist **dom, int devid,
const char *metadata);
extern void domain_free(struct domainlist *dl);
extern void domain_merge(struct domainlist **domp, struct dev_policy *pol,
@ -1195,9 +1194,9 @@ extern int check_partitions(int fd, char *dname,
extern int get_mdp_major(void);
extern int dev_open(char *dev, int flags);
extern int open_dev(int devnum);
extern int open_dev_flags(int devnum, int flags);
extern int open_dev_excl(int devnum);
extern int open_dev(char *devnm);
extern int open_dev_flags(char *devnm, int flags);
extern int open_dev_excl(char *devnm);
extern int is_standard(char *dev, int *nump);
extern int same_dev(char *one, char *two);
extern int compare_paths (char* path1,char* path2);
@ -1271,11 +1270,12 @@ extern char *human_size(long long bytes);
extern char *human_size_brief(long long bytes, int prefix);
extern void print_r10_layout(int layout);
#define NoMdDev (1<<23)
extern int find_free_devnum(int use_partitions);
extern char *find_free_devnm(int use_partitions);
extern void put_md_name(char *name);
extern char *get_md_name(int dev);
extern char *devid2devnm(int devid);
extern int devnm2devid(char *devnm);
extern char *get_md_name(char *devnm);
extern char DefaultConfFile[];
@ -1288,16 +1288,18 @@ extern int create_mddev(char *dev, char *name, int autof, int trustworthy,
#define METADATA 3
extern int open_mddev(char *dev, int report_errors);
extern int open_container(int fd);
extern int metadata_container_matches(char *metadata, char *devnm);
extern int metadata_subdev_matches(char *metadata, char *devnm);
extern int is_container_member(struct mdstat_ent *ent, char *devname);
extern int is_subarray_active(char *subarray, char *devname);
extern int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet);
extern struct superswitch *version_to_superswitch(char *vers);
extern int mdmon_running(int devnum);
extern int mdmon_pid(int devnum);
extern int mdmon_running(char *devnm);
extern int mdmon_pid(char *devnm);
extern int check_env(char *name);
extern __u32 random32(void);
extern int start_mdmon(int devnum);
extern int start_mdmon(char *devnm);
extern int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
struct supertype *st, unsigned long stripes,
@ -1305,26 +1307,9 @@ extern int child_monitor(int afd, struct mdinfo *sra, struct reshape *reshape,
int dests, int *destfd, unsigned long long *destoffsets);
void abort_reshape(struct mdinfo *sra);
extern char *devnum2devname(int num);
extern void fmt_devname(char *name, int num);
extern int devname2devnum(char *name);
extern int stat2devnum(struct stat *st);
extern int fd2devnum(int fd);
static inline int dev2major(int d)
{
if (d >= 0)
return MD_MAJOR;
else
return get_mdp_major();
}
static inline int dev2minor(int d)
{
if (d >= 0)
return d;
return (-1-d) << MdpMinorShift;
}
extern char *stat2devnm(struct stat *st);
extern char *fd2devnm(int fd);
#define _ROUND_UP(val, base) (((val) + (base) - 1) & ~(base - 1))
#define ROUND_UP(val, base) _ROUND_UP(val, (typeof(val))(base))

77
mdmon.c
View File

@ -277,13 +277,12 @@ void usage(void)
exit(2);
}
static int mdmon(char *devname, int devnum, int must_fork, int takeover);
static int mdmon(char *devnm, int must_fork, int takeover);
int main(int argc, char *argv[])
{
char *container_name = NULL;
int devnum;
char *devname;
char *devnm = NULL;
int status = 0;
int opt;
int all = 0;
@ -349,47 +348,39 @@ int main(int argc, char *argv[])
if (e->metadata_version &&
strncmp(e->metadata_version, "external:", 9) == 0 &&
!is_subarray(&e->metadata_version[9])) {
devname = devnum2devname(e->devnum);
/* update cmdline so this mdmon instance can be
* distinguished from others in a call to ps(1)
*/
if (strlen(devname) <= (unsigned)container_len) {
if (strlen(e->devnm) <= (unsigned)container_len) {
memset(container_name, 0, container_len);
sprintf(container_name, "%s", devname);
sprintf(container_name, "%s", e->devnm);
}
status |= mdmon(devname, e->devnum, 1,
takeover);
status |= mdmon(e->devnm, 1, takeover);
}
}
free_mdstat(mdstat);
return status;
} else if (strncmp(container_name, "md", 2) == 0) {
devnum = devname2devnum(container_name);
devname = devnum2devname(devnum);
if (strcmp(container_name, devname) != 0)
devname = NULL;
int id = devnm2devid(container_name);
if (id)
devnm = container_name;
} else {
struct stat st;
devnum = NoMdDev;
if (stat(container_name, &st) == 0)
devnum = stat2devnum(&st);
if (devnum == NoMdDev)
devname = NULL;
else
devname = devnum2devname(devnum);
devnm = xstrdup(stat2devnm(&st));
}
if (!devname) {
if (!devnm) {
fprintf(stderr, "mdmon: %s is not a valid md device name\n",
container_name);
exit(1);
}
return mdmon(devname, devnum, dofork && do_fork(), takeover);
return mdmon(devnm, dofork && do_fork(), takeover);
}
static int mdmon(char *devname, int devnum, int must_fork, int takeover)
static int mdmon(char *devnm, int must_fork, int takeover)
{
int mdfd;
struct mdinfo *mdi, *di;
@ -402,17 +393,17 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover)
pid_t victim = -1;
int victim_sock = -1;
dprintf("starting mdmon for %s\n", devname);
dprintf("starting mdmon for %s\n", devnm);
mdfd = open_dev(devnum);
mdfd = open_dev(devnm);
if (mdfd < 0) {
fprintf(stderr, "mdmon: %s: %s\n", devname,
fprintf(stderr, "mdmon: %s: %s\n", devnm,
strerror(errno));
return 1;
}
if (md_get_version(mdfd) < 0) {
fprintf(stderr, "mdmon: %s: Not an md device\n",
devname);
devnm);
return 1;
}
@ -442,39 +433,33 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover)
pfd[0] = pfd[1] = -1;
container = xcalloc(1, sizeof(*container));
container->devnum = devnum;
container->devname = devname;
strcpy(container->devnm, devnm);
container->arrays = NULL;
container->sock = -1;
if (!container->devname) {
fprintf(stderr, "mdmon: failed to allocate container name string\n");
exit(3);
}
mdi = sysfs_read(mdfd, container->devnum, GET_VERSION|GET_LEVEL|GET_DEVS);
mdi = sysfs_read(mdfd, container->devnm, GET_VERSION|GET_LEVEL|GET_DEVS);
if (!mdi) {
fprintf(stderr, "mdmon: failed to load sysfs info for %s\n",
container->devname);
container->devnm);
exit(3);
}
if (mdi->array.level != UnSet) {
fprintf(stderr, "mdmon: %s is not a container - cannot monitor\n",
devname);
devnm);
exit(3);
}
if (mdi->array.major_version != -1 ||
mdi->array.minor_version != -2) {
fprintf(stderr, "mdmon: %s does not use external metadata - cannot monitor\n",
devname);
devnm);
exit(3);
}
container->ss = version_to_superswitch(mdi->text_version);
if (container->ss == NULL) {
fprintf(stderr, "mdmon: %s uses unsupported metadata: %s\n",
devname, mdi->text_version);
devnm, mdi->text_version);
exit(3);
}
@ -502,23 +487,23 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover)
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
victim = mdmon_pid(container->devnum);
victim = mdmon_pid(container->devnm);
if (victim >= 0)
victim_sock = connect_monitor(container->devname);
victim_sock = connect_monitor(container->devnm);
ignore = chdir("/");
if (!takeover && victim > 0 && victim_sock >= 0) {
if (fping_monitor(victim_sock) == 0) {
fprintf(stderr, "mdmon: %s already managed\n",
container->devname);
container->devnm);
exit(3);
}
close(victim_sock);
victim_sock = -1;
}
if (container->ss->load_container(container, mdfd, devname)) {
if (container->ss->load_container(container, mdfd, devnm)) {
fprintf(stderr, "mdmon: Cannot load metadata for %s\n",
devname);
devnm);
exit(3);
}
close(mdfd);
@ -526,11 +511,11 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover)
/* Ok, this is close enough. We can say goodbye to our parent now.
*/
if (victim > 0)
remove_pidfile(devname);
if (make_pidfile(devname) < 0) {
remove_pidfile(devnm);
if (make_pidfile(devnm) < 0) {
exit(3);
}
container->sock = make_control_sock(devname);
container->sock = make_control_sock(devnm);
status = 0;
if (write(pfd[1], &status, sizeof(status)) < 0)
@ -547,7 +532,7 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover)
}
if (victim > 0) {
try_kill_monitor(victim, container->devname, victim_sock);
try_kill_monitor(victim, container->devnm, victim_sock);
if (victim_sock >= 0)
close(victim_sock);
}

View File

@ -48,8 +48,6 @@ struct active_array {
int check_degraded; /* flag set by mon, read by manage */
int check_reshape; /* flag set by mon, read by manage */
int devnum;
};
/*

View File

@ -145,6 +145,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
int parts;
char *cname;
char devname[20];
char devnm[32];
char cbuf[400];
if (chosen == NULL)
chosen = cbuf;
@ -252,30 +253,31 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
num = strtoul(n2, &ep, 10);
if (ep == n2 || *ep)
num = -1;
else if (mddev_busy(use_mdp ? (-1-num) : num))
num = -1;
else {
sprintf(devnm, "md%s%d", use_mdp ? "_d":"", num);
if (mddev_busy(devnm))
num = -1;
}
}
if (num < 0) {
/* need to choose a free number. */
num = find_free_devnum(use_mdp);
if (num == NoMdDev) {
char *_devnm = find_free_devnm(use_mdp);
if (devnm == NULL) {
pr_err("No avail md devices - aborting\n");
return -1;
}
strcpy(devnm, _devnm);
} else {
num = use_mdp ? (-1-num) : num;
if (mddev_busy(num)) {
sprintf(devnm, "%s%d", use_mdp?"md_d":"md", num);
if (mddev_busy(devnm)) {
pr_err("%s is already in use.\n",
dev);
return -1;
}
}
if (num < 0)
sprintf(devname, "/dev/md_d%d", -1-num);
else
sprintf(devname, "/dev/md%d", num);
sprintf(devname, "/dev/%s", devnm);
if (cname[0] == 0 && name) {
/* Need to find a name if we can
@ -335,14 +337,14 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
if (lstat(devname, &stb) == 0) {
/* Must be the correct device, else error */
if ((stb.st_mode&S_IFMT) != S_IFBLK ||
stb.st_rdev != makedev(dev2major(num),dev2minor(num))) {
stb.st_rdev != (dev_t)devnm2devid(devnm)) {
pr_err("%s exists but looks wrong, please fix\n",
devname);
return -1;
}
} else {
if (mknod(devname, S_IFBLK|0600,
makedev(dev2major(num),dev2minor(num))) != 0) {
devnm2devid(devnm)) != 0) {
pr_err("failed to create %s\n",
devname);
return -1;
@ -389,7 +391,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy,
make_parts(chosen, parts);
}
}
mdfd = open_dev_excl(num);
mdfd = open_dev_excl(devnm);
if (mdfd < 0)
pr_err("unexpected failure opening %s\n",
devname);

View File

@ -152,9 +152,8 @@ struct mdstat_ent *mdstat_read(int hold, int start)
for (; (line = conf_line(f)) ; free_line(line)) {
struct mdstat_ent *ent;
char *w;
int devnum;
char devnm[32];
int in_devs = 0;
char *ep;
if (strcmp(line, "Personalities")==0)
continue;
@ -164,18 +163,10 @@ struct mdstat_ent *mdstat_read(int hold, int start)
continue;
insert_here = NULL;
/* Better be an md line.. */
if (strncmp(line, "md", 2)!= 0)
if (strncmp(line, "md", 2)!= 0 || strlen(line) >= 32
|| (line[2] != '_' && !isdigit(line[2])))
continue;
if (strncmp(line, "md_d", 4) == 0)
devnum = -1-strtoul(line+4, &ep, 10);
else if (strncmp(line, "md", 2) == 0)
devnum = strtoul(line+2, &ep, 10);
else
continue;
if (ep == NULL || *ep ) {
/* pr_err("bad /proc/mdstat line starts: %s\n", line); */
continue;
}
strcpy(devnm, line);
ent = xmalloc(sizeof(*ent));
ent->dev = ent->level = ent->pattern= NULL;
@ -189,7 +180,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
ent->members = NULL;
ent->dev = xstrdup(line);
ent->devnum = devnum;
strcpy(ent->devnm, devnm);
for (w=dl_next(line); w!= line ; w=dl_next(w)) {
int l = strlen(w);
@ -207,19 +198,20 @@ struct mdstat_ent *mdstat_read(int hold, int start)
} else if (in_devs && strcmp(w, "blocks")==0)
in_devs = 0;
else if (in_devs) {
char *ep = strchr(w, '[');
ent->devcnt +=
add_member_devname(&ent->members, w);
if (strncmp(w, "md", 2)==0) {
if (ep && strncmp(w, "md", 2)==0) {
/* This has an md device as a component.
* If that device is already in the
* list, make sure we insert before
* there.
*/
struct mdstat_ent **ih;
int dn2 = devname2devnum(w);
ih = &all;
while (ih != insert_here && *ih &&
(*ih)->devnum != dn2)
((int)strlen((*ih)->devnm) != ep-w
|| strncmp((*ih)->devnm, w, ep-w) != 0))
ih = & (*ih)->next;
insert_here = ih;
}
@ -345,13 +337,13 @@ void mdstat_wait_fd(int fd, const sigset_t *sigmask)
NULL, sigmask);
}
int mddev_busy(int devnum)
int mddev_busy(char *devnm)
{
struct mdstat_ent *mdstat = mdstat_read(0, 0);
struct mdstat_ent *me;
for (me = mdstat ; me ; me = me->next)
if (me->devnum == devnum)
if (strcmp(me->devnm, devnm) == 0)
break;
free_mdstat(mdstat);
return me != NULL;
@ -384,35 +376,34 @@ struct mdstat_ent *mdstat_by_component(char *name)
return NULL;
}
struct mdstat_ent *mdstat_by_subdev(char *subdev, int container)
struct mdstat_ent *mdstat_by_subdev(char *subdev, char *container)
{
struct mdstat_ent *mdstat = mdstat_read(0, 0);
struct mdstat_ent *ent = NULL;
while (mdstat) {
struct mdstat_ent *ent;
char *pos;
/* metadata version must match:
* external:[/-]md%d/%s
* where %d is 'container' and %s is 'subdev'
* external:[/-]%s/%s
* where first %s is 'container' and second %s is 'subdev'
*/
if (mdstat->metadata_version &&
strncmp(mdstat->metadata_version, "external:", 9) == 0 &&
strchr("/-", mdstat->metadata_version[9]) != NULL &&
strncmp(mdstat->metadata_version+10, "md", 2) == 0 &&
strtoul(mdstat->metadata_version+12, &pos, 10)
== (unsigned)container &&
pos > mdstat->metadata_version+12 &&
*pos == '/' &&
strcmp(pos+1, subdev) == 0
) {
free_mdstat(mdstat->next);
mdstat->next = NULL;
return mdstat;
}
if (ent)
free_mdstat(ent);
ent = mdstat;
mdstat = mdstat->next;
ent->next = NULL;
free_mdstat(ent);
if (ent->metadata_version == NULL ||
strncmp(ent->metadata_version, "external:", 9) != 0)
continue;
if (!metadata_container_matches(ent->metadata_version+9,
container) ||
!metadata_subdev_matches(ent->metadata_version+9,
subdev))
continue;
free_mdstat(mdstat);
return ent;
}
return NULL;
}

View File

@ -573,9 +573,9 @@ static int wait_and_act(struct supertype *container, int nowait)
*/
int fd;
if (sigterm)
fd = open_dev_excl(container->devnum);
fd = open_dev_excl(container->devnm);
else
fd = open_dev_flags(container->devnum, O_RDONLY|O_EXCL);
fd = open_dev_flags(container->devnm, O_RDONLY|O_EXCL);
if (fd >= 0 || errno != EBUSY) {
/* OK, we are safe to leave */
if (sigterm && !dirty_arrays)
@ -586,7 +586,7 @@ static int wait_and_act(struct supertype *container, int nowait)
/* On SIGTERM, someone (the take-over mdmon) will
* clean up
*/
remove_pidfile(container->devname);
remove_pidfile(container->devnm);
exit_now = 1;
signal_manager();
close(fd);

27
msg.c
View File

@ -216,20 +216,6 @@ int ping_monitor(char *devname)
return err;
}
/* ping monitor using device number */
int ping_monitor_by_id(int devnum)
{
int err = -1;
char *container = devnum2devname(devnum);
if (container) {
err = ping_monitor(container);
free(container);
}
return err;
}
static char *ping_monitor_version(char *devname)
{
int sfd = connect_monitor(devname);
@ -291,9 +277,8 @@ int block_subarray(struct mdinfo *sra)
int check_mdmon_version(char *container)
{
char *version = NULL;
int devnum = devname2devnum(container);
if (!mdmon_running(devnum)) {
if (!mdmon_running(container)) {
/* if mdmon is not active we assume that any instance that is
* later started will match the current mdadm version, if this
* assumption is violated we may inadvertantly rebuild an array
@ -357,7 +342,7 @@ int block_monitor(char *container, const int freeze)
if (!is_container_member(e, container))
continue;
sysfs_free(sra);
sra = sysfs_read(-1, e->devnum, GET_VERSION);
sra = sysfs_read(-1, e->devnm, GET_VERSION);
if (!sra) {
pr_err("failed to read sysfs for subarray%s\n",
to_subarray(e, container));
@ -393,7 +378,7 @@ int block_monitor(char *container, const int freeze)
* or part-spares
*/
sysfs_free(sra);
sra = sysfs_read(-1, e->devnum, GET_DEVS | GET_STATE);
sra = sysfs_read(-1, e->devnm, GET_DEVS | GET_STATE);
if (sra && sra->array.spare_disks > 0) {
unblock_subarray(sra, freeze);
break;
@ -409,7 +394,7 @@ int block_monitor(char *container, const int freeze)
if (!is_container_member(e2, container))
continue;
sysfs_free(sra);
sra = sysfs_read(-1, e2->devnum, GET_VERSION);
sra = sysfs_read(-1, e2->devnm, GET_VERSION);
if (unblock_subarray(sra, freeze))
pr_err("Failed to unfreeze %s\n", e2->dev);
}
@ -441,7 +426,7 @@ void unblock_monitor(char *container, const int unfreeze)
if (!is_container_member(e, container))
continue;
sysfs_free(sra);
sra = sysfs_read(-1, e->devnum, GET_VERSION|GET_LEVEL);
sra = sysfs_read(-1, e->devnm, GET_VERSION|GET_LEVEL);
if (!sra)
continue;
if (sra->array.level > 0)
@ -456,8 +441,6 @@ void unblock_monitor(char *container, const int unfreeze)
free_mdstat(ent);
}
/* give the manager a chance to view the updated container state. This
* would naturally happen due to the manager noticing a change in
* /proc/mdstat; however, pinging encourages this detection to happen

1
msg.h
View File

@ -27,7 +27,6 @@ extern int ack(int fd, int tmo);
extern int wait_reply(int fd, int tmo);
extern int connect_monitor(char *devname);
extern int ping_monitor(char *devname);
extern int ping_monitor_by_id(int devnum);
extern int block_subarray(struct mdinfo *sra);
extern int unblock_subarray(struct mdinfo *sra, const int unfreeze);
extern int block_monitor(char *container, const int freeze);

View File

@ -421,7 +421,7 @@ struct dev_policy *disk_policy(struct mdinfo *disk)
return pol;
}
struct dev_policy *devnum_policy(int dev)
struct dev_policy *devid_policy(int dev)
{
struct mdinfo disk;
disk.disk.major = major(dev);
@ -677,9 +677,9 @@ int domain_test(struct domainlist *dom, struct dev_policy *pol,
return found_any;
}
void domainlist_add_dev(struct domainlist **dom, int devnum, const char *metadata)
void domainlist_add_dev(struct domainlist **dom, int devid, const char *metadata)
{
struct dev_policy *pol = devnum_policy(devnum);
struct dev_policy *pol = devid_policy(devid);
domain_merge(dom, pol, metadata);
dev_policy_free(pol);
}

View File

@ -884,7 +884,6 @@ static struct supertype *match_metadata_desc_ddf(char *arg)
return NULL;
st = xcalloc(1, sizeof(*st));
st->container_dev = NoMdDev;
st->ss = &super_ddf;
st->max_devs = 512;
st->minor_version = 0;
@ -1451,7 +1450,7 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
info->array.major_version = -1;
info->array.minor_version = -2;
sprintf(info->text_version, "/%s/%d",
devnum2devname(st->container_dev),
st->container_devnm,
info->container_member);
info->safe_mode_delay = 200;
@ -2676,7 +2675,7 @@ static int validate_geometry_ddf(struct supertype *st,
*/
fd = open(dev, O_RDONLY|O_EXCL, 0);
if (fd >= 0) {
sra = sysfs_read(fd, 0, GET_VERSION);
sra = sysfs_read(fd, NULL, GET_VERSION);
close(fd);
if (sra && sra->array.major_version == -1 &&
strcmp(sra->text_version, "ddf") == 0) {
@ -2708,7 +2707,7 @@ static int validate_geometry_ddf(struct supertype *st,
dev, strerror(EBUSY));
return 0;
}
sra = sysfs_read(cfd, 0, GET_VERSION);
sra = sysfs_read(cfd, NULL, GET_VERSION);
close(fd);
if (sra && sra->array.major_version == -1 &&
strcmp(sra->text_version, "ddf") == 0) {
@ -2718,7 +2717,7 @@ static int validate_geometry_ddf(struct supertype *st,
struct ddf_super *ddf;
if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL) == 0) {
st->sb = ddf;
st->container_dev = fd2devnum(cfd);
strcpy(st->container_devnm, fd2devnm(cfd));
close(cfd);
return validate_geometry_ddf_bvd(st, level, layout,
raiddisks, chunk, size,
@ -2937,7 +2936,7 @@ static int load_super_ddf_all(struct supertype *st, int fd,
st->minor_version = 0;
st->max_devs = 512;
}
st->container_dev = fd2devnum(fd);
strcpy(st->container_devnm, fd2devnm(fd));
return 0;
}
@ -3020,8 +3019,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
ddf->currentconf = NULL;
sprintf(this->text_version, "/%s/%d",
devnum2devname(st->container_dev),
this->container_member);
st->container_devnm, this->container_member);
for (i = 0 ; i < ddf->mppe ; i++) {
struct mdinfo *dev;

View File

@ -431,7 +431,7 @@ struct imsm_update_activate_spare {
};
struct geo_params {
int dev_id;
char devnm[32];
char *dev_name;
unsigned long long size;
int level;
@ -605,7 +605,6 @@ static struct supertype *match_metadata_desc_imsm(char *arg)
return NULL;
st = xcalloc(1, sizeof(*st));
st->container_dev = NoMdDev;
st->ss = &super_imsm;
st->max_devs = IMSM_MAX_DEVICES;
st->minor_version = 0;
@ -2532,7 +2531,6 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
struct imsm_map *prev_map = get_imsm_map(dev, MAP_1);
struct imsm_map *map_to_analyse = map;
struct dl *dl;
char *devname;
int map_disks = info->array.raid_disks;
memset(info, 0, sizeof(*info));
@ -2694,11 +2692,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
info->array.major_version = -1;
info->array.minor_version = -2;
devname = devnum2devname(st->container_dev);
*info->text_version = '\0';
if (devname)
sprintf(info->text_version, "/%s/%d", devname, info->container_member);
free(devname);
sprintf(info->text_version, "/%s/%d", st->container_devnm, info->container_member);
info->safe_mode_delay = 4000; /* 4 secs like the Matrix driver */
uuid_from_super_imsm(st, info->uuid);
@ -4158,7 +4152,7 @@ imsm_thunderdome(struct intel_super **super_list, int len)
static int
get_sra_super_block(int fd, struct intel_super **super_list, char *devname, int *max, int keep_fd);
static int get_super_block(struct intel_super **super_list, int devnum, char *devname,
static int get_super_block(struct intel_super **super_list, char *devnm, char *devname,
int major, int minor, int keep_fd);
static int
get_devlist_super_block(struct md_list *devlist, struct intel_super **super_list,
@ -4233,9 +4227,9 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
*sbp = super;
if (fd >= 0)
st->container_dev = fd2devnum(fd);
strcpy(st->container_devnm, fd2devnm(fd));
else
st->container_dev = NoMdDev;
st->container_devnm[0] = 0;
if (err == 0 && st->ss == NULL) {
st->ss = &super_imsm;
st->minor_version = 0;
@ -4278,7 +4272,7 @@ get_devlist_super_block(struct md_list *devlist, struct intel_super **super_list
int major = major(tmpdev->st_rdev);
int minor = minor(tmpdev->st_rdev);
err = get_super_block(super_list,
-1,
NULL,
tmpdev->devname,
major, minor,
keep_fd);
@ -4294,7 +4288,7 @@ get_devlist_super_block(struct md_list *devlist, struct intel_super **super_list
return err;
}
static int get_super_block(struct intel_super **super_list, int devnum, char *devname,
static int get_super_block(struct intel_super **super_list, char *devnm, char *devname,
int major, int minor, int keep_fd)
{
struct intel_super*s = NULL;
@ -4320,7 +4314,7 @@ static int get_super_block(struct intel_super **super_list, int devnum, char *de
err = load_and_parse_mpb(dfd, s, NULL, keep_fd);
/* retry the load if we might have raced against mdmon */
if (err == 3 && (devnum != -1) && mdmon_running(devnum))
if (err == 3 && devnm && mdmon_running(devnm))
for (retry = 0; retry < 3; retry++) {
usleep(3000);
err = load_and_parse_mpb(dfd, s, NULL, keep_fd);
@ -4347,11 +4341,11 @@ static int
get_sra_super_block(int fd, struct intel_super **super_list, char *devname, int *max, int keep_fd)
{
struct mdinfo *sra;
int devnum;
char *devnm;
struct mdinfo *sd;
int err = 0;
int i = 0;
sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
sra = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
if (!sra)
return 1;
@ -4362,9 +4356,9 @@ get_sra_super_block(int fd, struct intel_super **super_list, char *devname, int
goto error;
}
/* load all mpbs */
devnum = fd2devnum(fd);
devnm = fd2devnm(fd);
for (sd = sra->devs, i = 0; sd; sd = sd->next, i++) {
if (get_super_block(super_list, devnum, devname,
if (get_super_block(super_list, devnm, devname,
sd->disk.major, sd->disk.minor, keep_fd) != 0) {
err = 7;
goto error;
@ -6230,7 +6224,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
dev);
return 0;
}
sra = sysfs_read(cfd, 0, GET_VERSION);
sra = sysfs_read(cfd, NULL, GET_VERSION);
if (sra && sra->array.major_version == -1 &&
strcmp(sra->text_version, "imsm") == 0)
is_member = 1;
@ -6243,7 +6237,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
if (load_super_imsm_all(st, cfd, (void **) &super, NULL, NULL, 1) == 0) {
st->sb = super;
st->container_dev = fd2devnum(cfd);
strcpy(st->container_devnm, fd2devnm(cfd));
close(cfd);
return validate_geometry_imsm_volume(st, level, layout,
raiddisks, chunk,
@ -6301,7 +6295,7 @@ static int kill_subarray_imsm(struct supertype *st)
if (i < current_vol)
continue;
sprintf(subarray, "%u", i);
if (is_subarray_active(subarray, st->devname)) {
if (is_subarray_active(subarray, st->devnm)) {
pr_err("deleting subarray-%d would change the UUID of active subarray-%d, aborting\n",
current_vol, i);
@ -6357,7 +6351,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
char *ep;
int vol;
if (is_subarray_active(subarray, st->devname)) {
if (is_subarray_active(subarray, st->devnm)) {
pr_err("Unable to update name of active subarray\n");
return 2;
}
@ -9332,19 +9326,20 @@ static const char *imsm_get_disk_controller_domain(const char *path)
return drv;
}
static int imsm_find_array_minor_by_subdev(int subdev, int container, int *minor)
static char *imsm_find_array_devnm_by_subdev(int subdev, char *container)
{
static char devnm[32];
char subdev_name[20];
struct mdstat_ent *mdstat;
sprintf(subdev_name, "%d", subdev);
mdstat = mdstat_by_subdev(subdev_name, container);
if (!mdstat)
return -1;
return NULL;
*minor = mdstat->devnum;
strcpy(devnm, mdstat->devnm);
free_mdstat(mdstat);
return 0;
return devnm;
}
static int imsm_reshape_is_allowed_on_container(struct supertype *st,
@ -9361,8 +9356,7 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st,
int devices_that_can_grow = 0;
dprintf("imsm: imsm_reshape_is_allowed_on_container(ENTER): "
"st->devnum = (%i)\n",
st->devnum);
"st->devnm = (%s)\n", st->devnm);
if (geo->size > 0 ||
geo->level != UnSet ||
@ -9382,8 +9376,7 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st,
info = container_content_imsm(st, NULL);
for (member = info; member; member = member->next) {
int result;
int minor;
char *result;
dprintf("imsm: checking device_num: %i\n",
member->container_member);
@ -9440,10 +9433,9 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st,
* so they need to be assembled. We have already
* checked that no recovery etc is happening.
*/
result = imsm_find_array_minor_by_subdev(member->container_member,
st->container_dev,
&minor);
if (result < 0) {
result = imsm_find_array_devnm_by_subdev(member->container_member,
st->container_devnm);
if (result == NULL) {
dprintf("imsm: cannot find array\n");
break;
}
@ -9819,8 +9811,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
}
if ((super->current_vol + 1) != super->anchor->num_raid_devs) {
pr_err("Error. The last volume in container "
"can be expanded only (%i/%i).\n",
super->current_vol, st->devnum);
"can be expanded only (%i/%s).\n",
super->current_vol, st->devnm);
goto analyse_change_exit;
}
/* check the maximum available size
@ -9959,7 +9951,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size,
memset(&geo, 0, sizeof(struct geo_params));
geo.dev_name = dev;
geo.dev_id = st->devnum;
strcpy(geo.devnm, st->devnm);
geo.size = size;
geo.level = level;
geo.layout = layout;
@ -9974,7 +9966,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size,
if (experimental() == 0)
return ret_val;
if (st->container_dev == st->devnum) {
if (strcmp(st->container_devnm, st->devnm) == 0) {
/* On container level we can only increase number of devices. */
dprintf("imsm: info: Container operation\n");
int old_raid_disks = 0;
@ -10013,19 +10005,20 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size,
*/
struct intel_super *super = st->sb;
struct intel_dev *dev = super->devlist;
int change, devnum;
int change;
dprintf("imsm: info: Volume operation\n");
/* find requested device */
while (dev) {
if (imsm_find_array_minor_by_subdev(
dev->index, st->container_dev, &devnum) == 0
&& devnum == geo.dev_id)
char *devnm =
imsm_find_array_devnm_by_subdev(
dev->index, st->container_devnm);
if (devnm && strcmp(devnm, geo.devnm) == 0)
break;
dev = dev->next;
}
if (dev == NULL) {
pr_err("Cannot find %s (%i) subarray\n",
geo.dev_name, geo.dev_id);
pr_err("Cannot find %s (%s) subarray\n",
geo.dev_name, geo.devnm);
goto exit_imsm_reshape_super;
}
super->current_vol = dev->index;

View File

@ -953,7 +953,7 @@ static struct supertype *match_metadata_desc0(char *arg)
{
struct supertype *st = xcalloc(1, sizeof(*st));
st->container_dev = NoMdDev;
st->container_devnm[0] = 0;
st->ss = &super0;
st->info = NULL;
st->minor_version = 90;

View File

@ -1716,7 +1716,7 @@ static struct supertype *match_metadata_desc1(char *arg)
{
struct supertype *st = xcalloc(1, sizeof(*st));
st->container_dev = NoMdDev;
st->container_devnm[0] = 0;
st->ss = &super1;
st->max_devs = MAX_DEVS;
st->sb = NULL;

61
sysfs.c
View File

@ -57,16 +57,12 @@ void sysfs_free(struct mdinfo *sra)
}
}
int sysfs_open(int devnum, char *devname, char *attr)
int sysfs_open(char *devnm, char *devname, char *attr)
{
char fname[50];
int fd;
char *mdname = devnum2devname(devnum);
if (!mdname)
return -1;
sprintf(fname, "/sys/block/%s/md/", mdname);
sprintf(fname, "/sys/block/%s/md/", devnm);
if (devname) {
strcat(fname, devname);
strcat(fname, "/");
@ -75,26 +71,25 @@ int sysfs_open(int devnum, char *devname, char *attr)
fd = open(fname, O_RDWR);
if (fd < 0 && errno == EACCES)
fd = open(fname, O_RDONLY);
free(mdname);
return fd;
}
void sysfs_init(struct mdinfo *mdi, int fd, int devnum)
void sysfs_init(struct mdinfo *mdi, int fd, char *devnm)
{
mdi->sys_name[0] = 0;
if (fd >= 0) {
mdu_version_t vers;
if (ioctl(fd, RAID_VERSION, &vers) != 0)
return;
devnum = fd2devnum(fd);
devnm = fd2devnm(fd);
}
if (devnum == NoMdDev)
if (devnm == NULL)
return;
fmt_devname(mdi->sys_name, devnum);
strcpy(mdi->sys_name, devnm);
}
struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
{
char fname[PATH_MAX];
char buf[PATH_MAX];
@ -106,7 +101,7 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
struct dirent *de;
sra = xcalloc(1, sizeof(*sra));
sysfs_init(sra, fd, devnum);
sysfs_init(sra, fd, devnm);
if (sra->sys_name[0] == 0) {
free(sra);
return NULL;
@ -641,13 +636,7 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
return rv;
memset(nm, 0, sizeof(nm));
sprintf(dv, "/sys/dev/block/%d:%d", sd->disk.major, sd->disk.minor);
rv = readlink(dv, nm, sizeof(nm)-1);
if (rv <= 0)
return -1;
nm[rv] = '\0';
dname = strrchr(nm, '/');
if (dname) dname++;
dname = devid2devnm(makedev(sd->disk.major, sd->disk.minor));
strcpy(sd->sys_name, "dev-");
strcpy(sd->sys_name+4, dname);
@ -779,12 +768,12 @@ int sysfs_disk_to_scsi_id(int fd, __u32 *id)
}
int sysfs_unique_holder(int devnum, long rdev)
int sysfs_unique_holder(char *devnm, long rdev)
{
/* Check that devnum is a holder of rdev,
/* Check that devnm is a holder of rdev,
* and is the only holder.
* we should be locked against races by
* an O_EXCL on devnum
* an O_EXCL on devnm
* Return values:
* 0 - not unique, not even a holder
* 1 - unique, this is the only holder.
@ -803,11 +792,9 @@ int sysfs_unique_holder(int devnum, long rdev)
return -1;
l = strlen(dirname);
while ((de = readdir(dir)) != NULL) {
char buf[10];
char buf[100];
char *sl;
int n;
int mj, mn;
char c;
int fd;
if (de->d_ino == 0)
continue;
@ -815,24 +802,16 @@ int sysfs_unique_holder(int devnum, long rdev)
continue;
strcpy(dirname+l, "/");
strcat(dirname+l, de->d_name);
strcat(dirname+l, "/dev");
fd = open(dirname, O_RDONLY);
if (fd < 0) {
/* Probably a race, just ignore this */
continue;
}
n = read(fd, buf, sizeof(buf)-1);
close(fd);
if (n < 0)
n = readlink(dirname, buf, sizeof(buf)-1);
if (n <= 0)
continue;
buf[n] = 0;
if (sscanf(buf, "%d:%d%c", &mj, &mn, &c) != 3 ||
c != '\n')
sl = strrchr(buf, '/');
if (!sl)
continue;
if (mj != MD_MAJOR)
mn = -1-(mn>>6);
sl++;
if (devnum == mn)
if (strcmp(devnm, sl) == 0)
ret |= 1;
else
ret |= 2;

214
util.c
View File

@ -778,42 +778,79 @@ int get_data_disks(int level, int layout, int raid_disks)
}
#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
char *get_md_name(int dev)
int devnm2devid(char *devnm)
{
/* First look in /sys/block/$DEVNM/dev for %d:%d
* If that fails, try parsing out a number
*/
char path[100];
char *ep;
int fd;
int mjr,mnr;
sprintf(path, "/sys/block/%s/dev", devnm);
fd = open(path, O_RDONLY);
if (fd >= 0) {
char buf[20];
int n = read(fd, buf, sizeof(buf));
close(fd);
if (n > 0)
buf[n] = 0;
if (n > 0 && sscanf(buf, "%d:%d\n", &mjr, &mnr) == 2)
return makedev(mjr, mnr);
}
if (strncmp(devnm, "md_d", 4) == 0 &&
isdigit(devnm[4]) &&
(mnr = strtoul(devnm+4, &ep, 10)) >= 0 &&
ep > devnm && *ep == 0)
return makedev(get_mdp_major(), mnr << MdpMinorShift);
if (strncmp(devnm, "md", 2) == 0 &&
isdigit(devnm[2]) &&
(mnr = strtoul(devnm+2, &ep, 10)) >= 0 &&
ep > devnm && *ep == 0)
return makedev(MD_MAJOR, mnr);
return 0;
}
char *get_md_name(char *devnm)
{
/* find /dev/md%d or /dev/md/%d or make a device /dev/.tmp.md%d */
/* if dev < 0, want /dev/md/d%d or find mdp in /proc/devices ... */
static char devname[50];
struct stat stb;
dev_t rdev;
dev_t rdev = devnm2devid(devnm);
char *dn;
if (dev < 0) {
int mdp = get_mdp_major();
if (mdp < 0) return NULL;
rdev = makedev(mdp, (-1-dev)<<6);
snprintf(devname, sizeof(devname), "/dev/md/d%d", -1-dev);
if (stat(devname, &stb) == 0
&& (S_IFMT&stb.st_mode) == S_IFBLK
&& (stb.st_rdev == rdev))
return devname;
} else {
rdev = makedev(MD_MAJOR, dev);
snprintf(devname, sizeof(devname), "/dev/md%d", dev);
if (stat(devname, &stb) == 0
&& (S_IFMT&stb.st_mode) == S_IFBLK
&& (stb.st_rdev == rdev))
return devname;
snprintf(devname, sizeof(devname), "/dev/md/%d", dev);
if (rdev == 0)
return 0;
if (strncmp(devnm, "md_", 3) == 0) {
snprintf(devname, sizeof(devname), "/dev/md/%s",
devnm + 3);
if (stat(devname, &stb) == 0
&& (S_IFMT&stb.st_mode) == S_IFBLK
&& (stb.st_rdev == rdev))
return devname;
}
snprintf(devname, sizeof(devname), "/dev/%s", devnm);
if (stat(devname, &stb) == 0
&& (S_IFMT&stb.st_mode) == S_IFBLK
&& (stb.st_rdev == rdev))
return devname;
snprintf(devname, sizeof(devname), "/dev/md/%s", devnm+2);
if (stat(devname, &stb) == 0
&& (S_IFMT&stb.st_mode) == S_IFBLK
&& (stb.st_rdev == rdev))
return devname;
dn = map_dev(major(rdev), minor(rdev), 0);
if (dn)
return dn;
snprintf(devname, sizeof(devname), "/dev/.tmp.md%d", dev);
snprintf(devname, sizeof(devname), "/dev/.tmp.%s", devnm);
if (mknod(devname, S_IFBLK | 0600, rdev) == -1)
if (errno != EEXIST)
return NULL;
@ -832,33 +869,37 @@ void put_md_name(char *name)
unlink(name);
}
int find_free_devnum(int use_partitions)
char *find_free_devnm(int use_partitions)
{
static char devnm[32];
int devnum;
for (devnum = 127; devnum != 128;
devnum = devnum ? devnum-1 : (1<<20)-1) {
int _devnum;
char nbuf[50];
_devnum = use_partitions ? (-1-devnum) : devnum;
if (mddev_busy(_devnum))
if (use_partitions)
sprintf(devnm, "md_d%d", devnum);
else
sprintf(devnm, "md%d", devnum);
if (mddev_busy(devnm))
continue;
sprintf(nbuf, "%s%d", use_partitions?"mdp":"md", devnum);
if (!conf_name_is_free(nbuf))
if (!conf_name_is_free(devnm))
continue;
if (!use_udev()) {
/* make sure it is new to /dev too, at least as a
* non-standard */
char *dn = map_dev(dev2major(_devnum),
dev2minor(_devnum), 0);
if (dn && ! is_standard(dn, NULL))
continue;
int devid = devnm2devid(devnm);
if (devid) {
char *dn = map_dev(major(devid),
minor(devid), 0);
if (dn && ! is_standard(dn, NULL))
continue;
}
}
break;
}
if (devnum == 128)
return NoMdDev;
return use_partitions ? (-1-devnum) : devnum;
return NULL;
return devnm;
}
#endif /* !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) */
@ -900,26 +941,29 @@ int dev_open(char *dev, int flags)
return fd;
}
int open_dev_flags(int devnum, int flags)
int open_dev_flags(char *devnm, int flags)
{
int devid;
char buf[20];
sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
devid = devnm2devid(devnm);
sprintf(buf, "%d:%d", major(devid), minor(devid));
return dev_open(buf, flags);
}
int open_dev(int devnum)
int open_dev(char *devnm)
{
return open_dev_flags(devnum, O_RDONLY);
return open_dev_flags(devnm, O_RDONLY);
}
int open_dev_excl(int devnum)
int open_dev_excl(char *devnm)
{
char buf[20];
int i;
int flags = O_RDWR;
int devid = devnm2devid(devnm);
sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
sprintf(buf, "%d:%d", major(devid), minor(devid));
for (i = 0 ; i < 25 ; i++) {
int fd = dev_open(buf, flags|O_EXCL);
if (fd >= 0)
@ -990,9 +1034,9 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
char version[20];
int i;
char *subarray = NULL;
int container = NoMdDev;
char container[32] = "";
sra = sysfs_read(fd, 0, GET_VERSION);
sra = sysfs_read(fd, NULL, GET_VERSION);
if (sra) {
vers = sra->array.major_version;
@ -1018,7 +1062,7 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
*subarray++ = '\0';
subarray = xstrdup(subarray);
}
container = devname2devnum(dev);
strcpy(container, dev);
if (sra)
sysfs_free(sra);
sra = sysfs_read(-1, container, GET_VERSION);
@ -1037,8 +1081,8 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
st->sb = NULL;
if (subarrayp)
*subarrayp = subarray;
st->container_dev = container;
st->devnum = fd2devnum(fd);
strcpy(st->container_devnm, container);
strcpy(st->devnm, fd2devnm(fd));
} else
free(subarray);
@ -1091,7 +1135,7 @@ struct supertype *guess_super_type(int fd, enum guess_types guess_type)
int i;
st = xcalloc(1, sizeof(*st));
st->container_dev = NoMdDev;
st->container_devnm[0] = 0;
for (i = 0 ; superlist[i]; i++) {
int rv;
@ -1386,13 +1430,47 @@ struct superswitch *version_to_superswitch(char *vers)
return NULL;
}
int metadata_container_matches(char *metadata, char *devnm)
{
/* Check if 'devnm' is the container named in 'metadata'
* which is
* /containername/componentname or
* -containername/componentname
*/
int l;
if (*metadata != '/' && *metadata != '-')
return 0;
l = strlen(devnm);
if (strncmp(metadata+1, devnm, l) != 0)
return 0;
if (metadata[l+1] != '/')
return 0;
return 1;
}
int metadata_subdev_matches(char *metadata, char *devnm)
{
/* Check if 'devnm' is the subdev named in 'metadata'
* which is
* /containername/subdev or
* -containername/subdev
*/
char *sl;
if (*metadata != '/' && *metadata != '-')
return 0;
sl = strchr(metadata+1, '/');
if (!sl)
return 0;
if (strcmp(sl+1, devnm) == 0)
return 1;
return 0;
}
int is_container_member(struct mdstat_ent *mdstat, char *container)
{
if (mdstat->metadata_version == NULL ||
strncmp(mdstat->metadata_version, "external:", 9) != 0 ||
!is_subarray(mdstat->metadata_version+9) ||
strncmp(mdstat->metadata_version+10, container, strlen(container)) != 0 ||
mdstat->metadata_version[10+strlen(container)] != '/')
!metadata_container_matches(mdstat->metadata_version+9, container))
return 0;
return 1;
@ -1425,6 +1503,7 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet)
struct mdinfo *mdi;
struct mdinfo *info;
int fd, err = 1;
char *_devnm;
fd = open(dev, O_RDWR|O_EXCL);
if (fd < 0) {
@ -1434,15 +1513,16 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet)
return -1;
}
st->devnum = fd2devnum(fd);
if (st->devnum == NoMdDev) {
_devnm = fd2devnm(fd);
if (_devnm == NULL) {
if (!quiet)
pr_err("Failed to determine device number for %s\n",
dev);
goto close_fd;
}
strcpy(st->devnm, _devnm);
mdi = sysfs_read(fd, st->devnum, GET_VERSION|GET_LEVEL);
mdi = sysfs_read(fd, st->devnm, GET_VERSION|GET_LEVEL);
if (!mdi) {
if (!quiet)
pr_err("Failed to read sysfs for %s\n",
@ -1464,8 +1544,7 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet)
goto free_sysfs;
}
st->devname = devnum2devname(st->devnum);
if (!st->devname) {
if (st->devnm[0] == 0) {
if (!quiet)
pr_err("Failed to allocate device name\n");
goto free_sysfs;
@ -1474,14 +1553,14 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet)
if (!st->ss->load_container) {
if (!quiet)
pr_err("%s is not a container\n", dev);
goto free_name;
goto free_sysfs;
}
if (st->ss->load_container(st, fd, NULL)) {
if (!quiet)
pr_err("Failed to load metadata for %s\n",
dev);
goto free_name;
goto free_sysfs;
}
info = st->ss->container_content(st, subarray);
@ -1498,9 +1577,6 @@ int open_subarray(char *dev, char *subarray, struct supertype *st, int quiet)
free_super:
if (err)
st->ss->free_super(st);
free_name:
if (err)
free(st->devname);
free_sysfs:
sysfs_free(mdi);
close_fd:
@ -1598,16 +1674,14 @@ unsigned long long min_recovery_start(struct mdinfo *array)
return recovery_start;
}
int mdmon_pid(int devnum)
int mdmon_pid(char *devnm)
{
char path[100];
char pid[10];
int fd;
int n;
char *devname = devnum2devname(devnum);
sprintf(path, "%s/%s.pid", MDMON_DIR, devname);
free(devname);
sprintf(path, "%s/%s.pid", MDMON_DIR, devnm);
fd = open(path, O_RDONLY | O_NOATIME, 0);
@ -1620,9 +1694,9 @@ int mdmon_pid(int devnum)
return atoi(pid);
}
int mdmon_running(int devnum)
int mdmon_running(char *devnm)
{
int pid = mdmon_pid(devnum);
int pid = mdmon_pid(devnm);
if (pid <= 0)
return 0;
if (kill(pid, 0) == 0)
@ -1630,7 +1704,7 @@ int mdmon_running(int devnum)
return 0;
}
int start_mdmon(int devnum)
int start_mdmon(char *devnm)
{
int i, skipped;
int len;
@ -1672,7 +1746,7 @@ int start_mdmon(int devnum)
skipped = 0;
snprintf(pathbuf, sizeof(pathbuf), "mdmon@%s.service",
devnum2devname(devnum));
devnm);
status = execl("/usr/bin/systemctl", "systemctl", "start",
pathbuf, NULL);
status = execl("/bin/systemctl", "systemctl", "start",
@ -1701,7 +1775,7 @@ int start_mdmon(int devnum)
for (i = 0; paths[i]; i++)
if (paths[i][0]) {
execl(paths[i], "mdmon",
devnum2devname(devnum), NULL);
devnm, NULL);
}
exit(1);
case -1: pr_err("cannot run mdmon. "
@ -1748,7 +1822,7 @@ int flush_metadata_updates(struct supertype *st)
return -1;
}
sfd = connect_monitor(devnum2devname(st->container_dev));
sfd = connect_monitor(st->container_devnm);
if (sfd < 0)
return -1;
@ -1835,7 +1909,7 @@ struct mdinfo *container_choose_spares(struct supertype *st,
found = 1;
/* check if domain matches */
if (found && domlist) {
struct dev_policy *pol = devnum_policy(dev);
struct dev_policy *pol = devid_policy(dev);
if (spare_group)
pol_add(&pol, pol_domain,
spare_group, NULL);