aboutsummaryrefslogtreecommitdiff
path: root/util-linux/fdisk_sun.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-10-12 19:30:44 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-10-12 19:30:44 +0000
commit98ae2160b62b99424e5793e97d5abd4e3c2e576b (patch)
tree58f4e56d32330ea4abe200f3b2b0e21392d944e1 /util-linux/fdisk_sun.c
parenta6dbb08a48903cb8f31fad2cf2d1cffa92bd4808 (diff)
downloadbusybox-w32-98ae2160b62b99424e5793e97d5abd4e3c2e576b.tar.gz
busybox-w32-98ae2160b62b99424e5793e97d5abd4e3c2e576b.tar.bz2
busybox-w32-98ae2160b62b99424e5793e97d5abd4e3c2e576b.zip
fdisk: separate sun/aix/etc code into #included files
Diffstat (limited to 'util-linux/fdisk_sun.c')
-rw-r--r--util-linux/fdisk_sun.c731
1 files changed, 731 insertions, 0 deletions
diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c
new file mode 100644
index 000000000..6973fbf30
--- /dev/null
+++ b/util-linux/fdisk_sun.c
@@ -0,0 +1,731 @@
1#ifdef CONFIG_FEATURE_SUN_LABEL
2
3#define SUN_LABEL_MAGIC 0xDABE
4#define SUN_LABEL_MAGIC_SWAPPED 0xBEDA
5#define SUN_SSWAP16(x) (sun_other_endian ? __swap16(x) \
6 : (uint16_t)(x))
7#define SUN_SSWAP32(x) (sun_other_endian ? __swap32(x) \
8 : (uint32_t)(x))
9
10/* Copied from linux/major.h */
11#define FLOPPY_MAJOR 2
12
13#define SCSI_IOCTL_GET_IDLUN 0x5382
14
15/*
16 * fdisksunlabel.c
17 *
18 * I think this is mostly, or entirely, due to
19 * Jakub Jelinek (jj@sunsite.mff.cuni.cz), July 1996
20 *
21 * Merged with fdisk for other architectures, aeb, June 1998.
22 *
23 * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
24 * Internationalization
25 */
26
27
28static int sun_other_endian;
29static int scsi_disk;
30static int floppy;
31
32#ifndef IDE0_MAJOR
33#define IDE0_MAJOR 3
34#endif
35#ifndef IDE1_MAJOR
36#define IDE1_MAJOR 22
37#endif
38
39static void
40guess_device_type(void)
41{
42 struct stat bootstat;
43
44 if (fstat(fd, &bootstat) < 0) {
45 scsi_disk = 0;
46 floppy = 0;
47 } else if (S_ISBLK(bootstat.st_mode)
48 && (major(bootstat.st_rdev) == IDE0_MAJOR ||
49 major(bootstat.st_rdev) == IDE1_MAJOR)) {
50 scsi_disk = 0;
51 floppy = 0;
52 } else if (S_ISBLK(bootstat.st_mode)
53 && major(bootstat.st_rdev) == FLOPPY_MAJOR) {
54 scsi_disk = 0;
55 floppy = 1;
56 } else {
57 scsi_disk = 1;
58 floppy = 0;
59 }
60}
61
62static const struct systypes sun_sys_types[] = {
63 { "\x00" "Empty" }, /* 0 */
64 { "\x01" "Boot" }, /* 1 */
65 { "\x02" "SunOS root" }, /* 2 */
66 { "\x03" "SunOS swap" }, /* SUNOS_SWAP */
67 { "\x04" "SunOS usr" }, /* 4 */
68 { "\x05" "Whole disk" }, /* SUN_WHOLE_DISK */
69 { "\x06" "SunOS stand" }, /* 6 */
70 { "\x07" "SunOS var" }, /* 7 */
71 { "\x08" "SunOS home" }, /* 8 */
72 { "\x82" "Linux swap" }, /* LINUX_SWAP */
73 { "\x83" "Linux native" }, /* LINUX_NATIVE */
74 { "\x8e" "Linux LVM" }, /* 0x8e */
75/* New (2.2.x) raid partition with autodetect using persistent superblock */
76 { "\xfd" "Linux raid autodetect" }, /* 0xfd */
77 { NULL }
78};
79
80
81static void
82set_sun_partition(int i, uint start, uint stop, int sysid)
83{
84 sunlabel->infos[i].id = sysid;
85 sunlabel->partitions[i].start_cylinder =
86 SUN_SSWAP32(start / (heads * sectors));
87 sunlabel->partitions[i].num_sectors =
88 SUN_SSWAP32(stop - start);
89 set_changed(i);
90}
91
92static int
93check_sun_label(void)
94{
95 unsigned short *ush;
96 int csum;
97
98 if (sunlabel->magic != SUN_LABEL_MAGIC
99 && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) {
100 current_label_type = label_dos;
101 sun_other_endian = 0;
102 return 0;
103 }
104 sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
105 ush = ((unsigned short *) (sunlabel + 1)) - 1;
106 for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--;
107 if (csum) {
108 fprintf(stderr,_("Detected sun disklabel with wrong checksum.\n"
109 "Probably you'll have to set all the values,\n"
110 "e.g. heads, sectors, cylinders and partitions\n"
111 "or force a fresh label (s command in main menu)\n"));
112 } else {
113 heads = SUN_SSWAP16(sunlabel->ntrks);
114 cylinders = SUN_SSWAP16(sunlabel->ncyl);
115 sectors = SUN_SSWAP16(sunlabel->nsect);
116 }
117 update_units();
118 current_label_type = label_sun;
119 partitions = 8;
120 return 1;
121}
122
123static const struct sun_predefined_drives {
124 const char *vendor;
125 const char *model;
126 unsigned short sparecyl;
127 unsigned short ncyl;
128 unsigned short nacyl;
129 unsigned short pcylcount;
130 unsigned short ntrks;
131 unsigned short nsect;
132 unsigned short rspeed;
133} sun_drives[] = {
134 { "Quantum","ProDrive 80S",1,832,2,834,6,34,3662},
135 { "Quantum","ProDrive 105S",1,974,2,1019,6,35,3662},
136 { "CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600},
137 { "IBM","DPES-31080",0,4901,2,4903,4,108,5400},
138 { "IBM","DORS-32160",0,1015,2,1017,67,62,5400},
139 { "IBM","DNES-318350",0,11199,2,11474,10,320,7200},
140 { "SEAGATE","ST34371",0,3880,2,3882,16,135,7228},
141 { "","SUN0104",1,974,2,1019,6,35,3662},
142 { "","SUN0207",4,1254,2,1272,9,36,3600},
143 { "","SUN0327",3,1545,2,1549,9,46,3600},
144 { "","SUN0340",0,1538,2,1544,6,72,4200},
145 { "","SUN0424",2,1151,2,2500,9,80,4400},
146 { "","SUN0535",0,1866,2,2500,7,80,5400},
147 { "","SUN0669",5,1614,2,1632,15,54,3600},
148 { "","SUN1.0G",5,1703,2,1931,15,80,3597},
149 { "","SUN1.05",0,2036,2,2038,14,72,5400},
150 { "","SUN1.3G",6,1965,2,3500,17,80,5400},
151 { "","SUN2.1G",0,2733,2,3500,19,80,5400},
152 { "IOMEGA","Jaz",0,1019,2,1021,64,32,5394},
153};
154
155static const struct sun_predefined_drives *
156sun_autoconfigure_scsi(void)
157{
158 const struct sun_predefined_drives *p = NULL;
159
160#ifdef SCSI_IOCTL_GET_IDLUN
161 unsigned int id[2];
162 char buffer[2048];
163 char buffer2[2048];
164 FILE *pfd;
165 char *vendor;
166 char *model;
167 char *q;
168 int i;
169
170 if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id))
171 return NULL;
172
173 sprintf(buffer,
174 "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n",
175 /* This is very wrong (works only if you have one HBA),
176 but I haven't found a way how to get hostno
177 from the current kernel */
178 0,
179 (id[0]>>16) & 0xff,
180 id[0] & 0xff,
181 (id[0]>>8) & 0xff
182 );
183 pfd = fopen("/proc/scsi/scsi", "r");
184 if (!pfd) {
185 return NULL;
186 }
187 while (fgets(buffer2, 2048, pfd)) {
188 if (strcmp(buffer, buffer2))
189 continue;
190 if (!fgets(buffer2, 2048, pfd))
191 break;
192 q = strstr(buffer2, "Vendor: ");
193 if (!q)
194 break;
195 q += 8;
196 vendor = q;
197 q = strstr(q, " ");
198 *q++ = '\0'; /* truncate vendor name */
199 q = strstr(q, "Model: ");
200 if (!q)
201 break;
202 *q = '\0';
203 q += 7;
204 model = q;
205 q = strstr(q, " Rev: ");
206 if (!q)
207 break;
208 *q = '\0';
209 for (i = 0; i < SIZE(sun_drives); i++) {
210 if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor))
211 continue;
212 if (!strstr(model, sun_drives[i].model))
213 continue;
214 printf(_("Autoconfigure found a %s%s%s\n"),
215 sun_drives[i].vendor,
216 (*sun_drives[i].vendor) ? " " : "",
217 sun_drives[i].model);
218 p = sun_drives + i;
219 break;
220 }
221 break;
222 }
223 fclose(pfd);
224#endif
225 return p;
226}
227
228static void
229create_sunlabel(void)
230{
231 struct hd_geometry geometry;
232 unsigned int ndiv;
233 int i;
234 unsigned char c;
235 const struct sun_predefined_drives *p = NULL;
236
237 fprintf(stderr,
238 _("Building a new sun disklabel. Changes will remain in memory only,\n"
239 "until you decide to write them. After that, of course, the previous\n"
240 "content won't be recoverable.\n\n"));
241 sun_other_endian = BB_LITTLE_ENDIAN;
242 memset(MBRbuffer, 0, sizeof(MBRbuffer));
243 sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC);
244 if (!floppy) {
245 puts(_("Drive type\n"
246 " ? auto configure\n"
247 " 0 custom (with hardware detected defaults)"));
248 for (i = 0; i < SIZE(sun_drives); i++) {
249 printf(" %c %s%s%s\n",
250 i + 'a', sun_drives[i].vendor,
251 (*sun_drives[i].vendor) ? " " : "",
252 sun_drives[i].model);
253 }
254 while (1) {
255 c = read_nonempty(_("Select type (? for auto, 0 for custom): "));
256 if (c >= 'a' && c < 'a' + SIZE(sun_drives)) {
257 p = sun_drives + c - 'a';
258 break;
259 } else if (c >= 'A' && c < 'A' + SIZE(sun_drives)) {
260 p = sun_drives + c - 'A';
261 break;
262 } else if (c == '0') {
263 break;
264 } else if (c == '?' && scsi_disk) {
265 p = sun_autoconfigure_scsi();
266 if (!p)
267 printf(_("Autoconfigure failed.\n"));
268 else
269 break;
270 }
271 }
272 }
273 if (!p || floppy) {
274 if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
275 heads = geometry.heads;
276 sectors = geometry.sectors;
277 cylinders = geometry.cylinders;
278 } else {
279 heads = 0;
280 sectors = 0;
281 cylinders = 0;
282 }
283 if (floppy) {
284 sunlabel->nacyl = 0;
285 sunlabel->pcylcount = SUN_SSWAP16(cylinders);
286 sunlabel->rspeed = SUN_SSWAP16(300);
287 sunlabel->ilfact = SUN_SSWAP16(1);
288 sunlabel->sparecyl = 0;
289 } else {
290 heads = read_int(1,heads,1024,0,_("Heads"));
291 sectors = read_int(1,sectors,1024,0,_("Sectors/track"));
292 if (cylinders)
293 cylinders = read_int(1,cylinders-2,65535,0,_("Cylinders"));
294 else
295 cylinders = read_int(1,0,65535,0,_("Cylinders"));
296 sunlabel->nacyl = SUN_SSWAP16(read_int(0,2,65535,0, _("Alternate cylinders")));
297 sunlabel->pcylcount = SUN_SSWAP16(read_int(0,cylinders+SUN_SSWAP16(sunlabel->nacyl), 65535,0, _("Physical cylinders")));
298 sunlabel->rspeed = SUN_SSWAP16(read_int(1,5400,100000,0, _("Rotation speed (rpm)")));
299 sunlabel->ilfact = SUN_SSWAP16(read_int(1,1,32,0, _("Interleave factor")));
300 sunlabel->sparecyl = SUN_SSWAP16(read_int(0,0,sectors,0, _("Extra sectors per cylinder")));
301 }
302 } else {
303 sunlabel->sparecyl = SUN_SSWAP16(p->sparecyl);
304 sunlabel->ncyl = SUN_SSWAP16(p->ncyl);
305 sunlabel->nacyl = SUN_SSWAP16(p->nacyl);
306 sunlabel->pcylcount = SUN_SSWAP16(p->pcylcount);
307 sunlabel->ntrks = SUN_SSWAP16(p->ntrks);
308 sunlabel->nsect = SUN_SSWAP16(p->nsect);
309 sunlabel->rspeed = SUN_SSWAP16(p->rspeed);
310 sunlabel->ilfact = SUN_SSWAP16(1);
311 cylinders = p->ncyl;
312 heads = p->ntrks;
313 sectors = p->nsect;
314 puts(_("You may change all the disk params from the x menu"));
315 }
316
317 snprintf((char *)(sunlabel->info), sizeof(sunlabel->info),
318 "%s%s%s cyl %d alt %d hd %d sec %d",
319 p ? p->vendor : "", (p && *p->vendor) ? " " : "",
320 p ? p->model : (floppy ? _("3,5\" floppy") : _("Linux custom")),
321 cylinders, SUN_SSWAP16(sunlabel->nacyl), heads, sectors);
322
323 sunlabel->ntrks = SUN_SSWAP16(heads);
324 sunlabel->nsect = SUN_SSWAP16(sectors);
325 sunlabel->ncyl = SUN_SSWAP16(cylinders);
326 if (floppy)
327 set_sun_partition(0, 0, cylinders * heads * sectors, LINUX_NATIVE);
328 else {
329 if (cylinders * heads * sectors >= 150 * 2048) {
330 ndiv = cylinders - (50 * 2048 / (heads * sectors)); /* 50M swap */
331 } else
332 ndiv = cylinders * 2 / 3;
333 set_sun_partition(0, 0, ndiv * heads * sectors, LINUX_NATIVE);
334 set_sun_partition(1, ndiv * heads * sectors, cylinders * heads * sectors, LINUX_SWAP);
335 sunlabel->infos[1].flags |= 0x01; /* Not mountable */
336 }
337 set_sun_partition(2, 0, cylinders * heads * sectors, SUN_WHOLE_DISK);
338 {
339 unsigned short *ush = (unsigned short *)sunlabel;
340 unsigned short csum = 0;
341 while (ush < (unsigned short *)(&sunlabel->csum))
342 csum ^= *ush++;
343 sunlabel->csum = csum;
344 }
345
346 set_all_unchanged();
347 set_changed(0);
348 get_boot(create_empty_sun);
349}
350
351static void
352toggle_sunflags(int i, unsigned char mask)
353{
354 if (sunlabel->infos[i].flags & mask)
355 sunlabel->infos[i].flags &= ~mask;
356 else
357 sunlabel->infos[i].flags |= mask;
358 set_changed(i);
359}
360
361static void
362fetch_sun(uint *starts, uint *lens, uint *start, uint *stop)
363{
364 int i, continuous = 1;
365
366 *start = 0;
367 *stop = cylinders * heads * sectors;
368 for (i = 0; i < partitions; i++) {
369 if (sunlabel->partitions[i].num_sectors
370 && sunlabel->infos[i].id
371 && sunlabel->infos[i].id != SUN_WHOLE_DISK) {
372 starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors;
373 lens[i] = SUN_SSWAP32(sunlabel->partitions[i].num_sectors);
374 if (continuous) {
375 if (starts[i] == *start)
376 *start += lens[i];
377 else if (starts[i] + lens[i] >= *stop)
378 *stop = starts[i];
379 else
380 continuous = 0;
381 /* There will be probably more gaps
382 than one, so lets check afterwards */
383 }
384 } else {
385 starts[i] = 0;
386 lens[i] = 0;
387 }
388 }
389}
390
391static uint *verify_sun_starts;
392
393static int
394verify_sun_cmp(int *a, int *b)
395{
396 if (*a == -1) return 1;
397 if (*b == -1) return -1;
398 if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1;
399 return -1;
400}
401
402static void
403verify_sun(void)
404{
405 uint starts[8], lens[8], start, stop;
406 int i,j,k,starto,endo;
407 int array[8];
408
409 verify_sun_starts = starts;
410 fetch_sun(starts,lens,&start,&stop);
411 for (k = 0; k < 7; k++) {
412 for (i = 0; i < 8; i++) {
413 if (k && (lens[i] % (heads * sectors))) {
414 printf(_("Partition %d doesn't end on cylinder boundary\n"), i+1);
415 }
416 if (lens[i]) {
417 for (j = 0; j < i; j++)
418 if (lens[j]) {
419 if (starts[j] == starts[i]+lens[i]) {
420 starts[j] = starts[i]; lens[j] += lens[i];
421 lens[i] = 0;
422 } else if (starts[i] == starts[j]+lens[j]){
423 lens[j] += lens[i];
424 lens[i] = 0;
425 } else if (!k) {
426 if (starts[i] < starts[j]+lens[j]
427 && starts[j] < starts[i]+lens[i]) {
428 starto = starts[i];
429 if (starts[j] > starto)
430 starto = starts[j];
431 endo = starts[i]+lens[i];
432 if (starts[j]+lens[j] < endo)
433 endo = starts[j]+lens[j];
434 printf(_("Partition %d overlaps with others in "
435 "sectors %d-%d\n"), i+1, starto, endo);
436 }
437 }
438 }
439 }
440 }
441 }
442 for (i = 0; i < 8; i++) {
443 if (lens[i])
444 array[i] = i;
445 else
446 array[i] = -1;
447 }
448 qsort(array,SIZE(array),sizeof(array[0]),
449 (int (*)(const void *,const void *)) verify_sun_cmp);
450 if (array[0] == -1) {
451 printf(_("No partitions defined\n"));
452 return;
453 }
454 stop = cylinders * heads * sectors;
455 if (starts[array[0]])
456 printf(_("Unused gap - sectors 0-%d\n"),starts[array[0]]);
457 for (i = 0; i < 7 && array[i+1] != -1; i++) {
458 printf(_("Unused gap - sectors %d-%d\n"),starts[array[i]]+lens[array[i]],starts[array[i+1]]);
459 }
460 start = starts[array[i]] + lens[array[i]];
461 if (start < stop)
462 printf(_("Unused gap - sectors %d-%d\n"),start,stop);
463}
464
465static void
466add_sun_partition(int n, int sys)
467{
468 uint start, stop, stop2;
469 uint starts[8], lens[8];
470 int whole_disk = 0;
471
472 char mesg[256];
473 int i, first, last;
474
475 if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) {
476 printf(_("Partition %d is already defined. Delete "
477 "it before re-adding it.\n"), n + 1);
478 return;
479 }
480
481 fetch_sun(starts,lens,&start,&stop);
482 if (stop <= start) {
483 if (n == 2)
484 whole_disk = 1;
485 else {
486 printf(_("Other partitions already cover the whole disk.\nDelete "
487 "some/shrink them before retry.\n"));
488 return;
489 }
490 }
491 snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
492 while (1) {
493 if (whole_disk)
494 first = read_int(0, 0, 0, 0, mesg);
495 else
496 first = read_int(scround(start), scround(stop)+1,
497 scround(stop), 0, mesg);
498 if (display_in_cyl_units)
499 first *= units_per_sector;
500 else
501 /* Starting sector has to be properly aligned */
502 first = (first + heads * sectors - 1) / (heads * sectors);
503 if (n == 2 && first != 0)
504 printf("\
505It is highly recommended that the third partition covers the whole disk\n\
506and is of type `Whole disk'\n");
507 /* ewt asks to add: "don't start a partition at cyl 0"
508 However, edmundo@rano.demon.co.uk writes:
509 "In addition to having a Sun partition table, to be able to
510 boot from the disc, the first partition, /dev/sdX1, must
511 start at cylinder 0. This means that /dev/sdX1 contains
512 the partition table and the boot block, as these are the
513 first two sectors of the disc. Therefore you must be
514 careful what you use /dev/sdX1 for. In particular, you must
515 not use a partition starting at cylinder 0 for Linux swap,
516 as that would overwrite the partition table and the boot
517 block. You may, however, use such a partition for a UFS
518 or EXT2 file system, as these file systems leave the first
519 1024 bytes undisturbed. */
520 /* On the other hand, one should not use partitions
521 starting at block 0 in an md, or the label will
522 be trashed. */
523 for (i = 0; i < partitions; i++)
524 if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first)
525 break;
526 if (i < partitions && !whole_disk) {
527 if (n == 2 && !first) {
528 whole_disk = 1;
529 break;
530 }
531 printf(_("Sector %d is already allocated\n"), first);
532 } else
533 break;
534 }
535 stop = cylinders * heads * sectors;
536 stop2 = stop;
537 for (i = 0; i < partitions; i++) {
538 if (starts[i] > first && starts[i] < stop)
539 stop = starts[i];
540 }
541 snprintf(mesg, sizeof(mesg),
542 _("Last %s or +size or +sizeM or +sizeK"),
543 str_units(SINGULAR));
544 if (whole_disk)
545 last = read_int(scround(stop2), scround(stop2), scround(stop2),
546 0, mesg);
547 else if (n == 2 && !first)
548 last = read_int(scround(first), scround(stop2), scround(stop2),
549 scround(first), mesg);
550 else
551 last = read_int(scround(first), scround(stop), scround(stop),
552 scround(first), mesg);
553 if (display_in_cyl_units)
554 last *= units_per_sector;
555 if (n == 2 && !first) {
556 if (last >= stop2) {
557 whole_disk = 1;
558 last = stop2;
559 } else if (last > stop) {
560 printf(_("You haven't covered the whole disk with "
561 "the 3rd partition, but your value\n"
562 "%d %s covers some other partition. "
563 "Your entry has been changed\n"
564 "to %d %s\n"),
565 scround(last), str_units(SINGULAR),
566 scround(stop), str_units(SINGULAR));
567 last = stop;
568 }
569 } else if (!whole_disk && last > stop)
570 last = stop;
571
572 if (whole_disk)
573 sys = SUN_WHOLE_DISK;
574 set_sun_partition(n, first, last, sys);
575}
576
577static void
578sun_delete_partition(int i)
579{
580 unsigned int nsec;
581
582 if (i == 2
583 && sunlabel->infos[i].id == SUN_WHOLE_DISK
584 && !sunlabel->partitions[i].start_cylinder
585 && (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == heads * sectors * cylinders)
586 printf(_("If you want to maintain SunOS/Solaris compatibility, "
587 "consider leaving this\n"
588 "partition as Whole disk (5), starting at 0, with %u "
589 "sectors\n"), nsec);
590 sunlabel->infos[i].id = 0;
591 sunlabel->partitions[i].num_sectors = 0;
592}
593
594static void
595sun_change_sysid(int i, int sys)
596{
597 if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) {
598 read_maybe_empty(
599 _("It is highly recommended that the partition at offset 0\n"
600 "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
601 "there may destroy your partition table and bootblock.\n"
602 "Type YES if you're very sure you would like that partition\n"
603 "tagged with 82 (Linux swap): "));
604 if (strcmp (line_ptr, _("YES\n")))
605 return;
606 }
607 switch (sys) {
608 case SUNOS_SWAP:
609 case LINUX_SWAP:
610 /* swaps are not mountable by default */
611 sunlabel->infos[i].flags |= 0x01;
612 break;
613 default:
614 /* assume other types are mountable;
615 user can change it anyway */
616 sunlabel->infos[i].flags &= ~0x01;
617 break;
618 }
619 sunlabel->infos[i].id = sys;
620}
621
622static void
623sun_list_table(int xtra)
624{
625 int i, w;
626
627 w = strlen(disk_device);
628 if (xtra)
629 printf(
630 _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n"
631 "%d cylinders, %d alternate cylinders, %d physical cylinders\n"
632 "%d extra sects/cyl, interleave %d:1\n"
633 "%s\n"
634 "Units = %s of %d * 512 bytes\n\n"),
635 disk_device, heads, sectors, SUN_SSWAP16(sunlabel->rspeed),
636 cylinders, SUN_SSWAP16(sunlabel->nacyl),
637 SUN_SSWAP16(sunlabel->pcylcount),
638 SUN_SSWAP16(sunlabel->sparecyl),
639 SUN_SSWAP16(sunlabel->ilfact),
640 (char *)sunlabel,
641 str_units(PLURAL), units_per_sector);
642 else
643 printf(
644 _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n"
645 "Units = %s of %d * 512 bytes\n\n"),
646 disk_device, heads, sectors, cylinders,
647 str_units(PLURAL), units_per_sector);
648
649 printf(_("%*s Flag Start End Blocks Id System\n"),
650 w + 1, _("Device"));
651 for (i = 0 ; i < partitions; i++) {
652 if (sunlabel->partitions[i].num_sectors) {
653 uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors;
654 uint32_t len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors);
655 printf("%s %c%c %9ld %9ld %9ld%c %2x %s\n",
656 partname(disk_device, i+1, w), /* device */
657 (sunlabel->infos[i].flags & 0x01) ? 'u' : ' ', /* flags */
658 (sunlabel->infos[i].flags & 0x10) ? 'r' : ' ',
659 (long) scround(start), /* start */
660 (long) scround(start+len), /* end */
661 (long) len / 2, len & 1 ? '+' : ' ', /* odd flag on end */
662 sunlabel->infos[i].id, /* type id */
663 partition_type(sunlabel->infos[i].id)); /* type name */
664 }
665 }
666}
667
668#ifdef CONFIG_FEATURE_FDISK_ADVANCED
669
670static void
671sun_set_alt_cyl(void)
672{
673 sunlabel->nacyl =
674 SUN_SSWAP16(read_int(0,SUN_SSWAP16(sunlabel->nacyl), 65535, 0,
675 _("Number of alternate cylinders")));
676}
677
678static void
679sun_set_ncyl(int cyl)
680{
681 sunlabel->ncyl = SUN_SSWAP16(cyl);
682}
683
684static void
685sun_set_xcyl(void)
686{
687 sunlabel->sparecyl =
688 SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), sectors, 0,
689 _("Extra sectors per cylinder")));
690}
691
692static void
693sun_set_ilfact(void)
694{
695 sunlabel->ilfact =
696 SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->ilfact), 32, 0,
697 _("Interleave factor")));
698}
699
700static void
701sun_set_rspeed(void)
702{
703 sunlabel->rspeed =
704 SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->rspeed), 100000, 0,
705 _("Rotation speed (rpm)")));
706}
707
708static void
709sun_set_pcylcount(void)
710{
711 sunlabel->pcylcount =
712 SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0,
713 _("Number of physical cylinders")));
714}
715#endif /* CONFIG_FEATURE_FDISK_ADVANCED */
716
717static void
718sun_write_table(void)
719{
720 unsigned short *ush = (unsigned short *)sunlabel;
721 unsigned short csum = 0;
722
723 while (ush < (unsigned short *)(&sunlabel->csum))
724 csum ^= *ush++;
725 sunlabel->csum = csum;
726 if (lseek(fd, 0, SEEK_SET) < 0)
727 fdisk_fatal(unable_to_seek);
728 if (write(fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE)
729 fdisk_fatal(unable_to_write);
730}
731#endif /* SUN_LABEL */