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,
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);
}
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;
}
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);
}
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];
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);
}
}
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);
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);
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];
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);
}
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;
}
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))
}
}
-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;
* 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++)
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);
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,
* 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,
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,
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;
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:
* 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 &&
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)
dev->curr_state = DS_FAULTY;
}
}
- a->info.container_member = n;
+ a->info.container_member = inst;
return 0;
}
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;
/*
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;
*/
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;
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;
.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,
.default_geometry = default_geometry_ddf,
.external = 1,
+ .swapuuid = 0,
/* for mdmon */
.open_new = ddf_open_new,