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;
int devcnt = 0;
int nextspare = 0;
int bitmap_done = 0;
int most_recent = -1;
int bestcnt = 0;
int *best = *bestp;
@ -661,7 +660,7 @@ static int load_devices(struct devs *devices, char *devmap,
if (c->update == UOPT_UUID && !ident->uuid_set)
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");
close(mdfd);
free(devices);
@ -728,16 +727,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);
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 {
dfd = dev_open(devname,
tmpdev->disposition == 'I'
@ -1057,26 +1046,6 @@ static int start_array(int mdfd,
mddev, strerror(errno));
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 */
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;
int subdevs = 0, missing_disks = 0;
struct mddev_dev *dv;
int bitmap_fd;
unsigned long long bitmapsize;
int mdfd;
char chosen_name[1024];
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;
}
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 */
for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) {
mdu_disk_info_t disk;
@ -150,31 +141,7 @@ int Build(struct mddev_ident *ident, struct mddev_dev *devlist, struct shape *s,
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)) {
pr_err("RUN_ARRAY failed: %s\n", strerror(errno));
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 total_slots;
int rv;
int bitmap_fd;
int have_container = 0;
int container_fd = -1;
int need_mdmon = 0;
@ -534,9 +533,9 @@ int Create(struct supertype *st, struct mddev_ident *ident, int subdevs,
struct map_ent *map = NULL;
unsigned long long newsize;
mdu_array_info_t inf;
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;
if (c->nodes <= 1) {
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");
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",
map_num(pers, s->level)?:"given");
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 &&
!st->ss->write_init_ppl) {
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.
*/
if (s->bitmap_file && (strcmp(s->bitmap_file, "internal") == 0 ||
strcmp(s->bitmap_file, "clustered") == 0)) {
if (s->btype == BitmapInternal || s->btype == BitmapCluster) {
if (!st->ss->add_internal_bitmap) {
pr_err("internal bitmaps not supported with %s metadata\n",
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");
goto abort_locked;
}
s->bitmap_file = 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;
}
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,
have_container, insert_point, major_num, chosen_name))
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
* to all devices
*/
mdu_bitmap_file_t bmf;
mdu_array_info_t array;
struct supertype *st;
char *subarray = NULL;
@ -294,40 +293,21 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
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.
*/
if (!s->bitmap_file)
if (s->btype == BitmapUnknown)
return 1;
if (strcmp(s->bitmap_file, "clustered") == 0)
if (s->btype == BitmapCluster)
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) {
pr_err("cannot get array status for %s\n", devname);
return 1;
}
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);
if (md_set_array_info(fd, &array) != 0) {
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;
}
if (str_is_none(s->bitmap_file) == true) {
if (s->btype == BitmapNone) {
pr_err("no bitmap found on %s\n", devname);
return 1;
}
if (array.level <= 0) {
pr_err("Bitmaps not meaningful with level %s\n",
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);
bitmapsize = bitmapsize * array.raid_disks / ncopies;
if (strcmp(s->bitmap_file, "clustered") == 0 &&
if (s->btype == BitmapCluster &&
!is_near_layout_10(array.layout)) {
pr_err("only near layout is supported with clustered raid10\n");
return 1;
@ -402,8 +383,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
free(mdi);
}
if (strcmp(s->bitmap_file, "internal") == 0 ||
strcmp(s->bitmap_file, "clustered") == 0) {
if (s->btype == BitmapInternal || s->btype == BitmapCluster) {
int rv;
int d;
int offset_setable = 0;
@ -432,7 +412,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
if (!dv)
continue;
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);
free(mdi);
return 1;
@ -471,7 +451,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
mdi->bitmap_offset);
free(mdi);
} else {
if (strcmp(s->bitmap_file, "clustered") == 0)
if (s->btype == BitmapCluster)
array.state |= (1 << MD_SB_CLUSTERED);
array.state |= (1 << MD_SB_BITMAP_PRESENT);
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");
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;

View file

@ -544,21 +544,7 @@ int Incremental(struct mddev_dev *devlist, struct context *c,
cont_err("by --incremental. Please use --assemble\n");
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
* 'count_active' discerned were too old or inappropriate
*/
@ -1400,28 +1386,7 @@ restart:
if (mddev->devname && me->path &&
devname_matches(mddev->devname, me->path))
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
* starting array.
*/

View file

@ -1448,6 +1448,18 @@ int Manage_subdevs(char *devname, int fd,
int rv, err = 0;
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;
if (dv->disposition == 'c') {
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
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
[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
if you cannot use Github. Please add "mdadm:" to the subject to allow automation to create Github
Pull Request and run checks.
While this is the preferred contribution method, mailing list submissions are still welcome and
will be handled as has always been the case for mdadm. Please add "mdadm:" to the subject to allow
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
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);
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) {
pr_err("bitmap file is not supported %s\n", filename);
close(fd);
return -1;
}
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);
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;
}
*stp = st;
return fd;
}

View file

@ -171,8 +171,7 @@ inline void ident_init(struct mddev_ident *ident)
assert(ident);
ident->assembled = false;
ident->bitmap_fd = -1;
ident->bitmap_file = NULL;
ident->btype = BitmapUnknown;
ident->container = NULL;
ident->devices = NULL;
ident->devname = NULL;
@ -542,11 +541,19 @@ void arrayline(char *line)
/* Ignore name in confile */
continue;
} 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",
w);
else
mis.bitmap_file = xstrdup(w + 7);
else {
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) {
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)
{
if (s->bitmap_file) {
if (s->btype != BitmapUnknown) {
pr_err("--bitmap cannot be set twice. Second value: \"%s\".\n", val);
return MDADM_STATUS_ERROR;
}
if (strcmp(val, "internal") == 0 || strcmp(optarg, STR_COMMON_NONE) == 0) {
s->bitmap_file = val;
if (strcmp(optarg, STR_COMMON_NONE) == 0) {
s->btype = BitmapNone;
return MDADM_STATUS_SUCCESS;
}
if (strcmp(val, "internal") == 0) {
s->btype = BitmapInternal;
return MDADM_STATUS_SUCCESS;
}
if (strcmp(val, "clustered") == 0) {
s->bitmap_file = val;
s->btype = BitmapCluster;
/* Set the default number of cluster nodes
* 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, '/')) {
pr_info("Custom write-intent bitmap file option is deprecated.\n");
if (ask("Do you want to continue? (y/n)")) {
s->bitmap_file = val;
return MDADM_STATUS_SUCCESS;
}
pr_err("Custom write-intent bitmap file option is not supported.\n");
return MDADM_STATUS_ERROR;
}
pr_err("--bitmap value must contain a '/' or be 'internal', 'clustered' or 'none'\n");
pr_err("Current value is \"%s\"", val);
pr_err("--bitmap value must be 'internal', 'clustered' or 'none'\n");
pr_err("Current value is \"%s\"\n", val);
return MDADM_STATUS_ERROR;
}
@ -99,7 +99,6 @@ int main(int argc, char *argv[])
struct mddev_ident ident;
char *configfile = NULL;
int devmode = 0;
int bitmap_fd = -1;
struct mddev_dev *devlist = NULL;
struct mddev_dev **devlistend = & devlist;
struct mddev_dev *dv;
@ -116,6 +115,7 @@ int main(int argc, char *argv[])
.bitmap_chunk = UnSet,
.consistency_policy = CONSISTENCY_POLICY_UNKNOWN,
.data_offset = INVALID_SECTORS,
.btype = BitmapUnknown,
};
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,Bitmap):
if (!optarg) {
pr_err("bitmap file needed with -b in --assemble mode\n");
exit(2);
}
if (strcmp(optarg, "internal") == 0 ||
strcmp(optarg, "clustered") == 0) {
if (optarg && (strcmp(optarg, "internal") == 0 ||
strcmp(optarg, "clustered")) == 0) {
pr_err("no need to specify --bitmap when assembling"
" arrays with internal or clustered bitmap\n");
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(GROW, BackupFile):
/* 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");
exit(2);
} 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",
map_num_s(consistency_policies, s.consistency_policy));
exit(2);
} else if (s.bitmap_file &&
str_is_none(s.bitmap_file) == false &&
} else if ((s.btype == BitmapInternal || s.btype == BitmapCluster) &&
s.consistency_policy != CONSISTENCY_POLICY_BITMAP &&
s.consistency_policy != CONSISTENCY_POLICY_JOURNAL) {
pr_err("--bitmap is not compatible with consistency policy: %s\n",
@ -1394,7 +1384,7 @@ int main(int argc, char *argv[])
c.brief = 1;
if (mode == CREATE) {
if (s.bitmap_file && strcmp(s.bitmap_file, "clustered") == 0) {
if (s.btype == BitmapCluster) {
locked = cluster_get_dlmlock();
if (locked != 1)
exit(1);
@ -1479,7 +1469,17 @@ int main(int argc, char *argv[])
case BUILD:
if (c.delay == 0)
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");
rv = 1;
break;
@ -1490,14 +1490,6 @@ int main(int argc, char *argv[])
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);
break;
case CREATE:
@ -1505,8 +1497,7 @@ int main(int argc, char *argv[])
c.delay = DEFAULT_BITMAP_DELAY;
if (c.nodes) {
if (!s.bitmap_file ||
strcmp(s.bitmap_file, "clustered") != 0) {
if (s.btype != BitmapCluster) {
pr_err("--nodes argument only compatible with --bitmap=clustered\n");
rv = 1;
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");
rv = 1;
break;
@ -1535,6 +1526,14 @@ int main(int argc, char *argv[])
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);
break;
case MISC:
@ -1626,7 +1625,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 || s.bitmap_file) {
s.layout_str || s.btype != BitmapNone) {
pr_err("--add cannot be used with other geometry changes in --grow mode\n");
rv = 1;
break;
@ -1636,7 +1635,7 @@ int main(int argc, char *argv[])
if (rv)
break;
}
} else if (s.bitmap_file) {
} else if (s.btype != BitmapUnknown) {
if (s.size > 0 || s.raiddisks || s.chunk ||
s.layout_str || devs_found > 1) {
pr_err("--bitmap changes cannot be used with other geometry changes in --grow mode\n");

26
mdadm.h
View file

@ -603,6 +603,13 @@ enum bitmap_update {
NodeNumUpdate,
};
enum bitmap_type {
BitmapNone,
BitmapInternal,
BitmapCluster,
BitmapUnknown,
};
enum flag_mode {
FlagDefault, FlagSet, FlagClear,
};
@ -640,8 +647,7 @@ struct mddev_ident {
int spare_disks;
struct supertype *st;
char *spare_group;
char *bitmap_file;
int bitmap_fd;
enum bitmap_type btype;
char *container; /* /dev/whatever name of container, or
* uuid of container. You would expect
@ -693,7 +699,7 @@ struct shape {
char *layout_str;
int chunk;
int bitmap_chunk;
char *bitmap_file;
enum bitmap_type btype;
int assume_clean;
bool write_zeroes;
int write_behind;
@ -1899,15 +1905,23 @@ static inline sighandler_t signal_s(int sig, sighandler_t handler)
}
#ifdef DEBUG
#include <time.h>
#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...) \
fprintf(stderr, fmt, ##arg)
#else
#define dprintf(fmt, arg...) \
({ if (0) fprintf(stderr, "%s: %s: " fmt, Name, __func__, ##arg); 0; })
do { } while (0)
#define dprintf_cont(fmt, arg...) \
({ if (0) fprintf(stderr, fmt, ##arg); 0; })
do { } while (0)
#endif
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;
int ret = 0;
int count = 0;
struct timeval tv;
bool write_checkpoint = false;
a->next_state = bad_word;
@ -453,10 +452,8 @@ static int read_and_act(struct active_array *a)
check_for_cleared_bb(a, mdi);
}
gettimeofday(&tv, NULL);
dprintf("(%d): %ld.%06ld state:%s prev:%s action:%s prev: %s start:%llu\n",
dprintf("(%d): 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],
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++) {
struct imsm_disk *d;
struct intel_disk *idisk;
struct imsm_super *mpb = super_table[i]->anchor;
s = super_table[i];
d = &s->disks->disk;
@ -5108,7 +5107,7 @@ imsm_thunderdome(struct intel_super **super_list, int len)
if (!s)
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->minor);
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",
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"
"\tPlease refer to Intel(R) RSTe/VROC user guide.\n");
goto error;
@ -7056,7 +7056,8 @@ active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
int fd = -1;
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);
if (num > 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",
dev->name, strerror(errno));
}
free(path);
dev = dev->next;
}
found = 0;

31
test
View file

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

View file

@ -22,40 +22,6 @@ mdadm -D /dev/md0 | grep -s > /dev/null 01234567:89abcdef:fedcba98:76543210 || {
}
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.
mdadm -CR --assume-clean -b internal --bitmap-chunk 4 $md0 -l5 -n3 $dev0 $dev1 $dev2
mdadm -S /dev/md0

View file

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

View file

@ -31,7 +31,21 @@ do
echo 1000 > /proc/sys/dev/raid/speed_limit_min
echo 2000 > /proc/sys/dev/raid/speed_limit_max
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
mm=`cat /sys/block/md0/md/mismatch_cnt`
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
# one array is local
hostname=$(hostname)
if [ `expr length "$(hostname)$name"` -lt 31 ]; then
if [ `expr length "$(hostname):$name"` -lt 31 ]; then
is_foreign="no"
else
is_foreign="yes"
@ -202,6 +202,24 @@ restore_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() {
warn "Warning! Test suite will set up systemd environment!\n"
echo "Use \"systemctl show-environment\" to show systemd environment variables"
@ -357,15 +375,28 @@ check() {
max=`cat /proc/sys/dev/raid/speed_limit_max`
echo 200000 > /proc/sys/dev/raid/speed_limit_max
sleep 0.1
while grep -Eq '(resync|recovery|reshape|check|repair) *=' /proc/mdstat ||
grep -v idle > /dev/null /sys/block/md*/md/sync_action
do
sleep 0.5
done
while ps auxf | grep "mdadm --grow --continue" | grep -v grep
iterations=0
# Wait 10 seconds for one of the actions appears in sync_action.
while [ $iterations -le 10 ]
do
sync_action=$(grep -Ec '(resync|recovery|reshape|check|repair) *=' /proc/mdstat)
if (( "$sync_action" == 0 )); then
sleep 1
iterations=$(( $iterations + 1 ))
continue
else
break
fi
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 $max > /proc/sys/dev/raid/speed_limit_max
;;

View file

@ -103,9 +103,7 @@ 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

View file

@ -4,8 +4,6 @@ function names_create() {
local NAME=$2
local NEG_TEST=$3
is_raid_foreign $DEVNAME
if [[ -z "$NAME" ]]; then
mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force
else
@ -34,6 +32,10 @@ function names_verify() {
local WANTED_NAME="$3"
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)"
if [[ "$?" != "0" ]]; then
echo "Cannot get details for $DEVNODE_NAME - unexpected devnode."