source: MondoRescue/branches/stable/mindi-busybox/util-linux/fdisk_osf.c@ 1770

Last change on this file since 1770 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: 29.8 KB
RevLine 
[1765]1#if ENABLE_FEATURE_OSF_LABEL
2/*
3 * Copyright (c) 1987, 1988 Regents of the University of California.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgment:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35
36#ifndef BSD_DISKMAGIC
37#define BSD_DISKMAGIC ((uint32_t) 0x82564557)
38#endif
39
40#ifndef BSD_MAXPARTITIONS
41#define BSD_MAXPARTITIONS 16
42#endif
43
44#define BSD_LINUX_BOOTDIR "/usr/ucb/mdec"
45
46#if defined(i386) || defined(__sparc__) || defined(__arm__) \
47 || defined(__m68k__) || defined(__mips__) || defined(__s390__) \
48 || defined(__sh__) || defined(__x86_64__)
49#define BSD_LABELSECTOR 1
50#define BSD_LABELOFFSET 0
51#elif defined(__alpha__) || defined(__powerpc__) || defined(__ia64__) \
52 || defined(__hppa__)
53#define BSD_LABELSECTOR 0
54#define BSD_LABELOFFSET 64
55#elif defined(__s390__) || defined(__s390x__)
56#define BSD_LABELSECTOR 1
57#define BSD_LABELOFFSET 0
58#else
59#error unknown architecture
60#endif
61
62#define BSD_BBSIZE 8192 /* size of boot area, with label */
63#define BSD_SBSIZE 8192 /* max size of fs superblock */
64
65struct xbsd_disklabel {
66 uint32_t d_magic; /* the magic number */
67 int16_t d_type; /* drive type */
68 int16_t d_subtype; /* controller/d_type specific */
69 char d_typename[16]; /* type name, e.g. "eagle" */
70 char d_packname[16]; /* pack identifier */
71 /* disk geometry: */
72 uint32_t d_secsize; /* # of bytes per sector */
73 uint32_t d_nsectors; /* # of data sectors per track */
74 uint32_t d_ntracks; /* # of tracks per cylinder */
75 uint32_t d_ncylinders; /* # of data cylinders per unit */
76 uint32_t d_secpercyl; /* # of data sectors per cylinder */
77 uint32_t d_secperunit; /* # of data sectors per unit */
78 /*
79 * Spares (bad sector replacements) below
80 * are not counted in d_nsectors or d_secpercyl.
81 * Spare sectors are assumed to be physical sectors
82 * which occupy space at the end of each track and/or cylinder.
83 */
84 uint16_t d_sparespertrack; /* # of spare sectors per track */
85 uint16_t d_sparespercyl; /* # of spare sectors per cylinder */
86 /*
87 * Alternate cylinders include maintenance, replacement,
88 * configuration description areas, etc.
89 */
90 uint32_t d_acylinders; /* # of alt. cylinders per unit */
91
92 /* hardware characteristics: */
93 /*
94 * d_interleave, d_trackskew and d_cylskew describe perturbations
95 * in the media format used to compensate for a slow controller.
96 * Interleave is physical sector interleave, set up by the formatter
97 * or controller when formatting. When interleaving is in use,
98 * logically adjacent sectors are not physically contiguous,
99 * but instead are separated by some number of sectors.
100 * It is specified as the ratio of physical sectors traversed
101 * per logical sector. Thus an interleave of 1:1 implies contiguous
102 * layout, while 2:1 implies that logical sector 0 is separated
103 * by one sector from logical sector 1.
104 * d_trackskew is the offset of sector 0 on track N
105 * relative to sector 0 on track N-1 on the same cylinder.
106 * Finally, d_cylskew is the offset of sector 0 on cylinder N
107 * relative to sector 0 on cylinder N-1.
108 */
109 uint16_t d_rpm; /* rotational speed */
110 uint16_t d_interleave; /* hardware sector interleave */
111 uint16_t d_trackskew; /* sector 0 skew, per track */
112 uint16_t d_cylskew; /* sector 0 skew, per cylinder */
113 uint32_t d_headswitch; /* head switch time, usec */
114 uint32_t d_trkseek; /* track-to-track seek, usec */
115 uint32_t d_flags; /* generic flags */
116#define NDDATA 5
117 uint32_t d_drivedata[NDDATA]; /* drive-type specific information */
118#define NSPARE 5
119 uint32_t d_spare[NSPARE]; /* reserved for future use */
120 uint32_t d_magic2; /* the magic number (again) */
121 uint16_t d_checksum; /* xor of data incl. partitions */
122 /* filesystem and partition information: */
123 uint16_t d_npartitions; /* number of partitions in following */
124 uint32_t d_bbsize; /* size of boot area at sn0, bytes */
125 uint32_t d_sbsize; /* max size of fs superblock, bytes */
126 struct xbsd_partition { /* the partition table */
127 uint32_t p_size; /* number of sectors in partition */
128 uint32_t p_offset; /* starting sector */
129 uint32_t p_fsize; /* filesystem basic fragment size */
130 uint8_t p_fstype; /* filesystem type, see below */
131 uint8_t p_frag; /* filesystem fragments per block */
132 uint16_t p_cpg; /* filesystem cylinders per group */
133 } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
134};
135
136/* d_type values: */
137#define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
138#define BSD_DTYPE_MSCP 2 /* MSCP */
139#define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */
140#define BSD_DTYPE_SCSI 4 /* SCSI */
141#define BSD_DTYPE_ESDI 5 /* ESDI interface */
142#define BSD_DTYPE_ST506 6 /* ST506 etc. */
143#define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */
144#define BSD_DTYPE_HPFL 8 /* HP Fiber-link */
145#define BSD_DTYPE_FLOPPY 10 /* floppy */
146
147/* d_subtype values: */
148#define BSD_DSTYPE_INDOSPART 0x8 /* is inside dos partition */
149#define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */
150#define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */
151
152static const char *const xbsd_dktypenames[] = {
153 "unknown",
154 "SMD",
155 "MSCP",
156 "old DEC",
157 "SCSI",
158 "ESDI",
159 "ST506",
160 "HP-IB",
161 "HP-FL",
162 "type 9",
163 "floppy",
164 0
165};
166
167
168/*
169 * Filesystem type and version.
170 * Used to interpret other filesystem-specific
171 * per-partition information.
172 */
173#define BSD_FS_UNUSED 0 /* unused */
174#define BSD_FS_SWAP 1 /* swap */
175#define BSD_FS_V6 2 /* Sixth Edition */
176#define BSD_FS_V7 3 /* Seventh Edition */
177#define BSD_FS_SYSV 4 /* System V */
178#define BSD_FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */
179#define BSD_FS_V8 6 /* Eighth Edition, 4K blocks */
180#define BSD_FS_BSDFFS 7 /* 4.2BSD fast file system */
181#define BSD_FS_BSDLFS 9 /* 4.4BSD log-structured file system */
182#define BSD_FS_OTHER 10 /* in use, but unknown/unsupported */
183#define BSD_FS_HPFS 11 /* OS/2 high-performance file system */
184#define BSD_FS_ISO9660 12 /* ISO-9660 filesystem (cdrom) */
185#define BSD_FS_ISOFS BSD_FS_ISO9660
186#define BSD_FS_BOOT 13 /* partition contains bootstrap */
187#define BSD_FS_ADOS 14 /* AmigaDOS fast file system */
188#define BSD_FS_HFS 15 /* Macintosh HFS */
189#define BSD_FS_ADVFS 16 /* Digital Unix AdvFS */
190
191/* this is annoying, but it's also the way it is :-( */
192#ifdef __alpha__
193#define BSD_FS_EXT2 8 /* ext2 file system */
194#else
195#define BSD_FS_MSDOS 8 /* MS-DOS file system */
196#endif
197
198static const char *const xbsd_fstypes[] = {
199 "\x00" "unused", /* BSD_FS_UNUSED */
200 "\x01" "swap", /* BSD_FS_SWAP */
201 "\x02" "Version 6", /* BSD_FS_V6 */
202 "\x03" "Version 7", /* BSD_FS_V7 */
203 "\x04" "System V", /* BSD_FS_SYSV */
204 "\x05" "4.1BSD", /* BSD_FS_V71K */
205 "\x06" "Eighth Edition", /* BSD_FS_V8 */
206 "\x07" "4.2BSD", /* BSD_FS_BSDFFS */
207#ifdef __alpha__
208 "\x08" "ext2", /* BSD_FS_EXT2 */
209#else
210 "\x08" "MS-DOS", /* BSD_FS_MSDOS */
211#endif
212 "\x09" "4.4LFS", /* BSD_FS_BSDLFS */
213 "\x0a" "unknown", /* BSD_FS_OTHER */
214 "\x0b" "HPFS", /* BSD_FS_HPFS */
215 "\x0c" "ISO-9660", /* BSD_FS_ISO9660 */
216 "\x0d" "boot", /* BSD_FS_BOOT */
217 "\x0e" "ADOS", /* BSD_FS_ADOS */
218 "\x0f" "HFS", /* BSD_FS_HFS */
219 "\x10" "AdvFS", /* BSD_FS_ADVFS */
220 NULL
221};
222
223
224/*
225 * flags shared by various drives:
226 */
227#define BSD_D_REMOVABLE 0x01 /* removable media */
228#define BSD_D_ECC 0x02 /* supports ECC */
229#define BSD_D_BADSECT 0x04 /* supports bad sector forw. */
230#define BSD_D_RAMDISK 0x08 /* disk emulator */
231#define BSD_D_CHAIN 0x10 /* can do back-back transfers */
232#define BSD_D_DOSPART 0x20 /* within MSDOS partition */
233
234/*
235 Changes:
236 19990319 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> - i18n/nls
237
238 20000101 - David Huggins-Daines <dhuggins@linuxcare.com> - Better
239 support for OSF/1 disklabels on Alpha.
240 Also fixed unaligned accesses in alpha_bootblock_checksum()
241*/
242
243static int possibly_osf_label;
244
245#define FREEBSD_PARTITION 0xa5
246#define NETBSD_PARTITION 0xa9
247
248static void xbsd_delete_part(void);
249static void xbsd_new_part(void);
250static void xbsd_write_disklabel(void);
251static int xbsd_create_disklabel(void);
252static void xbsd_edit_disklabel(void);
253static void xbsd_write_bootstrap(void);
254static void xbsd_change_fstype(void);
255static int xbsd_get_part_index(int max);
256static int xbsd_check_new_partition(int *i);
257static void xbsd_list_types(void);
258static uint16_t xbsd_dkcksum(struct xbsd_disklabel *lp);
259static int xbsd_initlabel(struct partition *p);
260static int xbsd_readlabel(struct partition *p);
261static int xbsd_writelabel(struct partition *p);
262
263#if defined(__alpha__)
264static void alpha_bootblock_checksum(char *boot);
265#endif
266
267#if !defined(__alpha__)
268static int xbsd_translate_fstype(int linux_type);
269static void xbsd_link_part(void);
270static struct partition *xbsd_part;
271static int xbsd_part_index;
272#endif
273
274
275/* Group big globals data and allocate it in one go */
276struct bsd_globals {
277/* We access this through a uint64_t * when checksumming */
278/* hopefully xmalloc gives us required alignment */
279 char disklabelbuffer[BSD_BBSIZE];
280 struct xbsd_disklabel xbsd_dlabel;
281};
282
283static struct bsd_globals *bsd_globals_ptr;
284
285#define disklabelbuffer (bsd_globals_ptr->disklabelbuffer)
286#define xbsd_dlabel (bsd_globals_ptr->xbsd_dlabel)
287
288
289/* Code */
290
291#define bsd_cround(n) \
292 (display_in_cyl_units ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n))
293
294/*
295 * Test whether the whole disk has BSD disk label magic.
296 *
297 * Note: often reformatting with DOS-type label leaves the BSD magic,
298 * so this does not mean that there is a BSD disk label.
299 */
300static int
301check_osf_label(void)
302{
303 if (xbsd_readlabel(NULL) == 0)
304 return 0;
305 return 1;
306}
307
308static int
309bsd_trydev(const char * dev)
310{
311 if (xbsd_readlabel(NULL) == 0)
312 return -1;
313 printf("\nBSD label for device: %s\n", dev);
314 xbsd_print_disklabel(0);
315 return 0;
316}
317
318static void
319bsd_menu(void)
320{
321 puts("Command Action");
322 puts("d\tdelete a BSD partition");
323 puts("e\tedit drive data");
324 puts("i\tinstall bootstrap");
325 puts("l\tlist known filesystem types");
326 puts("n\tadd a new BSD partition");
327 puts("p\tprint BSD partition table");
328 puts("q\tquit without saving changes");
329 puts("r\treturn to main menu");
330 puts("s\tshow complete disklabel");
331 puts("t\tchange a partition's filesystem id");
332 puts("u\tchange units (cylinders/sectors)");
333 puts("w\twrite disklabel to disk");
334#if !defined(__alpha__)
335 puts("x\tlink BSD partition to non-BSD partition");
336#endif
337}
338
339#if !defined(__alpha__)
340static int
341hidden(int type)
342{
343 return type ^ 0x10;
344}
345
346static int
347is_bsd_partition_type(int type)
348{
349 return (type == FREEBSD_PARTITION ||
350 type == hidden(FREEBSD_PARTITION) ||
351 type == NETBSD_PARTITION ||
352 type == hidden(NETBSD_PARTITION));
353}
354#endif
355
356static void
357bsd_select(void)
358{
359#if !defined(__alpha__)
360 int t, ss;
361 struct partition *p;
362
363 for (t = 0; t < 4; t++) {
364 p = get_part_table(t);
365 if (p && is_bsd_partition_type(p->sys_ind)) {
366 xbsd_part = p;
367 xbsd_part_index = t;
368 ss = get_start_sect(xbsd_part);
369 if (ss == 0) {
370 printf("Partition %s has invalid starting sector 0\n",
371 partname(disk_device, t+1, 0));
372 return;
373 }
374 printf("Reading disklabel of %s at sector %d\n",
375 partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR);
376 if (xbsd_readlabel(xbsd_part) == 0)
377 if (xbsd_create_disklabel() == 0)
378 return;
379 break;
380 }
381 }
382
383 if (t == 4) {
384 printf("There is no *BSD partition on %s\n", disk_device);
385 return;
386 }
387
388#elif defined(__alpha__)
389
390 if (xbsd_readlabel(NULL) == 0)
391 if (xbsd_create_disklabel() == 0)
392 exit(EXIT_SUCCESS);
393
394#endif
395
396 while (1) {
397 putchar('\n');
398 switch (tolower(read_nonempty("BSD disklabel command (m for help): "))) {
399 case 'd':
400 xbsd_delete_part();
401 break;
402 case 'e':
403 xbsd_edit_disklabel();
404 break;
405 case 'i':
406 xbsd_write_bootstrap();
407 break;
408 case 'l':
409 xbsd_list_types();
410 break;
411 case 'n':
412 xbsd_new_part();
413 break;
414 case 'p':
415 xbsd_print_disklabel(0);
416 break;
417 case 'q':
418 close(fd);
419 exit(EXIT_SUCCESS);
420 case 'r':
421 return;
422 case 's':
423 xbsd_print_disklabel(1);
424 break;
425 case 't':
426 xbsd_change_fstype();
427 break;
428 case 'u':
429 change_units();
430 break;
431 case 'w':
432 xbsd_write_disklabel();
433 break;
434#if !defined(__alpha__)
435 case 'x':
436 xbsd_link_part();
437 break;
438#endif
439 default:
440 bsd_menu();
441 break;
442 }
443 }
444}
445
446static void
447xbsd_delete_part(void)
448{
449 int i;
450
451 i = xbsd_get_part_index(xbsd_dlabel.d_npartitions);
452 xbsd_dlabel.d_partitions[i].p_size = 0;
453 xbsd_dlabel.d_partitions[i].p_offset = 0;
454 xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;
455 if (xbsd_dlabel.d_npartitions == i + 1)
456 while (xbsd_dlabel.d_partitions[xbsd_dlabel.d_npartitions-1].p_size == 0)
457 xbsd_dlabel.d_npartitions--;
458}
459
460static void
461xbsd_new_part(void)
462{
463 off_t begin, end;
464 char mesg[256];
465 int i;
466
467 if (!xbsd_check_new_partition(&i))
468 return;
469
470#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__)
471 begin = get_start_sect(xbsd_part);
472 end = begin + get_nr_sects(xbsd_part) - 1;
473#else
474 begin = 0;
475 end = xbsd_dlabel.d_secperunit - 1;
476#endif
477
478 snprintf(mesg, sizeof(mesg), "First %s", str_units(SINGULAR));
479 begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end),
480 0, mesg);
481
482 if (display_in_cyl_units)
483 begin = (begin - 1) * xbsd_dlabel.d_secpercyl;
484
485 snprintf(mesg, sizeof(mesg), "Last %s or +size or +sizeM or +sizeK",
486 str_units(SINGULAR));
487 end = read_int(bsd_cround(begin), bsd_cround(end), bsd_cround(end),
488 bsd_cround(begin), mesg);
489
490 if (display_in_cyl_units)
491 end = end * xbsd_dlabel.d_secpercyl - 1;
492
493 xbsd_dlabel.d_partitions[i].p_size = end - begin + 1;
494 xbsd_dlabel.d_partitions[i].p_offset = begin;
495 xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;
496}
497
498static void
499xbsd_print_disklabel(int show_all)
500{
501 struct xbsd_disklabel *lp = &xbsd_dlabel;
502 struct xbsd_partition *pp;
503 int i, j;
504
505 if (show_all) {
506#if defined(__alpha__)
507 printf("# %s:\n", disk_device);
508#else
509 printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0));
510#endif
511 if ((unsigned) lp->d_type < ARRAY_SIZE(xbsd_dktypenames)-1)
512 printf("type: %s\n", xbsd_dktypenames[lp->d_type]);
513 else
514 printf("type: %d\n", lp->d_type);
515 printf("disk: %.*s\n", (int) sizeof(lp->d_typename), lp->d_typename);
516 printf("label: %.*s\n", (int) sizeof(lp->d_packname), lp->d_packname);
517 printf("flags:");
518 if (lp->d_flags & BSD_D_REMOVABLE)
519 printf(" removable");
520 if (lp->d_flags & BSD_D_ECC)
521 printf(" ecc");
522 if (lp->d_flags & BSD_D_BADSECT)
523 printf(" badsect");
524 puts("");
525 /* On various machines the fields of *lp are short/int/long */
526 /* In order to avoid problems, we cast them all to long. */
527 printf("bytes/sector: %ld\n", (long) lp->d_secsize);
528 printf("sectors/track: %ld\n", (long) lp->d_nsectors);
529 printf("tracks/cylinder: %ld\n", (long) lp->d_ntracks);
530 printf("sectors/cylinder: %ld\n", (long) lp->d_secpercyl);
531 printf("cylinders: %ld\n", (long) lp->d_ncylinders);
532 printf("rpm: %d\n", lp->d_rpm);
533 printf("interleave: %d\n", lp->d_interleave);
534 printf("trackskew: %d\n", lp->d_trackskew);
535 printf("cylinderskew: %d\n", lp->d_cylskew);
536 printf("headswitch: %ld\t\t# milliseconds\n",
537 (long) lp->d_headswitch);
538 printf("track-to-track seek: %ld\t# milliseconds\n",
539 (long) lp->d_trkseek);
540 printf("drivedata: ");
541 for (i = NDDATA - 1; i >= 0; i--)
542 if (lp->d_drivedata[i])
543 break;
544 if (i < 0)
545 i = 0;
546 for (j = 0; j <= i; j++)
547 printf("%ld ", (long) lp->d_drivedata[j]);
548 }
549 printf("\n%d partitions:\n", lp->d_npartitions);
550 printf("# start end size fstype [fsize bsize cpg]\n");
551 pp = lp->d_partitions;
552 for (i = 0; i < lp->d_npartitions; i++, pp++) {
553 if (pp->p_size) {
554 if (display_in_cyl_units && lp->d_secpercyl) {
555 printf(" %c: %8ld%c %8ld%c %8ld%c ",
556 'a' + i,
557 (long) pp->p_offset / lp->d_secpercyl + 1,
558 (pp->p_offset % lp->d_secpercyl) ? '*' : ' ',
559 (long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl,
560 ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ',
561 (long) pp->p_size / lp->d_secpercyl,
562 (pp->p_size % lp->d_secpercyl) ? '*' : ' '
563 );
564 } else {
565 printf(" %c: %8ld %8ld %8ld ",
566 'a' + i,
567 (long) pp->p_offset,
568 (long) pp->p_offset + pp->p_size - 1,
569 (long) pp->p_size
570 );
571 }
572
573 if ((unsigned) pp->p_fstype < ARRAY_SIZE(xbsd_fstypes)-1)
574 printf("%8.8s", xbsd_fstypes[pp->p_fstype]);
575 else
576 printf("%8x", pp->p_fstype);
577
578 switch (pp->p_fstype) {
579 case BSD_FS_UNUSED:
580 printf(" %5ld %5ld %5.5s ",
581 (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, "");
582 break;
583 case BSD_FS_BSDFFS:
584 printf(" %5ld %5ld %5d ",
585 (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, pp->p_cpg);
586 break;
587 default:
588 printf("%22.22s", "");
589 break;
590 }
591 puts("");
592 }
593 }
594}
595
596static void
597xbsd_write_disklabel(void)
598{
599#if defined(__alpha__)
600 printf("Writing disklabel to %s\n", disk_device);
601 xbsd_writelabel(NULL);
602#else
603 printf("Writing disklabel to %s\n",
604 partname(disk_device, xbsd_part_index + 1, 0));
605 xbsd_writelabel(xbsd_part);
606#endif
607 reread_partition_table(0); /* no exit yet */
608}
609
610static int
611xbsd_create_disklabel(void)
612{
613 char c;
614
615#if defined(__alpha__)
616 printf("%s contains no disklabel\n", disk_device);
617#else
618 printf("%s contains no disklabel\n",
619 partname(disk_device, xbsd_part_index + 1, 0));
620#endif
621
622 while (1) {
623 c = read_nonempty("Do you want to create a disklabel? (y/n) ");
624 if (c == 'y' || c == 'Y') {
625 if (xbsd_initlabel(
626#if defined(__alpha__) || defined(__powerpc__) || defined(__hppa__) || \
627 defined(__s390__) || defined(__s390x__)
628 NULL
629#else
630 xbsd_part
631#endif
632 ) == 1) {
633 xbsd_print_disklabel(1);
634 return 1;
635 } else
636 return 0;
637 } else if (c == 'n')
638 return 0;
639 }
640}
641
642static int
643edit_int(int def, const char *mesg)
644{
645 mesg = xasprintf("%s (%d): ", mesg, def);
646 do {
647 if (!read_line(mesg))
648 goto ret;
649 } while (!isdigit(*line_ptr));
650 def = atoi(line_ptr);
651 ret:
652 free((char*)mesg);
653 return def;
654}
655
656static void
657xbsd_edit_disklabel(void)
658{
659 struct xbsd_disklabel *d;
660
661 d = &xbsd_dlabel;
662
663#if defined(__alpha__) || defined(__ia64__)
664 d->d_secsize = edit_int(d->d_secsize , "bytes/sector");
665 d->d_nsectors = edit_int(d->d_nsectors , "sectors/track");
666 d->d_ntracks = edit_int(d->d_ntracks , "tracks/cylinder");
667 d->d_ncylinders = edit_int(d->d_ncylinders , "cylinders");
668#endif
669
670 /* d->d_secpercyl can be != d->d_nsectors * d->d_ntracks */
671 while (1) {
672 d->d_secpercyl = edit_int(d->d_nsectors * d->d_ntracks,
673 "sectors/cylinder");
674 if (d->d_secpercyl <= d->d_nsectors * d->d_ntracks)
675 break;
676
677 printf("Must be <= sectors/track * tracks/cylinder (default)\n");
678 }
679 d->d_rpm = edit_int(d->d_rpm , "rpm");
680 d->d_interleave = edit_int(d->d_interleave, "interleave");
681 d->d_trackskew = edit_int(d->d_trackskew , "trackskew");
682 d->d_cylskew = edit_int(d->d_cylskew , "cylinderskew");
683 d->d_headswitch = edit_int(d->d_headswitch, "headswitch");
684 d->d_trkseek = edit_int(d->d_trkseek , "track-to-track seek");
685
686 d->d_secperunit = d->d_secpercyl * d->d_ncylinders;
687}
688
689static int
690xbsd_get_bootstrap(char *path, void *ptr, int size)
691{
692 int fdb;
693
694 fdb = open(path, O_RDONLY);
695 if (fdb < 0) {
696 perror(path);
697 return 0;
698 }
699 if (read(fdb, ptr, size) < 0) {
700 perror(path);
701 close(fdb);
702 return 0;
703 }
704 printf(" ... %s\n", path);
705 close(fdb);
706 return 1;
707}
708
709static void
710sync_disks(void)
711{
712 printf("Syncing disks\n");
713 sync();
714 /* sleep(4); What? */
715}
716
717static void
718xbsd_write_bootstrap(void)
719{
720 char path[MAXPATHLEN];
721 const char *bootdir = BSD_LINUX_BOOTDIR;
722 const char *dkbasename;
723 struct xbsd_disklabel dl;
724 char *d, *p, *e;
725 int sector;
726
727 if (xbsd_dlabel.d_type == BSD_DTYPE_SCSI)
728 dkbasename = "sd";
729 else
730 dkbasename = "wd";
731
732 snprintf(path, sizeof(path), "Bootstrap: %sboot -> boot%s (%s): ",
733 dkbasename, dkbasename, dkbasename);
734 if (read_line(path)) {
735 dkbasename = line_ptr;
736 }
737 snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename);
738 if (!xbsd_get_bootstrap(path, disklabelbuffer, (int) xbsd_dlabel.d_secsize))
739 return;
740
741/* We need a backup of the disklabel (xbsd_dlabel might have changed). */
742 d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE];
743 memmove(&dl, d, sizeof(struct xbsd_disklabel));
744
745/* The disklabel will be overwritten by 0's from bootxx anyway */
746 memset(d, 0, sizeof(struct xbsd_disklabel));
747
748 snprintf(path, sizeof(path), "%s/boot%s", bootdir, dkbasename);
749 if (!xbsd_get_bootstrap(path, &disklabelbuffer[xbsd_dlabel.d_secsize],
750 (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize))
751 return;
752
753 e = d + sizeof(struct xbsd_disklabel);
754 for (p = d; p < e; p++)
755 if (*p) {
756 printf("Bootstrap overlaps with disk label!\n");
757 exit(EXIT_FAILURE);
758 }
759
760 memmove(d, &dl, sizeof(struct xbsd_disklabel));
761
762#if defined(__powerpc__) || defined(__hppa__)
763 sector = 0;
764#elif defined(__alpha__)
765 sector = 0;
766 alpha_bootblock_checksum(disklabelbuffer);
767#else
768 sector = get_start_sect(xbsd_part);
769#endif
770
771 if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1)
772 fdisk_fatal(unable_to_seek);
773 if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE))
774 fdisk_fatal(unable_to_write);
775
776#if defined(__alpha__)
777 printf("Bootstrap installed on %s\n", disk_device);
778#else
779 printf("Bootstrap installed on %s\n",
780 partname(disk_device, xbsd_part_index+1, 0));
781#endif
782
783 sync_disks();
784}
785
786static void
787xbsd_change_fstype(void)
788{
789 int i;
790
791 i = xbsd_get_part_index(xbsd_dlabel.d_npartitions);
792 xbsd_dlabel.d_partitions[i].p_fstype = read_hex(xbsd_fstypes);
793}
794
795static int
796xbsd_get_part_index(int max)
797{
798 char prompt[sizeof("Partition (a-%c): ") + 16];
799 char l;
800
801 snprintf(prompt, sizeof(prompt), "Partition (a-%c): ", 'a' + max - 1);
802 do
803 l = tolower(read_nonempty(prompt));
804 while (l < 'a' || l > 'a' + max - 1);
805 return l - 'a';
806}
807
808static int
809xbsd_check_new_partition(int *i)
810{
811 /* room for more? various BSD flavours have different maxima */
812 if (xbsd_dlabel.d_npartitions == BSD_MAXPARTITIONS) {
813 int t;
814
815 for (t = 0; t < BSD_MAXPARTITIONS; t++)
816 if (xbsd_dlabel.d_partitions[t].p_size == 0)
817 break;
818
819 if (t == BSD_MAXPARTITIONS) {
820 printf("The maximum number of partitions has been created\n");
821 return 0;
822 }
823 }
824
825 *i = xbsd_get_part_index(BSD_MAXPARTITIONS);
826
827 if (*i >= xbsd_dlabel.d_npartitions)
828 xbsd_dlabel.d_npartitions = (*i) + 1;
829
830 if (xbsd_dlabel.d_partitions[*i].p_size != 0) {
831 printf("This partition already exists\n");
832 return 0;
833 }
834
835 return 1;
836}
837
838static void
839xbsd_list_types(void)
840{
841 list_types(xbsd_fstypes);
842}
843
844static uint16_t
845xbsd_dkcksum(struct xbsd_disklabel *lp)
846{
847 uint16_t *start, *end;
848 uint16_t sum = 0;
849
850 start = (uint16_t *) lp;
851 end = (uint16_t *) &lp->d_partitions[lp->d_npartitions];
852 while (start < end)
853 sum ^= *start++;
854 return sum;
855}
856
857static int
858xbsd_initlabel(struct partition *p)
859{
860 struct xbsd_disklabel *d = &xbsd_dlabel;
861 struct xbsd_partition *pp;
862
863 get_geometry();
864 memset(d, 0, sizeof(struct xbsd_disklabel));
865
866 d->d_magic = BSD_DISKMAGIC;
867
868 if (strncmp(disk_device, "/dev/sd", 7) == 0)
869 d->d_type = BSD_DTYPE_SCSI;
870 else
871 d->d_type = BSD_DTYPE_ST506;
872
873#if !defined(__alpha__)
874 d->d_flags = BSD_D_DOSPART;
875#else
876 d->d_flags = 0;
877#endif
878 d->d_secsize = SECTOR_SIZE; /* bytes/sector */
879 d->d_nsectors = sectors; /* sectors/track */
880 d->d_ntracks = heads; /* tracks/cylinder (heads) */
881 d->d_ncylinders = cylinders;
882 d->d_secpercyl = sectors * heads; /* sectors/cylinder */
883 if (d->d_secpercyl == 0)
884 d->d_secpercyl = 1; /* avoid segfaults */
885 d->d_secperunit = d->d_secpercyl * d->d_ncylinders;
886
887 d->d_rpm = 3600;
888 d->d_interleave = 1;
889 d->d_trackskew = 0;
890 d->d_cylskew = 0;
891 d->d_headswitch = 0;
892 d->d_trkseek = 0;
893
894 d->d_magic2 = BSD_DISKMAGIC;
895 d->d_bbsize = BSD_BBSIZE;
896 d->d_sbsize = BSD_SBSIZE;
897
898#if !defined(__alpha__)
899 d->d_npartitions = 4;
900 pp = &d->d_partitions[2]; /* Partition C should be NetBSD partition */
901
902 pp->p_offset = get_start_sect(p);
903 pp->p_size = get_nr_sects(p);
904 pp->p_fstype = BSD_FS_UNUSED;
905 pp = &d->d_partitions[3]; /* Partition D should be whole disk */
906
907 pp->p_offset = 0;
908 pp->p_size = d->d_secperunit;
909 pp->p_fstype = BSD_FS_UNUSED;
910#else
911 d->d_npartitions = 3;
912 pp = &d->d_partitions[2]; /* Partition C should be
913 the whole disk */
914 pp->p_offset = 0;
915 pp->p_size = d->d_secperunit;
916 pp->p_fstype = BSD_FS_UNUSED;
917#endif
918
919 return 1;
920}
921
922/*
923 * Read a xbsd_disklabel from sector 0 or from the starting sector of p.
924 * If it has the right magic, return 1.
925 */
926static int
927xbsd_readlabel(struct partition *p)
928{
929 struct xbsd_disklabel *d;
930 int t, sector;
931
932 if (!bsd_globals_ptr)
933 bsd_globals_ptr = xzalloc(sizeof(*bsd_globals_ptr));
934
935 d = &xbsd_dlabel;
936
937 /* p is used only to get the starting sector */
938#if !defined(__alpha__)
939 sector = (p ? get_start_sect(p) : 0);
940#else
941 sector = 0;
942#endif
943
944 if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1)
945 fdisk_fatal(unable_to_seek);
946 if (BSD_BBSIZE != read(fd, disklabelbuffer, BSD_BBSIZE))
947 fdisk_fatal(unable_to_read);
948
949 memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
950 sizeof(struct xbsd_disklabel));
951
952 if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC)
953 return 0;
954
955 for (t = d->d_npartitions; t < BSD_MAXPARTITIONS; t++) {
956 d->d_partitions[t].p_size = 0;
957 d->d_partitions[t].p_offset = 0;
958 d->d_partitions[t].p_fstype = BSD_FS_UNUSED;
959 }
960
961 if (d->d_npartitions > BSD_MAXPARTITIONS)
962 printf("Warning: too many partitions (%d, maximum is %d)\n",
963 d->d_npartitions, BSD_MAXPARTITIONS);
964 return 1;
965}
966
967static int
968xbsd_writelabel(struct partition *p)
969{
970 struct xbsd_disklabel *d = &xbsd_dlabel;
971 unsigned int sector;
972
973#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__hppa__)
974 sector = get_start_sect(p) + BSD_LABELSECTOR;
975#else
976 sector = BSD_LABELSECTOR;
977#endif
978
979 d->d_checksum = 0;
980 d->d_checksum = xbsd_dkcksum(d);
981
982 /* This is necessary if we want to write the bootstrap later,
983 otherwise we'd write the old disklabel with the bootstrap.
984 */
985 memmove(&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
986 d, sizeof(struct xbsd_disklabel));
987
988#if defined(__alpha__) && BSD_LABELSECTOR == 0
989 alpha_bootblock_checksum(disklabelbuffer);
990 if (lseek(fd, 0, SEEK_SET) == -1)
991 fdisk_fatal(unable_to_seek);
992 if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE))
993 fdisk_fatal(unable_to_write);
994#else
995 if (lseek(fd, sector * SECTOR_SIZE + BSD_LABELOFFSET, SEEK_SET) == -1)
996 fdisk_fatal(unable_to_seek);
997 if (sizeof(struct xbsd_disklabel) != write(fd, d, sizeof(struct xbsd_disklabel)))
998 fdisk_fatal(unable_to_write);
999#endif
1000 sync_disks();
1001 return 1;
1002}
1003
1004
1005#if !defined(__alpha__)
1006static int
1007xbsd_translate_fstype(int linux_type)
1008{
1009 switch (linux_type) {
1010 case 0x01: /* DOS 12-bit FAT */
1011 case 0x04: /* DOS 16-bit <32M */
1012 case 0x06: /* DOS 16-bit >=32M */
1013 case 0xe1: /* DOS access */
1014 case 0xe3: /* DOS R/O */
1015 case 0xf2: /* DOS secondary */
1016 return BSD_FS_MSDOS;
1017 case 0x07: /* OS/2 HPFS */
1018 return BSD_FS_HPFS;
1019 default:
1020 return BSD_FS_OTHER;
1021 }
1022}
1023
1024static void
1025xbsd_link_part(void)
1026{
1027 int k, i;
1028 struct partition *p;
1029
1030 k = get_partition(1, partitions);
1031
1032 if (!xbsd_check_new_partition(&i))
1033 return;
1034
1035 p = get_part_table(k);
1036
1037 xbsd_dlabel.d_partitions[i].p_size = get_nr_sects(p);
1038 xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(p);
1039 xbsd_dlabel.d_partitions[i].p_fstype = xbsd_translate_fstype(p->sys_ind);
1040}
1041#endif
1042
1043#if defined(__alpha__)
1044static void
1045alpha_bootblock_checksum(char *boot)
1046{
1047 uint64_t *dp, sum;
1048 int i;
1049
1050 dp = (uint64_t *)boot;
1051 sum = 0;
1052 for (i = 0; i < 63; i++)
1053 sum += dp[i];
1054 dp[63] = sum;
1055}
1056#endif /* __alpha__ */
1057
1058/* Undefine 'global' tricks */
1059#undef disklabelbuffer
1060#undef xbsd_dlabel
1061
1062#endif /* OSF_LABEL */
Note: See TracBrowser for help on using the repository browser.