#include "errors.h"
#include "debug.h"
-extern char bootdevice[1024];
+extern char bootdevice[];
static char *netdev_path_to_filename(const char *path)
{
/* This function follows the device path in the devtree and separates
the device name, partition number, and other datas (mostly file name)
the string passed in parameters is changed since 0 are put in place
- of some separators to terminate the various strings.
+ of some separators to terminate the various strings.
when a default device is supplied imagepath will be assumed to be a
plain filename unless it contains a : otherwise if defaultdev is
char *ptr;
char *ipath = NULL;
char *defdev = NULL;
- int device_kind;
+ int device_kind = -1;
result->dev = NULL;
result->part = -1;
if (!imagepath)
return 0;
- else if (!(ipath = strdup(imagepath)))
+
+ /*
+ * Do preliminary checking for an iscsi device; it may appear as
+ * pure a network device (device_type == "network") if this is
+ * ISWI. This is the case on IBM systems doing an iscsi OFW
+ * boot.
+ */
+ if (strstr(imagepath, TOK_ISCSI)) {
+ /*
+ * get the virtual device information from the
+ * "nas-bootdevice" property.
+ */
+ if (prom_get_chosen("nas-bootdevice", bootdevice, BOOTDEVSZ)) {
+ DEBUG_F("reset boot-device to"
+ " /chosen/nas-bootdevice = %s\n", bootdevice);
+ device_kind = FILE_DEVICE_ISCSI;
+ ipath = strdup(bootdevice);
+ if (!ipath)
+ return 0;
+ }
+ else
+ return 0;
+ }
+ else if (!(ipath = strdup(imagepath)))
return 0;
if (defdevice) {
defdev = strdup(defdevice);
device_kind = prom_get_devtype(defdev);
- } else
+ } else if (device_kind == -1)
device_kind = prom_get_devtype(ipath);
- if (device_kind != FILE_DEVICE_NET && strchr(defdev, ':') != NULL) {
+ /*
+ * When an iscsi iqn is present, it may have embedded colons, so
+ * don't parse off anything.
+ */
+ if (device_kind != FILE_DEVICE_NET &&
+ device_kind != FILE_DEVICE_ISCSI &&
+ strchr(defdev, ':') != NULL) {
if ((ptr = strrchr(defdev, ':')) != NULL)
*ptr = 0; /* remove trailing : from defdevice if necessary */
}
/* This will not properly handle an obp-tftp argument list
* with elements after the filename; that is handled below.
*/
- if (device_kind != FILE_DEVICE_NET && strchr(ipath, ':') != NULL) {
+ if (device_kind != FILE_DEVICE_NET &&
+ device_kind != FILE_DEVICE_ISCSI &&
+ strchr(ipath, ':') != NULL) {
if ((ptr = strrchr(ipath, ',')) != NULL) {
char *colon = strrchr(ipath, ':');
/* If a ':' occurs *after* a ',', then we assume that there is
if (!defdev)
result->dev = netdev_path_to_dev(ipath);
- } else if ((ptr = strchr(ipath, ':')) != NULL) {
+ } else if (device_kind != FILE_DEVICE_ISCSI &&
+ (ptr = strrchr(ipath, ':')) != NULL) {
*ptr = 0;
result->dev = strdup(ipath);
if (*(ptr+1))
result->part = simple_strtol(ptr+1, NULL, 10);
} else if (!defdev) {
- result->dev = strdup(ipath);
+ result->dev = strdup(ipath);
} else if (strlen(ipath)) {
result->file = strdup(ipath);
} else {
if (!result->dev && defdev)
result->dev = strdup(defdev);
-
+
if (result->part < 0)
result->part = defpart;
-
+
if (!result->file)
result->file = strdup(deffile);
struct partition_t* parts;
struct partition_t* p;
struct partition_t* found;
-
+
parts = partitions_lookup(dev_name);
found = NULL;
-
+
#if DEBUG
if (parts)
prom_printf("partitions:\n");
#if DEBUG
if (found)
prom_printf(" (match)\n");
-#endif
+#endif
}
/* Note: we don't skip when found is NULL since we can, in some
int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file)
{
int result;
-
+
memset(file, 0, sizeof(struct boot_file_t*));
file->fs = &fs_default;
file->device_kind = result;
else
return result;
-
+
switch(file->device_kind) {
case FILE_DEVICE_BLOCK:
DEBUG_F("device is a block device\n");
return 0;
}
-/*
+/*
* Local variables:
* c-file-style: "k&r"
* c-basic-offset: 5