Prepare for netboot fix(following patch). No Functional change.
[yaboot.git] / second / file.c
index 0e58286e724f1be9c44fd4158cebe21d5e23747c..0082eae4c5abea524c766daa00162364d1bf2b01 100644 (file)
@@ -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)
 {
@@ -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;
+
+      /*
+       * 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,7 +254,8 @@ 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))
@@ -255,15 +287,14 @@ 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
@@ -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 {
@@ -296,7 +327,7 @@ file_block_open(    struct boot_file_t*     file,
       * 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,7 +377,7 @@ 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;
 
@@ -367,10 +396,10 @@ int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file)
      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;
 }