new signals
[unix-history] / usr / src / usr.sbin / diskpart / diskpart.c
CommitLineData
11236beb 1#ifndef lint
6a034b04 2static char sccsid[] = "@(#)diskpart.c 4.3 (Berkeley) %G%";
11236beb
SL
3#endif
4
5/*
6 * Program to calculate standard disk partition sizes.
7 */
8#include <sys/param.h>
9
10#include <stdio.h>
11#include <disktab.h>
12
13#define NPARTITIONS 8
14#define PART(x) (x - 'a')
15
16/*
17 * Default partition sizes, where they exist.
18 */
19#define NDEFAULTS 4
20int defpart[NDEFAULTS][NPARTITIONS] = {
21 { 15884, 66880, 0, 15884, 307200, 0, 0, 291346 }, /* ~ 356+ Mbytes */
22 { 15884, 33440, 0, 15884, 55936, 0, 0, 291346 }, /* ~ 206-355 Mbytes */
23 { 15884, 33440, 0, 15884, 55936, 0, 0, 0 }, /* ~ 61-205 Mbytes */
24 { 15884, 10032, 0, 15884, 0, 0, 0, 0 }, /* ~ 20-60 Mbytes */
25};
26
27/*
28 * Each array defines a layout for a disk;
29 * that is, the collection of partitions totally
30 * covers the physical space on a disk.
31 */
32#define NLAYOUTS 3
33char layouts[NLAYOUTS][NPARTITIONS] = {
34 { 'a', 'b', 'h', 'g' },
35 { 'a', 'b', 'h', 'd', 'e', 'f' },
36 { 'c' },
37};
38
39/*
40 * Default disk block and disk block fragment
41 * sizes for each file system. Those file systems
42 * with zero block and frag sizes are special cases
43 * (e.g. swap areas or for access to the entire device).
44 */
45struct defparam {
46 int p_bsize; /* block size */
47 int p_fsize; /* frag size */
48} defparam[NPARTITIONS] = {
49 { 8192, 1024 }, /* a */
50 { 0 }, /* b */
51 { 0 }, /* c */
52 { 8192, 1024 }, /* d */
53 { 4096, 512 }, /* e */
54 { 4096, 1024 }, /* f */
55 { 4096, 1024 }, /* g */
56 { 4096, 512 } /* h */
57};
58
59/*
60 * Each disk has some space reserved for a bad sector
6a034b04
SL
61 * forwarding table. DEC standard 144 uses the first
62 * 5 even numbered sectors in the last track of the
63 * last cylinder for replicated storage of the bad sector
64 * table; another 126 sectors past this is needed as a
65 * pool of replacement sectors.
11236beb 66 */
6a034b04 67int badsecttable = 126; /* # sectors */
11236beb
SL
68
69int pflag; /* print device driver partition tables */
70int dflag; /* print disktab entry */
71
72struct disktab *promptfordisk();
73
74main(argc, argv)
75 int argc;
76 char *argv[];
77{
78 struct disktab *dp;
79 register int curcyl, spc, def, part, layout;
80 int threshhold, numcyls[NPARTITIONS], startcyl[NPARTITIONS];
81 char *lp;
82
83 argc--, argv++;
84 if (argc < 1) {
85 fprintf(stderr, "usage: disktab [ -p ] [ -d ] disk-type\n");
86 exit(1);
87 }
88 if (argc > 0 && strcmp(*argv, "-p") == 0) {
89 pflag++;
90 argc--, argv++;
91 }
92 if (argc > 0 && strcmp(*argv, "-d") == 0) {
93 dflag++;
94 argc--, argv++;
95 }
96 dp = getdiskbyname(*argv);
97 if (dp == NULL) {
98 if (isatty(0))
99 dp = promptfordisk(*argv);
100 if (dp == NULL) {
101 fprintf(stderr, "%s: unknown disk type\n", *argv);
102 exit(2);
103 }
104 }
105 spc = dp->d_nsectors * dp->d_ntracks;
6a034b04
SL
106 /*
107 * Bad sector table contains one track for the replicated
108 * copies of the table and enough full tracks preceding
109 * the last track to hold the pool of free blocks to which
110 * bad sectors are mapped.
111 */
112 badsecttable = dp->d_nsectors + roundup(badsecttable, dp->d_nsectors);
11236beb
SL
113 threshhold = howmany(spc, badsecttable);
114
115 /*
116 * Figure out if disk is large enough for
117 * expanded swap area and 'd', 'e', and 'f'
118 * partitions. Otherwise, use smaller defaults
119 * based on RK07.
120 */
121 for (def = 0; def < NDEFAULTS; def++) {
122 curcyl = 0;
123 for (part = PART('a'); part < NPARTITIONS; part++)
124 curcyl += howmany(defpart[def][part], spc);
125 if (curcyl < dp->d_ncylinders - threshhold)
126 break;
127 }
128 if (def >= NDEFAULTS) {
129 fprintf(stderr, "%s: disk too small, calculate by hand\n",
130 *argv);
131 exit(3);
132 }
133
134 /*
135 * Calculate number of cylinders allocated to each disk
136 * partition. We may waste a bit of space here, but it's
137 * in the interest of compatibility (for mixed disk systems).
138 */
139 for (curcyl = 0, part = PART('a'); part < NPARTITIONS; part++) {
140 numcyls[part] = 0;
141 if (defpart[def][part] != 0) {
142 numcyls[part] = howmany(defpart[def][part], spc);
143 curcyl += numcyls[part];
144 }
145 }
146 numcyls[PART('f')] = dp->d_ncylinders - curcyl;
147 numcyls[PART('g')] =
148 numcyls[PART('d')] + numcyls[PART('e')] + numcyls[PART('f')];
149 numcyls[PART('c')] = dp->d_ncylinders;
150 defpart[def][PART('f')] = numcyls[PART('f')] * spc - badsecttable;
151 defpart[def][PART('g')] = numcyls[PART('g')] * spc - badsecttable;
152 defpart[def][PART('c')] = numcyls[PART('c')] * spc;
153
154 /*
155 * Calculate starting cylinder number for each partition.
156 * Note the 'h' partition is physically located before the
157 * 'g' or 'd' partition. This is reflected in the layout
158 * arrays defined above.
159 */
160 for (layout = 0; layout < NLAYOUTS; layout++) {
161 curcyl = 0;
162 for (lp = layouts[layout]; *lp != 0; lp++) {
163 startcyl[PART(*lp)] = curcyl;
164 curcyl += numcyls[PART(*lp)];
165 }
166 }
167
168 if (pflag) {
169 printf("}, %s_sizes[%d] = {\n", dp->d_name, NPARTITIONS);
170 for (part = PART('a'); part < NPARTITIONS; part++) {
171 if (numcyls[part] == 0) {
172 printf("\t0,\t0,\n");
173 continue;
174 }
175 printf("\t%d,\t%d,\t\t/* %c=cyl %d thru %d */\n",
176 defpart[def][part], startcyl[part],
177 'A' + part, startcyl[part],
178 startcyl[part] + numcyls[part] - 1);
179 }
180 exit(0);
181 }
182 if (dflag) {
510f89e2
SL
183 int nparts;
184
11236beb
SL
185 /*
186 * In case the disk is in the ``in-between'' range
187 * where the 'g' partition is smaller than the 'h'
188 * partition, reverse the frag sizes so the /usr partition
189 * is always set up with a frag size larger than the
190 * user's partition.
191 */
192 if (defpart[def][PART('g')] < defpart[def][PART('h')]) {
193 int temp;
194
195 temp = defparam[PART('h')].p_fsize;
196 defparam[PART('h')].p_fsize =
197 defparam[PART('g')].p_fsize;
198 defparam[PART('g')].p_fsize = temp;
199 }
200 printf("%s:\\\n", dp->d_name);
201 printf("\t:ty=%s:ns#%d:nt#%d:nc#%d:\\\n", dp->d_type,
202 dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders);
510f89e2
SL
203 for (nparts = 0, part = PART('a'); part < NPARTITIONS; part++)
204 if (defpart[def][part] != 0)
205 nparts++;
11236beb
SL
206 for (part = PART('a'); part < NPARTITIONS; part++) {
207 if (defpart[def][part] == 0)
208 continue;
209 printf("\t:p%c#%d:", 'a' + part, defpart[def][part]);
510f89e2 210 if (defparam[part].p_bsize != 0) {
11236beb
SL
211 printf("b%c#%d:f%c#%d:",
212 'a' + part, defparam[part].p_bsize,
213 'a' + part, defparam[part].p_fsize);
510f89e2
SL
214 }
215 nparts--;
216 printf("%s\n", nparts > 0 ? "\\" : "");
11236beb
SL
217 }
218 exit(0);
219 }
220 printf("%s: #sectors/track=%d, #tracks/cylinder=%d #cylinders=%d\n",
221 dp->d_name, dp->d_nsectors, dp->d_ntracks, dp->d_ncylinders);
222 printf("\n Partition\t Size\t Range\n");
223 for (part = PART('a'); part < NPARTITIONS; part++) {
224 printf("\t%c\t", 'a' + part);
225 if (numcyls[part] == 0) {
226 printf(" unused\n");
227 continue;
228 }
229 printf("%7d\t%4d - %d\n", defpart[def][part], startcyl[part],
230 startcyl[part] + numcyls[part] - 1);
231 }
232}
233
234struct disktab disk;
235
236struct field {
237 char *f_name;
238 char *f_defaults;
239 int *f_location;
240} fields[] = {
241 { "sector size", "512", &disk.d_secsize },
242 { "#sectors/track", 0, &disk.d_nsectors },
243 { "#tracks/cylinder", 0, &disk.d_ntracks },
244 { "#cylinders", 0, &disk.d_ncylinders },
245 { "revolutions/minute", "3600", &disk.d_rpm },
246 { 0, 0, 0 },
247};
248
249struct disktab *
250promptfordisk(name)
251 char *name;
252{
253 register struct disktab *dp = &disk;
254 register struct field *fp;
255 static char type[BUFSIZ];
256 char buf[BUFSIZ], *cp, *gets();
257
258 dp->d_name = name;
259 fprintf(stderr,
260 "%s: unknown disk type, want to supply parameters (y/n)? ",
261 name);
262 (void) gets(buf);
263 if (*buf != 'y')
264 return ((struct disktab *)0);
265gettype:
266 fprintf(stderr, "type (winchester|removable|simulated)? ");
267 (void) gets(type);
268 if (strcmp(type, "winchester") && strcmp(type, "removable") &&
269 strcmp(type, "simulated")) {
270 fprintf(stderr, "%s: bad disk type\n", type);
271 goto gettype;
272 }
273 dp->d_type = type;
274 fprintf(stderr, "(type <cr> to get default value, if only one)\n");
275 for (fp = fields; fp->f_name != NULL; fp++) {
276again:
277 fprintf(stderr, "%s ", fp->f_name);
278 if (fp->f_defaults != NULL)
279 fprintf(stderr, "(%s)", fp->f_defaults);
280 fprintf(stderr, "? ");
281 cp = gets(buf);
282 if (*cp == '\0') {
283 if (fp->f_defaults == NULL) {
284 fprintf(stderr, "no default value\n");
285 goto again;
286 }
287 cp = fp->f_defaults;
288 }
289 *fp->f_location = atoi(cp);
290 if (*fp->f_location == 0) {
291 fprintf(stderr, "%s: bad value\n", cp);
292 goto again;
293 }
294 }
295 return (dp);
296}