Add 'container' level and ->validate_geometry method.
These will be used for ddf.
This commit is contained in:
parent
2270232245
commit
17f25ca6fb
56
Create.c
56
Create.c
|
@ -182,6 +182,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
case 1:
|
||||
case LEVEL_FAULTY:
|
||||
case LEVEL_MULTIPATH:
|
||||
case LEVEL_CONTAINER:
|
||||
if (chunk) {
|
||||
chunk = 0;
|
||||
if (verbose > 0)
|
||||
|
@ -193,13 +194,17 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (st && ! st->ss->validate_geometry(st, level, layout, raiddisks,
|
||||
chunk, size, NULL, NULL))
|
||||
return 1;
|
||||
|
||||
/* now look at the subdevs */
|
||||
info.array.active_disks = 0;
|
||||
info.array.working_disks = 0;
|
||||
dnum = 0;
|
||||
for (dv=devlist; dv; dv=dv->next, dnum++) {
|
||||
char *dname = dv->devname;
|
||||
unsigned long long ldsize, freesize;
|
||||
unsigned long long freesize;
|
||||
int fd;
|
||||
if (strcasecmp(dname, "missing")==0) {
|
||||
if (first_missing > dnum)
|
||||
|
@ -219,11 +224,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
fail=1;
|
||||
continue;
|
||||
}
|
||||
if (!get_dev_size(fd, dname, &ldsize)) {
|
||||
fail = 1;
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
if (st == NULL) {
|
||||
struct createinfo *ci = conf_get_create_info();
|
||||
if (ci)
|
||||
|
@ -231,17 +231,22 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
}
|
||||
if (st == NULL) {
|
||||
/* Need to choose a default metadata, which is different
|
||||
* depending on the sizes of devices
|
||||
* depending on geometry of array.
|
||||
*/
|
||||
int i;
|
||||
char *name = "default";
|
||||
if (level >= 1 && ldsize > (0x7fffffffULL<<10))
|
||||
name = "default/large";
|
||||
for(i=0; !st && superlist[i]; i++)
|
||||
for(i=0; !st && superlist[i]; i++) {
|
||||
st = superlist[i]->match_metadata_desc(name);
|
||||
if (st && !st->ss->validate_geometry
|
||||
(st, level, layout, raiddisks,
|
||||
chunk, size, dname, &freesize))
|
||||
st = NULL;
|
||||
}
|
||||
|
||||
if (!st) {
|
||||
fprintf(stderr, Name ": internal error - no default metadata style\n");
|
||||
fprintf(stderr, Name ": device %s not suitable "
|
||||
"for any style of array\n",
|
||||
dname);
|
||||
exit(2);
|
||||
}
|
||||
if (st->ss->major != 0 ||
|
||||
|
@ -250,14 +255,19 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
" %d.%d metadata\n",
|
||||
st->ss->major,
|
||||
st->minor_version);
|
||||
}
|
||||
freesize = st->ss->avail_size(st, ldsize >> 9);
|
||||
if (freesize == 0) {
|
||||
fprintf(stderr, Name ": %s is too small: %luK\n",
|
||||
dname, (unsigned long)(ldsize>>10));
|
||||
fail = 1;
|
||||
close(fd);
|
||||
continue;
|
||||
} else {
|
||||
if (!st->ss->validate_geometry(st, level, layout,
|
||||
raiddisks,
|
||||
chunk, size, dname,
|
||||
&freesize)) {
|
||||
|
||||
fprintf(stderr,
|
||||
Name ": %s is not suitable for "
|
||||
"this array.\n",
|
||||
dname);
|
||||
fail = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
freesize /= 2; /* convert to K */
|
||||
|
@ -268,7 +278,8 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
|
||||
if (size && freesize < size) {
|
||||
fprintf(stderr, Name ": %s is smaller that given size."
|
||||
" %lluK < %lluK + superblock\n", dname, freesize, size);
|
||||
" %lluK < %lluK + metadata\n",
|
||||
dname, freesize, size);
|
||||
fail = 1;
|
||||
close(fd);
|
||||
continue;
|
||||
|
@ -581,7 +592,10 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
st->ss->free_super(st);
|
||||
|
||||
/* param is not actually used */
|
||||
if (runstop == 1 || subdevs >= raiddisks) {
|
||||
if (level == LEVEL_CONTAINER)
|
||||
/* No need to start */
|
||||
;
|
||||
else if (runstop == 1 || subdevs >= raiddisks) {
|
||||
mdu_param_t param;
|
||||
if (ioctl(mdfd, RUN_ARRAY, ¶m)) {
|
||||
fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
|
||||
|
|
1
ReadMe.c
1
ReadMe.c
|
@ -610,6 +610,7 @@ mapping_t pers[] = {
|
|||
{ "raid10", 10},
|
||||
{ "10", 10},
|
||||
{ "faulty", LEVEL_FAULTY},
|
||||
{ "container", LEVEL_CONTAINER},
|
||||
{ NULL, 0}
|
||||
};
|
||||
|
||||
|
|
7
mdadm.h
7
mdadm.h
|
@ -358,6 +358,10 @@ extern struct superswitch {
|
|||
void (*locate_bitmap)(struct supertype *st, int fd);
|
||||
int (*write_bitmap)(struct supertype *st, int fd);
|
||||
void (*free_super)(struct supertype *st);
|
||||
int (*validate_geometry)(struct supertype *st, int level, int layout,
|
||||
int raiddisks,
|
||||
int chunk, unsigned long long size,
|
||||
char *subdev, unsigned long long *freesize);
|
||||
int major;
|
||||
int swapuuid; /* true if uuid is bigending rather than hostendian */
|
||||
} super0, super1, *superlist[];
|
||||
|
@ -531,6 +535,9 @@ extern int open_mddev_devnum(char *devname, int devnum, char *name,
|
|||
#define LEVEL_LINEAR (-1)
|
||||
#define LEVEL_FAULTY (-5)
|
||||
|
||||
/* kernel module doesn't know about these */
|
||||
#define LEVEL_CONTAINER (-100)
|
||||
|
||||
|
||||
/* faulty stuff */
|
||||
|
||||
|
|
38
super0.c
38
super0.c
|
@ -991,6 +991,43 @@ static void free_super0(struct supertype *st)
|
|||
st->sb = NULL;
|
||||
}
|
||||
|
||||
static int validate_geometry0(struct supertype *st, int level,
|
||||
int layout, int raiddisks,
|
||||
int chunk, unsigned long long size,
|
||||
char *subdev, unsigned long long *freesize)
|
||||
{
|
||||
unsigned long long ldsize;
|
||||
int fd;
|
||||
|
||||
if (level == LEVEL_CONTAINER)
|
||||
return 0;
|
||||
if (raiddisks > MD_SB_DISKS)
|
||||
return 0;
|
||||
if (size > (0x7fffffffULL<<10))
|
||||
return 0;
|
||||
if (!subdev)
|
||||
return 1;
|
||||
|
||||
fd = open(subdev, O_RDONLY|O_EXCL, 0);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, Name ": Cannot open %s: %s\n",
|
||||
subdev, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (!get_dev_size(fd, subdev, &ldsize)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (ldsize < MD_RESERVED_SECTORS * 512)
|
||||
return 0;
|
||||
if (size > (0x7fffffffULL<<10))
|
||||
return 0;
|
||||
*freesize = MD_NEW_SIZE_SECTORS(ldsize >> 9);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct superswitch super0 = {
|
||||
#ifndef MDASSEMBLE
|
||||
.examine_super = examine_super0,
|
||||
|
@ -1016,6 +1053,7 @@ struct superswitch super0 = {
|
|||
.locate_bitmap = locate_bitmap0,
|
||||
.write_bitmap = write_bitmap0,
|
||||
.free_super = free_super0,
|
||||
.validate_geometry = validate_geometry0,
|
||||
.major = 0,
|
||||
.swapuuid = 0,
|
||||
};
|
||||
|
|
32
super1.c
32
super1.c
|
@ -1199,7 +1199,7 @@ static struct supertype *match_metadata_desc1(char *arg)
|
|||
return st;
|
||||
}
|
||||
if (strcmp(arg, "1") == 0 ||
|
||||
strcmp(arg, "default/large") == 0) {
|
||||
strcmp(arg, "default") == 0) {
|
||||
st->minor_version = -1;
|
||||
return st;
|
||||
}
|
||||
|
@ -1416,6 +1416,35 @@ static void free_super1(struct supertype *st)
|
|||
st->sb = NULL;
|
||||
}
|
||||
|
||||
static int validate_geometry1(struct supertype *st, int level,
|
||||
int layout, int raiddisks,
|
||||
int chunk, unsigned long long size,
|
||||
char *subdev, unsigned long long *freesize)
|
||||
{
|
||||
unsigned long long ldsize;
|
||||
int fd;
|
||||
|
||||
if (level == LEVEL_CONTAINER)
|
||||
return 0;
|
||||
if (!subdev)
|
||||
return 1;
|
||||
|
||||
fd = open(subdev, O_RDONLY|O_EXCL, 0);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, Name ": Cannot open %s: %s\n",
|
||||
subdev, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (!get_dev_size(fd, subdev, &ldsize)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
*freesize = avail_size1(st, ldsize >> 9);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct superswitch super1 = {
|
||||
#ifndef MDASSEMBLE
|
||||
.examine_super = examine_super1,
|
||||
|
@ -1441,6 +1470,7 @@ struct superswitch super1 = {
|
|||
.locate_bitmap = locate_bitmap1,
|
||||
.write_bitmap = write_bitmap1,
|
||||
.free_super = free_super1,
|
||||
.validate_geometry = validate_geometry1,
|
||||
.major = 1,
|
||||
#if __BYTE_ORDER == BIG_ENDIAN
|
||||
.swapuuid = 0,
|
||||
|
|
Loading…
Reference in New Issue