"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "Create.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.

Create.c  (mdadm-4.1):Create.c  (mdadm-4.2)
skipping to change at line 30 skipping to change at line 30
* *
* Author: Neil Brown * Author: Neil Brown
* Email: <neilb@suse.de> * Email: <neilb@suse.de>
*/ */
#include "mdadm.h" #include "mdadm.h"
#include "md_u.h" #include "md_u.h"
#include "md_p.h" #include "md_p.h"
#include <ctype.h> #include <ctype.h>
static int round_size_and_verify(unsigned long long *size, int chunk)
{
if (*size == 0)
return 0;
*size &= ~(unsigned long long)(chunk - 1);
if (*size == 0) {
pr_err("Size cannot be smaller than chunk.\n");
return 1;
}
return 0;
}
static int default_layout(struct supertype *st, int level, int verbose) static int default_layout(struct supertype *st, int level, int verbose)
{ {
int layout = UnSet; int layout = UnSet;
if (st && st->ss->default_geometry) if (st && st->ss->default_geometry)
st->ss->default_geometry(st, &level, &layout, NULL); st->ss->default_geometry(st, &level, &layout, NULL);
if (layout == UnSet) if (layout == UnSet)
switch(level) { switch(level) {
default: /* no layout */ default: /* no layout */
layout = 0; layout = 0;
break; break;
case 0:
layout = RAID0_ORIG_LAYOUT;
break;
case 10: case 10:
layout = 0x102; /* near=2, far=1 */ layout = 0x102; /* near=2, far=1 */
if (verbose > 0) if (verbose > 0)
pr_err("layout defaults to n2\n"); pr_err("layout defaults to n2\n");
break; break;
case 5: case 5:
case 6: case 6:
layout = map_name(r5layout, "default"); layout = map_name(r5layout, "default");
if (verbose > 0) if (verbose > 0)
pr_err("layout defaults to %s\n", map_num(r5layou t, layout)); pr_err("layout defaults to %s\n", map_num(r5layou t, layout));
skipping to change at line 141 skipping to change at line 156
} }
if (s->raiddisks < 4 && s->level == 6) { if (s->raiddisks < 4 && s->level == 6) {
pr_err("at least 4 raid-devices needed for level 6\n"); pr_err("at least 4 raid-devices needed for level 6\n");
return 1; return 1;
} }
if (s->raiddisks > 256 && s->level == 6) { if (s->raiddisks > 256 && s->level == 6) {
pr_err("no more than 256 raid-devices supported for level 6\n"); pr_err("no more than 256 raid-devices supported for level 6\n");
return 1; return 1;
} }
if (s->raiddisks < 2 && s->level >= 4) { if (s->raiddisks < 2 && s->level >= 4) {
pr_err("at least 2 raid-devices needed for level 4 or 5\n"); pr_err("at least 2 raid-devices needed for level %d\n", s->level) ;
return 1; return 1;
} }
if (s->level <= 0 && s->sparedisks) { if (s->level <= 0 && s->sparedisks) {
pr_err("This level does not support spare devices\n"); pr_err("This level does not support spare devices\n");
return 1; return 1;
} }
if (subdevs == 1 && strcmp(devlist->devname, "missing") != 0) { if (subdevs == 1 && strcmp(devlist->devname, "missing") != 0) {
/* If given a single device, it might be a container, and we can /* If given a single device, it might be a container, and we can
* extract a device list from there * extract a device list from there
skipping to change at line 242 skipping to change at line 257
s->chunk = 64; s->chunk = 64;
if (c->verbose > 0) if (c->verbose > 0)
pr_err("chunk size defaults to 64K\n"); pr_err("chunk size defaults to 64K\n");
} }
break; break;
case 1: case 1:
case LEVEL_FAULTY: case LEVEL_FAULTY:
case LEVEL_MULTIPATH: case LEVEL_MULTIPATH:
case LEVEL_CONTAINER: case LEVEL_CONTAINER:
if (s->chunk) { if (s->chunk) {
s->chunk = 0; pr_err("specifying chunk size is forbidden for this level
if (c->verbose > 0) \n");
pr_err("chunk size ignored for this level\n"); return 1;
} }
break; break;
default: default:
pr_err("unknown level %d\n", s->level); pr_err("unknown level %d\n", s->level);
return 1; return 1;
} }
if (s->size == MAX_SIZE) if (s->size == MAX_SIZE)
/* use '0' to mean 'max' now... */ /* use '0' to mean 'max' now... */
s->size = 0; s->size = 0;
if (s->size && s->chunk && s->chunk != UnSet) if (s->size && s->chunk && s->chunk != UnSet)
s->size &= ~(unsigned long long)(s->chunk - 1); if (round_size_and_verify(&s->size, s->chunk))
return 1;
newsize = s->size * 2; newsize = s->size * 2;
if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddis ks, if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddis ks,
&s->chunk, s->size*2, &s->chunk, s->size*2,
data_offset, NULL, data_offset, NULL,
&newsize, s->consistency_policy, &newsize, s->consistency_policy,
c->verbose >= 0)) c->verbose >= 0))
return 1; return 1;
if (s->chunk && s->chunk != UnSet) { if (s->chunk && s->chunk != UnSet) {
newsize &= ~(unsigned long long)(s->chunk*2 - 1); newsize &= ~(unsigned long long)(s->chunk*2 - 1);
if (do_default_chunk) { if (do_default_chunk) {
/* default chunk was just set */ /* default chunk was just set */
if (c->verbose > 0) if (c->verbose > 0)
pr_err("chunk size defaults to %dK\n", s->chunk); pr_err("chunk size defaults to %dK\n", s->chunk);
s->size &= ~(unsigned long long)(s->chunk - 1); if (round_size_and_verify(&s->size, s->chunk))
return 1;
do_default_chunk = 0; do_default_chunk = 0;
} }
} }
if (s->size == 0) { if (s->size == 0) {
s->size = newsize / 2; s->size = newsize / 2;
if (s->level == 1) if (s->level == 1)
/* If this is ever reshaped to RAID5, we will /* If this is ever reshaped to RAID5, we will
* need a chunksize. So round it off a bit * need a chunksize. So round it off a bit
* now just to be safe * now just to be safe
skipping to change at line 416 skipping to change at line 434
goto skip_size_check; /* skip write journal for size che ck */ goto skip_size_check; /* skip write journal for size che ck */
freesize /= 2; /* convert to K */ freesize /= 2; /* convert to K */
if (s->chunk && s->chunk != UnSet) { if (s->chunk && s->chunk != UnSet) {
/* round to chunk size */ /* round to chunk size */
freesize = freesize & ~(s->chunk-1); freesize = freesize & ~(s->chunk-1);
if (do_default_chunk) { if (do_default_chunk) {
/* default chunk was just set */ /* default chunk was just set */
if (c->verbose > 0) if (c->verbose > 0)
pr_err("chunk size defaults to %dK\n", s- >chunk); pr_err("chunk size defaults to %dK\n", s- >chunk);
s->size &= ~(unsigned long long)(s->chunk - 1); if (round_size_and_verify(&s->size, s->chunk))
return 1;
do_default_chunk = 0; do_default_chunk = 0;
} }
} }
if (!freesize) { if (!freesize) {
pr_err("no free space left on %s\n", dname); pr_err("no free space left on %s\n", dname);
fail = 1; fail = 1;
continue; continue;
} }
if (s->size && freesize < s->size) { if (s->size && freesize < s->size) {
skipping to change at line 523 skipping to change at line 542
* need a chunksize. So round it off a bit * need a chunksize. So round it off a bit
* now just to be safe * now just to be safe
*/ */
s->size &= ~(64ULL-1); s->size &= ~(64ULL-1);
if (c->verbose > 0) if (c->verbose > 0)
pr_err("size set to %lluK\n", s->size); pr_err("size set to %lluK\n", s->size);
} }
} }
if (!s->bitmap_file && if (!s->bitmap_file &&
!st->ss->external &&
s->level >= 1 && s->level >= 1 &&
st->ss->add_internal_bitmap && st->ss->add_internal_bitmap &&
s->journaldisks == 0 &&
(s->consistency_policy != CONSISTENCY_POLICY_RESYNC && (s->consistency_policy != CONSISTENCY_POLICY_RESYNC &&
s->consistency_policy != CONSISTENCY_POLICY_PPL) && s->consistency_policy != CONSISTENCY_POLICY_PPL) &&
(s->write_behind || s->size > 100*1024*1024ULL)) { (s->write_behind || s->size > 100*1024*1024ULL)) {
if (c->verbose > 0) if (c->verbose > 0)
pr_err("automatically enabling write-intent bitmap on lar ge array\n"); pr_err("automatically enabling write-intent bitmap on lar ge array\n");
s->bitmap_file = "internal"; s->bitmap_file = "internal";
} }
if (s->bitmap_file && strcmp(s->bitmap_file, "none") == 0) if (s->bitmap_file && strcmp(s->bitmap_file, "none") == 0)
s->bitmap_file = NULL; s->bitmap_file = NULL;
skipping to change at line 826 skipping to change at line 847
st->ss->uuid_from_super(st, uuid); st->ss->uuid_from_super(st, uuid);
if (CreateBitmap(s->bitmap_file, c->force, (char*)uuid, s->bitmap _chunk, if (CreateBitmap(s->bitmap_file, c->force, (char*)uuid, s->bitmap _chunk,
c->delay, s->write_behind, c->delay, s->write_behind,
bitmapsize, bitmapsize,
major_num)) { major_num)) {
goto abort_locked; goto abort_locked;
} }
bitmap_fd = open(s->bitmap_file, O_RDWR); bitmap_fd = open(s->bitmap_file, O_RDWR);
if (bitmap_fd < 0) { if (bitmap_fd < 0) {
pr_err("weird: %s cannot be openned\n", pr_err("weird: %s cannot be opened\n",
s->bitmap_file); s->bitmap_file);
goto abort_locked; goto abort_locked;
} }
if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) { if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
pr_err("Cannot set bitmap file for %s: %s\n", pr_err("Cannot set bitmap file for %s: %s\n",
mddev, strerror(errno)); mddev, strerror(errno));
goto abort_locked; goto abort_locked;
} }
} }
skipping to change at line 881 skipping to change at line 902
if (dv->disposition == 'j') { if (dv->disposition == 'j') {
inf->disk.raid_disk = MD_DISK_ROLE_JOURNA L; inf->disk.raid_disk = MD_DISK_ROLE_JOURNA L;
inf->disk.state = (1<<MD_DISK_JOURNAL); inf->disk.state = (1<<MD_DISK_JOURNAL);
raid_disk_num--; raid_disk_num--;
} else if (inf->disk.raid_disk < s->raiddisks) } else if (inf->disk.raid_disk < s->raiddisks)
inf->disk.state = (1<<MD_DISK_ACTIVE) | inf->disk.state = (1<<MD_DISK_ACTIVE) |
(1<<MD_DISK_SYNC); (1<<MD_DISK_SYNC);
else else
inf->disk.state = 0; inf->disk.state = 0;
if (dv->writemostly == FlagSet) if (dv->writemostly == FlagSet) {
inf->disk.state |= (1<<MD_DISK_WRITEMOSTL if (major_num == BITMAP_MAJOR_CLUSTERED)
Y); {
pr_err("Can not set %s --write-mo
stly with a clustered bitmap\n",dv->devname);
goto abort_locked;
} else
inf->disk.state |= (1<<MD_DISK_WR
ITEMOSTLY);
}
if (dv->failfast == FlagSet) if (dv->failfast == FlagSet)
inf->disk.state |= (1<<MD_DISK_FAILFAST); inf->disk.state |= (1<<MD_DISK_FAILFAST);
if (have_container) if (have_container)
fd = -1; fd = -1;
else { else {
if (st->ss->external && if (st->ss->external &&
st->container_devnm[0]) st->container_devnm[0])
fd = open(dv->devname, O_RDWR); fd = open(dv->devname, O_RDWR);
else else
skipping to change at line 936 skipping to change at line 962
} }
break; break;
case 2: case 2:
inf->errors = 0; inf->errors = 0;
rv = add_disk(mdfd, st, &info, inf); rv = add_disk(mdfd, st, &info, inf);
if (rv) { if (rv) {
pr_err("ADD_NEW_DISK for %s failed: %s\n" , pr_err("ADD_NEW_DISK for %s failed: %s\n" ,
dv->devname, strerror(errno)); dv->devname, strerror(errno));
if (errno == EINVAL &&
info.array.level == 0) {
pr_err("Possibly your kernel does
n't support RAID0 layouts.\n");
pr_err("Either upgrade, or use --
layout=dangerous\n");
}
goto abort_locked; goto abort_locked;
} }
break; break;
} }
if (!have_container && if (!have_container &&
dv == moved_disk && dnum != insert_point) break; dv == moved_disk && dnum != insert_point) break;
} }
if (pass == 1) { if (pass == 1) {
struct mdinfo info_new; struct mdinfo info_new;
struct map_ent *me = NULL; struct map_ent *me = NULL;
skipping to change at line 966 skipping to change at line 997
map_update(&map, fd2devnm(mdfd), map_update(&map, fd2devnm(mdfd),
info_new.text_version, info_new.text_version,
info_new.uuid, chosen_name); info_new.uuid, chosen_name);
me = map_by_devnm(&map, st->container_devnm); me = map_by_devnm(&map, st->container_devnm);
} }
if (st->ss->write_init_super(st)) { if (st->ss->write_init_super(st)) {
st->ss->free_super(st); st->ss->free_super(st);
goto abort_locked; goto abort_locked;
} }
/*
* Before activating the array, perform extra steps
* required to configure the internal write-intent
* bitmap.
*/
if (info_new.consistency_policy ==
CONSISTENCY_POLICY_BITMAP &&
st->ss->set_bitmap &&
st->ss->set_bitmap(st, &info)) {
st->ss->free_super(st);
goto abort_locked;
}
/* update parent container uuid */ /* update parent container uuid */
if (me) { if (me) {
char *path = xstrdup(me->path); char *path = xstrdup(me->path);
st->ss->getinfo_super(st, &info_new, NULL); st->ss->getinfo_super(st, &info_new, NULL);
map_update(&map, st->container_devnm, map_update(&map, st->container_devnm,
info_new.text_version, info_new.text_version,
info_new.uuid, path); info_new.uuid, path);
free(path); free(path);
skipping to change at line 1032 skipping to change at line 1075
strerror(errno)); strerror(errno));
ioctl(mdfd, STOP_ARRAY, NULL); ioctl(mdfd, STOP_ARRAY, NULL);
goto abort; goto abort;
} }
} else { } else {
/* param is not actually used */ /* param is not actually used */
mdu_param_t param; mdu_param_t param;
if (ioctl(mdfd, RUN_ARRAY, &param)) { if (ioctl(mdfd, RUN_ARRAY, &param)) {
pr_err("RUN_ARRAY failed: %s\n", pr_err("RUN_ARRAY failed: %s\n",
strerror(errno)); strerror(errno));
if (errno == 524 /* ENOTSUP */ &&
info.array.level == 0)
cont_err("Please use --layout=original or
--layout=alternate\n");
if (info.array.chunk_size & (info.array.chunk_siz e-1)) { if (info.array.chunk_size & (info.array.chunk_siz e-1)) {
cont_err("Problem may be that chunk size is not a power of 2\n"); cont_err("Problem may be that chunk size is not a power of 2\n");
} }
ioctl(mdfd, STOP_ARRAY, NULL); ioctl(mdfd, STOP_ARRAY, NULL);
goto abort; goto abort;
} }
/* if start_ro module parameter is set, array is /* if start_ro module parameter is set, array is
* auto-read-only, which is bad as the resync won't * auto-read-only, which is bad as the resync won't
* start. So lets make it read-write now. * start. So lets make it read-write now.
*/ */
skipping to change at line 1057 skipping to change at line 1103
if (need_mdmon) if (need_mdmon)
start_mdmon(st->container_devnm); start_mdmon(st->container_devnm);
ping_monitor(st->container_devnm); ping_monitor(st->container_devnm);
close(container_fd); close(container_fd);
} }
wait_for(chosen_name, mdfd); wait_for(chosen_name, mdfd);
} else { } else {
pr_err("not starting array - not enough devices.\n"); pr_err("not starting array - not enough devices.\n");
} }
close(mdfd);
/* Give udev a moment to process the Change event caused
* by the close.
*/
usleep(100*1000);
udev_unblock(); udev_unblock();
close(mdfd);
sysfs_uevent(&info, "change");
return 0; return 0;
abort: abort:
udev_unblock(); udev_unblock();
map_lock(&map); map_lock(&map);
abort_locked: abort_locked:
map_remove(&map, fd2devnm(mdfd)); map_remove(&map, fd2devnm(mdfd));
map_unlock(&map); map_unlock(&map);
if (mdfd >= 0) if (mdfd >= 0)
 End of changes. 17 change blocks. 
16 lines changed or deleted 65 lines changed or added

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