[OpenBIOS] [PATCH] disk-label.c: Fix opening of raw block devices

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Fri Apr 19 12:08:31 CEST 2013


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 at ilande.co.uk>
---
 openbios-devel/packages/disk-label.c |  105 ++++++++++++++++++----------------
 1 file changed, 56 insertions(+), 49 deletions(-)

diff --git a/openbios-devel/packages/disk-label.c b/openbios-devel/packages/disk-label.c
index 44b9f9e..1c18d74 100644
--- a/openbios-devel/packages/disk-label.c
+++ b/openbios-devel/packages/disk-label.c
@@ -73,63 +73,70 @@ dlabel_open( dlabel_info_t *di )
 	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
-		 */
+		/* Read first block from parent device */
+		DPUSH(0);
+		call_package(di->parent_seek_xt, my_parent());
+		POP();
 
-		DPRINTF("Unknown or missing partition map; trying whole disk\n");
+		PUSH(pointer2cell(block0));
+		PUSH(sizeof(block0));
+		call_package(di->parent_read_xt, my_parent());
+		status = POP();
+		if (status != sizeof(block0))
+			goto out;
 
-		/* Probe for filesystem from start of device */
-		DPUSH ( 0 );	
-		PUSH_ih( my_self() );
-		selfword("find-filesystem");
+		/* 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));
-
-                        if (path && strlen(path)) {
-				DPRINTF("INTERPOSE!\n");
-
-				push_str( path );
-				PUSH_ph( ph );
-				fword("interpose");
+			/* 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");	
+
+			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 we passed, so we just use the parent raw device directly */
 		success = 1;
 	}
 
-- 
1.7.10.4




More information about the OpenBIOS mailing list