summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Create.c23
-rw-r--r--mdadm.h5
-rw-r--r--sysfs.c53
3 files changed, 70 insertions, 11 deletions
diff --git a/Create.c b/Create.c
index 15a5bfd..50da1ad 100644
--- a/Create.c
+++ b/Create.c
@@ -546,7 +546,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
"support external metadata.\n");
return 1;
}
- rv = 0;
+ rv = sysfs_set_array(sra, &info);
} else if ((vers % 100) >= 1) { /* can use different versions */
mdu_array_info_t inf;
memset(&inf, 0, sizeof(inf));
@@ -632,18 +632,19 @@ int Create(struct supertype *st, char *mddev, int mdfd,
fd, dv->devname);
break;
case 2:
- close(fd);
+ info.component_size = info.array.size * 2;
+ info.errors = 0;
+ rv = 0;
if (st->ss->external) {
- char dv[100];
- sprintf(dv, "%d:%d\n",
- info.disk.major,
- info.disk.minor);
- sysfs_set_str(sra, NULL, "new_dev", dv);
- /* FIXME check error */
- /*FIXME find that device and set it up*/
- } else if (ioctl(mdfd, ADD_NEW_DISK,
- &info.disk)) {
+ rv = sysfs_add_disk(sra, fd, &info);
+ close(fd);
+ } else {
+ close(fd);
+ rv = ioctl(mdfd, ADD_NEW_DISK,
+ &info.disk);
+ }
+ if (rv) {
fprintf(stderr,
Name ": ADD_NEW_DISK for %s "
"failed: %s\n",
diff --git a/mdadm.h b/mdadm.h
index 73881e2..93425b1 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -317,6 +317,11 @@ extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long val);
extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long *val);
+extern int sysfs_set_array(struct mdinfo *sra,
+ struct mdinfo *array);
+extern int sysfs_add_disk(struct mdinfo *sra, int fd, struct mdinfo *sd);
+
+
extern int save_stripes(int *source, unsigned long long *offsets,
diff --git a/sysfs.c b/sysfs.c
index 0255f88..6fa76fd 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -310,3 +310,56 @@ int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
return -1;
return 0;
}
+
+int sysfs_set_array(struct mdinfo *sra,
+ struct mdinfo *info)
+{
+ int rv = 0;
+ sra->array = info->array;
+ if (info->array.level < 0)
+ return 0; /* FIXME */
+ rv |= sysfs_set_str(sra, NULL, "level",
+ map_num(pers, info->array.level));
+ rv |= sysfs_set_num(sra, NULL, "raid_disks", info->array.raid_disks);
+ rv |= sysfs_set_num(sra, NULL, "chunk_size", info->array.chunk_size);
+ rv |= sysfs_set_num(sra, NULL, "layout", info->array.layout);
+ rv |= sysfs_set_num(sra, NULL, "component_size", info->component_size);
+ sra->array = info->array;
+ return rv;
+}
+
+int sysfs_add_disk(struct mdinfo *sra, int fd, struct mdinfo *sd)
+{
+ char dv[100];
+ char nm[100];
+ struct mdinfo *sd2;
+ char *dname;
+ int rv;
+
+ sprintf(dv, "%d:%d", sd->disk.major, sd->disk.minor);
+ rv = sysfs_set_str(sra, NULL, "new_dev", dv);
+ if (rv)
+ return rv;
+
+ memset(nm, 0, sizeof(nm));
+ sprintf(dv, "/sys/dev/block/%d:%d", sd->disk.major, sd->disk.minor);
+ if (readlink(dv, nm, sizeof(nm)) < 0)
+ return -1;
+ dname = strrchr(nm, '/');
+ if (dname) dname++;
+ strcpy(sd->sys_name, "dev-");
+ strcpy(sd->sys_name+4, dname);
+
+ rv |= sysfs_set_num(sra, sd, "offset", sd->data_offset);
+ rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2);
+ if (sra->array.level != LEVEL_CONTAINER) {
+ rv |= sysfs_set_num(sra, sd, "slot", sd->disk.raid_disk);
+// rv |= sysfs_set_str(sra, sd, "state", "in_sync");
+ }
+ sd2 = malloc(sizeof(*sd2));
+ *sd2 = *sd;
+ sd2->next = sra->devs;
+ sra->devs = sd2;
+
+ return rv;
+}