Re: [PATCH 1/8] Do not continue reshape during initrd phase

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 27 Sep 2011 14:04:39 +0200 Adam Kwolek <adam.kwolek@xxxxxxxxx> wrote:

> During initrd phase continuing reshape will cause file system context
> lost. This blocks ability to control reshape using checkpoints.
> 
> To avoid this, during initrd phase assemble has to be executed with
> '--freeze-reshape' option. This causes that mdadm restores reshape
> critical section only.
> 
> Reshape can be continued later after system full boot.

Thanks.
I've applied this with a few small changes:

- The constants FREEZE_RESHAPE_NONE and FREEZE_RESHAPE_ASSEMBLY are not
  necessary and don't help readability.  Just treat "freeze_reshape" as a
  boolean, either true or false.

- The change to share_reshape as unnecessary so I removed it.

Thanks,
NeilBrown


>
> 
> Signed-off-by: Adam Kwolek <adam.kwolek@xxxxxxxxx>
> ---
> 
>  Assemble.c    |   12 +++++++-----
>  Grow.c        |   52 ++++++++++++++++++++++++++++++++++++++--------------
>  Incremental.c |   16 ++++++++++------
>  ReadMe.c      |    1 +
>  mdadm.c       |   33 ++++++++++++++++++++++++---------
>  mdadm.h       |   18 ++++++++++++++----
>  6 files changed, 94 insertions(+), 38 deletions(-)
> 
> diff --git a/Assemble.c b/Assemble.c
> index c6aad20..afca38e 100644
> --- a/Assemble.c
> +++ b/Assemble.c
> @@ -138,7 +138,7 @@ int Assemble(struct supertype *st, char *mddev,
>  	     char *backup_file, int invalid_backup,
>  	     int readonly, int runstop,
>  	     char *update, char *homehost, int require_homehost,
> -	     int verbose, int force)
> +	     int verbose, int force, int freeze_reshape)
>  {
>  	/*
>  	 * The task of Assemble is to find a collection of
> @@ -697,7 +697,7 @@ int Assemble(struct supertype *st, char *mddev,
>  		int err;
>  		err = assemble_container_content(st, mdfd, content, runstop,
>  						 chosen_name, verbose,
> -						 backup_file);
> +						 backup_file, freeze_reshape);
>  		close(mdfd);
>  		return err;
>  	}
> @@ -1344,7 +1344,8 @@ int Assemble(struct supertype *st, char *mddev,
>  #ifndef MDASSEMBLE
>  			if (content->reshape_active &&
>  			    content->delta_disks <= 0)
> -				rv = Grow_continue(mdfd, st, content, backup_file);
> +				rv = Grow_continue(mdfd, st, content,
> +						   backup_file, freeze_reshape);
>  			else
>  #endif
>  				rv = ioctl(mdfd, RUN_ARRAY, NULL);
> @@ -1511,7 +1512,7 @@ int Assemble(struct supertype *st, char *mddev,
>  int assemble_container_content(struct supertype *st, int mdfd,
>  			       struct mdinfo *content, int runstop,
>  			       char *chosen_name, int verbose,
> -			       char *backup_file)
> +			       char *backup_file, int freeze_reshape)
>  {
>  	struct mdinfo *dev, *sra;
>  	int working = 0, preexist = 0;
> @@ -1560,7 +1561,8 @@ int assemble_container_content(struct supertype *st, int mdfd,
>  					   spare, backup_file, verbose) == 1)
>  				return 1;
>  
> -			err = Grow_continue(mdfd, st, content, backup_file);
> +			err = Grow_continue(mdfd, st, content, backup_file,
> +					    freeze_reshape);
>  		} else switch(content->array.level) {
>  		case LEVEL_LINEAR:
>  		case LEVEL_MULTIPATH:
> diff --git a/Grow.c b/Grow.c
> index 4a25165..4509488 100644
> --- a/Grow.c
> +++ b/Grow.c
> @@ -696,10 +696,16 @@ static int subarray_set_num(char *container, struct mdinfo *sra, char *name, int
>  	return rc;
>  }
>  
> -int start_reshape(struct mdinfo *sra, int already_running)
> +int start_reshape(struct mdinfo *sra, int already_running, int freeze_reshape)
>  {
>  	int err;
> -	sysfs_set_num(sra, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL);
> +
> +	/* do not block array as we not continue reshape this time
> +	 */
> +	if (freeze_reshape == FREEZE_RESHAPE_NONE)
> +		sysfs_set_num(sra, NULL, "suspend_lo", 0x7FFFFFFFFFFFFFFFULL);
> +	else
> +		sysfs_set_num(sra, NULL, "suspend_lo", 0);
>  	err = sysfs_set_num(sra, NULL, "suspend_hi", 0);
>  	err = err ?: sysfs_set_num(sra, NULL, "suspend_lo", 0);
>  	if (!already_running)
> @@ -1344,13 +1350,13 @@ static int reshape_array(char *container, int fd, char *devname,
>  			 struct supertype *st, struct mdinfo *info,
>  			 int force, struct mddev_dev *devlist,
>  			 char *backup_file, int quiet, int forked,
> -			 int restart);
> +			 int restart, int freeze_reshape);
>  static int reshape_container(char *container, char *devname,
>  			     struct supertype *st, 
>  			     struct mdinfo *info,
>  			     int force,
>  			     char *backup_file,
> -			     int quiet, int restart);
> +			     int quiet, int restart, int freeze_reshape);
>  
>  int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
>  		 long long size,
> @@ -1761,7 +1767,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
>  		 * performed at the level of the container
>  		 */
>  		rv = reshape_container(container, devname, st, &info,
> -				       force, backup_file, quiet, 0);
> +				       force, backup_file, quiet, 0, 0);
>  		frozen = 0;
>  	} else {
>  		/* get spare devices from external metadata
> @@ -1789,7 +1795,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
>  		}
>  		sync_metadata(st);
>  		rv = reshape_array(container, fd, devname, st, &info, force,
> -				   devlist, backup_file, quiet, 0, 0);
> +				   devlist, backup_file, quiet, 0, 0, 0);
>  		frozen = 0;
>  	}
>  release:
> @@ -1802,7 +1808,7 @@ static int reshape_array(char *container, int fd, char *devname,
>  			 struct supertype *st, struct mdinfo *info,
>  			 int force, struct mddev_dev *devlist,
>  			 char *backup_file, int quiet, int forked,
> -			 int restart)
> +			 int restart, int freeze_reshape)
>  {
>  	struct reshape reshape;
>  	int spares_needed;
> @@ -2241,7 +2247,7 @@ started:
>  		}
>  	}
>  
> -	err = start_reshape(sra, restart);
> +	err = start_reshape(sra, restart, freeze_reshape);
>  	if (err) {
>  		fprintf(stderr, 
>  			Name ": Cannot %s reshape for %s\n",
> @@ -2251,6 +2257,15 @@ started:
>  	}
>  	if (restart)
>  		sysfs_set_str(sra, NULL, "array_state", "active");
> +	if (freeze_reshape == FREEZE_RESHAPE_ASSEMBLY) {
> +		free(fdlist);
> +		free(offsets);
> +		sysfs_free(sra);
> +		fprintf(stderr, Name ": Reshape has to be continued from"
> +			" location %llu when root fileststem will be mounted\n",
> +			sra->reshape_progress);
> +		return 1;
> +	}
>  
>  	/* Now we just need to kick off the reshape and watch, while
>  	 * handling backups of the data...
> @@ -2389,7 +2404,7 @@ int reshape_container(char *container, char *devname,
>  		      struct mdinfo *info,
>  		      int force,
>  		      char *backup_file,
> -		      int quiet, int restart)
> +		      int quiet, int restart, int freeze_reshape)
>  {
>  	struct mdinfo *cc = NULL;
>  	int rv = restart;
> @@ -2418,7 +2433,9 @@ int reshape_container(char *container, char *devname,
>  		unfreeze(st);
>  		return 1;
>  	default: /* parent */
> -		printf(Name ": multi-array reshape continues in background\n");
> +		if (freeze_reshape == FREEZE_RESHAPE_NONE)
> +			printf(Name ": multi-array reshape continues"
> +			       "in background\n");
>  		return 0;
>  	case 0: /* child */
>  		break;
> @@ -2473,8 +2490,15 @@ int reshape_container(char *container, char *devname,
>  
>  		rv = reshape_array(container, fd, adev, st,
>  				   content, force, NULL,
> -				   backup_file, quiet, 1, restart);
> +				   backup_file, quiet, 1, restart,
> +				   freeze_reshape);
>  		close(fd);
> +
> +		if (freeze_reshape) {
> +			sysfs_free(cc);
> +			exit(0);
> +		}
> +
>  		restart = 0;
>  		if (rv)
>  			break;
> @@ -3613,7 +3637,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
>  }
>  
>  int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
> -		  char *backup_file)
> +		  char *backup_file, int freeze_reshape)
>  {
>  	char buf[40];
>  	char *container = NULL;
> @@ -3640,9 +3664,9 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
>  			close(cfd);
>  			return reshape_container(container, NULL,
>  						 st, info, 0, backup_file,
> -						 0, 1);
> +						 0, 1, freeze_reshape);
>  		}
>  	}
>  	return reshape_array(container, mdfd, "array", st, info, 1,
> -			     NULL, backup_file, 0, 0, 1);
> +			     NULL, backup_file, 0, 0, 1, freeze_reshape);
>  }
> diff --git a/Incremental.c b/Incremental.c
> index 791ad85..571d45d 100644
> --- a/Incremental.c
> +++ b/Incremental.c
> @@ -44,7 +44,8 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
>  
>  static int Incremental_container(struct supertype *st, char *devname,
>  				 char *homehost,
> -				 int verbose, int runstop, int autof);
> +				 int verbose, int runstop, int autof,
> +				 int freeze_reshape);
>  
>  static struct mddev_ident *search_mdstat(struct supertype *st,
>  					   struct mdinfo *info,
> @@ -53,7 +54,7 @@ static struct mddev_ident *search_mdstat(struct supertype *st,
>  
>  int Incremental(char *devname, int verbose, int runstop,
>  		struct supertype *st, char *homehost, int require_homehost,
> -		int autof)
> +		int autof, int freeze_reshape)
>  {
>  	/* Add this device to an array, creating the array if necessary
>  	 * and starting the array if sensible or - if runstop>0 - if possible.
> @@ -140,7 +141,8 @@ int Incremental(char *devname, int verbose, int runstop,
>  		close(dfd);
>  		if (!rv && st->ss->container_content)
>  			return Incremental_container(st, devname, homehost,
> -						     verbose, runstop, autof);
> +						     verbose, runstop, autof,
> +						     freeze_reshape);
>  
>  		fprintf(stderr, Name ": %s is not part of an md array.\n",
>  			devname);
> @@ -450,7 +452,8 @@ int Incremental(char *devname, int verbose, int runstop,
>  		close(mdfd);
>  		sysfs_free(sra);
>  		rv = Incremental(chosen_name, verbose, runstop,
> -				 NULL, homehost, require_homehost, autof);
> +				 NULL, homehost, require_homehost, autof,
> +				 freeze_reshape);
>  		if (rv == 1)
>  			/* Don't fail the whole -I if a subarray didn't
>  			 * have enough devices to start yet
> @@ -1416,7 +1419,7 @@ static char *container2devname(char *devname)
>  
>  static int Incremental_container(struct supertype *st, char *devname,
>  				 char *homehost, int verbose,
> -				 int runstop, int autof)
> +				 int runstop, int autof, int freeze_reshape)
>  {
>  	/* Collect the contents of this container and for each
>  	 * array, choose a device name and assemble the array.
> @@ -1551,7 +1554,8 @@ static int Incremental_container(struct supertype *st, char *devname,
>  		}
>  
>  		assemble_container_content(st, mdfd, ra, runstop,
> -					   chosen_name, verbose, NULL);
> +					   chosen_name, verbose, NULL,
> +					   freeze_reshape);
>  		close(mdfd);
>  	}
>  
> diff --git a/ReadMe.c b/ReadMe.c
> index b658841..89dd7af 100644
> --- a/ReadMe.c
> +++ b/ReadMe.c
> @@ -153,6 +153,7 @@ struct option long_options[] = {
>      {"scan",      0, 0, 's'},
>      {"force",	  0, 0, Force},
>      {"update",	  1, 0, 'U'},
> +    {"freeze-reshape", 0, 0, FreezeReshape},
>  
>      /* Management */
>      {"add",       0, 0, Add},
> diff --git a/mdadm.c b/mdadm.c
> index 1533510..18ca2ee 100644
> --- a/mdadm.c
> +++ b/mdadm.c
> @@ -112,6 +112,8 @@ int main(int argc, char *argv[])
>  
>  	int mdfd = -1;
>  
> +	int freeze_reshape = FREEZE_RESHAPE_NONE;
> +
>  	srandom(time(0) ^ getpid());
>  
>  	ident.uuid_set=0;
> @@ -612,8 +614,12 @@ int main(int argc, char *argv[])
>  		case O(MANAGE,Force): /* add device which is too large */
>  			force=1;
>  			continue;
> -
>  			/* now for the Assemble options */
> +		case O(ASSEMBLE, FreezeReshape):   /* Freeze reshape during
> +						    * initrd phase */
> +		case O(INCREMENTAL, FreezeReshape):
> +			freeze_reshape = FREEZE_RESHAPE_ASSEMBLY;
> +			continue;
>  		case O(CREATE,'u'): /* uuid of array */
>  		case O(ASSEMBLE,'u'): /* uuid of array */
>  			if (ident.uuid_set) {
> @@ -1228,14 +1234,16 @@ int main(int argc, char *argv[])
>  					       NULL, backup_file, invalid_backup,
>  					       readonly, runstop, update,
>  					       homehost, require_homehost,
> -					       verbose-quiet, force);
> +					       verbose-quiet, force,
> +					       freeze_reshape);
>  			}
>  		} else if (!scan)
>  			rv = Assemble(ss, devlist->devname, &ident,
>  				      devlist->next, backup_file, invalid_backup,
>  				      readonly, runstop, update,
>  				      homehost, require_homehost,
> -				      verbose-quiet, force);
> +				      verbose-quiet, force,
> +				      freeze_reshape);
>  		else if (devs_found>0) {
>  			if (update && devs_found > 1) {
>  				fprintf(stderr, Name ": can only update a single array at a time\n");
> @@ -1259,7 +1267,8 @@ int main(int argc, char *argv[])
>  					       NULL, backup_file, invalid_backup,
>  					       readonly, runstop, update,
>  					       homehost, require_homehost,
> -					       verbose-quiet, force);
> +					       verbose-quiet, force,
> +					       freeze_reshape);
>  			}
>  		} else {
>  			struct mddev_ident *a, *array_list =  conf_get_ident(NULL);
> @@ -1300,7 +1309,8 @@ int main(int argc, char *argv[])
>  						     NULL, NULL, 0,
>  						     readonly, runstop, NULL,
>  						     homehost, require_homehost,
> -						     verbose-quiet, force);
> +						     verbose-quiet, force,
> +						     freeze_reshape);
>  					if (r == 0) {
>  						a->assembled = 1;
>  						successes++;
> @@ -1325,9 +1335,13 @@ int main(int argc, char *argv[])
>  						rv2 = Assemble(ss, NULL,
>  							       &ident,
>  							       devlist, NULL, 0,
> -							       readonly, runstop, NULL,
> -							       homehost, require_homehost,
> -							       verbose-quiet, force);
> +							       readonly,
> +							       runstop, NULL,
> +							       homehost,
> +							       require_homehost,
> +							       verbose-quiet,
> +							       force,
> +							       freeze_reshape);
>  						if (rv2==0) {
>  							cnt++;
>  							acnt++;
> @@ -1681,7 +1695,8 @@ int main(int argc, char *argv[])
>  		else
>  			rv = Incremental(devlist->devname, verbose-quiet,
>  					 runstop, ss, homehost,
> -					 require_homehost, autof);
> +					 require_homehost, autof,
> +					 freeze_reshape);
>  		break;
>  	case AUTODETECT:
>  		autodetect();
> diff --git a/mdadm.h b/mdadm.h
> index 8dd37d9..073deb9 100644
> --- a/mdadm.h
> +++ b/mdadm.h
> @@ -313,6 +313,7 @@ enum special_options {
>  	RebuildMapOpt,
>  	InvalidBackup,
>  	UdevRules,
> +	FreezeReshape,
>  };
>  
>  /* structures read from config file */
> @@ -1030,7 +1031,16 @@ extern int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
>  extern int Grow_restart(struct supertype *st, struct mdinfo *info,
>  			int *fdlist, int cnt, char *backup_file, int verbose);
>  extern int Grow_continue(int mdfd, struct supertype *st,
> -			 struct mdinfo *info, char *backup_file);
> +			 struct mdinfo *info, char *backup_file,
> +			 int freeze_reshape);
> +
> +/* define stages for freeze assembly feature
> + * FREEZE_RESHAPE_NONE     : disabled
> + * FREEZE_RESHAPE_ASSEMBLY : assemby phase
> + */
> +#define FREEZE_RESHAPE_NONE		0
> +#define FREEZE_RESHAPE_ASSEMBLY		1
> +
>  extern int restore_backup(struct supertype *st,
>  			  struct mdinfo *content,
>  			  int working_disks,
> @@ -1044,7 +1054,7 @@ extern int Assemble(struct supertype *st, char *mddev,
>  		    char *backup_file, int invalid_backup,
>  		    int readonly, int runstop,
>  		    char *update, char *homehost, int require_homehost,
> -		    int verbose, int force);
> +		    int verbose, int force, int freeze_reshape);
>  
>  extern int Build(char *mddev, int chunk, int level, int layout,
>  		 int raiddisks, struct mddev_dev *devlist, int assume_clean,
> @@ -1078,7 +1088,7 @@ extern int WaitClean(char *dev, int sock, int verbose);
>  
>  extern int Incremental(char *devname, int verbose, int runstop,
>  		       struct supertype *st, char *homehost, int require_homehost,
> -		       int autof);
> +		       int autof, int freeze_reshape);
>  extern void RebuildMap(void);
>  extern int IncrementalScan(int verbose);
>  extern int IncrementalRemove(char *devname, char *path, int verbose);
> @@ -1157,7 +1167,7 @@ extern void append_metadata_update(struct supertype *st, void *buf, int len);
>  extern int assemble_container_content(struct supertype *st, int mdfd,
>  				      struct mdinfo *content, int runstop,
>  				      char *chosen_name, int verbose,
> -				      char *backup_file);
> +				      char *backup_file, int freeze_reshape);
>  extern struct mdinfo *container_choose_spares(struct supertype *st,
>  					      unsigned long long min_size,
>  					      struct domainlist *domlist,

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux