]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-ddf.c
Create.c: fix uclibc build
[thirdparty/mdadm.git] / super-ddf.c
index 618542c4b7dd5bc037b434317ea365bf7b753df9..21426c753c6dff4d9dfdba152bb2fb8ac503f107 100644 (file)
@@ -503,13 +503,6 @@ struct ddf_super {
 static int load_super_ddf_all(struct supertype *st, int fd,
                              void **sbp, char *devname);
 static int get_svd_state(const struct ddf_super *, const struct vcl *);
-static int
-validate_geometry_ddf_container(struct supertype *st,
-                               int level, int layout, int raiddisks,
-                               int chunk, unsigned long long size,
-                               unsigned long long data_offset,
-                               char *dev, unsigned long long *freesize,
-                               int verbose);
 
 static int validate_geometry_ddf_bvd(struct supertype *st,
                                     int level, int layout, int raiddisks,
@@ -1477,13 +1470,13 @@ static void examine_vds(struct ddf_super *sb)
                printf("\n");
                printf("         unit[%d] : %d\n", i, be16_to_cpu(ve->unit));
                printf("        state[%d] : %s, %s%s\n", i,
-                      map_num(ddf_state, ve->state & 7),
+                      map_num_s(ddf_state, ve->state & 7),
                       (ve->state & DDF_state_morphing) ? "Morphing, ": "",
                       (ve->state & DDF_state_inconsistent)? "Not Consistent" : "Consistent");
                printf("   init state[%d] : %s\n", i,
-                      map_num(ddf_init_state, ve->init_state&DDF_initstate_mask));
+                      map_num_s(ddf_init_state, ve->init_state & DDF_initstate_mask));
                printf("       access[%d] : %s\n", i,
-                      map_num(ddf_access, (ve->init_state & DDF_access_mask) >> 6));
+                      map_num_s(ddf_access, (ve->init_state & DDF_access_mask) >> 6));
                printf("         Name[%d] : %.16s\n", i, ve->name);
                examine_vd(i, sb, ve->guid);
        }
@@ -1599,15 +1592,20 @@ static unsigned int get_vd_num_of_subarray(struct supertype *st)
        sra = sysfs_read(-1, st->devnm, GET_VERSION);
        if (!sra || sra->array.major_version != -1 ||
            sra->array.minor_version != -2 ||
-           !is_subarray(sra->text_version))
+           !is_subarray(sra->text_version)) {
+               if (sra)
+                       sysfs_free(sra);
                return DDF_NOTFOUND;
+       }
 
        sub = strchr(sra->text_version + 1, '/');
        if (sub != NULL)
                vcnum = strtoul(sub + 1, &end, 10);
        if (sub == NULL || *sub == '\0' || *end != '\0' ||
-           vcnum >= be16_to_cpu(ddf->active->max_vd_entries))
+           vcnum >= be16_to_cpu(ddf->active->max_vd_entries)) {
+               sysfs_free(sra);
                return DDF_NOTFOUND;
+       }
 
        return vcnum;
 }
@@ -1619,7 +1617,7 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose)
        struct mdinfo info;
        char nbuf[64];
        getinfo_super_ddf(st, &info, NULL);
-       fname_from_uuid(st, &info, nbuf, ':');
+       fname_from_uuid(&info, nbuf);
 
        printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
 }
@@ -1634,7 +1632,7 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
        unsigned int i;
        char nbuf[64];
        getinfo_super_ddf(st, &info, NULL);
-       fname_from_uuid(st, &info, nbuf, ':');
+       fname_from_uuid(&info, nbuf);
 
        for (i = 0; i < be16_to_cpu(ddf->virt->max_vdes); i++) {
                struct virtual_entry *ve = &ddf->virt->entries[i];
@@ -1647,10 +1645,10 @@ static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
                ddf->currentconf =&vcl;
                vcl.vcnum = i;
                uuid_from_super_ddf(st, info.uuid);
-               fname_from_uuid(st, &info, nbuf1, ':');
+               fname_from_uuid(&info, nbuf1);
                _ddf_array_name(namebuf, ddf, i);
                printf("ARRAY%s%s container=%s member=%d UUID=%s\n",
-                      namebuf[0] == '\0' ? "" : " /dev/md/", namebuf,
+                      namebuf[0] == '\0' ? "" : " " DEV_MD_DIR, namebuf,
                       nbuf+5, i, nbuf1+5);
        }
 }
@@ -1660,7 +1658,7 @@ static void export_examine_super_ddf(struct supertype *st)
        struct mdinfo info;
        char nbuf[64];
        getinfo_super_ddf(st, &info, NULL);
-       fname_from_uuid(st, &info, nbuf, ':');
+       fname_from_uuid(&info, nbuf);
        printf("MD_METADATA=ddf\n");
        printf("MD_LEVEL=container\n");
        printf("MD_UUID=%s\n", nbuf+5);
@@ -1730,7 +1728,8 @@ err:
        return 1;
 }
 
-static void detail_super_ddf(struct supertype *st, char *homehost)
+static void detail_super_ddf(struct supertype *st, char *homehost,
+                            char *subarray)
 {
        struct ddf_super *sb = st->sb;
        int cnt = be16_to_cpu(sb->virt->populated_vdes);
@@ -1787,7 +1786,7 @@ static void uuid_of_ddf_subarray(const struct ddf_super *ddf,
        memcpy(uuid, sha, 4*4);
 }
 
-static void brief_detail_super_ddf(struct supertype *st)
+static void brief_detail_super_ddf(struct supertype *st, char *subarray)
 {
        struct mdinfo info;
        char nbuf[64];
@@ -1799,7 +1798,7 @@ static void brief_detail_super_ddf(struct supertype *st)
                return;
        else
                uuid_of_ddf_subarray(ddf, vcnum, info.uuid);
-       fname_from_uuid(st, &info, nbuf,':');
+       fname_from_uuid(&info, nbuf);
        printf(" UUID=%s", nbuf + 5);
 }
 
@@ -1900,7 +1899,7 @@ static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst,
                return conf;
        }
 bad:
-       pr_err("Could't find disk %d in array %u\n", n, inst);
+       pr_err("Couldn't find disk %d in array %u\n", n, inst);
        return NULL;
 }
 
@@ -1985,12 +1984,14 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
                info->disk.number = be32_to_cpu(ddf->dlist->disk.refnum);
                info->disk.raid_disk = find_phys(ddf, ddf->dlist->disk.refnum);
 
+               if (info->disk.raid_disk < 0)
+                       return;
+
                info->data_offset = be64_to_cpu(ddf->phys->
                                                  entries[info->disk.raid_disk].
                                                  config_size);
                info->component_size = ddf->dlist->size - info->data_offset;
-               if (info->disk.raid_disk >= 0)
-                       pde = ddf->phys->entries + info->disk.raid_disk;
+               pde = ddf->phys->entries + info->disk.raid_disk;
                if (pde &&
                    !(be16_to_cpu(pde->state) & DDF_Failed) &&
                    !(be16_to_cpu(pde->state) & DDF_Missing))
@@ -2145,75 +2146,6 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
                }
 }
 
-static int update_super_ddf(struct supertype *st, struct mdinfo *info,
-                           char *update,
-                           char *devname, int verbose,
-                           int uuid_set, char *homehost)
-{
-       /* For 'assemble' and 'force' we need to return non-zero if any
-        * change was made.  For others, the return value is ignored.
-        * Update options are:
-        *  force-one : This device looks a bit old but needs to be included,
-        *        update age info appropriately.
-        *  assemble: clear any 'faulty' flag to allow this device to
-        *              be assembled.
-        *  force-array: Array is degraded but being forced, mark it clean
-        *         if that will be needed to assemble it.
-        *
-        *  newdev:  not used ????
-        *  grow:  Array has gained a new device - this is currently for
-        *              linear only
-        *  resync: mark as dirty so a resync will happen.
-        *  uuid:  Change the uuid of the array to match what is given
-        *  homehost:  update the recorded homehost
-        *  name:  update the name - preserving the homehost
-        *  _reshape_progress: record new reshape_progress position.
-        *
-        * Following are not relevant for this version:
-        *  sparc2.2 : update from old dodgey metadata
-        *  super-minor: change the preferred_minor number
-        *  summaries:  update redundant counters.
-        */
-       int rv = 0;
-//     struct ddf_super *ddf = st->sb;
-//     struct vd_config *vd = find_vdcr(ddf, info->container_member);
-//     struct virtual_entry *ve = find_ve(ddf);
-
-       /* we don't need to handle "force-*" or "assemble" as
-        * there is no need to 'trick' the kernel.  When the metadata is
-        * first updated to activate the array, all the implied modifications
-        * will just happen.
-        */
-
-       if (strcmp(update, "grow") == 0) {
-               /* FIXME */
-       } else if (strcmp(update, "resync") == 0) {
-//             info->resync_checkpoint = 0;
-       } else if (strcmp(update, "homehost") == 0) {
-               /* homehost is stored in controller->vendor_data,
-                * or it is when we are the vendor
-                */
-//             if (info->vendor_is_local)
-//                     strcpy(ddf->controller.vendor_data, homehost);
-               rv = -1;
-       } else if (strcmp(update, "name") == 0) {
-               /* name is stored in virtual_entry->name */
-//             memset(ve->name, ' ', 16);
-//             strncpy(ve->name, info->name, 16);
-               rv = -1;
-       } else if (strcmp(update, "_reshape_progress") == 0) {
-               /* We don't support reshape yet */
-       } else if (strcmp(update, "assemble") == 0 ) {
-               /* Do nothing, just succeed */
-               rv = 0;
-       } else
-               rv = -1;
-
-//     update_all_csum(ddf);
-
-       return rv;
-}
-
 static void make_header_guid(char *guid)
 {
        be32 stamp;
@@ -2434,8 +2366,7 @@ static int init_super_ddf(struct supertype *st,
         * Remaining 16 are serial number.... maybe a hostname would do?
         */
        memcpy(ddf->controller.guid, T10, sizeof(T10));
-       gethostname(hostname, sizeof(hostname));
-       hostname[sizeof(hostname) - 1] = 0;
+       s_gethostname(hostname, sizeof(hostname));
        hostlen = strlen(hostname);
        memcpy(ddf->controller.guid + 24 - hostlen, hostname, hostlen);
        for (i = strlen(T10) ; i+hostlen < 24; i++)
@@ -2636,9 +2567,11 @@ static int init_super_ddf_bvd(struct supertype *st,
                ve->init_state = DDF_init_not;
 
        memset(ve->pad1, 0xff, 14);
-       memset(ve->name, ' ', 16);
-       if (name)
-               strncpy(ve->name, name, 16);
+       memset(ve->name, '\0', sizeof(ve->name));
+       if (name) {
+               int l = strnlen(name, sizeof(ve->name));
+               memcpy(ve->name, name, l);
+       }
        ddf->virt->populated_vdes =
                cpu_to_be16(be16_to_cpu(ddf->virt->populated_vdes)+1);
 
@@ -3319,6 +3252,42 @@ static int reserve_space(struct supertype *st, int raiddisks,
        return 1;
 }
 
+static int
+validate_geometry_ddf_container(struct supertype *st,
+                               int level, int raiddisks,
+                               unsigned long long data_offset,
+                               char *dev, unsigned long long *freesize,
+                               int verbose)
+{
+       int fd;
+       unsigned long long ldsize;
+
+       if (!is_container(level))
+               return 0;
+       if (!dev)
+               return 1;
+
+       fd = dev_open(dev, O_RDONLY|O_EXCL);
+       if (fd < 0) {
+               if (verbose)
+                       pr_err("ddf: Cannot open %s: %s\n",
+                              dev, strerror(errno));
+               return 0;
+       }
+       if (!get_dev_size(fd, dev, &ldsize)) {
+               close(fd);
+               return 0;
+       }
+       close(fd);
+       if (freesize) {
+               *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS);
+               if (*freesize == 0)
+                       return 0;
+       }
+
+       return 1;
+}
+
 static int validate_geometry_ddf(struct supertype *st,
                                 int level, int layout, int raiddisks,
                                 int *chunk, unsigned long long size,
@@ -3337,20 +3306,18 @@ static int validate_geometry_ddf(struct supertype *st,
         * If given BVDs, we make an SVD, changing all the GUIDs in the process.
         */
 
-       if (*chunk == UnSet)
-               *chunk = DEFAULT_CHUNK;
-
        if (level == LEVEL_NONE)
                level = LEVEL_CONTAINER;
-       if (level == LEVEL_CONTAINER) {
+       if (is_container(level)) {
                /* Must be a fresh device to add to a container */
-               return validate_geometry_ddf_container(st, level, layout,
-                                                      raiddisks, *chunk,
-                                                      size, data_offset, dev,
-                                                      freesize,
-                                                      verbose);
+               return validate_geometry_ddf_container(st, level, raiddisks,
+                                                      data_offset, dev,
+                                                      freesize, verbose);
        }
 
+       if (*chunk == UnSet)
+               *chunk = DEFAULT_CHUNK;
+
        if (!dev) {
                mdu_array_info_t array = {
                        .level = level,
@@ -3446,42 +3413,6 @@ static int validate_geometry_ddf(struct supertype *st,
        return 1;
 }
 
-static int
-validate_geometry_ddf_container(struct supertype *st,
-                               int level, int layout, int raiddisks,
-                               int chunk, unsigned long long size,
-                               unsigned long long data_offset,
-                               char *dev, unsigned long long *freesize,
-                               int verbose)
-{
-       int fd;
-       unsigned long long ldsize;
-
-       if (level != LEVEL_CONTAINER)
-               return 0;
-       if (!dev)
-               return 1;
-
-       fd = open(dev, O_RDONLY|O_EXCL, 0);
-       if (fd < 0) {
-               if (verbose)
-                       pr_err("ddf: Cannot open %s: %s\n",
-                              dev, strerror(errno));
-               return 0;
-       }
-       if (!get_dev_size(fd, dev, &ldsize)) {
-               close(fd);
-               return 0;
-       }
-       close(fd);
-
-       *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS);
-       if (*freesize == 0)
-               return 0;
-
-       return 1;
-}
-
 static int validate_geometry_ddf_bvd(struct supertype *st,
                                     int level, int layout, int raiddisks,
                                     int *chunk, unsigned long long size,
@@ -3494,7 +3425,7 @@ static int validate_geometry_ddf_bvd(struct supertype *st,
        struct dl *dl;
        unsigned long long maxsize;
        /* ddf/bvd supports lots of things, but not containers */
-       if (level == LEVEL_CONTAINER) {
+       if (is_container(level)) {
                if (verbose)
                        pr_err("DDF cannot create a container within an container\n");
                return 0;
@@ -3913,7 +3844,8 @@ static int store_super_ddf(struct supertype *st, int fd)
        return 0;
 }
 
-static int compare_super_ddf(struct supertype *st, struct supertype *tst)
+static int compare_super_ddf(struct supertype *st, struct supertype *tst,
+                            int verbose)
 {
        /*
         * return:
@@ -4054,20 +3986,19 @@ static int compare_super_ddf(struct supertype *st, struct supertype *tst)
  * We need to confirm that the array matches the metadata in 'c' so
  * that we don't corrupt any metadata.
  */
-static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst)
+static int ddf_open_new(struct supertype *c, struct active_array *a, int inst)
 {
        struct ddf_super *ddf = c->sb;
-       int n = atoi(inst);
        struct mdinfo *dev;
        struct dl *dl;
        static const char faulty[] = "faulty";
 
-       if (all_ff(ddf->virt->entries[n].guid)) {
-               pr_err("subarray %d doesn't exist\n", n);
+       if (all_ff(ddf->virt->entries[inst].guid)) {
+               pr_err("subarray %d doesn't exist\n", inst);
                return -ENODEV;
        }
-       dprintf("new subarray %d, GUID: %s\n", n,
-               guid_str(ddf->virt->entries[n].guid));
+       dprintf("new subarray %d, GUID: %s\n", inst,
+               guid_str(ddf->virt->entries[inst].guid));
        for (dev = a->info.devs; dev; dev = dev->next) {
                for (dl = ddf->dlist; dl; dl = dl->next)
                        if (dl->major == dev->disk.major &&
@@ -4075,13 +4006,13 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst)
                                break;
                if (!dl || dl->pdnum < 0) {
                        pr_err("device %d/%d of subarray %d not found in meta data\n",
-                               dev->disk.major, dev->disk.minor, n);
+                               dev->disk.major, dev->disk.minor, inst);
                        return -1;
                }
                if ((be16_to_cpu(ddf->phys->entries[dl->pdnum].state) &
                        (DDF_Online|DDF_Missing|DDF_Failed)) != DDF_Online) {
                        pr_err("new subarray %d contains broken device %d/%d (%02x)\n",
-                              n, dl->major, dl->minor,
+                              inst, dl->major, dl->minor,
                               be16_to_cpu(ddf->phys->entries[dl->pdnum].state));
                        if (write(dev->state_fd, faulty, sizeof(faulty)-1) !=
                            sizeof(faulty) - 1)
@@ -4089,7 +4020,7 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst)
                        dev->curr_state = DS_FAULTY;
                }
        }
-       a->info.container_member = n;
+       a->info.container_member = inst;
        return 0;
 }
 
@@ -4445,7 +4376,7 @@ static int _kill_subarray_ddf(struct ddf_super *ddf, const char *guid)
        return 0;
 }
 
-static int kill_subarray_ddf(struct supertype *st)
+static int kill_subarray_ddf(struct supertype *st, char *subarray_id)
 {
        struct ddf_super *ddf = st->sb;
        /*
@@ -4910,7 +4841,7 @@ static int raid10_degraded(struct mdinfo *info)
                        pr_err("BUG: invalid raid disk\n");
                        goto out;
                }
-               if (d->state_fd > 0)
+               if (is_fd_valid(d->state_fd))
                        found[i]++;
        }
        ret = 2;
@@ -5121,13 +5052,16 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
         */
        vc = find_vdcr(ddf, a->info.container_member, rv->disk.raid_disk,
                       &n_bvd, &vcl);
-       if (vc == NULL)
+       if (vc == NULL) {
+               free(rv);
                return NULL;
+       }
 
        mu = xmalloc(sizeof(*mu));
        if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) {
                free(mu);
-               mu = NULL;
+               free(rv);
+               return NULL;
        }
 
        mu->len = ddf->conf_rec_len * 512 * vcl->conf.sec_elmnt_count;
@@ -5157,6 +5091,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
                        pr_err("BUG: can't find disk %d (%d/%d)\n",
                               di->disk.raid_disk,
                               di->disk.major, di->disk.minor);
+                       free(mu);
+                       free(rv);
                        return NULL;
                }
                vc->phys_refnum[i_prim] = ddf->phys->entries[dl->pdnum].refnum;
@@ -5212,7 +5148,6 @@ struct superswitch super_ddf = {
        .match_home     = match_home_ddf,
        .uuid_from_super= uuid_from_super_ddf,
        .getinfo_super  = getinfo_super_ddf,
-       .update_super   = update_super_ddf,
 
        .avail_size     = avail_size_ddf,
 
@@ -5227,6 +5162,7 @@ struct superswitch super_ddf = {
        .default_geometry = default_geometry_ddf,
 
        .external       = 1,
+       .swapuuid       = 0,
 
 /* for mdmon */
        .open_new       = ddf_open_new,