[iSCSI] Produce meaningful errors on login failure
authorMichael Brown <mcb30@etherboot.org>
Tue, 3 Jun 2008 22:46:36 +0000 (23:46 +0100)
committerMichael Brown <mcb30@etherboot.org>
Tue, 3 Jun 2008 22:47:20 +0000 (23:47 +0100)
Return the most appropriate of EACCES, EPERM, ENODEV, ENOTSUP, EIO or
EINVAL depending on the exact error returned by the target, rather than
just always returning EPERM.

Also, ensure that error strings exist for these errors.

src/hci/strerror.c
src/include/gpxe/iscsi.h
src/net/tcp/iscsi.c

index 6967590..74995e8 100644 (file)
@@ -108,15 +108,18 @@ const char * strerror ( int errno ) {
 /** The most common errors */
 struct errortab common_errors[] __errortab = {
        { 0, "No error" },
-       { ENOMEM, "Out of memory" },
+       { EACCES, "Permission denied" },
+       { ECANCELED, "Operation cancelled" },
+       { ECONNRESET, "Connection reset" },
        { EINVAL, "Invalid argument" },
-       { ENOSPC, "No space left on device" },
        { EIO, "Input/output error" },
-       { EACCES, "Permission denied" },
-       { ENOENT, "File not found" },
        { ENETUNREACH, "Network unreachable" },
-       { ETIMEDOUT, "Connection timed out" },
-       { EPIPE, "Broken pipe" },
-       { ECANCELED, "Operation cancelled" },
+       { ENODEV, "No such device" },
+       { ENOENT, "File not found" },
        { ENOEXEC, "Not an executable image" },
+       { ENOMEM, "Out of memory" },
+       { ENOSPC, "No space left on device" },
+       { ENOTSUP, "Not supported" },
+       { EPERM, "Operation not permitted" },
+       { ETIMEDOUT, "Connection timed out" },
 };
index e4df684..5c44675 100644 (file)
@@ -224,10 +224,14 @@ struct iscsi_bhs_login_response {
 #define ISCSI_OPCODE_LOGIN_RESPONSE 0x23
 
 /* Login response status codes */
-#define ISCSI_STATUS_SUCCESS           0x00
-#define ISCSI_STATUS_REDIRECT          0x01
-#define ISCSI_STATUS_INITIATOR_ERROR   0x02
-#define ISCSI_STATUS_TARGET_ERROR      0x03
+#define ISCSI_STATUS_SUCCESS                   0x00
+#define ISCSI_STATUS_REDIRECT                  0x01
+#define ISCSI_STATUS_INITIATOR_ERROR           0x02
+#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION    0x01
+#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION     0x02
+#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND         0x03
+#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED           0x04
+#define ISCSI_STATUS_TARGET_ERROR              0x03
 
 /**
  * iSCSI SCSI command basic header segment
index 3cd5470..a12fca8 100644 (file)
@@ -830,6 +830,35 @@ static int iscsi_rx_buffered_data ( struct iscsi_session *iscsi,
        return 0;
 }
 
+/**
+ * Convert iSCSI response status to return status code
+ *
+ * @v status_class     iSCSI status class
+ * @v status_detail    iSCSI status detail
+ * @ret rc             Return status code
+ */
+static int iscsi_status_to_rc ( unsigned int status_class,
+                               unsigned int status_detail ) {
+       switch ( status_class ) {
+       case ISCSI_STATUS_INITIATOR_ERROR :
+               switch ( status_detail ) {
+               case ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION :
+                       return -EACCES;
+               case ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION :
+                       return -EPERM;
+               case ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND :
+               case ISCSI_STATUS_INITIATOR_ERROR_REMOVED :
+                       return -ENODEV;
+               default :
+                       return -ENOTSUP;
+               }
+       case ISCSI_STATUS_TARGET_ERROR :
+               return -EIO;
+       default :
+               return -EINVAL;
+       }
+}
+
 /**
  * Receive data segment of an iSCSI login response PDU
  *
@@ -877,8 +906,10 @@ static int iscsi_rx_login_response ( struct iscsi_session *iscsi,
        if ( response->status_class != 0 ) {
                DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n",
                       response->status_class, response->status_detail );
-               iscsi->instant_rc = -EPERM;
-               return -EPERM;
+               rc = iscsi_status_to_rc ( response->status_class,
+                                         response->status_detail );
+               iscsi->instant_rc = rc;
+               return rc;
        }
 
        /* Handle login transitions */
@@ -1177,7 +1208,7 @@ static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data,
                        return 0;
                DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi,
                       response->opcode );
-               return -EOPNOTSUPP;
+               return -ENOTSUP;
        }
 }