1
0
Fork 0

Merging upstream version 4.3+20241202.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-14 06:37:23 +01:00
parent 1eb55d062a
commit 72807d3921
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
22 changed files with 325 additions and 402 deletions

18
.github/tools/run_mdadm_tests.sh vendored Executable file
View file

@ -0,0 +1,18 @@
#!/usr/bin/bash
sudo make clean
sudo make -j$(nproc)
sudo make install
sudo mdadm -Ss
sudo ./test setup
# Uncomment and adjust this to minimalize testing time for CI or test improvements.
# --tests=test1,test2,... Comma separated list of tests to run
#sudo ./test --tests=00createnames
sudo ./test --skip-broken --no-error --disable-integrity --disable-multipath --disable-linear --keep-going
ret=$?
sudo ./test cleanup
exit $ret

77
.github/workflows/tests.yml vendored Normal file
View file

@ -0,0 +1,77 @@
name: tests
on:
schedule:
- cron: "0 0 * * *"
pull_request:
paths:
- '*.c'
- '*.h'
- 'tests/*'
- 'test'
- '.github/*'
- '.github/workflows/*'
- '.github/tools/*'
jobs:
upstream_tests:
if: ${{ github.repository == 'md-raid-utilities/mdadm' }}
runs-on: self-hosted
timeout-minutes: 150
name: upstream tests
steps:
- uses: actions/checkout@v4
if: ${{ github.event_name == 'pull_request' }}
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- uses: actions/checkout@v4
if: ${{ github.event_name == 'schedule' }}
with:
ref: main
fetch-depth: 0
- name: 'Prepare machine'
run: |
cd ..
vagrant halt
vagrant status
vagrant up
- name: 'Run tests'
id: testing
continue-on-error: true
run: |
cd ..
vagrant ssh -c "cd /home/vagrant/host/mdadm && .github/tools/run_mdadm_tests.sh"
- name: 'Copy logs to host machine'
if: ${{ steps.testing.outcome == 'failure' }}
run: |
cd ..
vagrant ssh -c "sudo mkdir -p /home/vagrant/host/logs && sudo mv /var/tmp/*.log /home/vagrant/host/logs"
- name: "Save artifacts"
if: ${{ steps.testing.outcome == 'failure' }}
uses: actions/upload-artifact@v4
with:
name: "Logs from failed tests"
path: /home/ci/actions-runner/_work/mdadm/logs/*.log
- name: "Clean logs"
if: ${{ steps.testing.outcome == 'failure' }}
run: |
cd ..
sudo rm /home/ci/actions-runner/_work/mdadm/logs/*.log
- name: "Set failed"
if: ${{ steps.testing.outcome == 'failure' }}
run: exit 1
cleanup:
runs-on: self-hosted
needs: [upstream_tests]
steps:
- name: Restore clean VM
run: |
cd ..
vagrant up
vagrant ssh -c "sudo mdadm -Ss"
vagrant halt

View file

@ -633,7 +633,6 @@ static int load_devices(struct devs *devices, char *devmap,
struct mddev_dev *tmpdev; struct mddev_dev *tmpdev;
int devcnt = 0; int devcnt = 0;
int nextspare = 0; int nextspare = 0;
int bitmap_done = 0;
int most_recent = -1; int most_recent = -1;
int bestcnt = 0; int bestcnt = 0;
int *best = *bestp; int *best = *bestp;
@ -661,7 +660,7 @@ static int load_devices(struct devs *devices, char *devmap,
if (c->update == UOPT_UUID && !ident->uuid_set) if (c->update == UOPT_UUID && !ident->uuid_set)
random_uuid((__u8 *)ident->uuid); random_uuid((__u8 *)ident->uuid);
if (c->update == UOPT_PPL && ident->bitmap_fd >= 0) { if (c->update == UOPT_PPL && ident->btype != BitmapNone) {
pr_err("PPL is not compatible with bitmap\n"); pr_err("PPL is not compatible with bitmap\n");
close(mdfd); close(mdfd);
free(devices); free(devices);
@ -728,16 +727,6 @@ static int load_devices(struct devs *devices, char *devmap,
if (tst->ss->store_super(tst, dfd)) if (tst->ss->store_super(tst, dfd))
pr_err("Could not re-write superblock on %s.\n", pr_err("Could not re-write superblock on %s.\n",
devname); devname);
if (c->update == UOPT_UUID &&
ident->bitmap_fd >= 0 && !bitmap_done) {
if (bitmap_update_uuid(ident->bitmap_fd,
content->uuid,
tst->ss->swapuuid) != 0)
pr_err("Could not update uuid on external bitmap.\n");
else
bitmap_done = 1;
}
} else { } else {
dfd = dev_open(devname, dfd = dev_open(devname,
tmpdev->disposition == 'I' tmpdev->disposition == 'I'
@ -1057,26 +1046,6 @@ static int start_array(int mdfd,
mddev, strerror(errno)); mddev, strerror(errno));
return 1; return 1;
} }
if (ident->bitmap_fd >= 0) {
if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) {
pr_err("SET_BITMAP_FILE failed.\n");
return 1;
}
} else if (ident->bitmap_file) {
/* From config file */
int bmfd = open(ident->bitmap_file, O_RDWR);
if (bmfd < 0) {
pr_err("Could not open bitmap file %s\n",
ident->bitmap_file);
return 1;
}
if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
pr_err("Failed to set bitmapfile for %s\n", mddev);
close(bmfd);
return 1;
}
close(bmfd);
}
/* First, add the raid disks, but add the chosen one last */ /* First, add the raid disks, but add the chosen one last */
for (i = 0; i <= bestcnt; i++) { for (i = 0; i <= bestcnt; i++) {

35
Build.c
View file

@ -40,8 +40,6 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
dev_t rdev; dev_t rdev;
int subdevs = 0, missing_disks = 0; int subdevs = 0, missing_disks = 0;
struct mddev_dev *dv; struct mddev_dev *dv;
int bitmap_fd;
unsigned long long bitmapsize;
int mdfd; int mdfd;
char chosen_name[1024]; char chosen_name[1024];
int uuid[4] = {0,0,0,0}; int uuid[4] = {0,0,0,0};
@ -110,13 +108,6 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
goto abort; goto abort;
} }
if (s->bitmap_file && str_is_none(s->bitmap_file) == true)
s->bitmap_file = NULL;
if (s->bitmap_file && s->level <= 0) {
pr_err("bitmaps not meaningful with level %s\n",
map_num(pers, s->level)?:"given");
goto abort;
}
/* now add the devices */ /* now add the devices */
for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) { for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) {
mdu_disk_info_t disk; mdu_disk_info_t disk;
@ -150,31 +141,7 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
goto abort; goto abort;
} }
} }
/* now to start it */
if (s->bitmap_file) {
bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
int major = BITMAP_MAJOR_HI;
bitmapsize = s->size >> 9; /* FIXME wrong for RAID10 */
if (CreateBitmap(s->bitmap_file, 1, NULL,
s->bitmap_chunk, c->delay,
s->write_behind, bitmapsize, major)) {
goto abort;
}
bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
pr_err("%s cannot be opened.\n", s->bitmap_file);
goto abort;
}
}
if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
pr_err("Cannot set bitmap file for %s: %s\n", chosen_name,
strerror(errno));
close(bitmap_fd);
goto abort;
}
close(bitmap_fd);
}
if (ioctl(mdfd, RUN_ARRAY, &param)) { if (ioctl(mdfd, RUN_ARRAY, &param)) {
pr_err("RUN_ARRAY failed: %s\n", strerror(errno)); pr_err("RUN_ARRAY failed: %s\n", strerror(errno));
if (s->chunk & (s->chunk - 1)) { if (s->chunk & (s->chunk - 1)) {

View file

@ -521,7 +521,6 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
int insert_point = subdevs * 2; /* where to insert a missing drive */ int insert_point = subdevs * 2; /* where to insert a missing drive */
int total_slots; int total_slots;
int rv; int rv;
int bitmap_fd;
int have_container = 0; int have_container = 0;
int container_fd = -1; int container_fd = -1;
int need_mdmon = 0; int need_mdmon = 0;
@ -534,9 +533,9 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
struct map_ent *map = NULL; struct map_ent *map = NULL;
unsigned long long newsize; unsigned long long newsize;
mdu_array_info_t inf; mdu_array_info_t inf;
int major_num = BITMAP_MAJOR_HI; int major_num = BITMAP_MAJOR_HI;
if (s->bitmap_file && strcmp(s->bitmap_file, "clustered") == 0) {
if (s->btype == BitmapCluster) {
major_num = BITMAP_MAJOR_CLUSTERED; major_num = BITMAP_MAJOR_CLUSTERED;
if (c->nodes <= 1) { if (c->nodes <= 1) {
pr_err("At least 2 nodes are needed for cluster-md\n"); pr_err("At least 2 nodes are needed for cluster-md\n");
@ -618,7 +617,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
pr_err("You haven't given enough devices (real or missing) to create this array\n"); pr_err("You haven't given enough devices (real or missing) to create this array\n");
return 1; return 1;
} }
if (s->bitmap_file && s->level <= 0) { if (s->btype != BitmapNone && s->level <= 0) {
pr_err("bitmaps not meaningful with level %s\n", pr_err("bitmaps not meaningful with level %s\n",
map_num(pers, s->level)?:"given"); map_num(pers, s->level)?:"given");
return 1; return 1;
@ -949,21 +948,6 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
} }
} }
if (!s->bitmap_file &&
!st->ss->external &&
s->level >= 1 &&
st->ss->add_internal_bitmap &&
s->journaldisks == 0 &&
(s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
s->consistency_policy != CONSISTENCY_POLICY_PPL) &&
(s->write_behind || s->size > 100*1024*1024ULL)) {
if (c->verbose > 0)
pr_err("automatically enabling write-intent bitmap on large array\n");
s->bitmap_file = "internal";
}
if (s->bitmap_file && str_is_none(s->bitmap_file) == true)
s->bitmap_file = NULL;
if (s->consistency_policy == CONSISTENCY_POLICY_PPL && if (s->consistency_policy == CONSISTENCY_POLICY_PPL &&
!st->ss->write_init_ppl) { !st->ss->write_init_ppl) {
pr_err("%s metadata does not support PPL\n", st->ss->name); pr_err("%s metadata does not support PPL\n", st->ss->name);
@ -1198,8 +1182,7 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
* to stop another mdadm from finding and using those devices. * to stop another mdadm from finding and using those devices.
*/ */
if (s->bitmap_file && (strcmp(s->bitmap_file, "internal") == 0 || if (s->btype == BitmapInternal || s->btype == BitmapCluster) {
strcmp(s->bitmap_file, "clustered") == 0)) {
if (!st->ss->add_internal_bitmap) { if (!st->ss->add_internal_bitmap) {
pr_err("internal bitmaps not supported with %s metadata\n", pr_err("internal bitmaps not supported with %s metadata\n",
st->ss->name); st->ss->name);
@ -1211,7 +1194,6 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
pr_err("Given bitmap chunk size not supported.\n"); pr_err("Given bitmap chunk size not supported.\n");
goto abort_locked; goto abort_locked;
} }
s->bitmap_file = NULL;
} }
if (sysfs_init(&info, mdfd, NULL)) { if (sysfs_init(&info, mdfd, NULL)) {
@ -1253,28 +1235,6 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
goto abort_locked; goto abort_locked;
} }
if (s->bitmap_file) {
int uuid[4];
st->ss->uuid_from_super(st, uuid);
if (CreateBitmap(s->bitmap_file, c->force, (char*)uuid, s->bitmap_chunk,
c->delay, s->write_behind,
bitmapsize,
major_num)) {
goto abort_locked;
}
bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
pr_err("weird: %s cannot be opened\n",
s->bitmap_file);
goto abort_locked;
}
if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
pr_err("Cannot set bitmap file for %s: %s\n", chosen_name, strerror(errno));
goto abort_locked;
}
}
if (add_disks(mdfd, &info, s, c, st, &map, devlist, total_slots, if (add_disks(mdfd, &info, s, c, st, &map, devlist, total_slots,
have_container, insert_point, major_num, chosen_name)) have_container, insert_point, major_num, chosen_name))
goto abort_locked; goto abort_locked;

94
Grow.c
View file

@ -285,7 +285,6 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
* find all the active devices, and write the bitmap block * find all the active devices, and write the bitmap block
* to all devices * to all devices
*/ */
mdu_bitmap_file_t bmf;
mdu_array_info_t array; mdu_array_info_t array;
struct supertype *st; struct supertype *st;
char *subarray = NULL; char *subarray = NULL;
@ -294,40 +293,21 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
struct mdinfo *mdi; struct mdinfo *mdi;
/* /*
* We only ever get called if s->bitmap_file is != NULL, so this check * We only ever get called if bitmap is not none, so this check
* is just here to quiet down static code checkers. * is just here to quiet down static code checkers.
*/ */
if (!s->bitmap_file) if (s->btype == BitmapUnknown)
return 1; return 1;
if (strcmp(s->bitmap_file, "clustered") == 0) if (s->btype == BitmapCluster)
major = BITMAP_MAJOR_CLUSTERED; major = BITMAP_MAJOR_CLUSTERED;
if (ioctl(fd, GET_BITMAP_FILE, &bmf) != 0) {
if (errno == ENOMEM)
pr_err("Memory allocation failure.\n");
else
pr_err("bitmaps not supported by this kernel.\n");
return 1;
}
if (bmf.pathname[0]) {
if (str_is_none(s->bitmap_file) == true) {
if (ioctl(fd, SET_BITMAP_FILE, -1) != 0) {
pr_err("failed to remove bitmap %s\n",
bmf.pathname);
return 1;
}
return 0;
}
pr_err("%s already has a bitmap (%s)\n", devname, bmf.pathname);
return 1;
}
if (md_get_array_info(fd, &array) != 0) { if (md_get_array_info(fd, &array) != 0) {
pr_err("cannot get array status for %s\n", devname); pr_err("cannot get array status for %s\n", devname);
return 1; return 1;
} }
if (array.state & (1 << MD_SB_BITMAP_PRESENT)) { if (array.state & (1 << MD_SB_BITMAP_PRESENT)) {
if (str_is_none(s->bitmap_file) == true) { if (s->btype == BitmapNone) {
array.state &= ~(1 << MD_SB_BITMAP_PRESENT); array.state &= ~(1 << MD_SB_BITMAP_PRESENT);
if (md_set_array_info(fd, &array) != 0) { if (md_set_array_info(fd, &array) != 0) {
if (array.state & (1 << MD_SB_CLUSTERED)) if (array.state & (1 << MD_SB_CLUSTERED))
@ -342,10 +322,11 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
return 1; return 1;
} }
if (str_is_none(s->bitmap_file) == true) { if (s->btype == BitmapNone) {
pr_err("no bitmap found on %s\n", devname); pr_err("no bitmap found on %s\n", devname);
return 1; return 1;
} }
if (array.level <= 0) { if (array.level <= 0) {
pr_err("Bitmaps not meaningful with level %s\n", pr_err("Bitmaps not meaningful with level %s\n",
map_num(pers, array.level)?:"of this array"); map_num(pers, array.level)?:"of this array");
@ -371,7 +352,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
ncopies = (array.layout & 255) * ((array.layout >> 8) & 255); ncopies = (array.layout & 255) * ((array.layout >> 8) & 255);
bitmapsize = bitmapsize * array.raid_disks / ncopies; bitmapsize = bitmapsize * array.raid_disks / ncopies;
if (strcmp(s->bitmap_file, "clustered") == 0 && if (s->btype == BitmapCluster &&
!is_near_layout_10(array.layout)) { !is_near_layout_10(array.layout)) {
pr_err("only near layout is supported with clustered raid10\n"); pr_err("only near layout is supported with clustered raid10\n");
return 1; return 1;
@ -402,8 +383,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
free(mdi); free(mdi);
} }
if (strcmp(s->bitmap_file, "internal") == 0 || if (s->btype == BitmapInternal || s->btype == BitmapCluster) {
strcmp(s->bitmap_file, "clustered") == 0) {
int rv; int rv;
int d; int d;
int offset_setable = 0; int offset_setable = 0;
@ -432,7 +412,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
if (!dv) if (!dv)
continue; continue;
if ((disk.state & (1 << MD_DISK_WRITEMOSTLY)) && if ((disk.state & (1 << MD_DISK_WRITEMOSTLY)) &&
(strcmp(s->bitmap_file, "clustered") == 0)) { s->btype == BitmapCluster) {
pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname); pr_err("%s disks marked write-mostly are not supported with clustered bitmap\n",devname);
free(mdi); free(mdi);
return 1; return 1;
@ -471,7 +451,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
mdi->bitmap_offset); mdi->bitmap_offset);
free(mdi); free(mdi);
} else { } else {
if (strcmp(s->bitmap_file, "clustered") == 0) if (s->btype == BitmapCluster)
array.state |= (1 << MD_SB_CLUSTERED); array.state |= (1 << MD_SB_CLUSTERED);
array.state |= (1 << MD_SB_BITMAP_PRESENT); array.state |= (1 << MD_SB_BITMAP_PRESENT);
rv = md_set_array_info(fd, &array); rv = md_set_array_info(fd, &array);
@ -482,60 +462,6 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
pr_err("failed to set internal bitmap.\n"); pr_err("failed to set internal bitmap.\n");
return 1; return 1;
} }
} else {
int uuid[4];
int bitmap_fd;
int d;
int max_devs = st->max_devs;
/* try to load a superblock */
for (d = 0; d < max_devs; d++) {
mdu_disk_info_t disk;
char *dv;
int fd2;
disk.number = d;
if (md_get_disk_info(fd, &disk) < 0)
continue;
if ((disk.major==0 && disk.minor == 0) ||
(disk.state & (1 << MD_DISK_REMOVED)))
continue;
dv = map_dev(disk.major, disk.minor, 1);
if (!dv)
continue;
fd2 = dev_open(dv, O_RDONLY);
if (fd2 >= 0) {
if (st->ss->load_super(st, fd2, NULL) == 0) {
close(fd2);
st->ss->uuid_from_super(st, uuid);
break;
}
close(fd2);
}
}
if (d == max_devs) {
pr_err("cannot find UUID for array!\n");
return 1;
}
if (CreateBitmap(s->bitmap_file, c->force, (char*)uuid,
s->bitmap_chunk, c->delay, s->write_behind,
bitmapsize, major)) {
return 1;
}
bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) {
pr_err("weird: %s cannot be opened\n", s->bitmap_file);
return 1;
}
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 set bitmap file for %s: %s\n",
devname, strerror(err));
close_fd(&bitmap_fd);
return 1;
}
close_fd(&bitmap_fd);
} }
return 0; return 0;

View file

@ -544,21 +544,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
cont_err("by --incremental. Please use --assemble\n"); cont_err("by --incremental. Please use --assemble\n");
goto out; goto out;
} }
if (match && match->bitmap_file) {
int bmfd = open(match->bitmap_file, O_RDWR);
if (bmfd < 0) {
pr_err("Could not open bitmap file %s.\n",
match->bitmap_file);
goto out;
}
if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
close(bmfd);
pr_err("Failed to set bitmapfile for %s.\n",
chosen_name);
goto out;
}
close(bmfd);
}
/* Need to remove from the array any devices which /* Need to remove from the array any devices which
* 'count_active' discerned were too old or inappropriate * 'count_active' discerned were too old or inappropriate
*/ */
@ -1400,28 +1386,7 @@ restart:
if (mddev->devname && me->path && if (mddev->devname && me->path &&
devname_matches(mddev->devname, me->path)) devname_matches(mddev->devname, me->path))
break; break;
if (mddev && mddev->bitmap_file) {
/*
* Note: early kernels will wrongly fail this, so it
* is a hint only
*/
int added = -1;
int bmfd;
bmfd = open(mddev->bitmap_file, O_RDWR);
if (is_fd_valid(bmfd)) {
added = ioctl(mdfd, SET_BITMAP_FILE, bmfd);
close_fd(&bmfd);
}
if (c->verbose >= 0) {
if (added == 0)
pr_err("Added bitmap %s to %s\n",
mddev->bitmap_file, me->path);
else if (errno != EEXIST)
pr_err("Failed to add bitmap to %s: %s\n",
me->path, strerror(errno));
}
}
/* FIXME check for reshape_active and consider not /* FIXME check for reshape_active and consider not
* starting array. * starting array.
*/ */

View file

@ -1448,6 +1448,18 @@ int Manage_subdevs(char *devname, int fd,
int rv, err = 0; int rv, err = 0;
int mj, mn; int mj, mn;
if (tst->ss->external && dv->disposition == 'A') {
pr_err("Cannot re-add member device %s to %s, it is not supported for external metadata, aborting.\n",
dv->devname, fd2devnm(fd));
goto abort;
}
if (array.not_persistent == 1 && dv->disposition == 'A') {
pr_err("Cannot re-add member device %s to %s, array is not persistent, aborting.\n",
dv->devname, fd2devnm(fd));
goto abort;
}
raid_slot = -1; raid_slot = -1;
if (dv->disposition == 'c') { if (dv->disposition == 'c') {
rv = parse_cluster_confirm_arg(dv->devname, &dv->devname, &raid_slot); rv = parse_cluster_confirm_arg(dv->devname, &dv->devname, &raid_slot);

View file

@ -51,14 +51,14 @@ Generally, if you are not sure it is better to ask on
# How to Contribute # How to Contribute
Effective immediately [Github](https://github.com/md-raid-utilities/mdadm) is the primary Effective immediately [Github](https://github.com/md-raid-utilities/mdadm) is the primary
location for **mdadm**. Use pull request to contribute. location for **mdadm**. Please use pull requests to contribute.
It was originally hosted on [kernel.org](https://kernel.org/). You can access the old repository It was originally hosted on [kernel.org](https://kernel.org/). You can access the old repository
[here](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git). [here](https://git.kernel.org/pub/scm/utils/mdadm/mdadm.git).
Patches sent through Mailing list are accepted but Github is preferred. Sent then to ML only While this is the preferred contribution method, mailing list submissions are still welcome and
if you cannot use Github. Please add "mdadm:" to the subject to allow automation to create Github will be handled as has always been the case for mdadm. Please add "mdadm:" to the subject to allow
Pull Request and run checks. automation to create Github Pull Request and run checks.
**NOTE:** Maintainers may ask you to send RFC to mailing list if the proposed code requires **NOTE:** Maintainers may ask you to send RFC to mailing list if the proposed code requires
consultation with kernel developers. consultation with kernel developers.

View file

@ -200,28 +200,32 @@ bitmap_file_open(char *filename, struct supertype **stp, int node_num, int fd)
close(fd); close(fd);
return -1; return -1;
} }
if ((stb.st_mode & S_IFMT) == S_IFBLK) {
/* block device, so we are probably after an internal bitmap */ if ((stb.st_mode & S_IFMT) != S_IFBLK) {
if (!st) pr_err("bitmap file is not supported %s\n", filename);
st = guess_super(fd); close(fd);
if (!st) { return -1;
/* just look at device... */
lseek(fd, 0, 0);
} else if (!st->ss->locate_bitmap) {
pr_err("No bitmap possible with %s metadata\n",
st->ss->name);
close(fd);
return -1;
} else {
if (st->ss->locate_bitmap(st, fd, node_num)) {
pr_err("%s doesn't have bitmap\n", filename);
close(fd);
fd = -1;
}
}
*stp = st;
} }
if (!st)
st = guess_super(fd);
if (!st) {
/* just look at device... */
lseek(fd, 0, 0);
} else if (!st->ss->locate_bitmap) {
pr_err("No bitmap possible with %s metadata\n", st->ss->name);
close(fd);
return -1;
}
if (st->ss->locate_bitmap(st, fd, node_num)) {
pr_err("%s doesn't have bitmap\n", filename);
close(fd);
fd = -1;
}
*stp = st;
return fd; return fd;
} }

View file

@ -171,8 +171,7 @@ inline void ident_init(struct mddev_ident *ident)
assert(ident); assert(ident);
ident->assembled = false; ident->assembled = false;
ident->bitmap_fd = -1; ident->btype = BitmapUnknown;
ident->bitmap_file = NULL;
ident->container = NULL; ident->container = NULL;
ident->devices = NULL; ident->devices = NULL;
ident->devname = NULL; ident->devname = NULL;
@ -542,11 +541,19 @@ void arrayline(char *line)
/* Ignore name in confile */ /* Ignore name in confile */
continue; continue;
} else if (strncasecmp(w, "bitmap=", 7) == 0) { } else if (strncasecmp(w, "bitmap=", 7) == 0) {
if (mis.bitmap_file) if (mis.btype != BitmapUnknown)
pr_err("only specify bitmap file once. %s ignored\n", pr_err("only specify bitmap file once. %s ignored\n",
w); w);
else else {
mis.bitmap_file = xstrdup(w + 7); char *bname = xstrdup(w + 7);
if (strcmp(bname, STR_COMMON_NONE) == 0)
mis.btype = BitmapNone;
else if (strcmp(bname, "internal") == 0)
mis.btype = BitmapInternal;
else if (strcmp(bname, "clustered") == 0)
mis.btype = BitmapCluster;
}
} else if (strncasecmp(w, "devices=", 8 ) == 0) { } else if (strncasecmp(w, "devices=", 8 ) == 0) {
if (mis.devices) if (mis.devices)

87
mdadm.c
View file

@ -41,18 +41,23 @@
*/ */
static mdadm_status_t set_bitmap_value(struct shape *s, struct context *c, char *val) static mdadm_status_t set_bitmap_value(struct shape *s, struct context *c, char *val)
{ {
if (s->bitmap_file) { if (s->btype != BitmapUnknown) {
pr_err("--bitmap cannot be set twice. Second value: \"%s\".\n", val); pr_err("--bitmap cannot be set twice. Second value: \"%s\".\n", val);
return MDADM_STATUS_ERROR; return MDADM_STATUS_ERROR;
} }
if (strcmp(val, "internal") == 0 || strcmp(optarg, STR_COMMON_NONE) == 0) { if (strcmp(optarg, STR_COMMON_NONE) == 0) {
s->bitmap_file = val; s->btype = BitmapNone;
return MDADM_STATUS_SUCCESS;
}
if (strcmp(val, "internal") == 0) {
s->btype = BitmapInternal;
return MDADM_STATUS_SUCCESS; return MDADM_STATUS_SUCCESS;
} }
if (strcmp(val, "clustered") == 0) { if (strcmp(val, "clustered") == 0) {
s->bitmap_file = val; s->btype = BitmapCluster;
/* Set the default number of cluster nodes /* Set the default number of cluster nodes
* to 4 if not already set by user * to 4 if not already set by user
*/ */
@ -62,17 +67,12 @@ static mdadm_status_t set_bitmap_value(struct shape *s, struct context *c, char
} }
if (strchr(val, '/')) { if (strchr(val, '/')) {
pr_info("Custom write-intent bitmap file option is deprecated.\n"); pr_err("Custom write-intent bitmap file option is not supported.\n");
if (ask("Do you want to continue? (y/n)")) {
s->bitmap_file = val;
return MDADM_STATUS_SUCCESS;
}
return MDADM_STATUS_ERROR; return MDADM_STATUS_ERROR;
} }
pr_err("--bitmap value must contain a '/' or be 'internal', 'clustered' or 'none'\n"); pr_err("--bitmap value must be 'internal', 'clustered' or 'none'\n");
pr_err("Current value is \"%s\"", val); pr_err("Current value is \"%s\"\n", val);
return MDADM_STATUS_ERROR; return MDADM_STATUS_ERROR;
} }
@ -99,7 +99,6 @@ int main(int argc, char *argv[])
struct mddev_ident ident; struct mddev_ident ident;
char *configfile = NULL; char *configfile = NULL;
int devmode = 0; int devmode = 0;
int bitmap_fd = -1;
struct mddev_dev *devlist = NULL; struct mddev_dev *devlist = NULL;
struct mddev_dev **devlistend = & devlist; struct mddev_dev **devlistend = & devlist;
struct mddev_dev *dv; struct mddev_dev *dv;
@ -116,6 +115,7 @@ int main(int argc, char *argv[])
.bitmap_chunk = UnSet, .bitmap_chunk = UnSet,
.consistency_policy = CONSISTENCY_POLICY_UNKNOWN, .consistency_policy = CONSISTENCY_POLICY_UNKNOWN,
.data_offset = INVALID_SECTORS, .data_offset = INVALID_SECTORS,
.btype = BitmapUnknown,
}; };
char sys_hostname[256]; char sys_hostname[256];
@ -1089,24 +1089,15 @@ int main(int argc, char *argv[])
case O(ASSEMBLE,'b'): /* here we simply set the bitmap file */ case O(ASSEMBLE,'b'): /* here we simply set the bitmap file */
case O(ASSEMBLE,Bitmap): case O(ASSEMBLE,Bitmap):
if (!optarg) { if (optarg && (strcmp(optarg, "internal") == 0 ||
pr_err("bitmap file needed with -b in --assemble mode\n"); strcmp(optarg, "clustered")) == 0) {
exit(2);
}
if (strcmp(optarg, "internal") == 0 ||
strcmp(optarg, "clustered") == 0) {
pr_err("no need to specify --bitmap when assembling" pr_err("no need to specify --bitmap when assembling"
" arrays with internal or clustered bitmap\n"); " arrays with internal or clustered bitmap\n");
continue; continue;
} }
bitmap_fd = open(optarg, O_RDWR);
if (!*optarg || bitmap_fd < 0) {
pr_err("cannot open bitmap file %s: %s\n", optarg, strerror(errno));
exit(2);
}
ident.bitmap_fd = bitmap_fd; /* for Assemble */
continue;
pr_err("bitmap file is not supported %s\n", optarg);
exit(2);
case O(ASSEMBLE, BackupFile): case O(ASSEMBLE, BackupFile):
case O(GROW, BackupFile): case O(GROW, BackupFile):
/* Specify a file into which grow might place a backup, /* Specify a file into which grow might place a backup,
@ -1256,12 +1247,11 @@ int main(int argc, char *argv[])
pr_err("PPL consistency policy is only supported for RAID level 5.\n"); pr_err("PPL consistency policy is only supported for RAID level 5.\n");
exit(2); exit(2);
} else if (s.consistency_policy == CONSISTENCY_POLICY_BITMAP && } else if (s.consistency_policy == CONSISTENCY_POLICY_BITMAP &&
(!s.bitmap_file || str_is_none(s.bitmap_file) == true)) { s.btype == BitmapNone) {
pr_err("--bitmap is required for consistency policy: %s\n", pr_err("--bitmap is required for consistency policy: %s\n",
map_num_s(consistency_policies, s.consistency_policy)); map_num_s(consistency_policies, s.consistency_policy));
exit(2); exit(2);
} else if (s.bitmap_file && } else if ((s.btype == BitmapInternal || s.btype == BitmapCluster) &&
str_is_none(s.bitmap_file) == false &&
s.consistency_policy != CONSISTENCY_POLICY_BITMAP && s.consistency_policy != CONSISTENCY_POLICY_BITMAP &&
s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) { s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
pr_err("--bitmap is not compatible with consistency policy: %s\n", pr_err("--bitmap is not compatible with consistency policy: %s\n",
@ -1394,7 +1384,7 @@ int main(int argc, char *argv[])
c.brief = 1; c.brief = 1;
if (mode == CREATE) { if (mode == CREATE) {
if (s.bitmap_file && strcmp(s.bitmap_file, "clustered") == 0) { if (s.btype == BitmapCluster) {
locked = cluster_get_dlmlock(); locked = cluster_get_dlmlock();
if (locked != 1) if (locked != 1)
exit(1); exit(1);
@ -1479,7 +1469,17 @@ int main(int argc, char *argv[])
case BUILD: case BUILD:
if (c.delay == 0) if (c.delay == 0)
c.delay = DEFAULT_BITMAP_DELAY; c.delay = DEFAULT_BITMAP_DELAY;
if (s.write_behind && !s.bitmap_file) {
if (s.btype == BitmapUnknown)
s.btype = BitmapNone;
if (s.btype != BitmapNone) {
pr_err("--build argument only compatible with --bitmap=none\n");
rv |= 1;
break;
}
if (s.write_behind) {
pr_err("write-behind mode requires a bitmap.\n"); pr_err("write-behind mode requires a bitmap.\n");
rv = 1; rv = 1;
break; break;
@ -1490,14 +1490,6 @@ int main(int argc, char *argv[])
break; break;
} }
if (s.bitmap_file) {
if (strcmp(s.bitmap_file, "internal") == 0 ||
strcmp(s.bitmap_file, "clustered") == 0) {
pr_err("'internal' and 'clustered' bitmaps not supported with --build\n");
rv |= 1;
break;
}
}
rv = Build(&ident, devlist->next, &s, &c); rv = Build(&ident, devlist->next, &s, &c);
break; break;
case CREATE: case CREATE:
@ -1505,8 +1497,7 @@ int main(int argc, char *argv[])
c.delay = DEFAULT_BITMAP_DELAY; c.delay = DEFAULT_BITMAP_DELAY;
if (c.nodes) { if (c.nodes) {
if (!s.bitmap_file || if (s.btype != BitmapCluster) {
strcmp(s.bitmap_file, "clustered") != 0) {
pr_err("--nodes argument only compatible with --bitmap=clustered\n"); pr_err("--nodes argument only compatible with --bitmap=clustered\n");
rv = 1; rv = 1;
break; break;
@ -1524,7 +1515,7 @@ int main(int argc, char *argv[])
} }
} }
if (s.write_behind && !s.bitmap_file) { if (s.write_behind && s.btype == BitmapNone) {
pr_err("write-behind mode requires a bitmap.\n"); pr_err("write-behind mode requires a bitmap.\n");
rv = 1; rv = 1;
break; break;
@ -1535,6 +1526,14 @@ int main(int argc, char *argv[])
break; break;
} }
if (s.btype == BitmapUnknown) {
if (c.runstop != 1 && s.level >= 1 &&
ask("To optimalize recovery speed, it is recommended to enable write-indent bitmap, do you want to enable it now?"))
s.btype = BitmapInternal;
else
s.btype = BitmapNone;
}
rv = Create(ss, &ident, devs_found - 1, devlist->next, &s, &c); rv = Create(ss, &ident, devs_found - 1, devlist->next, &s, &c);
break; break;
case MISC: case MISC:
@ -1626,7 +1625,7 @@ int main(int argc, char *argv[])
if (devs_found > 1 && s.raiddisks == 0 && s.level == UnSet) { if (devs_found > 1 && s.raiddisks == 0 && s.level == UnSet) {
/* must be '-a'. */ /* must be '-a'. */
if (s.size > 0 || s.chunk || if (s.size > 0 || s.chunk ||
s.layout_str || s.bitmap_file) { s.layout_str || s.btype != BitmapNone) {
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; rv = 1;
break; break;
@ -1636,7 +1635,7 @@ int main(int argc, char *argv[])
if (rv) if (rv)
break; break;
} }
} else if (s.bitmap_file) { } else if (s.btype != BitmapUnknown) {
if (s.size > 0 || s.raiddisks || s.chunk || if (s.size > 0 || s.raiddisks || s.chunk ||
s.layout_str || devs_found > 1) { s.layout_str || 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");

32
mdadm.h
View file

@ -598,9 +598,16 @@ enum prefix_standard {
}; };
enum bitmap_update { enum bitmap_update {
NoUpdate, NoUpdate,
NameUpdate, NameUpdate,
NodeNumUpdate, NodeNumUpdate,
};
enum bitmap_type {
BitmapNone,
BitmapInternal,
BitmapCluster,
BitmapUnknown,
}; };
enum flag_mode { enum flag_mode {
@ -640,8 +647,7 @@ struct mddev_ident {
int spare_disks; int spare_disks;
struct supertype *st; struct supertype *st;
char *spare_group; char *spare_group;
char *bitmap_file; enum bitmap_type btype;
int bitmap_fd;
char *container; /* /dev/whatever name of container, or char *container; /* /dev/whatever name of container, or
* uuid of container. You would expect * uuid of container. You would expect
@ -693,7 +699,7 @@ struct shape {
char *layout_str; char *layout_str;
int chunk; int chunk;
int bitmap_chunk; int bitmap_chunk;
char *bitmap_file; enum bitmap_type btype;
int assume_clean; int assume_clean;
bool write_zeroes; bool write_zeroes;
int write_behind; int write_behind;
@ -1899,15 +1905,23 @@ static inline sighandler_t signal_s(int sig, sighandler_t handler)
} }
#ifdef DEBUG #ifdef DEBUG
#include <time.h>
#define dprintf(fmt, arg...) \ #define dprintf(fmt, arg...) \
fprintf(stderr, "%s: %s: "fmt, Name, __func__, ##arg) do { \
struct timespec ts; \
clock_gettime(CLOCK_MONOTONIC, &ts); \
double timestamp = ts.tv_sec + ts.tv_nsec / 1e9; \
fprintf(stderr, "[%10.5f] %s: %s: " fmt, timestamp, Name, __func__, ##arg); \
} while (0)
#define dprintf_cont(fmt, arg...) \ #define dprintf_cont(fmt, arg...) \
fprintf(stderr, fmt, ##arg) fprintf(stderr, fmt, ##arg)
#else #else
#define dprintf(fmt, arg...) \ #define dprintf(fmt, arg...) \
({ if (0) fprintf(stderr, "%s: %s: " fmt, Name, __func__, ##arg); 0; }) do { } while (0)
#define dprintf_cont(fmt, arg...) \ #define dprintf_cont(fmt, arg...) \
({ if (0) fprintf(stderr, fmt, ##arg); 0; }) do { } while (0)
#endif #endif
static inline int xasprintf(char **strp, const char *fmt, ...) { static inline int xasprintf(char **strp, const char *fmt, ...) {

View file

@ -406,7 +406,6 @@ static int read_and_act(struct active_array *a)
struct mdinfo *mdi; struct mdinfo *mdi;
int ret = 0; int ret = 0;
int count = 0; int count = 0;
struct timeval tv;
bool write_checkpoint = false; bool write_checkpoint = false;
a->next_state = bad_word; a->next_state = bad_word;
@ -453,10 +452,8 @@ static int read_and_act(struct active_array *a)
check_for_cleared_bb(a, mdi); check_for_cleared_bb(a, mdi);
} }
gettimeofday(&tv, NULL); dprintf("(%d): state:%s prev:%s action:%s prev: %s start:%llu\n",
dprintf("(%d): %ld.%06ld state:%s prev:%s action:%s prev: %s start:%llu\n",
a->info.container_member, a->info.container_member,
tv.tv_sec, tv.tv_usec,
array_states[a->curr_state], array_states[a->curr_state],
array_states[a->prev_state], array_states[a->prev_state],
sync_actions[a->curr_action], sync_actions[a->curr_action],

View file

@ -5092,7 +5092,6 @@ imsm_thunderdome(struct intel_super **super_list, int len)
for (i = 0; i < tbl_size; i++) { for (i = 0; i < tbl_size; i++) {
struct imsm_disk *d; struct imsm_disk *d;
struct intel_disk *idisk; struct intel_disk *idisk;
struct imsm_super *mpb = super_table[i]->anchor;
s = super_table[i]; s = super_table[i];
d = &s->disks->disk; d = &s->disks->disk;
@ -5108,7 +5107,7 @@ imsm_thunderdome(struct intel_super **super_list, int len)
if (!s) if (!s)
dprintf("marking family: %#x from %d:%d offline\n", dprintf("marking family: %#x from %d:%d offline\n",
mpb->family_num, super_table[i]->anchor->family_num,
super_table[i]->disks->major, super_table[i]->disks->major,
super_table[i]->disks->minor); super_table[i]->disks->minor);
super_table[i] = s; super_table[i] = s;
@ -6122,7 +6121,8 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
pr_err("%s controller supports Multi-Path I/O, Intel (R) VROC does not support multipathing\n", pr_err("%s controller supports Multi-Path I/O, Intel (R) VROC does not support multipathing\n",
basename(cntrl_path)); basename(cntrl_path));
if (super->orom && !imsm_orom_has_tpv_support(super->orom)) { if (super->orom && devpath_to_vendor(pci_dev_path) != 0x8086 &&
!imsm_orom_has_tpv_support(super->orom)) {
pr_err("\tPlatform configuration does not support non-Intel NVMe drives.\n" pr_err("\tPlatform configuration does not support non-Intel NVMe drives.\n"
"\tPlease refer to Intel(R) RSTe/VROC user guide.\n"); "\tPlease refer to Intel(R) RSTe/VROC user guide.\n");
goto error; goto error;
@ -7056,7 +7056,8 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
int fd = -1; int fd = -1;
while (dev && !is_fd_valid(fd)) { while (dev && !is_fd_valid(fd)) {
char *path = xmalloc(strlen(dev->name) + strlen("/dev/") + 1); char path[PATH_MAX];
num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name); num = snprintf(path, PATH_MAX, "%s%s", "/dev/", dev->name);
if (num > 0) if (num > 0)
fd = open(path, O_RDONLY, 0); fd = open(path, O_RDONLY, 0);
@ -7064,7 +7065,6 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
pr_vrb("Cannot open %s: %s\n", pr_vrb("Cannot open %s: %s\n",
dev->name, strerror(errno)); dev->name, strerror(errno));
} }
free(path);
dev = dev->next; dev = dev->next;
} }
found = 0; found = 0;

33
test
View file

@ -95,11 +95,22 @@ mdadm() {
return $rv return $rv
} }
print_time_elapsed() {
local start_sec=$1
local end_sec=$(date +%s)
local execution_time=$((end_sec - start_sec))
echo -ne "Execution time (seconds): ${execution_time} "
}
do_test() { do_test() {
_script=$1 _script=$1
_basename=`basename $_script` _basename=`basename $_script`
_broken=0 _broken=0
local start_sec=$(date +%s)
if [ -f "$_script" ] if [ -f "$_script" ]
then then
if [ -f "${_script}.broken" ]; then if [ -f "${_script}.broken" ]; then
@ -121,6 +132,7 @@ do_test() {
echo -ne "$_script... " echo -ne "$_script... "
if ( set -ex ; . $_script ) &> $targetdir/log if ( set -ex ; . $_script ) &> $targetdir/log
then then
print_time_elapsed $start_sec
if [ -f "${_script}.inject_error" ]; then if [ -f "${_script}.inject_error" ]; then
echo "dmesg checking is skipped because test inject error" echo "dmesg checking is skipped because test inject error"
else else
@ -130,6 +142,7 @@ do_test() {
succeed "succeeded\n" succeed "succeeded\n"
_fail=0 _fail=0
else else
print_time_elapsed $start_sec
save_log fail save_log fail
_fail=1 _fail=1
if [ "$_broken" == "1" ]; then if [ "$_broken" == "1" ]; then
@ -137,11 +150,14 @@ do_test() {
fi fi
fi fi
restore_system_speed_limit restore_system_speed_limit
[ "$savelogs" == "1" ] &&
mv -f $targetdir/log $logdir/$_basename.log [ "$savelogs" == "1" ] && mv -f $targetdir/log $logdir/$_basename.log
[ "$ctrl_c_error" == "1" ] && exit 1 [ "$ctrl_c_error" == "1" ] && exit 1
[ "$_fail" == "1" -a "$exitonerror" == "1" \
-a "$_broken" == "0" ] && exit 1 [ "$_fail" == "1" -a "$exitonerror" == "1" -a "$_broken" == "0" ] && exit 1
[ "$_fail" == "1" ] && do_test_ret=1
fi fi
} }
@ -327,6 +343,8 @@ main() {
[ "$savelogs" == "1" ] && [ "$savelogs" == "1" ] &&
echo "Saving logs to $logdir" echo "Saving logs to $logdir"
do_test_ret=0
while true; do while true; do
if [ "x$TESTLIST" != "x" ] if [ "x$TESTLIST" != "x" ]
then then
@ -337,11 +355,10 @@ main() {
else else
for script in $testdir/$prefix $testdir/$prefix*[^~] for script in $testdir/$prefix $testdir/$prefix*[^~]
do do
case $script in case $script in *.broken) ;;
*.broken) ;;
*) *)
do_test $script do_test $script
esac esac
done done
fi fi
@ -352,7 +369,7 @@ main() {
done done
restore_selinux restore_selinux
exit 0 exit $do_test_ret
} }
parse_args $@ parse_args $@

View file

@ -22,40 +22,6 @@ mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
} }
mdadm -S /dev/md0 mdadm -S /dev/md0
# now if we have a bitmap, that needs updating too.
rm -f $targetdir/bitmap
yes | mdadm -CR --assume-clean -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2
mdadm -S /dev/md0
mdadm -A /dev/md0 -b $targetdir/bitmap --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
no_errors
mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
echo Wrong uuid; mdadm -D /dev/md0 ; exit 2;
}
if mdadm -X $targetdir/bitmap | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 ||
mdadm -X $targetdir/bitmap | grep -s > /dev/null 67452301:efcdab89:98badcfe:10325476
then : ; else
echo Wrong uuid; mdadm -X $targetdir/bitmap ; exit 2;
fi
mdadm -S /dev/md0
# and bitmap for version1
rm -f $targetdir/bitmap
yes | mdadm -CR --assume-clean -e1.1 -b $targetdir/bitmap $md0 -l5 -n3 $dev0 $dev1 $dev2
mdadm -S /dev/md0
mdadm -A /dev/md0 -b $targetdir/bitmap --update=uuid --uuid=0123456789abcdef:fedcba9876543210 $dev0 $dev1 $dev2
no_errors
mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
echo Wrong uuid; mdadm -D /dev/md0 ; exit 2;
}
# -X cannot tell which byteorder to use for the UUID, so allow both.
if mdadm -X $targetdir/bitmap | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 ||
mdadm -X $targetdir/bitmap | grep -s > /dev/null 67452301:efcdab89:98badcfe:10325476
then : ; else
echo Wrong uuid; mdadm -X $targetdir/bitmap ; exit 2;
fi
mdadm -S /dev/md0
# Internal bitmaps too. # Internal bitmaps too.
mdadm -CR --assume-clean -b internal --bitmap-chunk 4 $md0 -l5 -n3 $dev0 $dev1 $dev2 mdadm -CR --assume-clean -b internal --bitmap-chunk 4 $md0 -l5 -n3 $dev0 $dev1 $dev2
mdadm -S /dev/md0 mdadm -S /dev/md0

View file

@ -1,12 +1,8 @@
# #
# create a raid1, remove a drive, and readd it. # create a raid1 without superblock, remove a drive, and readd it.
# resync should be instant. # readd should fail.
# Then do some IO first. Resync should still be very fast
# #
bmf=$targetdir/bitmap2 mdadm -B $md0 -l1 -n2 -d1 $dev1 $dev2
rm -f $bmf
yes | mdadm -B $md0 -l1 -n2 -b$bmf -d1 $dev1 $dev2
check resync check resync
check wait check wait
testdev $md0 1 $size 1 testdev $md0 1 $size 1
@ -15,24 +11,8 @@ sleep 4
mdadm $md0 -f $dev2 mdadm $md0 -f $dev2
sleep 1 sleep 1
mdadm $md0 -r $dev2 mdadm $md0 -r $dev2
mdadm $md0 --re-add $dev2 if mdadm $md0 --re-add $dev2; then
check nosync err "re-add should fail"
fi
mdadm $md0 -f $dev2
sleep 1
mdadm $md0 -r $dev2
testdev $md0 1 $size 1
mdadm $md0 --re-add $dev2
check wait
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
# should BLKFLSBUF and then read $dev1/$dev2...
cmp --bytes=$[$mdsize0*1024] $file1 $file2
mdadm -S $md0 mdadm -S $md0

View file

@ -31,7 +31,21 @@ do
echo 1000 > /proc/sys/dev/raid/speed_limit_min echo 1000 > /proc/sys/dev/raid/speed_limit_min
echo 2000 > /proc/sys/dev/raid/speed_limit_max echo 2000 > /proc/sys/dev/raid/speed_limit_max
check wait check wait
while ! echo check > /sys/block/md0/md/sync_action; do sleep 0.1; done
max=5
for ((i = 0 ; i < max ; i++ )); do
if [[ $(echo check > /sys/block/md0/md/sync_action) != 0 ]]; then
break;
fi
sleep 1
done
if [[ i == max ]]; then
echo >&2 "Timeout waiting for check to succeed"
exit 1
fi
check wait check wait
mm=`cat /sys/block/md0/md/mismatch_cnt` mm=`cat /sys/block/md0/md/mismatch_cnt`
if [ $mm -gt 0 ] if [ $mm -gt 0 ]

View file

@ -186,7 +186,7 @@ is_raid_foreign() {
# to decide if an array is foreign or local. It adds homehost if # to decide if an array is foreign or local. It adds homehost if
# one array is local # one array is local
hostname=$(hostname) hostname=$(hostname)
if [ `expr length "$(hostname)$name"` -lt 31 ]; then if [ `expr length "$(hostname):$name"` -lt 31 ]; then
is_foreign="no" is_foreign="no"
else else
is_foreign="yes" is_foreign="yes"
@ -202,6 +202,24 @@ restore_selinux() {
setenforce $sys_selinux setenforce $sys_selinux
} }
wait_for_reshape_end() {
# wait for grow-continue to finish but break if sync_action does not
# contain any reshape value
while true
do
sync_action=$(grep -Ec '(resync|recovery|reshape|check|repair) *=' /proc/mdstat)
if (( "$sync_action" != 0 )); then
sleep 1
continue
elif [[ $(pgrep -f "mdadm --grow --continue" > /dev/null) != "" ]]; then
echo "Grow continue did not finish but reshape is done" >&2
exit 1
else
break
fi
done
}
setup_systemd_env() { setup_systemd_env() {
warn "Warning! Test suite will set up systemd environment!\n" warn "Warning! Test suite will set up systemd environment!\n"
echo "Use \"systemctl show-environment\" to show systemd environment variables" echo "Use \"systemctl show-environment\" to show systemd environment variables"
@ -357,15 +375,28 @@ check() {
max=`cat /proc/sys/dev/raid/speed_limit_max` max=`cat /proc/sys/dev/raid/speed_limit_max`
echo 200000 > /proc/sys/dev/raid/speed_limit_max echo 200000 > /proc/sys/dev/raid/speed_limit_max
sleep 0.1 sleep 0.1
while grep -Eq '(resync|recovery|reshape|check|repair) *=' /proc/mdstat || iterations=0
grep -v idle > /dev/null /sys/block/md*/md/sync_action # Wait 10 seconds for one of the actions appears in sync_action.
while [ $iterations -le 10 ]
do do
sleep 0.5 sync_action=$(grep -Ec '(resync|recovery|reshape|check|repair) *=' /proc/mdstat)
done if (( "$sync_action" == 0 )); then
while ps auxf | grep "mdadm --grow --continue" | grep -v grep sleep 1
do iterations=$(( $iterations + 1 ))
sleep 1 continue
else
break
fi
done done
echo "Reshape has not started after 10 seconds"
# Now let's wait for reshape to finish.
echo "Waiting for grow-continue to finish"
wait_for_reshape_end
# If we have matrix-raid there's a second process ongoing
sleep 5
wait_for_reshape_end
echo $min > /proc/sys/dev/raid/speed_limit_min echo $min > /proc/sys/dev/raid/speed_limit_min
echo $max > /proc/sys/dev/raid/speed_limit_max echo $max > /proc/sys/dev/raid/speed_limit_max
;; ;;

View file

@ -103,9 +103,7 @@ else
exit 1 exit 1
fi fi
else else
sleep 5
check wait check wait
sleep 5
check wait check wait
imsm_check member $member0 $num_disks $vol0_level $vol0_comp_size $((vol0_comp_size * vol0_new_num_comps)) $vol0_offset $vol0_chunk 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 testdev $member0 $vol0_new_num_comps $vol0_comp_size $vol0_chunk

View file

@ -4,8 +4,6 @@ function names_create() {
local NAME=$2 local NAME=$2
local NEG_TEST=$3 local NEG_TEST=$3
is_raid_foreign $DEVNAME
if [[ -z "$NAME" ]]; then if [[ -z "$NAME" ]]; then
mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force
else else
@ -34,6 +32,10 @@ function names_verify() {
local WANTED_NAME="$3" local WANTED_NAME="$3"
local EXPECTED="" local EXPECTED=""
# We don't know what is saved in metadata, but we know what to expect. Therfore check if
# expecation would be foreign (no hostname information).
is_raid_foreign $WANTED_NAME
local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)" local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)"
if [[ "$?" != "0" ]]; then if [[ "$?" != "0" ]]; then
echo "Cannot get details for $DEVNODE_NAME - unexpected devnode." echo "Cannot get details for $DEVNODE_NAME - unexpected devnode."