imsm: add --update=uuid support
When disks have conflicting container memberships (same container ids but incompatible member arrays) --update=uuid can be used to move offenders to a new container id by changing 'orig_family_num'. Note that this only supports random updates of the uuid as the actual uuid is synthesized. We also need to communicate the new 'orig_family_num' value to all disks involved in the update. A new field 'update_private' is added to struct mdinfo to allow this information to be transmitted. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
955e9ea139
commit
6e46bf344b
|
@ -565,6 +565,7 @@ int Assemble(struct supertype *st, char *mddev,
|
||||||
#endif
|
#endif
|
||||||
/* Ok, no bad inconsistancy, we can try updating etc */
|
/* Ok, no bad inconsistancy, we can try updating etc */
|
||||||
bitmap_done = 0;
|
bitmap_done = 0;
|
||||||
|
content->update_private = NULL;
|
||||||
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
|
for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
|
||||||
char *devname = tmpdev->devname;
|
char *devname = tmpdev->devname;
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
|
@ -717,6 +718,8 @@ int Assemble(struct supertype *st, char *mddev,
|
||||||
}
|
}
|
||||||
devcnt++;
|
devcnt++;
|
||||||
}
|
}
|
||||||
|
free(content->update_private);
|
||||||
|
content->update_private = NULL;
|
||||||
|
|
||||||
if (devcnt == 0) {
|
if (devcnt == 0) {
|
||||||
fprintf(stderr, Name ": no devices found for %s\n",
|
fprintf(stderr, Name ": no devices found for %s\n",
|
||||||
|
|
5
mdadm.h
5
mdadm.h
|
@ -153,6 +153,11 @@ struct mdinfo {
|
||||||
int cache_size; /* size of raid456 stripe cache*/
|
int cache_size; /* size of raid456 stripe cache*/
|
||||||
int mismatch_cnt;
|
int mismatch_cnt;
|
||||||
char text_version[50];
|
char text_version[50];
|
||||||
|
void *update_private; /* for passing metadata-format
|
||||||
|
* specific update data
|
||||||
|
* between successive calls to
|
||||||
|
* update_super()
|
||||||
|
*/
|
||||||
|
|
||||||
int container_member; /* for assembling external-metatdata arrays
|
int container_member; /* for assembling external-metatdata arrays
|
||||||
* This is to be used internally by metadata
|
* This is to be used internally by metadata
|
||||||
|
|
|
@ -1378,8 +1378,6 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info,
|
||||||
char *update, char *devname, int verbose,
|
char *update, char *devname, int verbose,
|
||||||
int uuid_set, char *homehost)
|
int uuid_set, char *homehost)
|
||||||
{
|
{
|
||||||
/* FIXME */
|
|
||||||
|
|
||||||
/* For 'assemble' and 'force' we need to return non-zero if any
|
/* For 'assemble' and 'force' we need to return non-zero if any
|
||||||
* change was made. For others, the return value is ignored.
|
* change was made. For others, the return value is ignored.
|
||||||
* Update options are:
|
* Update options are:
|
||||||
|
@ -1395,26 +1393,55 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info,
|
||||||
* linear only
|
* linear only
|
||||||
* resync: mark as dirty so a resync will happen.
|
* resync: mark as dirty so a resync will happen.
|
||||||
* name: update the name - preserving the homehost
|
* name: update the name - preserving the homehost
|
||||||
|
* uuid: Change the uuid of the array to match watch is given
|
||||||
*
|
*
|
||||||
* Following are not relevant for this imsm:
|
* Following are not relevant for this imsm:
|
||||||
* sparc2.2 : update from old dodgey metadata
|
* sparc2.2 : update from old dodgey metadata
|
||||||
* super-minor: change the preferred_minor number
|
* super-minor: change the preferred_minor number
|
||||||
* summaries: update redundant counters.
|
* summaries: update redundant counters.
|
||||||
* uuid: Change the uuid of the array to match watch is given
|
|
||||||
* homehost: update the recorded homehost
|
* homehost: update the recorded homehost
|
||||||
* _reshape_progress: record new reshape_progress position.
|
* _reshape_progress: record new reshape_progress position.
|
||||||
*/
|
*/
|
||||||
int rv = 0;
|
int rv = 1;
|
||||||
//struct intel_super *super = st->sb;
|
struct intel_super *super = st->sb;
|
||||||
//struct imsm_super *mpb = super->mpb;
|
struct imsm_super *mpb;
|
||||||
|
|
||||||
if (strcmp(update, "grow") == 0) {
|
/* we can only update container info */
|
||||||
}
|
if (!super || super->current_vol >= 0 || !super->anchor)
|
||||||
if (strcmp(update, "resync") == 0) {
|
return 1;
|
||||||
/* dev->vol.dirty = 1; */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IMSM has no concept of UUID or homehost */
|
mpb = super->anchor;
|
||||||
|
|
||||||
|
if (strcmp(update, "uuid") == 0 && uuid_set && !info->update_private)
|
||||||
|
fprintf(stderr,
|
||||||
|
Name ": '--uuid' not supported for imsm metadata\n");
|
||||||
|
else if (strcmp(update, "uuid") == 0 && uuid_set && info->update_private) {
|
||||||
|
mpb->orig_family_num = *((__u32 *) info->update_private);
|
||||||
|
rv = 0;
|
||||||
|
} else if (strcmp(update, "uuid") == 0) {
|
||||||
|
__u32 *new_family = malloc(sizeof(*new_family));
|
||||||
|
|
||||||
|
/* update orig_family_number with the incoming random
|
||||||
|
* data, report the new effective uuid, and store the
|
||||||
|
* new orig_family_num for future updates.
|
||||||
|
*/
|
||||||
|
if (new_family) {
|
||||||
|
memcpy(&mpb->orig_family_num, info->uuid, sizeof(__u32));
|
||||||
|
uuid_from_super_imsm(st, info->uuid);
|
||||||
|
*new_family = mpb->orig_family_num;
|
||||||
|
info->update_private = new_family;
|
||||||
|
rv = 0;
|
||||||
|
}
|
||||||
|
} else if (strcmp(update, "assemble") == 0)
|
||||||
|
rv = 0;
|
||||||
|
else
|
||||||
|
fprintf(stderr,
|
||||||
|
Name ": '--update=%s' not supported for imsm metadata\n",
|
||||||
|
update);
|
||||||
|
|
||||||
|
/* successful update? recompute checksum */
|
||||||
|
if (rv == 0)
|
||||||
|
mpb->check_sum = __le32_to_cpu(__gen_imsm_checksum(mpb));
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue