X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=super-intel.c;h=f0377b814c946d9b52ec41a033c87e5c91975d4d;hb=aa534678baad80689a642ba1bd602a00a267ac03;hp=d81d620dcecfd3e02796e39dd234a821e4216bb6;hpb=33414a0182ae193150f65f7bca97a7e4d818a49e;p=thirdparty%2Fmdadm.git diff --git a/super-intel.c b/super-intel.c index d81d620d..f0377b81 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,