summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/iscsi_if.h17
-rw-r--r--usr/iscsi_ipc.h2
-rw-r--r--usr/iscsiadm.c43
-rw-r--r--usr/netlink.c10
4 files changed, 62 insertions, 10 deletions
diff --git a/include/iscsi_if.h b/include/iscsi_if.h
index ce9ba15..dad9fd8 100644
--- a/include/iscsi_if.h
+++ b/include/iscsi_if.h
@@ -270,7 +270,8 @@ struct iscsi_uevent {
} host_event;
struct msg_ping_comp {
uint32_t host_no;
- uint32_t status;
+ uint32_t status; /* enum
+ * iscsi_ping_status_code */
uint32_t pid; /* unique ping id associated
with each ping request */
uint32_t data_size;
@@ -515,6 +516,20 @@ enum iscsi_host_param {
#define ISCSI_HOST_NETDEV_NAME (1ULL << ISCSI_HOST_PARAM_NETDEV_NAME)
#define ISCSI_HOST_IPADDRESS (1ULL << ISCSI_HOST_PARAM_IPADDRESS)
+/* iSCSI PING status/error code */
+enum iscsi_ping_status_code {
+ ISCSI_PING_SUCCESS = 0,
+ ISCSI_PING_FW_DISABLED = 0x1,
+ ISCSI_PING_IPADDR_INVALID = 0x2,
+ ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID = 0x3,
+ ISCSI_PING_TIMEOUT = 0x4,
+ ISCSI_PING_INVALID_DEST_ADDR = 0x5,
+ ISCSI_PING_OVERSIZE_PACKET = 0x6,
+ ISCSI_PING_ICMP_ERROR = 0x7,
+ ISCSI_PING_MAX_REQ_EXCEEDED = 0x8,
+ ISCSI_PING_NO_ARP_RECEIVED = 0x9,
+};
+
#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
diff --git a/usr/iscsi_ipc.h b/usr/iscsi_ipc.h
index 08cf6f9..db5f1f0 100644
--- a/usr/iscsi_ipc.h
+++ b/usr/iscsi_ipc.h
@@ -137,7 +137,7 @@ struct iscsi_ipc {
int (*exec_ping) (uint64_t transport_handle, uint32_t host_no,
struct sockaddr *addr, uint32_t iface_num,
- uint32_t iface_type, uint32_t size);
+ uint32_t iface_type, uint32_t size, uint32_t *status);
int (*get_chap) (uint64_t transport_handle, uint32_t host_no,
uint16_t chap_tbl_idx, uint32_t num_entries,
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index a6b6a00..2b5b02c 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -2245,13 +2245,46 @@ static uint32_t parse_host_info(char *optarg, int *rc)
return host_no;
}
+static char *iscsi_ping_stat_strs[] = {
+ /* ISCSI_PING_SUCCESS */
+ "success",
+ /* ISCSI_PING_FW_DISABLED */
+ "firmware disabled",
+ /* ISCSI_PING_IPADDR_INVALID */
+ "invalid IP address",
+ /* ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID */
+ "invalid link local IPv6 address",
+ /* ISCSI_PING_TIMEOUT */
+ "timed out",
+ /* ISCSI_PING_INVALID_DEST_ADDR */
+ "invalid destination address",
+ /* ISCSI_PING_OVERSIZE_PACKET */
+ "oversized packet",
+ /* ISCSI_PING_ICMP_ERROR */
+ "ICMP error",
+ /* ISCSI_PING_MAX_REQ_EXCEEDED */
+ "Max request exceeded",
+ /* ISCSI_PING_NO_ARP_RECEIVED */
+ "No ARP response received",
+};
+
+static char *iscsi_ping_stat_to_str(uint32_t status)
+{
+ if (status < 0 || status > ISCSI_PING_NO_ARP_RECEIVED) {
+ log_error("Invalid ping status %u\n", status);
+ return NULL;
+ }
+
+ return iscsi_ping_stat_strs[status];
+}
+
static int exec_ping_op(struct iface_rec *iface, char *ip, int size, int count,
int interval)
{
int rc = ISCSI_ERR;
uint32_t iface_type = ISCSI_IFACE_TYPE_IPV4;
struct iscsi_transport *t = NULL;
- uint32_t host_no;
+ uint32_t host_no, status = 0;
struct sockaddr_storage addr;
int i;
@@ -2324,11 +2357,15 @@ static int exec_ping_op(struct iface_rec *iface, char *ip, int size, int count,
* the iscsi if to send a ping, we can add a transport
* callout here.
*/
+ status = 0;
rc = ipc->exec_ping(t->handle, host_no,
(struct sockaddr *)&addr, iface->iface_num,
- iface_type, size);
- if (!rc)
+ iface_type, size, &status);
+ if (!rc && !status)
printf("Ping %d completed\n", i);
+ else if (status)
+ printf("Ping %d failed: %s\n", i,
+ iscsi_ping_stat_to_str(status));
else
printf("Ping %d failed: %s\n", i, iscsi_err_to_str(rc));
diff --git a/usr/netlink.c b/usr/netlink.c
index cd1c9db..c43f686 100644
--- a/usr/netlink.c
+++ b/usr/netlink.c
@@ -1085,13 +1085,15 @@ ksend_ping(uint64_t transport_handle, uint32_t host_no, struct sockaddr *addr,
static int kexec_ping(uint64_t transport_handle, uint32_t host_no,
struct sockaddr *addr, uint32_t iface_num,
- uint32_t iface_type, uint32_t size)
+ uint32_t iface_type, uint32_t size, uint32_t *status)
{
struct pollfd pfd;
struct timeval ping_timer;
int timeout, fd, rc;
uint32_t pid;
+ *status = 0;
+
fd = ipc->ctldev_open();
if (fd < 0) {
log_error("Could not open netlink socket.");
@@ -1151,10 +1153,8 @@ static int kexec_ping(uint64_t transport_handle, uint32_t host_no,
if (pid != ping_event.pid)
continue;
- if (ping_event.status == 0)
- rc = 0;
- else
- rc = ISCSI_ERR;
+ rc = 0;
+ *status = ping_event.status;
break;
}