From 948fb73b04fa9b0f9a9e81e08040b79b65826a16 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Sun, 8 Nov 2015 11:48:28 +0000 Subject: New upstream release. --- ANNOUNCE-3.3.3 | 18 + ANNOUNCE-3.3.4 | 37 ++ Assemble.c | 152 ++++--- Build.c | 3 +- Create.c | 45 +-- Detail.c | 8 +- Grow.c | 291 ++++++------- Incremental.c | 88 ++-- Makefile | 14 +- Manage.c | 136 ++++--- Monitor.c | 94 +++-- ReadMe.c | 10 +- bitmap.c | 12 +- config.c | 22 +- debian/changelog | 6 + external-reshape-design.txt | 10 +- inventory | 3 + managemon.c | 48 ++- md.4 | 6 +- mdadm.8.in | 31 +- mdadm.c | 115 ++---- mdadm.conf-example | 4 +- mdadm.conf.5 | 2 +- mdadm.h | 25 +- mdadm.spec | 2 +- mdassemble.8 | 6 +- mdassemble.c | 14 +- mdmon.8 | 2 +- mdmon.c | 2 + mdmon.h | 3 +- mdopen.c | 15 +- mdstat.c | 4 +- misc/mdcheck | 3 +- monitor.c | 25 +- msg.c | 4 +- platform-intel.c | 348 +++++++++++----- platform-intel.h | 39 +- policy.c | 9 +- raid6check.c | 315 +++++++++------ restripe.c | 48 ++- sha1.h | 8 +- super-ddf.c | 206 ++++------ super-gpt.c | 3 +- super-intel.c | 785 +++++++++++++++++++----------------- super-mbr.c | 6 +- super0.c | 9 +- super1.c | 22 +- sysfs.c | 21 +- systemd/mdmonitor.service | 5 +- test | 65 ++- tests/00linear | 2 +- tests/00raid0 | 16 +- tests/00raid1 | 8 +- tests/00raid4 | 4 +- tests/00raid5 | 8 +- tests/00raid6 | 4 +- tests/01r1fail | 10 +- tests/01r5fail | 10 +- tests/01r5integ | 2 +- tests/01raid6integ | 4 +- tests/02r1add | 8 +- tests/02r1grow | 4 +- tests/02r5grow | 4 +- tests/02r6grow | 4 +- tests/03r0assem | 48 +-- tests/03r5assem | 46 +-- tests/04r0update | 6 +- tests/04r1update | 6 +- tests/04update-metadata | 2 +- tests/05r1-add-internalbitmap-v1b | 2 +- tests/05r1-add-internalbitmap-v1c | 2 +- tests/05r1-bitmapfile | 6 +- tests/05r1-grow-external | 2 +- tests/05r1-grow-internal | 2 +- tests/05r1-grow-internal-1 | 2 +- tests/05r1-internalbitmap | 6 +- tests/05r1-internalbitmap-v1a | 6 +- tests/05r1-internalbitmap-v1b | 6 +- tests/05r1-internalbitmap-v1c | 6 +- tests/05r1-n3-bitmapfile | 6 +- tests/05r1-re-add | 7 +- tests/05r1-re-add-nosuper | 1 + tests/05r6tor0 | 10 +- tests/07changelevelintr | 3 +- tests/07changelevels | 5 +- tests/07layouts | 4 +- tests/07reshape5intr | 2 +- tests/07revert-inplace | 6 +- tests/09imsm-assemble | 6 +- tests/09imsm-create-fail-rebuild | 2 +- tests/10ddf-assemble-missing | 6 +- tests/10ddf-create | 2 +- tests/10ddf-create-fail-rebuild | 2 +- tests/10ddf-fail-readd | 4 +- tests/10ddf-fail-readd-readonly | 2 +- tests/10ddf-fail-stop-readd | 8 +- tests/10ddf-fail-twice | 4 +- tests/10ddf-fail-two-spares | 8 +- tests/10ddf-incremental-wrong-order | 16 +- tests/10ddf-sudden-degraded | 2 +- tests/18imsm-1d-takeover-r0_1d | 3 +- tests/18imsm-1d-takeover-r1_2d | 3 +- tests/18imsm-r1_2d-takeover-r0_1d | 2 +- tests/19raid6auto-repair | 2 - tests/19raid6check | 27 ++ tests/19raid6repair | 2 +- tests/19repair-does-not-destroy | 1 - tests/ToTest | 4 +- tests/imsm-grow-template | 10 +- udev-md-raid-arrays.rules | 8 +- udev-md-raid-assembly.rules | 2 +- util.c | 29 +- xmalloc.c | 28 +- 113 files changed, 1983 insertions(+), 1629 deletions(-) create mode 100644 ANNOUNCE-3.3.3 create mode 100644 ANNOUNCE-3.3.4 create mode 100644 tests/19raid6check diff --git a/ANNOUNCE-3.3.3 b/ANNOUNCE-3.3.3 new file mode 100644 index 00000000..ac1b2173 --- /dev/null +++ b/ANNOUNCE-3.3.3 @@ -0,0 +1,18 @@ +Subject: ANNOUNCE: mdadm 3.3.3 - A tool for managing md Soft RAID under Linux + +I am pleased to announce the availability of + mdadm version 3.3.3 + +It is available at the usual places: + http://www.kernel.org/pub/linux/utils/raid/mdadm/ +and via git at + git://github.com/neilbrown/mdadm + git://neil.brown.name/mdadm + http://git.neil.brown.name/git/mdadm.git + +The 100 changes since 3.3.3 are mostly little bugfixes and some improvements +to the selftests. +raid6check now handle all RAID6 layouts including DDF correctly. +See git log for the rest. + +NeilBrown 24th July 2015 diff --git a/ANNOUNCE-3.3.4 b/ANNOUNCE-3.3.4 new file mode 100644 index 00000000..52b94562 --- /dev/null +++ b/ANNOUNCE-3.3.4 @@ -0,0 +1,37 @@ +Subject: ANNOUNCE: mdadm 3.3.4 - A tool for managing md Soft RAID under Linux + +I am somewhat disappointed to have to announce the availability of + mdadm version 3.3.4 + +It is available at the usual places: + http://www.kernel.org/pub/linux/utils/raid/mdadm/ +and via git at + git://github.com/neilbrown/mdadm + git://neil.brown.name/mdadm + http://git.neil.brown.name/git/mdadm.git + +In mdadm-3.3 a change was made to how IMSM (Intel Matrix Storage +Manager) metadata was handled. Previously an IMSM array would only +be assembled if it was attached to an IMSM controller. + +In 3.3 this was relaxed as there are circumstances where the +controller is not properly detected. Unfortunately this has negative +consequences which have only just come to light. + +If you have an IMSM RAID1 configured and then disable RAID in the +BIOS, the metadata will remain on the devices. If you then install +some other OS on one device and then install Linux on the other, Linux +might eventually start noticing the IMSM metadata (depending a bit on whether +mdadm is included in the initramfs) and might start up the RAID1. This could +copy one device over the other, thus trashing one of the installations. + +Not good. + +So with this release IMSM arrays will only be assembled if attached to +an IMSM controller, or if "--force" is given to --assemble, or if the +environment variable IMSM_NO_PLATFORM is set (used primarily for +testing). + +I strongly recommend upgrading to 3.3.4 if you are using 3.3 or later. + +NeilBrown 3rd August 2015. diff --git a/Assemble.c b/Assemble.c index cdcdb0f8..29257330 100644 --- a/Assemble.c +++ b/Assemble.c @@ -25,21 +25,27 @@ #include "mdadm.h" #include -static int name_matches(char *found, char *required, char *homehost) +static int name_matches(char *found, char *required, char *homehost, int require_homehost) { /* See if the name found matches the required name, possibly * prefixed with 'homehost' */ - char fnd[33]; + char *sep; + unsigned int l; - strncpy(fnd, found, 32); - fnd[32] = 0; if (strcmp(found, required)==0) return 1; - if (homehost) { - int l = strlen(homehost); - if (l < 32 && fnd[l] == ':' && - strcmp(fnd+l+1, required)==0) + sep = strchr(found, ':'); + if (!sep) + return 0; + l = sep - found; + if (strncmp(found, "any:", 4) == 0 || + (homehost && strcmp(homehost, "any") == 0) || + !require_homehost || + (homehost && strlen(homehost) == l && + strncmp(found, homehost, l) == 0)) { + /* matching homehost */ + if (strcmp(sep+1, required) == 0) return 1; } return 0; @@ -73,7 +79,7 @@ static int is_member_busy(char *metadata_version) static int ident_matches(struct mddev_ident *ident, struct mdinfo *content, struct supertype *tst, - char *homehost, + char *homehost, int require_homehost, char *update, char *devname) { @@ -85,7 +91,7 @@ static int ident_matches(struct mddev_ident *ident, return 0; } if (ident->name[0] && (!update || strcmp(update, "name")!= 0) && - name_matches(content->name, ident->name, homehost)==0) { + name_matches(content->name, ident->name, homehost, require_homehost)==0) { if (devname) pr_err("%s has wrong name.\n", devname); return 0; @@ -233,8 +239,7 @@ static int select_devices(struct mddev_dev *devlist, !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 " - "auto-assembly is disabled\n", + pr_err("%s has metadata type %s for which auto-assembly is disabled\n", devname, tst->ss->name); tmpdev->used = 2; } else @@ -245,7 +250,9 @@ static int select_devices(struct mddev_dev *devlist, pr_err("no recogniseable superblock on %s\n", devname); tmpdev->used = 2; - } else if (tst->ss->load_super(tst,dfd, NULL)) { + } else if ((tst->ignore_hw_compat = 0), + tst->ss->load_super(tst, dfd, + report_mismatch ? devname : NULL)) { if (report_mismatch) pr_err("no RAID superblock on %s\n", devname); @@ -259,8 +266,7 @@ static int select_devices(struct mddev_dev *devlist, !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 " - "auto-assembly is disabled\n", + pr_err("%s has metadata type %s for which auto-assembly is disabled\n", devname, tst->ss->name); tmpdev->used = 2; } @@ -327,7 +333,8 @@ static int select_devices(struct mddev_dev *devlist, content = content->next) { if (!ident_matches(ident, content, tst, - c->homehost, c->update, + c->homehost, c->require_homehost, + c->update, report_mismatch ? devname : NULL)) /* message already printed */; else if (is_member_busy(content->text_version)) { @@ -350,8 +357,7 @@ static int select_devices(struct mddev_dev *devlist, st = tst; tst = NULL; if (!auto_assem && inargv && tmpdev->next != NULL) { - pr_err("%s is a container, but is not " - "only device given: confused and aborting\n", + pr_err("%s is a container, but is not only device given: confused and aborting\n", devname); st->ss->free_super(st); dev_policy_free(pol); @@ -370,7 +376,8 @@ static int select_devices(struct mddev_dev *devlist, tst->ss->getinfo_super(tst, content, NULL); if (!ident_matches(ident, content, tst, - c->homehost, c->update, + c->homehost, c->require_homehost, + c->update, report_mismatch ? devname : NULL)) goto loop; @@ -394,7 +401,8 @@ static int select_devices(struct mddev_dev *devlist, goto loop; } if (match && !ident_matches(match, content, tst, - c->homehost, c->update, + c->homehost, c->require_homehost, + c->update, report_mismatch ? devname : NULL)) /* Array exists in mdadm.conf but some * details don't match, so reject it @@ -579,13 +587,13 @@ static int load_devices(struct devs *devices, char *devmap, struct stat stb; struct supertype *tst; int i; + int dfd; if (tmpdev->used != 1) continue; /* looks like a good enough match to update the super block if needed */ #ifndef MDASSEMBLE if (c->update) { - int dfd; /* prepare useful information in info structures */ struct stat stb2; int err; @@ -636,8 +644,7 @@ static int load_devices(struct devs *devices, char *devmap, c->homehost); if (err < 0) { if (err == -1) - pr_err("--update=%s not understood" - " for %s metadata\n", + pr_err("--update=%s not understood for %s metadata\n", c->update, tst->ss->name); tst->ss->free_super(tst); free(tst); @@ -656,7 +663,6 @@ static int load_devices(struct devs *devices, char *devmap, if (tst->ss->store_super(tst, dfd)) pr_err("Could not re-write superblock on %s.\n", devname); - close(dfd); if (strcmp(c->update, "uuid")==0 && ident->bitmap_fd >= 0 && !bitmap_done) { @@ -670,9 +676,9 @@ static int load_devices(struct devs *devices, char *devmap, } else #endif { - int dfd = dev_open(devname, - tmpdev->disposition == 'I' - ? O_RDWR : (O_RDWR|O_EXCL)); + dfd = dev_open(devname, + tmpdev->disposition == 'I' + ? O_RDWR : (O_RDWR|O_EXCL)); tst = dup_super(st); if (dfd < 0 || tst->ss->load_super(tst, dfd, NULL) != 0) { @@ -689,10 +695,10 @@ static int load_devices(struct devs *devices, char *devmap, return -1; } tst->ss->getinfo_super(tst, content, devmap + devcnt * content->array.raid_disks); - close(dfd); } - stat(devname, &stb); + fstat(dfd, &stb); + close(dfd); if (c->verbose > 0) pr_err("%s is identified as a member of %s, slot %d%s.\n", @@ -762,12 +768,9 @@ static int load_devices(struct devs *devices, char *devmap, * Could be a mis-detection caused by overlapping * partitions. fail-safe. */ - pr_err("WARNING %s and %s appear" - " to have very similar superblocks.\n" - " If they are really different, " - "please --zero the superblock on one\n" - " If they are the same or overlap," - " please remove one from %s.\n", + pr_err("WARNING %s and %s appear to have very similar superblocks.\n" + " If they are really different, please --zero the superblock on one\n" + " If they are the same or overlap, please remove one from %s.\n", devices[best[i]].devname, devname, inargv ? "the list" : "the\n DEVICE list in mdadm.conf" @@ -825,12 +828,37 @@ static int force_array(struct mdinfo *content, i < content->array.raid_disks * 2 && i < bestcnt; i += 2) { int j = best[i]; - if (j>=0 && - !devices[j].uptodate && - devices[j].i.recovery_start == MaxSector && - (chosen_drive < 0 || + if (j < 0) + continue; + if (devices[j].uptodate) + continue; + if (devices[j].i.recovery_start != MaxSector) { + int delta; + if (!devices[j].i.reshape_active || + devices[j].i.delta_disks <= 0) + continue; + /* When increasing number of devices, an + * added device also appears to be + * recovering. It is safe to include it + * as long as it won't be a source of + * data. + * For now, just allow for last data + * devices in RAID4 or last devices in RAID4/5/6. + */ + delta = devices[j].i.delta_disks; + if (devices[j].i.array.level >= 4 && + devices[j].i.array.level <= 6 && + i/2 >= content->array.raid_disks - delta) + /* OK */; + else if (devices[j].i.array.level == 4 && + i/2 >= content->array.raid_disks - delta - 1) + /* OK */; + else + continue; + } + if (chosen_drive < 0 || devices[j].i.events - > devices[chosen_drive].i.events)) + > devices[chosen_drive].i.events) chosen_drive = j; } if (chosen_drive < 0) @@ -968,8 +996,7 @@ static int start_array(int mdfd, rv = add_disk(mdfd, st, content, &devices[j].i); if (rv) { - pr_err("failed to add " - "%s to %s: %s\n", + pr_err("failed to add %s to %s: %s\n", devices[j].devname, mddev, strerror(errno)); @@ -993,13 +1020,12 @@ static int start_array(int mdfd, } else if (c->verbose > 0 && i < content->array.raid_disks*2 && (i&1) == 0) pr_err("no uptodate device for slot %d of %s\n", - i, mddev); + i/2, mddev); } if (content->array.level == LEVEL_CONTAINER) { if (c->verbose >= 0) { - pr_err("Container %s has been " - "assembled with %d drive%s", + pr_err("Container %s has been assembled with %d drive%s", mddev, okcnt+sparecnt, okcnt+sparecnt==1?"":"s"); if (okcnt < (unsigned)content->array.raid_disks) fprintf(stderr, " (out of %d)", @@ -1094,12 +1120,16 @@ static int start_array(int mdfd, /* might need to increase the size * of the stripe cache - default is 256 */ - if (256 < 4 * (content->array.chunk_size/4096)) { + int chunk_size = content->array.chunk_size; + if (content->reshape_active && + content->new_chunk > chunk_size) + chunk_size = content->new_chunk; + if (256 < 4 * ((chunk_size+4065)/4096)) { struct mdinfo *sra = sysfs_read(mdfd, NULL, 0); if (sra) sysfs_set_num(sra, NULL, "stripe_cache_size", - (4 * content->array.chunk_size / 4096) + 1); + (4 * chunk_size / 4096) + 1); sysfs_free(sra); } } @@ -1141,15 +1171,12 @@ static int start_array(int mdfd, if (!enough(content->array.level, content->array.raid_disks, content->array.layout, 1, avail)) - pr_err("Not enough devices to " - "start the array.\n"); + pr_err("Not enough devices to start the array.\n"); else if (!enough(content->array.level, content->array.raid_disks, content->array.layout, clean, avail)) - pr_err("Not enough devices to " - "start the array while not clean " - "- consider --force.\n"); + pr_err("Not enough devices to start the array while not clean - consider --force.\n"); return 1; } @@ -1174,9 +1201,7 @@ static int start_array(int mdfd, content->array.raid_disks, content->array.layout, clean, avail)) - fprintf(stderr, " - not enough to start the " - "array while not clean - consider " - "--force.\n"); + fprintf(stderr, " - not enough to start the array while not clean - consider --force.\n"); else { if (req_cnt == (unsigned)content->array.raid_disks) fprintf(stderr, " - need all %d to start it", req_cnt); @@ -1314,7 +1339,7 @@ try_again: mddev ? mddev : "further assembly"); content = &info; - if (st) + if (st && c->force) st->ignore_hw_compat = 1; num_devs = select_devices(devlist, ident, &st, &content, c, inargv, auto_assem); @@ -1338,7 +1363,10 @@ try_again: */ if (map_lock(&map)) pr_err("failed to get exclusive lock on mapfile - continue anyway...\n"); - mp = map_by_uuid(&map, content->uuid); + if (c->update && strcmp(c->update,"uuid") == 0) + mp = NULL; + else + mp = map_by_uuid(&map, content->uuid); if (mp) { struct mdinfo *dv; /* array already exists. */ @@ -1541,9 +1569,7 @@ try_again: if (i < content->array.raid_disks * 2) { if (devices[j].i.recovery_start == MaxSector || (content->reshape_active && - ((i >= content->array.raid_disks - content->delta_disks) || - (i >= content->array.raid_disks - content->delta_disks - 1 - && content->array.level == 4)))) { + i >= content->array.raid_disks - content->delta_disks)) { if (!avail[i/2]) { okcnt++; avail[i/2]=1; @@ -1698,8 +1724,7 @@ try_again: int err = 0; int *fdlist = xmalloc(sizeof(int)* bestcnt); if (c->verbose > 0) - pr_err(":%s has an active reshape - checking " - "if critical section needs to be restored\n", + pr_err("%s has an active reshape - checking if critical section needs to be restored\n", chosen_name); if (!c->backup_file) c->backup_file = locate_backup(content->sys_name); @@ -1727,8 +1752,7 @@ try_again: c->backup_file, c->verbose > 0); if (err && c->invalid_backup) { if (c->verbose > 0) - pr_err("continuing" - " without restoring backup\n"); + pr_err("continuing without restoring backup\n"); err = 0; } } diff --git a/Build.c b/Build.c index da64dc89..8603c710 100644 --- a/Build.c +++ b/Build.c @@ -254,8 +254,7 @@ int Build(char *mddev, struct mddev_dev *devlist, pr_err("RUN_ARRAY failed: %s\n", strerror(errno)); if (s->chunk & (s->chunk-1)) { - cont_err("Problem may be that chunk size" - " is not a power of 2\n"); + cont_err("Problem may be that chunk size is not a power of 2\n"); } goto abort; } diff --git a/Create.c b/Create.c index 330c5b42..ef28da0c 100644 --- a/Create.c +++ b/Create.c @@ -177,8 +177,7 @@ int Create(struct supertype *st, char *mddev, close(fd); } if (st && st->ss->external && s->sparedisks) { - pr_err("This metadata type does not support " - "spare disks at create time\n"); + pr_err("This metadata type does not support spare disks at create time\n"); return 1; } if (subdevs > s->raiddisks+s->sparedisks) { @@ -261,8 +260,7 @@ int Create(struct supertype *st, char *mddev, if (do_default_chunk) { /* default chunk was just set */ if (c->verbose > 0) - pr_err("chunk size " - "defaults to %dK\n", s->chunk); + pr_err("chunk size defaults to %dK\n", s->chunk); s->size &= ~(unsigned long long)(s->chunk - 1); do_default_chunk = 0; } @@ -375,8 +373,7 @@ int Create(struct supertype *st, char *mddev, dname, strerror(errno)); exit(2); } - pr_err("device %s not suitable " - "for any style of array\n", + pr_err("device %s not suitable for any style of array\n", dname); exit(2); } @@ -393,8 +390,7 @@ int Create(struct supertype *st, char *mddev, dname, &freesize, c->verbose >= 0)) { - pr_err("%s is not suitable for " - "this array.\n", + pr_err("%s is not suitable for this array.\n", dname); fail = 1; continue; @@ -408,8 +404,7 @@ int Create(struct supertype *st, char *mddev, if (do_default_chunk) { /* default chunk was just set */ if (c->verbose > 0) - pr_err("chunk size " - "defaults to %dK\n", s->chunk); + pr_err("chunk size defaults to %dK\n", s->chunk); s->size &= ~(unsigned long long)(s->chunk - 1); do_default_chunk = 0; } @@ -421,8 +416,7 @@ int Create(struct supertype *st, char *mddev, } if (s->size && freesize < s->size) { - pr_err("%s is smaller than given size." - " %lluK < %lluK + metadata\n", + pr_err("%s is smaller than given size. %lluK < %lluK + metadata\n", dname, freesize, s->size); fail = 1; continue; @@ -473,8 +467,7 @@ int Create(struct supertype *st, char *mddev, } } if (s->raiddisks + s->sparedisks > st->max_devs) { - pr_err("Too many devices:" - " %s metadata only supports %d\n", + pr_err("Too many devices: %s metadata only supports %d\n", st->ss->name, st->max_devs); return 1; } @@ -618,8 +611,7 @@ int Create(struct supertype *st, char *mddev, memset(&inf, 0, sizeof(inf)); ioctl(mdfd, GET_ARRAY_INFO, &inf); if (inf.working_disks != 0) { - pr_err("another array by this name" - " is already running.\n"); + pr_err("another array by this name is already running.\n"); goto abort_locked; } } @@ -741,8 +733,7 @@ int Create(struct supertype *st, char *mddev, mdi?mdi->text_version:"managed", devnm); sysfs_free(mdi); } else - pr_err("Defaulting to version" - " %s metadata\n", info.text_version); + pr_err("Defaulting to version %s metadata\n", info.text_version); } map_update(&map, fd2devnm(mdfd), info.text_version, @@ -797,14 +788,12 @@ int Create(struct supertype *st, char *mddev, */ container_fd = open_dev_excl(st->container_devnm); if (container_fd < 0) { - pr_err("Cannot get exclusive " - "open on container - weird.\n"); + pr_err("Cannot get exclusive open on container - weird.\n"); goto abort_locked; } if (mdmon_running(st->container_devnm)) { if (c->verbose) - pr_err("reusing mdmon " - "for %s.\n", + pr_err("reusing mdmon for %s.\n", st->container_devnm); st->update_tail = &st->updates; } else @@ -890,8 +879,7 @@ int Create(struct supertype *st, char *mddev, fd = open(dv->devname, O_RDWR|O_EXCL); if (fd < 0) { - pr_err("failed to open %s " - "after earlier success - aborting\n", + pr_err("failed to open %s after earlier success - aborting\n", dv->devname); goto abort_locked; } @@ -928,8 +916,7 @@ int Create(struct supertype *st, char *mddev, rv = add_disk(mdfd, st, &info, inf); if (rv) { - pr_err("ADD_NEW_DISK for %s " - "failed: %s\n", + pr_err("ADD_NEW_DISK for %s failed: %s\n", dv->devname, strerror(errno)); goto abort_locked; } @@ -1007,8 +994,7 @@ int Create(struct supertype *st, char *mddev, } sysfs_set_safemode(&info, safe_mode_delay); if (err) { - pr_err("failed to" - " activate array.\n"); + pr_err("failed to activate array.\n"); ioctl(mdfd, STOP_ARRAY, NULL); goto abort; } @@ -1029,8 +1015,7 @@ int Create(struct supertype *st, char *mddev, pr_err("RUN_ARRAY failed: %s\n", strerror(errno)); if (info.array.chunk_size & (info.array.chunk_size-1)) { - cont_err("Problem may be that " - "chunk size is not a power of 2\n"); + cont_err("Problem may be that chunk size is not a power of 2\n"); } ioctl(mdfd, STOP_ARRAY, NULL); goto abort; diff --git a/Detail.c b/Detail.c index c4fcad96..dd72eded 100644 --- a/Detail.c +++ b/Detail.c @@ -295,8 +295,8 @@ int Detail(char *dev, struct context *c) goto out; } - disks = xmalloc(max_disks * sizeof(mdu_disk_info_t)); - for (d = 0; d < max_disks; d++) { + disks = xmalloc(max_disks * 2 * sizeof(mdu_disk_info_t)); + for (d = 0; d < max_disks * 2; d++) { disks[d].state = (1<= 0 && disk.raid_disk < array.raid_disks && disks[disk.raid_disk*2+1].state == (1<ss->add_internal_bitmap == NULL) { - pr_err("Internal bitmaps not supported " - "with %s metadata\n", st->ss->name); + pr_err("Internal bitmaps not supported with %s metadata\n", st->ss->name); return 1; } mdi = sysfs_read(fd, NULL, GET_BITMAP_LOCATION); @@ -417,8 +412,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) ) st->ss->write_bitmap(st, fd2); else { - pr_err("failed to create internal bitmap" - " - chunksize problem.\n"); + pr_err("failed to create internal bitmap - chunksize problem.\n"); close(fd2); return 1; } @@ -437,8 +431,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) } if (rv < 0) { if (errno == EBUSY) - pr_err("Cannot add bitmap while array is" - " resyncing or reshaping etc.\n"); + pr_err("Cannot add bitmap while array is resyncing or reshaping etc.\n"); pr_err("failed to set internal bitmap.\n"); return 1; } @@ -489,8 +482,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) if (ioctl(fd, SET_BITMAP_FILE, bitmap_fd) < 0) { int err = errno; if (errno == EBUSY) - pr_err("Cannot add bitmap while array is" - " resyncing or reshaping etc.\n"); + pr_err("Cannot add bitmap while array is resyncing or reshaping etc.\n"); pr_err("Cannot set bitmap file for %s: %s\n", devname, strerror(err)); return 1; @@ -620,10 +612,8 @@ static void unfreeze(struct supertype *st) if (sra && sysfs_get_str(sra, NULL, "sync_action", buf, 20) > 0 - && strcmp(buf, "frozen\n") == 0) { - printf("unfreeze\n"); + && strcmp(buf, "frozen\n") == 0) sysfs_set_str(sra, NULL, "sync_action", "idle"); - } sysfs_free(sra); } } @@ -726,9 +716,14 @@ int start_reshape(struct mdinfo *sra, int already_running, if (!already_running) sysfs_set_num(sra, NULL, "sync_min", sync_max_to_set); err = err ?: sysfs_set_num(sra, NULL, "sync_max", sync_max_to_set); - if (!already_running) - err = err ?: sysfs_set_str(sra, NULL, "sync_action", "reshape"); - + if (!already_running && err == 0) { + int cnt = 5; + do { + err = sysfs_set_str(sra, NULL, "sync_action", "reshape"); + if (err) + sleep(1); + } while (err && errno == EBUSY && cnt-- > 0); + } return err; } @@ -853,7 +848,8 @@ int reshape_prepare_fdlist(char *devname, for (sd = sra->devs; sd; sd = sd->next) { if (sd->disk.state & (1<disk.state & (1<disk.state & (1<disk.raid_disk < raid_disks) { char *dn = map_dev(sd->disk.major, sd->disk.minor, 1); fdlist[sd->disk.raid_disk] @@ -917,8 +913,7 @@ int reshape_open_backup_file(char *backup_file, dev = stb.st_dev; fstat(fd, &stb); if (stb.st_rdev == dev) { - pr_err("backup file must NOT be" - " on the array being reshaped.\n"); + pr_err("backup file must NOT be on the array being reshaped.\n"); close(*fdlist); return 0; } @@ -926,8 +921,7 @@ int reshape_open_backup_file(char *backup_file, memset(buf, 0, 512); for (i=0; i < blocks + 8 ; i++) { if (write(*fdlist, buf, 512) != 512) { - pr_err("%s: cannot create" - " backup file %s: %s\n", + pr_err("%s: cannot create backup file %s: %s\n", devname, backup_file, strerror(errno)); return 0; } @@ -941,7 +935,7 @@ int reshape_open_backup_file(char *backup_file, if (!restart && strncmp(backup_file, MAP_DIR, strlen(MAP_DIR)) != 0) { char *bu = make_backup(sys_name); if (symlink(backup_file, bu)) - pr_err("Recording backup file in " MAP_DIR "failed: %s\n", + pr_err("Recording backup file in " MAP_DIR " failed: %s\n", strerror(errno)); free(bu); } @@ -1041,13 +1035,11 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) */ if (info->new_level > 1 && (info->component_size & 7)) - return "Cannot convert RAID1 of this size - " - "reduce size to multiple of 4K first."; + return "Cannot convert RAID1 of this size - reduce size to multiple of 4K first."; if (info->new_level == 0) { if (info->delta_disks != UnSet && info->delta_disks != 0) - return "Cannot change number of disks " - "with RAID1->RAID0 conversion"; + return "Cannot change number of disks with RAID1->RAID0 conversion"; re->level = 0; re->before.data_disks = 1; re->after.data_disks = 1; @@ -1133,8 +1125,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) if (far > 1 && !offset) return "Cannot reshape RAID10 to far-mode"; if (near * far != copies) - return "Cannot change number of copies" - " when reshaping RAID10"; + return "Cannot change number of copies when reshaping RAID10"; } if (info->delta_disks == UnSet) info->delta_disks = 0; @@ -1184,15 +1175,13 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) / info->array.raid_disks); if (info->array.raid_disks * (copies-1) != info->delta_disks) - return "Impossible number of devices" - " for RAID0->RAID10"; + return "Impossible number of devices for RAID0->RAID10"; info->new_layout = 0x100 + copies; } if (info->delta_disks == UnSet) { int copies = info->new_layout & 0xff; if (info->new_layout != 0x100 + copies) - return "New layout impossible" - " for RAID0->RAID10";; + return "New layout impossible for RAID0->RAID10";; info->delta_disks = (copies - 1) * info->array.raid_disks; } @@ -1287,8 +1276,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) return "Can only convert a 2-device array to RAID1"; if (info->delta_disks != UnSet && info->delta_disks != 0) - return "Cannot set raid_disk when " - "converting RAID5->RAID1"; + return "Cannot set raid_disk when converting RAID5->RAID1"; re->level = 1; info->new_chunk = 0; return NULL; @@ -1383,8 +1371,7 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) strcat(strcpy(layout, ls), "-6"); l = map_name(r6layout, layout); if (l == UnSet) - return "Cannot find RAID6 layout" - " to convert to"; + return "Cannot find RAID6 layout to convert to"; } else { /* Current RAID6 has no equivalent. * If it is already a '-6' layout we @@ -1496,8 +1483,8 @@ static int set_array_size(struct supertype *st, struct mdinfo *sra, ret_val = 0; dprintf("Array size changed"); } - dprintf(" from %llu to %llu.\n", - current_size, new_size); + dprintf_cont(" from %llu to %llu.\n", + current_size, new_size); } sysfs_free(info); } else @@ -1571,10 +1558,8 @@ int Grow_reshape(char *devname, int fd, if (s->size > 0 && (s->chunk || s->level!= UnSet || s->layout_str || s->raiddisks)) { - pr_err("cannot change component size at the same time " - "as other changes.\n" - " Change size first, then check data is intact before " - "making other changes.\n"); + pr_err("cannot change component size at the same time as other changes.\n" + " Change size first, then check data is intact before making other changes.\n"); return 1; } @@ -1592,8 +1577,7 @@ int Grow_reshape(char *devname, int fd, return 1; } if (s->raiddisks > st->max_devs) { - pr_err("Cannot increase raid-disks on this array" - " beyond %d\n", st->max_devs); + pr_err("Cannot increase raid-disks on this array beyond %d\n", st->max_devs); return 1; } @@ -1647,9 +1631,7 @@ int Grow_reshape(char *devname, int fd, & (1<raiddisks > array.raid_disks && array.spare_disks +added_disks < (s->raiddisks - array.raid_disks) && !c->force) { - pr_err("Need %d spare%s to avoid degraded array," - " and only have %d.\n" + pr_err("Need %d spare%s to avoid degraded array, and only have %d.\n" " Use --force to over-ride this check.\n", s->raiddisks - array.raid_disks, s->raiddisks - array.raid_disks == 1 ? "" : "s", @@ -1695,8 +1676,7 @@ int Grow_reshape(char *devname, int fd, sysfs_free(sra); return 1; } else if (frozen < 0) { - pr_err("%s is performing resync/recovery and cannot" - " be reshaped\n", devname); + pr_err("%s is performing resync/recovery and cannot be reshaped\n", devname); sysfs_free(sra); return 1; } @@ -1737,8 +1717,7 @@ int Grow_reshape(char *devname, int fd, sizeinfo->array.layout, sizeinfo->array.raid_disks); new_size /= data_disks; - dprintf("Metadata size correction from %llu to " - "%llu (%llu)\n", orig_size, new_size, + dprintf("Metadata size correction from %llu to %llu (%llu)\n", orig_size, new_size, new_size * data_disks); s->size = new_size; sysfs_free(sizeinfo); @@ -1775,13 +1754,11 @@ int Grow_reshape(char *devname, int fd, } } if (rv) { - pr_err("Cannot set size on " - "array members.\n"); + pr_err("Cannot set size on array members.\n"); goto size_change_error; } if (min_csize && s->size > min_csize) { - pr_err("Cannot safely make this array " - "use more than 2TB per device on this kernel.\n"); + pr_err("Cannot safely make this array use more than 2TB per device on this kernel.\n"); rv = 1; goto size_change_error; } @@ -1789,8 +1766,7 @@ int Grow_reshape(char *devname, int fd, /* Don't let the kernel choose a size - it will get * it wrong */ - pr_err("Limited v0.90 array to " - "2TB per device\n"); + pr_err("Limited v0.90 array to 2TB per device\n"); s->size = min_csize; } if (st->ss->external) { @@ -1799,8 +1775,8 @@ int Grow_reshape(char *devname, int fd, "raid5"); if (!rv) { raid0_takeover = 1; - /* get array parametes after takeover - * to chane one parameter at time only + /* get array parameters after takeover + * to change one parameter at time only */ rv = ioctl(fd, GET_ARRAY_INFO, &array); } @@ -1818,7 +1794,7 @@ int Grow_reshape(char *devname, int fd, if (s->size == MAX_SIZE) s->size = 0; array.size = s->size; - if (array.size != (signed)s->size) { + if (s->size & ~INT32_MAX) { /* got truncated to 32bit, write to * component_size instead */ @@ -1879,12 +1855,10 @@ size_change_error: s->size = array.size; if (c->verbose >= 0) { if (s->size == orig_size) - pr_err("component size of %s " - "unchanged at %lluK\n", + pr_err("component size of %s unchanged at %lluK\n", devname, s->size); else - pr_err("component size of %s " - "has been set to %lluK\n", + pr_err("component size of %s has been set to %lluK\n", devname, s->size); } changed = 1; @@ -1919,7 +1893,7 @@ size_change_error: int err; err = remove_disks_for_takeover(st, sra, array.layout); if (err) { - dprintf(Name": Array cannot be reshaped\n"); + dprintf("Array cannot be reshaped\n"); if (cfd > -1) close(cfd); rv = 1; @@ -1952,12 +1926,9 @@ size_change_error: if (info.array.level == 6 && (info.new_level == 6 || info.new_level == UnSet) && info.array.layout >= 16) { - pr_err("%s has a non-standard layout. If you" - " wish to preserve this\n", devname); - cont_err("during the reshape, please specify" - " --layout=preserve\n"); - cont_err("If you want to change it, specify a" - " layout or use --layout=normalise\n"); + pr_err("%s has a non-standard layout. If you wish to preserve this\n", devname); + cont_err("during the reshape, please specify --layout=preserve\n"); + cont_err("If you want to change it, specify a layout or use --layout=normalise\n"); rv = 1; goto release; } @@ -1974,8 +1945,7 @@ size_change_error: info.new_layout = map_name(r6layout, l); } } else { - pr_err("%s is only meaningful when reshaping" - " a RAID6 array.\n", s->layout_str); + pr_err("%s is only meaningful when reshaping a RAID6 array.\n", s->layout_str); rv = 1; goto release; } @@ -1997,8 +1967,7 @@ size_change_error: strcat(l, "-6"); info.new_layout = map_name(r6layout, l); } else { - pr_err("%s in only meaningful when reshaping" - " to RAID6\n", s->layout_str); + pr_err("%s in only meaningful when reshaping to RAID6\n", s->layout_str); rv = 1; goto release; } @@ -2020,14 +1989,12 @@ size_change_error: info.new_layout = parse_layout_faulty(s->layout_str); break; default: - pr_err("layout not meaningful" - " with this level\n"); + pr_err("layout not meaningful with this level\n"); rv = 1; goto release; } if (info.new_layout == UnSet) { - pr_err("layout %s not understood" - " for this level\n", + pr_err("layout %s not understood for this level\n", s->layout_str); rv = 1; goto release; @@ -2133,27 +2100,22 @@ static int verify_reshape_position(struct mdinfo *info, int level) char *ep; unsigned long long position = strtoull(buf, &ep, 0); - dprintf(Name": Read sync_max sysfs entry is: %s\n", buf); + dprintf("Read sync_max sysfs entry is: %s\n", buf); if (!(ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' '))) { position *= get_data_disks(level, info->new_layout, info->array.raid_disks); if (info->reshape_progress < position) { - dprintf("Corrected reshape progress (%llu) to " - "md position (%llu)\n", + dprintf("Corrected reshape progress (%llu) to md position (%llu)\n", info->reshape_progress, position); info->reshape_progress = position; ret_val = 1; } else if (info->reshape_progress > position) { - pr_err("Fatal error: array " - "reshape was not properly frozen " - "(expected reshape position is %llu, " - "but reshape progress is %llu.\n", + pr_err("Fatal error: array reshape was not properly frozen (expected reshape position is %llu, but reshape progress is %llu.\n", position, info->reshape_progress); ret_val = -1; } else { - dprintf("Reshape position in md and metadata " - "are the same;"); + dprintf("Reshape position in md and metadata are the same;"); ret_val = 1; } } @@ -2255,7 +2217,10 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st, if (info2.space_before == 0 && info2.space_after == 0) { /* Metadata doesn't support data_offset changes */ - return 1; + if (!can_fallback) + pr_err("%s: Metadata version doesn't support data_offset changes\n", + devname); + goto fallback; } if (before > info2.space_before) before = info2.space_before; @@ -2500,8 +2465,7 @@ static int raid10_reshape(char *container, int fd, char *devname, devname); if (err == EBUSY && (info->array.state & (1<cache_size < cache) subarray_set_num(container, sra, "stripe_cache_size", @@ -2625,8 +2589,7 @@ static int impose_reshape(struct mdinfo *sra, if (err == EBUSY && (array.state & (1<= 0) @@ -2870,8 +2831,7 @@ static int reshape_array(char *container, int fd, char *devname, reshape.before.layout != info->array.layout || reshape.before.data_disks + reshape.parity != info->array.raid_disks - max(0, info->delta_disks))) { - pr_err("reshape info is not in native format -" - " cannot continue.\n"); + pr_err("reshape info is not in native format - cannot continue.\n"); goto release; } @@ -2928,8 +2888,7 @@ static int reshape_array(char *container, int fd, char *devname, if (!force && info->new_level > 1 && info->array.level > 1 && spares_needed > info->array.spare_disks + added_disks) { - pr_err("Need %d spare%s to avoid degraded array," - " and only have %d.\n" + pr_err("Need %d spare%s to avoid degraded array, and only have %d.\n" " Use --force to over-ride this check.\n", spares_needed, spares_needed == 1 ? "" : "s", @@ -2942,8 +2901,7 @@ static int reshape_array(char *container, int fd, char *devname, - array.raid_disks; if ((info->new_level > 1 || info->new_level == 0) && spares_needed > info->array.spare_disks +added_disks) { - pr_err("Need %d spare%s to create working array," - " and only have %d.\n", + pr_err("Need %d spare%s to create working array, and only have %d.\n", spares_needed, spares_needed == 1 ? "" : "s", info->array.spare_disks + added_disks); @@ -3150,8 +3108,19 @@ static int reshape_array(char *container, int fd, char *devname, devname, container, &reshape) < 0) goto release; if (sysfs_set_str(sra, NULL, "sync_action", "reshape") < 0) { - pr_err("Failed to initiate reshape!\n"); - goto release; + struct mdinfo *sd; + if (errno != EINVAL) { + pr_err("Failed to initiate reshape!\n"); + goto release; + } + /* revert data_offset and try the old way */ + for (sd = sra->devs; sd; sd = sd->next) { + sysfs_set_num(sra, sd, "new_offset", + sd->data_offset); + sysfs_set_str(sra, NULL, "reshape_direction", + "forwards"); + } + break; } if (info->new_level == reshape.level) return 0; @@ -3194,12 +3163,10 @@ started: blocks < 16*1024*2) blocks *= 2; } else - pr_err("Need to backup %luK of critical " - "section..\n", blocks/2); + pr_err("Need to backup %luK of critical section..\n", blocks/2); if (blocks >= sra->component_size/2) { - pr_err("%s: Something wrong" - " - reshape aborted\n", + pr_err("%s: Something wrong - reshape aborted\n", devname); goto release; } @@ -3216,7 +3183,7 @@ started: d = reshape_prepare_fdlist(devname, sra, odisks, nrdisks, blocks, backup_file, fdlist, offsets); - if (d < 0) { + if (d < odisks) { goto release; } if ((st->ss->manage_reshape == NULL) || @@ -3228,10 +3195,8 @@ started: devname); pr_err(" Please provide one with \"--backup=...\"\n"); goto release; - } else if (sra->array.spare_disks == 0) { - pr_err("%s: Cannot grow - " - "need a spare or backup-file to backup " - "critical section\n", devname); + } else if (d == odisks) { + pr_err("%s: Cannot grow - need a spare or backup-file to backup critical section\n", devname); goto release; } } else { @@ -3274,8 +3239,7 @@ started: free(fdlist); free(offsets); sysfs_free(sra); - pr_err("Reshape has to be continued from" - " location %llu when root filesystem has been mounted.\n", + pr_err("Reshape has to be continued from location %llu when root filesystem has been mounted.\n", sra->reshape_progress); return 1; } @@ -3372,7 +3336,7 @@ started: bul = make_backup(sra->sys_name); if (bul) { char buf[1024]; - int l = readlink(bul, buf, sizeof(buf)); + int l = readlink(bul, buf, sizeof(buf) - 1); if (l > 0) { buf[l]=0; unlink(buf); @@ -3492,8 +3456,7 @@ int reshape_container(char *container, char *devname, return 1; default: /* parent */ if (!freeze_reshape) - printf(Name ": multi-array reshape continues" - " in background\n"); + printf("%s: multi-array reshape continues in background\n", Name); return 0; case 0: /* child */ map_fork(); @@ -3555,8 +3518,7 @@ int reshape_container(char *container, char *devname, fd = open_dev(mdstat->devnm); if (fd < 0) { - printf(Name ": Device %s cannot be opened for reshape.", - adev); + pr_err("Device %s cannot be opened for reshape.\n", adev); break; } @@ -3571,8 +3533,7 @@ int reshape_container(char *container, char *devname, * This is possibly interim until the behaviour of * reshape_array is resolved(). */ - printf(Name ": Multiple reshape execution detected for " - "device %s.", adev); + printf("%s: Multiple reshape execution detected for device %s.\n", Name, adev); close(fd); break; } @@ -3882,9 +3843,11 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape, * So we need these extra tests. */ if (completed == 0 && advancing + && strncmp(action, "idle", 4) == 0 && info->reshape_progress > 0) break; if (completed == 0 && !advancing + && strncmp(action, "idle", 4) == 0 && info->reshape_progress < (info->component_size * reshape->after.data_disks)) break; @@ -3893,21 +3856,31 @@ int progress_reshape(struct mdinfo *info, struct reshape *reshape, goto check_progress; } /* Some kernels reset 'sync_completed' to zero, - * we need to have real point we are in md + * we need to have real point we are in md. + * So in that case, read 'reshape_position' from sysfs. */ - if (completed == 0) - completed = max_progress; - - /* some kernels can give an incorrectly high 'completed' number */ - completed /= (info->new_chunk/512); - completed *= (info->new_chunk/512); - /* Convert 'completed' back in to a 'progress' number */ - completed *= reshape->after.data_disks; - if (!advancing) { - completed = info->component_size * reshape->after.data_disks - - completed; + if (completed == 0) { + unsigned long long reshapep; + char action[20]; + if (sysfs_get_str(info, NULL, "sync_action", + action, 20) > 0 && + strncmp(action, "idle", 4) == 0 && + sysfs_get_ll(info, NULL, + "reshape_position", &reshapep) == 0) + *reshape_completed = reshapep; + } else { + /* some kernels can give an incorrectly high + * 'completed' number, so round down */ + completed /= (info->new_chunk/512); + completed *= (info->new_chunk/512); + /* Convert 'completed' back in to a 'progress' number */ + completed *= reshape->after.data_disks; + if (!advancing) + completed = (info->component_size + * reshape->after.data_disks + - completed); + *reshape_completed = completed; } - *reshape_completed = completed; close(fd); @@ -3927,7 +3900,6 @@ check_progress: * it was just a device failure that leaves us degraded but * functioning. */ - strcpy(buf, "hi"); if (sysfs_get_str(info, NULL, "reshape_position", buf, sizeof(buf)) < 0 || strncmp(buf, "none", 4) != 0) { /* The abort might only be temporary. Wait up to 10 @@ -4527,8 +4499,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt if (info->array.utime > (int)__le64_to_cpu(bsb.mtime) + 2*60*60 || info->array.utime < (int)__le64_to_cpu(bsb.mtime) - 10*60) { if (check_env("MDADM_GROW_ALLOW_OLD")) { - pr_err("accepting backup with timestamp %lu " - "for array with timestamp %lu\n", + pr_err("accepting backup with timestamp %lu for array with timestamp %lu\n", (unsigned long)__le64_to_cpu(bsb.mtime), (unsigned long)info->array.utime); } else { @@ -4609,7 +4580,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt st->ss->free_super(st); offsets[j] = dinfo.data_offset * 512; } - printf(Name ": restoring critical section\n"); + printf("%s: restoring critical section\n", Name); if (restore_stripes(fdlist, offsets, info->array.raid_disks, @@ -4768,10 +4739,9 @@ int Grow_continue_command(char *devname, int fd, dprintf("Grow continue is run for "); if (st->ss->external == 0) { int d; - dprintf("native array (%s)\n", devname); + dprintf_cont("native array (%s)\n", devname); if (ioctl(fd, GET_ARRAY_INFO, &array.array) < 0) { - pr_err("%s is not an active md array -" - " aborting\n", devname); + pr_err("%s is not an active md array - aborting\n", devname); ret_val = 1; goto Grow_continue_command_exit; } @@ -4816,19 +4786,18 @@ int Grow_continue_command(char *devname, int fd, char *container; if (subarray) { - dprintf("subarray (%s)\n", subarray); + dprintf_cont("subarray (%s)\n", subarray); container = st->container_devnm; cfd = open_dev_excl(st->container_devnm); } else { container = st->devnm; close(fd); cfd = open_dev_excl(st->devnm); - dprintf("container (%s)\n", container); + dprintf_cont("container (%s)\n", container); fd = cfd; } if (cfd < 0) { - pr_err("Unable to open container " - "for %s\n", devname); + pr_err("Unable to open container for %s\n", devname); ret_val = 1; goto Grow_continue_command_exit; } @@ -4864,9 +4833,7 @@ int Grow_continue_command(char *devname, int fd, allow_reshape = 0; if (!allow_reshape) { - pr_err("cannot continue reshape of an array" - " in container with unsupported" - " metadata: %s(%s)\n", + pr_err("cannot continue reshape of an array in container with unsupported metadata: %s(%s)\n", devname, container); ret_val = 1; goto Grow_continue_command_exit; @@ -4886,8 +4853,7 @@ int Grow_continue_command(char *devname, int fd, break; } if (!content) { - pr_err("Unable to determine reshaped " - "array for %s\n", devname); + pr_err("Unable to determine reshaped array for %s\n", devname); ret_val = 1; goto Grow_continue_command_exit; } @@ -4909,8 +4875,7 @@ int Grow_continue_command(char *devname, int fd, if (mdmon_running(container)) st->update_tail = &st->updates; else { - pr_err("No mdmon found. " - "Grow cannot continue.\n"); + pr_err("No mdmon found. Grow cannot continue.\n"); ret_val = 1; goto Grow_continue_command_exit; } diff --git a/Incremental.c b/Incremental.c index c9372587..41876b9e 100644 --- a/Incremental.c +++ b/Incremental.c @@ -130,16 +130,13 @@ int Incremental(struct mddev_dev *devlist, struct context *c, if (must_be_container(dfd)) { if (!st) st = super_by_fd(dfd, NULL); - if (st) - st->ignore_hw_compat = 1; if (st && st->ss->load_container) rv = st->ss->load_container(st, dfd, NULL); close(dfd); if (!rv && st->ss->container_content) { if (map_lock(&map)) - pr_err("failed to get " - "exclusive lock on mapfile\n"); + pr_err("failed to get exclusive lock on mapfile\n"); if (c->export) printf("MD_DEVNAME=%s\n", devname); rv = Incremental_container(st, devname, c, NULL); @@ -196,18 +193,19 @@ int Incremental(struct mddev_dev *devlist, struct context *c, policy = disk_policy(&dinfo); have_target = policy_check_path(&dinfo, &target_array); - if (st == NULL && (st = guess_super(dfd)) == NULL) { + if (st == NULL && (st = guess_super_type(dfd, guess_array)) == NULL) { if (c->verbose >= 0) pr_err("no recognisable superblock on %s.\n", devname); rv = try_spare(devname, &dfd, policy, have_target ? &target_array : NULL, - st, c->verbose); + NULL, c->verbose); goto out; } - st->ignore_hw_compat = 1; + st->ignore_hw_compat = 0; + if (st->ss->compare_super == NULL || - st->ss->load_super(st, dfd, NULL)) { + st->ss->load_super(st, dfd, c->verbose >= 0 ? devname : NULL)) { if (c->verbose >= 0) pr_err("no RAID superblock on %s.\n", devname); @@ -229,8 +227,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, if (match && match->devname && strcasecmp(match->devname, "") == 0) { if (c->verbose >= 0) - pr_err("array containing %s is explicitly" - " ignored by mdadm.conf\n", + pr_err("array containing %s is explicitly ignored by mdadm.conf\n", devname); goto out; } @@ -251,8 +248,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, if (!match && !conf_test_metadata(st->ss->name, policy, (trustworthy == LOCAL))) { if (c->verbose >= 1) - pr_err("%s has metadata type %s for which " - "auto-assembly is disabled\n", + pr_err("%s has metadata type %s for which auto-assembly is disabled\n", devname, st->ss->name); goto out; } @@ -289,8 +285,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, /* 4/ Check if array exists. */ if (map_lock(&map)) - pr_err("failed to get exclusive lock on " - "mapfile\n"); + pr_err("failed to get exclusive lock on mapfile\n"); /* Now check we can get O_EXCL. If not, probably "mdadm -A" has * taken over */ @@ -352,8 +347,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, * So reject it. */ ioctl(mdfd, STOP_ARRAY, NULL); - pr_err("You have an old buggy kernel which cannot support\n" - " --incremental reliably. Aborting.\n"); + pr_err("You have an old buggy kernel which cannot support\n --incremental reliably. Aborting.\n"); rv = 2; goto out_unlock; } @@ -420,8 +414,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c, st2 = dup_super(st); if (st2->ss->load_super(st2, dfd2, NULL) || st->ss->compare_super(st, st2) != 0) { - pr_err("metadata mismatch between %s and " - "chosen array %s\n", + pr_err("metadata mismatch between %s and chosen array %s\n", devname, chosen_name); close(dfd2); rv = 2; @@ -864,8 +857,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, */ if (map_lock(&map)) { - pr_err("failed to get exclusive lock on " - "mapfile\n"); + pr_err("failed to get exclusive lock on mapfile\n"); return 1; } for (mp = map ; mp ; mp = mp->next) { @@ -911,8 +903,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, sra->text_version); if (!st2) { if (verbose > 1) - pr_err("not adding %s to %s" - " as metadata not recognised.\n", + pr_err("not adding %s to %s as metadata not recognised.\n", devname, mp->path); goto next; } @@ -994,8 +985,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol, if (domain_test(dl, pol, st2->ss->name) != 1) { /* domain test fails */ if (verbose > 1) - pr_err("not adding %s to %s as" - " it is not in a compatible domain\n", + pr_err("not adding %s to %s as it is not in a compatible domain\n", devname, mp->path); goto next; @@ -1132,6 +1122,7 @@ static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol, if (st2 == NULL || st2->ss->load_super(st2, fd, NULL) < 0) goto next; + st2->ignore_hw_compat = 0; if (!st) { /* Check domain policy again, this time referring to metadata */ @@ -1267,8 +1258,7 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol, !policy_action_allows(pol, st?st->ss->name:NULL, act_spare_same_slot)) { if (verbose > 1) - pr_err("%s is not bare, so not " - "considering as a spare\n", + pr_err("%s is not bare, so not considering as a spare\n", devname); return 1; } @@ -1359,12 +1349,11 @@ restart: struct supertype *st = super_by_fd(mdfd, NULL); int ret = 0; struct map_ent *map = NULL; - if (st) - st->ignore_hw_compat = 1; + if (st && st->ss->load_container) ret = st->ss->load_container(st, mdfd, NULL); close(mdfd); - if (!ret && st->ss->container_content) { + if (!ret && st && st->ss->container_content) { if (map_lock(&map)) pr_err("failed to get exclusive lock on mapfile\n"); ret = Incremental_container(st, me->path, c, only); @@ -1576,8 +1565,7 @@ static int Incremental_container(struct supertype *st, char *devname, if (match && match->devname && strcasecmp(match->devname, "") == 0) { if (c->verbose > 0) - pr_err("array %s/%s is " - "explicitly ignored by mdadm.conf\n", + pr_err("array %s/%s is explicitly ignored by mdadm.conf\n", match->container, match->member); continue; } @@ -1710,34 +1698,34 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) char buf[32]; if (!id_path) - dprintf(Name ": incremental removal without --path " - "lacks the possibility to re-add new device in this " - "port\n"); + dprintf("incremental removal without --path lacks the possibility to re-add new device in this port\n"); if (strchr(devname, '/')) { - pr_err("incremental removal requires a " - "kernel device name, not a file: %s\n", devname); + pr_err("incremental removal requires a kernel device name, not a file: %s\n", devname); return 1; } ent = mdstat_by_component(devname); if (!ent) { if (verbose >= 0) - pr_err("%s does not appear to be a component " - "of any array\n", devname); + pr_err("%s does not appear to be a component of any array\n", devname); return 1; } sysfs_init(&mdi, -1, ent->devnm); - if (sysfs_get_str(&mdi, NULL, "array_state", - buf, sizeof(buf)) > 0) { - if (strncmp(buf, "active", 6) == 0 || - strncmp(buf, "clean", 5) == 0) - sysfs_set_str(&mdi, NULL, - "array_state", "read-auto"); + mdfd = open_dev_excl(ent->devnm); + if (mdfd > 0) { + close(mdfd); + if (sysfs_get_str(&mdi, NULL, "array_state", + buf, sizeof(buf)) > 0) { + if (strncmp(buf, "active", 6) == 0 || + strncmp(buf, "clean", 5) == 0) + sysfs_set_str(&mdi, NULL, + "array_state", "read-auto"); + } } mdfd = open_dev(ent->devnm); if (mdfd < 0) { if (verbose >= 0) - pr_err("Cannot open array %s!!\n", ent->dev); + pr_err("Cannot open array %s!!\n", ent->devnm); free_mdstat(ent); return 1; } @@ -1759,11 +1747,11 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) struct mdstat_ent *mdstat = mdstat_read(0, 0); struct mdstat_ent *memb; for (memb = mdstat ; memb ; memb = memb->next) - if (is_container_member(memb, ent->dev)) { + if (is_container_member(memb, ent->devnm)) { int subfd = open_dev(memb->devnm); if (subfd >= 0) { rv |= Manage_subdevs( - memb->dev, subfd, + memb->devnm, subfd, &devlist, verbose, 0, NULL, 0); close(subfd); @@ -1771,7 +1759,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) } free_mdstat(mdstat); } else - rv |= Manage_subdevs(ent->dev, mdfd, &devlist, + rv |= Manage_subdevs(ent->devnm, mdfd, &devlist, verbose, 0, NULL, 0); if (rv & 2) { /* Failed due to EBUSY, try to stop the array. @@ -1779,7 +1767,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) */ int devid = devnm2devid(ent->devnm); run_udisks("--unmount", map_dev(major(devid),minor(devid), 0)); - rv = Manage_stop(ent->dev, mdfd, verbose, 1); + rv = Manage_stop(ent->devnm, mdfd, verbose, 1); if (rv) /* At least we can try to trigger a 'remove' */ sysfs_uevent(&mdi, "remove"); @@ -1789,7 +1777,7 @@ int IncrementalRemove(char *devname, char *id_path, int verbose) } } else { devlist.disposition = 'r'; - rv = Manage_subdevs(ent->dev, mdfd, &devlist, + rv = Manage_subdevs(ent->devnm, mdfd, &devlist, verbose, 0, NULL, 0); } close(mdfd); diff --git a/Makefile b/Makefile index 2a061c8a..d82e30f8 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ KLIBC_GCC = gcc -nostdinc -iwithprefix include -I$(KLIBC)/klibc/include -I$(KLIB CC = $(CROSS_COMPILE)gcc CXFLAGS ?= -ggdb -CWFLAGS = -Wall -Wstrict-prototypes -Wextra -Wno-unused-parameter +CWFLAGS = -Wall -Werror -Wstrict-prototypes -Wextra -Wno-unused-parameter ifdef WARN_UNUSED CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O3 endif @@ -62,8 +62,8 @@ CPPFLAGS += -DBINDIR=\"$(BINDIR)\" PKG_CONFIG ?= pkg-config SYSCONFDIR = /etc -CONFFILE = $(SYSCONFDIR)/mdadm/mdadm.conf -CONFFILE2 = $(SYSCONFDIR)/mdadm.conf +CONFFILE = $(SYSCONFDIR)/mdadm.conf +CONFFILE2 = $(SYSCONFDIR)/mdadm/mdadm.conf MAILCMD =/usr/sbin/sendmail -t CONFFILEFLAGS = -DCONFFILE=\"$(CONFFILE)\" -DCONFFILE2=\"$(CONFFILE2)\" # Both MAP_DIR and MDMON_DIR should be somewhere that persists across the @@ -145,7 +145,7 @@ STATICOBJS = pwgr.o ASSEMBLE_SRCS := mdassemble.c Assemble.c Manage.c config.c policy.c dlink.c util.c \ maps.c lib.c xmalloc.c \ super0.c super1.c super-ddf.c super-intel.c sha1.c crc32.c sg_io.c mdstat.c \ - platform-intel.c probe_roms.c sysfs.c super-mbr.c super-gpt.c + platform-intel.c probe_roms.c sysfs.c super-mbr.c super-gpt.c mapfile.c ASSEMBLE_AUTO_SRCS := mdopen.c ASSEMBLE_FLAGS:= $(CFLAGS) -DMDASSEMBLE ifdef MDASSEMBLE_AUTO @@ -153,7 +153,7 @@ ASSEMBLE_SRCS += $(ASSEMBLE_AUTO_SRCS) ASSEMBLE_FLAGS += -DMDASSEMBLE_AUTO endif -all : check_rundir mdadm mdmon +all : mdadm mdmon man : mdadm.man md.man mdadm.conf.man mdmon.man raid6check.man check_rundir: @@ -172,7 +172,7 @@ everything-test: all mdadm.static swap_super test_stripe \ # mdadm.uclibc and mdassemble.uclibc don't work on x86-64 # mdadm.tcc doesn't work.. -mdadm : $(OBJS) +mdadm : $(OBJS) | check_rundir $(CC) $(CFLAGS) $(LDFLAGS) -o mdadm $(OBJS) $(LDLIBS) mdadm.static : $(OBJS) $(STATICOBJS) @@ -195,7 +195,7 @@ mdmon.O2 : $(MON_SRCS) $(INCL) mdmon.h $(CC) -o mdmon.O2 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(MON_SRCS) # use '-z now' to guarantee no dynamic linker interactions with the monitor thread -mdmon : $(MON_OBJS) +mdmon : $(MON_OBJS) | check_rundir $(CC) $(CFLAGS) $(LDFLAGS) $(MON_LDFLAGS) -Wl,-z,now -o mdmon $(MON_OBJS) $(LDLIBS) msg.o: msg.c msg.h diff --git a/Manage.c b/Manage.c index 206f34ef..47faeedb 100644 --- a/Manage.c +++ b/Manage.c @@ -211,15 +211,11 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) if (md_get_version(fd) < 9000) { if (ioctl(fd, STOP_MD, 0) == 0) return 0; - pr_err("stopping device %s " - "failed: %s\n", + pr_err("stopping device %s failed: %s\n", devname, strerror(errno)); return 1; } - /* If this is an mdmon managed array, just write 'inactive' - * to the array state and let mdmon clear up. - */ strcpy(devnm, fd2devnm(fd)); /* Get EXCL access first. If this fails, then attempting * to stop is probably a bad idea. @@ -236,13 +232,17 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) container[0] = 0; close(fd); count = 5; - while (((fd = ((devnm[0] == '/') + while (((fd = ((devname[0] == '/') ?open(devname, O_RDONLY|O_EXCL) :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0 || strcmp(fd2devnm(fd), devnm) != 0) && container[0] && mdmon_running(container) && count) { + /* Can't open, so something might be wrong. However it + * is a container, so we might be racing with mdmon, so + * retry for a bit. + */ if (fd >= 0) close(fd); flush_mdmon(container); @@ -252,13 +252,13 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) if (fd >= 0) close(fd); if (verbose >= 0) - pr_err("Cannot get exclusive access to %s:" - "Perhaps a running " - "process, mounted filesystem " - "or active volume group?\n", + pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n", devname); return 1; } + /* If this is an mdmon managed array, just write 'inactive' + * to the array state and let mdmon clear up. + */ if (mdi && mdi->array.level > 0 && is_subarray(mdi->text_version)) { @@ -266,7 +266,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) /* This is mdmon managed. */ close(fd); - /* As we have an O_EXCL open, any use of the device + /* As we had an O_EXCL open, any use of the device * which blocks STOP_ARRAY is probably a transient use, * so it is reasonable to retry for a while - 5 seconds. */ @@ -293,8 +293,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) fd = open_dev_excl(devnm); if (fd < 0) { if (verbose >= 0) - pr_err("failed to completely stop %s" - ": Device is busy\n", + pr_err("failed to completely stop %s: Device is busy\n", devname); rv = 1; goto out; @@ -320,9 +319,8 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) metadata_container_matches(m->metadata_version+9, devnm)) { if (verbose >= 0) - pr_err("Cannot stop container %s: " - "member %s still active\n", - devname, m->dev); + pr_err("Cannot stop container %s: member %s still active\n", + devname, m->devnm); free_mdstat(mds); rv = 1; goto out; @@ -346,9 +344,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) sysfs_attribute_available(mdi, NULL, "reshape_direction") && sysfs_get_str(mdi, NULL, "sync_action", buf, 20) > 0 && strcmp(buf, "reshape\n") == 0 && - sysfs_get_two(mdi, NULL, "raid_disks", &rd1, &rd2) == 2 && - sysfs_set_str(mdi, NULL, "sync_action", "frozen") == 0) { - /* Array is frozen */ + sysfs_get_two(mdi, NULL, "raid_disks", &rd1, &rd2) == 2) { unsigned long long position, curr; unsigned long long chunk1, chunk2; unsigned long long rddiv, chunkdiv; @@ -359,12 +355,28 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) int delay; int scfd; + delay = 40; + while (rd1 > rd2 && delay > 0 && + sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) == 0) { + /* must be in the critical section - wait a bit */ + delay -= 1; + usleep(100000); + } + + if (sysfs_set_str(mdi, NULL, "sync_action", "frozen") != 0) + goto done; + /* Array is frozen */ + rd1 -= mdi->array.level == 6 ? 2 : 1; rd2 -= mdi->array.level == 6 ? 2 : 1; sysfs_get_str(mdi, NULL, "reshape_direction", buf, sizeof(buf)); if (strncmp(buf, "back", 4) == 0) backwards = 1; - sysfs_get_ll(mdi, NULL, "reshape_position", &position); + if (sysfs_get_ll(mdi, NULL, "reshape_position", &position) != 0) { + /* reshape must have finished now */ + sysfs_set_str(mdi, NULL, "sync_action", "idle"); + goto done; + } sysfs_get_two(mdi, NULL, "chunk_size", &chunk1, &chunk2); chunk1 /= 512; chunk2 /= 512; @@ -381,9 +393,20 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) size &= ~(chunk1-1); size &= ~(chunk2-1); /* rd1 must be smaller */ + /* Reshape may have progressed further backwards than + * recorded, so target even further back (hence "-1") + */ position = (position / sectors - 1) * sectors; + /* rd1 is always the conversion factor between 'sync' + * position and 'reshape' position. + * We read 1 "new" stripe worth of data from where-ever, + * and when write out that full stripe. + */ sync_max = size - position/rd1; } else { + /* Reshape will very likely be beyond position, and it may + * be too late to stop at '+1', so aim for '+2' + */ position = (position / sectors + 2) * sectors; sync_max = position/rd1; } @@ -406,6 +429,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) delay = 3000; scfd = sysfs_open(mdi->sys_name, NULL, "sync_completed"); while (scfd >= 0 && delay > 0 && old_sync_max > 0) { + unsigned long long max_completed; sysfs_get_ll(mdi, NULL, "reshape_position", &curr); sysfs_fd_get_str(scfd, buf, sizeof(buf)); if (strncmp(buf, "none", 4) == 0) { @@ -419,7 +443,10 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) break; } - if (sysfs_fd_get_ll(scfd, &completed) == 0 && + if (sysfs_fd_get_two(scfd, &completed, + &max_completed) == 2 && + /* 'completed' sometimes reads as max-uulong */ + completed < max_completed && (completed > sync_max || (completed == sync_max && curr != position))) { while (completed > sync_max) { @@ -443,6 +470,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) close(scfd); } +done: /* As we have an O_EXCL open, any use of the device * which blocks STOP_ARRAY is probably a transient use, @@ -460,9 +488,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry) pr_err("failed to stop array %s: %s\n", devname, strerror(errno)); if (errno == EBUSY) - cont_err("Perhaps a running " - "process, mounted filesystem " - "or active volume group?\n"); + cont_err("Perhaps a running process, mounted filesystem or active volume group?\n"); } rv = 1; goto out; @@ -652,8 +678,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, int rv = -1; tfd = dev_open(dv->devname, O_RDWR); if (tfd < 0) { - pr_err("failed to open %s for" - " superblock update during re-add\n", dv->devname); + pr_err("failed to open %s for superblock update during re-add\n", dv->devname); return -1; } @@ -673,8 +698,7 @@ int attempt_re_add(int fd, int tfd, struct mddev_dev *dv, rv = dev_st->ss->store_super(dev_st, tfd); close(tfd); if (rv != 0) { - pr_err("failed to update" - " superblock during re-add\n"); + pr_err("failed to update superblock during re-add\n"); return -1; } } @@ -717,17 +741,13 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, if (tst->ss == &super0 && ldsize > 4ULL*1024*1024*1024*1024) { /* More than 4TB is wasted on v0.90 */ if (!force) { - pr_err("%s is larger than %s can " - "effectively use.\n" - " Add --force is you " - "really want to add this device.\n", + pr_err("%s is larger than %s can effectively use.\n" + " Add --force is you really want to add this device.\n", dv->devname, devname); return -1; } - pr_err("%s is larger than %s can " - "effectively use.\n" - " Adding anyway as --force " - "was given.\n", + pr_err("%s is larger than %s can effectively use.\n" + " Adding anyway as --force was given.\n", dv->devname, devname); } if (!tst->ss->external && @@ -795,7 +815,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, } /* Make sure device is large enough */ - if (tst->ss->avail_size(tst, ldsize/512, INVALID_SECTORS) < + if (tst->sb && + tst->ss->avail_size(tst, ldsize/512, INVALID_SECTORS) < array_size) { if (dv->disposition == 'M') return 0; @@ -841,7 +862,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, int d; int found = 0; - for (d = 0; d < MAX_DISKS && found < array->active_disks; d++) { + for (d = 0; d < MAX_DISKS && found < array->nr_disks; d++) { disc.number = d; if (ioctl(fd, GET_DISK_INFO, &disc)) continue; @@ -949,8 +970,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, container_fd = open_dev_excl(devnm); if (container_fd < 0) { - pr_err("add failed for %s:" - " could not get exclusive access to container\n", + pr_err("add failed for %s: could not get exclusive access to container\n", dv->devname); tst->ss->free_super(tst); return -1; @@ -989,8 +1009,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv, * would block add_disk */ tst->ss->free_super(tst); if (sysfs_add_disk(sra, &new_mdi, 0) != 0) { - pr_err("add new device to external metadata" - " failed for %s\n", dv->devname); + pr_err("add new device to external metadata failed for %s\n", dv->devname); close(container_fd); sysfs_free(sra); return -1; @@ -1032,8 +1051,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, strcpy(devnm, fd2devnm(fd)); lfd = open_dev_excl(devnm); if (lfd < 0) { - pr_err("Cannot get exclusive access " - " to container - odd\n"); + pr_err("Cannot get exclusive access to container - odd\n"); return -1; } /* We may not be able to check on holders in @@ -1093,8 +1111,7 @@ int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv, } } if (err) { - pr_err("hot remove failed " - "for %s: %s\n", dv->devname, + pr_err("hot remove failed for %s: %s\n", dv->devname, strerror(errno)); if (lfd >= 0) close(lfd); @@ -1304,8 +1321,7 @@ int Manage_subdevs(char *devname, int fd, strcmp(dv->devname, "faulty") == 0) { if (dv->disposition != 'A' && dv->disposition != 'r') { - pr_err("%s only meaningful " - "with -r or --re-add, not -%c\n", + pr_err("%s only meaningful with -r or --re-add, not -%c\n", dv->devname, dv->disposition); goto abort; } @@ -1315,8 +1331,7 @@ int Manage_subdevs(char *devname, int fd, } if (strcmp(dv->devname, "detached") == 0) { if (dv->disposition != 'r' && dv->disposition != 'f') { - pr_err("%s only meaningful " - "with -r of -f, not -%c\n", + pr_err("%s only meaningful with -r of -f, not -%c\n", dv->devname, dv->disposition); goto abort; } @@ -1328,8 +1343,7 @@ int Manage_subdevs(char *devname, int fd, struct mddev_dev *add_devlist = NULL; struct mddev_dev **dp; if (dv->disposition != 'A') { - pr_err("'missing' only meaningful " - "with --re-add\n"); + pr_err("'missing' only meaningful with --re-add\n"); goto abort; } add_devlist = conf_get_devs(); @@ -1381,8 +1395,7 @@ int Manage_subdevs(char *devname, int fd, int found = 0; char dname[55]; if (dv->disposition != 'r' && dv->disposition != 'f') { - pr_err("%s only meaningful " - "with -r or -f, not -%c\n", + pr_err("%s only meaningful with -r or -f, not -%c\n", dv->devname, dv->disposition); goto abort; } @@ -1402,8 +1415,7 @@ int Manage_subdevs(char *devname, int fd, if (!found) { sysfd = sysfs_open(fd2devnm(fd), dname, "state"); if (sysfd < 0) { - pr_err("%s does not appear " - "to be a component of %s\n", + pr_err("%s does not appear to be a component of %s\n", dv->devname, devname); goto abort; } @@ -1462,9 +1474,7 @@ int Manage_subdevs(char *devname, int fd, case 'F': /* --re-add faulty */ /* add the device */ if (subarray) { - pr_err("Cannot add disks to a" - " \'member\' array, perform this" - " operation on the parent container\n"); + pr_err("Cannot add disks to a \'member\' array, perform this operation on the parent container\n"); goto abort; } if (dv->disposition == 'F') @@ -1507,9 +1517,7 @@ int Manage_subdevs(char *devname, int fd, case 'r': /* hot remove */ if (subarray) { - pr_err("Cannot remove disks from a" - " \'member\' array, perform this" - " operation on the parent container\n"); + pr_err("Cannot remove disks from a \'member\' array, perform this operation on the parent container\n"); rv = -1; } else rv = Manage_remove(tst, fd, dv, sysfd, @@ -1547,9 +1555,7 @@ int Manage_subdevs(char *devname, int fd, break; case 'R': /* Mark as replaceable */ if (subarray) { - pr_err("Cannot replace disks in a" - " \'member\' array, perform this" - " operation on the parent container\n"); + pr_err("Cannot replace disks in a \'member\' array, perform this operation on the parent container\n"); rv = -1; } else { if (!frozen) { diff --git a/Monitor.c b/Monitor.c index 5cb24fab..f19c2e58 100644 --- a/Monitor.c +++ b/Monitor.c @@ -310,15 +310,11 @@ static int check_one_sharer(int scan) rv = stat(dir, &buf); if (rv != -1) { if (scan) { - pr_err("Only one " - "autorebuild process allowed" - " in scan mode, aborting\n"); + pr_err("Only one autorebuild process allowed in scan mode, aborting\n"); fclose(fp); return 1; } else { - pr_err("Warning: One" - " autorebuild process already" - " running.\n"); + pr_err("Warning: One autorebuild process already running.\n"); } } fclose(fp); @@ -326,14 +322,11 @@ static int check_one_sharer(int scan) if (scan) { if (mkdir(MDMON_DIR, S_IRWXU) < 0 && errno != EEXIST) { - pr_err("Can't create " - "autorebuild.pid file\n"); + pr_err("Can't create autorebuild.pid file\n"); } else { fp = fopen(path, "w"); if (!fp) - pr_err("Cannot create" - " autorebuild.pid" - "file\n"); + pr_err("Cannot create autorebuild.pidfile\n"); else { pid = getpid(); fprintf(fp, "%d\n", pid); @@ -381,24 +374,21 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) if (info->mailfrom) fprintf(mp, "From: %s\n", info->mailfrom); else - fprintf(mp, "From: " Name " monitoring \n"); + fprintf(mp, "From: %s monitoring \n", Name); fprintf(mp, "To: %s\n", info->mailaddr); fprintf(mp, "Subject: %s event on %s:%s\n\n", event, dev, hname); fprintf(mp, - "This is an automatically generated" - " mail message from " Name "\n"); + "This is an automatically generated mail message from %s\n", Name); fprintf(mp, "running on %s\n\n", hname); fprintf(mp, - "A %s event had been detected on" - " md device %s.\n\n", event, dev); + "A %s event had been detected on md device %s.\n\n", event, dev); if (disc && disc[0] != ' ') fprintf(mp, - "It could be related to" - " component device %s.\n\n", disc); + "It could be related to component device %s.\n\n", disc); if (disc && disc[0] == ' ') fprintf(mp, "Extra information:%s.\n\n", disc); @@ -409,8 +399,7 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) char buf[8192]; int n; fprintf(mp, - "\nP.S. The /proc/mdstat file" - " currently contains the following:\n\n"); + "\nP.S. The /proc/mdstat file currently contains the following:\n\n"); while ( (n=fread(buf, 1, sizeof(buf), mdstat)) > 0) n=fwrite(buf, 1, n, mp); fclose(mdstat); @@ -437,10 +426,13 @@ static void alert(char *event, char *dev, char *disc, struct alert_info *info) else priority = LOG_INFO; - if (disc) + if (disc && disc[0] != ' ') syslog(priority, - "%s event detected on md device %s," - " component device %s", event, dev, disc); + "%s event detected on md device %s, component device %s", event, dev, disc); + else if (disc) + syslog(priority, + "%s event detected on md device %s: %s", + event, dev, disc); else syslog(priority, "%s event detected on md device %s", @@ -460,7 +452,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, mdu_array_info_t array; struct mdstat_ent *mse = NULL, *mse2; char *dev = st->devname; - int fd; + int fd = -1; int i; int remaining_disks; int last_disk; @@ -468,6 +460,33 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, if (test) alert("TestMessage", dev, NULL, ainfo); + if (st->devnm[0]) + fd = open("/sys/block", O_RDONLY|O_DIRECTORY); + if (fd >= 0) { + /* Don't open the device unless it is present and + * active in sysfs. + */ + char buf[10]; + close(fd); + fd = sysfs_open(st->devnm, NULL, "array_state"); + if (fd < 0 || + read(fd, buf, 10) < 5 || + strncmp(buf,"clear",5) == 0 || + strncmp(buf,"inact",5) == 0) { + if (fd >= 0) + close(fd); + fd = sysfs_open(st->devnm, NULL, "level"); + if (fd < 0 || read(fd, buf, 10) != 0) { + if (fd >= 0) + close(fd); + if (!st->err) + alert("DeviceDisappeared", dev, NULL, ainfo); + st->err++; + return 0; + } + } + close(fd); + } fd = open(dev, O_RDONLY); if (fd < 0) { if (!st->err) @@ -488,7 +507,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat, */ if (array.level == 0 || array.level == -1) { if (!st->err && !st->from_config) - alert("DeviceDisappeared", dev, "Wrong-Level", ainfo); + alert("DeviceDisappeared", dev, " Wrong-Level", ainfo); st->err++; close(fd); return 0; @@ -668,6 +687,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, { struct mdstat_ent *mse; int new_found = 0; + char *name; for (mse=mdstat; mse; mse=mse->next) if (mse->devnm[0] && @@ -678,7 +698,14 @@ 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->devnm)); + + name = get_md_name(mse->devnm); + if (!name) { + free(st); + continue; + } + + st->devname = xstrdup(name); if ((fd = open(st->devname, O_RDONLY)) < 0 || ioctl(fd, GET_ARRAY_INFO, &array)< 0) { /* no such array */ @@ -966,6 +993,7 @@ int Wait(char *dev) struct stat stb; char devnm[32]; int rv = 1; + int frozen_remaining = 3; if (stat(dev, &stb) != 0) { pr_err("Cannot find %s: %s\n", dev, @@ -982,7 +1010,7 @@ int Wait(char *dev) if (strcmp(e->devnm, devnm) == 0) break; - if (e->percent == RESYNC_NONE) { + if (e && e->percent == RESYNC_NONE) { /* We could be in the brief pause before something * starts. /proc/mdstat doesn't show that, but * sync_action does. @@ -992,8 +1020,15 @@ int Wait(char *dev) sysfs_init(&mdi, -1, devnm); if (sysfs_get_str(&mdi, NULL, "sync_action", buf, 20) > 0 && - strcmp(buf,"idle\n") != 0) + strcmp(buf,"idle\n") != 0) { e->percent = RESYNC_UNKNOWN; + if (strcmp(buf, "frozen\n") == 0) { + if (frozen_remaining == 0) + e->percent = RESYNC_NONE; + else + frozen_remaining -= 1; + } + } } if (!e || e->percent == RESYNC_NONE) { if (e && e->metadata_version && @@ -1035,8 +1070,7 @@ int WaitClean(char *dev, int sock, int verbose) mdi = sysfs_read(fd, devnm, GET_VERSION|GET_LEVEL|GET_SAFEMODE); if (!mdi) { if (verbose) - pr_err("Failed to read sysfs attributes for " - "%s\n", dev); + pr_err("Failed to read sysfs attributes for %s\n", dev); close(fd); return 0; } diff --git a/ReadMe.c b/ReadMe.c index ec8e3487..386d7a01 100644 --- a/ReadMe.c +++ b/ReadMe.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2014 Neil Brown + * Copyright (C) 2001-2015 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -25,12 +25,12 @@ #include "mdadm.h" #ifndef VERSION -#define VERSION "3.3.2" +#define VERSION "3.3.4" #endif #ifndef VERS_DATE -#define VERS_DATE "21st August 2014" +#define VERS_DATE "3rd August 2015" #endif -char Version[] = Name " - v" VERSION " - " VERS_DATE "\n"; +char Version[] = "mdadm - v" VERSION " - " VERS_DATE "\n"; /* * File: ReadMe.c @@ -593,7 +593,7 @@ char Help_incr[] = ; char Help_config[] = -"The /etc/mdadm/mdadm.conf config file:\n\n" +"The /etc/mdadm.conf config file:\n\n" " The config file contains, apart from blank lines and comment lines that\n" " start with a hash(#), array lines, device lines, and various\n" " configuration lines.\n" diff --git a/bitmap.c b/bitmap.c index 020f10d9..bbe9baec 100644 --- a/bitmap.c +++ b/bitmap.c @@ -20,7 +20,7 @@ #include "mdadm.h" -inline void sb_le_to_cpu(bitmap_super_t *sb) +static inline void sb_le_to_cpu(bitmap_super_t *sb) { sb->magic = __le32_to_cpu(sb->magic); sb->version = __le32_to_cpu(sb->version); @@ -34,7 +34,7 @@ inline void sb_le_to_cpu(bitmap_super_t *sb) sb->write_behind = __le32_to_cpu(sb->write_behind); } -inline void sb_cpu_to_le(bitmap_super_t *sb) +static inline void sb_cpu_to_le(bitmap_super_t *sb) { sb_le_to_cpu(sb); /* these are really the same thing */ } @@ -74,7 +74,7 @@ typedef struct bitmap_info_s { } bitmap_info_t; /* count the dirty bits in the first num_bits of byte */ -inline int count_dirty_bits_byte(char byte, int num_bits) +static inline int count_dirty_bits_byte(char byte, int num_bits) { int num = 0; @@ -140,8 +140,7 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief) info = xmalloc(sizeof(*info)); if (n < sizeof(info->sb)) { - pr_err("failed to read superblock of bitmap " - "file: %s\n", strerror(errno)); + pr_err("failed to read superblock of bitmap file: %s\n", strerror(errno)); free(info); free(buf); return NULL; @@ -182,8 +181,7 @@ bitmap_info_t *bitmap_fd_read(int fd, int brief) } if (read_bits < total_bits) { /* file truncated... */ - pr_err("WARNING: bitmap file is not large " - "enough for array size %llu!\n\n", + pr_err("WARNING: bitmap file is not large enough for array size %llu!\n\n", (unsigned long long)info->sb.sync_size); total_bits = read_bits; } diff --git a/config.c b/config.c index 909f83f4..a882ed33 100644 --- a/config.c +++ b/config.c @@ -167,10 +167,10 @@ struct mddev_dev *load_containers(void) !is_subarray(&ent->metadata_version[9])) { d = xmalloc(sizeof(*d)); memset(d, 0, sizeof(*d)); - me = map_by_devnm(&map, ent->dev); + me = map_by_devnm(&map, ent->devnm); if (me) d->devname = xstrdup(me->path); - else if (asprintf(&d->devname, "/dev/%s", ent->dev) < 0) { + else if (asprintf(&d->devname, "/dev/%s", ent->devnm) < 0) { free(d); continue; } @@ -396,14 +396,12 @@ void arrayline(char *line) ) { /* This is acceptable */; if (mis.devname) - pr_err("only give one " - "device per ARRAY line: %s and %s\n", + pr_err("only give one device per ARRAY line: %s and %s\n", mis.devname, w); else mis.devname = w; }else { - pr_err("%s is an invalid name for " - "an md device - ignored.\n", w); + pr_err("%s is an invalid name for an md device - ignored.\n", w); } } else if (strncasecmp(w, "uuid=", 5)==0 ) { if (mis.uuid_set) @@ -1121,8 +1119,7 @@ struct mddev_ident *conf_match(struct supertype *st, !array_list->devices && array_list->super_minor == UnSet) { if (verbose >= 2 && array_list->devname) - pr_err("%s doesn't have any identifying" - " information.\n", + pr_err("%s doesn't have any identifying information.\n", array_list->devname); continue; } @@ -1131,13 +1128,11 @@ struct mddev_ident *conf_match(struct supertype *st, if (match) { if (verbose >= 0) { if (match->devname && array_list->devname) - pr_err("we match both %s and %s - " - "cannot decide which to use.\n", + pr_err("we match both %s and %s - cannot decide which to use.\n", match->devname, array_list->devname); else - pr_err("multiple lines in mdadm.conf" - " match\n"); + pr_err("multiple lines in mdadm.conf match\n"); } if (rvp) *rvp = 2; @@ -1174,8 +1169,7 @@ int conf_verify_devnames(struct mddev_ident *array_list) "%s have the same name: %s\n", nbuf, a1->devname); } else - pr_err("Device %s given twice" - " in config file\n", a1->devname); + pr_err("Device %s given twice in config file\n", a1->devname); return 1; } } diff --git a/debian/changelog b/debian/changelog index 0a6a95a6..3878ed58 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +mdadm (3.3.4-1) unstable; urgency=medium + + * New upstream release. + + -- Dimitri John Ledkov Sun, 08 Nov 2015 11:48:03 +0000 + mdadm (3.3.2-5) unstable; urgency=medium * use-tempnode-not-devnode.patch: change udev rules file to use diff --git a/external-reshape-design.txt b/external-reshape-design.txt index 4eb04a2f..10c57ccb 100644 --- a/external-reshape-design.txt +++ b/external-reshape-design.txt @@ -166,7 +166,7 @@ sync_action monitor. 8/ mdadm::Grow_reshape() calls ->manage_reshape to oversee the rest of the reshape. - + 9/ mdadm::->manage_reshape(): saves data that will be overwritten by the kernel to either the backup file or the metadata specific location, advances sync_max, waits for reshape, ping mdmon, repeat. @@ -194,7 +194,7 @@ sync_action kernel-managed-metadata this protection is provided by ->reshape_safe, but that does not protect us in the case of user-space-managed-metadata. - + 10/ mdadm::->manage_reshape(): Once reshape completes changes the raid level back to the nominal raid level (if necessary) @@ -272,9 +272,9 @@ sync_action ->set_array_state to record the the reshape is complete. For container-wide reshape, this happens once for each member array. - - - + + + ... [1]: Linux kernel design patterns - part 3, Neil Brown http://lwn.net/Articles/336262/ diff --git a/inventory b/inventory index 40598cee..a9fc3c01 100755 --- a/inventory +++ b/inventory @@ -20,6 +20,8 @@ ANNOUNCE-3.2.6 ANNOUNCE-3.3 ANNOUNCE-3.3.1 ANNOUNCE-3.3.2 +ANNOUNCE-3.3.3 +ANNOUNCE-3.3.4 Assemble.c Build.c COPYING @@ -234,6 +236,7 @@ tests/18imsm-r0_2d-takeover-r10_4d tests/18imsm-r10_4d-takeover-r0_2d tests/18imsm-r1_2d-takeover-r0_1d tests/19raid6auto-repair +tests/19raid6check tests/19raid6repair tests/19repair-does-not-destroy tests/ToTest diff --git a/managemon.c b/managemon.c index 1c9eccc4..6d1b3d85 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: sys_name: %s\n", __func__, aa->info.sys_name); + dprintf("sys_name: %s\n", aa->info.sys_name); if (!aa->container) close_aa(aa); while (aa->info.devs) { @@ -273,8 +273,7 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd) .state = 0, }; - dprintf("%s: add %d:%d to container\n", - __func__, sd->disk.major, sd->disk.minor); + dprintf("add %d:%d to container\n", sd->disk.major, sd->disk.minor); sd->next = st->devs; st->devs = sd; @@ -325,8 +324,8 @@ static void remove_disk_from_container(struct supertype *st, struct mdinfo *sd) .raid_disk = -1, .state = 0, }; - dprintf("%s: remove %d:%d from container\n", - __func__, sd->disk.major, sd->disk.minor); + dprintf("remove %d:%d from container\n", + sd->disk.major, sd->disk.minor); st->update_tail = &update; st->ss->remove_from_super(st, &dk); @@ -402,6 +401,22 @@ static void manage_container(struct mdstat_ent *mdstat, } } +static int sysfs_open2(char *devnum, char *name, char *attr) +{ + int fd = sysfs_open(devnum, name, attr); + if (fd >= 0) { + /* seq_file in the kernel allocates buffer space + * on the first read. Do that now so 'monitor' + * never needs too. + */ + char buf[200]; + if (read(fd, buf, sizeof(buf)) < 0) + /* pretend not to ignore return value */ + return fd; + } + return fd; +} + static int disk_init_and_add(struct mdinfo *disk, struct mdinfo *clone, struct active_array *aa) { @@ -409,10 +424,11 @@ static int disk_init_and_add(struct mdinfo *disk, struct mdinfo *clone, return -1; *disk = *clone; - disk->recovery_fd = sysfs_open(aa->info.sys_name, disk->sys_name, "recovery_start"); + disk->recovery_fd = sysfs_open2(aa->info.sys_name, disk->sys_name, + "recovery_start"); if (disk->recovery_fd < 0) return -1; - disk->state_fd = sysfs_open(aa->info.sys_name, disk->sys_name, "state"); + disk->state_fd = sysfs_open2(aa->info.sys_name, disk->sys_name, "state"); if (disk->state_fd < 0) { close(disk->recovery_fd); return -1; @@ -525,7 +541,7 @@ static void manage_member(struct mdstat_ent *mdstat, /* prevent the kernel from activating the disk(s) before we * finish adding them */ - dprintf("%s: freezing %s\n", __func__, a->info.sys_name); + dprintf("freezing %s\n", a->info.sys_name); sysfs_set_str(&a->info, NULL, "sync_action", "frozen"); /* Add device to array and set offset/size/slot. @@ -550,8 +566,7 @@ static void manage_member(struct mdstat_ent *mdstat, if (sysfs_set_str(&a->info, NULL, "sync_action", "recover") == 0) newa->prev_action = recover; - dprintf("%s: recovery started on %s\n", __func__, - a->info.sys_name); + dprintf("recovery started on %s\n", a->info.sys_name); out: while (newdev) { d = newdev->next; @@ -692,12 +707,13 @@ static void manage_new(struct mdstat_ent *mdstat, } } - 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: %s action: %d state: %d\n", __func__, inst, + new->action_fd = sysfs_open2(new->info.sys_name, NULL, "sync_action"); + new->info.state_fd = sysfs_open2(new->info.sys_name, NULL, "array_state"); + new->resync_start_fd = sysfs_open2(new->info.sys_name, NULL, "resync_start"); + new->metadata_fd = sysfs_open2(new->info.sys_name, NULL, "metadata_version"); + new->sync_completed_fd = sysfs_open2(new->info.sys_name, NULL, "sync_completed"); + + dprintf("inst: %s action: %d state: %d\n", inst, new->action_fd, new->info.state_fd); if (sigterm) diff --git a/md.4 b/md.4 index e222237d..e955c3b4 100644 --- a/md.4 +++ b/md.4 @@ -40,7 +40,7 @@ MULTIPATH (a set of different interfaces to the same device), and FAULTY (a layer over a single device into which errors can be injected). .SS MD METADATA -Each device in an array may have some +Each device in an array may have some .I metadata stored in the device. This metadata is sometimes called a .BR superblock . @@ -176,7 +176,7 @@ device is rounded down to a multiple of this chunksize. A RAID0 array (which has zero redundancy) is also known as a striped array. A RAID0 array is configured at creation with a -.B "Chunk Size" +.B "Chunk Size" which must be a power of two (prior to Linux 2.6.31), and at least 4 kibibytes. @@ -1024,7 +1024,7 @@ number of times MD will service a full-stripe-write before servicing a stripe that requires some "prereading". For fairness this defaults to 1. Valid values are 0 to stripe_cache_size. Setting this to 0 maximizes sequential-write throughput at the cost of fairness to threads -doing small or random writes. +doing small or random writes. .SS KERNEL PARAMETERS diff --git a/mdadm.8.in b/mdadm.8.in index bc67a681..c25ac6c7 100644 --- a/mdadm.8.in +++ b/mdadm.8.in @@ -5,7 +5,7 @@ .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" See file COPYING in distribution for details. -.TH MDADM 8 "" v3.3.2 +.TH MDADM 8 "" v3.3.4 .SH NAME mdadm \- manage MD devices .I aka @@ -214,7 +214,7 @@ to detect and assemble arrays \(em possibly in an .P If a device is given before any options, or if the first option is -and of +one of .BR \-\-add , .BR \-\-re\-add , .BR \-\-add\-spare , @@ -267,13 +267,13 @@ the exact meaning of this option in different contexts. .TP .BR \-c ", " \-\-config= Specify the config file or directory. Default is to use -.B /etc/mdadm/mdadm.conf +.B /etc/mdadm.conf and -.BR /etc/mdadm/mdadm.conf.d , +.BR /etc/mdadm.conf.d , or if those are missing then -.B /etc/mdadm.conf +.B /etc/mdadm/mdadm.conf and -.BR /etc/mdadm.conf.d . +.BR /etc/mdadm/mdadm.conf.d . If the config file given is .B "partitions" then nothing will be read, but @@ -393,6 +393,13 @@ will be allowed to use 'local' names (i.e. not ending in '_' followed by a digit string). See below under .BR "Auto Assembly" . +The special name "\fBany\fP" can be used as a wild card. If an array +is created with +.B --homehost=any +then the name "\fBany\fP" will be stored in the array and it can be +assembled in the same way on any host. If an array is assembled with +this option, then the homehost recorded on the array will be ignored. + .TP .B \-\-prefer= When @@ -1796,9 +1803,9 @@ The config file is only used if explicitly named with or requested with (a possibly implicit) .BR \-\-scan . In the later case, -.B /etc/mdadm/mdadm.conf -or .B /etc/mdadm.conf +or +.B /etc/mdadm/mdadm.conf is used. If @@ -2196,11 +2203,11 @@ option. Currently only .B name is supported. -The +The .B name option updates the subarray name in the metadata, it may not affect the device node name or the device node symlink until the subarray is -re\-assembled. If updating +re\-assembled. If updating .B name would change the UUID of an active subarray this operation is blocked, and the command will end in an error. @@ -3092,7 +3099,7 @@ uses this to find arrays when is given in Misc mode, and to monitor array reconstruction on Monitor mode. -.SS /etc/mdadm/mdadm.conf (or /etc/mdadm.conf) +.SS /etc/mdadm.conf The config file lists which devices may be scanned to see if they contain MD super block, and gives identifying information @@ -3100,7 +3107,7 @@ they contain MD super block, and gives identifying information .BR mdadm.conf (5) for more details. -.SS /etc/mdadm/mdadm.conf.d (or /etc/mdadm.conf.d) +.SS /etc/mdadm.conf.d A directory containing configuration files which are read in lexical order. diff --git a/mdadm.c b/mdadm.c index be990b8a..93732a8f 100644 --- a/mdadm.c +++ b/mdadm.c @@ -38,6 +38,7 @@ static int misc_list(struct mddev_dev *devlist, struct mddev_ident *ident, char *dump_directory, struct supertype *ss, struct context *c); +const char Name[] = "mdadm"; int main(int argc, char *argv[]) { @@ -336,13 +337,11 @@ int main(int argc, char *argv[]) } if (devs_found > 0 && mode == MANAGE && !devmode) { - pr_err("Must give one of -a/-r/-f" - " for subsequent devices at %s\n", optarg); + pr_err("Must give one of -a/-r/-f for subsequent devices at %s\n", optarg); exit(2); } if (devs_found > 0 && mode == GROW && !devmode) { - pr_err("Must give -a/--add for" - " devices to add: %s\n", optarg); + pr_err("Must give -a/--add for devices to add: %s\n", optarg); exit(2); } dv = xmalloc(sizeof(*dv)); @@ -369,8 +368,7 @@ int main(int argc, char *argv[]) case O(BUILD,'c'): /* chunk or rounding */ case O(BUILD,ChunkSize): /* chunk or rounding */ if (s.chunk) { - pr_err("chunk/rounding may only be specified once. " - "Second value is %s.\n", optarg); + pr_err("chunk/rounding may only be specified once. Second value is %s.\n", optarg); exit(2); } s.chunk = parse_size(optarg); @@ -420,8 +418,7 @@ int main(int argc, char *argv[]) case O(CREATE,'z'): case O(BUILD,'z'): /* size */ if (s.size > 0) { - pr_err("size may only be specified once. " - "Second value is %s.\n", optarg); + pr_err("size may only be specified once. Second value is %s.\n", optarg); exit(2); } if (strcmp(optarg, "max")==0) @@ -441,8 +438,7 @@ int main(int argc, char *argv[]) case O(GROW,'Z'): /* array size */ if (array_size > 0) { - pr_err("array-size may only be specified once. " - "Second value is %s.\n", optarg); + pr_err("array-size may only be specified once. Second value is %s.\n", optarg); exit(2); } if (strcmp(optarg, "max") == 0) @@ -461,8 +457,7 @@ int main(int argc, char *argv[]) case O(CREATE,DataOffset): case O(GROW,DataOffset): if (data_offset != INVALID_SECTORS) { - pr_err("data-offset may only be specified one. " - "Second value is %s.\n", optarg); + pr_err("data-offset may only be specified one. Second value is %s.\n", optarg); exit(2); } if (mode == CREATE && @@ -481,8 +476,7 @@ int main(int argc, char *argv[]) case O(CREATE,'l'): case O(BUILD,'l'): /* set raid level*/ if (s.level != UnSet) { - pr_err("raid level may only be set once. " - "Second value is %s.\n", optarg); + pr_err("raid level may only be set once. Second value is %s.\n", optarg); exit(2); } s.level = map_name(pers, optarg); @@ -510,8 +504,7 @@ int main(int argc, char *argv[]) case O(GROW, 'p'): /* new layout */ case O(GROW, Layout): if (s.layout_str) { - pr_err("layout may only be sent once. " - "Second value was %s\n", optarg); + pr_err("layout may only be sent once. Second value was %s\n", optarg); exit(2); } s.layout_str = optarg; @@ -523,8 +516,7 @@ int main(int argc, char *argv[]) case O(BUILD,'p'): /* faulty layout */ case O(BUILD,Layout): if (s.layout != UnSet) { - pr_err("layout may only be sent once. " - "Second value was %s\n", optarg); + pr_err("layout may only be sent once. Second value was %s\n", optarg); exit(2); } switch(s.level) { @@ -655,8 +647,7 @@ int main(int argc, char *argv[]) case O(CREATE,'u'): /* uuid of array */ case O(ASSEMBLE,'u'): /* uuid of array */ if (ident.uuid_set) { - pr_err("uuid cannot be set twice. " - "Second value %s.\n", optarg); + pr_err("uuid cannot be set twice. Second value %s.\n", optarg); exit(2); } if (parse_uuid(optarg, ident.uuid)) @@ -671,8 +662,7 @@ int main(int argc, char *argv[]) case O(ASSEMBLE,'N'): case O(MISC,'N'): if (ident.name[0]) { - pr_err("name cannot be set twice. " - "Second value %s.\n", optarg); + pr_err("name cannot be set twice. Second value %s.\n", optarg); exit(2); } if (mode == MISC && !c.subarray) { @@ -690,8 +680,7 @@ int main(int argc, char *argv[]) case O(ASSEMBLE,'m'): /* super-minor for array */ case O(ASSEMBLE,SuperMinor): if (ident.super_minor != UnSet) { - pr_err("super-minor cannot be set twice. " - "Second value: %s.\n", optarg); + pr_err("super-minor cannot be set twice. Second value: %s.\n", optarg); exit(2); } if (strcmp(optarg, "dev")==0) @@ -714,14 +703,12 @@ int main(int argc, char *argv[]) case O(ASSEMBLE,'U'): /* update the superblock */ case O(MISC,'U'): if (c.update) { - pr_err("Can only update one aspect" - " of superblock, both %s and %s given.\n", + pr_err("Can only update one aspect of superblock, both %s and %s given.\n", c.update, optarg); exit(2); } if (mode == MISC && !c.subarray) { - pr_err("Only subarrays can be" - " updated in misc mode\n"); + pr_err("Only subarrays can be updated in misc mode\n"); exit(2); } c.update = optarg; @@ -753,16 +740,14 @@ int main(int argc, char *argv[]) continue; if (strcmp(c.update, "byteorder")==0) { if (ss) { - pr_err("must not set metadata" - " type with --update=byteorder.\n"); + pr_err("must not set metadata type with --update=byteorder.\n"); exit(2); } for(i=0; !ss && superlist[i]; i++) ss = superlist[i]->match_metadata_desc( "0.swap"); if (!ss) { - pr_err("INTERNAL ERROR" - " cannot find 0.swap\n"); + pr_err("INTERNAL ERROR cannot find 0.swap\n"); exit(2); } @@ -771,29 +756,29 @@ int main(int argc, char *argv[]) if (strcmp(c.update,"?") == 0 || strcmp(c.update, "help") == 0) { outf = stdout; - fprintf(outf, Name ": "); + fprintf(outf, "%s: ", Name); } else { outf = stderr; fprintf(outf, - Name ": '--update=%s' is invalid. ", - c.update); + "%s: '--update=%s' is invalid. ", + Name, c.update); } fprintf(outf, "Valid --update options are:\n" " 'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n" " 'summaries', 'homehost', 'byteorder', 'devicesize',\n" - " 'no-bitmap', 'metadata', 'revert-reshape'\n"); + " 'no-bitmap', 'metadata', 'revert-reshape'\n" + " 'bbl', 'no-bbl'\n" + ); exit(outf == stdout ? 0 : 2); case O(MANAGE,'U'): /* update=devicesize is allowed with --re-add */ if (devmode != 'A') { - pr_err("--update in Manage mode only" - " allowed with --re-add.\n"); + pr_err("--update in Manage mode only allowed with --re-add.\n"); exit(1); } if (c.update) { - pr_err("Can only update one aspect" - " of superblock, both %s and %s given.\n", + pr_err("Can only update one aspect of superblock, both %s and %s given.\n", c.update, optarg); exit(2); } @@ -801,8 +786,7 @@ int main(int argc, char *argv[]) if (strcmp(c.update, "devicesize") != 0 && strcmp(c.update, "bbl") != 0 && strcmp(c.update, "no-bbl") != 0) { - pr_err("only 'devicesize', 'bbl' and 'no-bbl' can be" - " updated with --re-add\n"); + pr_err("only 'devicesize', 'bbl' and 'no-bbl' can be updated with --re-add\n"); exit(2); } continue; @@ -824,8 +808,7 @@ int main(int argc, char *argv[]) case O(MONITOR,ConfigFile): case O(CREATE,ConfigFile): if (configfile) { - pr_err("configfile cannot be set twice. " - "Second value is %s.\n", optarg); + pr_err("configfile cannot be set twice. Second value is %s.\n", optarg); exit(2); } configfile = optarg; @@ -991,8 +974,7 @@ int main(int argc, char *argv[]) case O(MISC ,Action): if (opt == KillSubarray || opt == UpdateSubarray) { if (c.subarray) { - pr_err("subarray can only" - " be specified once\n"); + pr_err("subarray can only be specified once\n"); exit(2); } c.subarray = optarg; @@ -1039,12 +1021,10 @@ int main(int argc, char *argv[]) continue; case O(MISC, UdevRules): if (devmode && devmode != opt) { - pr_err("--udev-rules must" - " be the only option.\n"); + pr_err("--udev-rules must be the only option.\n"); } else { if (udev_filename) - pr_err("only specify one udev " - "rule filename. %s ignored.\n", + pr_err("only specify one udev rule filename. %s ignored.\n", optarg); else udev_filename = optarg; @@ -1236,15 +1216,13 @@ int main(int argc, char *argv[]) /* non-existent device is OK */ mdfd = open_mddev(devlist->devname, 0); if (mdfd == -2) { - pr_err("device %s exists but is not an " - "md array.\n", devlist->devname); + pr_err("device %s exists but is not an md array.\n", devlist->devname); exit(1); } if ((int)ident.super_minor == -2) { struct stat stb; if (mdfd < 0) { - pr_err("--super-minor=dev given, and " - "listed device %s doesn't exist.\n", + pr_err("--super-minor=dev given, and listed device %s doesn't exist.\n", devlist->devname); exit(1); } @@ -1269,7 +1247,7 @@ int main(int argc, char *argv[]) } } - if (c.homehost == NULL) + if (c.homehost == NULL && c.require_homehost) c.homehost = conf_get_homehost(&c.require_homehost); if (c.homehost == NULL || strcasecmp(c.homehost, "")==0) { if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { @@ -1482,8 +1460,7 @@ int main(int argc, char *argv[]) struct mdinfo sra; int err; if (s.raiddisks || s.level != UnSet) { - pr_err("cannot change array size in same operation " - "as changing raiddisks or level.\n" + pr_err("cannot change array size in same operation as changing raiddisks or level.\n" " Change size first, then check that data is still intact.\n"); rv = 1; break; @@ -1495,11 +1472,9 @@ int main(int argc, char *argv[]) err = sysfs_set_num(&sra, NULL, "array_size", array_size / 2); if (err < 0) { if (errno == E2BIG) - pr_err("--array-size setting" - " is too large.\n"); + pr_err("--array-size setting is too large.\n"); else - pr_err("current kernel does" - " not support setting --array-size\n"); + pr_err("current kernel does not support setting --array-size\n"); rv = 1; break; } @@ -1507,8 +1482,7 @@ int main(int argc, char *argv[]) if (devs_found > 1 && s.raiddisks == 0 && s.level == UnSet) { /* must be '-a'. */ if (s.size > 0 || s.chunk || s.layout_str != NULL || s.bitmap_file) { - pr_err("--add cannot be used with " - "other geometry changes in --grow mode\n"); + pr_err("--add cannot be used with other geometry changes in --grow mode\n"); rv = 1; break; } @@ -1521,9 +1495,7 @@ int main(int argc, char *argv[]) } else if (s.bitmap_file) { if (s.size > 0 || s.raiddisks || s.chunk || s.layout_str != NULL || devs_found > 1) { - pr_err("--bitmap changes cannot be " - "used with other geometry changes " - "in --grow mode\n"); + pr_err("--bitmap changes cannot be used with other geometry changes in --grow mode\n"); rv = 1; break; } @@ -1600,8 +1572,7 @@ static int scan_assemble(struct supertype *ss, int failures, successes; if (conf_verify_devnames(array_list)) { - pr_err("Duplicate MD device names in " - "conf file were found.\n"); + pr_err("Duplicate MD device names in conf file were found.\n"); return 1; } if (devlist == NULL) { @@ -1614,9 +1585,7 @@ static int scan_assemble(struct supertype *ss, a->autof = c->autof; } if (map_lock(&map)) - pr_err("%s: failed to get " - "exclusive lock on mapfile\n", - __func__); + pr_err("failed to get exclusive lock on mapfile\n"); do { failures = 0; successes = 0; @@ -1706,7 +1675,7 @@ static int misc_scan(char devmode, struct context *c) if (!name) { pr_err("cannot find device file for %s\n", - e->dev); + e->devnm); continue; } if (devmode == 'D') @@ -1741,7 +1710,7 @@ static int stop_scan(int verbose) if (!name) { pr_err("cannot find device file for %s\n", - e->dev); + e->devnm); continue; } mdfd = open_mddev(name, 1); diff --git a/mdadm.conf-example b/mdadm.conf-example index d9d8d396..35a75d12 100644 --- a/mdadm.conf-example +++ b/mdadm.conf-example @@ -15,9 +15,9 @@ # ARRAY lines specify information about how to identify arrays so # so that they can be activated # -# You can have more than one device line and use wild cards. The first +# You can have more than one device line and use wild cards. The first # example includes SCSI the first partition of SCSI disks /dev/sdb, -# /dev/sdc, /dev/sdd, /dev/sdj, /dev/sdk, and /dev/sdl. The second +# /dev/sdc, /dev/sdd, /dev/sdj, /dev/sdk, and /dev/sdl. The second # line looks for array slices on IDE disks. # #DEVICE /dev/sd[bcdjkl]1 diff --git a/mdadm.conf.5 b/mdadm.conf.5 index 542e2635..18512cb0 100644 --- a/mdadm.conf.5 +++ b/mdadm.conf.5 @@ -8,7 +8,7 @@ .SH NAME mdadm.conf \- configuration for management of Software RAID with mdadm .SH SYNOPSIS -/etc/mdadm/mdadm.conf +/etc/mdadm.conf .SH DESCRIPTION .PP .I mdadm diff --git a/mdadm.h b/mdadm.h index fc1fd318..b5976582 100644 --- a/mdadm.h +++ b/mdadm.h @@ -180,6 +180,8 @@ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence)); #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +extern const char Name[]; + /* general information that might be extracted from a superblock */ struct mdinfo { mdu_array_info_t array; @@ -262,8 +264,6 @@ struct createinfo { struct supertype *supertype; }; -#define Name "mdadm" - enum mode { ASSEMBLE=1, BUILD, @@ -453,7 +453,6 @@ typedef struct mapping { } mapping_t; struct mdstat_ent { - char *dev; char devnm[32]; int active; char *level; @@ -491,18 +490,8 @@ 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, char *devnm); extern struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]); -#ifdef MDASSEMBLE -static inline struct map_ent *map_by_devnm(struct map_ent **map, char *name) -{ - return NULL; -} -static inline void map_free(struct map_ent *map) -{ -} -#else extern struct map_ent *map_by_devnm(struct map_ent **map, char *devnm); extern void map_free(struct map_ent *map); -#endif 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); @@ -1440,9 +1429,13 @@ static inline char *to_subarray(struct mdstat_ent *ent, char *container) #ifdef DEBUG #define dprintf(fmt, arg...) \ + fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg) +#define dprintf_cont(fmt, arg...) \ fprintf(stderr, fmt, ##arg) #else #define dprintf(fmt, arg...) \ + ({ if (0) fprintf(stderr, "%s: %s: " fmt, Name, __func__, ##arg); 0; }) +#define dprintf_cont(fmt, arg...) \ ({ if (0) fprintf(stderr, fmt, ##arg); 0; }) #endif #include @@ -1457,7 +1450,11 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { return ret; } -#define pr_err(fmt ...) fprintf(stderr, Name ": " fmt) +#ifdef DEBUG +#define pr_err(fmt, args...) fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##args) +#else +#define pr_err(fmt, args...) fprintf(stderr, "%s: "fmt, Name, ##args) +#endif #define cont_err(fmt ...) fprintf(stderr, " " fmt) void *xmalloc(size_t len); diff --git a/mdadm.spec b/mdadm.spec index 384a1d89..293cb190 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Summary: mdadm is used for controlling Linux md devices (aka RAID arrays) Name: mdadm -Version: 3.3.2 +Version: 3.3.4 Release: 1 Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.gz URL: http://neil.brown.name/blog/mdadm diff --git a/mdassemble.8 b/mdassemble.8 index 0e640023..7601b1aa 100644 --- a/mdassemble.8 +++ b/mdassemble.8 @@ -1,5 +1,5 @@ .\" -*- nroff -*- -.TH MDASSEMBLE 8 "" v3.3.2 +.TH MDASSEMBLE 8 "" v3.3.4 .SH NAME mdassemble \- assemble MD devices .I aka @@ -40,7 +40,7 @@ There are no options to .SH FILES -.SS /etc/mdadm/mdadm.conf +.SS /etc/mdadm.conf The config file lists which devices may be scanned to see if they contain MD super block, and gives identifying information @@ -53,7 +53,7 @@ supports all configuration parameters defined in .B mdadm.conf with the exception of .B auto= -which is supported only if mdadm was built with the +which is supported only if mdadm was built with the .B \-DMDASSEMBLE_AUTO define. diff --git a/mdassemble.c b/mdassemble.c index 674be11f..78d363a3 100644 --- a/mdassemble.c +++ b/mdassemble.c @@ -26,6 +26,8 @@ #include "mdadm.h" #include "md_p.h" +char const Name[] = "mdassemble"; + #ifndef MDASSEMBLE_AUTO /* from mdopen.c */ int open_mddev(char *dev, int report_errors/*unused*/) @@ -48,18 +50,6 @@ int create_mddev(char *dev, char *name, int autof/*unused*/, int trustworthy, return open_mddev(dev, 0); } #endif -int map_update(struct map_ent **mpp, char *devnm, char *metadata, - int *uuid, char *path) -{ - return 0; -} -struct map_ent *map_by_name(struct map_ent **mpp, char *name) -{ - return NULL; -} -int map_lock(struct map_ent **melp){return 0;} -void map_unlock(struct map_ent **melp){} -struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]){return NULL;} int rv; int mdfd = -1; diff --git a/mdmon.8 b/mdmon.8 index 4f9a439a..beb82e03 100644 --- a/mdmon.8 +++ b/mdmon.8 @@ -1,5 +1,5 @@ .\" See file COPYING in distribution for details. -.TH MDMON 8 "" v3.3.2 +.TH MDMON 8 "" v3.3.4 .SH NAME mdmon \- monitor MD external metadata arrays diff --git a/mdmon.c b/mdmon.c index 27045a12..ee12b7c7 100644 --- a/mdmon.c +++ b/mdmon.c @@ -67,6 +67,8 @@ #include "mdadm.h" #include "mdmon.h" +char const Name[] = "mdmon"; + struct active_array *discard_this; struct active_array *pending_discard; diff --git a/mdmon.h b/mdmon.h index 5a8e1209..aa750c68 100644 --- a/mdmon.h +++ b/mdmon.h @@ -18,8 +18,7 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ -#undef pr_err -#define pr_err(fmt ...) fprintf(stderr, "mdmon: " fmt) +extern const char Name[]; enum array_state { clear, inactive, suspended, readonly, read_auto, clean, active, write_pending, active_idle, bad_word}; diff --git a/mdopen.c b/mdopen.c index 2c9d7455..28410f46 100644 --- a/mdopen.c +++ b/mdopen.c @@ -173,8 +173,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, /* name *must* be mdXX or md_dXX in this context */ if (num < 0 || (strcmp(cname, "md") != 0 && strcmp(cname, "md_d") != 0)) { - pr_err("%s is an invalid name " - "for an md device. Try /dev/md/%s\n", + pr_err("%s is an invalid name for an md device. Try /dev/md/%s\n", dev, dev+5); return -1; } @@ -191,13 +190,11 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, * empty. */ if (strchr(cname, '/') != NULL) { - pr_err("%s is an invalid name " - "for an md device.\n", dev); + pr_err("%s is an invalid name for an md device.\n", dev); return -1; } if (cname[0] == 0) { - pr_err("%s is an invalid name " - "for an md device (empty!).", dev); + pr_err("%s is an invalid name for an md device (empty!).", dev); return -1; } if (num < 0) { @@ -226,8 +223,7 @@ int create_mddev(char *dev, char *name, int autof, int trustworthy, if (name && name[0] == 0) name = NULL; if (name && trustworthy == METADATA && use_mdp == 1) { - pr_err("%s is not allowed for a %s container. " - "Consider /dev/md%d.\n", dev, name, num); + pr_err("%s is not allowed for a %s container. Consider /dev/md%d.\n", dev, name, num); return -1; } if (name && trustworthy == METADATA) @@ -432,8 +428,7 @@ int open_mddev(char *dev, int report_errors) if (md_get_version(mdfd) <= 0) { close(mdfd); if (report_errors) - pr_err("%s does not appear to be " - "an md device\n", dev); + pr_err("%s does not appear to be an md device\n", dev); return -2; } return mdfd; diff --git a/mdstat.c b/mdstat.c index 8b16d3e8..2972cdf6 100644 --- a/mdstat.c +++ b/mdstat.c @@ -114,7 +114,6 @@ void free_mdstat(struct mdstat_ent *ms) { while (ms) { struct mdstat_ent *t; - free(ms->dev); free(ms->level); free(ms->pattern); free(ms->metadata_version); @@ -169,7 +168,7 @@ struct mdstat_ent *mdstat_read(int hold, int start) strcpy(devnm, line); ent = xmalloc(sizeof(*ent)); - ent->dev = ent->level = ent->pattern= NULL; + ent->level = ent->pattern= NULL; ent->next = NULL; ent->percent = RESYNC_NONE; ent->active = -1; @@ -179,7 +178,6 @@ struct mdstat_ent *mdstat_read(int hold, int start) ent->devcnt = 0; ent->members = NULL; - ent->dev = xstrdup(line); strcpy(ent->devnm, devnm); for (w=dl_next(line); w!= line ; w=dl_next(w)) { diff --git a/misc/mdcheck b/misc/mdcheck index 33570b97..2c8f54d6 100644 --- a/misc/mdcheck +++ b/misc/mdcheck @@ -77,6 +77,7 @@ find /var/lib/mdcheck -name "MD_UUID*" -type f -mtime +180 -exec rm {} \; cnt=0 for dev in /dev/md?* do + [ -e "$dev" ] || continue sys=`sysname $dev` if [ ! -f "$sys/md/sync_action" ] then # cannot check this array @@ -87,7 +88,7 @@ do continue fi - mdadm --detail --export "$dev" > $tmp || continue + mdadm --detail --export "$dev" | grep '^MD_UUID=' > $tmp || continue source $tmp fl="/var/lib/mdcheck/MD_UUID_$MD_UUID" if [ -z "$cont" ] diff --git a/monitor.c b/monitor.c index f81e7075..870cc1a7 100644 --- a/monitor.c +++ b/monitor.c @@ -42,11 +42,11 @@ static void add_fd(fd_set *fds, int *maxfd, int fd) if (fd < 0) return; if (fstat(fd, &st) == -1) { - dprintf("%s: Invalid fd %d\n", __func__, fd); + dprintf("Invalid fd %d\n", fd); return; } if (st.st_nlink == 0) { - dprintf("%s: fd %d was deleted\n", __func__, fd); + dprintf("fd %d was deleted\n", fd); return; } if (fd > *maxfd) @@ -82,8 +82,7 @@ static void read_resync_start(int fd, unsigned long long *v) n = read_attr(buf, 30, fd); if (n <= 0) { - dprintf("%s: Failed to read resync_start (%d)\n", - __func__, fd); + dprintf("Failed to read resync_start (%d)\n", fd); return; } if (strncmp(buf, "none", 4) == 0) @@ -260,8 +259,8 @@ static int read_and_act(struct active_array *a) } gettimeofday(&tv, NULL); - dprintf("%s(%d): %ld.%06ld state:%s prev:%s action:%s prev: %s start:%llu\n", - __func__, a->info.container_member, + dprintf("(%d): %ld.%06ld state:%s prev:%s action:%s prev: %s start:%llu\n", + a->info.container_member, tv.tv_sec, tv.tv_usec, array_states[a->curr_state], array_states[a->prev_state], @@ -422,21 +421,21 @@ static int read_and_act(struct active_array *a) a->last_checkpoint = sync_completed; a->container->ss->sync_metadata(a->container); - dprintf("%s(%d): state:%s action:%s next(", __func__, a->info.container_member, + dprintf("(%d): state:%s action:%s next(", a->info.container_member, array_states[a->curr_state], sync_actions[a->curr_action]); /* Effect state changes in the array */ if (a->next_state != bad_word) { - dprintf(" state:%s", array_states[a->next_state]); + dprintf_cont(" state:%s", array_states[a->next_state]); write_attr(array_states[a->next_state], a->info.state_fd); } if (a->next_action != bad_action) { write_attr(sync_actions[a->next_action], a->action_fd); - dprintf(" action:%s", sync_actions[a->next_action]); + dprintf_cont(" action:%s", sync_actions[a->next_action]); } for (mdi = a->info.devs; mdi ; mdi = mdi->next) { if (mdi->next_state & DS_UNBLOCK) { - dprintf(" %d:-blocked", mdi->disk.raid_disk); + dprintf_cont(" %d:-blocked", mdi->disk.raid_disk); write_attr("-blocked", mdi->state_fd); } @@ -449,7 +448,7 @@ static int read_and_act(struct active_array *a) */ remove_result = write_attr("remove", mdi->state_fd); if (remove_result > 0) { - dprintf(" %d:removed", mdi->disk.raid_disk); + dprintf_cont(" %d:removed", mdi->disk.raid_disk); close(mdi->state_fd); close(mdi->recovery_fd); mdi->state_fd = -1; @@ -458,10 +457,10 @@ static int read_and_act(struct active_array *a) } if (mdi->next_state & DS_INSYNC) { write_attr("+in_sync", mdi->state_fd); - dprintf(" %d:+in_sync", mdi->disk.raid_disk); + dprintf_cont(" %d:+in_sync", mdi->disk.raid_disk); } } - dprintf(" )\n"); + dprintf_cont(" )\n"); /* move curr_ to prev_ */ a->prev_state = a->curr_state; diff --git a/msg.c b/msg.c index 2e64589b..754630b9 100644 --- a/msg.c +++ b/msg.c @@ -395,7 +395,7 @@ int block_monitor(char *container, const int freeze) sysfs_free(sra); sra = sysfs_read(-1, e2->devnm, GET_VERSION); if (unblock_subarray(sra, freeze)) - pr_err("Failed to unfreeze %s\n", e2->dev); + pr_err("Failed to unfreeze %s\n", e2->devnm); } ping_monitor(container); /* cleared frozen */ @@ -431,7 +431,7 @@ void unblock_monitor(char *container, const int unfreeze) if (sra->array.level > 0) to_ping++; if (unblock_subarray(sra, unfreeze)) - pr_err("Failed to unfreeze %s\n", e->dev); + pr_err("Failed to unfreeze %s\n", e->devnm); } if (to_ping) ping_monitor(container); diff --git a/platform-intel.c b/platform-intel.c index f347382a..edb86795 100644 --- a/platform-intel.c +++ b/platform-intel.c @@ -59,11 +59,14 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) struct sys_dev *list = NULL; enum sys_dev_type type; unsigned long long dev_id; + unsigned long long class; if (strcmp(driver, "isci") == 0) type = SYS_DEV_SAS; else if (strcmp(driver, "ahci") == 0) type = SYS_DEV_SATA; + else if (strcmp(driver, "nvme") == 0) + type = SYS_DEV_NVME; else type = SYS_DEV_UNKNOWN; @@ -99,6 +102,9 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) if (devpath_to_ll(path, "device", &dev_id) != 0) continue; + if (devpath_to_ll(path, "class", &class) != 0) + continue; + /* start / add list entry */ if (!head) { head = xmalloc(sizeof(*head)); @@ -114,6 +120,7 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) } list->dev_id = (__u16) dev_id; + list->class = (__u32) class; list->type = type; list->path = realpath(path, NULL); list->next = NULL; @@ -127,14 +134,14 @@ struct sys_dev *find_driver_devices(const char *bus, const char *driver) static struct sys_dev *intel_devices=NULL; static time_t valid_time = 0; -static enum sys_dev_type device_type_by_id(__u16 device_id) +struct sys_dev *device_by_id(__u16 device_id) { struct sys_dev *iter; - for(iter = intel_devices; iter != NULL; iter = iter->next) + for (iter = intel_devices; iter != NULL; iter = iter->next) if (iter->dev_id == device_id) - return iter->type; - return SYS_DEV_UNKNOWN; + return iter; + return NULL; } static int devpath_to_ll(const char *dev_path, const char *entry, unsigned long long *val) @@ -179,7 +186,7 @@ static __u16 devpath_to_vendor(const char *dev_path) struct sys_dev *find_intel_devices(void) { - struct sys_dev *ahci, *isci; + struct sys_dev *ahci, *isci, *nvme; if (valid_time > time(0) - 10) return intel_devices; @@ -189,14 +196,24 @@ struct sys_dev *find_intel_devices(void) isci = find_driver_devices("pci", "isci"); ahci = find_driver_devices("pci", "ahci"); + nvme = find_driver_devices("pci", "nvme"); - if (!ahci) { + if (!isci && !ahci) { + ahci = nvme; + } else if (!ahci) { ahci = isci; + struct sys_dev *elem = ahci; + while (elem->next) + elem = elem->next; + elem->next = nvme; } else { struct sys_dev *elem = ahci; while (elem->next) elem = elem->next; elem->next = isci; + while (elem->next) + elem = elem->next; + elem->next = nvme; } intel_devices = ahci; valid_time = time(0); @@ -209,16 +226,82 @@ struct pciExpDataStructFormat { __u8 ver[4]; __u16 vendorID; __u16 deviceID; + __u16 devListOffset; + __u16 pciDataStructLen; + __u8 pciDataStructRev; } __attribute__ ((packed)); -static struct imsm_orom imsm_orom[SYS_DEV_MAX]; -static int populated_orom[SYS_DEV_MAX]; +struct orom_entry *orom_entries; + +const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id) +{ + struct orom_entry *entry; + struct devid_list *devid; + + for (entry = orom_entries; entry; entry = entry->next) { + for (devid = entry->devid_list; devid; devid = devid->next) { + if (devid->devid == dev_id) + return entry; + } + } + + return NULL; +} + +const struct imsm_orom *get_orom_by_device_id(__u16 dev_id) +{ + const struct orom_entry *entry = get_orom_entry_by_device_id(dev_id); + + if (entry) + return &entry->orom; + + return NULL; +} + +static struct orom_entry *add_orom(const struct imsm_orom *orom) +{ + struct orom_entry *list; + struct orom_entry *prev = NULL; + + for (list = orom_entries; list; prev = list, list = list->next) + ; + + list = xmalloc(sizeof(struct orom_entry)); + list->orom = *orom; + list->devid_list = NULL; + list->next = NULL; + + if (prev == NULL) + orom_entries = list; + else + prev->next = list; + + return list; +} + +static void add_orom_device_id(struct orom_entry *entry, __u16 dev_id) +{ + struct devid_list *list; + struct devid_list *prev = NULL; + + for (list = entry->devid_list; list; prev = list, list = list->next) { + if (list->devid == dev_id) + return; + } + list = xmalloc(sizeof(struct devid_list)); + list->devid = dev_id; + list->next = NULL; + + if (prev == NULL) + entry->devid_list = list; + else + prev->next = list; +} static int scan(const void *start, const void *end, const void *data) { int offset; - const struct imsm_orom *imsm_mem; - int dev; + const struct imsm_orom *imsm_mem = NULL; int len = (end - start); struct pciExpDataStructFormat *ptr= (struct pciExpDataStructFormat *)data; @@ -231,81 +314,84 @@ static int scan(const void *start, const void *end, const void *data) (ulong) __le16_to_cpu(ptr->vendorID), (ulong) __le16_to_cpu(ptr->deviceID)); - if (__le16_to_cpu(ptr->vendorID) == 0x8086) { - /* serach attached intel devices by device id from OROM */ - dev = device_type_by_id(__le16_to_cpu(ptr->deviceID)); - if (dev == SYS_DEV_UNKNOWN) - return 0; - } - else + if (__le16_to_cpu(ptr->vendorID) != 0x8086) return 0; for (offset = 0; offset < len; offset += 4) { - imsm_mem = start + offset; - if ((memcmp(imsm_mem->signature, "$VER", 4) == 0)) { - imsm_orom[dev] = *imsm_mem; - populated_orom[dev] = 1; - return populated_orom[SYS_DEV_SATA] && populated_orom[SYS_DEV_SAS]; + const void *mem = start + offset; + + if ((memcmp(mem, IMSM_OROM_SIGNATURE, 4) == 0)) { + imsm_mem = mem; + break; } } + + if (!imsm_mem) + return 0; + + struct orom_entry *orom = add_orom(imsm_mem); + + /* only PciDataStructure with revision 3 and above supports devices list. */ + if (ptr->pciDataStructRev >= 3 && ptr->devListOffset) { + const __u16 *dev_list = (void *)ptr + ptr->devListOffset; + int i; + + for (i = 0; dev_list[i] != 0; i++) + add_orom_device_id(orom, dev_list[i]); + } else { + add_orom_device_id(orom, __le16_to_cpu(ptr->deviceID)); + } + return 0; } -const struct imsm_orom *imsm_platform_test(enum sys_dev_type hba_id, int *populated, - struct imsm_orom *imsm_orom) +const struct imsm_orom *imsm_platform_test(struct sys_dev *hba) { - memset(imsm_orom, 0, sizeof(*imsm_orom)); - imsm_orom->rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | - IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5; - imsm_orom->sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB | - IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB | - IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB | - IMSM_OROM_SSS_256kB | IMSM_OROM_SSS_512kB | - IMSM_OROM_SSS_1MB | IMSM_OROM_SSS_2MB; - imsm_orom->dpa = IMSM_OROM_DISKS_PER_ARRAY; - imsm_orom->tds = IMSM_OROM_TOTAL_DISKS; - imsm_orom->vpa = IMSM_OROM_VOLUMES_PER_ARRAY; - imsm_orom->vphba = IMSM_OROM_VOLUMES_PER_HBA; - imsm_orom->attr = imsm_orom->rlc | IMSM_OROM_ATTR_ChecksumVerify; - *populated = 1; + struct imsm_orom orom = { + .signature = IMSM_OROM_SIGNATURE, + .rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | + IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5, + .sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB | + IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB | + IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB | + IMSM_OROM_SSS_256kB | IMSM_OROM_SSS_512kB | + IMSM_OROM_SSS_1MB | IMSM_OROM_SSS_2MB, + .dpa = IMSM_OROM_DISKS_PER_ARRAY, + .tds = IMSM_OROM_TOTAL_DISKS, + .vpa = IMSM_OROM_VOLUMES_PER_ARRAY, + .vphba = IMSM_OROM_VOLUMES_PER_HBA + }; + orom.attr = orom.rlc | IMSM_OROM_ATTR_ChecksumVerify; if (check_env("IMSM_TEST_OROM_NORAID5")) { - imsm_orom->rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | + orom.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | IMSM_OROM_RLC_RAID10; } - if (check_env("IMSM_TEST_AHCI_EFI_NORAID5") && (hba_id == SYS_DEV_SAS)) { - imsm_orom->rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | + if (check_env("IMSM_TEST_AHCI_EFI_NORAID5") && (hba->type == SYS_DEV_SAS)) { + orom.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | IMSM_OROM_RLC_RAID10; } - if (check_env("IMSM_TEST_SCU_EFI_NORAID5") && (hba_id == SYS_DEV_SATA)) { - imsm_orom->rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | + if (check_env("IMSM_TEST_SCU_EFI_NORAID5") && (hba->type == SYS_DEV_SATA)) { + orom.rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | IMSM_OROM_RLC_RAID10; } - return imsm_orom; + struct orom_entry *ret = add_orom(&orom); + + add_orom_device_id(ret, hba->dev_id); + + return &ret->orom; } -static const struct imsm_orom *find_imsm_hba_orom(enum sys_dev_type hba_id) +static const struct imsm_orom *find_imsm_hba_orom(struct sys_dev *hba) { unsigned long align; - if (hba_id >= SYS_DEV_MAX) - return NULL; + if (check_env("IMSM_TEST_OROM")) + return imsm_platform_test(hba); - /* it's static data so we only need to read it once */ - if (populated_orom[hba_id]) { - dprintf("OROM CAP: %p, pid: %d pop: %d\n", - &imsm_orom[hba_id], (int) getpid(), populated_orom[hba_id]); - return &imsm_orom[hba_id]; - } - if (check_env("IMSM_TEST_OROM")) { - dprintf("OROM CAP: %p, pid: %d pop: %d\n", - &imsm_orom[hba_id], (int) getpid(), populated_orom[hba_id]); - return imsm_platform_test(hba_id, &populated_orom[hba_id], &imsm_orom[hba_id]); - } /* return empty OROM capabilities in EFI test mode */ - if (check_env("IMSM_TEST_AHCI_EFI") || - check_env("IMSM_TEST_SCU_EFI")) + if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI")) return NULL; find_intel_devices(); @@ -325,9 +411,7 @@ static const struct imsm_orom *find_imsm_hba_orom(enum sys_dev_type hba_id) scan_adapter_roms(scan); probe_roms_exit(); - if (populated_orom[hba_id]) - return &imsm_orom[hba_id]; - return NULL; + return get_orom_by_device_id(hba->dev_id); } #define GUID_STR_MAX 37 /* according to GUID format: @@ -341,23 +425,58 @@ static const struct imsm_orom *find_imsm_hba_orom(enum sys_dev_type hba_id) (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) #define SYS_EFI_VAR_PATH "/sys/firmware/efi/vars" +#define SYS_EFIVARS_PATH "/sys/firmware/efi/efivars" #define SCU_PROP "RstScuV" #define AHCI_PROP "RstSataV" +#define AHCI_SSATA_PROP "RstsSatV" +#define AHCI_CSATA_PROP "RstCSatV" #define VENDOR_GUID \ EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, 0x1a, 0x04, 0xc6) -int populated_efi[SYS_DEV_MAX] = { 0, 0 }; +#define PCI_CLASS_RAID_CNTRL 0x010400 + +static int read_efi_var(void *buffer, ssize_t buf_size, char *variable_name, struct efi_guid guid) +{ + char path[PATH_MAX]; + char buf[GUID_STR_MAX]; + int fd; + ssize_t n; + + snprintf(path, PATH_MAX, "%s/%s-%s", SYS_EFIVARS_PATH, variable_name, guid_str(buf, guid)); + + fd = open(path, O_RDONLY); + if (fd < 0) + return 1; + + /* read the variable attributes and ignore it */ + n = read(fd, buf, sizeof(__u32)); + if (n < 0) { + close(fd); + return 1; + } + + /* read the variable data */ + n = read(fd, buffer, buf_size); + close(fd); + if (n < buf_size) + return 1; -static struct imsm_orom imsm_efi[SYS_DEV_MAX]; + return 0; +} -int read_efi_variable(void *buffer, ssize_t buf_size, char *variable_name, struct efi_guid guid) +static int read_efi_variable(void *buffer, ssize_t buf_size, char *variable_name, struct efi_guid guid) { char path[PATH_MAX]; char buf[GUID_STR_MAX]; int dfd; ssize_t n, var_data_len; + /* Try to read the variable using the new efivarfs interface first. + * If that fails, fall back to the old sysfs-efivars interface. */ + if (!read_efi_var(buffer, buf_size, variable_name, guid)) + return 0; + snprintf(path, PATH_MAX, "%s/%s-%s/size", SYS_EFI_VAR_PATH, variable_name, guid_str(buf, guid)); dprintf("EFI VAR: path=%s\n", path); @@ -395,55 +514,92 @@ int read_efi_variable(void *buffer, ssize_t buf_size, char *variable_name, struc return 0; } -const struct imsm_orom *find_imsm_efi(enum sys_dev_type hba_id) +const struct imsm_orom *find_imsm_efi(struct sys_dev *hba) { - if (hba_id >= SYS_DEV_MAX) - return NULL; + struct imsm_orom orom; + struct orom_entry *ret; + int err; - dprintf("EFI CAP: %p, pid: %d pop: %d\n", - &imsm_efi[hba_id], (int) getpid(), populated_efi[hba_id]); + if (check_env("IMSM_TEST_AHCI_EFI") || check_env("IMSM_TEST_SCU_EFI")) + return imsm_platform_test(hba); - /* it's static data so we only need to read it once */ - if (populated_efi[hba_id]) { - dprintf("EFI CAP: %p, pid: %d pop: %d\n", - &imsm_efi[hba_id], (int) getpid(), populated_efi[hba_id]); - return &imsm_efi[hba_id]; - } - if (check_env("IMSM_TEST_AHCI_EFI") || - check_env("IMSM_TEST_SCU_EFI")) { - dprintf("OROM CAP: %p, pid: %d pop: %d\n", - &imsm_efi[hba_id], (int) getpid(), populated_efi[hba_id]); - return imsm_platform_test(hba_id, &populated_efi[hba_id], &imsm_efi[hba_id]); - } /* OROM test is set, return that there is no EFI capabilities */ if (check_env("IMSM_TEST_OROM")) return NULL; - if (read_efi_variable(&imsm_efi[hba_id], sizeof(imsm_efi[0]), hba_id == SYS_DEV_SAS ? SCU_PROP : AHCI_PROP, VENDOR_GUID)) { - populated_efi[hba_id] = 0; + if (hba->type == SYS_DEV_SATA && hba->class != PCI_CLASS_RAID_CNTRL) return NULL; + + err = read_efi_variable(&orom, sizeof(orom), hba->type == SYS_DEV_SAS ? SCU_PROP : AHCI_PROP, VENDOR_GUID); + + /* try to read variable for second AHCI controller */ + if (err && hba->type == SYS_DEV_SATA) + err = read_efi_variable(&orom, sizeof(orom), AHCI_SSATA_PROP, VENDOR_GUID); + + /* try to read variable for combined AHCI controllers */ + if (err && hba->type == SYS_DEV_SATA) { + static struct orom_entry *csata; + + err = read_efi_variable(&orom, sizeof(orom), AHCI_CSATA_PROP, VENDOR_GUID); + if (!err) { + if (!csata) + csata = add_orom(&orom); + add_orom_device_id(csata, hba->dev_id); + return &csata->orom; + } } - populated_efi[hba_id] = 1; - return &imsm_efi[hba_id]; + if (err) + return NULL; + + ret = add_orom(&orom); + add_orom_device_id(ret, hba->dev_id); + + return &ret->orom; } -/* - * backward interface compatibility - */ -const struct imsm_orom *find_imsm_orom(void) +const struct imsm_orom *find_imsm_nvme(struct sys_dev *hba) { - return find_imsm_hba_orom(SYS_DEV_SATA); + static struct orom_entry *nvme_orom; + + if (hba->type != SYS_DEV_NVME) + return NULL; + + if (!nvme_orom) { + struct imsm_orom nvme_orom_compat = { + .signature = IMSM_NVME_OROM_COMPAT_SIGNATURE, + .rlc = IMSM_OROM_RLC_RAID0 | IMSM_OROM_RLC_RAID1 | + IMSM_OROM_RLC_RAID10 | IMSM_OROM_RLC_RAID5, + .sss = IMSM_OROM_SSS_4kB | IMSM_OROM_SSS_8kB | + IMSM_OROM_SSS_16kB | IMSM_OROM_SSS_32kB | + IMSM_OROM_SSS_64kB | IMSM_OROM_SSS_128kB, + .dpa = IMSM_OROM_DISKS_PER_ARRAY_NVME, + .tds = IMSM_OROM_TOTAL_DISKS_NVME, + .vpa = IMSM_OROM_VOLUMES_PER_ARRAY, + .vphba = IMSM_OROM_TOTAL_DISKS_NVME / 2 * IMSM_OROM_VOLUMES_PER_ARRAY, + .attr = IMSM_OROM_ATTR_2TB | IMSM_OROM_ATTR_2TB_DISK, + .driver_features = IMSM_OROM_CAPABILITIES_EnterpriseSystem + }; + nvme_orom = add_orom(&nvme_orom_compat); + } + add_orom_device_id(nvme_orom, hba->dev_id); + return &nvme_orom->orom; } -const struct imsm_orom *find_imsm_capability(enum sys_dev_type hba_id) +const struct imsm_orom *find_imsm_capability(struct sys_dev *hba) { - const struct imsm_orom *cap=NULL; + const struct imsm_orom *cap = get_orom_by_device_id(hba->dev_id); - if ((cap = find_imsm_efi(hba_id)) != NULL) + if (cap) return cap; - if ((cap = find_imsm_hba_orom(hba_id)) != NULL) + + if (hba->type == SYS_DEV_NVME) + return find_imsm_nvme(hba); + if ((cap = find_imsm_efi(hba)) != NULL) + return cap; + if ((cap = find_imsm_hba_orom(hba)) != NULL) return cap; + return NULL; } diff --git a/platform-intel.h b/platform-intel.h index 8226be35..695d6c66 100644 --- a/platform-intel.h +++ b/platform-intel.h @@ -22,6 +22,8 @@ /* The IMSM Capability (IMSM AHCI and ISCU OROM/EFI variable) Version Table definition */ struct imsm_orom { __u8 signature[4]; + #define IMSM_OROM_SIGNATURE "$VER" + #define IMSM_NVME_OROM_COMPAT_SIGNATURE "$NVM" __u8 table_ver_major; /* Currently 2 (can change with future revs) */ __u8 table_ver_minor; /* Currently 2 (can change with future revs) */ __u16 major_ver; /* Example: 8 as in 8.6.0.1020 */ @@ -59,12 +61,15 @@ struct imsm_orom { #define IMSM_OROM_SSS_64MB (1 << 15) __u16 dpa; /* Disks Per Array supported */ #define IMSM_OROM_DISKS_PER_ARRAY 6 + #define IMSM_OROM_DISKS_PER_ARRAY_NVME 12 __u16 tds; /* Total Disks Supported */ #define IMSM_OROM_TOTAL_DISKS 6 + #define IMSM_OROM_TOTAL_DISKS_NVME 12 __u8 vpa; /* # Volumes Per Array supported */ #define IMSM_OROM_VOLUMES_PER_ARRAY 2 __u8 vphba; /* # Volumes Per Host Bus Adapter supported */ #define IMSM_OROM_VOLUMES_PER_HBA 4 + #define IMSM_OROM_VOLUMES_PER_HBA_NVME 4 /* Attributes supported. This should map to the * attributes in the MPB. Also, lower 16 bits * should match/duplicate RLC bits above. @@ -168,10 +173,22 @@ static inline int fls(int x) return r; } +static inline int imsm_orom_is_enterprise(const struct imsm_orom *orom) +{ + return !!(orom->driver_features & IMSM_OROM_CAPABILITIES_EnterpriseSystem); +} + +static inline int imsm_orom_is_nvme(const struct imsm_orom *orom) +{ + return memcmp(orom->signature, IMSM_NVME_OROM_COMPAT_SIGNATURE, + sizeof(orom->signature)) == 0; +} + enum sys_dev_type { SYS_DEV_UNKNOWN = 0, SYS_DEV_SAS, SYS_DEV_SATA, + SYS_DEV_NVME, SYS_DEV_MAX }; @@ -180,6 +197,7 @@ struct sys_dev { char *path; char *pci_id; __u16 dev_id; + __u32 class; struct sys_dev *next; }; @@ -187,10 +205,22 @@ struct efi_guid { __u8 b[16]; }; +struct devid_list { + __u16 devid; + struct devid_list *next; +}; + +struct orom_entry { + struct imsm_orom orom; + struct devid_list *devid_list; + struct orom_entry *next; +}; + +extern struct orom_entry *orom_entries; + static inline char *guid_str(char *buf, struct efi_guid guid) { - sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x-%02x%02x%02x%02x%02x%02x", + sprintf(buf, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid.b[3], guid.b[2], guid.b[1], guid.b[0], guid.b[5], guid.b[4], guid.b[7], guid.b[6], guid.b[8], guid.b[9], guid.b[10], guid.b[11], @@ -201,10 +231,13 @@ static inline char *guid_str(char *buf, struct efi_guid guid) char *diskfd_to_devpath(int fd); struct sys_dev *find_driver_devices(const char *bus, const char *driver); struct sys_dev *find_intel_devices(void); -const struct imsm_orom *find_imsm_capability(enum sys_dev_type hba_id); +const struct imsm_orom *find_imsm_capability(struct sys_dev *hba); const struct imsm_orom *find_imsm_orom(void); int disk_attached_to_hba(int fd, const char *hba_path); int devt_attached_to_hba(dev_t dev, const char *hba_path); char *devt_to_devpath(dev_t dev); int path_attached_to_hba(const char *disk_path, const char *hba_path); const char *get_sys_dev_type(enum sys_dev_type); +const struct orom_entry *get_orom_entry_by_device_id(__u16 dev_id); +const struct imsm_orom *get_orom_by_device_id(__u16 device_id); +struct sys_dev *device_by_id(__u16 device_id); diff --git a/policy.c b/policy.c index ef83621a..064d3491 100644 --- a/policy.c +++ b/policy.c @@ -727,16 +727,14 @@ void policy_save_path(char *id_path, struct map_ent *array) FILE *f = NULL; if (mkdir(FAILED_SLOTS_DIR, S_IRWXU) < 0 && errno != EEXIST) { - pr_err("can't create file to save path " - "to old disk: %s\n", strerror(errno)); + pr_err("can't create file to save path to old disk: %s\n", strerror(errno)); return; } snprintf(path, PATH_MAX, FAILED_SLOTS_DIR "/%s", id_path); f = fopen(path, "w"); if (!f) { - pr_err("can't create file to" - " save path to old disk: %s\n", + pr_err("can't create file to save path to old disk: %s\n", strerror(errno)); return; } @@ -745,8 +743,7 @@ void policy_save_path(char *id_path, struct map_ent *array) array->metadata, array->uuid[0], array->uuid[1], array->uuid[2], array->uuid[3]) <= 0) - pr_err("Failed to write to " - " cookie\n"); + pr_err("Failed to write to cookie\n"); fclose(f); } diff --git a/raid6check.c b/raid6check.c index 1d8ac40d..cb8522e5 100644 --- a/raid6check.c +++ b/raid6check.c @@ -30,6 +30,8 @@ #define CHECK_PAGE_BITS (12) #define CHECK_PAGE_SIZE (1 << CHECK_PAGE_BITS) +char const Name[] = "raid6check"; + enum repair { NO_REPAIR = 0, MANUAL_REPAIR, @@ -38,12 +40,14 @@ enum repair { int geo_map(int block, unsigned long long stripe, int raid_disks, int level, int layout); +int is_ddf(int layout); void qsyndrome(uint8_t *p, uint8_t *q, uint8_t **sources, int disks, int size); void make_tables(void); void ensure_zero_has_size(int chunk_size); -void raid6_datap_recov(int disks, size_t bytes, int faila, uint8_t **ptrs); +void raid6_datap_recov(int disks, size_t bytes, int faila, uint8_t **ptrs, + int neg_offset); void raid6_2data_recov(int disks, size_t bytes, int faila, int failb, - uint8_t **ptrs); + uint8_t **ptrs, int neg_offset); void xor_blocks(char *target, char **sources, int disks, int size); /* Collect per stripe consistency information */ @@ -157,38 +161,39 @@ int unlock_all_stripes(struct mdinfo *info, sighandler_t *sig) { } /* Autorepair */ -int autorepair(int *disk, int diskP, int diskQ, unsigned long long start, int chunk_size, - char *name[], int raid_disks, int data_disks, char **blocks_page, - char **blocks, uint8_t *p, char **stripes, int *block_index_for_slot, +int autorepair(int *disk, unsigned long long start, int chunk_size, + char *name[], int raid_disks, int syndrome_disks, char **blocks_page, + char **blocks, uint8_t *p, int *block_index_for_slot, int *source, unsigned long long *offsets) { int i, j; int pages_to_write_count = 0; int page_to_write[chunk_size >> CHECK_PAGE_BITS]; for(j = 0; j < (chunk_size >> CHECK_PAGE_BITS); j++) { - if (disk[j] >= 0) { - printf("Auto-repairing slot %d (%s)\n", disk[j], name[disk[j]]); + if (disk[j] >= -2 && block_index_for_slot[disk[j]] >= 0) { + int slot = block_index_for_slot[disk[j]]; + printf("Auto-repairing slot %d (%s)\n", slot, name[slot]); pages_to_write_count++; page_to_write[j] = 1; - for(i = 0; i < raid_disks; i++) { + for(i = -2; i < syndrome_disks; i++) { blocks_page[i] = blocks[i] + j * CHECK_PAGE_SIZE; } - if (disk[j] == diskQ) { - qsyndrome(p, (uint8_t*)stripes[diskQ] + j * CHECK_PAGE_SIZE, (uint8_t**)blocks_page, data_disks, CHECK_PAGE_SIZE); + if (disk[j] == -2) { + qsyndrome(p, (uint8_t*)blocks_page[-2], + (uint8_t**)blocks_page, + syndrome_disks, CHECK_PAGE_SIZE); } else { - char *all_but_failed_blocks[data_disks]; - int failed_block_index = block_index_for_slot[disk[j]]; - for(i = 0; i < data_disks; i++) { - if (failed_block_index == i) { - all_but_failed_blocks[i] = stripes[diskP] + j * CHECK_PAGE_SIZE; - } - else { + char *all_but_failed_blocks[syndrome_disks]; + for(i = 0; i < syndrome_disks; i++) { + if (i == disk[j]) + all_but_failed_blocks[i] = blocks_page[-1]; + else all_but_failed_blocks[i] = blocks_page[i]; - } } - xor_blocks(stripes[disk[j]] + j * CHECK_PAGE_SIZE, - all_but_failed_blocks, data_disks, CHECK_PAGE_SIZE); + xor_blocks(blocks_page[disk[j]], + all_but_failed_blocks, syndrome_disks, + CHECK_PAGE_SIZE); } } else { @@ -200,8 +205,11 @@ int autorepair(int *disk, int diskP, int diskQ, unsigned long long start, int ch int write_res = 0; for(j = 0; j < (chunk_size >> CHECK_PAGE_BITS); j++) { if(page_to_write[j] == 1) { - lseek64(source[disk[j]], offsets[disk[j]] + start * chunk_size + j * CHECK_PAGE_SIZE, SEEK_SET); - write_res += write(source[disk[j]], stripes[disk[j]] + j * CHECK_PAGE_SIZE, CHECK_PAGE_SIZE); + int slot = block_index_for_slot[disk[j]]; + lseek64(source[slot], offsets[slot] + start * chunk_size + j * CHECK_PAGE_SIZE, SEEK_SET); + write_res += write(source[slot], + blocks[disk[j]] + j * CHECK_PAGE_SIZE, + CHECK_PAGE_SIZE); } } @@ -215,101 +223,78 @@ int autorepair(int *disk, int diskP, int diskQ, unsigned long long start, int ch } /* Manual repair */ -int manual_repair(int diskP, int diskQ, int chunk_size, int raid_disks, int data_disks, - int failed_disk1, int failed_disk2, unsigned long long start, int *block_index_for_slot, - char *name[], char **stripes, char **blocks, uint8_t *p, struct mdinfo *info, sighandler_t *sig, +int manual_repair(int chunk_size, int syndrome_disks, + int failed_slot1, int failed_slot2, + unsigned long long start, int *block_index_for_slot, + char *name[], char **stripes, char **blocks, uint8_t *p, int *source, unsigned long long *offsets) { - int err = 0; int i; + int fd1 = block_index_for_slot[failed_slot1]; + int fd2 = block_index_for_slot[failed_slot2]; printf("Repairing stripe %llu\n", start); printf("Assuming slots %d (%s) and %d (%s) are incorrect\n", - failed_disk1, name[failed_disk1], - failed_disk2, name[failed_disk2]); + fd1, name[fd1], + fd2, name[fd2]); - if (failed_disk1 == diskQ || failed_disk2 == diskQ) { - char *all_but_failed_blocks[data_disks]; + if (failed_slot1 == -2 || failed_slot2 == -2) { + char *all_but_failed_blocks[syndrome_disks]; int failed_data_or_p; - int failed_block_index; - if (failed_disk1 == diskQ) { - failed_data_or_p = failed_disk2; - } - else { - failed_data_or_p = failed_disk1; - } + if (failed_slot1 == -2) + failed_data_or_p = failed_slot2; + else + failed_data_or_p = failed_slot1; + printf("Repairing D/P(%d) and Q\n", failed_data_or_p); - failed_block_index = block_index_for_slot[failed_data_or_p]; - for (i = 0; i < data_disks; i++) { - if (failed_block_index == i) { - all_but_failed_blocks[i] = stripes[diskP]; - } - else { + + for (i = 0; i < syndrome_disks; i++) { + if (i == failed_data_or_p) + all_but_failed_blocks[i] = blocks[-1]; + else all_but_failed_blocks[i] = blocks[i]; - } } - xor_blocks(stripes[failed_data_or_p], - all_but_failed_blocks, data_disks, chunk_size); - qsyndrome(p, (uint8_t*)stripes[diskQ], (uint8_t**)blocks, data_disks, chunk_size); - } - else { + xor_blocks(blocks[failed_data_or_p], + all_but_failed_blocks, syndrome_disks, chunk_size); + qsyndrome(p, (uint8_t*)blocks[-2], (uint8_t**)blocks, + syndrome_disks, chunk_size); + } else { ensure_zero_has_size(chunk_size); - if (failed_disk1 == diskP || failed_disk2 == diskP) { - int failed_data, failed_block_index; - if (failed_disk1 == diskP) { - failed_data = failed_disk2; - } - else { - failed_data = failed_disk1; - } - failed_block_index = block_index_for_slot[failed_data]; - printf("Repairing D(%d) and P\n", failed_data); - raid6_datap_recov(raid_disks, chunk_size, failed_block_index, (uint8_t**)blocks); - } - else { + if (failed_slot1 == -1 || failed_slot2 == -1) { + int failed_data; + if (failed_slot1 == -1) + failed_data = failed_slot2; + else + failed_data = failed_slot1; + printf("Repairing D(%d) and P\n", failed_data); + raid6_datap_recov(syndrome_disks+2, chunk_size, + failed_data, (uint8_t**)blocks, 1); + } else { printf("Repairing D and D\n"); - int failed_block_index1 = block_index_for_slot[failed_disk1]; - int failed_block_index2 = block_index_for_slot[failed_disk2]; - if (failed_block_index1 > failed_block_index2) { - int t = failed_block_index1; - failed_block_index1 = failed_block_index2; - failed_block_index2 = t; - } - raid6_2data_recov(raid_disks, chunk_size, failed_block_index1, failed_block_index2, (uint8_t**)blocks); - } - } - - err = lock_stripe(info, start, chunk_size, data_disks, sig); - if(err != 0) { - if (err != 2) { - return -1; + raid6_2data_recov(syndrome_disks+2, chunk_size, + failed_slot1, failed_slot2, + (uint8_t**)blocks, 1); } - return -2;; } int write_res1, write_res2; off64_t seek_res; - seek_res = lseek64(source[failed_disk1], - offsets[failed_disk1] + start * chunk_size, SEEK_SET); + seek_res = lseek64(source[fd1], + offsets[fd1] + start * chunk_size, SEEK_SET); if (seek_res < 0) { fprintf(stderr, "lseek failed for failed_disk1\n"); return -1; } - write_res1 = write(source[failed_disk1], stripes[failed_disk1], chunk_size); + write_res1 = write(source[fd1], blocks[failed_slot1], chunk_size); - seek_res = lseek64(source[failed_disk2], - offsets[failed_disk2] + start * chunk_size, SEEK_SET); + seek_res = lseek64(source[fd2], + offsets[fd2] + start * chunk_size, SEEK_SET); if (seek_res < 0) { - fprintf(stderr, "lseek failed for failed_disk1\n"); + fprintf(stderr, "lseek failed for failed_disk2\n"); return -1; } - write_res2 = write(source[failed_disk2], stripes[failed_disk2], chunk_size); - - err = unlock_all_stripes(info, sig); - if(err != 0) { - return -2; - } + write_res2 = write(source[fd2], blocks[failed_slot2], chunk_size); if (write_res1 != chunk_size || write_res2 != chunk_size) { fprintf(stderr, "Failed to write a complete chunk.\n"); @@ -325,19 +310,38 @@ int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets, enum repair repair, int failed_disk1, int failed_disk2) { /* read the data and p and q blocks, and check we got them right */ - char *stripe_buf = xmalloc(raid_disks * chunk_size); + int data_disks = raid_disks - 2; + int syndrome_disks = data_disks + is_ddf(layout) * 2; + char *stripe_buf; + + /* stripes[] is indexed by raid_disk and holds chunks from each device */ char **stripes = xmalloc(raid_disks * sizeof(char*)); - char **blocks = xmalloc(raid_disks * sizeof(char*)); - char **blocks_page = xmalloc(raid_disks * sizeof(char*)); - int *block_index_for_slot = xmalloc(raid_disks * sizeof(int)); + + /* blocks[] is indexed by syndrome number and points to either one of the + * chunks from 'stripes[]', or to a chunk of zeros. -1 and -2 are + * P and Q */ + char **blocks = xmalloc((syndrome_disks + 2) * sizeof(char*)); + + /* blocks_page[] is a temporary index to just one page of the chunks + * that blocks[] points to. */ + char **blocks_page = xmalloc((syndrome_disks + 2) * sizeof(char*)); + + /* block_index_for_slot[] provides the reverse mapping from blocks to stripes. + * The index is a syndrome position, the content is a raid_disk number. + * indicies -1 and -2 work, and are P and Q disks */ + int *block_index_for_slot = xmalloc((syndrome_disks+2) * sizeof(int)); + + /* 'p' and 'q' contain calcualted P and Q, to be compared with + * blocks[-1] and blocks[-2]; + */ uint8_t *p = xmalloc(chunk_size); uint8_t *q = xmalloc(chunk_size); + char *zero = xmalloc(chunk_size); int *results = xmalloc(chunk_size * sizeof(int)); sighandler_t *sig = xmalloc(3 * sizeof(sighandler_t)); int i, j; - int diskP, diskQ; - int data_disks = raid_disks - 2; + int diskP, diskQ, diskD; int err = 0; extern int tables_ready; @@ -345,10 +349,20 @@ int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets, if (!tables_ready) make_tables(); + posix_memalign((void**)&stripe_buf, 4096, raid_disks * chunk_size); + block_index_for_slot += 2; + blocks += 2; + blocks_page += 2; + + memset(zero, 0, chunk_size); for ( i = 0 ; i < raid_disks ; i++) stripes[i] = stripe_buf + i * chunk_size; while (length > 0) { + /* The syndrome number of the broken disk is recorded + * in 'disk[]' which allows a different broken disk for + * each page. + */ int disk[chunk_size >> CHECK_PAGE_BITS]; err = lock_stripe(info, start, chunk_size, data_disks, sig); @@ -375,40 +389,68 @@ int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets, } } - for (i = 0 ; i < data_disks ; i++) { - int disk = geo_map(i, start, raid_disks, level, layout); - blocks[i] = stripes[disk]; - block_index_for_slot[disk] = i; - } - - qsyndrome(p, q, (uint8_t**)blocks, data_disks, chunk_size); diskP = geo_map(-1, start, raid_disks, level, layout); + block_index_for_slot[-1] = diskP; + blocks[-1] = stripes[diskP]; + diskQ = geo_map(-2, start, raid_disks, level, layout); - blocks[data_disks] = stripes[diskP]; - block_index_for_slot[diskP] = data_disks; - blocks[data_disks+1] = stripes[diskQ]; - block_index_for_slot[diskQ] = data_disks+1; + block_index_for_slot[-2] = diskQ; + blocks[-2] = stripes[diskQ]; + + if (!is_ddf(layout)) { + /* The syndrome-order of disks starts immediately after 'Q', + * but skips P */ + diskD = diskQ; + for (i = 0 ; i < data_disks ; i++) { + diskD = diskD + 1; + if (diskD >= raid_disks) + diskD = 0; + if (diskD == diskP) + diskD += 1; + if (diskD >= raid_disks) + diskD = 0; + blocks[i] = stripes[diskD]; + block_index_for_slot[i] = diskD; + } + } else { + /* The syndrome-order exactly follows raid-disk + * numbers, with ZERO in place of P and Q + */ + for (i = 0 ; i < raid_disks; i++) { + if (i == diskP || i == diskQ) { + blocks[i] = zero; + block_index_for_slot[i] = -1; + } else { + blocks[i] = stripes[i]; + block_index_for_slot[i] = i; + } + } + } + + qsyndrome(p, q, (uint8_t**)blocks, syndrome_disks, chunk_size); raid6_collect(chunk_size, p, q, stripes[diskP], stripes[diskQ], results); raid6_stats(disk, results, raid_disks, chunk_size); for(j = 0; j < (chunk_size >> CHECK_PAGE_BITS); j++) { - if(disk[j] >= -2) { - disk[j] = geo_map(disk[j], start, raid_disks, level, layout); - } - if(disk[j] >= 0) { - printf("Error detected at stripe %llu, page %d: possible failed disk slot: %d --> %s\n", - start, j, disk[j], name[disk[j]]); - } - if(disk[j] == -65535) { + int role = disk[j]; + if (role >= -2) { + int slot = block_index_for_slot[role]; + if (slot >= 0) + printf("Error detected at stripe %llu, page %d: possible failed disk slot %d: %d --> %s\n", + start, j, role, slot, name[slot]); + else + printf("Error detected at stripe %llu, page %d: failed slot %d should be zeros\n", + start, j, role); + } else if(disk[j] == -65535) { printf("Error detected at stripe %llu, page %d: disk slot unknown\n", start, j); } } if(repair == AUTO_REPAIR) { - err = autorepair(disk, diskP, diskQ, start, chunk_size, - name, raid_disks, data_disks, blocks_page, - blocks, p, stripes, block_index_for_slot, + err = autorepair(disk, start, chunk_size, + name, raid_disks, syndrome_disks, blocks_page, + blocks, p, block_index_for_slot, source, offsets); if(err != 0) { unlock_all_stripes(info, sig); @@ -416,22 +458,30 @@ int check_stripes(struct mdinfo *info, int *source, unsigned long long *offsets, } } - err = unlock_all_stripes(info, sig); - if(err != 0) { - goto exitCheck; - } - if(repair == MANUAL_REPAIR) { - err = manual_repair(diskP, diskQ, chunk_size, raid_disks, data_disks, - failed_disk1, failed_disk2, start, block_index_for_slot, - name, stripes, blocks, p, info, sig, - source, offsets); + int failed_slot1 = -1, failed_slot2 = -1; + for (i = -2; i < syndrome_disks; i++) { + if (block_index_for_slot[i] == failed_disk1) + failed_slot1 = i; + if (block_index_for_slot[i] == failed_disk2) + failed_slot2 = i; + } + err = manual_repair(chunk_size, syndrome_disks, + failed_slot1, failed_slot2, + start, block_index_for_slot, + name, stripes, blocks, p, + source, offsets); if(err == -1) { unlock_all_stripes(info, sig); goto exitCheck; } } + err = unlock_all_stripes(info, sig); + if(err != 0) { + goto exitCheck; + } + length--; start++; } @@ -440,9 +490,9 @@ exitCheck: free(stripe_buf); free(stripes); - free(blocks); - free(blocks_page); - free(block_index_for_slot); + free(blocks-2); + free(blocks_page-2); + free(block_index_for_slot-2); free(p); free(q); free(results); @@ -626,7 +676,7 @@ int main(int argc, char *argv[]) if(disk_slot >= 0) { disk_name[disk_slot] = map_dev(comp->disk.major, comp->disk.minor, 0); offsets[disk_slot] = comp->data_offset * 512; - fds[disk_slot] = open(disk_name[disk_slot], O_RDWR | O_SYNC); + fds[disk_slot] = open(disk_name[disk_slot], O_RDWR | O_DIRECT); if (fds[disk_slot] < 0) { perror(disk_name[disk_slot]); fprintf(stderr,"%s: cannot open %s\n", prg, disk_name[disk_slot]); @@ -642,8 +692,7 @@ int main(int argc, char *argv[]) raid_disks, chunk_size, level, layout, start, length, disk_name, repair, failed_disk1, failed_disk2); if (rv != 0) { - fprintf(stderr, - "%s: check_stripes returned %d\n", prg, rv); + fprintf(stderr, "%s: check_stripes returned %d\n", prg, rv); exit_err = 7; goto exitHere; } diff --git a/restripe.c b/restripe.c index 93ef056e..4d921904 100644 --- a/restripe.c +++ b/restripe.c @@ -194,7 +194,8 @@ int geo_map(int block, unsigned long long stripe, int raid_disks, } return -1; } -static int is_ddf(int layout) + +int is_ddf(int layout) { switch (layout) { @@ -344,16 +345,28 @@ void ensure_zero_has_size(int chunk_size) /* Following was taken from linux/drivers/md/raid6recov.c */ /* Recover two failed data blocks. */ + void raid6_2data_recov(int disks, size_t bytes, int faila, int failb, - uint8_t **ptrs) + uint8_t **ptrs, int neg_offset) { uint8_t *p, *q, *dp, *dq; uint8_t px, qx, db; const uint8_t *pbmul; /* P multiplier table for B data */ const uint8_t *qmul; /* Q multiplier table (for both) */ - p = ptrs[disks-2]; - q = ptrs[disks-1]; + if (faila > failb) { + int t = faila; + faila = failb; + failb = t; + } + + if (neg_offset) { + p = ptrs[-1]; + q = ptrs[-2]; + } else { + p = ptrs[disks-2]; + q = ptrs[disks-1]; + } /* Compute syndrome with zero for the missing data pages Use the dead data pages as temporary storage for @@ -384,13 +397,19 @@ void raid6_2data_recov(int disks, size_t bytes, int faila, int failb, } /* Recover failure of one data block plus the P block */ -void raid6_datap_recov(int disks, size_t bytes, int faila, uint8_t **ptrs) +void raid6_datap_recov(int disks, size_t bytes, int faila, uint8_t **ptrs, + int neg_offset) { uint8_t *p, *q, *dq; const uint8_t *qmul; /* Q multiplier table */ - p = ptrs[disks-2]; - q = ptrs[disks-1]; + if (neg_offset) { + p = ptrs[-1]; + q = ptrs[-2]; + } else { + p = ptrs[disks-2]; + q = ptrs[disks-1]; + } /* Compute syndrome with zero for the missing data page Use the dead data page as temporary storage for delta q */ @@ -636,16 +655,11 @@ int save_stripes(int *source, unsigned long long *offsets, if (fblock[1] == data_disks) /* One data failed, and parity failed */ raid6_datap_recov(syndrome_disks+2, chunk_size, - fdisk[0], bufs); + fdisk[0], bufs, 0); else { - if (fdisk[0] > fdisk[1]) { - int t = fdisk[0]; - fdisk[0] = fdisk[1]; - fdisk[1] = t; - } /* Two data blocks failed, P,Q OK */ raid6_2data_recov(syndrome_disks+2, chunk_size, - fdisk[0], fdisk[1], bufs); + fdisk[0], fdisk[1], bufs, 0); } } if (dest) { @@ -882,7 +896,8 @@ unsigned long long getnum(char *str, char **err) return rv; } -main(int argc, char *argv[]) +char const Name[] = "test_restripe"; +int main(int argc, char *argv[]) { /* save/restore file raid_disks chunk_size level layout start length devices... */ @@ -898,8 +913,7 @@ main(int argc, char *argv[]) char *err = NULL; if (argc < 10) { - fprintf(stderr, "Usage: test_stripe save/restore file raid_disks" - " chunk_size level layout start length devices...\n"); + fprintf(stderr, "Usage: test_stripe save/restore file raid_disks chunk_size level layout start length devices...\n"); exit(1); } if (strcmp(argv[1], "save")==0) diff --git a/sha1.h b/sha1.h index 0f986585..999fc6a3 100644 --- a/sha1.h +++ b/sha1.h @@ -22,7 +22,7 @@ #include -#if 1 /* defined HAVE_LIMITS_H || _LIBC */ +#if defined HAVE_LIMITS_H || _LIBC # include #endif @@ -33,9 +33,9 @@ the resulting executable. Locally running cross-compiled executables is usually not possible. */ -#if 1 /* def _LIBC */ -# include -typedef uint32_t sha1_uint32; +#ifdef _LIBC +# include +typedef u_int32_t sha1_uint32; typedef uintptr_t sha1_uintptr; #else # define INT_MAX_32_BITS 2147483647 diff --git a/super-ddf.c b/super-ddf.c index bc0ce2c0..faaf0a7c 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -541,15 +541,15 @@ static int init_super_ddf_bvd(struct supertype *st, static void pr_state(struct ddf_super *ddf, const char *msg) { unsigned int i; - dprintf("%s/%s: ", __func__, msg); + dprintf("%s: ", msg); for (i = 0; i < be16_to_cpu(ddf->active->max_vd_entries); i++) { if (all_ff(ddf->virt->entries[i].guid)) continue; - dprintf("%u(s=%02x i=%02x) ", i, + dprintf_cont("%u(s=%02x i=%02x) ", i, ddf->virt->entries[i].state, ddf->virt->entries[i].init_state); } - dprintf("\n"); + dprintf_cont("\n"); } #else static void pr_state(const struct ddf_super *ddf, const char *msg) {} @@ -825,11 +825,11 @@ static int load_ddf_header(int fd, unsigned long long lba, return 0; if (!be32_eq(hdr->magic, DDF_HEADER_MAGIC)) { - pr_err("%s: bad header magic\n", __func__); + pr_err("bad header magic\n"); return 0; } if (!be32_eq(calc_crc(hdr, 512), hdr->crc)) { - pr_err("%s: bad CRC\n", __func__); + pr_err("bad CRC\n"); return 0; } if (memcmp(anchor->guid, hdr->guid, DDF_GUID_LEN) != 0 || @@ -839,7 +839,7 @@ static int load_ddf_header(int fd, unsigned long long lba, hdr->type != type || memcmp(anchor->pad2, hdr->pad2, 512 - offsetof(struct ddf_header, pad2)) != 0) { - pr_err("%s: header mismatch\n", __func__); + pr_err("header mismatch\n"); return 0; } @@ -918,8 +918,7 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname) if (memcmp(super->anchor.revision, DDF_REVISION_0, 8) != 0 && memcmp(super->anchor.revision, DDF_REVISION_2, 8) != 0) { if (devname) - pr_err("can only support super revision" - " %.8s and earlier, not %.8s on %s\n", + pr_err("can only support super revision %.8s and earlier, not %.8s on %s\n", DDF_REVISION_2, super->anchor.revision,devname); return 2; } @@ -928,8 +927,7 @@ static int load_ddf_headers(int fd, struct ddf_super *super, char *devname) dsize >> 9, 1, &super->primary, &super->anchor) == 0) { if (devname) - pr_err("Failed to load primary DDF header " - "on %s\n", devname); + pr_err("Failed to load primary DDF header on %s\n", devname); } else super->active = &super->primary; @@ -1055,8 +1053,7 @@ static int load_ddf_local(int fd, struct ddf_super *super, if (posix_memalign((void**)&dl, 512, sizeof(*dl) + (super->max_part) * sizeof(dl->vlist[0])) != 0) { - pr_err("%s could not allocate disk info buffer\n", - __func__); + pr_err("could not allocate disk info buffer\n"); return 1; } @@ -1116,8 +1113,7 @@ static int load_ddf_local(int fd, struct ddf_super *super, continue; if (posix_memalign((void**)&dl->spare, 512, super->conf_rec_len*512) != 0) { - pr_err("%s could not allocate spare info buf\n", - __func__); + pr_err("could not allocate spare info buf\n"); return 1; } @@ -1148,16 +1144,14 @@ static int load_ddf_local(int fd, struct ddf_super *super, if (posix_memalign((void**)&vcl, 512, (super->conf_rec_len*512 + offsetof(struct vcl, conf))) != 0) { - pr_err("%s could not allocate vcl buf\n", - __func__); + pr_err("could not allocate vcl buf\n"); return 1; } vcl->next = super->conflist; vcl->block_sizes = NULL; /* FIXME not for CONCAT */ vcl->conf.sec_elmnt_count = vd->sec_elmnt_count; if (alloc_other_bvds(super, vcl) != 0) { - pr_err("%s could not allocate other bvds\n", - __func__); + pr_err("could not allocate other bvds\n"); free(vcl); return 1; }; @@ -1193,15 +1187,13 @@ static int load_super_ddf(struct supertype *st, int fd, /* 32M is a lower bound */ if (dsize <= 32*1024*1024) { if (devname) - pr_err("%s is too small for ddf: " - "size is %llu sectors.\n", + pr_err("%s is too small for ddf: size is %llu sectors.\n", devname, dsize>>9); return 1; } if (dsize & 511) { if (devname) - pr_err("%s is an odd size for ddf: " - "size is %llu bytes.\n", + pr_err("%s is an odd size for ddf: size is %llu bytes.\n", devname, dsize); return 1; } @@ -1227,8 +1219,7 @@ static int load_super_ddf(struct supertype *st, int fd, if (rv) { if (devname) - pr_err("Failed to load all information " - "sections on %s\n", devname); + pr_err("Failed to load all information sections on %s\n", devname); free(super); return rv; } @@ -1237,8 +1228,7 @@ static int load_super_ddf(struct supertype *st, int fd, if (rv) { if (devname) - pr_err("Failed to load all information " - "sections on %s\n", devname); + pr_err("Failed to load all information sections on %s\n", devname); free(super); return rv; } @@ -1865,8 +1855,8 @@ static int find_index_in_bvd(const struct ddf_super *ddf, j++; } } - dprintf("%s: couldn't find BVD member %u (total %u)\n", - __func__, n, be16_to_cpu(conf->prim_elmnt_count)); + dprintf("couldn't find BVD member %u (total %u)\n", + n, be16_to_cpu(conf->prim_elmnt_count)); return 0; } @@ -1897,8 +1887,8 @@ static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst, goto bad; } if (v->other_bvds == NULL) { - pr_err("%s: BUG: other_bvds is NULL, nsec=%u\n", - __func__, conf->sec_elmnt_count); + pr_err("BUG: other_bvds is NULL, nsec=%u\n", + conf->sec_elmnt_count); goto bad; } nsec = n / be16_to_cpu(conf->prim_elmnt_count); @@ -1915,13 +1905,13 @@ static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst, if (!find_index_in_bvd(ddf, conf, n - nsec*conf->sec_elmnt_count, n_bvd)) goto bad; - dprintf("%s: found disk %u as member %u in bvd %d of array %u\n" - , __func__, n, *n_bvd, ibvd, inst); + dprintf("found disk %u as member %u in bvd %d of array %u\n", + n, *n_bvd, ibvd, inst); *vcl = v; return conf; } bad: - pr_err("%s: Could't find disk %d in array %u\n", __func__, n, inst); + pr_err("Could't find disk %d in array %u\n", n, inst); return NULL; } #endif @@ -2342,7 +2332,7 @@ static int init_super_ddf(struct supertype *st, data_offset); if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) { - pr_err("%s could not allocate superblock\n", __func__); + pr_err("could not allocate superblock\n"); return 0; } memset(ddf, 0, sizeof(*ddf)); @@ -2477,7 +2467,7 @@ static int init_super_ddf(struct supertype *st, strcpy((char*)ddf->controller.vendor_data, homehost); if (posix_memalign((void**)&pd, 512, pdsize) != 0) { - pr_err("%s could not allocate pd\n", __func__); + pr_err("could not allocate pd\n"); return 0; } ddf->phys = pd; @@ -2493,7 +2483,7 @@ static int init_super_ddf(struct supertype *st, memset(pd->entries[i].guid, 0xff, DDF_GUID_LEN); if (posix_memalign((void**)&vd, 512, vdsize) != 0) { - pr_err("%s could not allocate vd\n", __func__); + pr_err("could not allocate vd\n"); return 0; } ddf->virt = vd; @@ -2672,7 +2662,7 @@ static int init_super_ddf_bvd(struct supertype *st, /* Now create a new vd_config */ if (posix_memalign((void**)&vcl, 512, (offsetof(struct vcl, conf) + ddf->conf_rec_len * 512)) != 0) { - pr_err("%s could not allocate vd_config\n", __func__); + pr_err("could not allocate vd_config\n"); return 0; } vcl->vcnum = venum; @@ -2687,15 +2677,14 @@ static int init_super_ddf_bvd(struct supertype *st, vc->chunk_shift = chunk_to_shift(info->chunk_size); if (layout_md2ddf(info, vc) == -1 || be16_to_cpu(vc->prim_elmnt_count) > ddf->mppe) { - pr_err("%s: unsupported RAID level/layout %d/%d with %d disks\n", - __func__, info->level, info->layout, info->raid_disks); + pr_err("unsupported RAID level/layout %d/%d with %d disks\n", + info->level, info->layout, info->raid_disks); free(vcl); return 0; } vc->sec_elmnt_seq = 0; if (alloc_other_bvds(ddf, vcl) != 0) { - pr_err("%s could not allocate other bvds\n", - __func__); + pr_err("could not allocate other bvds\n"); free(vcl); return 0; } @@ -2814,8 +2803,8 @@ static void add_to_super_ddf_bvd(struct supertype *st, cpu_to_be16(DDF_Global_Spare)); be16_set(ddf->phys->entries[dl->pdnum].type, cpu_to_be16(DDF_Active_in_VD)); - dprintf("%s: added disk %d/%08x to VD %d/%s as disk %d\n", - __func__, dl->pdnum, be32_to_cpu(dl->disk.refnum), + dprintf("added disk %d/%08x to VD %d/%s as disk %d\n", + dl->pdnum, be32_to_cpu(dl->disk.refnum), ddf->currentconf->vcnum, guid_str(vc->guid), dk->raid_disk); ddf_set_updates_pending(ddf, vc); @@ -2846,15 +2835,14 @@ static void _set_config_size(struct phys_disk_entry *pde, const struct dl *dl) if (t < cfs) { __u64 wsp = cfs - t; if (wsp > 1024*1024*2ULL && wsp > dl->size / 16) { - pr_err("%s: %x:%x: workspace size 0x%llx too big, ignoring\n", - __func__, dl->major, dl->minor, - (unsigned long long)wsp); + pr_err("%x:%x: workspace size 0x%llx too big, ignoring\n", + dl->major, dl->minor, (unsigned long long)wsp); } else cfs = t; } pde->config_size = cpu_to_be64(cfs); - dprintf("%s: %x:%x config_size %llx, DDF structure is %llx blocks\n", - __func__, dl->major, dl->minor, + dprintf("%x:%x config_size %llx, DDF structure is %llx blocks\n", + dl->major, dl->minor, (unsigned long long)cfs, (unsigned long long)(dl->size-cfs)); } @@ -2886,23 +2874,20 @@ static int add_to_super_ddf(struct supertype *st, fstat(fd, &stb); n = find_unused_pde(ddf); if (n == DDF_NOTFOUND) { - pr_err("%s: No free slot in array, cannot add disk\n", - __func__); + pr_err("No free slot in array, cannot add disk\n"); return 1; } pde = &ddf->phys->entries[n]; get_dev_size(fd, NULL, &size); if (size <= 32*1024*1024) { - pr_err("%s: device size must be at least 32MB\n", - __func__); + pr_err("device size must be at least 32MB\n"); return 1; } size >>= 9; if (posix_memalign((void**)&dd, 512, sizeof(*dd) + sizeof(dd->vlist[0]) * ddf->max_part) != 0) { - pr_err("%s could allocate buffer for new disk, aborting\n", - __func__); + pr_err("could allocate buffer for new disk, aborting\n"); return 1; } dd->major = major(stb.st_rdev); @@ -3173,6 +3158,7 @@ static int _write_super_to_disk(struct ddf_super *ddf, struct dl *d) memcpy(&ddf->primary, &ddf->anchor, 512); memcpy(&ddf->secondary, &ddf->anchor, 512); + ddf->anchor.type = DDF_HEADER_ANCHOR; ddf->anchor.openflag = 0xFF; /* 'open' means nothing */ ddf->anchor.seq = cpu_to_be32(0xFFFFFFFF); /* no sequencing in anchor */ ddf->anchor.crc = calc_crc(&ddf->anchor, 512); @@ -3439,8 +3425,7 @@ static int validate_geometry_ddf(struct supertype *st, close(fd); /* Just a bare device, no good to us */ if (verbose) - pr_err("ddf: Cannot create this array " - "on device %s - a container is required.\n", + pr_err("ddf: Cannot create this array on device %s - a container is required.\n", dev); return 0; } @@ -3556,8 +3541,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st, } if (dcnt < raiddisks) { if (verbose) - pr_err("ddf: Not enough devices with " - "space for this array (%d < %d)\n", + pr_err("ddf: Not enough devices with space for this array (%d < %d)\n", dcnt, raiddisks); return 0; } @@ -3575,8 +3559,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st, } if (!dl) { if (verbose) - pr_err("ddf: %s is not in the " - "same DDF set\n", + pr_err("ddf: %s is not in the same DDF set\n", dev); return 0; } @@ -3925,8 +3908,7 @@ static int store_super_ddf(struct supertype *st, int fd) int ofd, ret; if (fstat(fd, &sta) == -1 || !S_ISBLK(sta.st_mode)) { - pr_err("%s: file descriptor for invalid device\n", - __func__); + pr_err("file descriptor for invalid device\n"); return 1; } for (dl = ddf->dlist; dl; dl = dl->next) @@ -3934,7 +3916,7 @@ static int store_super_ddf(struct supertype *st, int fd) dl->minor == (int)minor(sta.st_rdev)) break; if (!dl) { - pr_err("%s: couldn't find disk %d/%d\n", __func__, + pr_err("couldn't find disk %d/%d\n", (int)major(sta.st_rdev), (int)minor(sta.st_rdev)); return 1; @@ -3988,7 +3970,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) */ if (!be32_eq(first->active->seq, second->active->seq)) { - dprintf("%s: sequence number mismatch %u<->%u\n", __func__, + dprintf("sequence number mismatch %u<->%u\n", be32_to_cpu(first->active->seq), be32_to_cpu(second->active->seq)); return 0; @@ -4010,7 +3992,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) if (vl1->other_bvds != NULL && vl1->conf.sec_elmnt_seq != vl2->conf.sec_elmnt_seq) { - dprintf("%s: adding BVD %u\n", __func__, + dprintf("adding BVD %u\n", vl2->conf.sec_elmnt_seq); add_other_bvd(vl1, &vl2->conf, first->conf_rec_len*512); @@ -4021,8 +4003,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) if (posix_memalign((void **)&vl1, 512, (first->conf_rec_len*512 + offsetof(struct vcl, conf))) != 0) { - pr_err("%s could not allocate vcl buf\n", - __func__); + pr_err("could not allocate vcl buf\n"); return 3; } @@ -4030,8 +4011,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) vl1->block_sizes = NULL; memcpy(&vl1->conf, &vl2->conf, first->conf_rec_len*512); if (alloc_other_bvds(first, vl1) != 0) { - pr_err("%s could not allocate other bvds\n", - __func__); + pr_err("could not allocate other bvds\n"); free(vl1); return 3; } @@ -4040,7 +4020,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) vl1->conf.guid, DDF_GUID_LEN)) break; vl1->vcnum = vd; - dprintf("%s: added config for VD %u\n", __func__, vl1->vcnum); + dprintf("added config for VD %u\n", vl1->vcnum); first->conflist = vl1; } @@ -4054,8 +4034,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) if (posix_memalign((void **)&dl1, 512, sizeof(*dl1) + (first->max_part) * sizeof(dl1->vlist[0])) != 0) { - pr_err("%s could not allocate disk info buffer\n", - __func__); + pr_err("could not allocate disk info buffer\n"); return 3; } memcpy(dl1, dl2, sizeof(*dl1)); @@ -4070,8 +4049,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) if (dl2->spare) { if (posix_memalign((void **)&dl1->spare, 512, first->conf_rec_len*512) != 0) { - pr_err("%s could not allocate spare info buf\n", - __func__); + pr_err("could not allocate spare info buf\n"); return 3; } memcpy(dl1->spare, dl2->spare, first->conf_rec_len*512); @@ -4090,7 +4068,7 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst) } } first->dlist = dl1; - dprintf("%s: added disk %d: %08x\n", __func__, dl1->pdnum, + dprintf("added disk %d: %08x\n", dl1->pdnum, be32_to_cpu(dl1->disk.refnum)); } @@ -4113,10 +4091,10 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst) static const char faulty[] = "faulty"; if (all_ff(ddf->virt->entries[n].guid)) { - pr_err("%s: subarray %d doesn't exist\n", __func__, n); + pr_err("subarray %d doesn't exist\n", n); return -ENODEV; } - dprintf("%s: new subarray %d, GUID: %s\n", __func__, n, + dprintf("new subarray %d, GUID: %s\n", n, guid_str(ddf->virt->entries[n].guid)); for (dev = a->info.devs; dev; dev = dev->next) { for (dl = ddf->dlist; dl; dl = dl->next) @@ -4124,16 +4102,15 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst) dl->minor == dev->disk.minor) break; if (!dl || dl->pdnum < 0) { - pr_err("%s: device %d/%d of subarray %d not found in meta data\n", - __func__, dev->disk.major, dev->disk.minor, n); + pr_err("device %d/%d of subarray %d not found in meta data\n", + dev->disk.major, dev->disk.minor, n); return -1; } if ((be16_to_cpu(ddf->phys->entries[dl->pdnum].state) & (DDF_Online|DDF_Missing|DDF_Failed)) != DDF_Online) { - pr_err("%s: new subarray %d contains broken device %d/%d (%02x)\n", - __func__, n, dl->major, dl->minor, - be16_to_cpu( - ddf->phys->entries[dl->pdnum].state)); + pr_err("new subarray %d contains broken device %d/%d (%02x)\n", + n, dl->major, dl->minor, + be16_to_cpu(ddf->phys->entries[dl->pdnum].state)); if (write(dev->state_fd, faulty, sizeof(faulty)-1) != sizeof(faulty) - 1) pr_err("Write to state_fd failed\n"); @@ -4357,7 +4334,7 @@ static void ddf_set_disk(struct active_array *a, int n, int state) struct dl *dl; int update = 0; - dprintf("%s: %d to %x\n", __func__, n, state); + dprintf("%d to %x\n", n, state); if (vc == NULL) { dprintf("ddf: cannot find instance %d!!\n", inst); return; @@ -4367,8 +4344,7 @@ static void ddf_set_disk(struct active_array *a, int n, int state) if (mdi->disk.raid_disk == n) break; if (!mdi) { - pr_err("%s: cannot find raid disk %d\n", - __func__, n); + pr_err("cannot find raid disk %d\n", n); return; } @@ -4379,9 +4355,8 @@ static void ddf_set_disk(struct active_array *a, int n, int state) mdi->disk.minor == dl->minor) break; if (!dl) { - pr_err("%s: cannot find raid disk %d (%d/%d)\n", - __func__, n, - mdi->disk.major, mdi->disk.minor); + pr_err("cannot find raid disk %d (%d/%d)\n", + n, mdi->disk.major, mdi->disk.minor); return; } @@ -4389,11 +4364,11 @@ static void ddf_set_disk(struct active_array *a, int n, int state) if (pd < 0 || pd != dl->pdnum) { /* disk doesn't currently exist or has changed. * If it is now in_sync, insert it. */ - dprintf("%s: phys disk not found for %d: %d/%d ref %08x\n", - __func__, dl->pdnum, dl->major, dl->minor, + dprintf("phys disk not found for %d: %d/%d ref %08x\n", + dl->pdnum, dl->major, dl->minor, be32_to_cpu(dl->disk.refnum)); - dprintf("%s: array %u disk %u ref %08x pd %d\n", - __func__, inst, n_bvd, + dprintf("array %u disk %u ref %08x pd %d\n", + inst, n_bvd, be32_to_cpu(vc->phys_refnum[n_bvd]), pd); if ((state & DS_INSYNC) && ! (state & DS_FAULTY) && dl->pdnum >= 0) { @@ -4480,13 +4455,11 @@ static int _kill_subarray_ddf(struct ddf_super *ddf, const char *guid) unsigned int vdnum, i; vdnum = find_vde_by_guid(ddf, guid); if (vdnum == DDF_NOTFOUND) { - pr_err("%s: could not find VD %s\n", __func__, - guid_str(guid)); + pr_err("could not find VD %s\n", guid_str(guid)); return -1; } if (del_from_conflist(&ddf->conflist, guid) == 0) { - pr_err("%s: could not find conf %s\n", __func__, - guid_str(guid)); + pr_err("could not find conf %s\n", guid_str(guid)); return -1; } for (dl = ddf->dlist; dl; dl = dl->next) @@ -4496,7 +4469,7 @@ static int _kill_subarray_ddf(struct ddf_super *ddf, const char *guid) DDF_GUID_LEN)) dl->vlist[i] = NULL; memset(ddf->virt->entries[vdnum].guid, 0xff, DDF_GUID_LEN); - dprintf("%s: deleted %s\n", __func__, guid_str(guid)); + dprintf("deleted %s\n", guid_str(guid)); return 0; } @@ -4513,14 +4486,13 @@ static int kill_subarray_ddf(struct supertype *st) ddf->currentconf = NULL; if (!victim) { - pr_err("%s: nothing to kill\n", __func__); + pr_err("nothing to kill\n"); return -1; } conf = &victim->conf; vdnum = find_vde_by_guid(ddf, conf->guid); if (vdnum == DDF_NOTFOUND) { - pr_err("%s: could not find VD %s\n", __func__, - guid_str(conf->guid)); + pr_err("could not find VD %s\n", guid_str(conf->guid)); return -1; } if (st->update_tail) { @@ -4529,8 +4501,7 @@ static int kill_subarray_ddf(struct supertype *st) + sizeof(struct virtual_entry); vd = xmalloc(len); if (vd == NULL) { - pr_err("%s: failed to allocate %d bytes\n", __func__, - len); + pr_err("failed to allocate %d bytes\n", len); return -1; } memset(vd, 0 , len); @@ -4565,7 +4536,7 @@ static void copy_matching_bvd(struct ddf_super *ddf, return; } } - pr_err("%s: no match for BVD %d of %s in update\n", __func__, + pr_err("no match for BVD %d of %s in update\n", conf->sec_elmnt_seq, guid_str(conf->guid)); } @@ -4637,8 +4608,8 @@ static void ddf_process_virt_update(struct supertype *st, } else { ent = find_vde_by_guid(ddf, vd->entries[0].guid); if (ent != DDF_NOTFOUND) { - dprintf("%s: VD %s exists already in slot %d\n", - __func__, guid_str(vd->entries[0].guid), + dprintf("VD %s exists already in slot %d\n", + guid_str(vd->entries[0].guid), ent); return; } @@ -4650,8 +4621,8 @@ static void ddf_process_virt_update(struct supertype *st, cpu_to_be16( 1 + be16_to_cpu( ddf->virt->populated_vdes)); - dprintf("%s: added VD %s in slot %d(s=%02x i=%02x)\n", - __func__, guid_str(vd->entries[0].guid), ent, + dprintf("added VD %s in slot %d(s=%02x i=%02x)\n", + guid_str(vd->entries[0].guid), ent, ddf->virt->entries[ent].state, ddf->virt->entries[ent].init_state); } @@ -4788,15 +4759,15 @@ static void ddf_process_conf_update(struct supertype *st, vc = (struct vd_config*)update->buf; len = ddf->conf_rec_len * 512; if ((unsigned int)update->len != len * vc->sec_elmnt_count) { - pr_err("%s: %s: insufficient data (%d) for %u BVDs\n", - __func__, guid_str(vc->guid), update->len, + pr_err("%s: insufficient data (%d) for %u BVDs\n", + guid_str(vc->guid), update->len, vc->sec_elmnt_count); return; } for (vcl = ddf->conflist; vcl ; vcl = vcl->next) if (memcmp(vcl->conf.guid, vc->guid, DDF_GUID_LEN) == 0) break; - dprintf("%s: conf update for %s (%s)\n", __func__, + dprintf("conf update for %s (%s)\n", guid_str(vc->guid), (vcl ? "old" : "new")); if (vcl) { /* An update, just copy the phys_refnum and lba_offset @@ -4964,7 +4935,7 @@ static int raid10_degraded(struct mdinfo *info) for (d = info->devs; d; d = d->next) { i = d->disk.raid_disk / n_prim; if (i >= n_bvds) { - pr_err("%s: BUG: invalid raid disk\n", __func__); + pr_err("BUG: invalid raid disk\n"); goto out; } if (d->state_fd > 0) @@ -4973,12 +4944,11 @@ static int raid10_degraded(struct mdinfo *info) ret = 2; for (i = 0; i < n_bvds; i++) if (!found[i]) { - dprintf("%s: BVD %d/%d failed\n", __func__, i, n_bvds); + dprintf("BVD %d/%d failed\n", i, n_bvds); ret = 0; goto out; } else if (found[i] < n_prim) { - dprintf("%s: BVD %d/%d degraded\n", __func__, i, - n_bvds); + dprintf("BVD %d/%d degraded\n", i, n_bvds); ret = 1; } out: @@ -5027,7 +4997,7 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, working ++; } - dprintf("%s: working=%d (%d) level=%d\n", __func__, working, + dprintf("working=%d (%d) level=%d\n", working, a->info.array.raid_disks, a->info.array.level); if (working == a->info.array.raid_disks) @@ -5212,8 +5182,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, && dl->minor == di->disk.minor) break; if (!dl || dl->pdnum < 0) { - pr_err("%s: BUG: can't find disk %d (%d/%d)\n", - __func__, di->disk.raid_disk, + pr_err("BUG: can't find disk %d (%d/%d)\n", + di->disk.raid_disk, di->disk.major, di->disk.minor); return NULL; } diff --git a/super-gpt.c b/super-gpt.c index 6a2f749e..1a2adce0 100644 --- a/super-gpt.c +++ b/super-gpt.c @@ -77,8 +77,7 @@ static int load_gpt(struct supertype *st, int fd, char *devname) free_gpt(st); if (posix_memalign((void**)&super, 4096, 32*512) != 0) { - pr_err("%s could not allocate superblock\n", - __func__); + pr_err("could not allocate superblock\n"); return 1; } diff --git a/super-intel.c b/super-intel.c index e28ac7d3..95a72b6a 100644 --- a/super-intel.c +++ b/super-intel.c @@ -509,7 +509,8 @@ struct imsm_update_add_remove_disk { static const char *_sys_dev_type[] = { [SYS_DEV_UNKNOWN] = "Unknown", [SYS_DEV_SAS] = "SAS", - [SYS_DEV_SATA] = "SATA" + [SYS_DEV_SATA] = "SATA", + [SYS_DEV_NVME] = "NVMe" }; const char *get_sys_dev_type(enum sys_dev_type type) @@ -555,11 +556,26 @@ static int attach_hba_to_super(struct intel_super *super, struct sys_dev *device if (super->hba == NULL) { super->hba = alloc_intel_hba(device); return 1; - } else - /* IMSM metadata disallows to attach disks to multiple - * controllers. - */ + } + + hba = super->hba; + /* Intel metadata allows for all disks attached to the same type HBA. + * Do not support HBA types mixing + */ + if (device->type != hba->type) + return 2; + + /* Multiple same type HBAs can be used if they share the same OROM */ + const struct imsm_orom *device_orom = get_orom_by_device_id(device->dev_id); + + if (device_orom != super->orom) return 2; + + while (hba->next) + hba = hba->next; + + hba->next = alloc_intel_hba(device); + return 1; } static struct sys_dev* find_disk_attached_hba(int fd, const char *devname) @@ -1370,7 +1386,7 @@ static int imsm_check_attributes(__u32 attributes) } if (not_supported) - dprintf(Name "(IMSM): Unknown attributes : %x\n", not_supported); + dprintf("(IMSM): Unknown attributes : %x\n", not_supported); ret_val = 0; } @@ -1693,7 +1709,8 @@ static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_b break; } *c = '\0'; - if (sscanf(&path[hba_len], "host%d", &port) == 1) + if ((sscanf(&path[hba_len], "ata%d", &port) == 1) || + ((sscanf(&path[hba_len], "host%d", &port) == 1))) port -= host_base; else { if (verbose > 0) { @@ -1752,6 +1769,8 @@ static void print_found_intel_controllers(struct sys_dev *elem) fprintf(stderr, "SATA "); else if (elem->type == SYS_DEV_SAS) fprintf(stderr, "SAS "); + else if (elem->type == SYS_DEV_NVME) + fprintf(stderr, "NVMe "); fprintf(stderr, "RAID controller"); if (elem->pci_id) fprintf(stderr, " at %s", elem->pci_id); @@ -1773,7 +1792,8 @@ static int ahci_get_port_count(const char *hba_path, int *port_count) for (ent = readdir(dir); ent; ent = readdir(dir)) { int host; - if (sscanf(ent->d_name, "host%d", &host) != 1) + if ((sscanf(ent->d_name, "ata%d", &host) != 1) && + ((sscanf(ent->d_name, "host%d", &host) != 1))) continue; if (*port_count == 0) host_base = host; @@ -1789,9 +1809,15 @@ static int ahci_get_port_count(const char *hba_path, int *port_count) static void print_imsm_capability(const struct imsm_orom *orom) { - printf(" Platform : Intel(R) Matrix Storage Manager\n"); - printf(" Version : %d.%d.%d.%d\n", orom->major_ver, orom->minor_ver, - orom->hotfix_ver, orom->build); + printf(" Platform : Intel(R) "); + if (orom->capabilities == 0 && orom->driver_features == 0) + printf("Matrix Storage Manager\n"); + else + printf("Rapid Storage Technology%s\n", + imsm_orom_is_enterprise(orom) ? " enterprise" : ""); + if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) + printf(" Version : %d.%d.%d.%d\n", orom->major_ver, + orom->minor_ver, orom->hotfix_ver, orom->build); printf(" RAID Levels :%s%s%s%s%s\n", imsm_orom_has_raid0(orom) ? " raid0" : "", imsm_orom_has_raid1(orom) ? " raid1" : "", @@ -1820,16 +1846,18 @@ static void print_imsm_capability(const struct imsm_orom *orom) printf(" 2TB disks :%s supported\n", (orom->attr & IMSM_OROM_ATTR_2TB_DISK)?"":" not"); printf(" Max Disks : %d\n", orom->tds); - printf(" Max Volumes : %d per array, %d per controller\n", - orom->vpa, orom->vphba); + printf(" Max Volumes : %d per array, %d per %s\n", + orom->vpa, orom->vphba, + imsm_orom_is_nvme(orom) ? "platform" : "controller"); return; } static void print_imsm_capability_export(const struct imsm_orom *orom) { printf("MD_FIRMWARE_TYPE=imsm\n"); - printf("IMSM_VERSION=%d.%d.%d.%d\n",orom->major_ver, orom->minor_ver, - orom->hotfix_ver, orom->build); + if (orom->major_ver || orom->minor_ver || orom->hotfix_ver || orom->build) + printf("IMSM_VERSION=%d.%d.%d.%d\n", orom->major_ver, orom->minor_ver, + orom->hotfix_ver, orom->build); printf("IMSM_SUPPORTED_RAID_LEVELS=%s%s%s%s%s\n", imsm_orom_has_raid0(orom) ? "raid0 " : "", imsm_orom_has_raid1(orom) ? "raid1 " : "", @@ -1873,7 +1901,6 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle * platform capabilities. If raid support is disabled in the BIOS the * option-rom capability structure will not be available. */ - const struct imsm_orom *orom; struct sys_dev *list, *hba; int host_base = 0; int port_count = 0; @@ -1886,13 +1913,12 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle if (!list) return 2; for (hba = list; hba; hba = hba->next) { - orom = find_imsm_capability(hba->type); - if (!orom) { - result = 2; + if (find_imsm_capability(hba)) { + result = 0; break; } else - result = 0; + result = 2; } return result; } @@ -1900,46 +1926,66 @@ static int detail_platform_imsm(int verbose, int enumerate_only, char *controlle list = find_intel_devices(); if (!list) { if (verbose > 0) - pr_err("no active Intel(R) RAID " - "controller found.\n"); + pr_err("no active Intel(R) RAID controller found.\n"); return 2; } else if (verbose > 0) print_found_intel_controllers(list); for (hba = list; hba; hba = hba->next) { - if (controller_path && (compare_paths(hba->path,controller_path) != 0)) + if (controller_path && (compare_paths(hba->path, controller_path) != 0)) continue; - orom = find_imsm_capability(hba->type); - if (!orom) + if (!find_imsm_capability(hba)) { pr_err("imsm capabilities not found for controller: %s (type %s)\n", hba->path, get_sys_dev_type(hba->type)); - else { - result = 0; - print_imsm_capability(orom); + continue; + } + result = 0; + } + + if (controller_path && result == 1) { + pr_err("no active Intel(R) RAID controller found under %s\n", + controller_path); + return result; + } + + const struct orom_entry *entry; + + for (entry = orom_entries; entry; entry = entry->next) { + print_imsm_capability(&entry->orom); + + if (imsm_orom_is_nvme(&entry->orom)) { + for (hba = list; hba; hba = hba->next) { + if (hba->type == SYS_DEV_NVME) + printf(" NVMe Device : %s\n", hba->path); + } + continue; + } + + struct devid_list *devid; + for (devid = entry->devid_list; devid; devid = devid->next) { + hba = device_by_id(devid->devid); + if (!hba) + continue; + printf(" I/O Controller : %s (%s)\n", hba->path, get_sys_dev_type(hba->type)); if (hba->type == SYS_DEV_SATA) { host_base = ahci_get_port_count(hba->path, &port_count); if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) { if (verbose > 0) - pr_err("failed to enumerate " - "ports on SATA controller at %s.\n", hba->pci_id); + pr_err("failed to enumerate ports on SATA controller at %s.\n", hba->pci_id); result |= 2; } } } + printf("\n"); } - if (controller_path && result == 1) - pr_err("no active Intel(R) RAID " - "controller found under %s\n",controller_path); - return result; } static int export_detail_platform_imsm(int verbose, char *controller_path) { - const struct imsm_orom *orom; struct sys_dev *list, *hba; int result=1; @@ -1954,17 +2000,17 @@ static int export_detail_platform_imsm(int verbose, char *controller_path) for (hba = list; hba; hba = hba->next) { if (controller_path && (compare_paths(hba->path,controller_path) != 0)) continue; - orom = find_imsm_capability(hba->type); - if (!orom) { - if (verbose > 0) - pr_err("IMSM_DETAIL_PLATFORM_ERROR=NO_IMSM_CAPABLE_DEVICE_UNDER_%s\n",hba->path); - } - else { - print_imsm_capability_export(orom); + if (!find_imsm_capability(hba) && verbose > 0) + pr_err("IMSM_DETAIL_PLATFORM_ERROR=NO_IMSM_CAPABLE_DEVICE_UNDER_%s\n", hba->path); + else result = 0; - } } + const struct orom_entry *entry; + + for (entry = orom_entries; entry; entry = entry->next) + print_imsm_capability_export(&entry->orom); + return result; } @@ -2142,7 +2188,7 @@ static __u8 imsm_num_data_members(struct imsm_dev *dev, int second_map) case 5: return map->num_members - 1; default: - dprintf("%s: unsupported raid level\n", __func__); + dprintf("unsupported raid level\n"); return 0; } } @@ -2399,7 +2445,7 @@ static int imsm_create_metadata_checkpoint_update( int update_memory_size = 0; - dprintf("imsm_create_metadata_checkpoint_update(enter)\n"); + dprintf("(enter)\n"); if (u == NULL) return 0; @@ -2411,14 +2457,12 @@ static int imsm_create_metadata_checkpoint_update( *u = xcalloc(1, update_memory_size); if (*u == NULL) { - dprintf("error: cannot get memory for " - "imsm_create_metadata_checkpoint_update update\n"); + dprintf("error: cannot get memory\n"); return 0; } (*u)->type = update_general_migration_checkpoint; (*u)->curr_migr_unit = __le32_to_cpu(super->migr_rec->curr_migr_unit); - dprintf("imsm_create_metadata_checkpoint_update: prepared for %u\n", - (*u)->curr_migr_unit); + dprintf("prepared for %u\n", (*u)->curr_migr_unit); return update_memory_size; } @@ -2553,9 +2597,7 @@ static unsigned long long imsm_component_size_aligment_check(int level, */ component_size_alligment = component_size % (chunk_size/512); - dprintf("imsm_component_size_aligment_check(Level: %i, " - "chunk_size = %i, component_size = %llu), " - "component_size_alligment = %u\n", + dprintf("(Level: %i, chunk_size = %i, component_size = %llu), component_size_alligment = %u\n", level, chunk_size, component_size, component_size_alligment); @@ -2563,7 +2605,7 @@ static unsigned long long imsm_component_size_aligment_check(int level, dprintf("imsm: reported component size alligned from %llu ", component_size); component_size -= component_size_alligment; - dprintf("to %llu (%i).\n", + dprintf_cont("to %llu (%i).\n", component_size, component_size_alligment); } @@ -2703,8 +2745,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, info->reshape_progress = blocks_per_unit * units; - dprintf("IMSM: General Migration checkpoint : %llu " - "(%llu) -> read reshape progress : %llu\n", + dprintf("IMSM: General Migration checkpoint : %llu (%llu) -> read reshape progress : %llu\n", (unsigned long long)units, (unsigned long long)blocks_per_unit, info->reshape_progress); @@ -2883,7 +2924,7 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * */ max_enough = max(max_enough, enough); } - dprintf("%s: enough: %d\n", __func__, max_enough); + dprintf("enough: %d\n", max_enough); info->container_enough = max_enough; if (super->disks) { @@ -3087,13 +3128,18 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst) * use the same Intel hba * If not on Intel hba at all, allow anything. */ - if (!check_env("IMSM_NO_PLATFORM")) { - if (first->hba && sec->hba && - strcmp(first->hba->path, sec->hba->path) != 0) { + if (!check_env("IMSM_NO_PLATFORM") && first->hba && sec->hba) { + if (first->hba->type != sec->hba->type) { fprintf(stderr, - "HBAs of devices does not match %s != %s\n", - first->hba ? first->hba->path : NULL, - sec->hba ? sec->hba->path : NULL); + "HBAs of devices do not match %s != %s\n", + get_sys_dev_type(first->hba->type), + get_sys_dev_type(sec->hba->type)); + return 3; + } + if (first->orom != sec->orom) { + fprintf(stderr, + "HBAs of devices do not match %s != %s\n", + first->hba->pci_id, sec->hba->pci_id); return 3; } } @@ -3568,8 +3614,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname) if (posix_memalign((void**)&anchor, 512, 512) != 0) { if (devname) - pr_err("Failed to allocate imsm anchor buffer" - " on %s\n", devname); + pr_err("Failed to allocate imsm anchor buffer on %s\n", devname); return 1; } if (read(fd, anchor, 512) != 512) { @@ -3606,7 +3651,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname) free(anchor); if (posix_memalign(&super->migr_rec_buf, 512, MIGR_REC_BUF_SIZE) != 0) { - pr_err("%s could not allocate migr_rec buffer\n", __func__); + pr_err("could not allocate migr_rec buffer\n"); free(super->buf); return 2; } @@ -3817,14 +3862,12 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de if (devname) { struct intel_hba *hba = super->hba; - pr_err("%s is attached to Intel(R) %s RAID " - "controller (%s),\n" - " but the container is assigned to Intel(R) " - "%s RAID controller (", + pr_err("%s is attached to Intel(R) %s RAID controller (%s),\n" + " but the container is assigned to Intel(R) %s RAID controller (", devname, - hba_name->path, + get_sys_dev_type(hba_name->type), hba_name->pci_id ? : "Err!", - get_sys_dev_type(hba_name->type)); + get_sys_dev_type(super->hba->type)); while (hba) { fprintf(stderr, "%s", hba->pci_id ? : "Err!"); @@ -3832,16 +3875,15 @@ static int find_intel_hba_capability(int fd, struct intel_super *super, char *de fprintf(stderr, ", "); hba = hba->next; } - - fprintf(stderr, ").\n"); - cont_err("Mixing devices attached to multiple controllers " - "is not allowed.\n"); + fprintf(stderr, ").\n" + " Mixing devices attached to different controllers is not allowed.\n"); } return 2; } - super->orom = find_imsm_capability(hba_name->type); + super->orom = find_imsm_capability(hba_name); if (!super->orom) return 3; + return 0; } @@ -3906,8 +3948,8 @@ static int __prep_thunderdome(struct intel_super **table, int tbl_size, if (tbl_mpb->family_num == mpb->family_num) { if (tbl_mpb->check_sum == mpb->check_sum) { - dprintf("%s: mpb from %d:%d matches %d:%d\n", - __func__, super->disks->major, + dprintf("mpb from %d:%d matches %d:%d\n", + super->disks->major, super->disks->minor, table[i]->disks->major, table[i]->disks->minor); @@ -3924,8 +3966,8 @@ static int __prep_thunderdome(struct intel_super **table, int tbl_size, */ struct intel_disk *idisk; - dprintf("%s: mpb from %d:%d replaces %d:%d\n", - __func__, super->disks->major, + dprintf("mpb from %d:%d replaces %d:%d\n", + super->disks->major, super->disks->minor, table[i]->disks->major, table[i]->disks->minor); @@ -3953,8 +3995,8 @@ static int __prep_thunderdome(struct intel_super **table, int tbl_size, idisk->disk.status |= CONFIGURED_DISK; } - dprintf("%s: mpb from %d:%d prefer %d:%d\n", - __func__, super->disks->major, + dprintf("mpb from %d:%d prefer %d:%d\n", + super->disks->major, super->disks->minor, table[i]->disks->major, table[i]->disks->minor); @@ -4013,12 +4055,12 @@ validate_members(struct intel_super *super, struct intel_disk *disk_list, idisk->owner == IMSM_UNKNOWN_OWNER) ok_count++; else - dprintf("%s: '%.16s' owner %d != %d\n", - __func__, disk->serial, idisk->owner, + dprintf("'%.16s' owner %d != %d\n", + disk->serial, idisk->owner, owner); } else { - dprintf("%s: unknown disk %x [%d]: %.16s\n", - __func__, __le32_to_cpu(mpb->family_num), i, + dprintf("unknown disk %x [%d]: %.16s\n", + __le32_to_cpu(mpb->family_num), i, disk->serial); break; } @@ -4074,8 +4116,8 @@ imsm_thunderdome(struct intel_super **super_list, int len) s = NULL; if (!s) - dprintf("%s: marking family: %#x from %d:%d offline\n", - __func__, mpb->family_num, + dprintf("marking family: %#x from %d:%d offline\n", + mpb->family_num, super_table[i]->disks->major, super_table[i]->disks->minor); super_table[i] = s; @@ -4122,8 +4164,7 @@ imsm_thunderdome(struct intel_super **super_list, int len) champion = s; if (conflict) - pr_err("Chose family %#x on '%s', " - "assemble conflicts to new container with '--update=uuid'\n", + pr_err("Chose family %#x on '%s', assemble conflicts to new container with '--update=uuid'\n", __le32_to_cpu(s->anchor->family_num), s->disks->devname); /* collect all dl's onto 'champion', and update them to @@ -4463,8 +4504,7 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname) if (rv) { if (devname) - pr_err("Failed to load all information " - "sections on %s\n", devname); + pr_err("Failed to load all information sections on %s\n", devname); free_imsm(super); return rv; } @@ -4600,8 +4640,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, unsigned long long num_data_stripes; if (super->orom && mpb->num_raid_devs >= super->orom->vpa) { - pr_err("This imsm-container already has the " - "maximum of %d volumes\n", super->orom->vpa); + pr_err("This imsm-container already has the maximum of %d volumes\n", super->orom->vpa); return 0; } @@ -4618,8 +4657,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, } if (posix_memalign(&super->migr_rec_buf, 512, MIGR_REC_BUF_SIZE) != 0) { - pr_err("%s could not allocate migr_rec buffer\n", - __func__); + pr_err("could not allocate migr_rec buffer\n"); free(super->buf); free(super); free(mpb_new); @@ -4703,8 +4741,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info, if (info->level == 1 && info->raid_disks > 2) { free(dev); free(dv); - pr_err("imsm does not support more than 2 disks" - "in a raid1 volume\n"); + pr_err("imsm does not support more than 2 disksin a raid1 volume\n"); return 0; } @@ -4777,11 +4814,11 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info, super = NULL; } if (!super) { - pr_err("%s could not allocate superblock\n", __func__); + pr_err("could not allocate superblock\n"); return 0; } if (posix_memalign(&super->migr_rec_buf, 512, MIGR_REC_BUF_SIZE) != 0) { - pr_err("%s could not allocate migr_rec buffer\n", __func__); + pr_err("could not allocate migr_rec buffer\n"); free(super->buf); free(super); return 0; @@ -5000,6 +5037,14 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, } get_dev_size(fd, NULL, &size); + /* clear migr_rec when adding disk to container */ + memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SIZE); + if (lseek64(fd, size - MIGR_REC_POSITION, SEEK_SET) >= 0) { + if (write(fd, super->migr_rec_buf, + MIGR_REC_BUF_SIZE) != MIGR_REC_BUF_SIZE) + perror("Write migr_rec failed"); + } + size /= 512; serialcpy(dd->disk.serial, dd->serial); set_total_blocks(&dd->disk, size); @@ -5035,8 +5080,7 @@ static int remove_from_super_imsm(struct supertype *st, mdu_disk_info_t *dk) * is prepared. */ if (!st->update_tail) { - pr_err("%s shall be used in mdmon context only" - "(line %d).\n", __func__, __LINE__); + pr_err("shall be used in mdmon context only\n"); return 1; } dd = xcalloc(1, sizeof(*dd)); @@ -5069,13 +5113,13 @@ static int write_super_imsm_spares(struct intel_super *super, int doclose) __u32 sum; struct dl *d; - spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super)), - spare->generation_num = __cpu_to_le32(1UL), + spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super)); + spare->generation_num = __cpu_to_le32(1UL); spare->attributes = MPB_ATTRIB_CHECKSUM_VERIFY; - spare->num_disks = 1, - spare->num_raid_devs = 0, - spare->cache_size = mpb->cache_size, - spare->pwr_cycle_count = __cpu_to_le32(1), + spare->num_disks = 1; + spare->num_raid_devs = 0; + spare->cache_size = mpb->cache_size; + spare->pwr_cycle_count = __cpu_to_le32(1); snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH, MPB_SIGNATURE MPB_VERSION_RAID0); @@ -5095,8 +5139,8 @@ static int write_super_imsm_spares(struct intel_super *super, int doclose) spare->check_sum = __cpu_to_le32(sum); if (store_imsm_mpb(d->fd, spare)) { - pr_err("%s: failed for device %d:%d %s\n", - __func__, d->major, d->minor, strerror(errno)); + pr_err("failed for device %d:%d %s\n", + d->major, d->minor, strerror(errno)); return 1; } if (doclose) { @@ -5189,8 +5233,8 @@ static int write_super_imsm(struct supertype *st, int doclose) if (store_imsm_mpb(d->fd, mpb)) fprintf(stderr, - "%s: failed for device %d:%d (fd: %d)%s\n", - __func__, d->major, d->minor, + "failed for device %d:%d (fd: %d)%s\n", + d->major, d->minor, d->fd, strerror(errno)); if (doclose) { @@ -5345,7 +5389,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level, #if DEBUG char str[256]; fd2devname(fd, str); - dprintf("validate_geometry_imsm_container: fd: %d %s orom: %p rv: %d raiddisk: %d\n", + dprintf("fd: %d %s orom: %p rv: %d raiddisk: %d\n", fd, str, super->orom, rv, raiddisks); #endif /* no orom/efi or non-intel hba of the disk */ @@ -5357,8 +5401,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level, if (super->orom) { if (raiddisks > super->orom->tds) { if (verbose) - pr_err("%d exceeds maximum number of" - " platform supported disks: %d\n", + pr_err("%d exceeds maximum number of platform supported disks: %d\n", raiddisks, super->orom->tds); free_imsm(super); return 0; @@ -5542,15 +5585,15 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist, for (vol = mdstat ; vol ; vol = vol->next) { if ((vol->active > 0) && vol->metadata_version && - is_container_member(vol, memb->dev)) { + is_container_member(vol, memb->devnm)) { found++; count++; } } if (*devlist && (found < dpa)) { dv = xcalloc(1, sizeof(*dv)); - dv->devname = xmalloc(strlen(memb->dev) + strlen("/dev/") + 1); - sprintf(dv->devname, "%s%s", "/dev/", memb->dev); + dv->devname = xmalloc(strlen(memb->devnm) + strlen("/dev/") + 1); + sprintf(dv->devname, "%s%s", "/dev/", memb->devnm); dv->found = found; dv->used = 0; dv->next = *devlist; @@ -5679,27 +5722,27 @@ count_volumes_list(struct md_list *devlist, char *homehost, tmpdev->container = 0; dfd = dev_open(devname, O_RDONLY|O_EXCL); if (dfd < 0) { - dprintf(": cannot open device %s: %s\n", + dprintf("cannot open device %s: %s\n", devname, strerror(errno)); tmpdev->used = 2; } else if (fstat(dfd, &stb)< 0) { /* Impossible! */ - dprintf(": fstat failed for %s: %s\n", + dprintf("fstat failed for %s: %s\n", devname, strerror(errno)); tmpdev->used = 2; } else if ((stb.st_mode & S_IFMT) != S_IFBLK) { - dprintf(": %s is not a block device.\n", + dprintf("%s is not a block device.\n", devname); tmpdev->used = 2; } else if (must_be_container(dfd)) { struct supertype *cst; cst = super_by_fd(dfd, NULL); if (cst == NULL) { - dprintf(": cannot recognize container type %s\n", + dprintf("cannot recognize container type %s\n", devname); tmpdev->used = 2; } else if (tst->ss != st->ss) { - dprintf(": non-imsm container - ignore it: %s\n", + dprintf("non-imsm container - ignore it: %s\n", devname); tmpdev->used = 2; } else if (!tst->ss->load_container || @@ -5713,11 +5756,11 @@ count_volumes_list(struct md_list *devlist, char *homehost, } else { tmpdev->st_rdev = stb.st_rdev; if (tst->ss->load_super(tst,dfd, NULL)) { - dprintf(": no RAID superblock on %s\n", + dprintf("no RAID superblock on %s\n", devname); tmpdev->used = 2; } else if (tst->ss->compare_super == NULL) { - dprintf(": Cannot assemble %s metadata on %s\n", + dprintf("Cannot assemble %s metadata on %s\n", tst->ss->name, devname); tmpdev->used = 2; } @@ -5754,7 +5797,7 @@ count_volumes_list(struct md_list *devlist, char *homehost, * Or, if we are auto assembling, we just ignore the second * for now. */ - dprintf(": superblock on %s doesn't match others - assembly aborted\n", + dprintf("superblock on %s doesn't match others - assembly aborted\n", devname); goto loop; } @@ -5776,7 +5819,7 @@ count_volumes_list(struct md_list *devlist, char *homehost, if (iter->array.state & (1<text_version); } else count++; @@ -5784,11 +5827,11 @@ count_volumes_list(struct md_list *devlist, char *homehost, sysfs_free(head); } else { - dprintf(" no valid super block on device list: err: %d %p\n", + dprintf("No valid super block on device list: err: %d %p\n", err, st->sb); } } else { - dprintf(" no more devices to examin\n"); + dprintf("no more devices to examine\n"); } for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) { @@ -5810,37 +5853,68 @@ count_volumes_list(struct md_list *devlist, char *homehost, } static int -count_volumes(char *hba, int dpa, int verbose) +count_volumes(struct intel_hba *hba, int dpa, int verbose) { - struct md_list *devlist = NULL; + struct sys_dev *idev, *intel_devices = find_intel_devices(); int count = 0; - int found = 0;; + const struct orom_entry *entry; + struct devid_list *dv, *devid_list; - devlist = get_devices(hba); - /* if no intel devices return zero volumes */ - if (devlist == NULL) + if (!hba || !hba->path) return 0; - count = active_arrays_by_format("imsm", hba, &devlist, dpa, verbose); - dprintf(" path: %s active arrays: %d\n", hba, count); - if (devlist == NULL) + for (idev = intel_devices; idev; idev = idev->next) { + if (strstr(idev->path, hba->path)) + break; + } + + if (!idev || !idev->dev_id) return 0; - do { - found = 0; - count += count_volumes_list(devlist, - NULL, - verbose, - &found); - dprintf("found %d count: %d\n", found, count); - } while (found); - - dprintf("path: %s total number of volumes: %d\n", hba, count); - - while(devlist) { - struct md_list *dv = devlist; - devlist = devlist->next; - free(dv->devname); - free(dv); + + entry = get_orom_entry_by_device_id(idev->dev_id); + + if (!entry || !entry->devid_list) + return 0; + + devid_list = entry->devid_list; + for (dv = devid_list; dv; dv = dv->next) { + + struct md_list *devlist = NULL; + struct sys_dev *device = device_by_id(dv->devid); + char *hba_path; + int found = 0; + + if (device) + hba_path = device->path; + else + return 0; + + devlist = get_devices(hba_path); + /* if no intel devices return zero volumes */ + if (devlist == NULL) + return 0; + + count += active_arrays_by_format("imsm", hba_path, &devlist, dpa, verbose); + dprintf("path: %s active arrays: %d\n", hba_path, count); + if (devlist == NULL) + return 0; + do { + found = 0; + count += count_volumes_list(devlist, + NULL, + verbose, + &found); + dprintf("found %d count: %d\n", found, count); + } while (found); + + dprintf("path: %s total number of volumes: %d\n", hba_path, count); + + while (devlist) { + struct md_list *dv = devlist; + devlist = devlist->next; + free(dv->devname); + free(dv); + } } return count; } @@ -5877,8 +5951,7 @@ validate_geometry_imsm_orom(struct intel_super *super, int level, int layout, *chunk = imsm_default_chunk(super->orom); if (super->orom && !imsm_orom_has_chunk(super->orom, *chunk)) { - pr_vrb(": platform does not support a chunk size of: " - "%d\n", *chunk); + pr_vrb(": platform does not support a chunk size of: %d\n", *chunk); return 0; } @@ -5898,6 +5971,7 @@ validate_geometry_imsm_orom(struct intel_super *super, int level, int layout, pr_vrb(": platform does not support a volume size over 2TB\n"); return 0; } + return 1; } @@ -5928,8 +6002,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, mpb = super->anchor; if (!validate_geometry_imsm_orom(super, level, layout, raiddisks, chunk, size, verbose)) { - pr_err("RAID gemetry validation failed. " - "Cannot proceed with the action(s).\n"); + pr_err("RAID gemetry validation failed. Cannot proceed with the action(s).\n"); return 0; } if (!dev) { @@ -5970,9 +6043,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, } if (dcnt < raiddisks) { if (verbose) - pr_err("imsm: Not enough " - "devices with space for this array " - "(%d < %d)\n", + pr_err("imsm: Not enough devices with space for this array (%d < %d)\n", dcnt, raiddisks); return 0; } @@ -5991,8 +6062,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, } if (!dl) { if (verbose) - pr_err("%s is not in the " - "same imsm set\n", dev); + pr_err("%s is not in the same imsm set\n", dev); return 0; } else if (super->orom && dl->index < 0 && mpb->num_raid_devs) { /* If a volume is present then the current creation attempt @@ -6000,15 +6070,12 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, * understand this configuration (all member disks must be * members of each array in the container). */ - pr_err("%s is a spare and a volume" - " is already defined for this container\n", dev); - pr_err("The option-rom requires all member" - " disks to be a member of all volumes\n"); + pr_err("%s is a spare and a volume is already defined for this container\n", dev); + pr_err("The option-rom requires all member disks to be a member of all volumes\n"); return 0; } else if (super->orom && mpb->num_raid_devs > 0 && mpb->num_disks != raiddisks) { - pr_err("The option-rom requires all member" - " disks to be a member of all volumes\n"); + pr_err("The option-rom requires all member disks to be a member of all volumes\n"); return 0; } @@ -6051,21 +6118,16 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, if (!check_env("IMSM_NO_PLATFORM") && mpb->num_raid_devs > 0 && size && size != maxsize) { - pr_err("attempting to create a second " - "volume with size less then remaining space. " - "Aborting...\n"); + pr_err("attempting to create a second volume with size less then remaining space. Aborting...\n"); return 0; } if (maxsize < size || maxsize == 0) { if (verbose) { if (maxsize == 0) - pr_err("no free space" - " left on device. Aborting...\n"); + pr_err("no free space left on device. Aborting...\n"); else - pr_err("not enough space" - " to create volume of given size" - " (%llu < %llu). Aborting...\n", + pr_err("not enough space to create volume of given size (%llu < %llu). Aborting...\n", maxsize, size); } return 0; @@ -6074,7 +6136,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level, *freesize = maxsize; if (super->orom) { - int count = count_volumes(super->hba->path, + int count = count_volumes(super->hba, super->orom->dpa, verbose); if (super->orom->vphba <= count) { pr_vrb(": platform does not support more than %d raid volumes.\n", @@ -6151,9 +6213,7 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks, } if (!check_env("IMSM_NO_PLATFORM") && mpb->num_raid_devs > 0 && size && size != maxsize) { - pr_err("attempting to create a second " - "volume with size less then remaining space. " - "Aborting...\n"); + pr_err("attempting to create a second volume with size less then remaining space. Aborting...\n"); return 0; } cnt = 0; @@ -6232,11 +6292,10 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout, created */ if (super->orom && freesize) { int count; - count = count_volumes(super->hba->path, + count = count_volumes(super->hba, super->orom->dpa, verbose); if (super->orom->vphba <= count) { - pr_vrb(": platform does not support more" - " than %d raid volumes.\n", + pr_vrb(": platform does not support more than %d raid volumes.\n", super->orom->vphba); return 0; } @@ -6520,7 +6579,7 @@ static void update_recovery_start(struct intel_super *super, * IMSM_ORD_REBUILD, so assume they are missing and the * disk_ord_tbl was not correctly updated */ - dprintf("%s: failed to locate out-of-sync disk\n", __func__); + dprintf("failed to locate out-of-sync disk\n"); return; } @@ -6554,14 +6613,12 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra /* do not assemble arrays when not all attributes are supported */ if (imsm_check_attributes(mpb->attributes) == 0) { sb_errors = 1; - pr_err("Unsupported attributes in IMSM metadata." - "Arrays activation is blocked.\n"); + pr_err("Unsupported attributes in IMSM metadata.Arrays activation is blocked.\n"); } /* check for bad blocks */ if (imsm_bbm_log_size(super->anchor)) { - pr_err("BBM log found in IMSM metadata." - "Arrays activation is blocked.\n"); + pr_err("BBM log found in IMSM metadata.Arrays activation is blocked.\n"); sb_errors = 1; } @@ -6595,8 +6652,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra */ if (dev->vol.migr_state && (migr_type(dev) == MIGR_STATE_CHANGE)) { - pr_err("cannot assemble volume '%.16s':" - " unsupported migration in progress\n", + pr_err("cannot assemble volume '%.16s': unsupported migration in progress\n", dev->volume); continue; } @@ -6618,8 +6674,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra map->num_members, /* raid disks */ &chunk, join_u32(dev->size_low, dev->size_high), 1 /* verbose */)) { - pr_err("IMSM RAID geometry validation" - " failed. Array %s activation is blocked.\n", + pr_err("IMSM RAID geometry validation failed. Array %s activation is blocked.\n", dev->volume); this->array.state |= (1<anchor; if (atoi(inst) >= mpb->num_raid_devs) { - pr_err("%s: subarry index %d, out of range\n", - __func__, atoi(inst)); + pr_err("subarry index %d, out of range\n", atoi(inst)); return -ENODEV; } @@ -7255,7 +7309,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) case IMSM_T_STATE_NORMAL: /* transition to normal state */ dprintf("normal: "); if (is_rebuilding(dev)) { - dprintf("while rebuilding"); + dprintf_cont("while rebuilding"); /* check if recovery is really finished */ for (mdi = a->info.devs; mdi ; mdi = mdi->next) if (mdi->recovery_start != MaxSector) { @@ -7263,8 +7317,8 @@ static void imsm_set_disk(struct active_array *a, int n, int state) break; } if (recovery_not_finished) { - dprintf("\nimsm: Rebuild has not finished yet, " - "state not changed"); + dprintf_cont("\n"); + dprintf("Rebuild has not finished yet, state not changed"); if (a->last_checkpoint < mdi->recovery_start) { a->last_checkpoint = mdi->recovery_start; super->updates_pending++; @@ -7279,7 +7333,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) break; } if (is_gen_migration(dev)) { - dprintf("while general migration"); + dprintf_cont("while general migration"); if (a->last_checkpoint >= a->info.component_size) end_migration(dev, super, map_state); else @@ -7291,26 +7345,26 @@ static void imsm_set_disk(struct active_array *a, int n, int state) } break; case IMSM_T_STATE_DEGRADED: /* transition to degraded state */ - dprintf("degraded: "); + dprintf_cont("degraded: "); if ((map->map_state != map_state) && !dev->vol.migr_state) { - dprintf("mark degraded"); + dprintf_cont("mark degraded"); map->map_state = map_state; super->updates_pending++; a->last_checkpoint = 0; break; } if (is_rebuilding(dev)) { - dprintf("while rebuilding."); + dprintf_cont("while rebuilding."); if (map->map_state != map_state) { - dprintf(" Map state change"); + dprintf_cont(" Map state change"); end_migration(dev, super, map_state); super->updates_pending++; } break; } if (is_gen_migration(dev)) { - dprintf("while general migration"); + dprintf_cont("while general migration"); if (a->last_checkpoint >= a->info.component_size) end_migration(dev, super, map_state); else { @@ -7321,22 +7375,22 @@ static void imsm_set_disk(struct active_array *a, int n, int state) break; } if (is_initializing(dev)) { - dprintf("while initialization."); + dprintf_cont("while initialization."); map->map_state = map_state; super->updates_pending++; break; } break; case IMSM_T_STATE_FAILED: /* transition to failed state */ - dprintf("failed: "); + dprintf_cont("failed: "); if (is_gen_migration(dev)) { - dprintf("while general migration"); + dprintf_cont("while general migration"); map->map_state = map_state; super->updates_pending++; break; } if (map->map_state != map_state) { - dprintf("mark failed"); + dprintf_cont("mark failed"); end_migration(dev, super, map_state); super->updates_pending++; a->last_checkpoint = 0; @@ -7344,10 +7398,9 @@ static void imsm_set_disk(struct active_array *a, int n, int state) } break; default: - dprintf("state %i\n", map_state); + dprintf_cont("state %i\n", map_state); } - dprintf("\n"); - + dprintf_cont("\n"); } static int store_imsm_mpb(int fd, struct imsm_super *mpb) @@ -7409,7 +7462,7 @@ static struct dl *imsm_readd(struct intel_super *super, int idx, struct active_a dl = NULL; if (dl) - dprintf("%s: found %x:%x\n", __func__, dl->major, dl->minor); + dprintf("found %x:%x\n", dl->major, dl->minor); return dl; } @@ -7610,8 +7663,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a, /* Cannot activate another spare if rebuild is in progress already */ if (is_rebuilding(dev)) { - dprintf("imsm: No spare activation allowed. " - "Rebuild in progress already.\n"); + dprintf("imsm: No spare activation allowed. Rebuild in progress already.\n"); return NULL; } @@ -7631,8 +7683,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a, * are removed from container. */ if (failed) { - dprintf("found failed disks in %.*s, check if there another" - "failed sub-array.\n", + dprintf("found failed disks in %.*s, check if there anotherfailed sub-array.\n", MAX_RAID_SERIAL_LEN, dev->volume); /* check if states of the other volumes allow for rebuild */ for (i = 0; i < super->anchor->num_raid_devs; i++) { @@ -7776,8 +7827,7 @@ static int remove_disk_super(struct intel_super *super, int major, int minor) super->disks = dl->next; dl->next = NULL; __free_imsm_disk(dl); - dprintf("%s: removed %x:%x\n", - __func__, major, minor); + dprintf("removed %x:%x\n", major, minor); break; } prev = dl; @@ -7803,9 +7853,8 @@ static int add_remove_disk_update(struct intel_super *super) disk_cfg->next = super->disks; super->disks = disk_cfg; check_degraded = 1; - dprintf("%s: added %x:%x\n", - __func__, disk_cfg->major, - disk_cfg->minor); + dprintf("added %x:%x\n", + disk_cfg->major, disk_cfg->minor); } else if (disk_cfg->action == DISK_REMOVE) { dprintf("Disk remove action processed: %x.%x\n", disk_cfg->major, disk_cfg->minor); @@ -7837,7 +7886,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration * void **tofree = NULL; int ret_val = 0; - dprintf("apply_reshape_migration_update()\n"); + dprintf("(enter)\n"); if ((u->subdev < 0) || (u->subdev > 1)) { dprintf("imsm: Error: Wrong subdev: %i\n", u->subdev); @@ -7915,8 +7964,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration * new_disk = get_disk_super(super, major(u->new_disks[0]), minor(u->new_disks[0])); - dprintf("imsm: new disk for reshape is: %i:%i " - "(%p, index = %i)\n", + dprintf("imsm: new disk for reshape is: %i:%i (%p, index = %i)\n", major(u->new_disks[0]), minor(u->new_disks[0]), new_disk, new_disk->index); @@ -7957,7 +8005,7 @@ static int apply_size_change_update(struct imsm_update_size_change *u, struct intel_dev *id; int ret_val = 0; - dprintf("apply_size_change_update()\n"); + dprintf("(enter)\n"); if ((u->subdev < 0) || (u->subdev > 1)) { dprintf("imsm: Error: Wrong subdev: %i\n", u->subdev); @@ -7974,8 +8022,7 @@ static int apply_size_change_update(struct imsm_update_size_change *u, /* calculate new size */ blocks_per_member = u->new_size / used_disks; - dprintf("imsm: apply_size_change_update(size: %llu, " - "blocks per member: %llu)\n", + dprintf("(size: %llu, blocks per member: %llu)\n", u->new_size, blocks_per_member); set_blocks_per_member(map, blocks_per_member); imsm_set_array_size(dev, u->new_size); @@ -8017,8 +8064,7 @@ static int apply_update_activate_spare(struct imsm_update_activate_spare *u, break; if (!dl) { - pr_err("error: imsm_activate_spare passed " - "an unknown disk (index: %d)\n", + pr_err("error: imsm_activate_spare passed an unknown disk (index: %d)\n", u->dl->index); return 0; } @@ -8118,15 +8164,14 @@ static int apply_reshape_container_disks_update(struct imsm_update_reshape *u, int ret_val = 0; unsigned int dev_id; - dprintf("imsm: apply_reshape_container_disks_update()\n"); + dprintf("(enter)\n"); /* enable spares to use in array */ for (i = 0; i < delta_disks; i++) { new_disk = get_disk_super(super, major(u->new_disks[i]), minor(u->new_disks[i])); - dprintf("imsm: new disk for reshape is: %i:%i " - "(%p, index = %i)\n", + dprintf("imsm: new disk for reshape is: %i:%i (%p, index = %i)\n", major(u->new_disks[i]), minor(u->new_disks[i]), new_disk, new_disk->index); if ((new_disk == NULL) || @@ -8359,8 +8404,7 @@ static void imsm_process_update(struct supertype *st, struct imsm_update_general_migration_checkpoint *u = (void *)update->buf; - dprintf("imsm: process_update() " - "for update_general_migration_checkpoint called\n"); + dprintf("called for update_general_migration_checkpoint\n"); /* find device under general migration */ for (id = super->devlist ; id; id = id->next) { @@ -8429,15 +8473,14 @@ static void imsm_process_update(struct supertype *st, /* handle racing creates: first come first serve */ if (u->dev_idx < mpb->num_raid_devs) { - dprintf("%s: subarray %d already defined\n", - __func__, u->dev_idx); + dprintf("subarray %d already defined\n", u->dev_idx); goto create_error; } /* check update is next in sequence */ if (u->dev_idx != mpb->num_raid_devs) { - dprintf("%s: can not create array %d expected index %d\n", - __func__, u->dev_idx, mpb->num_raid_devs); + dprintf("can not create array %d expected index %d\n", + u->dev_idx, mpb->num_raid_devs); goto create_error; } @@ -8462,14 +8505,14 @@ static void imsm_process_update(struct supertype *st, continue; if (disks_overlap(super, i, u)) { - dprintf("%s: arrays overlap\n", __func__); + dprintf("arrays overlap\n"); goto create_error; } } /* check that prepare update was successful */ if (!update->space) { - dprintf("%s: prepare update failed\n", __func__); + dprintf("prepare update failed\n"); goto create_error; } @@ -8481,7 +8524,7 @@ static void imsm_process_update(struct supertype *st, for (i = 0; i < new_map->num_members; i++) { dl = serial_to_dl(inf[i].serial, super); if (!dl) { - dprintf("%s: disk disappeared\n", __func__); + dprintf("disk disappeared\n"); goto create_error; } } @@ -8600,8 +8643,7 @@ static void imsm_process_update(struct supertype *st, break; } default: - pr_err("error: unsuported process update type:" - "(type: %d)\n", type); + pr_err("error: unsuported process update type:(type: %d)\n", type); } } @@ -8632,8 +8674,7 @@ static int imsm_prepare_update(struct supertype *st, case update_general_migration_checkpoint: if (update->len < (int)sizeof(struct imsm_update_general_migration_checkpoint)) return 0; - dprintf("imsm: prepare_update() " - "for update_general_migration_checkpoint called\n"); + dprintf("called for update_general_migration_checkpoint\n"); break; case update_takeover: { struct imsm_update_takeover *u = (void *)update->buf; @@ -8682,7 +8723,7 @@ static int imsm_prepare_update(struct supertype *st, if (update->len < (int)sizeof(*u)) return 0; - dprintf("imsm: imsm_prepare_update() for update_reshape\n"); + dprintf("for update_reshape\n"); for (dl = super->devlist; dl; dl = dl->next) { int size = sizeof_imsm_dev(dl->dev, 1); @@ -8717,7 +8758,7 @@ static int imsm_prepare_update(struct supertype *st, if (update->len < (int)sizeof(*u)) return 0; - dprintf("imsm: imsm_prepare_update() for update_reshape\n"); + dprintf("for update_reshape\n"); /* add space for bigger array in update */ @@ -8879,8 +8920,7 @@ static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned ind int i, j, num_members; __u32 ord; - dprintf("%s: deleting device[%d] from imsm_super\n", - __func__, index); + dprintf("deleting device[%d] from imsm_super\n", index); /* shift all indexes down one */ for (iter = super->disks; iter; iter = iter->next) @@ -9061,32 +9101,68 @@ int open_backup_targets(struct mdinfo *info, int raid_disks, int *raid_fds, ******************************************************************************/ int validate_container_imsm(struct mdinfo *info) { - if (!check_env("IMSM_NO_PLATFORM")) { - struct sys_dev *idev; - struct mdinfo *dev; - char *hba_path = NULL; - char *dev_path = devt_to_devpath(makedev(info->disk.major, - info->disk.minor)); + if (check_env("IMSM_NO_PLATFORM")) + return 0; - for (idev = find_intel_devices(); idev; idev = idev->next) { - if (strstr(dev_path, idev->path)) { - hba_path = idev->path; - break; - } + struct sys_dev *idev; + struct sys_dev *hba = NULL; + struct sys_dev *intel_devices = find_intel_devices(); + char *dev_path = devt_to_devpath(makedev(info->disk.major, + info->disk.minor)); + + for (idev = intel_devices; idev; idev = idev->next) { + if (dev_path && strstr(dev_path, idev->path)) { + hba = idev; + break; } + } + if (dev_path) free(dev_path); - if (hba_path) { - for (dev = info->next; dev; dev = dev->next) { - if (!devt_attached_to_hba(makedev(dev->disk.major, - dev->disk.minor), hba_path)) { - pr_err("WARNING - IMSM container assembled with disks under different HBAs!\n" - " This operation is not supported and can lead to data loss.\n"); - return 1; - } + if (!hba) { + pr_err("WARNING - Cannot detect HBA for device %s!\n", + devid2kname(makedev(info->disk.major, info->disk.minor))); + return 1; + } + + const struct imsm_orom *orom = get_orom_by_device_id(hba->dev_id); + struct mdinfo *dev; + + for (dev = info->next; dev; dev = dev->next) { + dev_path = devt_to_devpath(makedev(dev->disk.major, dev->disk.minor)); + + struct sys_dev *hba2 = NULL; + for (idev = intel_devices; idev; idev = idev->next) { + if (dev_path && strstr(dev_path, idev->path)) { + hba2 = idev; + break; } } + if (dev_path) + free(dev_path); + + const struct imsm_orom *orom2 = hba2 == NULL ? NULL : + get_orom_by_device_id(hba2->dev_id); + + if (hba2 && hba->type != hba2->type) { + pr_err("WARNING - HBAs of devices do not match %s != %s\n", + get_sys_dev_type(hba->type), get_sys_dev_type(hba2->type)); + return 1; + } + + if (orom != orom2) { + pr_err("WARNING - IMSM container assembled with disks under different HBAs!\n" + " This operation is not supported and can lead to data loss.\n"); + return 1; + } + + if (!orom) { + pr_err("WARNING - IMSM container assembled with disks under HBAs without IMSM platform support!\n" + " This operation is not supported and can lead to data loss.\n"); + return 1; + } } + return 0; } #ifndef MDASSEMBLE @@ -9268,8 +9344,7 @@ int save_checkpoint_imsm(struct supertype *st, struct mdinfo *info, int state) unsigned long long curr_migr_unit; if (load_imsm_migr_rec(super, info) != 0) { - dprintf("imsm: ERROR: Cannot read migration record " - "for checkpoint save.\n"); + dprintf("imsm: ERROR: Cannot read migration record for checkpoint save.\n"); return 1; } @@ -9293,8 +9368,7 @@ int save_checkpoint_imsm(struct supertype *st, struct mdinfo *info, int state) __cpu_to_le32(curr_migr_unit * __le32_to_cpu(super->migr_rec->dest_depth_per_unit)); if (write_imsm_migr_rec(st) < 0) { - dprintf("imsm: Cannot write migration record " - "outside backup area\n"); + dprintf("imsm: Cannot write migration record outside backup area\n"); return 1; } @@ -9405,16 +9479,14 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info) new_disks, super, id->dev)) { - pr_err("Cannot restore data from backup." - " Too many failed disks\n"); + pr_err("Cannot restore data from backup. Too many failed disks\n"); goto abort; } if (save_checkpoint_imsm(st, info, UNIT_SRC_NORMAL)) { /* ignore error == 2, this can mean end of reshape here */ - dprintf("imsm: Cannot write checkpoint to " - "migration record (UNIT_SRC_NORMAL) during restart\n"); + dprintf("imsm: Cannot write checkpoint to migration record (UNIT_SRC_NORMAL) during restart\n"); } else retval = 0; @@ -9489,22 +9561,19 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, struct mdinfo *info, *member; int devices_that_can_grow = 0; - dprintf("imsm: imsm_reshape_is_allowed_on_container(ENTER): " - "st->devnm = (%s)\n", st->devnm); + dprintf("imsm: imsm_reshape_is_allowed_on_container(ENTER): st->devnm = (%s)\n", st->devnm); if (geo->size > 0 || geo->level != UnSet || geo->layout != UnSet || geo->chunksize != 0 || geo->raid_disks == UnSet) { - dprintf("imsm: Container operation is allowed for " - "raid disks number change only.\n"); + dprintf("imsm: Container operation is allowed for raid disks number change only.\n"); return ret_val; } if (direction == ROLLBACK_METADATA_CHANGES) { - dprintf("imsm: Metadata changes rollback is not supported for " - "container operation.\n"); + dprintf("imsm: Metadata changes rollback is not supported for container operation.\n"); return ret_val; } @@ -9519,8 +9588,7 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, /* we work on container for Online Capacity Expansion * only so raid_disks has to grow */ - dprintf("imsm: for container operation raid disks " - "increase is required\n"); + dprintf("imsm: for container operation raid disks increase is required\n"); break; } @@ -9528,8 +9596,7 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, (info->array.level != 5)) { /* we cannot use this container with other raid level */ - dprintf("imsm: for container operation wrong" - " raid level (%i) detected\n", + dprintf("imsm: for container operation wrong raid level (%i) detected\n", info->array.level); break; } else { @@ -9540,8 +9607,7 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, if (!is_raid_level_supported(super->orom, member->array.level, geo->raid_disks)) { - dprintf("platform does not support raid%d with" - " %d disk%s\n", + dprintf("platform does not support raid%d with %d disk%s\n", info->array.level, geo->raid_disks, geo->raid_disks > 1 ? "s" : ""); @@ -9551,8 +9617,7 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, */ if (info->component_size % (info->array.chunk_size/512)) { - dprintf("Component size is not aligned to " - "chunk size\n"); + dprintf("Component size is not aligned to chunk size\n"); break; } } @@ -9580,9 +9645,9 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st, ret_val = 1; if (ret_val) - dprintf("\tContainer operation allowed\n"); + dprintf("Container operation allowed\n"); else - dprintf("\tError: %i\n", ret_val); + dprintf("Error: %i\n", ret_val); return ret_val; } @@ -9620,8 +9685,7 @@ static int imsm_create_metadata_update_for_reshape( int delta_disks = 0; struct mdinfo *dev; - dprintf("imsm_update_metadata_for_reshape(enter) raid_disks = %i\n", - geo->raid_disks); + dprintf("(enter) raid_disks = %i\n", geo->raid_disks); delta_disks = geo->raid_disks - old_raid_disks; @@ -9642,8 +9706,7 @@ static int imsm_create_metadata_update_for_reshape( if (spares == NULL || delta_disks > spares->array.spare_disks) { - pr_err("imsm: ERROR: Cannot get spare devices " - "for %s.\n", geo->dev_name); + pr_err("imsm: ERROR: Cannot get spare devices for %s.\n", geo->dev_name); i = -1; goto abort; } @@ -9675,12 +9738,12 @@ abort: dprintf("imsm: reshape update preparation :"); if (i == delta_disks) { - dprintf(" OK\n"); + dprintf_cont(" OK\n"); *updatep = u; return update_memory_size; } free(u); - dprintf(" Error\n"); + dprintf_cont(" Error\n"); return 0; } @@ -9699,8 +9762,7 @@ static int imsm_create_metadata_update_for_size_change( int update_memory_size = 0; struct imsm_update_size_change *u = NULL; - dprintf("imsm_create_metadata_update_for_size_change(enter)" - " New size = %llu\n", geo->size); + dprintf("(enter) New size = %llu\n", geo->size); /* size of all update data without anchor */ update_memory_size = sizeof(struct imsm_update_size_change); @@ -9732,8 +9794,7 @@ static int imsm_create_metadata_update_for_migration( struct imsm_dev *dev; int previous_level = -1; - dprintf("imsm_create_metadata_update_for_migration(enter)" - " New Level = %i\n", geo->level); + dprintf("(enter) New Level = %i\n", geo->level); /* size of all update data without anchor */ update_memory_size = sizeof(struct imsm_update_reshape_migration); @@ -9758,8 +9819,7 @@ static int imsm_create_metadata_update_for_migration( if (geo->chunksize != current_chunk_size) { u->new_chunksize = geo->chunksize / 1024; - dprintf("imsm: " - "chunk size change from %i to %i\n", + dprintf("imsm: chunk size change from %i to %i\n", current_chunk_size, u->new_chunksize); } previous_level = map->raid_level; @@ -9774,8 +9834,7 @@ static int imsm_create_metadata_update_for_migration( free(u); sysfs_free(spares); update_memory_size = 0; - dprintf("error: cannot get spare device " - "for requested migration"); + dprintf("error: cannot get spare device for requested migration"); return 0; } sysfs_free(spares); @@ -9843,9 +9902,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, if (geo->level == 5) { change = CH_MIGRATION; if (geo->layout != ALGORITHM_LEFT_ASYMMETRIC) { - pr_err("Error. Requested Layout " - "not supported (left-asymmetric layout " - "is supported only)!\n"); + pr_err("Error. Requested Layout not supported (left-asymmetric layout is supported only)!\n"); change = -1; goto analyse_change_exit; } @@ -9870,8 +9927,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, break; } if (change == -1) { - pr_err("Error. Level Migration from %d to %d " - "not supported!\n", + pr_err("Error. Level Migration from %d to %d not supported!\n", info.array.level, geo->level); goto analyse_change_exit; } @@ -9892,8 +9948,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, geo->layout = 0; geo->level = 5; } else { - pr_err("Error. Layout Migration from %d to %d " - "not supported!\n", + pr_err("Error. Layout Migration from %d to %d not supported!\n", info.array.layout, geo->layout); change = -1; goto analyse_change_exit; @@ -9927,9 +9982,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, chunk * 1024, geo->size * 2); if (geo->size == 0) { - pr_err("Error. Size expansion is " \ - "supported only (current size is %llu, " \ - "requested size /rounded/ is 0).\n", + pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is 0).\n", current_size); goto analyse_change_exit; } @@ -9937,14 +9990,12 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, if ((current_size != geo->size) && (geo->size > 0)) { if (change != -1) { - pr_err("Error. Size change should be the only " - "one at a time.\n"); + pr_err("Error. Size change should be the only one at a time.\n"); change = -1; goto analyse_change_exit; } if ((super->current_vol + 1) != super->anchor->num_raid_devs) { - pr_err("Error. The last volume in container " - "can be expanded only (%i/%s).\n", + pr_err("Error. The last volume in container can be expanded only (%i/%s).\n", super->current_vol, st->devnm); goto analyse_change_exit; } @@ -9969,8 +10020,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, /* requested size change to the maximum available size */ if (max_size == 0) { - pr_err("Error. Cannot find " - "maximum available space.\n"); + pr_err("Error. Cannot find maximum available space.\n"); change = -1; goto analyse_change_exit; } else @@ -9988,17 +10038,12 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, dprintf("Prepare update for size change to %llu\n", geo->size ); if (current_size >= geo->size) { - pr_err("Error. Size expansion is " - "supported only (current size is %llu, " - "requested size /rounded/ is %llu).\n", + pr_err("Error. Size expansion is supported only (current size is %llu, requested size /rounded/ is %llu).\n", current_size, geo->size); goto analyse_change_exit; } if (max_size && geo->size > max_size) { - pr_err("Error. Requested size is larger " - "than maximum available size (maximum " - "available size is %llu, " - "requested size /rounded/ is %llu).\n", + pr_err("Error. Requested size is larger than maximum available size (maximum available size is %llu, requested size /rounded/ is %llu).\n", max_size, geo->size); goto analyse_change_exit; } @@ -10021,9 +10066,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, struct imsm_super *mpb = super->anchor; if (mpb->num_raid_devs > 1) { - pr_err("Error. Cannot perform operation on %s" - "- for this operation it MUST be single " - "array in container\n", + pr_err("Error. Cannot perform operation on %s- for this operation it MUST be single array in container\n", geo->dev_name); change = -1; } @@ -10032,8 +10075,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st, analyse_change_exit: if ((direction == ROLLBACK_METADATA_CHANGES) && ((change == CH_MIGRATION) || (change == CH_TAKEOVER))) { - dprintf("imsm: Metadata changes rollback is not supported for " - "migration and takeover operations.\n"); + dprintf("imsm: Metadata changes rollback is not supported for migration and takeover operations.\n"); change = -1; } return change; @@ -10079,7 +10121,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, int ret_val = 1; struct geo_params geo; - dprintf("imsm: reshape_super called.\n"); + dprintf("(enter)\n"); memset(&geo, 0, sizeof(struct geo_params)); @@ -10093,8 +10135,8 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, if (delta_disks != UnSet) geo.raid_disks += delta_disks; - dprintf("\tfor level : %i\n", geo.level); - dprintf("\tfor raid_disks : %i\n", geo.raid_disks); + dprintf("for level : %i\n", geo.level); + dprintf("for raid_disks : %i\n", geo.raid_disks); if (experimental() == 0) return ret_val; @@ -10127,8 +10169,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, free(u); } else { - pr_err("(imsm) Operation " - "is not allowed on this container\n"); + pr_err("(imsm) Operation is not allowed on this container\n"); } } else { /* On volume level we support following operations @@ -10166,8 +10207,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, imsm_create_metadata_update_for_migration( st, &geo, &u); if (len < 1) { - dprintf("imsm: " - "Cannot prepare update\n"); + dprintf("imsm: Cannot prepare update\n"); break; } ret_val = 0; @@ -10186,8 +10226,7 @@ static int imsm_reshape_super(struct supertype *st, unsigned long long size, imsm_create_metadata_update_for_size_change( st, &geo, &u); if (len < 1) { - dprintf("imsm: " - "Cannot prepare update\n"); + dprintf("imsm: Cannot prepare update\n"); break; } ret_val = 0; @@ -10231,21 +10270,18 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata) unsigned long long position_to_set = to_complete / ndata; if (fd < 0) { - dprintf("imsm: wait_for_reshape_imsm() " - "cannot open reshape_position\n"); + dprintf("cannot open reshape_position\n"); return 1; } if (sysfs_fd_get_ll(fd, &completed) < 0) { - dprintf("imsm: wait_for_reshape_imsm() " - "cannot read reshape_position (no reshape in progres)\n"); + dprintf("cannot read reshape_position (no reshape in progres)\n"); close(fd); return 0; } if (completed > position_to_set) { - dprintf("imsm: wait_for_reshape_imsm() " - "wrong next position to set %llu (%llu)\n", + dprintf("wrong next position to set %llu (%llu)\n", to_complete, position_to_set); close(fd); return -1; @@ -10253,8 +10289,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata) dprintf("Position set: %llu\n", position_to_set); if (sysfs_set_num(sra, NULL, "sync_max", position_to_set) != 0) { - dprintf("imsm: wait_for_reshape_imsm() " - "cannot set reshape position to %llu\n", + dprintf("cannot set reshape position to %llu\n", position_to_set); close(fd); return -1; @@ -10268,8 +10303,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata) strncmp(action, "reshape", 7) != 0) break; if (sysfs_fd_get_ll(fd, &completed) < 0) { - dprintf("imsm: wait_for_reshape_imsm() " - "cannot read reshape_position (in loop)\n"); + dprintf("cannot read reshape_position (in loop)\n"); close(fd); return 1; } @@ -10410,8 +10444,7 @@ static int imsm_manage_reshape( init_migr_record_imsm(st, dev, sra); else { if (__le32_to_cpu(migr_rec->rec_status) != UNIT_SRC_NORMAL) { - dprintf("imsm: cannot restart migration when data " - "are present in copy area.\n"); + dprintf("imsm: cannot restart migration when data are present in copy area.\n"); goto abort; } /* Save checkpoint to update migration record for current @@ -10421,9 +10454,7 @@ static int imsm_manage_reshape( if (save_checkpoint_imsm(st, sra, UNIT_SRC_NORMAL) == 1) { /* ignore error == 2, this can mean end of reshape here */ - dprintf("imsm: Cannot write checkpoint to " - "migration record (UNIT_SRC_NORMAL, " - "initial save)\n"); + dprintf("imsm: Cannot write checkpoint to migration record (UNIT_SRC_NORMAL, initial save)\n"); goto abort; } } @@ -10454,8 +10485,7 @@ static int imsm_manage_reshape( */ degraded = check_degradation_change(sra, fds, degraded); if (degraded > 1) { - dprintf("imsm: Abort reshape due to degradation" - " level (%i)\n", degraded); + dprintf("imsm: Abort reshape due to degradation level (%i)\n", degraded); goto abort; } @@ -10489,10 +10519,7 @@ static int imsm_manage_reshape( if (next_step_filler) next_step_filler = (old_data_stripe_length - next_step_filler); - dprintf("save_stripes() parameters: start = %llu," - "\tstart_src = %llu,\tnext_step*512 = %llu," - "\tstart_in_buf_shift = %llu," - "\tnext_step_filler = %llu\n", + dprintf("save_stripes() parameters: start = %llu,\tstart_src = %llu,\tnext_step*512 = %llu,\tstart_in_buf_shift = %llu,\tnext_step_filler = %llu\n", start, start_src, copy_length, start_buf_shift, next_step_filler); @@ -10502,8 +10529,7 @@ static int imsm_manage_reshape( copy_length + next_step_filler + start_buf_shift, buf)) { - dprintf("imsm: Cannot save stripes" - " to buffer\n"); + dprintf("imsm: Cannot save stripes to buffer\n"); goto abort; } /* Convert data to destination format and store it @@ -10511,14 +10537,12 @@ static int imsm_manage_reshape( */ if (save_backup_imsm(st, dev, sra, buf + start_buf_shift, copy_length)) { - dprintf("imsm: Cannot save stripes to " - "target devices\n"); + dprintf("imsm: Cannot save stripes to target devices\n"); goto abort; } if (save_checkpoint_imsm(st, sra, UNIT_SRC_IN_CP_AREA)) { - dprintf("imsm: Cannot write checkpoint to " - "migration record (UNIT_SRC_IN_CP_AREA)\n"); + dprintf("imsm: Cannot write checkpoint to migration record (UNIT_SRC_IN_CP_AREA)\n"); goto abort; } } else { @@ -10549,13 +10573,30 @@ static int imsm_manage_reshape( if (save_checkpoint_imsm(st, sra, UNIT_SRC_NORMAL) == 1) { /* ignore error == 2, this can mean end of reshape here */ - dprintf("imsm: Cannot write checkpoint to " - "migration record (UNIT_SRC_NORMAL)\n"); + dprintf("imsm: Cannot write checkpoint to migration record (UNIT_SRC_NORMAL)\n"); goto abort; } } + /* clear migr_rec on disks after successful migration */ + struct dl *d; + + memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SIZE); + for (d = super->disks; d; d = d->next) { + if (d->index < 0 || is_failed(&d->disk)) + continue; + unsigned long long dsize; + + get_dev_size(d->fd, NULL, &dsize); + if (lseek64(d->fd, dsize - MIGR_REC_POSITION, + SEEK_SET) >= 0) { + if (write(d->fd, super->migr_rec_buf, + MIGR_REC_BUF_SIZE) != MIGR_REC_BUF_SIZE) + perror("Write migr_rec failed"); + } + } + /* return '1' if done */ ret_val = 1; abort: diff --git a/super-mbr.c b/super-mbr.c index 0fcac7c3..62b3f031 100644 --- a/super-mbr.c +++ b/super-mbr.c @@ -81,8 +81,7 @@ static int load_super_mbr(struct supertype *st, int fd, char *devname) free_mbr(st); if (posix_memalign((void**)&super, 512, 512) != 0) { - pr_err("%s could not allocate superblock\n", - __func__); + pr_err("could not allocate superblock\n"); return 1; } @@ -119,8 +118,7 @@ static int store_mbr(struct supertype *st, int fd) struct MBR *old, *super; if (posix_memalign((void**)&old, 512, 512) != 0) { - pr_err("%s could not allocate superblock\n", - __func__); + pr_err("could not allocate superblock\n"); return 1; } diff --git a/super0.c b/super0.c index 1c203927..deb59994 100644 --- a/super0.c +++ b/super0.c @@ -713,7 +713,7 @@ static int init_super0(struct supertype *st, mdu_array_info_t *info, if (posix_memalign((void**)&sb, 4096, MD_SB_BYTES + ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) { - pr_err("%s could not allocate superblock\n", __func__); + pr_err("could not allocate superblock\n"); return 0; } memset(sb, 0, MD_SB_BYTES + sizeof(bitmap_super_t)); @@ -929,7 +929,7 @@ static int compare_super0(struct supertype *st, struct supertype *tst) if (posix_memalign((void**)&first, 4096, MD_SB_BYTES + ROUND_UP(sizeof(struct bitmap_super_s), 4096)) != 0) { - pr_err("%s could not allocate superblock\n", __func__); + pr_err("could not allocate superblock\n"); return 1; } memcpy(first, second, MD_SB_BYTES + sizeof(struct bitmap_super_s)); @@ -997,7 +997,7 @@ static int load_super0(struct supertype *st, int fd, char *devname) if (posix_memalign((void**)&super, 4096, MD_SB_BYTES + ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) { - pr_err("%s could not allocate superblock\n", __func__); + pr_err("could not allocate superblock\n"); return 1; } @@ -1269,8 +1269,7 @@ static int validate_geometry0(struct supertype *st, int level, } if (size >= tbmax * 2ULL*1024*1024*1024) { if (verbose) - pr_err("0.90 metadata supports at most " - "%d terabytes per device\n", tbmax); + pr_err("0.90 metadata supports at most %d terabytes per device\n", tbmax); return 0; } if (*chunk == UnSet) diff --git a/super1.c b/super1.c index 727a08a1..f0508fe7 100644 --- a/super1.c +++ b/super1.c @@ -197,8 +197,7 @@ static int aread(struct align_fd *afd, void *buf, int len) if (!bsize || bsize > 4096 || len > 4096) { if (!bsize) - fprintf(stderr, "WARNING - aread() called with " - "invalid block size\n"); + fprintf(stderr, "WARNING - aread() called with invalid block size\n"); return -1; } b = ROUND_UP_PTR((char *)abuf, 4096); @@ -230,8 +229,7 @@ static int awrite(struct align_fd *afd, void *buf, int len) bsize = afd->blk_sz; if (!bsize || bsize > 4096 || len > 4096) { if (!bsize) - fprintf(stderr, "WARNING - awrite() called with " - "invalid block size\n"); + fprintf(stderr, "WARNING - awrite() called with invalid block size\n"); return -1; } b = ROUND_UP_PTR((char *)abuf, 4096); @@ -811,7 +809,7 @@ static int examine_badblocks_super1(struct supertype *st, int fd, char *devname) size = __le32_to_cpu(sb->bblog_size)* 512; if (posix_memalign((void**)&bbl, 4096, size) != 0) { - pr_err("%s could not allocate badblocks list\n", __func__); + pr_err("could not allocate badblocks list\n"); return 0; } offset = __le64_to_cpu(sb->super_offset) + @@ -1245,12 +1243,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info, /* set data_size to device size less data_offset */ struct misc_dev_info *misc = (struct misc_dev_info*) (st->sb + MAX_SB_SIZE + BM_SUPER_SIZE); - printf("Size was %llu\n", (unsigned long long) - __le64_to_cpu(sb->data_size)); sb->data_size = __cpu_to_le64( misc->device_size - __le64_to_cpu(sb->data_offset)); - printf("Size is %llu\n", (unsigned long long) - __le64_to_cpu(sb->data_size)); } else if (strcmp(update, "revert-reshape") == 0) { rv = -2; if (!(sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE))) @@ -1332,7 +1326,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, int sbsize; if (posix_memalign((void**)&sb, 4096, SUPER1_SIZE) != 0) { - pr_err("%s could not allocate superblock\n", __func__); + pr_err("could not allocate superblock\n"); return 0; } memset(sb, 0, SUPER1_SIZE); @@ -1682,8 +1676,7 @@ static int write_init_super1(struct supertype *st) } break; default: - pr_err("Failed to write invalid " - "metadata format 1.%i to %s\n", + pr_err("Failed to write invalid metadata format 1.%i to %s\n", st->minor_version, di->devname); rv = -EINVAL; goto out; @@ -1730,7 +1723,7 @@ static int compare_super1(struct supertype *st, struct supertype *tst) if (!first) { if (posix_memalign((void**)&first, 4096, SUPER1_SIZE) != 0) { - pr_err("%s could not allocate superblock\n", __func__); + pr_err("could not allocate superblock\n"); return 1; } memcpy(first, second, SUPER1_SIZE); @@ -1841,8 +1834,7 @@ static int load_super1(struct supertype *st, int fd, char *devname) } if (posix_memalign((void**)&super, 4096, SUPER1_SIZE) != 0) { - pr_err("%s could not allocate superblock\n", - __func__); + pr_err("could not allocate superblock\n"); return 1; } diff --git a/sysfs.c b/sysfs.c index 9a1d8569..72684702 100644 --- a/sysfs.c +++ b/sysfs.c @@ -413,7 +413,7 @@ int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev, n = write(fd, val, strlen(val)); close(fd); if (n != strlen(val)) { - dprintf(Name ": failed to write '%s' to '%s' (%s)\n", + dprintf("failed to write '%s' to '%s' (%s)\n", val, fname, strerror(errno)); return -1; } @@ -450,7 +450,7 @@ int sysfs_uevent(struct mdinfo *sra, char *event) n = write(fd, event, strlen(event)); close(fd); if (n != (int)strlen(event)) { - dprintf(Name ": failed to write '%s' to '%s' (%s)\n", + dprintf("failed to write '%s' to '%s' (%s)\n", event, fname, strerror(errno)); return -1; } @@ -490,7 +490,7 @@ int sysfs_fd_get_ll(int fd, unsigned long long *val) lseek(fd, 0, 0); n = read(fd, buf, sizeof(buf)); - if (n <= 0) + if (n <= 0 || n == sizeof(buf)) return -2; buf[n] = 0; *val = strtoull(buf, &ep, 0); @@ -526,7 +526,7 @@ int sysfs_fd_get_two(int fd, unsigned long long *v1, unsigned long long *v2) lseek(fd, 0, 0); n = read(fd, buf, sizeof(buf)); - if (n <= 0) + if (n <= 0 || n == sizeof(buf)) return -2; buf[n] = 0; *v1 = strtoull(buf, &ep, 0); @@ -562,7 +562,7 @@ int sysfs_fd_get_str(int fd, char *val, int size) lseek(fd, 0, 0); n = read(fd, val, size); - if (n <= 0) + if (n <= 0 || n == size) return -1; val[n] = 0; return n; @@ -623,8 +623,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) if ((vers % 100) < 2 || sysfs_set_str(info, NULL, "metadata_version", ver) < 0) { - pr_err("This kernel does not " - "support external metadata.\n"); + pr_err("This kernel does not support external metadata.\n"); return 1; } } @@ -644,9 +643,7 @@ int sysfs_set_array(struct mdinfo *info, int vers) rc = sysfs_set_num(info, NULL, "array_size", info->custom_array_size/2); if (rc && errno == ENOENT) { - pr_err("This kernel does not " - "have the md/array_size attribute, " - "the array may be larger than expected\n"); + pr_err("This kernel does not have the md/array_size attribute, the array may be larger than expected\n"); rc = 0; } rv |= rc; @@ -718,7 +715,7 @@ int sysfs_disk_to_sg(int fd) struct stat st; char path[256]; char sg_path[256]; - char sg_major_minor[8]; + char sg_major_minor[10]; char *c; DIR *dir; struct dirent *de; @@ -753,7 +750,7 @@ int sysfs_disk_to_sg(int fd) rv = read(fd, sg_major_minor, sizeof(sg_major_minor)); close(fd); - if (rv < 0) + if (rv < 0 || rv == sizeof(sg_major_minor)) return -1; else sg_major_minor[rv - 1] = '\0'; diff --git a/systemd/mdmonitor.service b/systemd/mdmonitor.service index 9aff2f56..c7cff3e4 100644 --- a/systemd/mdmonitor.service +++ b/systemd/mdmonitor.service @@ -10,4 +10,7 @@ Description=MD array monitor DefaultDependencies=no [Service] -ExecStart=BINDIR/mdadm --monitor --scan +Environment= MDADM_MONITOR_ARGS=--scan +EnvironmentFile=-/run/sysconfig/mdadm +ExecStartPre=-/usr/lib/systemd/scripts/mdadm_env.sh +ExecStart=BINDIR/mdadm --monitor $MDADM_MONITOR_ARGS diff --git a/test b/test index 8e61f01c..d0a6cb85 100755 --- a/test +++ b/test @@ -94,6 +94,15 @@ do_setup() { trap cleanup 0 1 3 15 trap ctrl_c 2 + # make sure there are no loop devices remaining. + # udev started things can sometimes prevent them being stopped + # immediately + while grep loop /proc/partitions > /dev/null 2>&1 + do + mdadm -Ss + losetup -d /dev/loop[0-9]* 2> /dev/null + sleep 1 + done devlist= for d in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 do @@ -102,6 +111,8 @@ do_setup() { case $DEVTYPE in loop) [ -f $targetdir/mdtest$d ] || dd if=/dev/zero of=$targetdir/mdtest$d count=$sz bs=1K > /dev/null 2>&1 + # make sure udev doesn't touch + mdadm --zero $targetdir/mdtest$d 2> /dev/null [ -b /dev/loop$d ] || mknod /dev/loop$d b 7 $d if [ $d -eq 7 ] then @@ -143,15 +154,18 @@ do_setup() { mdadm() { rm -f $targetdir/stderr case $* in - *-S* ) udevadm settle;; + *-S* ) udevadm settle + p=`cat /proc/sys/dev/raid/speed_limit_max` + echo 20000 > /proc/sys/dev/raid/speed_limit_max esac case $* in - *-C* ) $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes;; - * ) $mdadm 2> $targetdir/stderr --quiet "$@" + *-C* ) $mdadm 2> $targetdir/stderr --quiet "$@" --auto=yes;; + * ) $mdadm 2> $targetdir/stderr --quiet "$@" esac rv=$? case $* in - *-S* ) udevadm settle;; + *-S* ) udevadm settle + echo $p > /proc/sys/dev/raid/speed_limit_max esac cat >&2 $targetdir/stderr return $rv @@ -176,15 +190,31 @@ check() { echo >&2 "ERROR algorithm $2 not found"; cat /proc/mdstat; exit 1;} ;; resync | recovery | reshape) - sleep 0.5 - grep -s $1 /proc/mdstat > /dev/null || { - echo >&2 ERROR no $1 happening; cat /proc/mdstat; exit 1; } - ;; + cnt=5 + while ! grep -s $1 /proc/mdstat > /dev/null + do + if [ $cnt -gt 0 ] && grep -v idle /sys/block/md*/md/sync_action > /dev/null + then # Something isn't idle - wait a bit + sleep 0.5 + cnt=$[cnt-1] + else + echo >&2 ERROR no $1 happening; cat /proc/mdstat; exit 1 + fi + done + ;; nosync ) sleep 0.5 + # Since 4.2 we delay the close of recovery until there has been a chance for + # spares to be activated. That means that a recovery that finds nothing + # to do can still take a little longer than expected. + # add an extra check: is sync_completed shows the end is reached, assume + # there is no recovery. if grep -s -E '(resync|recovery|reshape) *=' > /dev/null /proc/mdstat ; then + incomplete=`grep / /sys/block/md*/md/sync_completed 2> /dev/null | sed '/^ *\([0-9]*\) \/ \1/d'` + if [ -n "$incomplete" ]; then echo >&2 "ERROR resync or recovery is happening!"; cat /proc/mdstat ; exit 1; + fi fi ;; @@ -192,7 +222,8 @@ check() { p=`cat /proc/sys/dev/raid/speed_limit_max` echo 2000000 > /proc/sys/dev/raid/speed_limit_max sleep 0.1 - while grep -E '(resync|recovery|reshape|check|repair) *=' > /dev/null /proc/mdstat + while grep -E '(resync|recovery|reshape|check|repair) *=' > /dev/null /proc/mdstat || + grep -v idle > /dev/null /sys/block/md*/md/sync_action do sleep 0.5; done echo $p > /proc/sys/dev/raid/speed_limit_max @@ -233,7 +264,7 @@ testdev() { dvsize=$3 chunk=$4 if [ -z "$5" ]; then - mkfs -j $dev > /dev/null 2>&1 && fsck -fn $dev >&2 + mkfs.ext3 -F -j $dev > /dev/null 2>&1 && fsck -fn $dev >&2 fi dsize=$[dvsize/chunk] dsize=$[dsize*chunk] @@ -283,11 +314,13 @@ do_test() { else log=log cat $targetdir/stderr >> $targetdir/log + echo "=======================dmesg=================" >> $targetdir/log + dmesg | tail -n 200 >> $targetdir/log if [ $exitonerror == 0 ]; then log=log-`basename $_script` - mv $targetdir/log $targetdir/$log + mv $targetdir/log $logdir/$log fi - echo "FAILED - see $targetdir/$log for details" + echo "FAILED - see $logdir/$log for details" _fail=1 fi if [ "$savelogs" == "1" ]; then @@ -339,12 +372,6 @@ parse_args() { ;; --save-logs) savelogs=1 - if [ ! -d $logdir ] ; then - mkdir $logdir - if [ $? -ne 0 ] ; then - exit 1; - fi - fi ;; --keep-going | --no-error) exitonerror=0 @@ -380,9 +407,11 @@ parse_args() { done } +logdir=$targetdir parse_args $@ do_setup +mkdir -p $logdir if [ "$savelogs" == "1" ]; then echo "Saving logs to $logdir" diff --git a/tests/00linear b/tests/00linear index 30b2c65c..e3ac6555 100644 --- a/tests/00linear +++ b/tests/00linear @@ -19,7 +19,7 @@ testdev $md0 4 $mdsize1 1 mdadm -S $md0 # now with no superblock -mdadm -B $md0 -l linear -n5 $dev0 $dev1 $dev2 $dev3 $dev4 +mdadm -B $md0 -l linear -n5 $dev0 $dev1 $dev2 $dev3 $dev4 check linear testdev $md0 5 $size 64 mdadm -S $md0 diff --git a/tests/00raid0 b/tests/00raid0 index 7f87e6ca..8bc18985 100644 --- a/tests/00raid0 +++ b/tests/00raid0 @@ -1,19 +1,19 @@ # create a simple raid0 -mdadm -CR $md0 -l raid0 -n3 $dev0 $dev1 $dev2 +mdadm -CR $md0 -l raid0 -n3 $dev0 $dev1 $dev2 check raid0 -testdev $md0 3 $mdsize2_l 512 +testdev $md0 3 $mdsize2_l 512 mdadm -S $md0 # now with version-0.90 superblock -mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3 +mdadm -CR $md0 -e0.90 -l0 -n4 $dev0 $dev1 $dev2 $dev3 check raid0 -testdev $md0 4 $mdsize0 512 +testdev $md0 4 $mdsize0 512 mdadm -S $md0 # now with no superblock -mdadm -B $md0 -l0 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 +mdadm -B $md0 -l0 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 check raid0 testdev $md0 5 $size 512 mdadm -S $md0 @@ -22,19 +22,19 @@ mdadm -S $md0 # now same again with different chunk size for chunk in 4 32 256 do - mdadm -CR $md0 -e0.90 -l raid0 --chunk $chunk -n3 $dev0 $dev1 $dev2 + mdadm -CR $md0 -e0.90 -l raid0 --chunk $chunk -n3 $dev0 $dev1 $dev2 check raid0 testdev $md0 3 $mdsize0 $chunk mdadm -S $md0 # now with version-1 superblock - mdadm -CR $md0 -e1.0 -l0 -c $chunk -n4 $dev0 $dev1 $dev2 $dev3 + mdadm -CR $md0 -e1.0 -l0 -c $chunk -n4 $dev0 $dev1 $dev2 $dev3 check raid0 testdev $md0 4 $mdsize1 $chunk mdadm -S $md0 # now with no superblock - mdadm -B $md0 -l0 -n5 --chun=$chunk $dev0 $dev1 $dev2 $dev3 $dev4 + mdadm -B $md0 -l0 -n5 --chun=$chunk $dev0 $dev1 $dev2 $dev3 $dev4 check raid0 testdev $md0 5 $size $chunk mdadm -S $md0 diff --git a/tests/00raid1 b/tests/00raid1 index eb9a658c..c93465d8 100644 --- a/tests/00raid1 +++ b/tests/00raid1 @@ -3,28 +3,28 @@ # test version0, version1, and no super # test resync and recovery. -mdadm -CR $md0 -l 1 -n2 $dev0 $dev1 +mdadm -CR $md0 -l 1 -n2 $dev0 $dev1 check resync check raid1 testdev $md0 1 $mdsize1a 64 mdadm -S $md0 # now with version-0.90 superblock, spare -mdadm -CR $md0 -e0.90 --level=raid1 -n3 -x2 $dev0 missing missing $dev1 $dev2 +mdadm -CR $md0 -e0.90 --level=raid1 -n3 -x2 $dev0 missing missing $dev1 $dev2 check recovery check raid1 testdev $md0 1 $mdsize0 64 mdadm -S $md0 # now with no superblock -mdadm -B $md0 -l mirror -n2 $dev0 $dev1 +mdadm -B $md0 -l mirror -n2 $dev0 $dev1 check resync check raid1 testdev $md0 1 $size 1 mdadm -S $md0 # again, but with no resync -mdadm -B $md0 -l 1 --assume-clean -n2 $dev0 $dev1 +mdadm -B $md0 -l 1 --assume-clean -n2 $dev0 $dev1 check raid1 check nosync testdev $md0 1 $size 1 diff --git a/tests/00raid4 b/tests/00raid4 index 97d3e3fd..00a14f2f 100644 --- a/tests/00raid4 +++ b/tests/00raid4 @@ -1,13 +1,13 @@ # create a simple raid4 set -mdadm -CfR $md0 -l 4 -n3 $dev0 $dev1 $dev2 +mdadm -CfR $md0 -l 4 -n3 $dev0 $dev1 $dev2 check resync ; check raid[45] testdev $md0 2 $mdsize1 512 mdadm -S $md0 # now with version-1 superblock -mdadm -CR $md0 -e1 --level=raid4 -n4 $dev0 $dev1 $dev2 $dev3 +mdadm -CR $md0 -e1 --level=raid4 -n4 $dev0 $dev1 $dev2 $dev3 check recovery; check raid[45] testdev $md0 3 $mdsize1 512 mdadm -S $md0 diff --git a/tests/00raid5 b/tests/00raid5 index a288c839..b2b7a971 100644 --- a/tests/00raid5 +++ b/tests/00raid5 @@ -1,13 +1,13 @@ # create a simple raid5 set -mdadm -CfR $md0 -e 0.90 -l 5 -n3 $dev0 $dev1 $dev2 +mdadm -CfR $md0 -e 0.90 -l 5 -n3 $dev0 $dev1 $dev2 check resync testdev $md0 2 $mdsize0 512 mdadm -S $md0 # now with version-1 superblock -mdadm -CR $md0 -e1 --level=raid5 -n4 $dev0 $dev1 $dev2 $dev3 +mdadm -CR $md0 -e1 --level=raid5 -n4 $dev0 $dev1 $dev2 $dev3 check recovery testdev $md0 3 $mdsize1 512 mdadm -S $md0 @@ -17,13 +17,13 @@ mdadm -S $md0 for lo in la ra left-symmetric right-symmetric do - mdadm -CfR $md0 -l 5 -p $lo -n3 $dev0 $dev1 $dev2 + mdadm -CfR $md0 -l 5 -p $lo -n3 $dev0 $dev1 $dev2 check resync ; check raid5 testdev $md0 2 $mdsize1 512 mdadm -S $md0 # now with version-1 superblock - mdadm -CR $md0 -e1 --level=raid5 --layout $lo -n4 $dev0 $dev1 $dev2 $dev3 + mdadm -CR $md0 -e1 --level=raid5 --layout $lo -n4 $dev0 $dev1 $dev2 $dev3 check recovery ; check raid5 testdev $md0 3 $mdsize1 512 mdadm -S $md0 diff --git a/tests/00raid6 b/tests/00raid6 index 63d60f5c..6977af9b 100644 --- a/tests/00raid6 +++ b/tests/00raid6 @@ -1,13 +1,13 @@ # create a simple raid6 set -mdadm -CfR $md0 -e0.90 -l 6 -n4 $dev0 $dev1 $dev2 $dev3 +mdadm -CfR $md0 -e0.90 -l 6 -n4 $dev0 $dev1 $dev2 $dev3 check resync ; check raid6 testdev $md0 2 $mdsize0 512 mdadm -S $md0 # now with version-1 superblock -mdadm -CR $md0 -e1 --level=raid6 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 +mdadm -CR $md0 -e1 --level=raid6 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 check resync ; check raid6 testdev $md0 3 $mdsize1 512 mdadm -S $md0 diff --git a/tests/01r1fail b/tests/01r1fail index 9f556321..389b813f 100644 --- a/tests/01r1fail +++ b/tests/01r1fail @@ -5,23 +5,23 @@ mdadm -CR $md0 -l1 -n4 $dev0 $dev1 $dev2 missing check resync -mdadm $md0 --fail $dev2 +mdadm $md0 --fail $dev2 check resync -mdadm $md0 --fail $dev1 +mdadm $md0 --fail $dev1 sleep 1 check nosync check state U___ -mdadm $md0 --add $dev4 $dev3 +mdadm $md0 --add $dev4 $dev3 check recovery # there could be two separate recoveries, one for each dev check wait check wait -mdadm $md0 --remove $dev2 $dev1 +mdadm $md0 --remove $dev2 $dev1 check nosync check state UUU_ mdadm --zero-superblock $dev2 -mdadm $md0 -a $dev2 +mdadm $md0 -a $dev2 check recovery check wait check state UUUU diff --git a/tests/01r5fail b/tests/01r5fail index 1d629321..873dba58 100644 --- a/tests/01r5fail +++ b/tests/01r5fail @@ -4,22 +4,22 @@ # Add two more, fail and remove one # wait for sync to complete, fail, remove, re-add -mdadm -CR $md0 -l5 -n4 $dev0 $dev1 $dev2 $dev3 +mdadm -CR $md0 -l5 -n4 $dev0 $dev1 $dev2 $dev3 check recovery mdadm $md0 --fail $dev3 sleep 1 check nosync check state UUU_ -mdadm $md0 --add $dev4 $dev5 +mdadm $md0 --add $dev4 $dev5 check recovery check wait -mdadm $md0 --fail $dev0 -mdadm $md0 --remove $dev3 $dev0 +mdadm $md0 --fail $dev0 +mdadm $md0 --remove $dev3 $dev0 check recovery check state _UUU -mdadm $md0 -a $dev3 +mdadm $md0 -a $dev3 check recovery check wait check state UUUU diff --git a/tests/01r5integ b/tests/01r5integ index ffb30ce9..48676a22 100644 --- a/tests/01r5integ +++ b/tests/01r5integ @@ -27,7 +27,7 @@ do exit 1 fi mdadm $md0 -a $i - check wait + while ! (check state 'U*'); do check wait; sleep 0.2; done done mdadm -S $md0 done diff --git a/tests/01raid6integ b/tests/01raid6integ index c6fcdae6..12f4d81b 100644 --- a/tests/01raid6integ +++ b/tests/01raid6integ @@ -47,10 +47,10 @@ do exit 1 fi mdadm $md0 -a $first - check wait + while ! (check state 'U*_U*'); do check wait; sleep 0.2; done done mdadm $md0 -a $second - check wait + while ! (check state 'U*'); do check wait; sleep 0.2; done totest="$totest $second" done mdadm -S $md0 diff --git a/tests/02r1add b/tests/02r1add index c07ec977..757f6965 100644 --- a/tests/02r1add +++ b/tests/02r1add @@ -1,7 +1,7 @@ # Make a raid1, add a device, then remove it again. -mdadm -CR $md0 -l1 -n2 -x1 $dev0 $dev1 $dev2 +mdadm -CR $md0 -l1 -n2 -x1 $dev0 $dev1 $dev2 check resync check wait check state UU @@ -11,7 +11,7 @@ check recovery check wait check state UUU -mdadm $md0 --fail $dev0 +mdadm $md0 --fail $dev0 check state _UU mdadm --grow $md0 -n 2 @@ -21,7 +21,7 @@ mdadm -S $md0 # same again for version-1 -mdadm -CR $md0 -l1 -n2 -e1.2 -x1 $dev0 $dev1 $dev2 +mdadm -CR $md0 -l1 -n2 -e1.2 -x1 $dev0 $dev1 $dev2 check resync check wait check state UU @@ -31,7 +31,7 @@ check recovery check wait check state UUU -mdadm $md0 --fail $dev0 +mdadm $md0 --fail $dev0 check state _UU mdadm --grow $md0 -n 2 diff --git a/tests/02r1grow b/tests/02r1grow index 6604208d..5754c88b 100644 --- a/tests/02r1grow +++ b/tests/02r1grow @@ -2,7 +2,7 @@ # create a small raid1 array, make it larger. Then make it smaller -mdadm -CR $md0 -e 0.90 --level raid1 --raid-disks 3 --size $[size/2] $dev1 $dev2 $dev3 +mdadm -CR $md0 -e 0.90 --level raid1 --raid-disks 3 --size $[size/2] $dev1 $dev2 $dev3 check wait check state UUU testdev $md0 1 $[size/2] 1 @@ -19,7 +19,7 @@ testdev $md0 1 $[size/2] 1 mdadm -S $md0 # same again with version 1.1 superblock -mdadm -CR $md0 --level raid1 --metadata=1.1 --raid-disks 3 --size $[size/2] $dev1 $dev2 $dev3 +mdadm -CR $md0 --level raid1 --metadata=1.1 --raid-disks 3 --size $[size/2] $dev1 $dev2 $dev3 check wait check state UUU testdev $md0 1 $[size/2] 1 diff --git a/tests/02r5grow b/tests/02r5grow index b91ffcd4..386e82ee 100644 --- a/tests/02r5grow +++ b/tests/02r5grow @@ -2,7 +2,7 @@ # create a small raid5 array, make it larger. Then make it smaller -mdadm -CR $md0 -e0.90 --level raid5 --chunk=64 --raid-disks 3 --size $[size/2] $dev1 $dev2 $dev3 +mdadm -CR $md0 -e0.90 --level raid5 --chunk=64 --raid-disks 3 --size $[size/2] $dev1 $dev2 $dev3 check wait check state UUU testdev $md0 2 $[size/2] 32 @@ -19,7 +19,7 @@ testdev $md0 2 $[size/2] 32 mdadm -S $md0 # same again with version 1.1 superblock -mdadm -CR $md0 --level raid5 --metadata=1.1 --chunk=128 --raid-disks 4 --size $[size/2] $dev1 $dev2 $dev3 $dev4 +mdadm -CR $md0 --level raid5 --metadata=1.1 --chunk=128 --raid-disks 4 --size $[size/2] $dev1 $dev2 $dev3 $dev4 check wait check state UUUU testdev $md0 3 $[size/2] 128 diff --git a/tests/02r6grow b/tests/02r6grow index 38c77810..759e6275 100644 --- a/tests/02r6grow +++ b/tests/02r6grow @@ -2,7 +2,7 @@ # create a small raid6 array, make it larger. Then make it smaller -mdadm -CR $md0 -e 0.90 --level raid6 --chunk=64 --raid-disks 4 --size $[size/2] $dev1 $dev2 $dev3 $dev4 +mdadm -CR $md0 -e 0.90 --level raid6 --chunk=64 --raid-disks 4 --size $[size/2] $dev1 $dev2 $dev3 $dev4 check wait check state UUUU testdev $md0 2 $[size/2] 32 @@ -19,7 +19,7 @@ testdev $md0 2 $[size/2] 32 mdadm -S $md0 # same again with version 1.1 superblock -mdadm -CR $md0 --level raid6 --metadata=1.1 --chunk=128 --raid-disks 4 --size $[size/2] $dev1 $dev2 $dev3 $dev4 +mdadm -CR $md0 --level raid6 --metadata=1.1 --chunk=128 --raid-disks 4 --size $[size/2] $dev1 $dev2 $dev3 $dev4 check wait check state UUUU testdev $md0 2 $[size/2] 128 diff --git a/tests/03r0assem b/tests/03r0assem index 0b998ec1..6744e322 100644 --- a/tests/03r0assem +++ b/tests/03r0assem @@ -4,63 +4,63 @@ # uuid, md-minor on command line with wildcard devices # mdadm.conf file -mdadm -CR $md2 -l0 -n3 $dev0 $dev1 $dev2 +mdadm -CR $md2 -l0 -n3 $dev0 $dev1 $dev2 check raid0 tst="testdev $md2 3 $mdsize1_l 512" $tst uuid=`mdadm -Db $md2 | sed 's/.*UUID=//'` mdadm -S $md2 -mdadm -A $md2 $dev0 $dev1 $dev2 +mdadm -A $md2 $dev0 $dev1 $dev2 $tst mdadm -S $md2 -mdadm -A $md2 -u $uuid $devlist +mdadm -A $md2 -u $uuid $devlist $tst mdadm -S $md2 -mdadm --assemble $md2 --name=2 $devlist +mdadm --assemble $md2 --name=2 $devlist $tst mdadm -S $md2 conf=$targetdir/mdadm.conf -{ +{ echo DEVICE $devlist echo array $md2 UUID=$uuid } > $conf -mdadm -As -c $conf $md2 +mdadm -As -c $conf $md2 $tst mdadm -S $md2 -{ +{ echo DEVICE $devlist echo array $md2 name=2 } > $conf -mdadm -As -c $conf $md2 +mdadm -As -c $conf $md2 $tst mdadm -S $md2 -{ +{ echo DEVICE $devlist echo array $md2 devices=$dev0,$dev1,$dev2 } > $conf -mdadm -As -c $conf $md2 +mdadm -As -c $conf $md2 $tst echo "DEVICE $devlist" > $conf mdadm -Db $md2 >> $conf mdadm -S $md2 -mdadm --assemble --scan --config=$conf $md2 +mdadm --assemble --scan --config=$conf $md2 $tst mdadm -S $md2 echo " metadata=0.90 devices=$dev0,$dev1,$dev2" >> $conf -mdadm --assemble --scan --config=$conf $md2 +mdadm --assemble --scan --config=$conf $md2 $tst mdadm -S $md2 @@ -68,7 +68,7 @@ mdadm -S $md2 ### Now for version 0... mdadm --zero-superblock $dev0 $dev1 $dev2 -mdadm -CR $md2 -l0 --metadata=0.90 -n3 $dev0 $dev1 $dev2 +mdadm -CR $md2 -l0 --metadata=0.90 -n3 $dev0 $dev1 $dev2 check raid0 tst="testdev $md2 3 $mdsize0 512" $tst @@ -76,56 +76,56 @@ $tst uuid=`mdadm -Db $md2 | sed 's/.*UUID=//'` mdadm -S $md2 -mdadm -A $md2 $dev0 $dev1 $dev2 +mdadm -A $md2 $dev0 $dev1 $dev2 $tst mdadm -S $md2 -mdadm -A $md2 -u $uuid $devlist +mdadm -A $md2 -u $uuid $devlist $tst mdadm -S $md2 -mdadm --assemble $md2 --super-minor=2 $devlist # +mdadm --assemble $md2 --super-minor=2 $devlist # $tst mdadm -S $md2 conf=$targetdir/mdadm.conf -{ +{ echo DEVICE $devlist echo array $md2 UUID=$uuid } > $conf -mdadm -As -c $conf $md2 +mdadm -As -c $conf $md2 $tst mdadm -S $md2 -{ +{ echo DEVICE $devlist echo array $md2 super-minor=2 } > $conf -mdadm -As -c $conf $md2 +mdadm -As -c $conf $md2 $tst mdadm -S $md2 -{ +{ echo DEVICE $devlist echo array $md2 devices=$dev0,$dev1,$dev2 } > $conf -mdadm -As -c $conf $md2 +mdadm -As -c $conf $md2 $tst echo "DEVICE $devlist" > $conf mdadm -Db $md2 >> $conf mdadm -S $md2 -mdadm --assemble --scan --config=$conf $md2 +mdadm --assemble --scan --config=$conf $md2 $tst mdadm -S $md2 echo " metadata=1 devices=$dev0,$dev1,$dev2" >> $conf -mdadm --assemble --scan --config=$conf $md2 +mdadm --assemble --scan --config=$conf $md2 $tst mdadm -S $md2 diff --git a/tests/03r5assem b/tests/03r5assem index de0d56b6..0c7fb8c6 100644 --- a/tests/03r5assem +++ b/tests/03r5assem @@ -2,108 +2,108 @@ # create a raid5 array and assemble it in various ways, # including with missing devices. -mdadm -CR -e 0.90 $md1 -l5 -n3 $dev0 $dev1 $dev2 +mdadm -CR -e 0.90 $md1 -l5 -n3 $dev0 $dev1 $dev2 tst="check raid5 ;testdev $md1 2 $mdsize0 512 ; mdadm -S $md1" uuid=`mdadm -Db $md1 | sed 's/.*UUID=//'` check wait eval $tst -mdadm -A $md1 $dev0 $dev1 $dev2 +mdadm -A $md1 $dev0 $dev1 $dev2 eval $tst -mdadm -A $md1 -u $uuid $devlist +mdadm -A $md1 -u $uuid $devlist eval $tst -mdadm -A $md1 -m 1 $devlist +mdadm -A $md1 -m 1 $devlist eval $tst conf=$targetdir/mdadm.conf -{ +{ echo DEVICE $devlist echo array $md1 UUID=$uuid } > $conf -mdadm -As -c $conf $md1 +mdadm -As -c $conf $md1 eval $tst -{ +{ echo DEVICE $devlist echo array $md1 super-minor=1 } > $conf -mdadm -As -c $conf +mdadm -As -c $conf eval $tst -{ +{ echo DEVICE $devlist echo array $md1 devices=$dev0,$dev1,$dev2 } > $conf -mdadm -As -c $conf +mdadm -As -c $conf echo "DEVICE $devlist" > $conf mdadm -Db $md1 >> $conf eval $tst -mdadm --assemble --scan --config=$conf $md1 +mdadm --assemble --scan --config=$conf $md1 eval $tst echo " metadata=0.90 devices=$dev0,$dev1,$dev2" >> $conf -mdadm --assemble --scan --config=$conf $md1 +mdadm --assemble --scan --config=$conf $md1 eval $tst ### Now with a missing device -mdadm -AR $md1 $dev0 $dev2 # +mdadm -AR $md1 $dev0 $dev2 # check state U_U eval $tst -mdadm -A $md1 -u $uuid $devlist +mdadm -A $md1 -u $uuid $devlist check state U_U eval $tst -mdadm -A $md1 -m 1 $devlist +mdadm -A $md1 -m 1 $devlist check state U_U eval $tst conf=$targetdir/mdadm.conf -{ +{ echo DEVICE $devlist echo array $md1 UUID=$uuid } > $conf -mdadm -As -c $conf $md1 +mdadm -As -c $conf $md1 check state U_U eval $tst -{ +{ echo DEVICE $devlist echo array $md1 super-minor=1 } > $conf -mdadm -As -c $conf +mdadm -As -c $conf check state U_U eval $tst -{ +{ echo DEVICE $devlist echo array $md1 devices=$dev0,$dev1,$dev2 } > $conf -mdadm -As -c $conf +mdadm -As -c $conf echo "DEVICE $devlist" > $conf mdadm -Db $md1 >> $conf check state U_U eval $tst -mdadm --assemble --scan --config=$conf $md1 +mdadm --assemble --scan --config=$conf $md1 check state U_U eval $tst echo " metadata=0.90 devices=$dev0,$dev1,$dev2" >> $conf -mdadm --assemble --scan --config=$conf $md1 +mdadm --assemble --scan --config=$conf $md1 check state U_U eval $tst diff --git a/tests/04r0update b/tests/04r0update index 0cd815ac..73ee3b9f 100644 --- a/tests/04r0update +++ b/tests/04r0update @@ -1,15 +1,15 @@ # create a raid0, re-assemble with a different super-minor -mdadm -CR -e 0.90 $md0 -l0 -n3 $dev0 $dev1 $dev2 +mdadm -CR -e 0.90 $md0 -l0 -n3 $dev0 $dev1 $dev2 testdev $md0 3 $mdsize0 512 minor1=`mdadm -E $dev0 | sed -n -e 's/.*Preferred Minor : //p'` mdadm -S /dev/md0 -mdadm -A $md1 $dev0 $dev1 $dev2 +mdadm -A $md1 $dev0 $dev1 $dev2 minor2=`mdadm -E $dev0 | sed -n -e 's/.*Preferred Minor : //p'` mdadm -S /dev/md1 -mdadm -A $md1 --update=super-minor $dev0 $dev1 $dev2 +mdadm -A $md1 --update=super-minor $dev0 $dev1 $dev2 minor3=`mdadm -E $dev0 | sed -n -e 's/.*Preferred Minor : //p'` mdadm -S /dev/md1 diff --git a/tests/04r1update b/tests/04r1update index 7a50131f..e22965bc 100644 --- a/tests/04r1update +++ b/tests/04r1update @@ -2,14 +2,14 @@ set -i # create a raid1 array, let it sync, then re-assemble with a force-sync -mdadm -CR $md0 -l1 -n2 $dev0 $dev1 +mdadm -CR $md0 -l1 -n2 $dev0 $dev1 check wait mdadm -S $md0 -mdadm -A $md0 $dev0 $dev1 +mdadm -A $md0 $dev0 $dev1 check nosync mdadm -S $md0 -mdadm -A $md0 -U resync $dev0 $dev1 +mdadm -A $md0 -U resync $dev0 $dev1 check resync mdadm -S $md0 diff --git a/tests/04update-metadata b/tests/04update-metadata index 10bb70f0..232fc1ff 100644 --- a/tests/04update-metadata +++ b/tests/04update-metadata @@ -32,7 +32,7 @@ then echo >&2 should fail during resync exit 1 fi mdadm -A $md0 $dlist -mdadm --wait $md0 +mdadm --wait $md0 || true mdadm -S $md0 # should succeed now diff --git a/tests/05r1-add-internalbitmap-v1b b/tests/05r1-add-internalbitmap-v1b index b077fa7e..da78fd61 100644 --- a/tests/05r1-add-internalbitmap-v1b +++ b/tests/05r1-add-internalbitmap-v1b @@ -1,4 +1,4 @@ -# +# # create a raid1 without any bitmap, add the bitmap and then write to # the device. This should catch the case where the bitmap is created # but not reloaded correctly, such as the case fixed by diff --git a/tests/05r1-add-internalbitmap-v1c b/tests/05r1-add-internalbitmap-v1c index 7b397844..9f2f128b 100644 --- a/tests/05r1-add-internalbitmap-v1c +++ b/tests/05r1-add-internalbitmap-v1c @@ -1,4 +1,4 @@ -# +# # create a raid1 without any bitmap, add the bitmap and then write to # the device. This should catch the case where the bitmap is created # but not reloaded correctly, such as the case fixed by diff --git a/tests/05r1-bitmapfile b/tests/05r1-bitmapfile index fcd8372b..f384f0ea 100644 --- a/tests/05r1-bitmapfile +++ b/tests/05r1-bitmapfile @@ -1,10 +1,10 @@ -# +# # create a raid1 with a bitmap file # bmf=$targetdir/bitmap rm -f $bmf -mdadm --create --run $md0 --level=1 -n2 --delay=1 --bitmap $bmf $dev1 $dev2 +mdadm --create --run $md0 --level=1 -n2 --delay=1 --bitmap $bmf $dev1 $dev2 check wait testdev $md0 1 $mdsize1a 64 mdadm -S $md0 @@ -24,7 +24,7 @@ testdev $md0 1 $mdsize1a 64 sleep 4 dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` if [ $dirty3 -lt 400 ] -then +then echo >&2 "ERROR dirty count $dirty3 is too small" exit 2 fi diff --git a/tests/05r1-grow-external b/tests/05r1-grow-external index 49666369..69da3e90 100644 --- a/tests/05r1-grow-external +++ b/tests/05r1-grow-external @@ -21,7 +21,7 @@ dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` #echo $dirty1 $dirty2 $dirty3 $dirty4 if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ] -then +then echo bad dirty counts exit 1 fi diff --git a/tests/05r1-grow-internal b/tests/05r1-grow-internal index a648b440..24b3aece 100644 --- a/tests/05r1-grow-internal +++ b/tests/05r1-grow-internal @@ -19,7 +19,7 @@ dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` #echo $dirty1 $dirty2 $dirty3 $dirty4 if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ] -then +then echo bad dirty counts exit 1 fi diff --git a/tests/05r1-grow-internal-1 b/tests/05r1-grow-internal-1 index a110f3b0..2f0d8237 100644 --- a/tests/05r1-grow-internal-1 +++ b/tests/05r1-grow-internal-1 @@ -19,7 +19,7 @@ dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` #echo $dirty1 $dirty2 $dirty3 $dirty4 if [ $dirty2 -ne 0 -o $dirty4 -ne 0 -o $dirty3 -lt 400 ] -then +then echo bad dirty counts exit 1 fi diff --git a/tests/05r1-internalbitmap b/tests/05r1-internalbitmap index 2bfeab8e..dd7232a7 100644 --- a/tests/05r1-internalbitmap +++ b/tests/05r1-internalbitmap @@ -1,8 +1,8 @@ -# +# # create a raid1 with an internal bitmap # -mdadm --create -e0.90 --run $md0 --level=1 -n2 --delay=1 --bitmap internal --bitmap-chunk=4 $dev1 $dev2 +mdadm --create -e0.90 --run $md0 --level=1 -n2 --delay=1 --bitmap internal --bitmap-chunk=4 $dev1 $dev2 check wait testdev $md0 1 $mdsize0 64 mdadm -S $md0 @@ -22,7 +22,7 @@ testdev $md0 1 $mdsize0 64 sleep 4 dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` if [ $dirty3 -lt 400 ] -then +then echo >&2 "ERROR dirty count $dirty3 is too small" exit 2 fi diff --git a/tests/05r1-internalbitmap-v1a b/tests/05r1-internalbitmap-v1a index 3fcb0249..3ddc082f 100644 --- a/tests/05r1-internalbitmap-v1a +++ b/tests/05r1-internalbitmap-v1a @@ -1,8 +1,8 @@ -# +# # create a raid1 with an internal bitmap # -mdadm --create --run $md0 --metadata=1.0 --level=1 -n2 --delay=1 --bitmap internal --bitmap-chunk=4 $dev1 $dev2 +mdadm --create --run $md0 --metadata=1.0 --level=1 -n2 --delay=1 --bitmap internal --bitmap-chunk=4 $dev1 $dev2 check wait check bitmap testdev $md0 1 $mdsize1b 64 @@ -23,7 +23,7 @@ testdev $md0 1 $mdsize1b 64 sleep 4 dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` if [ $dirty3 -lt 400 ] -then +then echo >&2 "ERROR dirty count $dirty3 is too small" exit 2 fi diff --git a/tests/05r1-internalbitmap-v1b b/tests/05r1-internalbitmap-v1b index 1097536b..40f7abea 100644 --- a/tests/05r1-internalbitmap-v1b +++ b/tests/05r1-internalbitmap-v1b @@ -1,8 +1,8 @@ -# +# # create a raid1 with an internal bitmap # -mdadm --create --run $md0 --metadata=1.1 --level=1 -n2 --delay=1 --bitmap internal --bitmap-chunk=4 $dev1 $dev2 +mdadm --create --run $md0 --metadata=1.1 --level=1 -n2 --delay=1 --bitmap internal --bitmap-chunk=4 $dev1 $dev2 check wait check bitmap testdev $md0 1 $mdsize11 64 @@ -24,7 +24,7 @@ testdev $md0 1 $mdsize11 64 sleep 4 dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` if [ $dirty3 -lt 400 ] -then +then echo >&2 "ERROR dirty count $dirty3 is too small" exit 2 fi diff --git a/tests/05r1-internalbitmap-v1c b/tests/05r1-internalbitmap-v1c index f6bbcf6b..2eaea59b 100644 --- a/tests/05r1-internalbitmap-v1c +++ b/tests/05r1-internalbitmap-v1c @@ -1,8 +1,8 @@ -# +# # create a raid1 with an internal bitmap # -mdadm --create --run $md0 --metadata=1.2 --level=1 -n2 --delay=1 --bitmap internal --bitmap-chunk 4 $dev1 $dev2 +mdadm --create --run $md0 --metadata=1.2 --level=1 -n2 --delay=1 --bitmap internal --bitmap-chunk 4 $dev1 $dev2 check wait check bitmap testdev $md0 1 $mdsize12 64 @@ -23,7 +23,7 @@ testdev $md0 1 $mdsize12 64 sleep 4 dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` if [ $dirty3 -lt 400 ] -then +then echo >&2 "ERROR dirty count $dirty3 is too small" exit 2 fi diff --git a/tests/05r1-n3-bitmapfile b/tests/05r1-n3-bitmapfile index 1bb9af16..f1c3f1ee 100644 --- a/tests/05r1-n3-bitmapfile +++ b/tests/05r1-n3-bitmapfile @@ -1,12 +1,12 @@ -# +# # create a raid1 with 3 devices and a bitmap file # make sure resync does right thing. # # bmf=$targetdir/bitmap rm -f $bmf -mdadm --create -e0.90 --run $md0 --level=1 -n3 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3 +mdadm --create -e0.90 --run $md0 --level=1 -n3 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3 check wait testdev $md0 1 $mdsize0 64 mdadm -S $md0 @@ -26,7 +26,7 @@ testdev $md0 1 $mdsize0 64 sleep 4 dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` if [ $dirty3 -lt 400 ] -then +then echo >&2 "ERROR dirty count $dirty3 is too small" exit 2 fi diff --git a/tests/05r1-re-add b/tests/05r1-re-add index 44da8908..fa6bbcb4 100644 --- a/tests/05r1-re-add +++ b/tests/05r1-re-add @@ -24,13 +24,16 @@ mdadm $md0 -r $dev2 testdev $md0 1 $mdsize1a 64 mdadm $md0 -a $dev2 check wait -cmp --ignore-initial=$[16*512] --bytes=$[$mdsize0*1024] $dev1 $dev2 +blockdev --flushbufs $dev1 $dev2 +cmp --ignore-initial=$[64*512] --bytes=$[$mdsize0*1024] $dev1 $dev2 mdadm $md0 -f $dev2; sleep 1 mdadm $md0 -r $dev2 if dd if=/dev/zero of=$md0 ; then : ; fi +blockdev --flushbufs $md0 # ensure writes have been sent. mdadm $md0 -a $dev2 check recovery check wait -cmp --ignore-initial=$[16*512] --bytes=$[$mdsize0*1024] $dev1 $dev2 +blockdev --flushbufs $dev1 $dev2 +cmp --ignore-initial=$[64*512] --bytes=$[$mdsize0*1024] $dev1 $dev2 mdadm -S $md0 diff --git a/tests/05r1-re-add-nosuper b/tests/05r1-re-add-nosuper index 8025a685..058d602d 100644 --- a/tests/05r1-re-add-nosuper +++ b/tests/05r1-re-add-nosuper @@ -29,6 +29,7 @@ cmp --bytes=$[$mdsize0*1024] $dev1 $dev2 mdadm $md0 -f $dev2; sleep 1 mdadm $md0 -r $dev2 if dd if=/dev/zero of=$md0 ; then : ; fi +blockdev --flushbufs $md0 # make sure writes have been sent mdadm $md0 --re-add $dev2 check recovery check wait diff --git a/tests/05r6tor0 b/tests/05r6tor0 index 2e0f1853..2fd51f2e 100644 --- a/tests/05r6tor0 +++ b/tests/05r6tor0 @@ -4,24 +4,24 @@ set -x -e # then reshape back up to RAID5 and RAID5 mdadm -CR $md0 -l6 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 -check wait +check wait; sleep 1 check raid6 testdev $md0 3 19456 512 mdadm -G $md0 -l5 -check wait +check wait; sleep 1 check raid5 testdev $md0 3 19456 512 mdadm -G $md0 -l0 -check wait +check wait; sleep 1 check raid0 testdev $md0 3 19456 512 mdadm -G $md0 -l5 --add $dev3 $dev4 -check wait +check wait; sleep 1 check raid5 check algorithm 2 testdev $md0 3 19456 512 mdadm -G $md0 -l 6 -check wait +check wait; sleep 1 check raid6 check algorithm 2 testdev $md0 3 19456 512 diff --git a/tests/07changelevelintr b/tests/07changelevelintr index 89cfff0c..18c63092 100644 --- a/tests/07changelevelintr +++ b/tests/07changelevelintr @@ -12,7 +12,8 @@ checkgeo() { shift sleep 0.5 check wait - for attr in level raid_disks chunk_size layout + sleep 1 + for attr in level raid_disks chunk_size layout do if [ $# -gt 0 ] ; then val=$1 diff --git a/tests/07changelevels b/tests/07changelevels index d33e007c..a328874a 100644 --- a/tests/07changelevels +++ b/tests/07changelevels @@ -26,7 +26,8 @@ checkgeo() { shift sleep 0.5 check wait - for attr in level raid_disks chunk_size layout + sleep 1 + for attr in level raid_disks chunk_size layout do if [ $# -gt 0 ] ; then val=$1 @@ -38,7 +39,7 @@ checkgeo() { fi done } - + bu=/tmp/md-test-backup rm -f $bu diff --git a/tests/07layouts b/tests/07layouts index 4c20eb8b..acd1a800 100644 --- a/tests/07layouts +++ b/tests/07layouts @@ -28,7 +28,7 @@ checkgeo() { shift sleep 0.5 check wait - for attr in level raid_disks chunk_size layout + for attr in level raid_disks chunk_size layout do if [ $# -gt 0 ] ; then val=$1 @@ -40,7 +40,7 @@ checkgeo() { fi done } - + bu=/tmp/md-test-backup rm -f $bu diff --git a/tests/07reshape5intr b/tests/07reshape5intr index 71ef2c78..0f4803ac 100644 --- a/tests/07reshape5intr +++ b/tests/07reshape5intr @@ -31,7 +31,7 @@ do echo 1000 > /proc/sys/dev/raid/speed_limit_min echo 2000 > /proc/sys/dev/raid/speed_limit_max check wait - echo check > /sys/block/md0/md/sync_action + while ! echo check > /sys/block/md0/md/sync_action; do sleep 0.1; done check wait mm=`cat /sys/block/md0/md/mismatch_cnt` if [ $mm -gt 0 ] diff --git a/tests/07revert-inplace b/tests/07revert-inplace index 48416c8f..a73eb977 100644 --- a/tests/07revert-inplace +++ b/tests/07revert-inplace @@ -8,7 +8,7 @@ mdadm -CR --assume-clean $md0 -l5 -n4 -x1 $devlist4 check raid5 testdev $md0 3 $mdsize1 512 mdadm -G $md0 -l 6 -sleep 3 +sleep 2 mdadm -S $md0 mdadm -A $md0 --update=revert-reshape $devlist4 --backup-file=/tmp/md-backup check wait @@ -22,7 +22,7 @@ mdadm -CR --assume-clean $md0 -l6 -n5 $devlist4 check raid6 testdev $md0 3 $mdsize1 512 mdadm -G $md0 -l 5 -sleep 3 +sleep 2 mdadm -S $md0 mdadm -A $md0 --update=revert-reshape $devlist4 --backup-file=/tmp/md-backup check wait @@ -35,7 +35,7 @@ mdadm -CR --assume-clean $md0 -l10 -n6 -c 64 $devlist5 check raid10 testdev $md0 3 $mdsize1 64 mdadm -G $md0 -c 32 -sleep 3 +sleep 2 mdadm -S $md0 strace -o /tmp/str ./mdadm -A $md0 --update=revert-reshape $devlist5 check wait diff --git a/tests/09imsm-assemble b/tests/09imsm-assemble index 2a42369e..d7028c62 100644 --- a/tests/09imsm-assemble +++ b/tests/09imsm-assemble @@ -31,19 +31,19 @@ num_disks=4 size=$((10*1024)) mdadm -CR $container -e imsm -n $num_disks $dev0 $dev1 $dev2 $dev3 mdadm -CR $member $dev0 $dev2 -n 2 -l 1 -z $size -mdadm --wait $member +mdadm --wait $member || true mdadm -Ss # make dev0 and dev1 a new rebuild family mdadm -A $container $dev0 $dev1 mdadm -IR $container -mdadm --wait ${member}_0 +mdadm --wait ${member}_0 || true mdadm -Ss # make dev2 and dev3 a new rebuild family mdadm -A $container $dev2 $dev3 mdadm -IR $container -mdadm --wait ${member}_0 +mdadm --wait ${member}_0 || true mdadm -Ss # reassemble and make sure one of the families falls out diff --git a/tests/09imsm-create-fail-rebuild b/tests/09imsm-create-fail-rebuild index 4b656b53..de17f321 100644 --- a/tests/09imsm-create-fail-rebuild +++ b/tests/09imsm-create-fail-rebuild @@ -71,7 +71,7 @@ check wait # FAIL / REBUILD imsm_check_hold $container $dev0 mdadm --fail $member0 $dev0 -mdadm --wait-clean --scan +mdadm --wait-clean --scan || true imsm_check_removal $container $dev0 mdadm --add $container $dev4 check wait diff --git a/tests/10ddf-assemble-missing b/tests/10ddf-assemble-missing index 17f17244..4bf21b25 100644 --- a/tests/10ddf-assemble-missing +++ b/tests/10ddf-assemble-missing @@ -12,8 +12,8 @@ ddf_check container 4 mdadm -CR $member1 -n 4 -l 10 $dev8 $dev10 $dev9 $dev11 -z 10000 mdadm -CR $member0 -n 2 -l 1 $dev8 $dev9 -z 10000 -mdadm --wait $member0 -mdadm --wait $member1 +mdadm --wait $member0 || true +mdadm --wait $member1 || true mdadm -Ss sleep 1 @@ -23,7 +23,7 @@ mdadm -I $dev10 mdadm -I $dev11 # Start runnable members -mdadm -IRs +mdadm -IRs || true mdadm -Ss #[ -f /var/tmp/mdmon.log ] && cat /var/tmp/mdmon.log diff --git a/tests/10ddf-create b/tests/10ddf-create index 2f7747cd..44e95441 100644 --- a/tests/10ddf-create +++ b/tests/10ddf-create @@ -78,7 +78,7 @@ mdadm -Ss # and now assemble fully incrementally. for i in $dev8 $dev9 $dev10 $dev11 $dev12 -do +do mdadm -I $i -c /var/tmp/mdadm.conf done check nosync diff --git a/tests/10ddf-create-fail-rebuild b/tests/10ddf-create-fail-rebuild index 525c24d3..a8e8ced9 100644 --- a/tests/10ddf-create-fail-rebuild +++ b/tests/10ddf-create-fail-rebuild @@ -70,7 +70,7 @@ check wait # FAIL / REBUILD ddf_check_hold $container $dev8 mdadm --fail $member0 $dev8 -mdadm --wait-clean --scan +mdadm --wait-clean --scan || true ddf_check_removal $container $dev8 mdadm --add $container $dev12 check wait diff --git a/tests/10ddf-fail-readd b/tests/10ddf-fail-readd index 746f049e..9cd78937 100644 --- a/tests/10ddf-fail-readd +++ b/tests/10ddf-fail-readd @@ -10,7 +10,7 @@ mdadm -CR $container -e ddf -l container -n 2 $dev8 $dev9 mdadm -CR $member0 -l raid1 -n 2 $container #$dir/mdadm -CR $member0 -l raid1 -n 2 $container >/tmp/mdmon.txt 2>&1 -mke2fs $member0 +mke2fs -F $member0 check wait set -- $(get_raiddisks $member0) @@ -28,7 +28,7 @@ good0=$1 mdadm $container --add $fail0 sleep 1 -mdadm --wait $member0 +mdadm --wait $member0 || true ret=0 set -- $(get_raiddisks $member0) diff --git a/tests/10ddf-fail-readd-readonly b/tests/10ddf-fail-readd-readonly index ed24585d..6a74d9c8 100644 --- a/tests/10ddf-fail-readd-readonly +++ b/tests/10ddf-fail-readd-readonly @@ -45,7 +45,7 @@ mdadm $container --remove $fail0 mdadm $container --add $fail0 sleep 1 -mdadm --wait $member0 +mdadm --wait $member0 || true set -- $(get_raiddisks $member0) case $1:$2 in diff --git a/tests/10ddf-fail-stop-readd b/tests/10ddf-fail-stop-readd index 4a0511a1..f8ebe176 100644 --- a/tests/10ddf-fail-stop-readd +++ b/tests/10ddf-fail-stop-readd @@ -11,7 +11,7 @@ mdadm -CR $member0 -l raid1 -n 2 $container #$dir/mdadm -CR $member0 -l raid1 -n 2 $container >/tmp/mdmon.txt 2>&1 # Write to the array -mke2fs $member0 +mke2fs -F $member0 check wait set -- $(get_raiddisks $member0) @@ -30,16 +30,16 @@ mdadm -Ss sleep 1 # Now simulate incremental assembly mdadm -I $good0 -mdadm -IRs +mdadm -IRs || true # Write to the array -mke2fs $member0 +mke2fs -F $member0 # We re-add the disk now mdadm $container --add $fail0 sleep 1 -mdadm --wait $member0 +mdadm --wait $member0 || true ret=0 set -- $(get_raiddisks $member0) diff --git a/tests/10ddf-fail-twice b/tests/10ddf-fail-twice index d0b4ac61..6af19434 100644 --- a/tests/10ddf-fail-twice +++ b/tests/10ddf-fail-twice @@ -7,7 +7,7 @@ ddf_check container $num_disks mdadm -CR $member0 -n 2 -l 1 $container mdadm -CR $member1 -n 3 -l 5 $container -mdadm --wait $member1 $member0 || mdadm --wait $member1 $member0 +mdadm --wait $member1 $member0 || mdadm --wait $member1 $member0 || true set -- $(get_raiddisks $member0) fail0=$1 @@ -18,7 +18,7 @@ mdadm $member1 --fail $fail1 mdadm $container --add $dev13 -mdadm --wait $member1 $member0 || mdadm --wait $member1 $member0 +mdadm --wait $member1 $member0 || mdadm --wait $member1 $member0 || true devs0="$(get_raiddisks $member0)" diff --git a/tests/10ddf-fail-two-spares b/tests/10ddf-fail-two-spares index fa6e2e8c..e00810d8 100644 --- a/tests/10ddf-fail-two-spares +++ b/tests/10ddf-fail-two-spares @@ -14,8 +14,8 @@ mdadm -CR $member0 -l raid6 -n 4 $dev10 $dev11 $dev12 $dev13 -z 16384 # >/tmp/mdmon.txt 2>&1 mdadm -CR $member1 -l raid10 -n 4 $dev10 $dev11 $dev12 $dev13 -z 16384 -dd if=$sda of=$member0 bs=1M -dd if=$sda of=$member1 bs=1M skip=16 +dd if=$sda of=$member0 bs=1M count=32 +dd if=$sda of=$member1 bs=1M skip=16 count=16 check wait @@ -27,8 +27,8 @@ sleep 1 mdadm --fail $member1 $dev12 # We will have 4 resync procedures, 2 spares for 2 arrays. -mdadm --wait $member1 $member0 -mdadm --wait $member1 $member0 +mdadm --wait $member1 $member0 || true +mdadm --wait $member1 $member0 || true devs0="$(get_raiddisks $member0)" devs1="$(get_raiddisks $member1)" diff --git a/tests/10ddf-incremental-wrong-order b/tests/10ddf-incremental-wrong-order index 2324f1d7..9ecf6bc2 100644 --- a/tests/10ddf-incremental-wrong-order +++ b/tests/10ddf-incremental-wrong-order @@ -14,11 +14,11 @@ ddf_check container 4 mdadm -CR $member1 -n 4 -l 10 $dev8 $dev10 $dev9 $dev11 -z 10000 mdadm -CR $member0 -n 2 -l 1 $dev8 $dev9 -z 10000 -mdadm --wait $member0 -mdadm --wait $member1 +mdadm --wait $member0 || true +mdadm --wait $member1 || true -mke2fs $member0 -mke2fs $member1 +mke2fs -F $member0 +mke2fs -F $member1 sha_0a=$(sha1_sum $member0) sha_1a=$(sha1_sum $member1) @@ -30,7 +30,7 @@ mdadm -I $dev10 mdadm -I $dev11 # Start runnable members ($member1) and write -mdadm -IRs +mdadm -IRs || true e2fsck -fy $member1 sha_1b=$(sha1_sum $member1) @@ -52,14 +52,14 @@ fi #[ -f /var/tmp/mdmon.log ] && cat /var/tmp/mdmon.log -# Now reassemble +# Now reassemble # Note that we add the previously missing disks first. # $dev10 should have a higher seq number than $dev8 for d in $dev8 $dev9 $dev10 $dev11; do - mdadm -I $d + mdadm -I $d done -mdadm -IRs +mdadm -IRs || true sha_0c=$(sha1_sum $member0) sha_1c=$(sha1_sum $member1) diff --git a/tests/10ddf-sudden-degraded b/tests/10ddf-sudden-degraded index 1eab361a..dc692aea 100644 --- a/tests/10ddf-sudden-degraded +++ b/tests/10ddf-sudden-degraded @@ -8,7 +8,7 @@ mdadm -CR $container -e ddf -n 2 $dev8 $dev9 ddf_check container 2 mdadm -CR $member1 -n 2 -l1 $dev8 $dev9 -mdadm --wait $member1 +mdadm --wait $member1 || true mdadm -Ss mdadm -I $dev8 diff --git a/tests/18imsm-1d-takeover-r0_1d b/tests/18imsm-1d-takeover-r0_1d index bf462e27..6f5cf5a6 100644 --- a/tests/18imsm-1d-takeover-r0_1d +++ b/tests/18imsm-1d-takeover-r0_1d @@ -8,12 +8,11 @@ vol0_comp_size=$((10 * 1024)) # Create container mdadm --create --run $container --auto=md --metadata=imsm --force --raid-disks=$vol0_num_comps $dev0 -wait +check wait imsm_check container $vol0_num_comps # Create RAID 0 volume mdadm --create --run $member0 --auto=md --level=0 --size=$vol0_comp_size --chunk=64 --force --raid-disks=$vol0_num_comps $dev0 -wait check wait # Test the member diff --git a/tests/18imsm-1d-takeover-r1_2d b/tests/18imsm-1d-takeover-r1_2d index fa02b6c3..72e4173e 100644 --- a/tests/18imsm-1d-takeover-r1_2d +++ b/tests/18imsm-1d-takeover-r1_2d @@ -8,12 +8,11 @@ vol0_comp_size=$((10 * 1024)) # Create container mdadm --create --run $container --auto=md --metadata=imsm --force --raid-disks=$vol0_num_comps $dev0 -wait +check wait imsm_check container $vol0_num_comps # Create RAID 1 volume mdadm --create --run $member0 --auto=md --level=1 --size=$vol0_comp_size --chunk=64 --raid-disks=$((vol0_num_comps + 1)) $dev0 missing -wait check wait # Test the member0 diff --git a/tests/18imsm-r1_2d-takeover-r0_1d b/tests/18imsm-r1_2d-takeover-r0_1d index 1697d60e..cb10ec97 100644 --- a/tests/18imsm-r1_2d-takeover-r0_1d +++ b/tests/18imsm-r1_2d-takeover-r0_1d @@ -10,7 +10,7 @@ device_list="$dev0 $dev1" vol0_level=1 vol0_comp_size=$((5 * 1024)) vol0_chunk=64 -vol0_num_comps=$(( $num_disks - 1 )) +vol0_num_comps=$(( $num_disks - 1 )) vol0_offset=0 # After: RAID 0 volume, 1 disks, 64k chunk size diff --git a/tests/19raid6auto-repair b/tests/19raid6auto-repair index 23b14e4b..7fb1c72f 100644 --- a/tests/19raid6auto-repair +++ b/tests/19raid6auto-repair @@ -39,5 +39,3 @@ cmp -s -n $array_data_size_in_b $md0 /tmp/RandFile || { echo cmp failed ; exit 2 mdadm -S $md0 udevadm settle -blockdev --flushbufs $md0 $devs; sync -echo 3 > /proc/sys/vm/drop_caches diff --git a/tests/19raid6check b/tests/19raid6check new file mode 100644 index 00000000..67958c6a --- /dev/null +++ b/tests/19raid6check @@ -0,0 +1,27 @@ +# +# Confirm that raid6check handles all RAID6 layouts. +# Try both 4 and 5 devices. + +layouts='ls rs la ra' +lv=`uname -r` +if expr $lv '>=' 2.6.30 > /dev/null +then + layouts="$layouts parity-first ddf-zero-restart ddf-N-restart ddf-N-continue \ + left-asymmetric-6 right-asymmetric-6 left-symmetric-6 right-symmetric-6 parity-first-6" +fi + +for layout in $layouts +do + for devs in 4 5 + do + dl="$dev0 $dev1 $dev2 $dev3" + if [ $devs = 5 ]; then dl="$dl $dev4"; fi + + mdadm -CR $md0 -l6 --layout $layout -n$devs $dl + check wait + tar cf - /etc > $md0 + ./raid6check $md0 0 0 | grep 'Error detected' && exit 1 + mdadm -S $md0 + done +done + diff --git a/tests/19raid6repair b/tests/19raid6repair index ecff2c3a..1159bd3e 100644 --- a/tests/19raid6repair +++ b/tests/19raid6repair @@ -42,6 +42,6 @@ for failure in "$dev3 3 3 2" "$dev3 3 2 3" "$dev3 3 2 1" "$dev3 3 2 0" "$dev4 3 mdadm -S $md0 udevadm settle - blockdev --flushbufs $md0 $devs; sync + sync echo 3 > /proc/sys/vm/drop_caches done diff --git a/tests/19repair-does-not-destroy b/tests/19repair-does-not-destroy index 1d3b9b45..a92883fd 100644 --- a/tests/19repair-does-not-destroy +++ b/tests/19repair-does-not-destroy @@ -26,4 +26,3 @@ cmp -s -n $array_data_size_in_b $md0 /tmp/RandFile || { echo should not mess up mdadm -S $md0 udevadm settle -blockdev --flushbufs $md0 $devs; sync diff --git a/tests/ToTest b/tests/ToTest index 31d70828..b98e266d 100644 --- a/tests/ToTest +++ b/tests/ToTest @@ -6,7 +6,7 @@ add/remove/fail raid5 DONE raid6/10 needed?? -assemble +assemble by devices DONE by uuid DONE by superminor DONE @@ -23,7 +23,7 @@ bitmap separate file internal filename in config file - + examine --scan --brief diff --git a/tests/imsm-grow-template b/tests/imsm-grow-template index 8022e3ad..71a0bbb1 100644 --- a/tests/imsm-grow-template +++ b/tests/imsm-grow-template @@ -33,17 +33,17 @@ function grow_member() { # Create container mdadm --create --run $container --auto=md --metadata=imsm --raid-disks=$num_disks $device_list -wait +check wait imsm_check container $num_disks # Create first volume inside the container mdadm --create --run $member0 --auto=md --level=$vol0_level --size=$vol0_comp_size --chunk=$vol0_chunk --raid-disks=$num_disks $device_list -wait +check wait # Create second volume inside the container (if defined) if [ ! -z $vol1_chunk ]; then mdadm --create --run $member1 --auto=md --level=$vol1_level --size=$vol1_comp_size --chunk=$vol1_chunk --raid-disks=$num_disks $device_list - wait + check wait fi # Wait for any RESYNC to complete @@ -63,7 +63,7 @@ fi for i in $spare_list do mdadm --add $container $i - wait + check wait num_disks=$((num_disks + 1)) done @@ -90,8 +90,10 @@ else exit 1 fi else + sleep 5 check wait sleep 5 + check wait imsm_check member $member0 $num_disks $vol0_level $vol0_comp_size $((vol0_comp_size * vol0_new_num_comps)) $vol0_offset $vol0_chunk testdev $member0 $vol0_new_num_comps $vol0_comp_size $vol0_chunk if [ $vol1_new_num_comps -ne 0 ]; then diff --git a/udev-md-raid-arrays.rules b/udev-md-raid-arrays.rules index a32b6d2d..c95ec7b1 100644 --- a/udev-md-raid-arrays.rules +++ b/udev-md-raid-arrays.rules @@ -17,7 +17,7 @@ TEST!="md/array_state", ENV{SYSTEMD_READY}="0", GOTO="md_end" ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0", GOTO="md_end" LABEL="md_ignore_state" -IMPORT{program}="BINDIR/mdadm --detail --export $tempnode" +IMPORT{program}="BINDIR/mdadm --detail --export $devnode" ENV{DEVTYPE}=="disk", ENV{MD_NAME}=="?*", SYMLINK+="disk/by-id/md-name-$env{MD_NAME}", OPTIONS+="string_escape=replace" ENV{DEVTYPE}=="disk", ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env{MD_UUID}" ENV{DEVTYPE}=="disk", ENV{MD_DEVNAME}=="?*", SYMLINK+="md/$env{MD_DEVNAME}" @@ -26,14 +26,16 @@ ENV{DEVTYPE}=="partition", ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[^0-9]", SYMLINK+="md/$env{MD_DEVNAME}%n" ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[0-9]", SYMLINK+="md/$env{MD_DEVNAME}p%n" -IMPORT{program}="/sbin/blkid -o udev -p -u noraid $tempnode" +IMPORT{builtin}="blkid" +OPTIONS+="link_priority=100" +OPTIONS+="watch" ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}" ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" ENV{MD_LEVEL}=="raid[1-9]*", ENV{SYSTEMD_WANTS}+="mdmonitor.service" # Tell systemd to run mdmon for our container, if we need it. -ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c" +ENV{MD_LEVEL}=="raid[1-9]*", ENV{MD_CONTAINER}=="?*", PROGRAM="/usr/bin/readlink $env{MD_CONTAINER}", ENV{MD_MON_THIS}="%c" ENV{MD_MON_THIS}=="?*", PROGRAM="/usr/bin/basename $env{MD_MON_THIS}", ENV{SYSTEMD_WANTS}+="mdmon@%c.service" LABEL="md_end" diff --git a/udev-md-raid-assembly.rules b/udev-md-raid-assembly.rules index 4d27d630..d0d440a6 100644 --- a/udev-md-raid-assembly.rules +++ b/udev-md-raid-assembly.rules @@ -27,7 +27,7 @@ LABEL="md_inc" # remember you can limit what gets auto/incrementally assembled by # mdadm.conf(5)'s 'AUTO' and selectively whitelist using 'ARRAY' -ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $tempnode --offroot ${DEVLINKS}" +ACTION=="add|change", IMPORT{program}="BINDIR/mdadm --incremental --export $devnode --offroot ${DEVLINKS}" ACTION=="add|change", ENV{MD_STARTED}=="*unsafe*", ENV{MD_FOREIGN}=="no", ENV{SYSTEMD_WANTS}+="mdadm-last-resort@$env{MD_DEVICE}.timer" ACTION=="remove", ENV{ID_PATH}=="?*", RUN+="BINDIR/mdadm -If $name --path $env{ID_PATH}" ACTION=="remove", ENV{ID_PATH}!="?*", RUN+="BINDIR/mdadm -If $name" diff --git a/util.c b/util.c index 37c6e0d3..cc98d3ba 100644 --- a/util.c +++ b/util.c @@ -368,6 +368,13 @@ int enough(int level, int raid_disks, int layout, int clean, char *avail) case 1: return avail_disks >= 1; case 4: + if (avail_disks == raid_disks - 1 && + !avail[raid_disks - 1]) + /* If just the parity device is missing, then we + * have enough, even if not clean + */ + return 1; + /* FALL THROUGH */ case 5: if (clean) return avail_disks >= raid_disks-1; @@ -671,13 +678,13 @@ char *human_size(long long bytes) if (bytes < 5000*1024) buf[0] = 0; else if (bytes < 2*1024LL*1024LL*1024LL) { - long cMiB = (bytes / ( (1LL<<20) / 200LL ) +1) /2; + long cMiB = (bytes * 200LL / (1LL<<20) + 1) / 2; long cMB = (bytes / ( 1000000LL / 200LL ) +1) /2; snprintf(buf, sizeof(buf), " (%ld.%02ld MiB %ld.%02ld MB)", cMiB/100 , cMiB % 100, cMB/100, cMB % 100); } else { - long cGiB = (bytes / ( (1LL<<30) / 200LL ) +1) /2; + long cGiB = (bytes * 200LL / (1LL<<30) +1) / 2; long cGB = (bytes / (1000000000LL/200LL ) +1) /2; snprintf(buf, sizeof(buf), " (%ld.%02ld GiB %ld.%02ld GB)", cGiB/100 , cGiB % 100, @@ -706,11 +713,11 @@ char *human_size_brief(long long bytes, int prefix) buf[0] = 0; else if (prefix == IEC) { if (bytes < 2*1024LL*1024LL*1024LL) { - long cMiB = (bytes / ( (1LL<<20) / 200LL ) +1) /2; + long cMiB = (bytes * 200LL / (1LL<<20) +1) /2; snprintf(buf, sizeof(buf), "%ld.%02ldMiB", cMiB/100 , cMiB % 100); } else { - long cGiB = (bytes / ( (1LL<<30) / 200LL ) +1) /2; + long cGiB = (bytes * 200LL / (1LL<<30) +1) /2; snprintf(buf, sizeof(buf), "%ld.%02ldGiB", cGiB/100 , cGiB % 100); } @@ -990,7 +997,7 @@ void wait_for(char *dev, int fd) delay *= 2; } if (i == 25) - dprintf("%s: timeout waiting for %s\n", __func__, dev); + dprintf("timeout waiting for %s\n", dev); } struct superswitch *superlist[] = @@ -1740,8 +1747,7 @@ int start_mdmon(char *devnm) status = execl("/bin/systemctl", "systemctl", "start", pathbuf, NULL); exit(1); - case -1: pr_err("cannot run mdmon. " - "Array remains readonly\n"); + case -1: pr_err("cannot run mdmon. Array remains readonly\n"); return -1; default: /* parent - good */ pid = wait(&status); @@ -1766,14 +1772,12 @@ int start_mdmon(char *devnm) devnm, NULL); } exit(1); - case -1: pr_err("cannot run mdmon. " - "Array remains readonly\n"); + case -1: pr_err("cannot run mdmon. Array remains readonly\n"); return -1; default: /* parent - good */ pid = wait(&status); if (pid < 0 || status != 0) { - pr_err("failed to launch mdmon. " - "Array remains readonly\n"); + pr_err("failed to launch mdmon. Array remains readonly\n"); return -1; } } @@ -1845,8 +1849,7 @@ int experimental(void) if (check_env("MDADM_EXPERIMENTAL")) return 1; else { - pr_err("To use this feature MDADM_EXPERIMENTAL" - " environment variable has to be defined.\n"); + pr_err("To use this feature MDADM_EXPERIMENTAL environment variable has to be defined.\n"); return 0; } } diff --git a/xmalloc.c b/xmalloc.c index 8d42a7c4..8b3f78a6 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -35,38 +35,50 @@ void *xmalloc(size_t len) { void *rv = malloc(len); char *msg; + int n; if (rv) return rv; - msg = Name ": memory allocation failure - aborting\n"; - exit(4+!!write(2, msg, strlen(msg))); + msg = ": memory allocation failure - aborting\n"; + n = write(2, Name, strlen(Name)); + n += write(2, msg, strlen(msg)); + exit(4+!!n); } void *xrealloc(void *ptr, size_t len) { void *rv = realloc(ptr, len); char *msg; + int n; if (rv) return rv; - msg = Name ": memory allocation failure - aborting\n"; - exit(4+!!write(2, msg, strlen(msg))); + msg = ": memory allocation failure - aborting\n"; + n = write(2, Name, strlen(Name)); + n += write(2, msg, strlen(msg)); + exit(4+!!n); } void *xcalloc(size_t num, size_t size) { void *rv = calloc(num, size); char *msg; + int n; if (rv) return rv; - msg = Name ": memory allocation failure - aborting\n"; - exit(4+!!write(2, msg, strlen(msg))); + msg = ": memory allocation failure - aborting\n"; + n = write(2, Name, strlen(Name)); + n += write(2, msg, strlen(msg)); + exit(4+!!n); } char *xstrdup(const char *str) { char *rv = strdup(str); char *msg; + int n; if (rv) return rv; - msg = Name ": memory allocation failure - aborting\n"; - exit(4+!!write(2, msg, strlen(msg))); + msg = ": memory allocation failure - aborting\n"; + n = write(2, Name, strlen(Name)); + n += write(2, msg, strlen(msg)); + exit(4+!!n); } -- cgit v1.2.3