source: MondoRescue/branches/stable/mindi-busybox/util-linux/fdisk_sun.c

Last change on this file was 1770, checked in by Bruno Cornec, 16 years ago
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

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