iPXE
Data Structures | Defines | Enumerations | Functions | Variables
sanboot.h File Reference

iPXE sanboot API More...

#include <ipxe/api.h>
#include <ipxe/refcnt.h>
#include <ipxe/list.h>
#include <ipxe/uri.h>
#include <ipxe/retry.h>
#include <ipxe/process.h>
#include <ipxe/blockdev.h>
#include <ipxe/acpi.h>
#include <config/sanboot.h>
#include <ipxe/null_sanboot.h>
#include <ipxe/dummy_sanboot.h>
#include <ipxe/efi/efi_block.h>
#include <bits/sanboot.h>

Go to the source code of this file.

Data Structures

struct  san_path
 A SAN path. More...
struct  san_device
 A SAN device. More...

Defines

#define SANBOOT_INLINE(_subsys, _api_func)   SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func )
 Calculate static inline sanboot API function name.
#define PROVIDE_SANBOOT(_subsys, _api_func, _func)   PROVIDE_SINGLE_API ( SANBOOT_PREFIX_ ## _subsys, _api_func, _func )
 Provide a sanboot API implementation.
#define PROVIDE_SANBOOT_INLINE(_subsys, _api_func)   PROVIDE_SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func )
 Provide a static inline sanboot API implementation.
#define for_each_sandev(sandev)   list_for_each_entry ( (sandev), &san_devices, list )
 Iterate over all SAN devices.

Enumerations

enum  san_device_flags { SAN_NO_DESCRIBE = 0x0001 }
 SAN device flags. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int san_hook (unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
 Hook SAN device.
void san_unhook (unsigned int drive)
 Unhook SAN device.
int san_boot (unsigned int drive, const char *filename)
 Attempt to boot from a SAN device.
int san_describe (void)
 Describe SAN devices for SAN-booted operating system.
static int have_sandevs (void)
 There exist some SAN devices.
static struct san_devicesandev_get (struct san_device *sandev)
 Get reference to SAN device.
static void sandev_put (struct san_device *sandev)
 Drop reference to SAN device.
static size_t sandev_blksize (struct san_device *sandev)
 Calculate SAN device block size.
static uint64_t sandev_capacity (struct san_device *sandev)
 Calculate SAN device capacity.
static int sandev_needs_reopen (struct san_device *sandev)
 Check if SAN device needs to be reopened.
struct san_devicesandev_find (unsigned int drive)
 Find SAN device by drive number.
int sandev_reopen (struct san_device *sandev)
 (Re)open SAN device
int sandev_reset (struct san_device *sandev)
 Reset SAN device.
int sandev_read (struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
 Read from SAN device.
int sandev_write (struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
 Write to SAN device.
struct san_devicealloc_sandev (struct uri **uris, unsigned int count, size_t priv_size)
 Allocate SAN device.
int register_sandev (struct san_device *sandev, unsigned int drive, unsigned int flags)
 Register SAN device.
void unregister_sandev (struct san_device *sandev)
 Unregister SAN device.
unsigned int san_default_drive (void)
 Get default SAN drive number.

Variables

struct list_head san_devices

Detailed Description

iPXE sanboot API

The sanboot API provides methods for hooking, unhooking, describing, and booting from SAN devices.

Definition in file sanboot.h.


Define Documentation

#define SANBOOT_INLINE (   _subsys,
  _api_func 
)    SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func )

Calculate static inline sanboot API function name.

Parameters:
_prefixSubsystem prefix
_api_funcAPI function
Return values:
_subsys_funcSubsystem API function

Definition at line 105 of file sanboot.h.

#define PROVIDE_SANBOOT (   _subsys,
  _api_func,
  _func 
)    PROVIDE_SINGLE_API ( SANBOOT_PREFIX_ ## _subsys, _api_func, _func )

Provide a sanboot API implementation.

Parameters:
_prefixSubsystem prefix
_api_funcAPI function
_funcImplementing function

Definition at line 115 of file sanboot.h.

#define PROVIDE_SANBOOT_INLINE (   _subsys,
  _api_func 
)    PROVIDE_SINGLE_API_INLINE ( SANBOOT_PREFIX_ ## _subsys, _api_func )

Provide a static inline sanboot API implementation.

Parameters:
_prefixSubsystem prefix
_api_funcAPI function

Definition at line 124 of file sanboot.h.

#define for_each_sandev (   sandev)    list_for_each_entry ( (sandev), &san_devices, list )

Iterate over all SAN devices.

Definition at line 173 of file sanboot.h.

Referenced by int13(), and int13_sync_num_drives().


Enumeration Type Documentation

SAN device flags.

Enumerator:
SAN_NO_DESCRIBE 

Device should not be included in description tables.

Definition at line 93 of file sanboot.h.

                      {
        /** Device should not be included in description tables */
        SAN_NO_DESCRIBE = 0x0001,
};

Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int san_hook ( unsigned int  drive,
struct uri **  uris,
unsigned int  count,
unsigned int  flags 
)

Hook SAN device.

Parameters:
driveDrive number
urisList of URIs
countNumber of URIs
flagsFlags
Return values:
driveDrive number, or negative error

Referenced by uriboot().

void san_unhook ( unsigned int  drive)

Unhook SAN device.

Parameters:
driveDrive number

Referenced by uriboot().

int san_boot ( unsigned int  drive,
const char *  filename 
)

Attempt to boot from a SAN device.

Parameters:
driveDrive number
filenameFilename (or NULL to use default)
Return values:
rcReturn status code

Referenced by uriboot().

int san_describe ( void  )

Describe SAN devices for SAN-booted operating system.

Return values:
rcReturn status code

Referenced by uriboot().

static int have_sandevs ( void  ) [inline, static]

There exist some SAN devices.

Return values:
existenceExistence of SAN devices

Definition at line 180 of file sanboot.h.

References list_empty, and san_devices.

Referenced by int13_hook(), and int13_unhook().

                                        {
        return ( ! list_empty ( &san_devices ) );
}
static struct san_device* sandev_get ( struct san_device sandev) [static, read]

Get reference to SAN device.

Parameters:
sandevSAN device
Return values:
sandevSAN device

Definition at line 191 of file sanboot.h.

References ref_get.

                                         {
        ref_get ( &sandev->refcnt );
        return sandev;
}
static void sandev_put ( struct san_device sandev) [inline, static]

Drop reference to SAN device.

Parameters:
sandevSAN device

Definition at line 202 of file sanboot.h.

References ref_put.

Referenced by dummy_san_hook(), dummy_san_unhook(), efi_block_hook(), efi_block_unhook(), int13_hook(), and int13_unhook().

                                         {
        ref_put ( &sandev->refcnt );
}
static size_t sandev_blksize ( struct san_device sandev) [inline, static]

Calculate SAN device block size.

Parameters:
sandevSAN device
Return values:
blksizeSector size

Definition at line 212 of file sanboot.h.

References block_device_capacity::blksize, san_device::blksize_shift, and san_device::capacity.

Referenced by int13_get_extended_parameters(), int13_get_parameters(), int13_hook(), and int13_rw_sectors().

                                                                  {
        return ( sandev->capacity.blksize << sandev->blksize_shift );
}
static uint64_t sandev_capacity ( struct san_device sandev) [inline, static]

Calculate SAN device capacity.

Parameters:
sandevSAN device
Return values:
blocksNumber of blocks

Definition at line 222 of file sanboot.h.

References san_device::blksize_shift, block_device_capacity::blocks, and san_device::capacity.

Referenced by int13_capacity32(), int13_get_extended_parameters(), and int13_guess_geometry_fdd().

                                                                     {
        return ( sandev->capacity.blocks >> sandev->blksize_shift );
}
static int sandev_needs_reopen ( struct san_device sandev) [inline, static]

Check if SAN device needs to be reopened.

Parameters:
sandevSAN device
Return values:
needs_reopenSAN device needs to be reopened

Definition at line 232 of file sanboot.h.

References san_device::active, and NULL.

Referenced by int13_device_path_info(), and sandev_command().

                                                                    {
        return ( sandev->active == NULL );
}
struct san_device* sandev_find ( unsigned int  drive) [read]

Find SAN device by drive number.

Parameters:
driveDrive number
Return values:
sandevSAN device, or NULL

Definition at line 100 of file sanboot.c.

References san_device::drive, san_device::list, list_for_each_entry, NULL, and san_devices.

Referenced by dummy_san_unhook(), efi_block_boot(), efi_block_unhook(), int13_unhook(), and register_sandev().

                                                       {
        struct san_device *sandev;

        list_for_each_entry ( sandev, &san_devices, list ) {
                if ( sandev->drive == drive )
                        return sandev;
        }
        return NULL;
}
int sandev_reopen ( struct san_device sandev)

(Re)open SAN device

Parameters:
sandevSAN device
Return values:
rcReturn status code

This function will block until the device is available.

Definition at line 365 of file sanboot.c.

References san_device::active, assert, san_device::closed, DBGC, san_device::drive, ECONNRESET, ENODEV, san_path::list, list_empty, list_first_entry, list_for_each_entry, NULL, san_device::opened, san_path::path_rc, rc, sandev_restart(), sanpath_open(), step(), strerror(), and unquiesce().

Referenced by int13_device_path_info(), register_sandev(), sandev_command(), and sandev_reset().

                                                {
        struct san_path *sanpath;
        int rc;

        /* Unquiesce system */
        unquiesce();

        /* Close any outstanding command and restart interfaces */
        sandev_restart ( sandev, -ECONNRESET );
        assert ( sandev->active == NULL );
        assert ( list_empty ( &sandev->opened ) );

        /* Open all paths */
        while ( ( sanpath = list_first_entry ( &sandev->closed,
                                               struct san_path, list ) ) ) {
                if ( ( rc = sanpath_open ( sanpath ) ) != 0 )
                        goto err_open;
        }

        /* Wait for any device to become available, or for all devices
         * to fail.
         */
        while ( sandev->active == NULL ) {
                step();
                if ( list_empty ( &sandev->opened ) ) {
                        /* Get status of the first device to be
                         * closed.  Do this on the basis that earlier
                         * errors (e.g. "invalid IQN") are probably
                         * more interesting than later errors
                         * (e.g. "TCP timeout").
                         */
                        rc = -ENODEV;
                        list_for_each_entry ( sanpath, &sandev->closed, list ) {
                                rc = sanpath->path_rc;
                                break;
                        }
                        DBGC ( sandev, "SAN %#02x never became available: %s\n",
                               sandev->drive, strerror ( rc ) );
                        goto err_none;
                }
        }

        assert ( ! list_empty ( &sandev->opened ) );
        return 0;

 err_none:
 err_open:
        sandev_restart ( sandev, rc );
        return rc;
}
int sandev_reset ( struct san_device sandev)

Reset SAN device.

Parameters:
sandevSAN device
Return values:
rcReturn status code

Definition at line 565 of file sanboot.c.

References DBGC, san_device::drive, rc, and sandev_reopen().

Referenced by efi_block_io_reset(), and int13_reset().

                                               {
        int rc;

        DBGC ( sandev, "SAN %#02x reset\n", sandev->drive );

        /* Close and reopen underlying block device */
        if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
                return rc;

        return 0;
}
int sandev_read ( struct san_device sandev,
uint64_t  lba,
unsigned int  count,
userptr_t  buffer 
)

Read from SAN device.

Parameters:
sandevSAN device
lbaStarting logical block address
countNumber of logical blocks
bufferData buffer
Return values:
rcReturn status code

Definition at line 636 of file sanboot.c.

References block_read(), rc, and sandev_rw().

Referenced by efi_block_io_read(), int13_cdrom_read_boot_catalog(), int13_extended_read(), int13_guess_geometry_hdd(), int13_parse_eltorito(), int13_read_sectors(), and sandev_parse_iso9660().

                                                         {
        int rc;

        /* Read from device */
        if ( ( rc = sandev_rw ( sandev, lba, count, buffer, block_read ) ) != 0 )
                return rc;

        return 0;
}
int sandev_write ( struct san_device sandev,
uint64_t  lba,
unsigned int  count,
userptr_t  buffer 
)

Write to SAN device.

Parameters:
sandevSAN device
lbaStarting logical block address
countNumber of logical blocks
bufferData buffer
Return values:
rcReturn status code

Definition at line 656 of file sanboot.c.

References block_write(), quiesce(), rc, and sandev_rw().

Referenced by efi_block_io_write(), int13_extended_write(), and int13_write_sectors().

                                                          {
        int rc;

        /* Write to device */
        if ( ( rc = sandev_rw ( sandev, lba, count, buffer, block_write ) ) != 0 )
                return rc;

        /* Quiesce system.  This is a heuristic designed to ensure
         * that the system is quiesced before Windows starts up, since
         * a Windows SAN boot will typically write a status flag to
         * the disk as its last action before transferring control to
         * the native drivers.
         */
        quiesce();

        return 0;
}
struct san_device* alloc_sandev ( struct uri **  uris,
unsigned int  count,
size_t  priv_size 
) [read]

Allocate SAN device.

Parameters:
urisList of URIs
countNumber of URIs
priv_sizeSize of private data
Return values:
sandevSAN device, or NULL

Definition at line 825 of file sanboot.c.

References san_path::block, san_device::closed, san_device::command, count, EINPROGRESS, san_path::index, INIT_LIST_HEAD, intf_init(), san_path::list, list_add_tail, NULL, san_device::opened, san_device::path, san_path::path_rc, san_device::paths, san_device::priv, san_path::process, process_init_stopped(), ref_init, san_device::refcnt, san_path::sandev, sandev_command_expired(), sandev_free(), size, san_device::timer, san_path::uri, uri_get(), and zalloc().

Referenced by dummy_san_hook(), efi_block_hook(), and int13_hook().

                                                      {
        struct san_device *sandev;
        struct san_path *sanpath;
        size_t size;
        unsigned int i;

        /* Allocate and initialise structure */
        size = ( sizeof ( *sandev ) + ( count * sizeof ( sandev->path[0] ) ) );
        sandev = zalloc ( size + priv_size );
        if ( ! sandev )
                return NULL;
        ref_init ( &sandev->refcnt, sandev_free );
        intf_init ( &sandev->command, &sandev_command_desc, &sandev->refcnt );
        timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
        sandev->priv = ( ( ( void * ) sandev ) + size );
        sandev->paths = count;
        INIT_LIST_HEAD ( &sandev->opened );
        INIT_LIST_HEAD ( &sandev->closed );
        for ( i = 0 ; i < count ; i++ ) {
                sanpath = &sandev->path[i];
                sanpath->sandev = sandev;
                sanpath->index = i;
                sanpath->uri = uri_get ( uris[i] );
                list_add_tail ( &sanpath->list, &sandev->closed );
                intf_init ( &sanpath->block, &sanpath_block_desc,
                            &sandev->refcnt );
                process_init_stopped ( &sanpath->process, &sanpath_process_desc,
                                       &sandev->refcnt );
                sanpath->path_rc = -EINPROGRESS;
        }

        return sandev;
}
int register_sandev ( struct san_device sandev,
unsigned int  drive,
unsigned int  flags 
)

Register SAN device.

Parameters:
sandevSAN device
driveDrive number
flagsFlags
Return values:
rcReturn status code

Definition at line 868 of file sanboot.c.

References DBGC, san_device::drive, drive, EADDRINUSE, san_device::flags, flags, san_device::list, list_add_tail, list_del, NULL, rc, san_devices, sandev_command(), sandev_command_read_capacity(), sandev_describe(), sandev_find(), sandev_parse_iso9660(), sandev_reopen(), sandev_restart(), and sandev_undescribe().

Referenced by dummy_san_hook(), efi_block_hook(), and int13_hook().

                                           {
        int rc;

        /* Check that drive number is not in use */
        if ( sandev_find ( drive ) != NULL ) {
                DBGC ( sandev, "SAN %#02x is already in use\n", drive );
                rc = -EADDRINUSE;
                goto err_in_use;
        }

        /* Record drive number and flags */
        sandev->drive = drive;
        sandev->flags = flags;

        /* Check that device is capable of being opened (i.e. that all
         * URIs are well-formed and that at least one path is
         * working).
         */
        if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
                goto err_reopen;

        /* Describe device */
        if ( ( rc = sandev_describe ( sandev ) ) != 0 )
                goto err_describe;

        /* Read device capacity */
        if ( ( rc = sandev_command ( sandev, sandev_command_read_capacity,
                                     NULL ) ) != 0 )
                goto err_capacity;

        /* Configure as a CD-ROM, if applicable */
        if ( ( rc = sandev_parse_iso9660 ( sandev ) ) != 0 )
                goto err_iso9660;

        /* Add to list of SAN devices */
        list_add_tail ( &sandev->list, &san_devices );
        DBGC ( sandev, "SAN %#02x registered\n", sandev->drive );

        return 0;

        list_del ( &sandev->list );
 err_iso9660:
 err_capacity:
 err_describe:
 err_reopen:
        sandev_restart ( sandev, rc );
        sandev_undescribe ( sandev );
 err_in_use:
        return rc;
}
void unregister_sandev ( struct san_device sandev)

Unregister SAN device.

Parameters:
sandevSAN device

Definition at line 925 of file sanboot.c.

References assert, DBGC, san_device::drive, san_device::list, list_del, sandev_restart(), sandev_undescribe(), and san_device::timer.

Referenced by dummy_san_hook(), dummy_san_unhook(), efi_block_hook(), efi_block_unhook(), int13_hook(), and int13_unhook().

                                                     {

        /* Sanity check */
        assert ( ! timer_running ( &sandev->timer ) );

        /* Remove from list of SAN devices */
        list_del ( &sandev->list );

        /* Shut down interfaces */
        sandev_restart ( sandev, 0 );

        /* Remove ACPI descriptors */
        sandev_undescribe ( sandev );

        DBGC ( sandev, "SAN %#02x unregistered\n", sandev->drive );
}
unsigned int san_default_drive ( void  )

Get default SAN drive number.

Return values:
driveDefault drive number

Definition at line 956 of file sanboot.c.

References drive, fetch_uint_setting(), NULL, and SAN_DEFAULT_DRIVE.

Referenced by netboot(), and sanboot_core_exec().

                                        {
        unsigned long drive;

        /* Use "san-drive" setting, if specified */
        if ( fetch_uint_setting ( NULL, &san_drive_setting, &drive ) >= 0 )
                return drive;

        /* Otherwise, default to booting from first hard disk */
        return SAN_DEFAULT_DRIVE;
}

Variable Documentation