From 2f6079dc96180335fdb56d0b89e462e903abbb50 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Thu, 15 May 2008 16:48:21 +1000 Subject: [PATCH 1/1] Create a container member From: Neil Brown --- Create.c | 10 +++++++++- mdadm.h | 4 ++++ super-ddf.c | 5 ++++- sysfs.c | 3 ++- util.c | 23 +++++++++++++++++++++++ 5 files changed, 42 insertions(+), 3 deletions(-) diff --git a/Create.c b/Create.c index 0bc47380..c1d607fa 100644 --- a/Create.c +++ b/Create.c @@ -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", diff --git a/mdadm.h b/mdadm.h index 4c0e9e16..dae73cce 100644 --- a/mdadm.h +++ b/mdadm.h @@ -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 b494647e..69ca3201 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, diff --git a/sysfs.c b/sysfs.c index 6fa76fd2..8b5a6ff5 100644 --- a/sysfs.c +++ b/sysfs.c @@ -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", diff --git a/util.c b/util.c index 7b43ee2e..8ea30699 100644 --- a/util.c +++ b/util.c @@ -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; -- 2.39.2