Author: mcayland Date: Sun Apr 21 10:27:21 2013 New Revision: 1127 URL: http://tracker.coreboot.org/trac/openbios/changeset/1127
Log: disk-label.c: Fix opening of raw block devices
If open-dev is called on a raw block device such as cdrom, the current code will always attempt to interpose a partition handler for the first valid partition table type it finds.
This is incorrect when opening a raw block device directly as it means we "fall into" the first valid partition that can be found, rather than using the full raw device. Fix this by only attempting to interpose a partition handler if the package arguments are not empty.
This fixes the NetBSD SPARC64 bootloader as reported by Martin Husemann in https://bugs.launchpad.net/qemu/+bug/1169856.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
Modified: trunk/openbios-devel/packages/disk-label.c
Modified: trunk/openbios-devel/packages/disk-label.c ============================================================================== --- trunk/openbios-devel/packages/disk-label.c Fri Apr 19 09:05:33 2013 (r1126) +++ trunk/openbios-devel/packages/disk-label.c Sun Apr 21 10:27:21 2013 (r1127) @@ -73,63 +73,70 @@ di->filesystem_ph = 0; di->parent_seek_xt = find_parent_method("seek"); di->parent_tell_xt = find_parent_method("tell"); - di->parent_read_xt = find_parent_method("read"); + di->parent_read_xt = find_parent_method("read");
- /* Read first block from parent device */ - DPUSH(0); - call_package(di->parent_seek_xt, my_parent()); - POP(); - - PUSH(pointer2cell(block0)); - PUSH(sizeof(block0)); - call_package(di->parent_read_xt, my_parent()); - status = POP(); - if (status != sizeof(block0)) - goto out; - - /* Find partition handler */ - PUSH( pointer2cell(block0) ); - selfword("find-part-handler"); - ph = POP_ph(); - if( ph ) { - /* We found a suitable partition handler, so interpose it */ - DPRINTF("Partition found on disk - scheduling interpose with ph " FMT_ucellx "\n", ph); - - push_str(path); - PUSH_ph(ph); - fword("interpose"); + /* If arguments have been passed, determine the partition/filesystem type */ + if (path && strlen(path)) {
- success = 1; - } else { - /* unknown (or missing) partition map, - * try the whole disk - */ - - DPRINTF("Unknown or missing partition map; trying whole disk\n"); - - /* Probe for filesystem from start of device */ - DPUSH ( 0 ); - PUSH_ih( my_self() ); - selfword("find-filesystem"); + /* Read first block from parent device */ + DPUSH(0); + call_package(di->parent_seek_xt, my_parent()); + POP(); + + PUSH(pointer2cell(block0)); + PUSH(sizeof(block0)); + call_package(di->parent_read_xt, my_parent()); + status = POP(); + if (status != sizeof(block0)) + goto out; + + /* Find partition handler */ + PUSH( pointer2cell(block0) ); + selfword("find-part-handler"); ph = POP_ph(); if( ph ) { - /* If we have been asked to open a particular file, interpose the filesystem package with the passed filename as an argument */ - di->filesystem_ph = ph; - - DPRINTF("Located filesystem with ph " FMT_ucellx "\n", ph); - DPRINTF("path: %s length: %d\n", path, strlen(path)); + /* We found a suitable partition handler, so interpose it */ + DPRINTF("Partition found on disk - scheduling interpose with ph " FMT_ucellx "\n", ph);
- if (path && strlen(path)) { - DPRINTF("INTERPOSE!\n"); - - push_str( path ); - PUSH_ph( ph ); - fword("interpose"); + push_str(path); + PUSH_ph(ph); + fword("interpose"); + + success = 1; + } else { + /* unknown (or missing) partition map, + * try the whole disk + */ + + DPRINTF("Unknown or missing partition map; trying whole disk\n"); + + /* Probe for filesystem from start of device */ + DPUSH ( 0 ); + PUSH_ih( my_self() ); + selfword("find-filesystem"); + ph = POP_ph(); + if( ph ) { + /* If we have been asked to open a particular file, interpose the filesystem package with the passed filename as an argument */ + di->filesystem_ph = ph; + + DPRINTF("Located filesystem with ph " FMT_ucellx "\n", ph); + DPRINTF("path: %s length: %d\n", path, strlen(path)); + + if (path && strlen(path)) { + DPRINTF("INTERPOSE!\n"); + + push_str( path ); + PUSH_ph( ph ); + fword("interpose"); + } + } else if (path && strcmp(path, "%BOOT") != 0) { + goto out; } - } else if (path && strcmp(path, "%BOOT") != 0) { - goto out; - }
+ success = 1; + } + } else { + /* No arguments were passed, so we just use the parent raw device directly */ success = 1; }