* vfs_boot.cpp now also exports gReadOnlyBootDevice which is true when the
boot device is actually read-only (even if it's using the write overlay).
* Do not create a swap file on a read-only device - this would really be a
stupid use of the write overlay (just saw this happening on an older
machine).
* Made swap_file_{add|delete}() take a const char* path - there was no reason
this was writable, and this also avoids casting away the const when adding
the default swap file.
* Minor cleanup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30975 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
|
* Copyright 2005-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _KERNEL_BOOT_DEVICE_H
|
#ifndef _KERNEL_BOOT_DEVICE_H
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
extern dev_t gBootDevice;
|
extern dev_t gBootDevice;
|
||||||
|
extern bool gReadOnlyBootDevice;
|
||||||
// defined in fs/vfs_boot.cpp
|
// defined in fs/vfs_boot.cpp
|
||||||
|
|
||||||
#endif /* _KERNEL_BOOT_DEVICE_H */
|
#endif /* _KERNEL_BOOT_DEVICE_H */
|
||||||
|
|||||||
@@ -55,15 +55,16 @@ static struct {
|
|||||||
|
|
||||||
// This can be used by other code to see if there is a boot file system already
|
// This can be used by other code to see if there is a boot file system already
|
||||||
dev_t gBootDevice = -1;
|
dev_t gBootDevice = -1;
|
||||||
|
bool gReadOnlyBootDevice = false;
|
||||||
|
|
||||||
|
|
||||||
/*! No image was chosen - prefer disks with names like "Haiku", or "System"
|
/*! No image was chosen - prefer disks with names like "Haiku", or "System"
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
compare_image_boot(const void *_a, const void *_b)
|
compare_image_boot(const void* _a, const void* _b)
|
||||||
{
|
{
|
||||||
KPartition *a = *(KPartition **)_a;
|
KPartition* a = *(KPartition**)_a;
|
||||||
KPartition *b = *(KPartition **)_b;
|
KPartition* b = *(KPartition**)_b;
|
||||||
|
|
||||||
if (a->ContentName() != NULL) {
|
if (a->ContentName() != NULL) {
|
||||||
if (b->ContentName() == NULL)
|
if (b->ContentName() == NULL)
|
||||||
@@ -95,13 +96,15 @@ compare_image_boot(const void *_a, const void *_b)
|
|||||||
compare_image_boot().
|
compare_image_boot().
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
compare_cd_boot(const void *_a, const void *_b)
|
compare_cd_boot(const void* _a, const void* _b)
|
||||||
{
|
{
|
||||||
KPartition *a = *(KPartition **)_a;
|
KPartition* a = *(KPartition**)_a;
|
||||||
KPartition *b = *(KPartition **)_b;
|
KPartition* b = *(KPartition**)_b;
|
||||||
|
|
||||||
bool aIsCD = a->Type() != NULL && !strcmp(a->Type(), kPartitionTypeDataSession);
|
bool aIsCD = a->Type() != NULL
|
||||||
bool bIsCD = b->Type() != NULL && !strcmp(b->Type(), kPartitionTypeDataSession);
|
&& !strcmp(a->Type(), kPartitionTypeDataSession);
|
||||||
|
bool bIsCD = b->Type() != NULL
|
||||||
|
&& !strcmp(b->Type(), kPartitionTypeDataSession);
|
||||||
|
|
||||||
int compare = (int)aIsCD - (int)bIsCD;
|
int compare = (int)aIsCD - (int)bIsCD;
|
||||||
if (compare != 0)
|
if (compare != 0)
|
||||||
@@ -118,7 +121,7 @@ compare_cd_boot(const void *_a, const void *_b)
|
|||||||
boot/platform/bios_ia32/devices.cpp (or similar solutions).
|
boot/platform/bios_ia32/devices.cpp (or similar solutions).
|
||||||
*/
|
*/
|
||||||
static uint32
|
static uint32
|
||||||
compute_check_sum(KDiskDevice *device, off_t offset)
|
compute_check_sum(KDiskDevice* device, off_t offset)
|
||||||
{
|
{
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
ssize_t bytesRead = read_pos(device->FD(), offset, buffer, sizeof(buffer));
|
ssize_t bytesRead = read_pos(device->FD(), offset, buffer, sizeof(buffer));
|
||||||
@@ -128,10 +131,11 @@ compute_check_sum(KDiskDevice *device, off_t offset)
|
|||||||
if (bytesRead < (ssize_t)sizeof(buffer))
|
if (bytesRead < (ssize_t)sizeof(buffer))
|
||||||
memset(buffer + bytesRead, 0, sizeof(buffer) - bytesRead);
|
memset(buffer + bytesRead, 0, sizeof(buffer) - bytesRead);
|
||||||
|
|
||||||
uint32 *array = (uint32 *)buffer;
|
uint32* array = (uint32*)buffer;
|
||||||
uint32 sum = 0;
|
uint32 sum = 0;
|
||||||
|
|
||||||
for (uint32 i = 0; i < (bytesRead + sizeof(uint32) - 1) / sizeof(uint32); i++) {
|
for (uint32 i = 0;
|
||||||
|
i < (bytesRead + sizeof(uint32) - 1) / sizeof(uint32); i++) {
|
||||||
sum += array[i];
|
sum += array[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +185,7 @@ public:
|
|||||||
bool
|
bool
|
||||||
DiskBootMethod::IsBootDevice(KDiskDevice* device, bool strict)
|
DiskBootMethod::IsBootDevice(KDiskDevice* device, bool strict)
|
||||||
{
|
{
|
||||||
disk_identifier *disk;
|
disk_identifier* disk;
|
||||||
int32 diskIdentifierSize;
|
int32 diskIdentifierSize;
|
||||||
if (fBootVolume.FindData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE,
|
if (fBootVolume.FindData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE,
|
||||||
(const void**)&disk, &diskIdentifierSize) != B_OK) {
|
(const void**)&disk, &diskIdentifierSize) != B_OK) {
|
||||||
@@ -195,7 +199,8 @@ DiskBootMethod::IsBootDevice(KDiskDevice* device, bool strict)
|
|||||||
switch (disk->bus_type) {
|
switch (disk->bus_type) {
|
||||||
case PCI_BUS:
|
case PCI_BUS:
|
||||||
case LEGACY_BUS:
|
case LEGACY_BUS:
|
||||||
// TODO: implement this! (and then enable this feature in the boot loader)
|
// TODO: implement this! (and then enable this feature in the boot
|
||||||
|
// loader)
|
||||||
// (we need a way to get the device_node of a device, then)
|
// (we need a way to get the device_node of a device, then)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -244,13 +249,13 @@ DiskBootMethod::IsBootPartition(KPartition* partition, bool& foundForSure)
|
|||||||
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() == fBootVolume.GetInt64(
|
if (partition->Offset()
|
||||||
BOOT_VOLUME_PARTITION_OFFSET, 0)) {
|
== fBootVolume.GetInt64(BOOT_VOLUME_PARTITION_OFFSET, 0)) {
|
||||||
foundForSure = true;
|
foundForSure = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// for now, we will just collect all BFS volumes
|
// for now, we will just collect all BFS/ISO9660 volumes
|
||||||
if (fMethod == BOOT_METHOD_CD
|
if (fMethod == BOOT_METHOD_CD
|
||||||
&& fBootVolume.GetBool(BOOT_VOLUME_USER_SELECTED, false)
|
&& fBootVolume.GetBool(BOOT_VOLUME_USER_SELECTED, false)
|
||||||
&& partition->Type() != NULL
|
&& partition->Type() != NULL
|
||||||
@@ -272,7 +277,7 @@ DiskBootMethod::IsBootPartition(KPartition* partition, bool& foundForSure)
|
|||||||
void
|
void
|
||||||
DiskBootMethod::SortPartitions(KPartition** partitions, int32 count)
|
DiskBootMethod::SortPartitions(KPartition** partitions, int32 count)
|
||||||
{
|
{
|
||||||
qsort(partitions, count, sizeof(KPartition *),
|
qsort(partitions, count, sizeof(KPartition*),
|
||||||
fMethod == BOOT_METHOD_CD ? compare_cd_boot : compare_image_boot);
|
fMethod == BOOT_METHOD_CD ? compare_cd_boot : compare_image_boot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +292,7 @@ DiskBootMethod::SortPartitions(KPartition** partitions, int32 count)
|
|||||||
The boot code should then just try them one by one.
|
The boot code should then just try them one by one.
|
||||||
*/
|
*/
|
||||||
static status_t
|
static status_t
|
||||||
get_boot_partitions(kernel_args *args, PartitionStack &partitions)
|
get_boot_partitions(kernel_args* args, PartitionStack& partitions)
|
||||||
{
|
{
|
||||||
const KMessage& bootVolume = args->boot_volume;
|
const KMessage& bootVolume = args->boot_volume;
|
||||||
|
|
||||||
@@ -295,9 +300,9 @@ get_boot_partitions(kernel_args *args, PartitionStack &partitions)
|
|||||||
bootVolume.Dump(&dprintf);
|
bootVolume.Dump(&dprintf);
|
||||||
|
|
||||||
// create boot method
|
// create boot method
|
||||||
int32 bootMethodType = bootVolume.GetInt32(BOOT_METHOD,
|
int32 bootMethodType = bootVolume.GetInt32(BOOT_METHOD, BOOT_METHOD_DEFAULT);
|
||||||
BOOT_METHOD_DEFAULT);
|
dprintf("get_boot_partitions(): boot method type: %ld\n", bootMethodType);
|
||||||
dprintf("get_boot_partitions(): boot method type: %ld\n", bootMethodType);
|
|
||||||
BootMethod* bootMethod = NULL;
|
BootMethod* bootMethod = NULL;
|
||||||
switch (bootMethodType) {
|
switch (bootMethodType) {
|
||||||
case BOOT_METHOD_NET:
|
case BOOT_METHOD_NET:
|
||||||
@@ -425,7 +430,7 @@ vfs_bootstrap_file_systems(void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
vfs_mount_boot_file_system(kernel_args *args)
|
vfs_mount_boot_file_system(kernel_args* args)
|
||||||
{
|
{
|
||||||
PartitionStack partitions;
|
PartitionStack partitions;
|
||||||
status_t status = get_boot_partitions(args, partitions);
|
status_t status = get_boot_partitions(args, partitions);
|
||||||
@@ -436,21 +441,26 @@ vfs_mount_boot_file_system(kernel_args *args)
|
|||||||
panic("did not find any boot partitions!");
|
panic("did not find any boot partitions!");
|
||||||
}
|
}
|
||||||
|
|
||||||
KPartition *bootPartition;
|
KPartition* bootPartition;
|
||||||
while (partitions.Pop(&bootPartition)) {
|
while (partitions.Pop(&bootPartition)) {
|
||||||
KPath path;
|
KPath path;
|
||||||
if (bootPartition->GetPath(&path) != B_OK)
|
if (bootPartition->GetPath(&path) != B_OK)
|
||||||
panic("could not get boot device!\n");
|
panic("could not get boot device!\n");
|
||||||
|
|
||||||
const char *fsName = NULL;
|
const char *fsName = NULL;
|
||||||
if (strcmp(bootPartition->ContentType(), "ISO9660 File System") == 0)
|
bool readOnly = false;
|
||||||
|
if (strcmp(bootPartition->ContentType(), "ISO9660 File System") == 0) {
|
||||||
fsName = "iso9660:write_overlay:attribute_overlay";
|
fsName = "iso9660:write_overlay:attribute_overlay";
|
||||||
|
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 >= B_OK) {
|
||||||
|
gReadOnlyBootDevice = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (gBootDevice < B_OK)
|
if (gBootDevice < B_OK)
|
||||||
panic("could not mount boot device!\n");
|
panic("could not mount boot device!\n");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Zhao Shuai, [email protected].
|
* Copyright 2008, Zhao Shuai, [email protected].
|
||||||
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
* Copyright 2008-2009, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2002-2008, Axel Dörfler, [email protected].
|
* Copyright 2002-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <NodeMonitor.h>
|
#include <NodeMonitor.h>
|
||||||
|
|
||||||
#include <arch_config.h>
|
#include <arch_config.h>
|
||||||
|
#include <boot_device.h>
|
||||||
#include <driver_settings.h>
|
#include <driver_settings.h>
|
||||||
#include <fs/fd.h>
|
#include <fs/fd.h>
|
||||||
#include <fs_interface.h>
|
#include <fs_interface.h>
|
||||||
@@ -1006,7 +1007,7 @@ VMAnonymousCache::_Commit(off_t size)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
swap_file_add(char *path)
|
swap_file_add(const char *path)
|
||||||
{
|
{
|
||||||
// open the file
|
// open the file
|
||||||
int fd = open(path, O_RDWR | O_NOCACHE, S_IRUSR | S_IWUSR);
|
int fd = open(path, O_RDWR | O_NOCACHE, S_IRUSR | S_IWUSR);
|
||||||
@@ -1083,7 +1084,7 @@ swap_file_add(char *path)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
swap_file_delete(char *path)
|
swap_file_delete(const char *path)
|
||||||
{
|
{
|
||||||
vnode *node = NULL;
|
vnode *node = NULL;
|
||||||
status_t status = vfs_get_vnode_from_path(path, true, &node);
|
status_t status = vfs_get_vnode_from_path(path, true, &node);
|
||||||
@@ -1173,6 +1174,11 @@ swap_init(void)
|
|||||||
void
|
void
|
||||||
swap_init_post_modules()
|
swap_init_post_modules()
|
||||||
{
|
{
|
||||||
|
// Never try to create a swap file on a read-only device - when booting
|
||||||
|
// from CD, the write overlay is used.
|
||||||
|
if (gReadOnlyBootDevice)
|
||||||
|
return;
|
||||||
|
|
||||||
off_t size = 0;
|
off_t size = 0;
|
||||||
|
|
||||||
void *settings = load_driver_settings("virtual_memory");
|
void *settings = load_driver_settings("virtual_memory");
|
||||||
@@ -1208,13 +1214,13 @@ swap_init_post_modules()
|
|||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
error = swap_file_add((char *)"/var/swap");
|
error = swap_file_add("/var/swap");
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
dprintf("Failed to add swap file /var/swap: %s\n", strerror(error));
|
dprintf("Failed to add swap file /var/swap: %s\n", strerror(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// used by page daemon to free swap space
|
//! Used by page daemon to free swap space.
|
||||||
bool
|
bool
|
||||||
swap_free_page_swap_space(vm_page *page)
|
swap_free_page_swap_space(vm_page *page)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user