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

Last change on this file since 1770 was 1770, checked in by Bruno Cornec, 13 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
Line 
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.