mirror of
https://github.com/ipxe/ipxe
synced 2025-12-29 02:52:36 +03:00
[iSCSI] Support Windows Server 2008 direct iSCSI installation
Add yet another ugly hack to iscsiboot.c, this time to allow the user to inhibit the shutdown/removal of the iSCSI INT13 device (and the network devices, since they are required for the iSCSI device to function). On the plus side, the fact that shutdown() now takes flags to differentiate between shutdown-for-exit and shutdown-for-boot means that another ugly hack (to allow returning via the PXE stack on BIOSes that have broken INT 18 calls) will be easier. I feel dirty.
This commit is contained in:
@@ -41,6 +41,9 @@
|
||||
/** Time to wait for link-up */
|
||||
#define LINK_WAIT_MS 15000
|
||||
|
||||
/** Shutdown flags for exit */
|
||||
int shutdown_exit_flags = 0;
|
||||
|
||||
/**
|
||||
* Identify the boot network device
|
||||
*
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <gpxe/iscsi.h>
|
||||
#include <gpxe/settings.h>
|
||||
#include <gpxe/dhcp.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/ibft.h>
|
||||
#include <gpxe/init.h>
|
||||
#include <int13.h>
|
||||
#include <usr/autoboot.h>
|
||||
#include <usr/iscsiboot.h>
|
||||
|
||||
struct setting keep_san_setting __setting = {
|
||||
.name = "keep-san",
|
||||
.description = "Preserve SAN connection",
|
||||
.tag = DHCP_EB_KEEP_SAN,
|
||||
.type = &setting_type_int8,
|
||||
};
|
||||
|
||||
/**
|
||||
* Guess boot network device
|
||||
*
|
||||
@@ -25,45 +37,66 @@ static struct net_device * guess_boot_netdev ( void ) {
|
||||
}
|
||||
|
||||
int iscsiboot ( const char *root_path ) {
|
||||
struct scsi_device scsi;
|
||||
struct int13_drive drive;
|
||||
struct scsi_device *scsi;
|
||||
struct int13_drive *drive;
|
||||
int keep_san;
|
||||
int rc;
|
||||
|
||||
memset ( &scsi, 0, sizeof ( scsi ) );
|
||||
memset ( &drive, 0, sizeof ( drive ) );
|
||||
scsi = zalloc ( sizeof ( *scsi ) );
|
||||
if ( ! scsi ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc_scsi;
|
||||
}
|
||||
drive = zalloc ( sizeof ( *drive ) );
|
||||
if ( ! drive ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc_drive;
|
||||
}
|
||||
|
||||
printf ( "iSCSI booting from %s\n", root_path );
|
||||
|
||||
if ( ( rc = iscsi_attach ( &scsi, root_path ) ) != 0 ) {
|
||||
if ( ( rc = iscsi_attach ( scsi, root_path ) ) != 0 ) {
|
||||
printf ( "Could not attach iSCSI device: %s\n",
|
||||
strerror ( rc ) );
|
||||
goto error_attach;
|
||||
goto err_attach;
|
||||
}
|
||||
if ( ( rc = init_scsidev ( &scsi ) ) != 0 ) {
|
||||
if ( ( rc = init_scsidev ( scsi ) ) != 0 ) {
|
||||
printf ( "Could not initialise iSCSI device: %s\n",
|
||||
strerror ( rc ) );
|
||||
goto error_init;
|
||||
goto err_init;
|
||||
}
|
||||
|
||||
drive.blockdev = &scsi.blockdev;
|
||||
drive->blockdev = &scsi->blockdev;
|
||||
|
||||
/* FIXME: ugly, ugly hack */
|
||||
struct net_device *netdev = guess_boot_netdev();
|
||||
struct iscsi_session *iscsi =
|
||||
container_of ( scsi.backend, struct iscsi_session, refcnt );
|
||||
container_of ( scsi->backend, struct iscsi_session, refcnt );
|
||||
ibft_fill_data ( netdev, iscsi );
|
||||
|
||||
register_int13_drive ( &drive );
|
||||
printf ( "Registered as BIOS drive %#02x\n", drive.drive );
|
||||
printf ( "Booting from BIOS drive %#02x\n", drive.drive );
|
||||
rc = int13_boot ( drive.drive );
|
||||
register_int13_drive ( drive );
|
||||
printf ( "Registered as BIOS drive %#02x\n", drive->drive );
|
||||
printf ( "Booting from BIOS drive %#02x\n", drive->drive );
|
||||
rc = int13_boot ( drive->drive );
|
||||
printf ( "Boot failed\n" );
|
||||
|
||||
printf ( "Unregistering BIOS drive %#02x\n", drive.drive );
|
||||
unregister_int13_drive ( &drive );
|
||||
/* Leave drive registered, if instructed to do so */
|
||||
keep_san = fetch_intz_setting ( NULL, &keep_san_setting );
|
||||
if ( keep_san ) {
|
||||
printf ( "Preserving connection to SAN disk\n" );
|
||||
shutdown_exit_flags |= SHUTDOWN_KEEP_DEVICES;
|
||||
return rc;
|
||||
}
|
||||
|
||||
error_init:
|
||||
iscsi_detach ( &scsi );
|
||||
error_attach:
|
||||
printf ( "Unregistering BIOS drive %#02x\n", drive->drive );
|
||||
unregister_int13_drive ( drive );
|
||||
|
||||
err_init:
|
||||
iscsi_detach ( scsi );
|
||||
err_attach:
|
||||
free ( drive );
|
||||
err_alloc_drive:
|
||||
free ( scsi );
|
||||
err_alloc_scsi:
|
||||
return rc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user