"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "Grow.c" between
mdadm-4.1.tar.gz and mdadm-4.2.tar.gz

About: mdadm is a tool for creating, managing and monitoring device arrays using the "md" driver in Linux, also known as Software RAID arrays.

Grow.c  (mdadm-4.1):Grow.c  (mdadm-4.2)
skipping to change at line 200 skipping to change at line 200
} }
/* Ok, looks good. Lets update the superblock and write it out to /* Ok, looks good. Lets update the superblock and write it out to
* newdev. * newdev.
*/ */
info.disk.number = d; info.disk.number = d;
info.disk.major = major(rdev); info.disk.major = major(rdev);
info.disk.minor = minor(rdev); info.disk.minor = minor(rdev);
info.disk.raid_disk = d; info.disk.raid_disk = d;
info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE); info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
st->ss->update_super(st, &info, "linear-grow-new", newdev, 0, 0, NULL); if (st->ss->update_super(st, &info, "linear-grow-new", newdev,
0, 0, NULL) != 0) {
pr_err("Preparing new metadata failed on %s\n", newdev);
close(nfd);
return 1;
}
if (st->ss->store_super(st, nfd)) { if (st->ss->store_super(st, nfd)) {
pr_err("Cannot store new superblock on %s\n", newdev); pr_err("Cannot store new superblock on %s\n", newdev);
close(nfd); close(nfd);
return 1; return 1;
} }
close(nfd); close(nfd);
if (ioctl(fd, ADD_NEW_DISK, &info.disk) != 0) { if (ioctl(fd, ADD_NEW_DISK, &info.disk) != 0) {
pr_err("Cannot add new disk to this array\n"); pr_err("Cannot add new disk to this array\n");
skipping to change at line 253 skipping to change at line 258
pr_err("cannot find super block on %s\n", dv); pr_err("cannot find super block on %s\n", dv);
close(fd); close(fd);
close(fd2); close(fd2);
return 1; return 1;
} }
info.array.raid_disks = nd+1; info.array.raid_disks = nd+1;
info.array.nr_disks = nd+1; info.array.nr_disks = nd+1;
info.array.active_disks = nd+1; info.array.active_disks = nd+1;
info.array.working_disks = nd+1; info.array.working_disks = nd+1;
st->ss->update_super(st, &info, "linear-grow-update", dv, if (st->ss->update_super(st, &info, "linear-grow-update", dv,
0, 0, NULL); 0, 0, NULL) != 0) {
pr_err("Updating metadata failed on %s\n", dv);
close(fd2);
return 1;
}
if (st->ss->store_super(st, fd2)) { if (st->ss->store_super(st, fd2)) {
pr_err("Cannot store new superblock on %s\n", dv); pr_err("Cannot store new superblock on %s\n", dv);
close(fd2); close(fd2);
return 1; return 1;
} }
close(fd2); close(fd2);
} }
return 0; return 0;
skipping to change at line 424 skipping to change at line 433
disk.number = d; disk.number = d;
if (md_get_disk_info(fd, &disk) < 0) if (md_get_disk_info(fd, &disk) < 0)
continue; continue;
if (disk.major == 0 && disk.minor == 0) if (disk.major == 0 && disk.minor == 0)
continue; continue;
if ((disk.state & (1 << MD_DISK_SYNC)) == 0) if ((disk.state & (1 << MD_DISK_SYNC)) == 0)
continue; continue;
dv = map_dev(disk.major, disk.minor, 1); dv = map_dev(disk.major, disk.minor, 1);
if (!dv) if (!dv)
continue; continue;
if (((disk.state & (1 << MD_DISK_WRITEMOSTLY)) == 0) &&
(strcmp(s->bitmap_file, "clustered") == 0)) {
pr_err("%s disks marked write-mostly are not supp
orted with clustered bitmap\n",devname);
return 1;
}
fd2 = dev_open(dv, O_RDWR); fd2 = dev_open(dv, O_RDWR);
if (fd2 < 0) if (fd2 < 0)
continue; continue;
rv = st->ss->load_super(st, fd2, NULL); rv = st->ss->load_super(st, fd2, NULL);
if (!rv) { if (!rv) {
rv = st->ss->add_internal_bitmap( rv = st->ss->add_internal_bitmap(
st, &s->bitmap_chunk, c->delay, st, &s->bitmap_chunk, c->delay,
s->write_behind, bitmapsize, s->write_behind, bitmapsize,
offset_setable, major); offset_setable, major);
if (!rv) { if (!rv) {
skipping to change at line 449 skipping to change at line 463
} else { } else {
pr_err("failed to load super-block.\n"); pr_err("failed to load super-block.\n");
} }
close(fd2); close(fd2);
if (rv) if (rv)
return 1; return 1;
} }
if (offset_setable) { if (offset_setable) {
st->ss->getinfo_super(st, mdi, NULL); st->ss->getinfo_super(st, mdi, NULL);
if (sysfs_init(mdi, fd, NULL)) { if (sysfs_init(mdi, fd, NULL)) {
pr_err("failed to intialize sysfs.\n"); pr_err("failed to initialize sysfs.\n");
free(mdi); free(mdi);
} }
rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location", rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
mdi->bitmap_offset); mdi->bitmap_offset);
free(mdi); free(mdi);
} else { } else {
if (strcmp(s->bitmap_file, "clustered") == 0) if (strcmp(s->bitmap_file, "clustered") == 0)
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);
skipping to change at line 915 skipping to change at line 929
/* if we get EAGAIN here then the monitor is not active /* if we get EAGAIN here then the monitor is not active
* so stop trying * so stop trying
*/ */
rc = sysfs_set_num(sra, NULL, name, n); rc = sysfs_set_num(sra, NULL, name, n);
} }
sysfs_set_str(sra, NULL, "safe_mode_delay", safe); sysfs_set_str(sra, NULL, "safe_mode_delay", safe);
return rc; return rc;
} }
int start_reshape(struct mdinfo *sra, int already_running, int start_reshape(struct mdinfo *sra, int already_running,
int before_data_disks, int data_disks) int before_data_disks, int data_disks, struct supertype *st)
{ {
int err; int err;
unsigned long long sync_max_to_set; unsigned long long sync_max_to_set;
sysfs_set_num(sra, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL); sysfs_set_num(sra, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL);
err = sysfs_set_num(sra, NULL, "suspend_hi", sra->reshape_progress); err = sysfs_set_num(sra, NULL, "suspend_hi", sra->reshape_progress);
err = err ?: sysfs_set_num(sra, NULL, "suspend_lo", err = err ?: sysfs_set_num(sra, NULL, "suspend_lo",
sra->reshape_progress); sra->reshape_progress);
if (before_data_disks <= data_disks) if (before_data_disks <= data_disks)
sync_max_to_set = sra->reshape_progress / data_disks; sync_max_to_set = sra->reshape_progress / data_disks;
else else
sync_max_to_set = (sra->component_size * data_disks sync_max_to_set = (sra->component_size * data_disks
- sra->reshape_progress) / data_disks; - sra->reshape_progress) / data_disks;
if (!already_running) if (!already_running)
sysfs_set_num(sra, NULL, "sync_min", sync_max_to_set); 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 (st->ss->external)
err = err ?: sysfs_set_num(sra, NULL, "sync_max", sync_max_to_set
);
else
err = err ?: sysfs_set_str(sra, NULL, "sync_max", "max");
if (!already_running && err == 0) { if (!already_running && err == 0) {
int cnt = 5; int cnt = 5;
do { do {
err = sysfs_set_str(sra, NULL, "sync_action", err = sysfs_set_str(sra, NULL, "sync_action",
"reshape"); "reshape");
if (err) if (err)
sleep(1); sleep(1);
} while (err && errno == EBUSY && cnt-- > 0); } while (err && errno == EBUSY && cnt-- > 0);
} }
return err; return err;
skipping to change at line 1199 skipping to change at line 1219
/* So how much do we need to backup. /* So how much do we need to backup.
* We need an amount of data which is both a whole number of * We need an amount of data which is both a whole number of
* old stripes and a whole number of new stripes. * old stripes and a whole number of new stripes.
* So LCM for (chunksize*datadisks). * So LCM for (chunksize*datadisks).
*/ */
a = (ochunk/512) * odata; a = (ochunk/512) * odata;
b = (nchunk/512) * ndata; b = (nchunk/512) * ndata;
/* Find GCD */ /* Find GCD */
a = GCD(a, b); a = GCD(a, b);
/* LCM == product / GCD */ /* LCM == product / GCD */
blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a; blocks = (unsigned long)(ochunk/512) * (unsigned long)(nchunk/512) *
odata * ndata / a;
return blocks; return blocks;
} }
char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re) char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
{ {
/* Based on the current array state in info->array and /* Based on the current array state in info->array and
* the changes in info->new_* etc, determine: * the changes in info->new_* etc, determine:
* - whether the change is possible * - whether the change is possible
* - Intermediate level/raid_disks/layout * - Intermediate level/raid_disks/layout
skipping to change at line 1840 skipping to change at line 1861
st = super_by_fd(fd, &subarray); st = super_by_fd(fd, &subarray);
if (!st) { if (!st) {
pr_err("Unable to determine metadata format for %s\n", devname); pr_err("Unable to determine metadata format for %s\n", devname);
return 1; return 1;
} }
if (s->raiddisks > st->max_devs) { 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; return 1;
} }
if (s->level == 0 && if (s->level == 0 && (array.state & (1 << MD_SB_BITMAP_PRESENT)) &&
(array.state & (1<<MD_SB_BITMAP_PRESENT)) && !(array.state & (1 << MD_SB_CLUSTERED)) && !st->ss->external) {
!(array.state & (1<<MD_SB_CLUSTERED))) { 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) { pr_err("failed to remove internal bitmap.\n");
pr_err("failed to remove internal bitmap.\n"); return 1;
return 1; }
} }
}
/* in the external case we need to check that the requested reshape is /* in the external case we need to check that the requested reshape is
* supported, and perform an initial check that the container holds the * supported, and perform an initial check that the container holds the
* pre-requisite spare devices (mdmon owns final validation) * pre-requisite spare devices (mdmon owns final validation)
*/ */
if (st->ss->external) { if (st->ss->external) {
int retval; int retval;
if (subarray) { if (subarray) {
container = st->container_devnm; container = st->container_devnm;
skipping to change at line 1912 skipping to change at line 1932
free(subarray); free(subarray);
return 1; return 1;
} }
if (content->consistency_policy == if (content->consistency_policy ==
CONSISTENCY_POLICY_PPL) { CONSISTENCY_POLICY_PPL) {
pr_err("Operation not supported when ppl consistency policy is enabled\n"); pr_err("Operation not supported when ppl consistency policy is enabled\n");
sysfs_free(cc); sysfs_free(cc);
free(subarray); free(subarray);
return 1; return 1;
} }
if (content->consistency_policy ==
CONSISTENCY_POLICY_BITMAP) {
pr_err("Operation not supported when writ
e-intent bitmap is enabled\n");
sysfs_free(cc);
free(subarray);
return 1;
}
} }
sysfs_free(cc); sysfs_free(cc);
} }
if (mdmon_running(container)) if (mdmon_running(container))
st->update_tail = &st->updates; st->update_tail = &st->updates;
} }
added_disks = 0; added_disks = 0;
for (dv = devlist; dv; dv = dv->next) for (dv = devlist; dv; dv = dv->next)
added_disks++; added_disks++;
skipping to change at line 2180 skipping to change at line 2207
* and updated metadata before we continue with * and updated metadata before we continue with
* level change * level change
*/ */
if (container) if (container)
ping_monitor(container); ping_monitor(container);
} }
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.array = array; info.array = array;
if (sysfs_init(&info, fd, NULL)) { if (sysfs_init(&info, fd, NULL)) {
pr_err("failed to intialize sysfs.\n"); pr_err("failed to initialize sysfs.\n");
rv = 1; rv = 1;
goto release; goto release;
} }
strcpy(info.text_version, sra->text_version); strcpy(info.text_version, sra->text_version);
info.component_size = s->size*2; info.component_size = s->size*2;
info.new_level = s->level; info.new_level = s->level;
info.new_chunk = s->chunk * 1024; info.new_chunk = s->chunk * 1024;
if (info.array.level == LEVEL_CONTAINER) { if (info.array.level == LEVEL_CONTAINER) {
info.delta_disks = UnSet; info.delta_disks = UnSet;
info.array.raid_disks = s->raiddisks; info.array.raid_disks = s->raiddisks;
skipping to change at line 2310 skipping to change at line 2337
} }
} else if (array.level == LEVEL_CONTAINER) { } else if (array.level == LEVEL_CONTAINER) {
/* This change is to be applied to every array in the /* This change is to be applied to every array in the
* container. This is only needed when the metadata imposes * container. This is only needed when the metadata imposes
* restraints of the various arrays in the container. * restraints of the various arrays in the container.
* Currently we only know that IMSM requires all arrays * Currently we only know that IMSM requires all arrays
* to have the same number of devices so changing the * to have the same number of devices so changing the
* number of devices (On-Line Capacity Expansion) must be * number of devices (On-Line Capacity Expansion) must be
* performed at the level of the container * performed at the level of the container
*/ */
if (fd > 0) { close_fd(&fd);
close(fd);
fd = -1;
}
rv = reshape_container(container, devname, -1, st, &info, rv = reshape_container(container, devname, -1, st, &info,
c->force, c->backup_file, c->verbose, c->force, c->backup_file, c->verbose,
0, 0, 0); 0, 0, 0);
frozen = 0; frozen = 0;
} else { } else {
/* get spare devices from external metadata /* get spare devices from external metadata
*/ */
if (st->ss->external) { if (st->ss->external) {
struct mdinfo *info2; struct mdinfo *info2;
skipping to change at line 2615 skipping to change at line 2639
} else { } else {
/* Decrease data offset */ /* Decrease data offset */
if (before < min) { if (before < min) {
if (can_fallback) if (can_fallback)
goto fallback; goto fallback;
pr_err("insufficient head-room on %s\n", pr_err("insufficient head-room on %s\n",
dn); dn);
goto release; goto release;
} }
if (data_offset != INVALID_SECTORS && if (data_offset != INVALID_SECTORS &&
data_offset < sd->data_offset - min) { data_offset > sd->data_offset - min) {
pr_err("--data-offset too small on %s\n", pr_err("--data-offset too large on %s\n",
dn); dn);
goto release; goto release;
} }
if (data_offset != INVALID_SECTORS) if (data_offset != INVALID_SECTORS)
new_data_offset = data_offset; new_data_offset = data_offset;
else else
new_data_offset = choose_offset(sd->data_ offset - before, new_data_offset = choose_offset(sd->data_ offset - before,
sd->data_ offset, sd->data_ offset,
sd->data_ offset - before, sd->data_ offset - before,
sd->data_ offset - min); sd->data_ offset - min);
skipping to change at line 2905 skipping to change at line 2929
return -1; return -1;
} }
static int impose_level(int fd, int level, char *devname, int verbose) static int impose_level(int fd, int level, char *devname, int verbose)
{ {
char *c; char *c;
struct mdu_array_info_s array; struct mdu_array_info_s array;
struct mdinfo info; struct mdinfo info;
if (sysfs_init(&info, fd, NULL)) { if (sysfs_init(&info, fd, NULL)) {
pr_err("failed to intialize sysfs.\n"); pr_err("failed to initialize sysfs.\n");
return 1; return 1;
} }
md_get_array_info(fd, &array); md_get_array_info(fd, &array);
if (level == 0 && (array.level >= 4 && array.level <= 6)) { if (level == 0 && (array.level >= 4 && array.level <= 6)) {
/* To convert to RAID0 we need to fail and /* To convert to RAID0 we need to fail and
* remove any non-data devices. */ * remove any non-data devices. */
int found = 0; int found = 0;
int d; int d;
int data_disks = array.raid_disks - 1; int data_disks = array.raid_disks - 1;
skipping to change at line 2984 skipping to change at line 3008
} }
return 0; return 0;
} }
int sigterm = 0; int sigterm = 0;
static void catch_term(int sig) static void catch_term(int sig)
{ {
sigterm = 1; sigterm = 1;
} }
static int continue_via_systemd(char *devnm)
{
int skipped, i, pid, status;
char pathbuf[1024];
/* In a systemd/udev world, it is best to get systemd to
* run "mdadm --grow --continue" rather than running in the
* background.
*/
switch(fork()) {
case 0:
/* FIXME yuk. CLOSE_EXEC?? */
skipped = 0;
for (i = 3; skipped < 20; i++)
if (close(i) < 0)
skipped++;
else
skipped = 0;
/* Don't want to see error messages from
* systemctl. If the service doesn't exist,
* we fork ourselves.
*/
close(2);
open("/dev/null", O_WRONLY);
snprintf(pathbuf, sizeof(pathbuf),
"mdadm-grow-continue@%s.service", devnm);
status = execl("/usr/bin/systemctl", "systemctl", "restart",
pathbuf, NULL);
status = execl("/bin/systemctl", "systemctl", "restart",
pathbuf, NULL);
exit(1);
case -1: /* Just do it ourselves. */
break;
default: /* parent - good */
pid = wait(&status);
if (pid >= 0 && status == 0)
return 1;
}
return 0;
}
static int reshape_array(char *container, int fd, char *devname, static int reshape_array(char *container, int fd, char *devname,
struct supertype *st, struct mdinfo *info, struct supertype *st, struct mdinfo *info,
int force, struct mddev_dev *devlist, int force, struct mddev_dev *devlist,
unsigned long long data_offset, unsigned long long data_offset,
char *backup_file, int verbose, int forked, char *backup_file, int verbose, int forked,
int restart, int freeze_reshape) int restart, int freeze_reshape)
{ {
struct reshape reshape; struct reshape reshape;
int spares_needed; int spares_needed;
char *msg; char *msg;
skipping to change at line 3288 skipping to change at line 3271
} }
} }
if (info->new_chunk != 0 && if (info->new_chunk != 0 &&
info->new_chunk != array.chunk_size) { info->new_chunk != array.chunk_size) {
if (sysfs_set_num(info, NULL, if (sysfs_set_num(info, NULL,
"chunk_size", info->new_chunk) != 0) { "chunk_size", info->new_chunk) != 0) {
pr_err("failed to set chunk size\n"); pr_err("failed to set chunk size\n");
goto release; goto release;
} else if (verbose >= 0) } else if (verbose >= 0)
printf("chunk size for %s set to %d\n", printf("chunk size for %s set to %d\n",
devname, array.chunk_size); devname, info->new_chunk);
} }
unfreeze(st); unfreeze(st);
return 0; return 0;
} }
/* /*
* There are three possibilities. * There are three possibilities.
* 1/ The array will shrink. * 1/ The array will shrink.
* We need to ensure the reshape will pause before reaching * We need to ensure the reshape will pause before reaching
* the 'critical section'. We also need to fork and wait for * the 'critical section'. We also need to fork and wait for
skipping to change at line 3403 skipping to change at line 3386
} }
if (info->new_level == reshape.level) if (info->new_level == reshape.level)
return 0; return 0;
/* need to adjust level when reshape completes */ /* need to adjust level when reshape completes */
switch(fork()) { switch(fork()) {
case -1: /* ignore error, but don't wait */ case -1: /* ignore error, but don't wait */
return 0; return 0;
default: /* parent */ default: /* parent */
return 0; return 0;
case 0: case 0:
manage_fork_fds(0);
map_fork(); map_fork();
break; break;
} }
close(fd); close(fd);
wait_reshape(sra); wait_reshape(sra);
fd = open_dev(sra->sys_name); fd = open_dev(sra->sys_name);
if (fd >= 0) if (fd >= 0)
impose_level(fd, info->new_level, devname, verbose); impose_level(fd, info->new_level, devname, verbose);
return 0; return 0;
case 1: /* Couldn't set data_offset, try the old way */ case 1: /* Couldn't set data_offset, try the old way */
skipping to change at line 3494 skipping to change at line 3478
* If only changing raid_disks, use ioctl, else use * If only changing raid_disks, use ioctl, else use
* sysfs. * sysfs.
*/ */
sync_metadata(st); sync_metadata(st);
if (impose_reshape(sra, info, st, fd, restart, if (impose_reshape(sra, info, st, fd, restart,
devname, container, &reshape) < 0) devname, container, &reshape) < 0)
goto release; goto release;
err = start_reshape(sra, restart, reshape.before.data_disks, err = start_reshape(sra, restart, reshape.before.data_disks,
reshape.after.data_disks); reshape.after.data_disks, st);
if (err) { if (err) {
pr_err("Cannot %s reshape for %s\n", pr_err("Cannot %s reshape for %s\n",
restart ? "continue" : "start", devname); restart ? "continue" : "start", devname);
goto release; goto release;
} }
if (restart) if (restart)
sysfs_set_str(sra, NULL, "array_state", "active"); sysfs_set_str(sra, NULL, "array_state", "active");
if (freeze_reshape) { if (freeze_reshape) {
free(fdlist); free(fdlist);
free(offsets); free(offsets);
sysfs_free(sra); 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); sra->reshape_progress);
return 1; return 1;
} }
if (!forked && !check_env("MDADM_NO_SYSTEMCTL")) if (!forked)
if (continue_via_systemd(container ?: sra->sys_name)) { if (continue_via_systemd(container ?: sra->sys_name,
GROW_SERVICE)) {
free(fdlist); free(fdlist);
free(offsets); free(offsets);
sysfs_free(sra); sysfs_free(sra);
return 0; return 0;
} }
close(fd);
/* Now we just need to kick off the reshape and watch, while /* Now we just need to kick off the reshape and watch, while
* handling backups of the data... * handling backups of the data...
* This is all done by a forked background process. * This is all done by a forked background process.
*/ */
switch(forked ? 0 : fork()) { switch(forked ? 0 : fork()) {
case -1: case -1:
pr_err("Cannot run child to monitor reshape: %s\n", pr_err("Cannot run child to monitor reshape: %s\n",
strerror(errno)); strerror(errno));
abort_reshape(sra); abort_reshape(sra);
goto release; goto release;
skipping to change at line 3571 skipping to change at line 3557
free_mdstat(mds); free_mdstat(mds);
if (delayed == 1 && get_linux_version() < 3007000) { if (delayed == 1 && get_linux_version() < 3007000) {
pr_err("Reshape is delayed, but cannot wait carefully wit h this kernel.\n" pr_err("Reshape is delayed, but cannot wait carefully wit h this kernel.\n"
" You might experience problems until other reshapes complete.\n"); " You might experience problems until other reshapes complete.\n");
delayed = 0; delayed = 0;
} }
if (delayed) if (delayed)
mdstat_wait(30 - (delayed-1) * 25); mdstat_wait(30 - (delayed-1) * 25);
} while (delayed); } while (delayed);
mdstat_close(); mdstat_close();
close(fd);
if (check_env("MDADM_GROW_VERIFY")) if (check_env("MDADM_GROW_VERIFY"))
fd = open(devname, O_RDONLY | O_DIRECT); fd = open(devname, O_RDONLY | O_DIRECT);
else else
fd = -1; fd = -1;
mlockall(MCL_FUTURE); mlockall(MCL_FUTURE);
signal(SIGTERM, catch_term); signal(SIGTERM, catch_term);
if (st->ss->external) { if (st->ss->external) {
/* metadata handler takes it from here */ /* metadata handler takes it from here */
skipping to change at line 3706 skipping to change at line 3691
unfreeze(st); unfreeze(st);
return 1; return 1;
} }
sync_metadata(st); sync_metadata(st);
/* ping monitor to be sure that update is on disk /* ping monitor to be sure that update is on disk
*/ */
ping_monitor(container); ping_monitor(container);
if (!forked && !freeze_reshape && !check_env("MDADM_NO_SYSTEMCTL")) if (!forked && !freeze_reshape)
if (continue_via_systemd(container)) if (continue_via_systemd(container, GROW_SERVICE))
return 0; return 0;
switch (forked ? 0 : fork()) { switch (forked ? 0 : fork()) {
case -1: /* error */ case -1: /* error */
perror("Cannot fork to complete reshape\n"); perror("Cannot fork to complete reshape\n");
unfreeze(st); unfreeze(st);
return 1; return 1;
default: /* parent */ default: /* parent */
if (!freeze_reshape) if (!freeze_reshape)
printf("%s: multi-array reshape continues in background\n ", Name); printf("%s: multi-array reshape continues in background\n ", Name);
return 0; return 0;
case 0: /* child */ case 0: /* child */
manage_fork_fds(0);
map_fork(); map_fork();
break; break;
} }
/* close unused handle in child process /* close unused handle in child process
*/ */
if (mdfd > -1) if (mdfd > -1)
close(mdfd); close(mdfd);
while(1) { while(1) {
 End of changes. 23 change blocks. 
72 lines changed or deleted 61 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)