boot_loader_openfirmware: Add iSCSI boot support
If no Haiku remote disk server is found, try an iSCSI discovery session on the TFTP server, using the IP address from the boot command or OF options. All available IPv4 targets are considered, Target Portal Groups are ignored. RFC 4173 suggests a mechanism that avoids a discovery session by using DHCP; that requires a compatibly configured DHCP server though and we wouldn't have access to such data currently anyway. iSCSI is currently used as fallback, and when it doesn't succeed it falls back to the menu as before. Resolves ticket #5319. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38537 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2003-2006, Axel Dörfler, [email protected].
|
* Copyright 2003-2006, Axel Dörfler, [email protected].
|
||||||
|
* Copyright 2010, Andreas Färber <[email protected]>
|
||||||
* All rights reserved. Distributed under the terms of the MIT License.
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -10,6 +11,8 @@
|
|||||||
#include <boot/vfs.h>
|
#include <boot/vfs.h>
|
||||||
#include <boot/stdio.h>
|
#include <boot/stdio.h>
|
||||||
#include <boot/stage2.h>
|
#include <boot/stage2.h>
|
||||||
|
#include <boot/net/IP.h>
|
||||||
|
#include <boot/net/iSCSITarget.h>
|
||||||
#include <boot/net/NetStack.h>
|
#include <boot/net/NetStack.h>
|
||||||
#include <boot/net/RemoteDisk.h>
|
#include <boot/net/RemoteDisk.h>
|
||||||
#include <platform/openfirmware/devices.h>
|
#include <platform/openfirmware/devices.h>
|
||||||
@@ -20,6 +23,9 @@
|
|||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ENABLE_ISCSI
|
||||||
|
|
||||||
|
|
||||||
char sBootPath[192];
|
char sBootPath[192];
|
||||||
|
|
||||||
|
|
||||||
@@ -46,14 +52,45 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
|
|||||||
status_t error = net_stack_init();
|
status_t error = net_stack_init();
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
ip_addr_t bootAddress = 0;
|
||||||
|
char* bootArgs = strrchr(sBootPath, ':');
|
||||||
|
if (bootArgs != NULL) {
|
||||||
|
bootArgs++;
|
||||||
|
char* comma = strchr(bootArgs, ',');
|
||||||
|
if (comma != NULL && comma - bootArgs > 0) {
|
||||||
|
comma[0] = '\0';
|
||||||
|
bootAddress = ip_parse_address(bootArgs);
|
||||||
|
comma[0] = ',';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bootAddress == 0) {
|
||||||
|
int package = of_finddevice("/options");
|
||||||
|
char defaultServerIP[16];
|
||||||
|
int bytesRead = of_getprop(package, "default-server-ip",
|
||||||
|
defaultServerIP, sizeof(defaultServerIP) - 1);
|
||||||
|
if (bytesRead != OF_FAILED && bytesRead > 1) {
|
||||||
|
defaultServerIP[bytesRead] = '\0';
|
||||||
|
bootAddress = ip_parse_address(defaultServerIP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// init a remote disk, if possible
|
// init a remote disk, if possible
|
||||||
RemoteDisk *remoteDisk = RemoteDisk::FindAnyRemoteDisk();
|
RemoteDisk *remoteDisk = RemoteDisk::FindAnyRemoteDisk();
|
||||||
if (!remoteDisk)
|
if (remoteDisk != NULL) {
|
||||||
return B_ENTRY_NOT_FOUND;
|
devicesList->Add(remoteDisk);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
devicesList->Add(remoteDisk);
|
#ifdef ENABLE_ISCSI
|
||||||
return B_OK;
|
if (bootAddress != 0) {
|
||||||
|
if (iSCSITarget::DiscoverTargets(bootAddress, ISCSI_PORT,
|
||||||
|
devicesList))
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp("block", type) != 0) {
|
if (strcmp("block", type) != 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user