summaryrefslogtreecommitdiffstats
path: root/super-intel.c
diff options
context:
space:
mode:
Diffstat (limited to 'super-intel.c')
-rw-r--r--super-intel.c117
1 files changed, 107 insertions, 10 deletions
diff --git a/super-intel.c b/super-intel.c
index d81d620..f0377b8 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -283,6 +283,7 @@ enum imsm_update_type {
update_activate_spare,
update_create_array,
update_kill_array,
+ update_rename_array,
update_add_disk,
};
@@ -309,6 +310,12 @@ struct imsm_update_kill_array {
int dev_idx;
};
+struct imsm_update_rename_array {
+ enum imsm_update_type type;
+ __u8 name[MAX_RAID_SERIAL_LEN];
+ int dev_idx;
+};
+
struct imsm_update_add_disk {
enum imsm_update_type type;
};
@@ -2939,6 +2946,30 @@ static void imsm_update_version_info(struct intel_super *super)
}
}
+static int check_name(struct intel_super *super, char *name, int quiet)
+{
+ struct imsm_super *mpb = super->anchor;
+ char *reason = NULL;
+ int i;
+
+ if (strlen(name) > MAX_RAID_SERIAL_LEN)
+ reason = "must be 16 characters or less";
+
+ for (i = 0; i < mpb->num_raid_devs; i++) {
+ struct imsm_dev *dev = get_imsm_dev(super, i);
+
+ if (strncmp((char *) dev->volume, name, MAX_RAID_SERIAL_LEN) == 0) {
+ reason = "already exists";
+ break;
+ }
+ }
+
+ if (reason && !quiet)
+ fprintf(stderr, Name ": imsm volume name %s\n", reason);
+
+ return !reason;
+}
+
static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
unsigned long long size, char *name,
char *homehost, int *uuid)
@@ -2990,16 +3021,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
if (super->current_vol == 0)
mpb->num_disks = 0;
- for (i = 0; i < super->current_vol; i++) {
- dev = get_imsm_dev(super, i);
- if (strncmp((char *) dev->volume, name,
- MAX_RAID_SERIAL_LEN) == 0) {
- fprintf(stderr, Name": '%s' is already defined for this container\n",
- name);
- return 0;
- }
- }
-
+ if (!check_name(super, name, 0))
+ return 0;
sprintf(st->subarray, "%d", idx);
dv = malloc(sizeof(*dv));
if (!dv) {
@@ -4107,6 +4130,54 @@ static int kill_subarray_imsm(struct supertype *st)
return 0;
}
+
+static int update_subarray_imsm(struct supertype *st, char *update, mddev_ident_t ident)
+{
+ /* update the subarray currently referenced by ->current_vol */
+ struct intel_super *super = st->sb;
+ struct imsm_super *mpb = super->anchor;
+
+ if (super->current_vol < 0)
+ return 2;
+
+ if (strcmp(update, "name") == 0) {
+ char *name = ident->name;
+
+ if (is_subarray_active(st->subarray, st->devname)) {
+ fprintf(stderr,
+ Name ": Unable to update name of active subarray\n");
+ return 2;
+ }
+
+ if (!check_name(super, name, 0))
+ return 2;
+
+ if (st->update_tail) {
+ struct imsm_update_rename_array *u = malloc(sizeof(*u));
+
+ if (!u)
+ return 2;
+ u->type = update_rename_array;
+ u->dev_idx = super->current_vol;
+ snprintf((char *) u->name, MAX_RAID_SERIAL_LEN, "%s", name);
+ append_metadata_update(st, u, sizeof(*u));
+ } else {
+ struct imsm_dev *dev;
+ int i;
+
+ dev = get_imsm_dev(super, super->current_vol);
+ snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name);
+ for (i = 0; i < mpb->num_raid_devs; i++) {
+ dev = get_imsm_dev(super, i);
+ handle_missing(super, dev);
+ }
+ super->updates_pending++;
+ }
+ } else
+ return 2;
+
+ return 0;
+}
#endif /* MDASSEMBLE */
static int is_rebuilding(struct imsm_dev *dev)
@@ -5217,6 +5288,31 @@ static void imsm_process_update(struct supertype *st,
super->updates_pending++;
break;
}
+ case update_rename_array: {
+ struct imsm_update_rename_array *u = (void *) update->buf;
+ char name[MAX_RAID_SERIAL_LEN+1];
+ int target = u->dev_idx;
+ struct active_array *a;
+ struct imsm_dev *dev;
+
+ /* sanity check that we are not affecting the uuid of
+ * an active array
+ */
+ snprintf(name, MAX_RAID_SERIAL_LEN, "%s", (char *) u->name);
+ name[MAX_RAID_SERIAL_LEN] = '\0';
+ for (a = st->arrays; a; a = a->next)
+ if (a->info.container_member == target)
+ break;
+ dev = get_imsm_dev(super, u->dev_idx);
+ if (a || !dev || !check_name(super, name, 1)) {
+ dprintf("failed to rename subarray-%d\n", target);
+ break;
+ }
+
+ snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, name);
+ super->updates_pending++;
+ break;
+ }
case update_add_disk:
/* we may be able to repair some arrays if disks are
@@ -5393,6 +5489,7 @@ struct superswitch super_imsm = {
.add_to_super = add_to_super_imsm,
.detail_platform = detail_platform_imsm,
.kill_subarray = kill_subarray_imsm,
+ .update_subarray = update_subarray_imsm,
#endif
.match_home = match_home_imsm,
.uuid_from_super= uuid_from_super_imsm,