From owner-svn-src-all@FreeBSD.ORG Mon Jun 15 07:17:55 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9FE61106564A; Mon, 15 Jun 2009 07:17:55 +0000 (UTC) (envelope-from brian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8CD858FC0A; Mon, 15 Jun 2009 07:17:55 +0000 (UTC) (envelope-from brian@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5F7Hteq082408; Mon, 15 Jun 2009 07:17:55 GMT (envelope-from brian@svn.freebsd.org) Received: (from brian@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5F7HtaW082406; Mon, 15 Jun 2009 07:17:55 GMT (envelope-from brian@svn.freebsd.org) Message-Id: <200906150717.n5F7HtaW082406@svn.freebsd.org> From: Brian Somers Date: Mon, 15 Jun 2009 07:17:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r194234 - stable/7/sbin/fdisk X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Jun 2009 07:17:56 -0000 Author: brian Date: Mon Jun 15 07:17:55 2009 New Revision: 194234 URL: http://svn.freebsd.org/changeset/base/194234 Log: MFC: r192745: Enhance the 'p' command so that it understands size qualifiers (K/M/G) and so that it understands '*' as 'DTRT'. PR: 68312 Modified: stable/7/sbin/fdisk/ (props changed) stable/7/sbin/fdisk/fdisk.8 stable/7/sbin/fdisk/fdisk.c Modified: stable/7/sbin/fdisk/fdisk.8 ============================================================================== --- stable/7/sbin/fdisk/fdisk.8 Mon Jun 15 04:31:34 2009 (r194233) +++ stable/7/sbin/fdisk/fdisk.8 Mon Jun 15 07:17:55 2009 (r194234) @@ -372,6 +372,31 @@ starting at sector for .Ar length sectors. +If the +.Ar start +or +.Ar length +is suffixed with a +.Em K , +.Em M +or +.Em G , +it is taken as a +.Em Kilobyte , +.Em Megabyte +or +.Em Gigabyte +measurement respectively. +If the +.Ar start +is given as +.Qq * +it is set to the value of the previous partition end. +If the +.Ar length +is given as +.Qq * +the partition end is set to the end of the disk. .Pp Only those slices explicitly mentioned by these lines are modified; any slice not referenced by a @@ -421,6 +446,17 @@ for 2503871 sectors (note: these numbers downwards to correspond to head and cylinder boundaries): .Pp .Dl "p 1 165 1 2503871" +.Pp +Example: to set slices 1, 2 and 4 to +.Fx +slices, the first being 2 Gigabytes, the second being 10 Gigabytes and the +forth being the remainder of the disk (again, numbers will be rounded +appropriately): +.Pp +.Dl "p 1 165 63 2G" +.Dl "p 2 165 * 10G" +.Dl "p 3 0 0 0" +.Dl "p 4 165 * *" .It Ic a Ar slice Make .Ar slice Modified: stable/7/sbin/fdisk/fdisk.c ============================================================================== --- stable/7/sbin/fdisk/fdisk.c Mon Jun 15 04:31:34 2009 (r194233) +++ stable/7/sbin/fdisk/fdisk.c Mon Jun 15 07:17:55 2009 (r194234) @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); int iotest; +#define NOSECTORS ((u_int32_t)-1) #define LBUF 100 static char lbuf[LBUF]; @@ -107,6 +108,7 @@ typedef struct cmd { struct arg { char argtype; int arg_val; + char *arg_str; } args[MAX_ARGS]; } CMD; @@ -1001,16 +1003,23 @@ parse_config_line(char *line, CMD *comma */ while (1) { while (isspace(*cp)) ++cp; + if (*cp == '\0') + break; /* eol */ if (*cp == '#') break; /* found comment */ if (isalpha(*cp)) command->args[command->n_args].argtype = *cp++; - if (!isdigit(*cp)) - break; /* assume end of line */ end = NULL; command->args[command->n_args].arg_val = strtol(cp, &end, 0); - if (cp == end) - break; /* couldn't parse number */ + if (cp == end || (!isspace(*end) && *end != '\0')) { + char ch; + end = cp; + while (!isspace(*end) && *end != '\0') ++end; + ch = *end; *end = '\0'; + command->args[command->n_args].arg_str = strdup(cp); + *end = ch; + } else + command->args[command->n_args].arg_str = NULL; cp = end; command->n_args++; } @@ -1109,6 +1118,33 @@ process_geometry(CMD *command) return (status); } +static u_int32_t +str2sectors(const char *str) +{ + char *end; + unsigned long val; + + val = strtoul(str, &end, 0); + if (str == end || *end == '\0') { + warnx("ERROR line %d: unexpected size: \'%s\'", + current_line_number, str); + return NOSECTORS; + } + + if (*end == 'K') + val *= 1024UL / secsize; + else if (*end == 'M') + val *= 1024UL * 1024UL / secsize; + else if (*end == 'G') + val *= 1024UL * 1024UL * 1024UL / secsize; + else { + warnx("ERROR line %d: unexpected modifier: %c " + "(not K/M/G)", current_line_number, *end); + return NOSECTORS; + } + + return val; +} static int process_partition(CMD *command) @@ -1134,8 +1170,48 @@ process_partition(CMD *command) partp = ((struct dos_partition *) &mboot.parts) + partition - 1; bzero((char *)partp, sizeof (struct dos_partition)); partp->dp_typ = command->args[1].arg_val; - partp->dp_start = command->args[2].arg_val; - partp->dp_size = command->args[3].arg_val; + if (command->args[2].arg_str != NULL) { + if (strcmp(command->args[2].arg_str, "*") == 0) { + int i; + partp->dp_start = dos_sectors; + for (i = 1; i < partition; i++) { + struct dos_partition *prev_partp; + prev_partp = ((struct dos_partition *) + &mboot.parts) + i - 1; + if (prev_partp->dp_typ != 0) + partp->dp_start = prev_partp->dp_start + + prev_partp->dp_size; + } + if (partp->dp_start % dos_sectors != 0) { + prev_head_boundary = partp->dp_start / + dos_sectors * dos_sectors; + partp->dp_start = prev_head_boundary + + dos_sectors; + } + } else { + partp->dp_start = str2sectors(command->args[2].arg_str); + if (partp->dp_start == NOSECTORS) + break; + } + } else + partp->dp_start = command->args[2].arg_val; + + if (command->args[3].arg_str != NULL) { + if (strcmp(command->args[3].arg_str, "*") == 0) + partp->dp_size = ((disksecs / dos_cylsecs) * + dos_cylsecs) - partp->dp_start; + else { + partp->dp_size = str2sectors(command->args[3].arg_str); + if (partp->dp_size == NOSECTORS) + break; + } + prev_cyl_boundary = ((partp->dp_start + partp->dp_size) / + dos_cylsecs) * dos_cylsecs; + if (prev_cyl_boundary > partp->dp_start) + partp->dp_size = prev_cyl_boundary - partp->dp_start; + } else + partp->dp_size = command->args[3].arg_val; + max_end = partp->dp_start + partp->dp_size; if (partp->dp_typ == 0) {