int inline iscsi_service_reconnect_if_loggedin(struct iscsi_context *iscsi) { if (iscsi->is_loggedin) { if (iscsi_reconnect(iscsi) == 0) { return 0; } } return -1; }
static void iscsi_nop_timed_event(void *opaque) { IscsiLun *iscsilun = opaque; if (iscsi_get_nops_in_flight(iscsilun->iscsi) > MAX_NOP_FAILURES) { error_report("iSCSI: NOP timeout. Reconnecting..."); iscsi_reconnect(iscsilun->iscsi); } if (iscsi_nop_out_async(iscsilun->iscsi, NULL, NULL, 0, NULL) != 0) { error_report("iSCSI: failed to sent NOP-Out. Disabling NOP messages."); return; } qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL); iscsi_set_events(iscsilun); }
int iscsi_service_reconnect_if_loggedin(struct iscsi_context *iscsi) { if (iscsi->is_loggedin) { if (iscsi_reconnect(iscsi) == 0) { return 0; } } if (iscsi->old_iscsi) { if (!iscsi->pending_reconnect) { iscsi_reconnect_cb(iscsi, SCSI_STATUS_ERROR, NULL, NULL); } return 0; } iscsi_set_error(iscsi, "iscsi_service_reconnect_if_loggedin. Can not " "reconnect right now.\n"); return -1; }
int iscsi_tcp_service(struct iscsi_context *iscsi, int revents) { if (iscsi->fd < 0) { return 0; } if (iscsi->pending_reconnect) { if (time(NULL) >= iscsi->next_reconnect) { return iscsi_reconnect(iscsi); } else { if (iscsi->old_iscsi) { return 0; } } } if (revents & POLLERR) { int err = 0; socklen_t err_size = sizeof(err); if (getsockopt(iscsi->fd, SOL_SOCKET, SO_ERROR, (char *)&err, &err_size) != 0 || err != 0) { if (err == 0) { err = errno; } iscsi_set_error(iscsi, "iscsi_service: socket error " "%s(%d).", strerror(err), err); } else { iscsi_set_error(iscsi, "iscsi_service: POLLERR, " "Unknown socket error."); } if (iscsi->socket_status_cb) { iscsi->socket_status_cb(iscsi, SCSI_STATUS_ERROR, NULL, iscsi->connect_data); iscsi->socket_status_cb = NULL; } return iscsi_service_reconnect_if_loggedin(iscsi); } if (revents & POLLHUP) { iscsi_set_error(iscsi, "iscsi_service: POLLHUP, " "socket error."); if (iscsi->socket_status_cb) { iscsi->socket_status_cb(iscsi, SCSI_STATUS_ERROR, NULL, iscsi->connect_data); iscsi->socket_status_cb = NULL; } return iscsi_service_reconnect_if_loggedin(iscsi); } if (iscsi->is_connected == 0 && revents&POLLOUT) { int err = 0; socklen_t err_size = sizeof(err); struct sockaddr_in local; socklen_t local_l = sizeof(local); if (getsockopt(iscsi->fd, SOL_SOCKET, SO_ERROR, (char *)&err, &err_size) != 0 || err != 0) { if (err == 0) { err = errno; } iscsi_set_error(iscsi, "iscsi_service: socket error " "%s(%d) while connecting.", strerror(err), err); if (iscsi->socket_status_cb) { iscsi->socket_status_cb(iscsi, SCSI_STATUS_ERROR, NULL, iscsi->connect_data); iscsi->socket_status_cb = NULL; } return iscsi_service_reconnect_if_loggedin(iscsi); } if (getsockname(iscsi->fd, (struct sockaddr *) &local, &local_l) == 0) { ISCSI_LOG(iscsi, 2, "connection established (%s:%u -> %s)", inet_ntoa(local.sin_addr), (unsigned)ntohs(local.sin_port),iscsi->connected_portal); } iscsi->is_connected = 1; if (iscsi->socket_status_cb) { iscsi->socket_status_cb(iscsi, SCSI_STATUS_GOOD, NULL, iscsi->connect_data); iscsi->socket_status_cb = NULL; } return 0; } if (revents & POLLIN) { if (iscsi_read_from_socket(iscsi) != 0) { return iscsi_service_reconnect_if_loggedin(iscsi); } } if (revents & POLLOUT) { if (iscsi_write_to_socket(iscsi) != 0) { return iscsi_service_reconnect_if_loggedin(iscsi); } } iscsi_timeout_scan(iscsi); return 0; }