From: Ben Gras Date: Wed, 3 Aug 2005 10:24:53 +0000 (+0000) Subject: More autopart/setup fixes X-Git-Tag: v3.1.0~470 X-Git-Url: http://zhaoyanbai.com/repos/Bv9ARM.ch04.html?a=commitdiff_plain;h=6f1c7d6016563ffe243dd232963dd855c8a01bb9;p=minix.git More autopart/setup fixes --- diff --git a/commands/ibm/autopart.c b/commands/ibm/autopart.c index 11fb7233d..e8a5ea6e5 100755 --- a/commands/ibm/autopart.c +++ b/commands/ibm/autopart.c @@ -31,6 +31,7 @@ #include #include #include +#include /* True if a partition is an extended partition. */ #define ext_part(s) ((s) == 0x05 || (s) == 0x0F) @@ -64,7 +65,40 @@ Num Sort Type #define arraysize(a) (sizeof(a) / sizeof((a)[0])) #define arraylimit(a) ((a) + arraysize(a)) -#define SORNOT(n) ((n) == 1 ? " " : "s") +#define SORNOT(n) ((n) == 1 ? "" : "s") + +/* screen colours */ +#define COL_RED 1 +#define COL_GREEN 2 +#define COL_ORANGE 3 +#define COL_BLUE 4 +#define COL_MAGENTA 5 +#define COL_CYAN 6 + +#define SURE_SERIOUS 1 +#define SURE_BACK 2 + +void col(int col) +{ + if(!col) printf("\033[0m"); + else printf("\033[3%dm", col % 10); +} + +void type2col(int type) +{ + switch(type) { + /* minix */ + case 0x80: + case MINIX_PART: col(COL_GREEN); break; + + /* dos/windows */ + case 0x0B: case 0x0C: case 0x0E: case 0x0F: case 0x42: + case 0x07: col(COL_CYAN); break; + + /* linux */ + case 0x82: case 0x83: col(COL_ORANGE); break; + } +} int probing = 0, autopartmode = 0; @@ -1717,10 +1751,75 @@ int cylinderalign(region_t *reg) return reg->free_sec_last > reg->free_sec_start; } +void regionize(void) +{ + int free_sec, i, si; + + sort(); + + free_sec = table[0].lowsec + sectors; + + /* Create region data used in autopart mode. */ + free_regions = used_regions = nr_regions = nr_partitions = 0; + for(si = 1; si <= NR_PARTITIONS; si++) { + i = sort_order[si]; + if(i < 1 || i > NR_PARTITIONS) { + printf("Sorry, something unexpected has happened (%d out of range).\n", i); + exit(1); + } + + if(table[i].sysind == NO_PART) + break; + + /* Free space before this partition? */ + if(table[i].lowsec > free_sec) { + /* Free region before this partition. */ + regions[nr_regions].free_sec_start = free_sec; + regions[nr_regions].free_sec_last = table[i].lowsec-1; + regions[nr_regions].is_used_part = 0; + if(cylinderalign(®ions[nr_regions])) { + nr_regions++; + free_regions++; + } + } + + /* Sanity check. */ + if(autopartmode && si > 1) { + if(table[i].lowsec < table[sort_order[si-1]].lowsec || + table[i].lowsec < table[sort_order[si-1]].lowsec + table[sort_order[si-1]].size) { + printf("Sanity check failed - partitions overlap.\n" + "Please use expert mode to correct it.\n"); + exit(1); + } + } + + /* Remember used region. */ + memcpy(®ions[nr_regions].used_part, &table[i], sizeof(table[i])); + free_sec = table[i].lowsec+table[i].size; + regions[nr_regions].is_used_part = 1; + regions[nr_regions].tableno = i; + nr_partitions++; + nr_regions++; + used_regions++; + } + + /* Special case: space after partitions. */ + if(free_sec < table[0].size-1) { + regions[nr_regions].free_sec_start = free_sec; + regions[nr_regions].free_sec_last = table[0].lowsec + table[0].size-1; + regions[nr_regions].is_used_part = 0; + if(cylinderalign(®ions[nr_regions])) { + nr_regions++; + free_regions++; + } + } + +} + void m_read(int ev, object_t *op) /* Read the partition table from the current device. */ { - int si, i, mode, n, r, free_sec, v; + int si, i, mode, n, r, v; struct part_entry *pe; if (ev != 'r' || device >= 0) return; @@ -1815,62 +1914,7 @@ void m_read(int ev, object_t *op) stat_end(5); } - free_sec = table[0].lowsec + sectors; - - /* Create region data used in autopart mode. */ - free_regions = used_regions = nr_regions = nr_partitions = 0; - for(si = 1; si <= NR_PARTITIONS; si++) { - i = sort_order[si]; - if(i < 1 || i > NR_PARTITIONS) { - printf("Sorry, something unexpected has happened (%d out of range).\n", i); - exit(1); - } - - if(table[i].sysind == NO_PART) - break; - - /* Free space before this partition? */ - if(table[i].lowsec > free_sec) { - /* Free region before this partition. */ - regions[nr_regions].free_sec_start = free_sec; - regions[nr_regions].free_sec_last = table[i].lowsec-1; - regions[nr_regions].is_used_part = 0; - if(cylinderalign(®ions[nr_regions])) { - nr_regions++; - free_regions++; - } - } - - /* Sanity check. */ - if(autopartmode && si > 1) { - if(table[i].lowsec < table[sort_order[si-1]].lowsec || - table[i].lowsec < table[sort_order[si-1]].lowsec + table[sort_order[si-1]].size) { - printf("Sanity check failed - partitions overlap.\n" - "Please use expert mode to correct it.\n"); - exit(1); - } - } - - /* Remember used region. */ - memcpy(®ions[nr_regions].used_part, &table[i], sizeof(table[i])); - free_sec = table[i].lowsec+table[i].size; - regions[nr_regions].is_used_part = 1; - regions[nr_regions].tableno = i; - nr_partitions++; - nr_regions++; - used_regions++; - } - - /* Special case: space after partitions. */ - if(free_sec < table[0].size-1) { - regions[nr_regions].free_sec_start = free_sec; - regions[nr_regions].free_sec_last = table[0].lowsec + table[0].size-1; - regions[nr_regions].is_used_part = 0; - if(cylinderalign(®ions[nr_regions])) { - nr_regions++; - free_regions++; - } - } + regionize(); } void m_write(int ev, object_t *op) @@ -1988,38 +2032,29 @@ void m_shell(int ev, object_t *op) event(ctrl('L'), op); } -void m_dump(int ev, object_t *op) +void m_dump(struct part_entry *print_table) /* Raw dump of the partition table. */ { - struct part_entry table[NR_PARTITIONS], *pe; + struct part_entry *pe; int i; unsigned chs[3]; - if (ev != 'p' || device < 0) return; - - memcpy(table, bootblock+PART_TABLE_OFF, - NR_PARTITIONS * sizeof(table[0])); - for (i= 0; i < NR_PARTITIONS; i++) { - pe= &table[i]; - stat_start(0); +printf(" Partition + type Cyl Head Sec Cyl Head Sec Base Size Kb\n"); + for (i= 1; i <= NR_PARTITIONS; i++) { + pe= &print_table[i]; dos2chs(&pe->start_head, chs); printf("%2d%c %02X%15d%5d%4d", - i+1, + i, pe->bootind & ACTIVE_FLAG ? '*' : ' ', pe->sysind, chs[0], chs[1], chs[2]); dos2chs(&pe->last_head, chs); - printf("%6d%5d%4d%10lu%10ld%9lu", + printf("%6d%5d%4d%10lu%10ld%9lu\n", chs[0], chs[1], chs[2], pe->lowsec, howend == SIZE ? pe->size : pe->size + pe->lowsec - 1, pe->size / 2); - stat_end(10); } - stat_start(0); - printf("(Raw dump of the original %.40s table)", - curdev->subname); - stat_end(10); } int quitting= 0; @@ -2117,7 +2152,6 @@ void event(int ev, object_t *op) m_read(ev, op); m_write(ev, op); m_shell(ev, op); - m_dump(ev, op); m_quit(ev, op); } @@ -2226,23 +2260,49 @@ printregions(region_t *theregions, int indent, int p_nr_partitions, int p_free_r if(reg->is_used_part) { char *name; name = typ2txt(reg->used_part.sysind); - printf("%*s\033[31m", indent, ""); + printf("%*s", indent, ""); type2col(reg->used_part.sysind); if(numbers) printf("%2d. ", r); printf("In use by %-10s ", name); units = reg->used_part.size / 2; - printf("\033[0m (%s)\n", prettysizeprint(units)); + col(0); + printf(" (%s)\n", prettysizeprint(units)); } else if(!nofree) { - printf("%*s\033[36m", indent, ""); + printf("%*s", indent, ""); if(numbers) printf("%2d. ", r); printf("Free space "); units = ((reg->free_sec_last - reg->free_sec_start+1))/2; - printf("\033[0m (%s)\n", prettysizeprint(units)); + printf(" (%s)\n", prettysizeprint(units)); } } + if(p_nr_partitions >= NR_PARTITIONS && p_free_regions) { + printf( +"\nNote: there is free space on this disk, but I'm not showing it,\n" +"because there isn't a free slot to use it. You can free up a slot\n" +"by deleting an in-use region, or use expert mode.\n"); + } + return; } +int +is_sure(int flags, char *fmt, ...) +{ + char yesno[10]; + va_list ap; + va_start (ap, fmt); + vprintf(fmt, ap); + va_end(ap); + if(flags & SURE_SERIOUS) printf(" ('yes' or 'no' please) "); + else { + printf(" (y/n) [y] "); + } + fflush(stdout); + if(!fgets(yesno, sizeof(yesno)-1, stdin)) exit(1); + if(!(flags & SURE_SERIOUS)) return (tolower(yesno[0]) != 'n'); + return !strncmp(yesno, "yes", 3); +} + int may_kill_region(void) { @@ -2251,9 +2311,11 @@ may_kill_region(void) if(used_regions < 1) return 1; + printf("\n-- STEP 2 -- Optionally delete regions -----------------------------\n\n"); + printregions(regions, 0, nr_partitions, free_regions, nr_regions, 1); printf("\nIf you want to delete an in-use region to free it up for MINIX,\n" - "type its number.\nOtherwise hit ENTER to continue: "); + "type its number. Otherwise hit ENTER to continue: "); fflush(NULL); fgets(line, sizeof(line)-2, stdin); if(!isdigit(line[0])) @@ -2272,24 +2334,26 @@ may_kill_region(void) i = regions[r].tableno; - printf("Are you absolutely positive you want to delete this region,\n" + if(is_sure(0, "Are you sure you want to delete this region,\n" "losing all data it contains?\n" "You have selected a region used\n" "by %s (%s).\n" - "Please type yes or no: ", - typ2txt(table[i].sysind), - prettysizeprint(table[i].size / 2)); - fgets(line, sizeof(line)-2, stdin); - if(!strncmp(line, "yes", 3)) { + "I won't actually update your disk right away, but still. Sure?", + typ2txt(table[i].sysind), prettysizeprint(table[i].size / 2))) { table[i].sysind = NO_PART; dirty = 1; + regionize(); } + + /* User may go again. */ + return 0; } + region_t * select_region(void) { - int r, rem, rn; + int r, rem, rn, sure = 0; static char line[100]; region_t *reg; int nofree = 0; @@ -2316,17 +2380,21 @@ select_region(void) SORNOT(nr_regions), prettysizeprint(table[0].size/2)); printregions(regions, 0, nr_partitions, free_regions, nr_regions, 1); - if(nofree) { - printf("\nOnly the expert mode can free a slot to use the free space.\n"); + if(used_regions > 0) { + printf("\nIf you select a region that is already in use,\n" + "it will be overwritten.\n"); } if(nr_regions > 1) { - printf("\nPlease enter region number you want to use: "); + printf("\nPlease enter region number you want to use,\n" + "or ENTER to go back a step to free a region: "); fflush(NULL); if(!fgets(line, sizeof(line)-2, stdin)) exit(1); + if(line[0] == '\n') return NULL; + if(sscanf(line, "%d", &rn) != 1) continue; @@ -2340,17 +2408,12 @@ select_region(void) continue; } - printf("Really use region number %d? Please enter 'yes' or 'no': ", rn); - fflush(NULL); + sure = is_sure(0, "Please confirm you want to use region no. %d?", rn); } else { rn = 0; - printf("\nUse this region? Please enter 'yes' or 'no': "); - fflush(NULL); + sure = is_sure(0, "\nUse this region?"); } - - if(!fgets(line, sizeof(line)-2, stdin)) - exit(1); - } while(strncmp(line, "yes", 3)); + } while(!sure); return(®ions[rn]); } @@ -2358,13 +2421,11 @@ select_region(void) device_t * select_disk(void) { - + int sure = 0; int i, choice, drives; static char line[500]; - printf("Probing for disks. This may take a short while.\n" - "You can ignore errors while probing. If the system hangs,\n" - "please try expert mode.\n\n"); + printf("Probing for disks. This may take a short while. Please ignore error messages.\n"); do { i = 0; @@ -2401,16 +2462,10 @@ select_disk(void) for(i = 0; i < drives; i++) { if(drives > 1) - printf(" %2d. ", i); + printf("\n %2d. ", i); else printf(" "); - printf(" (%s) %d allocated region%s", - devices[i].dev->name, - devices[i].used_regions, SORNOT(devices[i].used_regions)); - if(devices[i].used_regions < NR_PARTITIONS) { - printf(", %d unallocated one%s ", - devices[i].free_regions, SORNOT(devices[i].free_regions)); - } - printf(" (%s)\n", prettysizeprint(devices[i].sectors/2)); + printf(" (%s, ", devices[i].dev->name); + printf("%s)\n", prettysizeprint(devices[i].sectors/2)); printregions(devices[i].regions, 8, devices[i].nr_partitions, devices[i].free_regions, @@ -2427,21 +2482,15 @@ select_disk(void) printf("Number out of range.\n"); continue; } - printf("\nUse disk number %d (%s)? ", - choice, devices[choice].dev->name); - fflush(NULL); - if(!fgets(line, sizeof(line)-2, stdin)) + if(!(sure = is_sure(0, "\nPlease confirm you want to use disk %d (%s)?", + choice, devices[choice].dev->name))) exit(1); } else { - printf("\nUse this disk? "); - choice = 0; - fflush(NULL); - if(!fgets(line, sizeof(line)-2, stdin)) - exit(1); - if(line[0] != 'y' && line[0] != 'Y') + if(!(sure = is_sure(0, "\nUse this disk?"))) exit(1); + choice = 0; } - } while(line[0] != 'y' && line[0] != 'Y'); + } while(!sure); return devices[choice].dev; } @@ -2482,10 +2531,11 @@ scribble_region(region_t *reg, struct part_entry **pe) newpart->size = reg->free_sec_last - reg->free_sec_start + 1; changed = 1; } else newpart = ®->used_part; + check_ind(newpart); newpart->sysind = MINIX_PART; *pe = newpart; changed = 1; - + dirty = 1; return changed; } @@ -2494,12 +2544,29 @@ do_autopart(int resultfd) { region_t *r; struct part_entry *pe; + char sure[50]; + struct part_entry orig_table[1 + NR_PARTITIONS]; nordonly = 1; probing = 1; autopartmode = 1; - /* Select drive. */ + printf("\nWelcome to the autopart process. There are four steps.\n\n" + "1. Select the drive you want to use.\n" + "2. Optionally delete in-use regions(s), if they exist.\n" + "3. Select a region to install MINIX in.\n" + "4. After confirmation, write new table to disk.\n" + "\n" + "As you can see, nothing will happen to your disk before the\n" + "last step. Then I will print the new table and let you confirm it.\n\n" + ); + + printf("Press ENTER to continue: "); + fflush(stdout); + if(!fgets(sure, sizeof(sure)-1, stdin)) exit(1); + + printf("\n-- STEP 1 -- Select drive -----------------------------------------\n\n"); + do { curdev = select_disk(); } while(!curdev); @@ -2510,39 +2577,43 @@ do_autopart(int resultfd) } recompute0(); - /* Allow for partition to be killed. */ - do { - m_read('r', NULL); - } while(!may_kill_region()); - - /* Update changes. */ - if(dirty) { - m_write('w', NULL); - } - - if(dirty) { - printf("Something went wrong writing.\n"); - exit(1); - } - - if (device >= 0) { close(device); device= -1; } - - /* Reread contents. */ m_read('r', NULL); - /* Show regions. */ + memcpy(orig_table, table, sizeof(table)); + do { + /* Allow for partition(s) to be killed. */ + while(!may_kill_region()) + ; + + printf("\n-- STEP 3 -- Select region to install in ---------------------------\n\n"); + + /* Show regions. */ r = select_region(); - } while(!r); + } while(!r); /* Back to step 2. */ + + printf("\n-- STEP 4 -- Write table to disk -----------------------------------\n\n"); /* Write things. */ if(scribble_region(r, &pe)) { char *name; int i, found = -1; char partbuf[100]; - dirty = 1; + + +#if 0 + printf("\nThis is your current partition table:\n"); + m_dump(orig_table); + printf("\nThis will be your new partition table:\n"); + m_dump(table); +#endif + + if(!is_sure(SURE_SERIOUS, "This is the point of no return.\n" + "Nothing has actually been written so far.\n" + "Are you sure you want to write it?")) + return 1; + m_write('w', NULL); - if(dirty) return 1; /* Retrieve partition number in sorted order that we * have scribbled in. */ @@ -2645,11 +2716,13 @@ int main(int argc, char **argv) while((c = getopt(argc, argv, "f:")) != EOF) { switch(c) { case 'f': + /* Make sure old data file is gone. */ unlink(optarg); if((resultfd=open(optarg, O_CREAT | O_WRONLY | O_TRUNC)) < 0) { perror(optarg); return 1; } + sync(); /* Make sure no old data file lingers. */ break; default: fprintf(stderr, "Unknown option\n"); diff --git a/commands/scripts/setup.sh b/commands/scripts/setup.sh index 14a5d9f06..18687ea43 100755 --- a/commands/scripts/setup.sh +++ b/commands/scripts/setup.sh @@ -90,12 +90,7 @@ ok="" while [ "$ok" = "" ] do echo -n "Welcome to Minix partitioning. Do you want to -follow the (A)utomatic or the e(X)pert mode? Expert mode drops -you into part to let you edit your partition table to taste. -Automatic mode is much easier, but can't handle all cases. In -cases it can't handle, it will tell you to use expert mode. -Please choose, A for Automatic, or X for Expert: [A] " - +follow the (A)utomatic or the e(X)pert mode? [A] " read ch case "$ch" in [Aa]*) auto="1"; ok="yes"; ;; @@ -145,9 +140,6 @@ else while [ -z "$primary" ] do PF="/tmp/pf" - echo -n "Press return to enter the autopart tool, or DEL to abort. -:" - read ret if autopart -f$PF then if [ -s "$PF" ] then @@ -383,7 +375,7 @@ if [ $cache -eq 0 ]; then cache=; else cache="ramsize=$cache"; fi # Make bootable. installboot -d /dev/$root /usr/mdec/bootblock /boot/boot >/dev/null || exit -edparams /dev/$root "rootdev=$root; ramimagedev=$root; $cache; $inetparams; main() { trap 2000 boot; menu; }; save" || exit +edparams /dev/$root "rootdev=$root; ramimagedev=$root; $cache; $inetparams; main() { echo \"This is the MINIX 3 boot monitor.\"; echo \"MINIX will load in 5 seconds, or press ESC.\"; trap 5000 boot; menu; }; save" || exit pfile="/usr/src/tools/fdbootparams" echo "Remembering boot parameters in ${pfile}." echo "rootdev=$root; ramimagedev=$root; $cache; save" >$pfile || exit