From: NeilBrown Date: Thu, 1 Nov 2012 05:14:01 +0000 (+1100) Subject: Discard devnum in favour of devnm X-Git-Tag: mdadm-3.3-rc1~117 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=commitdiff_plain;h=4dd2df0966ec2e43ea404df5de7adf9f0e1a8e40;hp=fdcad551e9a54c4aa8c4b63160b76e2c539a0441 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 --- diff --git a/Assemble.c b/Assemble.c index eed1c9b0..ab7e249e 100644 --- a/Assemble.c +++ b/Assemble.c @@ -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; itext_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; } diff --git a/Build.c b/Build.c index 1887822c..5c97d630 100644 --- a/Build.c +++ b/Build.c @@ -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); diff --git a/Create.c b/Create.c index 436bd1d9..a4aab41f 100644 --- a/Create.c +++ b/Create.c @@ -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; + + mdi = sysfs_read(-1, devnm, GET_VERSION); - pr_err("Creating array inside " - "%s container %s\n", - mdi?mdi->text_version:"managed", path); + 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) diff --git a/Detail.c b/Detail.c index ab49803d..250d5864 100644 --- a/Detail.c +++ b/Detail.c @@ -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); diff --git a/Grow.c b/Grow.c index 2cc93578..948fc8d9 100644 --- a/Grow.c +++ b/Grow.c @@ -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 diff --git a/Incremental.c b/Incremental.c index 19e4a1ec..36f79ef5 100644 --- a/Incremental.c +++ b/Incremental.c @@ -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, diff --git a/Kill.c b/Kill.c index cc2e5893..f2fdb856 100644 --- a/Kill.c +++ b/Kill.c @@ -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 */ diff --git a/Manage.c b/Manage.c index 4d9c0d2f..6267c0ca 100644 --- a/Manage.c +++ b/Manage.c @@ -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); diff --git a/Monitor.c b/Monitor.c index a5e7aaab..607d3ddd 100644 --- a/Monitor.c +++ b/Monitor.c @@ -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; diff --git a/config.c b/config.c index 8461309a..0eb2c8d1 100644 --- a/config.c +++ b/config.c @@ -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. diff --git a/lib.c b/lib.c index 8124fa1b..19580296 100644 --- a/lib.c +++ b/lib.c @@ -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; +} +char *stat2devnm(struct stat *st) +{ + if ((S_IFMT & st->st_mode) != S_IFBLK) + return NULL; + return devid2devnm(st->st_rdev); } -int fd2devnum(int fd) +char *fd2devnm(int fd) { struct stat stb; if (fstat(fd, &stb) == 0) - return stat2devnum(&stb); - return NoMdDev; + return stat2devnm(&stb); + return NULL; } diff --git a/managemon.c b/managemon.c index f0399b88..d155b042 100644 --- a/managemon.c +++ b/managemon.c @@ -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; diff --git a/mapfile.c b/mapfile.c index 34ebdb54..149f67b2 100644 --- a/mapfile.c +++ b/mapfile.c @@ -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"); diff --git a/mdadm.c b/mdadm.c index f22fd7ba..214afa31 100644 --- a/mdadm.c +++ b/mdadm.c @@ -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) { diff --git a/mdadm.h b/mdadm.h index 7ffac8f9..c7b5183b 100644 --- a/mdadm.h +++ b/mdadm.h @@ -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)) diff --git a/mdmon.c b/mdmon.c index 007071be..fd136e50 100644 --- a/mdmon.c +++ b/mdmon.c @@ -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); } diff --git a/mdmon.h b/mdmon.h index 59e1b537..21cf71d5 100644 --- a/mdmon.h +++ b/mdmon.h @@ -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; }; /* diff --git a/mdopen.c b/mdopen.c index 462743c4..856b5c04 100644 --- a/mdopen.c +++ b/mdopen.c @@ -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); diff --git a/mdstat.c b/mdstat.c index 5f690e5d..9ebfc075 100644 --- a/mdstat.c +++ b/mdstat.c @@ -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; } diff --git a/monitor.c b/monitor.c index c987d107..e034a6a0 100644 --- a/monitor.c +++ b/monitor.c @@ -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); diff --git a/msg.c b/msg.c index 70cefe8f..776b29be 100644 --- a/msg.c +++ b/msg.c @@ -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 diff --git a/msg.h b/msg.h index eefa6495..7306bcab 100644 --- a/msg.h +++ b/msg.h @@ -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); diff --git a/policy.c b/policy.c index c3de692e..48eed6c8 100644 --- a/policy.c +++ b/policy.c @@ -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); } diff --git a/super-ddf.c b/super-ddf.c index 3b3c1f0f..c0fd5fae 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -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; diff --git a/super-intel.c b/super-intel.c index 4c30b7e8..24016b7c 100644 --- a/super-intel.c +++ b/super-intel.c @@ -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; diff --git a/super0.c b/super0.c index bc95fb66..1f4dc750 100644 --- a/super0.c +++ b/super0.c @@ -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; diff --git a/super1.c b/super1.c index 4e380d98..d0f1d5f0 100644 --- a/super1.c +++ b/super1.c @@ -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; diff --git a/sysfs.c b/sysfs.c index b66cebf3..f9fb989d 100644 --- a/sysfs.c +++ b/sysfs.c @@ -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; diff --git a/util.c b/util.c index 8817a3e2..a5eb8ed5 100644 --- a/util.c +++ b/util.c @@ -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);