]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Create.c
Move calls to SET_ARRAY_INFO to common helper.
[thirdparty/mdadm.git] / Create.c
index 692a74ccde8e452533e0d069e88359d651c5267d..652bc1c761cbdd7e9a30839f33f29000e7d95a32 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -72,12 +72,12 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        int rv;
        int bitmap_fd;
        int have_container = 0;
-       int container_fd;
+       int container_fd = -1;
        int need_mdmon = 0;
        unsigned long long bitmapsize;
-       struct mdinfo *sra;
        struct mdinfo info, *infos;
        int did_default = 0;
+       unsigned long safe_mode_delay = 0;
 
        int major_num = BITMAP_MAJOR_HI;
 
@@ -139,7 +139,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                int fd;
 
                memset(&inf, 0, sizeof(inf));
-               fd = open(devlist->devname, O_RDONLY, 0);
+               fd = open(devlist->devname, O_RDONLY);
                if (fd >= 0 &&
                    ioctl(fd, GET_ARRAY_INFO, &inf) == 0 &&
                    inf.raid_disks == 0) {
@@ -333,7 +333,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        minsize = freesize;
                }
                if (runstop != 1 || verbose >= 0) {
-                       int fd = open(dname, O_RDONLY, 0);
+                       int fd = open(dname, O_RDONLY);
                        if (fd <0 ) {
                                fprintf(stderr, Name ": Cannot open %s: %s\n",
                                        dname, strerror(errno));
@@ -520,10 +520,11 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                return 1;
 
        total_slots = info.array.nr_disks;
+       sysfs_init(&info, mdfd, 0);
        st->ss->getinfo_super(st, &info);
 
        if (did_default && verbose >= 0) {
-               if (info.text_version[0] == '/') {
+               if (is_subarray(info.text_version)) {
                        int dnum = devname2devnum(info.text_version+1);
                        char *path;
                        int mdp = get_mdp_major();
@@ -567,61 +568,41 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        }
 
 
-       sra = sysfs_read(mdfd, 0, 0);
+       sysfs_init(&info, mdfd, 0);
 
-       if (st->ss->external) {
-               char ver[100];
-               strcat(strcpy(ver, "external:"),
-                      info.text_version);
-               if (st->ss->external && st->subarray[0]) {
-                       /* member */
-
-                       /* When creating a member, we need to be careful
-                        * to negotiate with mdmon properly.
-                        * If it is already running, we cannot write to
-                        * the devices and must ask it to do that part.
-                        * If it isn't running, we write to the devices,
-                        * and then start it.
-                        * We hold an exclusive open on the container
-                        * device to make sure mdmon doesn't exit after
-                        * we checked that it is running.
-                        *
-                        * For now, fail if it is already running.
-                        */
-                       container_fd = open_dev_excl(st->container_dev);
-                       if (container_fd < 0) {
-                               fprintf(stderr, Name ": Cannot get exclusive "
-                                       "open on container - weird.\n");
-                               return 1;
-                       }
-                       if (mdmon_running(st->container_dev)) {
-                               if (verbose)
-                                       fprintf(stderr, Name ": reusing mdmon "
-                                               "for %s.\n",
-                                               devnum2devname(st->container_dev));
-                               st->update_tail = &st->updates;
-                       } else
-                               need_mdmon = 1;
-               }
-               if ((vers % 100) < 2 ||
-                   sra == NULL ||
-                   sysfs_set_str(sra, NULL, "metadata_version",
-                                 ver) < 0) {
-                       fprintf(stderr, Name ": This kernel does not "
-                               "support external metadata.\n");
+       if (st->ss->external && st->subarray[0]) {
+               /* member */
+
+               /* When creating a member, we need to be careful
+                * to negotiate with mdmon properly.
+                * If it is already running, we cannot write to
+                * the devices and must ask it to do that part.
+                * If it isn't running, we write to the devices,
+                * and then start it.
+                * We hold an exclusive open on the container
+                * device to make sure mdmon doesn't exit after
+                * we checked that it is running.
+                *
+                * For now, fail if it is already running.
+                */
+               container_fd = open_dev_excl(st->container_dev);
+               if (container_fd < 0) {
+                       fprintf(stderr, Name ": Cannot get exclusive "
+                               "open on container - weird.\n");
                        return 1;
                }
-               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));
-               inf.major_version = info.array.major_version;
-               inf.minor_version = info.array.minor_version;
-               rv = ioctl(mdfd, SET_ARRAY_INFO, &inf);
-       } else
-               rv = ioctl(mdfd, SET_ARRAY_INFO, NULL);
+               if (mdmon_running(st->container_dev)) {
+                       if (verbose)
+                               fprintf(stderr, Name ": reusing mdmon "
+                                       "for %s.\n",
+                                       devnum2devname(st->container_dev));
+                       st->update_tail = &st->updates;
+               } else
+                       need_mdmon = 1;
+       }
+       rv = set_array_info(mdfd, st, &info);
        if (rv) {
-               fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n",
+               fprintf(stderr, Name ": failed to set array info for %s: %s\n",
                        mddev, strerror(errno));
                return 1;
        }
@@ -685,9 +666,9 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                        inf->disk.state |= (1<<MD_DISK_WRITEMOSTLY);
 
                                if (st->ss->external && st->subarray[0])
-                                       fd = open(dv->devname, O_RDWR, 0);
+                                       fd = open(dv->devname, O_RDWR);
                                else
-                                       fd = open(dv->devname, O_RDWR|O_EXCL,0);
+                                       fd = open(dv->devname, O_RDWR|O_EXCL);
 
                                if (fd < 0) {
                                        fprintf(stderr, Name ": failed to open %s "
@@ -703,6 +684,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                st->ss->add_to_super(st, &inf->disk,
                                                     fd, dv->devname);
                                st->ss->getinfo_super(st, inf);
+                               safe_mode_delay = inf->safe_mode_delay;
 
                                /* getinfo_super might have lost these ... */
                                inf->disk.major = major(stb.st_rdev);
@@ -712,11 +694,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                inf->errors = 0;
                                rv = 0;
 
-                               if (st->ss->external)
-                                       rv = sysfs_add_disk(sra, inf);
-                               else
-                                       rv = ioctl(mdfd, ADD_NEW_DISK,
-                                                  &inf->disk);
+                               rv = add_disk(mdfd, st, &info, inf);
 
                                if (rv) {
                                        fprintf(stderr,
@@ -748,15 +726,16 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        case LEVEL_LINEAR:
                        case LEVEL_MULTIPATH:
                        case 0:
-                               sysfs_set_str(sra, NULL, "array_state",
+                               sysfs_set_str(&info, NULL, "array_state",
                                              "active");
                                need_mdmon = 0;
                                break;
                        default:
-                               sysfs_set_str(sra, NULL, "array_state",
+                               sysfs_set_str(&info, NULL, "array_state",
                                              "readonly");
                                break;
                        }
+                       sysfs_set_safemode(&info, safe_mode_delay);
                } else {
                        mdu_param_t param;
                        if (ioctl(mdfd, RUN_ARRAY, &param)) {