diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2011-08-14 14:32:08 -0500 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2011-08-14 22:12:57 -0500 |
commit | 2029bf16ca3e3378d9f0f7c747d95f2f3489327e (patch) | |
tree | 49092ffcf559c5bdc172749c569b374540d96327 /usr | |
parent | deef9e20c2f1b107760b5b4c29289de77fcdc39f (diff) | |
download | open-iscsi-2029bf16ca3e3378d9f0f7c747d95f2f3489327e.tar.gz |
iscsiadm: print kernel iface info
This patch prints the kernel's iface info.
iscsiadm -m host -P 2
iscsiadm -m host -H $N -P 2
will print out the kernel's iface info for the ifaces under all
hosts or for specific hosts.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Diffstat (limited to 'usr')
-rw-r--r-- | usr/host.c | 44 | ||||
-rw-r--r-- | usr/iscsi_sysfs.c | 120 | ||||
-rw-r--r-- | usr/iscsi_sysfs.h | 4 | ||||
-rw-r--r-- | usr/sysfs.c | 28 | ||||
-rw-r--r-- | usr/sysfs.h | 4 |
5 files changed, 189 insertions, 11 deletions
@@ -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); |