Skip site navigation (1)Skip section navigation (2)
Date:      02 Nov 2000 17:36:15 -0500
From:      Randell Jesup <rjesup@wgate.com>
To:        Matt Dillon <dillon@earth.backplane.com>
Cc:        Randell Jesup <rjesup@wgate.com>, Marius Bendiksen <mbendiks@eunet.no>, arch@FreeBSD.ORG, Warner Losh <imp@village.org>
Subject:   Re: Like to commit my diskprep
Message-ID:  <ybuitq6atnk.fsf@jesup.eng.tvol.net.jesup.eng.tvol.net>
In-Reply-To: Matt Dillon's message of "Thu, 2 Nov 2000 09:25:40 -0800 (PST)"
References:  <Pine.BSF.4.05.10011021602500.10193-100000@login-1.eunet.no> <200011021632.eA2GWZ138286@earth.backplane.com> <ybupukecnoq.fsf@jesup.eng.tvol.net.jesup.eng.tvol.net> <200011021725.eA2HPeM38718@earth.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Following are changes to disklabel.c to change it to be much more user-
friendly (and kick out more warnings for things like overlapped
partitions).

It supports the syntax I mentioned before:
[snipped to keep things smaller]
#        size   offset    fstype   [fsize bsize bps/cpg]
  a:   819200        0    4.2BSD     4096 16384    75   # (Cyl.    0 - 812*)
  b:     800M   819200      swap 
  c:        *        0    unused  0 0
  e:      10%        *    4.2BSD 
  f:       5g        *    4.2BSD
  g:        *        *    4.2BSD  

Note that I support both % and * for hog partitions.  % is calculated as
a %age of space remaining after all fixed-size partitions are dealt with,
and * for size (hog) gets anything left after that.

* for offset means "calculate it your damn self, disklabel, I don't care".
:-)

If fsize/etc aren't specified, it uses defaults.  This might want to be
improved (better defaults, as per other conversation).

I also added a -n option to supress writing labels to the slice.  Handy for
testing!!!  If -n is used, it'll dump what it would have written to stdout.


WARNING:  Playing with disklabel CAN frag your disk!!!!!

Todo: add warnings about incompatibilities between old and new labels.
      update manpage
      change newfs defaults
      not require "0 0" after an unused partition.

-- 
Randell Jesup, Worldgate Communications, ex-Scala, ex-Amiga OS team ('88-94)
rjesup@wgate.com


*** /usr/src/sbin/disklabel/disklabel.c	Sat Jul  1 02:47:46 2000
--- disklabel.c	Thu Nov  2 15:29:04 2000
***************
*** 80,85 ****
--- 80,91 ----
  #define	BBSIZE	8192			/* size of boot area, with label */
  #endif
  
+ /* FIX!  These are too low, but are traditional */
+ #define DEFAULT_NEWFS_BLOCK  8192U
+ #define DEFAULT_NEWFS_FRAG   1024U
+ #define DEFAULT_NEWFS_CPG    16U
+ 
+ 
  #ifdef tahoe
  #define	NUMBOOT	0
  #else
***************
*** 119,124 ****
--- 125,138 ----
  struct	disklabel lab;
  char	bootarea[BBSIZE];
  
+ /* partition 'c' is the full disk and is special */
+ #define FULL_DISK_PART 2
+ #define MAX_PART ('z')
+ #define MAX_NUM_PARTS (1 + MAX_PART-'a')
+ char    part_size_type[MAX_NUM_PARTS];
+ char    part_offset_type[MAX_NUM_PARTS];
+ int     part_set[MAX_NUM_PARTS];
+ 
  #if NUMBOOT > 0
  int	installboot;	/* non-zero if we should install a boot program */
  char	*bootbuf;	/* pointer to buffer with remainder of boot prog */
***************
*** 134,145 ****
  } op = UNSPEC;
  
  int	rflag;
  
  #ifdef DEBUG
  int	debug;
! #define OPTIONS	"BNRWb:ders:w"
  #else
! #define OPTIONS	"BNRWb:ers:w"
  #endif
  
  int
--- 148,160 ----
  } op = UNSPEC;
  
  int	rflag;
+ int disable_write;   /* set to disable writing to disk label */
  
  #ifdef DEBUG
  int	debug;
! #define OPTIONS	"BNRWb:denrs:w"
  #else
! #define OPTIONS	"BNRWb:enrs:w"
  #endif
  
  int
***************
*** 152,157 ****
--- 167,174 ----
  	int ch, f = 0, flag, error = 0;
  	char *name = 0;
  
+ 	disable_write = 0; /* paranoia */
+ 
  	while ((ch = getopt(argc, argv, OPTIONS)) != -1)
  		switch (ch) {
  #if NUMBOOT > 0
***************
*** 172,177 ****
--- 189,197 ----
  					usage();
  				op = NOWRITE;
  				break;
+ 			case 'n':
+ 				disable_write = 1;
+ 				break;
  			case 'R':
  				if (op != UNSPEC)
  					usage();
***************
*** 398,473 ****
  	register int i;
  #endif
  
! 	setbootflag(lp);
! 	lp->d_magic = DISKMAGIC;
! 	lp->d_magic2 = DISKMAGIC;
! 	lp->d_checksum = 0;
! 	lp->d_checksum = dkcksum(lp);
! 	if (rflag) {
! 		/*
! 		 * First set the kernel disk label,
! 		 * then write a label to the raw disk.
! 		 * If the SDINFO ioctl fails because it is unimplemented,
! 		 * keep going; otherwise, the kernel consistency checks
! 		 * may prevent us from changing the current (in-core)
! 		 * label.
! 		 */
! 		if (ioctl(f, DIOCSDINFO, lp) < 0 &&
! 		    errno != ENODEV && errno != ENOTTY) {
! 			l_perror("ioctl DIOCSDINFO");
! 			return (1);
! 		}
! 		(void)lseek(f, (off_t)0, SEEK_SET);
! 
  #ifdef __alpha__
! 		/*
! 		 * Generate the bootblock checksum for the SRM console.
! 		 */
! 		for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++)
! 			sum += p[i];
! 		p[63] = sum;
  #endif
! 
! 		/*
! 		 * write enable label sector before write (if necessary),
! 		 * disable after writing.
! 		 */
! 		flag = 1;
! 		if (ioctl(f, DIOCWLABEL, &flag) < 0)
! 			warn("ioctl DIOCWLABEL");
! 		if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) {
! 			warn("write");
! 			return (1);
! 		}
  #if NUMBOOT > 0
! 		/*
! 		 * Output the remainder of the disklabel
! 		 */
! 		if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
! 			warn("write");
! 			return(1);
! 		}
  #endif
! 		flag = 0;
! 		(void) ioctl(f, DIOCWLABEL, &flag);
! 	} else if (ioctl(f, DIOCWDINFO, lp) < 0) {
! 		l_perror("ioctl DIOCWDINFO");
! 		return (1);
! 	}
  #ifdef vax
! 	if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {
! 		daddr_t alt;
! 
! 		alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
! 		for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
! 			(void)lseek(f, (off_t)((alt + i) * lp->d_secsize),
! 			    SEEK_SET);
! 			if (write(f, boot, lp->d_secsize) < lp->d_secsize)
! 				warn("alternate label %d write", i/2);
  		}
- 	}
  #endif
! 	return (0);
  }
  
  void
--- 418,502 ----
  	register int i;
  #endif
  
! 	if (disable_write)
! 	{
! 		Warning("write to disk label supressed - label was as follows:");
! 		display(stdout,lp);
! 		return 0;
! 	}
! 	else
! 	{
! 		setbootflag(lp);
! 		lp->d_magic = DISKMAGIC;
! 		lp->d_magic2 = DISKMAGIC;
! 		lp->d_checksum = 0;
! 		lp->d_checksum = dkcksum(lp);
! 		if (rflag) {
! 			/*
! 			 * First set the kernel disk label,
! 			 * then write a label to the raw disk.
! 			 * If the SDINFO ioctl fails because it is unimplemented,
! 			 * keep going; otherwise, the kernel consistency checks
! 			 * may prevent us from changing the current (in-core)
! 			 * label.
! 			 */
! 			if (ioctl(f, DIOCSDINFO, lp) < 0 &&
! 				errno != ENODEV && errno != ENOTTY) {
! 				l_perror("ioctl DIOCSDINFO");
! 				return (1);
! 			}
! 			(void)lseek(f, (off_t)0, SEEK_SET);
! 			
  #ifdef __alpha__
! 			/*
! 			 * Generate the bootblock checksum for the SRM console.
! 			 */
! 			for (p = (u_long *)boot, i = 0, sum = 0; i < 63; i++)
! 				sum += p[i];
! 			p[63] = sum;
  #endif
! 			
! 			/*
! 			 * write enable label sector before write (if necessary),
! 			 * disable after writing.
! 			 */
! 			flag = 1;
! 			if (ioctl(f, DIOCWLABEL, &flag) < 0)
! 				warn("ioctl DIOCWLABEL");
! 			if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) {
! 				warn("write");
! 				return (1);
! 			}
  #if NUMBOOT > 0
! 			/*
! 			 * Output the remainder of the disklabel
! 			 */
! 			if (bootbuf && write(f, bootbuf, bootsize) != bootsize) {
! 				warn("write");
! 				return(1);
! 			}
  #endif
! 			flag = 0;
! 			(void) ioctl(f, DIOCWLABEL, &flag);
! 		} else if (ioctl(f, DIOCWDINFO, lp) < 0) {
! 			l_perror("ioctl DIOCWDINFO");
! 			return (1);
! 		}
  #ifdef vax
! 		if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) {
! 			daddr_t alt;
! 			
! 			alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors;
! 			for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) {
! 				(void)lseek(f, (off_t)((alt + i) * lp->d_secsize),
! 							SEEK_SET);
! 				if (write(f, boot, lp->d_secsize) < lp->d_secsize)
! 					warn("alternate label %d write", i/2);
! 			}
  		}
  #endif
! 		return (0);
! 	}
  }
  
  void
***************
*** 934,942 ****
--- 963,980 ----
  {
  	register char **cpp, *cp;
  	register struct partition *pp;
+ 	register int i;
  	char *tp, *s, line[BUFSIZ];
  	int v, lineno = 0, errors = 0;
  
+ 	for (i = 0; i < MAX_NUM_PARTS; i++)
+ 	{
+ 		/* paranoia */
+ 		part_set[i] = 0;
+ 		part_size_type[i] = '\0';
+ 		part_offset_type[i] = '\0';
+ 	}
+ 
  	lp->d_bbsize = BBSIZE;				/* XXX */
  	lp->d_sbsize = SBSIZE;				/* XXX */
  	while (fgets(line, sizeof(line) - 1, f)) {
***************
*** 1138,1153 ****
  				lp->d_trkseek = v;
  			continue;
  		}
! 		if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') {
  			unsigned part = *cp - 'a';
  
  			if (part > lp->d_npartitions) {
  				fprintf(stderr,
! 				    "line %d: bad partition name\n", lineno);
  				errors++;
  				continue;
  			}
  			pp = &lp->d_partitions[part];
  #define NXTNUM(n) { \
  	if (tp == NULL) { \
  		fprintf(stderr, "line %d: too few numeric fields\n", lineno); \
--- 1176,1194 ----
  				lp->d_trkseek = v;
  			continue;
  		}
! 		/* the ':' was removed above */
! 		if ('a' <= *cp && *cp <= MAX_PART && cp[1] == '\0') {
  			unsigned part = *cp - 'a';
  
  			if (part > lp->d_npartitions) {
  				fprintf(stderr,
! 				    "line %d: partition name out of range a-%c: %s\n",
! 						lineno,'a' + lp->d_npartitions - 1,cp);
  				errors++;
  				continue;
  			}
  			pp = &lp->d_partitions[part];
+ 			part_set[part] = 1;
  #define NXTNUM(n) { \
  	if (tp == NULL) { \
  		fprintf(stderr, "line %d: too few numeric fields\n", lineno); \
***************
*** 1160,1231 ****
  		(n) = atoi(cp); \
  	} \
       }
  
! 			NXTNUM(v);
! 			if (v < 0) {
  				fprintf(stderr,
  				    "line %d: %s: bad partition size\n",
  				    lineno, cp);
  				errors++;
- 			} else
- 				pp->p_size = v;
- 			NXTNUM(v);
- 			if (v < 0) {
- 				fprintf(stderr,
- 				    "line %d: %s: bad partition offset\n",
- 				    lineno, cp);
- 				errors++;
- 			} else
- 				pp->p_offset = v;
- 			cp = tp, tp = word(cp);
- 			cpp = fstypenames;
- 			for (; cpp < &fstypenames[FSMAXTYPES]; cpp++)
- 				if ((s = *cpp) && streq(s, cp)) {
- 					pp->p_fstype = cpp - fstypenames;
- 					goto gottype;
- 				}
- 			if (isdigit(*cp))
- 				v = atoi(cp);
- 			else
- 				v = FSMAXTYPES;
- 			if ((unsigned)v >= FSMAXTYPES) {
- 				fprintf(stderr, "line %d: %s %s\n", lineno,
- 				    "Warning, unknown filesystem type", cp);
- 				v = FS_UNUSED;
- 			}
- 			pp->p_fstype = v;
- 	gottype:
- 
- 			switch (pp->p_fstype) {
- 
- 			case FS_UNUSED:				/* XXX */
- 				NXTNUM(pp->p_fsize);
- 				if (pp->p_fsize == 0)
- 					break;
- 				NXTNUM(v);
- 				pp->p_frag = v / pp->p_fsize;
  				break;
  
! 			case FS_BSDFFS:
! 				NXTNUM(pp->p_fsize);
! 				if (pp->p_fsize == 0)
  					break;
! 				NXTNUM(v);
! 				pp->p_frag = v / pp->p_fsize;
! 				NXTNUM(pp->p_cpg);
! 				break;
  
! 			case FS_BSDLFS:
! 				NXTNUM(pp->p_fsize);
! 				if (pp->p_fsize == 0)
! 					break;
! 				NXTNUM(v);
! 				pp->p_frag = v / pp->p_fsize;
! 				NXTNUM(pp->p_cpg);
! 				break;
  
! 			default:
! 				break;
  			}
  			continue;
  		}
--- 1201,1315 ----
  		(n) = atoi(cp); \
  	} \
       }
+ /* retain 1 character following number */
+ #define NXTWORD(w,n) { \
+ 	if (tp == NULL) { \
+ 		fprintf(stderr, "line %d: too few numeric fields\n", lineno); \
+ 		errors++; \
+ 		break; \
+ 	} else { \
+         char *tmp; \
+ 		cp = tp, tp = word(cp); \
+ 		if (tp == NULL) \
+ 			tp = cp; \
+         (n) = strtol(cp,&tmp,10); \
+ 		if (tmp) (w) = *tmp; \
+ 	} \
+      }
  
! 			v = 0;
! 			NXTWORD(part_size_type[part],v);
! 			if (v < 0 ||
! 				(v == 0 &&
! 				 part_size_type[part] != '*'))
! 			{
  				fprintf(stderr,
  				    "line %d: %s: bad partition size\n",
  				    lineno, cp);
  				errors++;
  				break;
+ 			}
+ 			else
+ 			{
+ 				pp->p_size = v;
  
! 				v = 0;
! 				NXTWORD(part_offset_type[part],v);
! 				if (v < 0 ||
! 					(v == 0 &&
! 					 part_offset_type[part] != '*' &&
! 					 part_offset_type[part] != '\0'))
! 				{
! 					fprintf(stderr,
! 							"line %d: %s: bad partition offset\n",
! 							lineno, cp);
! 					errors++;
  					break;
! 				}
! 				else
! 				{
! 					pp->p_offset = v;
! 
! 					cp = tp, tp = word(cp);
! 					cpp = fstypenames;
! 					for (; cpp < &fstypenames[FSMAXTYPES]; cpp++)
! 						if ((s = *cpp) && streq(s, cp)) {
! 							pp->p_fstype = cpp - fstypenames;
! 							goto gottype;
! 						}
! 					if (isdigit(*cp))
! 						v = atoi(cp);
! 					else
! 						v = FSMAXTYPES;
! 					if ((unsigned)v >= FSMAXTYPES) {
! 						fprintf(stderr, "line %d: %s %s\n", lineno,
! 								"Warning, unknown filesystem type", cp);
! 						v = FS_UNUSED;
! 					}
! 					pp->p_fstype = v;
! 	gottype:
  
! 					/* Note: NXTNUM will break us out of the switch only */
! 					switch (pp->p_fstype) {
  
! 						case FS_UNUSED:				/* XXX */
! 							/* are these really used for anything? */
! 							NXTNUM(pp->p_fsize);
! 							if (pp->p_fsize == 0)
! 								break;
! 							NXTNUM(v);
! 							pp->p_frag = v / pp->p_fsize;
! 							break;
! 
! 						/* These happen to be the same */
! 						case FS_BSDFFS:
! 						case FS_BSDLFS:
! 							/* allow us to accept defaults for fsize/frag/cpg */
! 							if (tp)
! 							{
! 								NXTNUM(pp->p_fsize);
! 								if (pp->p_fsize == 0)
! 									break;
! 								NXTNUM(v);
! 								pp->p_frag = v / pp->p_fsize;
! 								NXTNUM(pp->p_cpg);
! 							}
! 							else
! 							{
! /* FIX!  These are too low, but are traditional */
! 								pp->p_fsize = DEFAULT_NEWFS_BLOCK;
! 								pp->p_frag  = (unsigned char) DEFAULT_NEWFS_FRAG;
! 								pp->p_cpg   = DEFAULT_NEWFS_CPG;
! 								/* FIX! we should make these adaptive */
! 							}
! 							break;
! 
! 						default:
! 							break;
! 					}
! 					/* note: we may not have gotten all the entries for the fs */
! 					/* though if we didn't, errors will be set. */
! 				}
  			}
  			continue;
  		}
***************
*** 1250,1255 ****
--- 1334,1342 ----
  	register struct partition *pp;
  	int i, errors = 0;
  	char part;
+ 	unsigned long total_size,total_percent,current_offset;
+ 	int seen_default_offset;
+ 	int hog_part;
  
  	if (lp->d_secsize == 0) {
  		fprintf(stderr, "sector size 0\n");
***************
*** 1286,1291 ****
--- 1373,1547 ----
  	if (lp->d_npartitions > MAXPARTITIONS)
  		Warning("number of partitions (%lu) > MAXPARTITIONS (%d)",
  		    (u_long)lp->d_npartitions, MAXPARTITIONS);
+ 
+ 	/* first allocate space to the partitions, then offsets */
+ 	total_size = 0; /* in sectors */
+ 	total_percent = 0; /* in percent */
+ 	hog_part = -1;
+ 	/* find all fixed partitions */
+ 	for (i = 0; i < lp->d_npartitions; i++) {
+ 		pp = &lp->d_partitions[i];
+ 		if (part_set[i])
+ 		{
+ 			if (part_size_type[i] == '*')
+ 			{
+ 				/* partition 2 ('c') is special */
+ 				if (i == FULL_DISK_PART)
+ 					pp->p_size = lp->d_secperunit;
+ 				else {
+ 					if (hog_part != -1)
+ 						Warning("Too many '*'-sized partitions (%c and %c)",
+ 								hog_part+'a',i+'a');
+ 					else
+ 						hog_part = i;
+ 				}
+ 			}
+ 			else
+ 			{
+ 				char *type;
+ 				unsigned long size;
+ 
+ 				size = pp->p_size;
+ 				switch (part_size_type[i])
+ 				{
+ 					case '%':
+ 						total_percent += size;
+ 						break;
+ 
+ 					case 'k':
+ 					case 'K':
+ 						size *= 1024UL;
+ 						break;
+ 
+ 					case 'm':
+ 					case 'M':
+ 						size *= ((unsigned long) 1024*1024);
+ 						break;
+ 
+ 					case 'g':
+ 					case 'G':
+ 						size *= ((unsigned long) 1024*1024*1024);
+ 						break;
+ 
+ 					case '\0':
+ 						break;
+ 
+ 					default:
+ 						Warning("unknown size specifier '%c' (K/M/G are valid)",part_size_type[i]);
+ 						break;
+ 				}
+ 				/* don't count %'s yet */
+ 				if (part_size_type[i] != '%')
+ 				{
+ 					/* for all not in sectors, convert to sectors */
+ 					if (part_size_type[i] != '\0')
+ 					{
+ 						if (size % lp->d_secsize != 0)
+ 							Warning("partition %c not an integer number of sectors",
+ 									i + 'a');
+ 						size /= lp->d_secsize;
+ 						pp->p_size = size;
+ 					}
+ 					/* else already in sectors */
+ 					/* partition 2 ('c') is special */
+ 					if (i != FULL_DISK_PART)
+ 						total_size += size;
+ 				}
+ 			}
+ 		}
+ 	}
+ 	/* handle % partitions - note %'s don't need to add up to 100! */
+ 	if (total_percent != 0)
+ 	{
+ 		long free_space = lp->d_secperunit - total_size;
+ 
+ 		if (total_percent > 100)
+ 		{
+ 			fprintf(stderr,"total percentage %d is greater than 100\n",
+ 					total_percent);
+ 			errors++;
+ 		}
+ 
+ 		if (free_space > 0)
+ 		{
+ 			for (i = 0; i < lp->d_npartitions; i++) {
+ 				pp = &lp->d_partitions[i];
+ 				if (part_set[i] && part_size_type[i] == '%')
+ 				{
+ 					unsigned long old_size = pp->p_size;
+ 
+ 					/* careful of overflows! and integer roundoff */
+ 					pp->p_size = ((double)pp->p_size/100) * free_space;
+ 					total_size += pp->p_size;
+ 
+ 					/* FIX we can lose a sector or so due to roundoff per
+ 					   partition.  A more complex algorithm could avoid that */
+ 				}
+ 			}
+ 		}
+ 		else
+ 		{
+ 			fprintf(stderr,
+ 					"%ld sectors available to give to '*' and '%' partitions\n",
+ 					free_space);
+ 			errors++;
+ 			/* fix?  set all % partitions to size 0? */
+ 		}
+ 	}
+ 	/* give anything remaining to the hog partition */
+ 	if (hog_part != -1)
+ 	{
+ 		lp->d_partitions[hog_part].p_size = lp->d_secperunit - total_size;
+ 		total_size = lp->d_secperunit;
+ 	}
+ 
+ 	/* Now set the offsets for each partition */
+ 	current_offset = 0; /* in sectors */
+ 	seen_default_offset = 0;
+ 	for (i = 0; i < lp->d_npartitions; i++) {
+ 		part = 'a' + i;
+ 		pp = &lp->d_partitions[i];
+ 		if (part_set[i])
+ 		{
+ 			if (part_offset_type[i] == '*')
+ 			{
+ 				/* partition 2 ('c') is special */
+ 				if (i == FULL_DISK_PART)
+ 					pp->p_offset = 0;
+ 				else
+ 				{
+ 					pp->p_offset = current_offset;
+ 					seen_default_offset = 1;
+ 				}
+ 			}
+ 			else
+ 			{
+ 				/* allow them to be out of order for old-style tables */
+ 				/* partition 2 ('c') is special */
+ 				if (pp->p_offset < current_offset && seen_default_offset &&
+ 					i != FULL_DISK_PART)
+ 				{
+ 					fprintf(stderr,
+ 							"Offset %ld for partition %c overlaps previous partition which ends at %ld\n",
+ 							pp->p_offset,i+'a',current_offset);
+ 					fprintf(stderr,
+ 							"Labels with any *'s for offset must be in ascending order by sector\n");
+ 					errors++;
+ 				}
+ 				else if (pp->p_offset != current_offset &&
+ 						 i != FULL_DISK_PART && seen_default_offset)
+ 				{
+ 					/* this may give unneeded warnings if partitions are out-of-order */
+ 					Warning("Offset %ld for partition %c doesn't match expected value %ld",
+ 							pp->p_offset,i+'a',current_offset);
+ 				}
+ 			}
+ 			/* partition 2 ('c') is special */
+ 			if (i != FULL_DISK_PART)
+ 				current_offset = pp->p_offset + pp->p_size; 
+ 		}
+ 	}
+ 
  	for (i = 0; i < lp->d_npartitions; i++) {
  		part = 'a' + i;
  		pp = &lp->d_partitions[i];
***************
*** 1311,1316 ****
--- 1567,1596 ----
  			    part);
  			errors++;
  		}
+ 
+ 		/* check for overlaps */
+ 		{
+ 			int j;
+ 			register struct partition *pp2;
+ 
+ 			/* this will check for all possible overlaps once and only once */
+ 			for (j = 0; j < i; j++) {
+ 				/* partition 2 ('c') is special */
+ 				if (j != FULL_DISK_PART && i != FULL_DISK_PART &&
+ 					part_set[i] && part_set[j])
+ 				{
+ 					pp2 = &lp->d_partitions[j];
+ 					if (pp2->p_offset < pp->p_offset + pp->p_size &&
+ 						(pp2->p_offset + pp2->p_size > pp->p_offset ||
+ 						 pp2->p_offset >= pp->p_offset))
+ 					{
+ 						fprintf(stderr,"partitions %c and %c overlap!\n",
+ 								j+'a', i+'a');
+ 						errors++;
+ 					}
+ 				}
+ 			}
+ 		}
  	}
  	for (; i < MAXPARTITIONS; i++) {
  		part = 'a' + i;
***************
*** 1421,1445 ****
  	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
  		"usage: disklabel [-r] disk",
  		"\t\t(to read label)",
! 		"       disklabel -w [-r] disk type [ packid ]",
  		"\t\t(to write label with existing boot program)",
! 		"       disklabel -e [-r] disk",
  		"\t\t(to edit label)",
! 		"       disklabel -R [-r] disk protofile",
  		"\t\t(to restore label with existing boot program)",
  #if NUMBOOT > 1
! 		"       disklabel -B [ -b boot1 [ -s boot2 ] ] disk [ type ]",
  		"\t\t(to install boot program with existing label)",
! 		"       disklabel -w -B [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
  		"\t\t(to write label and boot program)",
! 		"       disklabel -R -B [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
  		"\t\t(to restore label and boot program)",
  #else
! 		"       disklabel -B [ -b bootprog ] disk [ type ]",
  		"\t\t(to install boot program with existing on-disk label)",
! 		"       disklabel -w -B [ -b bootprog ] disk type [ packid ]",
  		"\t\t(to write label and install boot program)",
! 		"       disklabel -R -B [ -b bootprog ] disk protofile [ type ]",
  		"\t\t(to restore label and install boot program)",
  #endif
  		"       disklabel [-NW] disk",
--- 1701,1725 ----
  	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
  		"usage: disklabel [-r] disk",
  		"\t\t(to read label)",
! 		"       disklabel -w [-r] [-n] disk type [ packid ]",
  		"\t\t(to write label with existing boot program)",
! 		"       disklabel -e [-r] [-n] disk",
  		"\t\t(to edit label)",
! 		"       disklabel -R [-r] [-n] disk protofile",
  		"\t\t(to restore label with existing boot program)",
  #if NUMBOOT > 1
! 		"       disklabel -B [-n] [ -b boot1 [ -s boot2 ] ] disk [ type ]",
  		"\t\t(to install boot program with existing label)",
! 		"       disklabel -w -B [-n] [ -b boot1 [ -s boot2 ] ] disk type [ packid ]",
  		"\t\t(to write label and boot program)",
! 		"       disklabel -R -B [-n] [ -b boot1 [ -s boot2 ] ] disk protofile [ type ]",
  		"\t\t(to restore label and boot program)",
  #else
! 		"       disklabel -B [-n] [ -b bootprog ] disk [ type ]",
  		"\t\t(to install boot program with existing on-disk label)",
! 		"       disklabel -w -B [-n] [ -b bootprog ] disk type [ packid ]",
  		"\t\t(to write label and install boot program)",
! 		"       disklabel -R -B [-n] [ -b bootprog ] disk protofile [ type ]",
  		"\t\t(to restore label and install boot program)",
  #endif
  		"       disklabel [-NW] disk",
***************
*** 1447,1457 ****
  #else
  	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
  		"usage: disklabel [-r] disk", "(to read label)",
! 		"       disklabel -w [-r] disk type [ packid ]",
  		"\t\t(to write label)",
! 		"       disklabel -e [-r] disk",
  		"\t\t(to edit label)",
! 		"       disklabel -R [-r] disk protofile",
  		"\t\t(to restore label)",
  		"       disklabel [-NW] disk",
  		"\t\t(to write disable/enable label)");
--- 1727,1737 ----
  #else
  	fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
  		"usage: disklabel [-r] disk", "(to read label)",
! 		"       disklabel -w [-r] [-n] disk type [ packid ]",
  		"\t\t(to write label)",
! 		"       disklabel -e [-r] [-n] disk",
  		"\t\t(to edit label)",
! 		"       disklabel -R [-r] [-n] disk protofile",
  		"\t\t(to restore label)",
  		"       disklabel [-NW] disk",
  		"\t\t(to write disable/enable label)");




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?ybuitq6atnk.fsf>