diff options
author | Neil Brown <neilb@suse.de> | 2008-05-15 16:48:21 +1000 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2008-05-15 16:48:21 +1000 |
commit | 2f6079dc96180335fdb56d0b89e462e903abbb50 (patch) | |
tree | c643ba942b6a7a2ccb100e3707eed3d139b5253d | |
parent | 598f0d58ac3544e25f90f2d34337e15764f4d877 (diff) | |
download | mdadm-2f6079dc96180335fdb56d0b89e462e903abbb50.tar.gz mdadm-2f6079dc96180335fdb56d0b89e462e903abbb50.tar.xz mdadm-2f6079dc96180335fdb56d0b89e462e903abbb50.zip |
Create a container member
From: Neil Brown <neilb@suse.de>
-rw-r--r-- | Create.c | 10 | ||||
-rw-r--r-- | mdadm.h | 4 | ||||
-rw-r--r-- | super-ddf.c | 5 | ||||
-rw-r--r-- | sysfs.c | 3 | ||||
-rw-r--r-- | util.c | 23 |
5 files changed, 42 insertions, 3 deletions
@@ -537,7 +537,15 @@ int Create(struct supertype *st, char *mddev, int mdfd, if (st->ss->external) { char ver[100]; - strcat(strcpy(ver, "external:"), st->ss->text_version); + if (st->ss->external == 1) + /* container */ + strcat(strcpy(ver, "external:"), st->ss->text_version); + else { + /* member */ + sprintf(ver, "external:/%s/%d", + devnum2devname(st->container_dev), + st->container_member); + } if ((vers % 100) < 2 || sra == NULL || sysfs_set_str(sra, NULL, "metadata_version", @@ -397,6 +397,8 @@ struct supertype { struct superswitch *ss; int minor_version; int max_devs; + int container_dev; /* devnum of container */ + int container_member; /* numerical position in container */ void *sb; void *info; }; @@ -563,6 +565,8 @@ extern int open_mddev_devnum(char *devname, int devnum, char *name, char *chosen_name, int parts); extern int open_container(int fd); +extern char *devnum2devname(int num); +extern int fd2devnum(int fd); #define LEVEL_MULTIPATH (-4) #define LEVEL_LINEAR (-1) diff --git a/super-ddf.c b/super-ddf.c index b494647..69ca320 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -416,7 +416,7 @@ struct ddf_super { #define offsetof(t,f) ((size_t)&(((t*)0)->f)) #endif -struct superswitch super_ddf_container, super_ddf_bvd; +extern struct superswitch super_ddf_container, super_ddf_bvd; static int calc_crc(void *buf, int len) { @@ -1657,6 +1657,7 @@ static int init_super_ddf_bvd(struct supertype *st, return 0; } ve = &ddf->virt->entries[venum]; + st->container_member = venum; /* A Virtual Disk GUID contains the T10 Vendor ID, controller type, * timestamp, random number @@ -2023,6 +2024,8 @@ int validate_geometry_ddf(struct supertype *st, st->ss = &super_ddf_bvd; if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL, 1) == 0) { st->sb = ddf; + st->container_dev = fd2devnum(cfd); + st->container_member = 27; // FIXME close(cfd); return st->ss->validate_geometry(st, level, layout, raiddisks, chunk, size, @@ -34,7 +34,7 @@ int load_sys(char *path, char *buf) return -1; n = read(fd, buf, 1024); close(fd); - if (n <=0 || n >= 1024) + if (n <0 || n >= 1024) return -1; buf[n] = 0; if (buf[n-1] == '\n') @@ -316,6 +316,7 @@ int sysfs_set_array(struct mdinfo *sra, { int rv = 0; sra->array = info->array; + if (info->array.level < 0) return 0; /* FIXME */ rv |= sysfs_set_str(sra, NULL, "level", @@ -978,6 +978,29 @@ int open_container(int fd) return -1; } +char *devnum2devname(int num) +{ + char name[100]; + if (num > 0) + sprintf(name, "md%d", num); + else + sprintf(name, "md_d%d", -1-num); + return strdup(name); +} + +int fd2devnum(int fd) +{ + struct stat stb; + if (fstat(fd, &stb) == 0 && + (S_IFMT&stb.st_mode)==S_IFBLK) { + if (major(stb.st_rdev) == MD_MAJOR) + return minor(stb.st_rdev); + else + return -1- (minor(stb.st_rdev)>>6); + } + return -1; +} + #ifdef __TINYC__ /* tinyc doesn't optimize this check in ioctl.h out ... */ unsigned int __invalid_size_argument_for_IOC = 0; |