17dd7cddfSDavid du Colombier /*
27dd7cddfSDavid du Colombier * prep - prepare plan9 disk partition
37dd7cddfSDavid du Colombier */
47dd7cddfSDavid du Colombier #include <u.h>
57dd7cddfSDavid du Colombier #include <libc.h>
67dd7cddfSDavid du Colombier #include <bio.h>
77dd7cddfSDavid du Colombier #include <disk.h>
87dd7cddfSDavid du Colombier #include "edit.h"
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier enum {
119a747e4fSDavid du Colombier Maxpath = 128,
127dd7cddfSDavid du Colombier };
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier static int blank;
157dd7cddfSDavid du Colombier static int file;
16dc5a79c1SDavid du Colombier static int doautox;
177dd7cddfSDavid du Colombier static int printflag;
187dd7cddfSDavid du Colombier static Part **opart;
197dd7cddfSDavid du Colombier static int nopart;
207dd7cddfSDavid du Colombier static char *osecbuf;
217dd7cddfSDavid du Colombier static char *secbuf;
227dd7cddfSDavid du Colombier static int rdonly;
237dd7cddfSDavid du Colombier static int dowrite;
247dd7cddfSDavid du Colombier static int docache;
2559cc4ca5SDavid du Colombier static int donvram;
267dd7cddfSDavid du Colombier
27dc5a79c1SDavid du Colombier static void autoxpart(Edit*);
287dd7cddfSDavid du Colombier static Part *mkpart(char*, vlong, vlong, int);
297dd7cddfSDavid du Colombier static void rdpart(Edit*);
307dd7cddfSDavid du Colombier static void wrpart(Edit*);
317dd7cddfSDavid du Colombier static void checkfat(Disk*);
327dd7cddfSDavid du Colombier
337dd7cddfSDavid du Colombier static void cmdsum(Edit*, Part*, vlong, vlong);
347dd7cddfSDavid du Colombier static char *cmdadd(Edit*, char*, vlong, vlong);
357dd7cddfSDavid du Colombier static char *cmddel(Edit*, Part*);
367dd7cddfSDavid du Colombier static char *cmdokname(Edit*, char*);
377dd7cddfSDavid du Colombier static char *cmdwrite(Edit*);
387dd7cddfSDavid du Colombier static char *cmdctlprint(Edit*, int, char**);
397dd7cddfSDavid du Colombier
407dd7cddfSDavid du Colombier Edit edit = {
417dd7cddfSDavid du Colombier .add= cmdadd,
427dd7cddfSDavid du Colombier .del= cmddel,
437dd7cddfSDavid du Colombier .okname=cmdokname,
447dd7cddfSDavid du Colombier .sum= cmdsum,
457dd7cddfSDavid du Colombier .write= cmdwrite,
4680ee5cbfSDavid du Colombier
4780ee5cbfSDavid du Colombier .unit= "sector",
487dd7cddfSDavid du Colombier };
497dd7cddfSDavid du Colombier
50dc5a79c1SDavid du Colombier typedef struct Auto Auto;
51dc5a79c1SDavid du Colombier struct Auto
52dc5a79c1SDavid du Colombier {
53dc5a79c1SDavid du Colombier char *name;
54dc5a79c1SDavid du Colombier uvlong min;
55dc5a79c1SDavid du Colombier uvlong max;
56dc5a79c1SDavid du Colombier uint weight;
57dc5a79c1SDavid du Colombier uchar alloc;
58dc5a79c1SDavid du Colombier uvlong size;
59dc5a79c1SDavid du Colombier };
60dc5a79c1SDavid du Colombier
61eba00c11SDavid du Colombier #define TB (1024LL*GB)
62dc5a79c1SDavid du Colombier #define GB (1024*1024*1024)
63dc5a79c1SDavid du Colombier #define MB (1024*1024)
64dc5a79c1SDavid du Colombier #define KB (1024)
65dc5a79c1SDavid du Colombier
66dc5a79c1SDavid du Colombier /*
67dc5a79c1SDavid du Colombier * Order matters -- this is the layout order on disk.
68dc5a79c1SDavid du Colombier */
69dc5a79c1SDavid du Colombier Auto autox[] =
70dc5a79c1SDavid du Colombier {
71dc5a79c1SDavid du Colombier { "9fat", 10*MB, 100*MB, 10, },
72dc5a79c1SDavid du Colombier { "nvram", 512, 512, 1, },
73*b07b71ebSDavid du Colombier { "fscfg", 1024, 8192, 1, },
74dc5a79c1SDavid du Colombier { "fs", 200*MB, 0, 10, },
75dc5a79c1SDavid du Colombier { "fossil", 200*MB, 0, 4, },
76dc5a79c1SDavid du Colombier { "arenas", 500*MB, 0, 20, },
77dc5a79c1SDavid du Colombier { "isect", 25*MB, 0, 1, },
7846dd08baSDavid du Colombier { "bloom", 4*MB, 512*MB, 1, },
7946dd08baSDavid du Colombier
80dc5a79c1SDavid du Colombier { "other", 200*MB, 0, 4, },
81dc5a79c1SDavid du Colombier { "swap", 100*MB, 512*MB, 1, },
82dc5a79c1SDavid du Colombier { "cache", 50*MB, 1*GB, 2, },
83dc5a79c1SDavid du Colombier };
84dc5a79c1SDavid du Colombier
857dd7cddfSDavid du Colombier void
usage(void)867dd7cddfSDavid du Colombier usage(void)
877dd7cddfSDavid du Colombier {
88c39c2eb3SDavid du Colombier fprint(2, "usage: disk/prep [-bcfprw] [-a partname]... [-s sectorsize] /dev/sdC0/plan9\n");
897dd7cddfSDavid du Colombier exits("usage");
907dd7cddfSDavid du Colombier }
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier void
main(int argc,char ** argv)937dd7cddfSDavid du Colombier main(int argc, char **argv)
947dd7cddfSDavid du Colombier {
957dd7cddfSDavid du Colombier int i;
96dc5a79c1SDavid du Colombier char *p;
977dd7cddfSDavid du Colombier Disk *disk;
987dd7cddfSDavid du Colombier vlong secsize;
997dd7cddfSDavid du Colombier
1007dd7cddfSDavid du Colombier secsize = 0;
1017dd7cddfSDavid du Colombier ARGBEGIN{
1027dd7cddfSDavid du Colombier case 'a':
103dc5a79c1SDavid du Colombier p = EARGF(usage());
104dc5a79c1SDavid du Colombier for(i=0; i<nelem(autox); i++){
105dc5a79c1SDavid du Colombier if(strcmp(p, autox[i].name) == 0){
106dc5a79c1SDavid du Colombier if(autox[i].alloc){
107dc5a79c1SDavid du Colombier fprint(2, "you said -a %s more than once.\n", p);
108dc5a79c1SDavid du Colombier usage();
109dc5a79c1SDavid du Colombier }
110dc5a79c1SDavid du Colombier autox[i].alloc = 1;
111dc5a79c1SDavid du Colombier break;
112dc5a79c1SDavid du Colombier }
113dc5a79c1SDavid du Colombier }
114dc5a79c1SDavid du Colombier if(i == nelem(autox)){
115c39c2eb3SDavid du Colombier fprint(2, "don't know how to create automatic partition %s\n", p);
116dc5a79c1SDavid du Colombier usage();
117dc5a79c1SDavid du Colombier }
118dc5a79c1SDavid du Colombier doautox = 1;
1197dd7cddfSDavid du Colombier break;
1207dd7cddfSDavid du Colombier case 'b':
1217dd7cddfSDavid du Colombier blank++;
1227dd7cddfSDavid du Colombier break;
1237dd7cddfSDavid du Colombier case 'c':
1247dd7cddfSDavid du Colombier docache++;
1257dd7cddfSDavid du Colombier break;
1267dd7cddfSDavid du Colombier case 'f':
1277dd7cddfSDavid du Colombier file++;
1287dd7cddfSDavid du Colombier break;
12959cc4ca5SDavid du Colombier case 'n':
13059cc4ca5SDavid du Colombier donvram++;
13159cc4ca5SDavid du Colombier break;
1327dd7cddfSDavid du Colombier case 'p':
1337dd7cddfSDavid du Colombier printflag++;
1347dd7cddfSDavid du Colombier rdonly++;
1357dd7cddfSDavid du Colombier break;
1367dd7cddfSDavid du Colombier case 'r':
1377dd7cddfSDavid du Colombier rdonly++;
1387dd7cddfSDavid du Colombier break;
1397dd7cddfSDavid du Colombier case 's':
1407dd7cddfSDavid du Colombier secsize = atoi(ARGF());
1417dd7cddfSDavid du Colombier break;
1427dd7cddfSDavid du Colombier case 'w':
1437dd7cddfSDavid du Colombier dowrite++;
1447dd7cddfSDavid du Colombier break;
1457dd7cddfSDavid du Colombier default:
1467dd7cddfSDavid du Colombier usage();
1477dd7cddfSDavid du Colombier }ARGEND;
1487dd7cddfSDavid du Colombier
1497dd7cddfSDavid du Colombier if(argc != 1)
1507dd7cddfSDavid du Colombier usage();
1517dd7cddfSDavid du Colombier
1527dd7cddfSDavid du Colombier disk = opendisk(argv[0], rdonly, file);
153c39c2eb3SDavid du Colombier if(disk == nil)
154c39c2eb3SDavid du Colombier sysfatal("cannot open disk: %r");
1557dd7cddfSDavid du Colombier
1567dd7cddfSDavid du Colombier if(secsize != 0) {
1577dd7cddfSDavid du Colombier disk->secsize = secsize;
1587dd7cddfSDavid du Colombier disk->secs = disk->size / secsize;
1597dd7cddfSDavid du Colombier }
16080ee5cbfSDavid du Colombier edit.end = disk->secs;
1617dd7cddfSDavid du Colombier
1627dd7cddfSDavid du Colombier checkfat(disk);
1637dd7cddfSDavid du Colombier
1647dd7cddfSDavid du Colombier secbuf = emalloc(disk->secsize+1);
1657dd7cddfSDavid du Colombier osecbuf = emalloc(disk->secsize+1);
1667dd7cddfSDavid du Colombier edit.disk = disk;
1677dd7cddfSDavid du Colombier
1687dd7cddfSDavid du Colombier if(blank == 0)
1697dd7cddfSDavid du Colombier rdpart(&edit);
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier opart = emalloc(edit.npart*sizeof(opart[0]));
1727dd7cddfSDavid du Colombier
1737dd7cddfSDavid du Colombier /* save old partition table */
1747dd7cddfSDavid du Colombier for(i=0; i<edit.npart; i++)
1757dd7cddfSDavid du Colombier opart[i] = edit.part[i];
1767dd7cddfSDavid du Colombier nopart = edit.npart;
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier if(printflag) {
1797dd7cddfSDavid du Colombier runcmd(&edit, "P");
1807dd7cddfSDavid du Colombier exits(0);
1817dd7cddfSDavid du Colombier }
1827dd7cddfSDavid du Colombier
183dc5a79c1SDavid du Colombier if(doautox)
184dc5a79c1SDavid du Colombier autoxpart(&edit);
1857dd7cddfSDavid du Colombier
1867dd7cddfSDavid du Colombier if(dowrite) {
18780ee5cbfSDavid du Colombier runcmd(&edit, "w");
1887dd7cddfSDavid du Colombier exits(0);
1897dd7cddfSDavid du Colombier }
1907dd7cddfSDavid du Colombier
1917dd7cddfSDavid du Colombier runcmd(&edit, "p");
1927dd7cddfSDavid du Colombier for(;;) {
1937dd7cddfSDavid du Colombier fprint(2, ">>> ");
1947dd7cddfSDavid du Colombier runcmd(&edit, getline(&edit));
1957dd7cddfSDavid du Colombier }
1967dd7cddfSDavid du Colombier }
1977dd7cddfSDavid du Colombier
1987dd7cddfSDavid du Colombier static void
cmdsum(Edit * edit,Part * p,vlong a,vlong b)1997dd7cddfSDavid du Colombier cmdsum(Edit *edit, Part *p, vlong a, vlong b)
2007dd7cddfSDavid du Colombier {
2017dd7cddfSDavid du Colombier vlong sz, div;
2027dd7cddfSDavid du Colombier char *suf, *name;
2037dd7cddfSDavid du Colombier char c;
2047dd7cddfSDavid du Colombier
2057dd7cddfSDavid du Colombier c = p && p->changed ? '\'' : ' ';
2067dd7cddfSDavid du Colombier name = p ? p->name : "empty";
2077dd7cddfSDavid du Colombier
2087dd7cddfSDavid du Colombier sz = (b-a)*edit->disk->secsize;
209eba00c11SDavid du Colombier if(sz >= 1*TB){
210eba00c11SDavid du Colombier suf = "TB";
211eba00c11SDavid du Colombier div = TB;
212eba00c11SDavid du Colombier }else if(sz >= 1*GB){
2137dd7cddfSDavid du Colombier suf = "GB";
2147dd7cddfSDavid du Colombier div = GB;
21580ee5cbfSDavid du Colombier }else if(sz >= 1*MB){
2167dd7cddfSDavid du Colombier suf = "MB";
2177dd7cddfSDavid du Colombier div = MB;
21880ee5cbfSDavid du Colombier }else if(sz >= 1*KB){
2197dd7cddfSDavid du Colombier suf = "KB";
2207dd7cddfSDavid du Colombier div = KB;
2217dd7cddfSDavid du Colombier }else{
222c39c2eb3SDavid du Colombier if (sz < 0)
223c39c2eb3SDavid du Colombier fprint(2, "%s: negative size!\n", argv0);
2247dd7cddfSDavid du Colombier suf = "B ";
2257dd7cddfSDavid du Colombier div = 1;
2267dd7cddfSDavid du Colombier }
2277dd7cddfSDavid du Colombier
2287dd7cddfSDavid du Colombier if(div == 1)
2297dd7cddfSDavid du Colombier print("%c %-12s %*lld %-*lld (%lld sectors, %lld %s)\n", c, name,
2307dd7cddfSDavid du Colombier edit->disk->width, a, edit->disk->width, b, b-a, sz, suf);
2317dd7cddfSDavid du Colombier else
2327dd7cddfSDavid du Colombier print("%c %-12s %*lld %-*lld (%lld sectors, %lld.%.2d %s)\n", c, name,
2337dd7cddfSDavid du Colombier edit->disk->width, a, edit->disk->width, b, b-a,
23480ee5cbfSDavid du Colombier sz/div, (int)(((sz%div)*100)/div), suf);
2357dd7cddfSDavid du Colombier }
2367dd7cddfSDavid du Colombier
2377dd7cddfSDavid du Colombier static char*
cmdadd(Edit * edit,char * name,vlong start,vlong end)2387dd7cddfSDavid du Colombier cmdadd(Edit *edit, char *name, vlong start, vlong end)
2397dd7cddfSDavid du Colombier {
24080ee5cbfSDavid du Colombier if(start < 2 && strcmp(name, "9fat") != 0)
24180ee5cbfSDavid du Colombier return "overlaps with the pbs and/or the partition table";
24280ee5cbfSDavid du Colombier
2437dd7cddfSDavid du Colombier return addpart(edit, mkpart(name, start, end, 1));
2447dd7cddfSDavid du Colombier }
2457dd7cddfSDavid du Colombier
2467dd7cddfSDavid du Colombier static char*
cmddel(Edit * edit,Part * p)2477dd7cddfSDavid du Colombier cmddel(Edit *edit, Part *p)
2487dd7cddfSDavid du Colombier {
2497dd7cddfSDavid du Colombier return delpart(edit, p);
2507dd7cddfSDavid du Colombier }
2517dd7cddfSDavid du Colombier
2527dd7cddfSDavid du Colombier static char*
cmdwrite(Edit * edit)2537dd7cddfSDavid du Colombier cmdwrite(Edit *edit)
2547dd7cddfSDavid du Colombier {
2557dd7cddfSDavid du Colombier wrpart(edit);
2567dd7cddfSDavid du Colombier return nil;
2577dd7cddfSDavid du Colombier }
2587dd7cddfSDavid du Colombier
2597dd7cddfSDavid du Colombier static char isfrog[256]={
2607dd7cddfSDavid du Colombier /*NUL*/ 1, 1, 1, 1, 1, 1, 1, 1,
2617dd7cddfSDavid du Colombier /*BKS*/ 1, 1, 1, 1, 1, 1, 1, 1,
2627dd7cddfSDavid du Colombier /*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1,
2637dd7cddfSDavid du Colombier /*CAN*/ 1, 1, 1, 1, 1, 1, 1, 1,
2647dd7cddfSDavid du Colombier [' '] 1,
2657dd7cddfSDavid du Colombier ['/'] 1,
2667dd7cddfSDavid du Colombier [0x7f] 1,
2677dd7cddfSDavid du Colombier };
2687dd7cddfSDavid du Colombier
2697dd7cddfSDavid du Colombier static char*
cmdokname(Edit *,char * elem)2707dd7cddfSDavid du Colombier cmdokname(Edit*, char *elem)
2717dd7cddfSDavid du Colombier {
2729a747e4fSDavid du Colombier for(; *elem; elem++)
2737dd7cddfSDavid du Colombier if(isfrog[*(uchar*)elem])
2747dd7cddfSDavid du Colombier return "bad character in name";
2757dd7cddfSDavid du Colombier return nil;
2767dd7cddfSDavid du Colombier }
2777dd7cddfSDavid du Colombier
2787dd7cddfSDavid du Colombier static Part*
mkpart(char * name,vlong start,vlong end,int changed)2797dd7cddfSDavid du Colombier mkpart(char *name, vlong start, vlong end, int changed)
2807dd7cddfSDavid du Colombier {
2817dd7cddfSDavid du Colombier Part *p;
2827dd7cddfSDavid du Colombier
2837dd7cddfSDavid du Colombier p = emalloc(sizeof(*p));
2849a747e4fSDavid du Colombier p->name = estrdup(name);
2859a747e4fSDavid du Colombier p->ctlname = estrdup(name);
2867dd7cddfSDavid du Colombier p->start = start;
2877dd7cddfSDavid du Colombier p->end = end;
2887dd7cddfSDavid du Colombier p->changed = changed;
2897dd7cddfSDavid du Colombier return p;
2907dd7cddfSDavid du Colombier }
2917dd7cddfSDavid du Colombier
2927dd7cddfSDavid du Colombier /* plan9 partition is first sector of the disk */
2937dd7cddfSDavid du Colombier static void
rdpart(Edit * edit)2947dd7cddfSDavid du Colombier rdpart(Edit *edit)
2957dd7cddfSDavid du Colombier {
2967dd7cddfSDavid du Colombier int i, nline, nf, waserr;
2977dd7cddfSDavid du Colombier vlong a, b;
298eba00c11SDavid du Colombier char *line[128];
2997dd7cddfSDavid du Colombier char *f[5];
3007dd7cddfSDavid du Colombier char *err;
3017dd7cddfSDavid du Colombier Disk *disk;
3027dd7cddfSDavid du Colombier
3037dd7cddfSDavid du Colombier disk = edit->disk;
3047dd7cddfSDavid du Colombier seek(disk->fd, disk->secsize, 0);
3057dd7cddfSDavid du Colombier if(readn(disk->fd, osecbuf, disk->secsize) != disk->secsize)
3067dd7cddfSDavid du Colombier return;
3077dd7cddfSDavid du Colombier osecbuf[disk->secsize] = '\0';
3087dd7cddfSDavid du Colombier memmove(secbuf, osecbuf, disk->secsize+1);
3097dd7cddfSDavid du Colombier
3107dd7cddfSDavid du Colombier if(strncmp(secbuf, "part", 4) != 0){
3117dd7cddfSDavid du Colombier fprint(2, "no plan9 partition table found\n");
3127dd7cddfSDavid du Colombier return;
3137dd7cddfSDavid du Colombier }
3147dd7cddfSDavid du Colombier
3157dd7cddfSDavid du Colombier waserr = 0;
3167dd7cddfSDavid du Colombier nline = getfields(secbuf, line, nelem(line), 1, "\n");
3177dd7cddfSDavid du Colombier for(i=0; i<nline; i++){
3187dd7cddfSDavid du Colombier if(strncmp(line[i], "part", 4) != 0) {
3197dd7cddfSDavid du Colombier Error:
3207dd7cddfSDavid du Colombier if(waserr == 0)
3217dd7cddfSDavid du Colombier fprint(2, "syntax error reading partition\n");
3227dd7cddfSDavid du Colombier waserr = 1;
3237dd7cddfSDavid du Colombier continue;
3247dd7cddfSDavid du Colombier }
3257dd7cddfSDavid du Colombier
3267dd7cddfSDavid du Colombier nf = getfields(line[i], f, nelem(f), 1, " \t\r");
3277dd7cddfSDavid du Colombier if(nf != 4 || strcmp(f[0], "part") != 0)
3287dd7cddfSDavid du Colombier goto Error;
3297dd7cddfSDavid du Colombier
3307dd7cddfSDavid du Colombier a = strtoll(f[2], 0, 0);
3317dd7cddfSDavid du Colombier b = strtoll(f[3], 0, 0);
3327dd7cddfSDavid du Colombier if(a >= b)
3337dd7cddfSDavid du Colombier goto Error;
3347dd7cddfSDavid du Colombier
3357dd7cddfSDavid du Colombier if(err = addpart(edit, mkpart(f[1], a, b, 0))) {
3367dd7cddfSDavid du Colombier fprint(2, "?%s: not continuing\n", err);
3377dd7cddfSDavid du Colombier exits("partition");
3387dd7cddfSDavid du Colombier }
3397dd7cddfSDavid du Colombier }
3407dd7cddfSDavid du Colombier }
3417dd7cddfSDavid du Colombier
3427dd7cddfSDavid du Colombier static vlong
min(vlong a,vlong b)3437dd7cddfSDavid du Colombier min(vlong a, vlong b)
3447dd7cddfSDavid du Colombier {
3457dd7cddfSDavid du Colombier if(a < b)
3467dd7cddfSDavid du Colombier return a;
3477dd7cddfSDavid du Colombier return b;
3487dd7cddfSDavid du Colombier }
3497dd7cddfSDavid du Colombier
3507dd7cddfSDavid du Colombier static void
autoxpart(Edit * edit)351dc5a79c1SDavid du Colombier autoxpart(Edit *edit)
3527dd7cddfSDavid du Colombier {
353dc5a79c1SDavid du Colombier int i, totw, futz;
354dc5a79c1SDavid du Colombier vlong secs, secsize, s;
3557dd7cddfSDavid du Colombier char *err;
3567dd7cddfSDavid du Colombier
3577dd7cddfSDavid du Colombier if(edit->npart > 0) {
358dc5a79c1SDavid du Colombier if(doautox)
3597dd7cddfSDavid du Colombier fprint(2, "partitions already exist; not repartitioning\n");
3607dd7cddfSDavid du Colombier return;
3617dd7cddfSDavid du Colombier }
3627dd7cddfSDavid du Colombier
3637dd7cddfSDavid du Colombier secs = edit->disk->secs;
3647dd7cddfSDavid du Colombier secsize = edit->disk->secsize;
365dc5a79c1SDavid du Colombier for(;;){
366dc5a79c1SDavid du Colombier /* compute total weights */
367dc5a79c1SDavid du Colombier totw = 0;
368dc5a79c1SDavid du Colombier for(i=0; i<nelem(autox); i++){
369dc5a79c1SDavid du Colombier if(autox[i].alloc==0 || autox[i].size)
370dc5a79c1SDavid du Colombier continue;
371dc5a79c1SDavid du Colombier totw += autox[i].weight;
372dc5a79c1SDavid du Colombier }
373dc5a79c1SDavid du Colombier if(totw == 0)
374dc5a79c1SDavid du Colombier break;
3757dd7cddfSDavid du Colombier
376dc5a79c1SDavid du Colombier if(secs <= 0){
377dc5a79c1SDavid du Colombier fprint(2, "ran out of disk space during autoxpartition.\n");
378dc5a79c1SDavid du Colombier return;
379dc5a79c1SDavid du Colombier }
3807dd7cddfSDavid du Colombier
381dc5a79c1SDavid du Colombier /* assign any minimums for small disks */
382dc5a79c1SDavid du Colombier futz = 0;
383dc5a79c1SDavid du Colombier for(i=0; i<nelem(autox); i++){
384dc5a79c1SDavid du Colombier if(autox[i].alloc==0 || autox[i].size)
385dc5a79c1SDavid du Colombier continue;
386dc5a79c1SDavid du Colombier s = (secs*autox[i].weight)/totw;
387dc5a79c1SDavid du Colombier if(s < autox[i].min/secsize){
388dc5a79c1SDavid du Colombier autox[i].size = autox[i].min/secsize;
389dc5a79c1SDavid du Colombier secs -= autox[i].size;
390dc5a79c1SDavid du Colombier futz = 1;
391dc5a79c1SDavid du Colombier break;
392dc5a79c1SDavid du Colombier }
393dc5a79c1SDavid du Colombier }
394dc5a79c1SDavid du Colombier if(futz)
395dc5a79c1SDavid du Colombier continue;
396dc5a79c1SDavid du Colombier
397dc5a79c1SDavid du Colombier /* assign any maximums for big disks */
398dc5a79c1SDavid du Colombier futz = 0;
399dc5a79c1SDavid du Colombier for(i=0; i<nelem(autox); i++){
400dc5a79c1SDavid du Colombier if(autox[i].alloc==0 || autox[i].size)
401dc5a79c1SDavid du Colombier continue;
402dc5a79c1SDavid du Colombier s = (secs*autox[i].weight)/totw;
403dc5a79c1SDavid du Colombier if(autox[i].max && s > autox[i].max/secsize){
404dc5a79c1SDavid du Colombier autox[i].size = autox[i].max/secsize;
405dc5a79c1SDavid du Colombier secs -= autox[i].size;
406dc5a79c1SDavid du Colombier futz = 1;
407dc5a79c1SDavid du Colombier break;
408dc5a79c1SDavid du Colombier }
409dc5a79c1SDavid du Colombier }
410dc5a79c1SDavid du Colombier if(futz)
411dc5a79c1SDavid du Colombier continue;
412dc5a79c1SDavid du Colombier
413dc5a79c1SDavid du Colombier /* finally, assign partition sizes according to weights */
414dc5a79c1SDavid du Colombier for(i=0; i<nelem(autox); i++){
415dc5a79c1SDavid du Colombier if(autox[i].alloc==0 || autox[i].size)
416dc5a79c1SDavid du Colombier continue;
417dc5a79c1SDavid du Colombier s = (secs*autox[i].weight)/totw;
418dc5a79c1SDavid du Colombier autox[i].size = s;
419dc5a79c1SDavid du Colombier
420dc5a79c1SDavid du Colombier /* use entire disk even in face of rounding errors */
421dc5a79c1SDavid du Colombier secs -= autox[i].size;
422dc5a79c1SDavid du Colombier totw -= autox[i].weight;
423dc5a79c1SDavid du Colombier }
424dc5a79c1SDavid du Colombier }
425dc5a79c1SDavid du Colombier
426dc5a79c1SDavid du Colombier for(i=0; i<nelem(autox); i++)
427f2baf03bSDavid du Colombier if(autox[i].alloc)
428f2baf03bSDavid du Colombier print("%s %llud\n", autox[i].name, autox[i].size);
429dc5a79c1SDavid du Colombier
430dc5a79c1SDavid du Colombier s = 0;
431dc5a79c1SDavid du Colombier for(i=0; i<nelem(autox); i++){
432dc5a79c1SDavid du Colombier if(autox[i].alloc == 0)
433dc5a79c1SDavid du Colombier continue;
434dc5a79c1SDavid du Colombier if(err = addpart(edit, mkpart(autox[i].name, s, s+autox[i].size, 1)))
435dc5a79c1SDavid du Colombier fprint(2, "addpart %s: %s\n", autox[i].name, err);
436dc5a79c1SDavid du Colombier s += autox[i].size;
437dc5a79c1SDavid du Colombier }
4387dd7cddfSDavid du Colombier }
4397dd7cddfSDavid du Colombier
4407dd7cddfSDavid du Colombier static void
restore(Edit * edit,int ctlfd)4417dd7cddfSDavid du Colombier restore(Edit *edit, int ctlfd)
4427dd7cddfSDavid du Colombier {
4437dd7cddfSDavid du Colombier int i;
4447dd7cddfSDavid du Colombier vlong offset;
4457dd7cddfSDavid du Colombier
4467dd7cddfSDavid du Colombier offset = edit->disk->offset;
4477dd7cddfSDavid du Colombier fprint(2, "attempting to restore partitions to previous state\n");
4487dd7cddfSDavid du Colombier if(seek(edit->disk->wfd, edit->disk->secsize, 0) != 0){
4497dd7cddfSDavid du Colombier fprint(2, "cannot restore: error seeking on disk\n");
4507dd7cddfSDavid du Colombier exits("inconsistent");
4517dd7cddfSDavid du Colombier }
4527dd7cddfSDavid du Colombier
4537dd7cddfSDavid du Colombier if(write(edit->disk->wfd, osecbuf, edit->disk->secsize) != edit->disk->secsize){
4547dd7cddfSDavid du Colombier fprint(2, "cannot restore: couldn't write old partition table to disk\n");
4557dd7cddfSDavid du Colombier exits("inconsistent");
4567dd7cddfSDavid du Colombier }
4577dd7cddfSDavid du Colombier
4587dd7cddfSDavid du Colombier if(ctlfd >= 0){
4597dd7cddfSDavid du Colombier for(i=0; i<edit->npart; i++)
4607dd7cddfSDavid du Colombier fprint(ctlfd, "delpart %s", edit->part[i]->name);
4617dd7cddfSDavid du Colombier for(i=0; i<nopart; i++){
4627dd7cddfSDavid du Colombier if(fprint(ctlfd, "part %s %lld %lld", opart[i]->name, opart[i]->start+offset, opart[i]->end+offset) < 0){
4637dd7cddfSDavid du Colombier fprint(2, "restored disk partition table but not kernel; reboot\n");
4647dd7cddfSDavid du Colombier exits("inconsistent");
4657dd7cddfSDavid du Colombier }
4667dd7cddfSDavid du Colombier }
4677dd7cddfSDavid du Colombier }
4687dd7cddfSDavid du Colombier exits("restored");
4697dd7cddfSDavid du Colombier }
4707dd7cddfSDavid du Colombier
4717dd7cddfSDavid du Colombier static void
wrpart(Edit * edit)4727dd7cddfSDavid du Colombier wrpart(Edit *edit)
4737dd7cddfSDavid du Colombier {
4747dd7cddfSDavid du Colombier int i, n;
4757dd7cddfSDavid du Colombier Disk *disk;
4767dd7cddfSDavid du Colombier
4777dd7cddfSDavid du Colombier disk = edit->disk;
4787dd7cddfSDavid du Colombier
4797dd7cddfSDavid du Colombier memset(secbuf, 0, disk->secsize);
4807dd7cddfSDavid du Colombier n = 0;
4817dd7cddfSDavid du Colombier for(i=0; i<edit->npart; i++)
4827dd7cddfSDavid du Colombier n += snprint(secbuf+n, disk->secsize-n, "part %s %lld %lld\n",
4837dd7cddfSDavid du Colombier edit->part[i]->name, edit->part[i]->start, edit->part[i]->end);
4847dd7cddfSDavid du Colombier
4857dd7cddfSDavid du Colombier if(seek(disk->wfd, disk->secsize, 0) != disk->secsize){
4867dd7cddfSDavid du Colombier fprint(2, "error seeking %d %lld on disk: %r\n", disk->wfd, disk->secsize);
4877dd7cddfSDavid du Colombier exits("seek");
4887dd7cddfSDavid du Colombier }
4897dd7cddfSDavid du Colombier
4907dd7cddfSDavid du Colombier if(write(disk->wfd, secbuf, disk->secsize) != disk->secsize){
4917dd7cddfSDavid du Colombier fprint(2, "error writing partition table to disk\n");
4927dd7cddfSDavid du Colombier restore(edit, -1);
4937dd7cddfSDavid du Colombier }
4947dd7cddfSDavid du Colombier
4957dd7cddfSDavid du Colombier if(ctldiff(edit, disk->ctlfd) < 0)
4967dd7cddfSDavid du Colombier fprint(2, "?warning: partitions could not be updated in devsd\n");
4977dd7cddfSDavid du Colombier }
4987dd7cddfSDavid du Colombier
4997dd7cddfSDavid du Colombier /*
5007dd7cddfSDavid du Colombier * Look for a boot sector in sector 1, as would be
5017dd7cddfSDavid du Colombier * the case if editing /dev/sdC0/data when that
5027dd7cddfSDavid du Colombier * was really a bootable disk.
5037dd7cddfSDavid du Colombier */
5047dd7cddfSDavid du Colombier static void
checkfat(Disk * disk)5057dd7cddfSDavid du Colombier checkfat(Disk *disk)
5067dd7cddfSDavid du Colombier {
5077dd7cddfSDavid du Colombier uchar buf[32];
5087dd7cddfSDavid du Colombier
5097dd7cddfSDavid du Colombier if(seek(disk->fd, disk->secsize, 0) < 0
5107dd7cddfSDavid du Colombier || read(disk->fd, buf, sizeof(buf)) < sizeof(buf))
5117dd7cddfSDavid du Colombier return;
5127dd7cddfSDavid du Colombier
5137dd7cddfSDavid du Colombier if(buf[0] != 0xEB || buf[1] != 0x3C || buf[2] != 0x90)
5147dd7cddfSDavid du Colombier return;
5157dd7cddfSDavid du Colombier
5167dd7cddfSDavid du Colombier fprint(2,
5177dd7cddfSDavid du Colombier "there's a fat partition where the\n"
5187dd7cddfSDavid du Colombier "plan9 partition table would go.\n"
5197dd7cddfSDavid du Colombier "if you really want to overwrite it, zero\n"
5207dd7cddfSDavid du Colombier "the second sector of the disk and try again\n");
5217dd7cddfSDavid du Colombier
5227dd7cddfSDavid du Colombier exits("fat partition");
5237dd7cddfSDavid du Colombier }
524