Esempio n. 1
0
int inline
iscsi_service_reconnect_if_loggedin(struct iscsi_context *iscsi)
{
	if (iscsi->is_loggedin) {
		if (iscsi_reconnect(iscsi) == 0) {
			return 0;
		}
	}
	return -1;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}