diff options
author | Dan Williams <dan.j.williams@intel.com> | 2008-05-15 16:48:14 +1000 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2008-05-15 16:48:14 +1000 |
commit | a322f70c41a1c381e19b1913b8ad2a8b77078800 (patch) | |
tree | 8bc0b5968ad74979e6248d5a8ff7a0ed0f8cefbc /util.c | |
parent | d03373f1deea242eaacfab6b2b0c4afc6d7702d2 (diff) | |
download | mdadm-a322f70c41a1c381e19b1913b8ad2a8b77078800.tar.gz mdadm-a322f70c41a1c381e19b1913b8ad2a8b77078800.tar.xz mdadm-a322f70c41a1c381e19b1913b8ad2a8b77078800.zip |
Initial DDF support code.
Create a ddf array by naming the device /dev/ddf* or
specifying metadata 'ddf'.
If ddf is specified with no level, assume a container (indeed,
anything else would be wrong).
**Need to use text_Version to set external metadata...
More ddf support
Load a ddf container. Now
--examine /dev/ddf
works.
super-ddf: fix compile warning
From: Dan Williams <dan.j.williams@intel.com>
super-ddf.c:723: format %lu expects type long unsigned int, but argument 3 has type unsigned int
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 52 |
1 files changed, 51 insertions, 1 deletions
@@ -31,6 +31,7 @@ #include "md_p.h" #include <sys/utsname.h> #include <ctype.h> +#include <dirent.h> /* * following taken from linux/blkpg.h because they aren't @@ -759,7 +760,7 @@ int dev_open(char *dev, int flags) return fd; } -struct superswitch *superlist[] = { &super0, &super1, NULL }; +struct superswitch *superlist[] = { &super0, &super1, &super_ddf, NULL }; #if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO) struct supertype *super_by_fd(int fd) @@ -908,6 +909,55 @@ void get_one_disk(int mdfd, mdu_array_info_t *ainf, mdu_disk_info_t *disk) return; } +int open_container(int fd) +{ + /* 'fd' is a block device. Find out if it is in use + * by a container, and return an open fd on that container. + */ + char path[256]; + char *e; + DIR *dir; + struct dirent *de; + int dfd, n; + char buf[200]; + int major, minor; + struct stat st; + + if (fstat(fd, &st) != 0) + return -1; + sprintf(path, "/sys/dev/block/%d:%d/holders", + (int)major(st.st_rdev), (int)minor(st.st_rdev)); + e = path + strlen(path); + + dir = opendir(path); + if (!dir) + return -1; + while ((de = readdir(dir))) { + if (de->d_ino == 0) + continue; + if (de->d_name[0] == '.') + continue; + sprintf(e, "/%s/dev", de->d_name); + dfd = open(path, O_RDONLY); + if (dfd < 0) + continue; + n = read(dfd, buf, sizeof(buf)); + close(dfd); + if (n <= 0 || n >= sizeof(buf)) + continue; + buf[n] = 0; + if (sscanf(buf, "%d:%d", &major, &minor) != 2) + continue; + sprintf(buf, "%d:%d", major, minor); + dfd = dev_open(buf, O_RDONLY); + if (dfd >= 0) { + closedir(dir); + return dfd; + } + } + return -1; +} + #ifdef __TINYC__ /* tinyc doesn't optimize this check in ioctl.h out ... */ unsigned int __invalid_size_argument_for_IOC = 0; |