On 3/17/20 4:34 PM, Gabriel Krisman Bertazi wrote:
> If an iSCSI connection happens to fail while the daemon isn't
> running (due to a crash or for another reason), the kernel failure
> report is not received.  When the daemon restarts, there is insufficient
> kernel state in sysfs for it to know that this happened.  open-iscsi
> tries to reopen every connection, but on different initiators, we'd like
> to know which connections have failed.
> 
> There is session->state, but that has a different lifetime than an iSCSI
> connection, so it doesn't directly relflect the connection state.
> 
> Cc: Khazhismel Kumykov <[email protected]>
> Suggested-by: Junho Ryu <[email protected]>
> Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
> ---
> Changes since v3:
>   - Change state type to enum (Bart)
> 
> Changes since v2:
>   - Use designated initializers (Bart)
> 
> Changes since v1:
>   - Remove dependency of state values (Bart)
> 
>  drivers/scsi/libiscsi.c             |  7 ++++++-
>  drivers/scsi/scsi_transport_iscsi.c | 29 ++++++++++++++++++++++++++++-
>  include/scsi/scsi_transport_iscsi.h |  8 ++++++++
>  3 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
> index 70b99c0e2e67..ca488c57ead4 100644
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
> @@ -3153,13 +3153,18 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, 
> int flag)
>  
>       switch (flag) {
>       case STOP_CONN_RECOVER:
> +             cls_conn->state = ISCSI_CONN_FAILED;
> +             break;
>       case STOP_CONN_TERM:
> -             iscsi_start_session_recovery(session, conn, flag);
> +             cls_conn->state = ISCSI_CONN_DOWN;
>               break;
>       default:
>               iscsi_conn_printk(KERN_ERR, conn,
>                                 "invalid stop flag %d\n", flag);
> +             return;
>       }
> +
> +     iscsi_start_session_recovery(session, conn, flag);
>  }
>  EXPORT_SYMBOL_GPL(iscsi_conn_stop);
>  
> diff --git a/drivers/scsi/scsi_transport_iscsi.c 
> b/drivers/scsi/scsi_transport_iscsi.c
> index 17a45716a0fe..0ec1b31c75a9 100644
> --- a/drivers/scsi/scsi_transport_iscsi.c
> +++ b/drivers/scsi/scsi_transport_iscsi.c
> @@ -2276,6 +2276,7 @@ iscsi_create_conn(struct iscsi_cls_session *session, 
> int dd_size, uint32_t cid)
>       INIT_LIST_HEAD(&conn->conn_list_err);
>       conn->transport = transport;
>       conn->cid = cid;
> +     conn->state = ISCSI_CONN_DOWN;
>  
>       /* this is released in the dev's release function */
>       if (!get_device(&session->dev))
> @@ -3709,8 +3710,11 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
> *nlh, uint32_t *group)
>               break;
>       case ISCSI_UEVENT_START_CONN:
>               conn = iscsi_conn_lookup(ev->u.start_conn.sid, 
> ev->u.start_conn.cid);
> -             if (conn)
> +             if (conn) {
>                       ev->r.retcode = transport->start_conn(conn);
> +                     if (!ev->r.retcode)
> +                             conn->state = ISCSI_CONN_UP;
> +             }
>               else
>                       err = -EINVAL;
>               break;
> @@ -3907,6 +3911,26 @@ iscsi_conn_attr(tcp_xmit_wsf, 
> ISCSI_PARAM_TCP_XMIT_WSF);
>  iscsi_conn_attr(tcp_recv_wsf, ISCSI_PARAM_TCP_RECV_WSF);
>  iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR);
>  
> +static const char *const connection_state_names[] = {
> +     [ISCSI_CONN_UP] = "up",
> +     [ISCSI_CONN_DOWN] = "down",
> +     [ISCSI_CONN_FAILED] = "failed"
> +};
> +
> +static ssize_t show_conn_state(struct device *dev,
> +                            struct device_attribute *attr, char *buf)
> +{
> +     struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent);
> +     const char *state = "unknown";
> +
> +     if (conn->state >= 0 &&
> +         conn->state < ARRAY_SIZE(connection_state_names))
> +             state = connection_state_names[conn->state];
> +
> +     return sprintf(buf, "%s\n", state);
> +}
> +static ISCSI_CLASS_ATTR(conn, state, S_IRUGO, show_conn_state,
> +                     NULL);
>  
>  #define iscsi_conn_ep_attr_show(param)                                       
> \
>  static ssize_t show_conn_ep_param_##param(struct device *dev,                
> \
> @@ -3976,6 +4000,7 @@ static struct attribute *iscsi_conn_attrs[] = {
>       &dev_attr_conn_tcp_xmit_wsf.attr,
>       &dev_attr_conn_tcp_recv_wsf.attr,
>       &dev_attr_conn_local_ipaddr.attr,
> +     &dev_attr_conn_state.attr,
>       NULL,
>  };
>  
> @@ -4047,6 +4072,8 @@ static umode_t iscsi_conn_attr_is_visible(struct 
> kobject *kobj,
>               param = ISCSI_PARAM_TCP_RECV_WSF;
>       else if (attr == &dev_attr_conn_local_ipaddr.attr)
>               param = ISCSI_PARAM_LOCAL_IPADDR;
> +     else if (attr == &dev_attr_conn_state.attr)
> +             return S_IRUGO;
>       else {
>               WARN_ONCE(1, "Invalid conn attr");
>               return 0;
> diff --git a/include/scsi/scsi_transport_iscsi.h 
> b/include/scsi/scsi_transport_iscsi.h
> index fa8814245796..bdcb6d69d154 100644
> --- a/include/scsi/scsi_transport_iscsi.h
> +++ b/include/scsi/scsi_transport_iscsi.h
> @@ -188,6 +188,13 @@ extern void iscsi_ping_comp_event(uint32_t host_no,
>                                 uint32_t status, uint32_t pid,
>                                 uint32_t data_size, uint8_t *data);
>  
> +/* iscsi class connection state */
> +enum iscsi_connection_state {
> +     ISCSI_CONN_UP = 0,
> +     ISCSI_CONN_DOWN,
> +     ISCSI_CONN_FAILED,
> +};
> +
>  struct iscsi_cls_conn {
>       struct list_head conn_list;     /* item in connlist */
>       struct list_head conn_list_err; /* item in connlist_err */
> @@ -198,6 +205,7 @@ struct iscsi_cls_conn {
>       struct iscsi_endpoint *ep;
>  
>       struct device dev;              /* sysfs transport/container device */
> +     enum iscsi_connection_state state;
>  };
>  
>  #define iscsi_dev_to_conn(_dev) \
> 

Reviewed-by: Lee Duncan <[email protected]>

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/2caa57c1-e1e2-3bb2-29f4-1c215016fca1%40suse.com.

Reply via email to