summaryrefslogtreecommitdiff
path: root/usr/host.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2009-04-19 15:06:55 -0400
committerMike Christie <michaelc@cs.wisc.edu>2009-05-10 21:52:04 -0500
commit986cce5291a402019b2e66cc172a1010ca2c3ee4 (patch)
treea904181cd6363810c829feffeb99c3bbb7efc2cd /usr/host.c
parent3c352a1ad2aeab88a84384989375f78e24b396fc (diff)
downloadopen-iscsi-986cce5291a402019b2e66cc172a1010ca2c3ee4.tar.gz
iscsiadm: add host mode
This prints out the info for iSCSI hosts in the system. EXAMPLE ------- iscsiadm -m host cxgb3i: [9] 10.10.15.50,[00:07:43:05:97:07],eth3 <empty> $TRANSPORT: [$HOST_NO] $HOST_IP,[$MAC},$NETDEV $INITIATORNAME EXAMPLE --------- iscsiadm -m host -P 2 Host Number: 9 State: running Transport: cxgb3i Initiatorname: <empty> IPaddress: 10.10.15.50 HWaddress: 00:07:43:05:97:07 Netdev: eth3 ********* Sessions: ********* Target: iqn.2001-04.com.home:meanminna Current Portal: 10.10.15.10:3260,1 Persistent Portal: 10.10.15.10:3260,1 ********** Interface: ********** Iface Name: cxgb3i Iface Transport: cxgb3i Iface Initiatorname: iqn.2005-06.com.redhat:noisymax Iface IPaddress: 10.10.15.50 Iface HWaddress: 00:07:43:05:97:07 Iface Netdev: eth3 SID: 8 iSCSI Connection State: LOGGED IN iSCSI Session State: LOGGED_IN Internal iscsid Session State: NO CHANGE ********** Interface: ********** Iface Name: cxgb3i.def Iface Transport: cxgb3i Iface Initiatorname: iqn.2005-06.com.redhat:madmax Iface IPaddress: 10.10.15.50 Iface HWaddress: 00:07:43:05:97:07 Iface Netdev: eth3 SID: 9 iSCSI Connection State: LOGGED IN iSCSI Session State: LOGGED_IN Internal iscsid Session State: NO CHANGE
Diffstat (limited to 'usr/host.c')
-rw-r--r--usr/host.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/usr/host.c b/usr/host.c
new file mode 100644
index 0000000..1f6ffb2
--- /dev/null
+++ b/usr/host.c
@@ -0,0 +1,212 @@
+/*
+ * iSCSI host helpers
+ *
+ * Copyright (C) 2008 Mike Christie
+ * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
+ * maintained by open-iscsi@@googlegroups.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * See the file COPYING included with this distribution for more details.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "list.h"
+#include "util.h"
+#include "log.h"
+#include "iscsi_sysfs.h"
+#include "version.h"
+#include "iscsi_settings.h"
+#include "mgmt_ipc.h"
+#include "host.h"
+#include "session_info.h"
+#include "transport.h"
+#include "initiator.h"
+#include "iface.h"
+
+static int match_host_to_session(void *data, struct session_info *info)
+{
+ uint32_t host_no = *(uint32_t *) data;
+ uint32_t info_host_no;
+ int rc;
+
+ info_host_no = iscsi_sysfs_get_host_no_from_sid(info->sid, &rc);
+ if (rc) {
+ log_error("could not get host_no for session%d err %d.",
+ info->sid, rc);
+ return 0;
+ }
+
+ return host_no == info_host_no;
+}
+
+static void print_host_info(struct iface_rec *iface, char *prefix)
+{
+ if (strlen(iface->transport_name))
+ printf("%sTransport: %s\n", prefix,
+ iface->transport_name);
+ else
+ printf("%sTransport: %s\n", prefix, UNKNOWN_VALUE);
+
+ if (strlen(iface->iname))
+ printf("%sInitiatorname: %s\n", prefix,
+ iface->iname);
+ else
+ printf("%sInitiatorname: %s\n", prefix, UNKNOWN_VALUE);
+
+ if (!strlen(iface->ipaddress))
+ printf("%sIPaddress: %s\n", prefix, UNKNOWN_VALUE);
+ else if (strchr(iface->ipaddress, '.'))
+ printf("%sIPaddress: %s\n", prefix, iface->ipaddress);
+ else
+ printf("%sIPaddress: [%s]\n", prefix, iface->ipaddress);
+
+ if (strlen(iface->hwaddress))
+ printf("%sHWaddress: %s\n", prefix, iface->hwaddress);
+ else
+ printf("%sHWaddress: %s\n", prefix, UNKNOWN_VALUE);
+
+ if (strlen(iface->netdev))
+ printf("%sNetdev: %s\n", prefix, iface->netdev);
+ else
+ printf("%sNetdev: %s\n", prefix, UNKNOWN_VALUE);
+}
+
+static int host_info_print_flat(void *data, struct host_info *hinfo)
+{
+ struct iface_rec *iface = &hinfo->iface;
+
+ if (strlen(iface->transport_name))
+ printf("%s: ", iface->transport_name);
+ else
+ printf("%s: ", UNKNOWN_VALUE);
+
+ printf("[%u] ", hinfo->host_no);
+
+ if (!strlen(iface->ipaddress))
+ printf("%s,", UNKNOWN_VALUE);
+ else if (strchr(iface->ipaddress, '.'))
+ printf("%s,", iface->ipaddress);
+ else
+ printf("[%s],", iface->ipaddress);
+
+ if (strlen(iface->hwaddress))
+ printf("[%s],", iface->hwaddress);
+ else
+ printf("[%s],", UNKNOWN_VALUE);
+
+ if (strlen(iface->netdev))
+ printf("%s ", iface->netdev);
+ else
+ printf("%s ", UNKNOWN_VALUE);
+
+ if (strlen(iface->iname))
+ printf("%s\n", iface->iname);
+ else
+ printf("%s\n", UNKNOWN_VALUE);
+ return 0;
+}
+
+static int host_info_print_tree(void *data, struct host_info *hinfo)
+{
+ struct list_head sessions;
+ struct session_link_info link_info;
+ int err, num_found = 0;
+ unsigned int session_info_flags = *(unsigned int *)data;
+ char state[SCSI_MAX_STATE_VALUE];
+
+ 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);
+ else
+ printf("\tState: Unknown\n");
+ print_host_info(&hinfo->iface, "\t");
+
+ if (!session_info_flags)
+ return 0;
+
+ link_info.list = &sessions;
+ link_info.match_fn = match_host_to_session;
+ link_info.data = &hinfo->host_no;
+
+ err = iscsi_sysfs_for_each_session(&link_info, &num_found,
+ session_info_create_list);
+ if (err || !num_found)
+ return 0;
+
+ printf("\t*********\n");
+ printf("\tSessions:\n");
+ printf("\t*********\n");
+
+ session_info_print_tree(&sessions, "\t", session_info_flags);
+ session_info_free_list(&sessions);
+ return 0;
+}
+
+int host_info_print(int info_level, uint32_t host_no)
+{
+ int num_found = 0, err = 0;
+ char *version;
+ unsigned int flags = 0;
+
+ switch (info_level) {
+ case 0:
+ case -1:
+ err = iscsi_sysfs_for_each_host(NULL, &num_found,
+ host_info_print_flat);
+ break;
+ case 4:
+ version = iscsi_sysfs_get_iscsi_kernel_version();
+ if (version) {
+ printf("iSCSI Transport Class version %s\n",
+ version);
+ printf("version %s\n", ISCSI_VERSION_STR);
+ }
+
+ flags |= SESSION_INFO_SCSI_DEVS;
+ /* fall through */
+ case 3:
+ flags |= SESSION_INFO_ISCSI_PARAMS;
+ /* fall through */
+ case 2:
+ flags |= SESSION_INFO_ISCSI_STATE | SESSION_INFO_IFACE;
+ /* fall through */
+ case 1:
+ if (host_no != -1) {
+ struct host_info hinfo;
+
+ memset(&hinfo, 0, sizeof(struct host_info));
+ hinfo.host_no = host_no;
+ iscsi_sysfs_get_hostinfo_by_host_no(&hinfo);
+ host_info_print_tree(&flags, &hinfo);
+ num_found = 1;
+ break;
+ }
+
+ err = iscsi_sysfs_for_each_host(&flags, &num_found,
+ host_info_print_tree);
+ break;
+ default:
+ log_error("Invalid info level %d. Try 0 - 4.", info_level);
+ return EINVAL;
+ }
+
+ if (err) {
+ log_error("Can not get list of iSCSI hosts (%d)", err);
+ return err;
+ } else if (!num_found)
+ log_error("No iSCSI hosts.");
+ return 0;
+}