* Replaced a few hardcoded partitioning/file system type names by the

respective constants.
* compare_image_boot(): Compare volume names case insensitively.
* DiskBootMethod::IsBootDevice(): For BOOT_METHOD_CD only accept devices with
  removable media.
* DiskBootMethod::IsBootPartition(): Added special recognition for anyboot
  CDs. Since their partition types aren't kPartitionTypeDataSession,
  compare_cd_boot() didn't prefer them and it was more or less random whether
  it was chosen when other Haiku installations where available. Moreover
  selecting the CD in the boot loader menu would cause the kernel not to find
  it.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36403 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2010-04-21 18:00:23 +00:00
parent 665c794f1d
commit 63fe660c1b
+43 -15
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2007, Ingo Weinhold, [email protected]. * Copyright 2007-2010, Ingo Weinhold, [email protected].
* Copyright 2002-2010, Axel Dörfler, [email protected]. * Copyright 2002-2010, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
@@ -74,7 +74,7 @@ compare_image_boot(const void* _a, const void* _b)
} else } else
return 0; return 0;
int compare = strcmp(a->ContentName(), b->ContentName()); int compare = strcasecmp(a->ContentName(), b->ContentName());
if (!compare) if (!compare)
return 0; return 0;
@@ -196,6 +196,10 @@ DiskBootMethod::IsBootDevice(KDiskDevice* device, bool strict)
TRACE(("boot device: bus %ld, device %ld\n", disk->bus_type, TRACE(("boot device: bus %ld, device %ld\n", disk->bus_type,
disk->device_type)); disk->device_type));
// Assume that CD boots only happen off removable media.
if (fMethod == BOOT_METHOD_CD && !device->IsRemovable())
return false;
switch (disk->bus_type) { switch (disk->bus_type) {
case PCI_BUS: case PCI_BUS:
case LEGACY_BUS: case LEGACY_BUS:
@@ -246,26 +250,49 @@ DiskBootMethod::IsBootDevice(KDiskDevice* device, bool strict)
bool bool
DiskBootMethod::IsBootPartition(KPartition* partition, bool& foundForSure) DiskBootMethod::IsBootPartition(KPartition* partition, bool& foundForSure)
{ {
off_t bootPartitionOffset = fBootVolume.GetInt64(
BOOT_VOLUME_PARTITION_OFFSET, 0);
if (!fBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) { if (!fBootVolume.GetBool(BOOT_VOLUME_BOOTED_FROM_IMAGE, false)) {
// the simple case: we can just boot from the selected boot // the simple case: we can just boot from the selected boot
// device // device
if (partition->Offset() if (partition->Offset() == bootPartitionOffset) {
== fBootVolume.GetInt64(BOOT_VOLUME_PARTITION_OFFSET, 0)) { dprintf("Identified boot partition by partition offset.\n");
foundForSure = true; foundForSure = true;
return true; return true;
} }
} else { } else {
// for now, we will just collect all BFS/ISO9660 volumes // For now, unless we can positively identify an anyboot CD, we will
if (fMethod == BOOT_METHOD_CD // just collect all BFS/ISO9660 volumes.
&& fBootVolume.GetBool(BOOT_VOLUME_USER_SELECTED, false)
&& partition->Type() != NULL if (fMethod == BOOT_METHOD_CD) {
&& strcmp(partition->Type(), kPartitionTypeDataSession)) { // Check for the boot partition of an anyboot CD. We identify it as
return false; // such, if it is the only primary partition on the CD, has type
// BFS, and the boot partition offset is 0.
KDiskDevice* device = partition->Device();
if (IsBootDevice(device, false) && bootPartitionOffset == 0
&& partition->Parent() == device && device->CountChildren() == 1
&& device->ContentType() != NULL
&& strcmp(device->ContentType(), kPartitionTypeIntel) == 0
&& partition->ContentType() != NULL
&& strcmp(partition->ContentType(), kPartitionTypeBFS) == 0) {
dprintf("Identified anyboot CD.\n");
foundForSure = true;
return true;
}
// Ignore non-session partitions, if a boot partition was selected
// by the user.
if (fBootVolume.GetBool(BOOT_VOLUME_USER_SELECTED, false)
&& partition->Type() != NULL
&& strcmp(partition->Type(), kPartitionTypeDataSession) != 0) {
return false;
}
} }
if (partition->ContentType() != NULL if (partition->ContentType() != NULL
&& (!strcmp(partition->ContentType(), "Be File System") && (strcmp(partition->ContentType(), kPartitionTypeBFS) == 0
|| !strcmp(partition->ContentType(), "ISO9660 File System"))) { || strcmp(partition->ContentType(), kPartitionTypeISO9660) == 0)) {
return true; return true;
} }
} }
@@ -449,18 +476,19 @@ vfs_mount_boot_file_system(kernel_args* args)
const char* fsName = NULL; const char* fsName = NULL;
bool readOnly = false; bool readOnly = false;
if (strcmp(bootPartition->ContentType(), "ISO9660 File System") == 0) { if (strcmp(bootPartition->ContentType(), kPartitionTypeISO9660) == 0) {
fsName = "iso9660:write_overlay:attribute_overlay"; fsName = "iso9660:write_overlay:attribute_overlay";
readOnly = true; readOnly = true;
} else if (bootPartition->IsReadOnly() } else if (bootPartition->IsReadOnly()
&& strcmp(bootPartition->ContentType(), "Be File System") == 0) { && strcmp(bootPartition->ContentType(), kPartitionTypeBFS) == 0) {
fsName = "bfs:write_overlay"; fsName = "bfs:write_overlay";
readOnly = true; readOnly = true;
} }
TRACE(("trying to mount boot partition: %s\n", path.Path())); TRACE(("trying to mount boot partition: %s\n", path.Path()));
gBootDevice = _kern_mount("/boot", path.Path(), fsName, 0, NULL, 0); gBootDevice = _kern_mount("/boot", path.Path(), fsName, 0, NULL, 0);
if (gBootDevice >= B_OK) { if (gBootDevice >= 0) {
dprintf("Mounted boot partition: %s\n", path.Path());
gReadOnlyBootDevice = readOnly; gReadOnlyBootDevice = readOnly;
break; break;
} }