summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/host.c44
-rw-r--r--usr/iscsi_sysfs.c120
-rw-r--r--usr/iscsi_sysfs.h4
-rw-r--r--usr/sysfs.c28
-rw-r--r--usr/sysfs.h4
5 files changed, 189 insertions, 11 deletions
diff --git a/usr/host.c b/usr/host.c
index d171455..60f67a7 100644
--- a/usr/host.c
+++ b/usr/host.c
@@ -118,6 +118,47 @@ static int host_info_print_flat(void *data, struct host_info *hinfo)
return 0;
}
+static int print_host_iface(void *data, struct iface_rec *iface)
+{
+ char *prefix = data;
+
+ printf("%s**********\n", prefix);
+ printf("%sInterface:\n", prefix);
+ printf("%s**********\n", prefix);
+
+ printf("%sKernel Name: %s\n", prefix, iface->name);
+
+ if (!strlen(iface->ipaddress))
+ printf("%sIPaddress: %s\n", prefix, UNKNOWN_VALUE);
+ else if (strchr(iface->ipaddress, '.')) {
+ printf("%sIPaddress: %s\n", prefix, iface->ipaddress);
+ printf("%sGateway: %s\n", prefix, iface->gateway);
+ printf("%sSubnet: %s\n", prefix, iface->subnet_mask);
+ printf("%sBootProto: %s\n", prefix, iface->bootproto);
+ } else {
+ printf("%sIPaddress: [%s]\n", prefix, iface->ipaddress);
+ printf("%sIPaddress Autocfg: %s\n", prefix, iface->ipv6_autocfg);
+ printf("%sLink Local Address: [%s]\n", prefix,
+ iface->ipv6_linklocal);
+ printf("%sLink Local Autocfg: %s\n", prefix,
+ iface->linklocal_autocfg);
+ printf("%sRouter Address: [%s]\n", prefix, iface->ipv6_router);
+ }
+
+ printf("%sMTU: %u\n", prefix, iface->mtu);
+ printf("%svlan ID: %u\n", prefix, iface->vlan_id);
+ printf("%svlan priority: %u\n", prefix, iface->vlan_priority);
+ return 0;
+}
+
+static void print_host_ifaces(struct host_info *hinfo, char *prefix)
+{
+ int nr_found;
+
+ iscsi_sysfs_for_each_iface_on_host(prefix, hinfo->host_no, &nr_found,
+ print_host_iface);
+}
+
static int host_info_print_tree(void *data, struct host_info *hinfo)
{
struct list_head sessions;
@@ -128,6 +169,7 @@ static int host_info_print_tree(void *data, struct host_info *hinfo)
INIT_LIST_HEAD(&sessions);
+
printf("Host Number: %u\n", hinfo->host_no);
if (!iscsi_sysfs_get_host_state(state, hinfo->host_no))
printf("\tState: %s\n", state);
@@ -135,6 +177,8 @@ static int host_info_print_tree(void *data, struct host_info *hinfo)
printf("\tState: Unknown\n");
print_host_info(&hinfo->iface, "\t");
+ print_host_ifaces(hinfo, "\t");
+
if (!session_info_flags)
return 0;
diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c
index 9f7a6f2..373507d 100644
--- a/usr/iscsi_sysfs.c
+++ b/usr/iscsi_sysfs.c
@@ -50,6 +50,7 @@
#define ISCSI_CONN_SUBSYS "iscsi_connection"
#define ISCSI_HOST_SUBSYS "iscsi_host"
#define ISCSI_TRANSPORT_SUBSYS "iscsi_transport"
+#define ISCSI_IFACE_SUBSYS "iscsi_iface"
#define SCSI_HOST_SUBSYS "scsi_host"
#define SCSI_SUBSYS "scsi"
@@ -423,9 +424,9 @@ uint32_t iscsi_sysfs_get_host_no_from_hwinfo(struct iface_rec *iface, int *rc)
* qla4xxx.
*/
static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no,
- char *session)
+ char *session, char *iface_kern_id)
{
- char id[NAME_SIZE];
+ char host_id[NAME_SIZE];
struct iscsi_transport *t;
int ret;
@@ -436,26 +437,31 @@ static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no,
else
strcpy(iface->transport_name, t->name);
- snprintf(id, sizeof(id), ISCSI_HOST_ID, host_no);
+ snprintf(host_id, sizeof(host_id), ISCSI_HOST_ID, host_no);
/*
* backward compat
* If we cannot get the address we assume we are doing the old
* style and use default.
*/
- ret = sysfs_get_str(id, ISCSI_HOST_SUBSYS, "hwaddress",
+ ret = sysfs_get_str(host_id, ISCSI_HOST_SUBSYS, "hwaddress",
iface->hwaddress, sizeof(iface->hwaddress));
if (ret)
log_debug(7, "could not read hwaddress for host%d\n", host_no);
- /* if not found just print out default */
- ret = sysfs_get_str(id, ISCSI_HOST_SUBSYS, "ipaddress",
- iface->ipaddress, sizeof(iface->ipaddress));
+ if (iface_kern_id)
+ ret = sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS,
+ "ipaddress",
+ iface->ipaddress, sizeof(iface->ipaddress));
+ else
+ /* if not found just print out default */
+ ret = sysfs_get_str(host_id, ISCSI_HOST_SUBSYS, "ipaddress",
+ iface->ipaddress, sizeof(iface->ipaddress));
if (ret)
log_debug(7, "could not read local address for host%d\n",
host_no);
/* if not found just print out default */
- ret = sysfs_get_str(id, ISCSI_HOST_SUBSYS, "netdev",
+ ret = sysfs_get_str(host_id, ISCSI_HOST_SUBSYS, "netdev",
iface->netdev, sizeof(iface->netdev));
if (ret)
log_debug(7, "could not read netdev for host%d\n", host_no);
@@ -487,7 +493,7 @@ static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no,
}
if (ret) {
- ret = sysfs_get_str(id, ISCSI_HOST_SUBSYS, "initiatorname",
+ ret = sysfs_get_str(host_id, ISCSI_HOST_SUBSYS, "initiatorname",
iface->iname, sizeof(iface->iname));
if (ret)
/*
@@ -531,6 +537,53 @@ static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no,
iface_str(iface));
}
}
+
+ if (!iface_kern_id)
+ goto done;
+
+ strlcpy(iface->name, iface_kern_id, sizeof(iface->name));
+
+ if (!strncmp(iface_kern_id, "ipv4", 4)) {
+ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS, "bootproto",
+ iface->bootproto, sizeof(iface->bootproto));
+
+ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS, "gateway",
+ iface->gateway, sizeof(iface->gateway));
+
+ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS, "subnet",
+ iface->subnet_mask, sizeof(iface->subnet_mask));
+ } else {
+ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS,
+ "ipaddr_autocfg",
+ iface->ipv6_autocfg, sizeof(iface->ipv6_autocfg));
+
+ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS,
+ "link_local_addr", iface->ipv6_linklocal,
+ sizeof(iface->ipv6_linklocal));
+
+ if (sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS,
+ "linklocal_autocfg",
+ iface->linklocal_autocfg,
+ sizeof(iface->linklocal_autocfg))) {
+ /* misspelled in some test kernels */
+ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS,
+ "link_local_autocfg",
+ iface->linklocal_autocfg,
+ sizeof(iface->linklocal_autocfg));
+ }
+
+ sysfs_get_str(iface_kern_id, ISCSI_IFACE_SUBSYS, "router_addr",
+ iface->ipv6_router,
+ sizeof(iface->ipv6_router));
+ }
+
+ sysfs_get_uint16(iface_kern_id, ISCSI_IFACE_SUBSYS, "mtu",
+ &iface->mtu);
+ sysfs_get_uint16(iface_kern_id, ISCSI_IFACE_SUBSYS, "vlan",
+ &iface->vlan_id);
+ sysfs_get_uint8(iface_kern_id, ISCSI_IFACE_SUBSYS, "vlan_priority",
+ &iface->vlan_priority);
+done:
if (ret)
return ISCSI_ERR_SYSFS_LOOKUP;
else
@@ -539,7 +592,8 @@ static int iscsi_sysfs_read_iface(struct iface_rec *iface, int host_no,
int iscsi_sysfs_get_hostinfo_by_host_no(struct host_info *hinfo)
{
- return iscsi_sysfs_read_iface(&hinfo->iface, hinfo->host_no, NULL);
+ return iscsi_sysfs_read_iface(&hinfo->iface, hinfo->host_no, NULL,
+ NULL);
}
int iscsi_sysfs_for_each_host(void *data, int *nr_found,
@@ -583,6 +637,50 @@ free_info:
return rc;
}
+int iscsi_sysfs_for_each_iface_on_host(void *data, uint32_t host_no,
+ int *nr_found,
+ iscsi_sysfs_iface_op_fn *fn)
+{
+ struct dirent **namelist;
+ int rc = 0, i, n;
+ struct iface_rec iface;
+ char devpath[PATH_SIZE];
+ char sysfs_path[PATH_SIZE];
+ char id[NAME_SIZE];
+
+ snprintf(id, sizeof(id), "host%u", host_no);
+ if (!sysfs_lookup_devpath_by_subsys_id(devpath, sizeof(devpath),
+ SCSI_SUBSYS, id)) {
+ log_error("Could not look up host's ifaces via scsi bus.");
+ return ISCSI_ERR_SYSFS_LOOKUP;
+ }
+
+ sprintf(sysfs_path, "/sys");
+ strlcat(sysfs_path, devpath, sizeof(sysfs_path));
+ strlcat(sysfs_path, "/iscsi_iface", sizeof(sysfs_path));
+
+ n = scandir(sysfs_path, &namelist, trans_filter, alphasort);
+ if (n <= 0)
+ /* older kernels or some drivers will not have ifaces */
+ return 0;
+
+ for (i = 0; i < n; i++) {
+ memset(&iface, 0, sizeof(iface));
+
+ iscsi_sysfs_read_iface(&iface, host_no, NULL,
+ namelist[i]->d_name);
+ rc = fn(data, &iface);
+ if (rc != 0)
+ break;
+ (*nr_found)++;
+ }
+
+ for (i = 0; i < n; i++)
+ free(namelist[i]);
+ free(namelist);
+ return rc;
+}
+
/**
* sysfs_session_has_leadconn - checks if session has lead conn in kernel
* @sid: session id
@@ -782,7 +880,7 @@ int iscsi_sysfs_get_sessioninfo_by_id(struct session_info *info, char *session)
return ret;
}
- iscsi_sysfs_read_iface(&info->iface, host_no, session);
+ iscsi_sysfs_read_iface(&info->iface, host_no, session, NULL);
log_debug(7, "found targetname %s address %s pers address %s port %d "
"pers port %d driver %s iface name %s ipaddress %s "
diff --git a/usr/iscsi_sysfs.h b/usr/iscsi_sysfs.h
index 3195c89..6b5bed1 100644
--- a/usr/iscsi_sysfs.h
+++ b/usr/iscsi_sysfs.h
@@ -43,7 +43,11 @@ extern int iscsi_sysfs_session_has_leadconn(uint32_t sid);
typedef int (iscsi_sysfs_session_op_fn)(void *, struct session_info *);
typedef int (iscsi_sysfs_host_op_fn)(void *, struct host_info *);
+typedef int (iscsi_sysfs_iface_op_fn)(void *, struct iface_rec *);
+extern int iscsi_sysfs_for_each_iface_on_host(void *data, uint32_t host_no,
+ int *nr_found,
+ iscsi_sysfs_iface_op_fn *fn);
extern int iscsi_sysfs_for_each_session(void *data, int *nr_found,
iscsi_sysfs_session_op_fn *fn);
extern int iscsi_sysfs_for_each_host(void *data, int *nr_found,
diff --git a/usr/sysfs.c b/usr/sysfs.c
index cb9cf08..7f31c1a 100644
--- a/usr/sysfs.c
+++ b/usr/sysfs.c
@@ -636,6 +636,34 @@ int sysfs_get_uint64(char *id, char *subsys, char *param, uint64_t *value)
return 0;
}
+int sysfs_get_uint8(char *id, char *subsys, char *param,
+ uint8_t *value)
+{
+ char *sysfs_value;
+
+ *value = -1;
+ sysfs_value = sysfs_get_value(id, subsys, param);
+ if (!sysfs_value)
+ return EIO;
+
+ *value = (uint8_t)atoi(sysfs_value);
+ return 0;
+}
+
+int sysfs_get_uint16(char *id, char *subsys, char *param,
+ uint16_t *value)
+{
+ char *sysfs_value;
+
+ *value = -1;
+ sysfs_value = sysfs_get_value(id, subsys, param);
+ if (!sysfs_value)
+ return EIO;
+
+ *value = (uint16_t)atoi(sysfs_value);
+ return 0;
+}
+
int sysfs_set_param(char *id, char *subsys, char *attr_name,
char *write_buf, ssize_t buf_size)
{
diff --git a/usr/sysfs.h b/usr/sysfs.h
index f5e13b3..304dbbf 100644
--- a/usr/sysfs.h
+++ b/usr/sysfs.h
@@ -59,6 +59,10 @@ extern int sysfs_get_str(char *id, char *subsys, char *param, char *value,
int value_size);
extern int sysfs_get_uint64(char *id, char *subsys, char *param,
uint64_t *value);
+extern int sysfs_get_uint8(char *id, char *subsys, char *param,
+ uint8_t *value);
+extern int sysfs_get_uint16(char *id, char *subsys, char *param,
+ uint16_t *value);
extern int sysfs_set_param(char *id, char *subsys, char *attr_name,
char *write_buf, ssize_t buf_size);