X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=blobdiff_plain;f=second%2Ffile.c;h=0082eae4c5abea524c766daa00162364d1bf2b01;hp=8f86a6eaefb0b11e685ae5831bfd799617a59ba3;hb=d1e8ca1612860aece5ee4ab5f23d91737f0fa3e6;hpb=7558941ebce6bd1e085cde875133745e4824cedd diff --git a/second/file.c b/second/file.c index 8f86a6e..0082eae 100644 --- a/second/file.c +++ b/second/file.c @@ -36,7 +36,7 @@ #include "errors.h" #include "debug.h" -extern char bootdevice[1024]; +extern char bootdevice[]; static char *netdev_path_to_filename(const char *path) { @@ -147,7 +147,7 @@ static char *netdev_path_to_dev(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 @@ -177,7 +177,7 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, char *ptr; char *ipath = NULL; char *defdev = NULL; - int device_kind; + int device_kind = -1; result->dev = NULL; result->part = -1; @@ -185,16 +185,45 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, 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 */ } @@ -202,7 +231,9 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, /* 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 @@ -223,13 +254,14 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, 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 { @@ -239,10 +271,10 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, if (!result->dev && defdev) result->dev = strdup(defdev); - + if (result->part < 0) result->part = defpart; - + if (!result->file) result->file = strdup(deffile); @@ -255,17 +287,16 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, static int file_block_open( struct boot_file_t* file, - const char* dev_name, - const char* file_name, + struct boot_fspec_t* fspec, int partition) { struct partition_t* parts; struct partition_t* p; struct partition_t* found; - - parts = partitions_lookup(dev_name); + + parts = partitions_lookup(fspec->dev); found = NULL; - + #if DEBUG if (parts) prom_printf("partitions:\n"); @@ -276,7 +307,7 @@ file_block_open( struct boot_file_t* file, DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n", p->part_number, p->part_start, p->part_size ); if (partition == -1) { - file->fs = fs_open( file, dev_name, p, file_name ); + file->fs = fs_open( file, p, fspec ); if (file->fs == NULL || fserrorno != FILE_ERR_OK) continue; else { @@ -289,14 +320,14 @@ file_block_open( struct boot_file_t* file, #if DEBUG if (found) prom_printf(" (match)\n"); -#endif +#endif } /* Note: we don't skip when found is NULL since we can, in some * cases, let OF figure out a default partition. */ DEBUG_F( "Using OF defaults.. (found = %p)\n", found ); - file->fs = fs_open( file, dev_name, found, file_name ); + file->fs = fs_open( file, found, fspec ); done: if (parts) @@ -306,12 +337,10 @@ done: } static int -file_net_open( struct boot_file_t* file, - const char* dev_name, - const char* file_name) +file_net_open(struct boot_file_t* file, struct boot_fspec_t *fspec) { file->fs = fs_of_netboot; - return fs_of_netboot->open(file, dev_name, NULL, file_name); + return fs_of_netboot->open(file, NULL, fspec); } static int @@ -348,10 +377,10 @@ static struct fs_t fs_default = }; -int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file) +int open_file(struct boot_fspec_t* spec, struct boot_file_t* file) { int result; - + memset(file, 0, sizeof(struct boot_file_t*)); file->fs = &fs_default; @@ -363,19 +392,19 @@ int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file) file->device_kind = result; else return result; - + switch(file->device_kind) { case FILE_DEVICE_BLOCK: DEBUG_F("device is a block device\n"); - return file_block_open(file, spec->dev, spec->file, spec->part); + return file_block_open(file, spec, spec->part); case FILE_DEVICE_NET: DEBUG_F("device is a network device\n"); - return file_net_open(file, spec->dev, spec->file); + return file_net_open(file, spec); } return 0; } -/* +/* * Local variables: * c-file-style: "k&r" * c-basic-offset: 5