2abe1f9
From 3029917e4ed624245cb6d3ab6fd6a4058530f988 Mon Sep 17 00:00:00 2001
2abe1f9
From: Peter Hatina <phatina@redhat.com>
2abe1f9
Date: Mon, 5 Oct 2015 16:50:36 -0700
2abe1f9
Subject: [PATCH] libiscsi introduce sessions API
2abe1f9
2abe1f9
---
2abe1f9
 libiscsi/libiscsi.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2abe1f9
 libiscsi/libiscsi.h |  56 +++++++++++++++++++++++
2abe1f9
 usr/iscsi_sysfs.c   |   6 +++
2abe1f9
 usr/iscsi_sysfs.h   |   2 +
2abe1f9
 4 files changed, 189 insertions(+)
2abe1f9
ff3d34e
diff --git a/libiscsi/libiscsi.c b/libiscsi/libiscsi.c
ff3d34e
index 064e4b5..755c18c 100644
ff3d34e
--- a/libiscsi/libiscsi.c
ff3d34e
+++ b/libiscsi/libiscsi.c
ff3d34e
@@ -3,6 +3,7 @@
ff3d34e
  *
ff3d34e
  * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
ff3d34e
  * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
ff3d34e
+ * Copyright (C) 2015      Peter Hatina <phatina@redhat.com>
ff3d34e
  * maintained by open-iscsi@googlegroups.com
ff3d34e
  *
ff3d34e
  * This program is free software; you can redistribute it and/or modify
ff3d34e
@@ -469,6 +470,130 @@ leave:
ff3d34e
 	return rc;
ff3d34e
 }
ff3d34e
 
ff3d34e
+struct libiscsi_session_array {
ff3d34e
+	int cnt;
ff3d34e
+	int size;
ff3d34e
+	struct libiscsi_session_info *data;
ff3d34e
+};
ff3d34e
+
ff3d34e
+static void libiscsi_session_array_init(struct libiscsi_session_array *arr)
ff3d34e
+{
ff3d34e
+	arr->cnt = 0;
ff3d34e
+	arr->size = 0;
ff3d34e
+	arr->data = NULL;
ff3d34e
+}
ff3d34e
+
ff3d34e
+static int libiscsi_session_array_grow(struct libiscsi_session_array *arr)
ff3d34e
+{
ff3d34e
+	if (arr->size == 0)
ff3d34e
+		arr->size = 4;
ff3d34e
+	else
ff3d34e
+		arr->size *= 2;
ff3d34e
+
ff3d34e
+	arr->data = (struct libiscsi_session_info *) realloc(
ff3d34e
+		arr->data,
ff3d34e
+		arr->size * sizeof(struct libiscsi_session_info));
ff3d34e
+
ff3d34e
+	return arr->data ? 0 : 1;
ff3d34e
+}
ff3d34e
+
ff3d34e
+static int libiscsi_session_array_grow_ondemand(struct libiscsi_session_array *arr)
ff3d34e
+{
ff3d34e
+	if (arr->size == arr->cnt)
ff3d34e
+		return libiscsi_session_array_grow(arr);
ff3d34e
+	return 0;
ff3d34e
+}
ff3d34e
+
ff3d34e
+static int libiscsi_session_array_resize_precize(struct libiscsi_session_array *arr)
ff3d34e
+{
ff3d34e
+	arr->data = (struct libiscsi_session_info *) realloc(
ff3d34e
+		arr->data,
ff3d34e
+		arr->cnt * sizeof(struct libiscsi_session_info));
ff3d34e
+	arr->size = arr->cnt;
ff3d34e
+
ff3d34e
+	return arr->data ? 0 : 1;
ff3d34e
+}
ff3d34e
+
ff3d34e
+static void copy_session_info_to_libiscsi_session_info(
ff3d34e
+	struct libiscsi_session_info *info,
ff3d34e
+	struct session_info *s_info)
ff3d34e
+{
ff3d34e
+	/* Copy session info to public struct. */
ff3d34e
+	info->sid = s_info->sid;
ff3d34e
+	/* Timeouts */
ff3d34e
+	memcpy(&info->tmo, &s_info->tmo, sizeof(struct libiscsi_session_timeout));
ff3d34e
+	/* CHAP authentication information */
ff3d34e
+	memcpy(&info->chap, &s_info->chap, sizeof(struct libiscsi_chap_auth_info));
ff3d34e
+	/* Target information */
ff3d34e
+	strncpy(info->targetname, s_info->targetname, LIBISCSI_VALUE_MAXLEN);
ff3d34e
+	strncpy(info->address, s_info->address, NI_MAXHOST);
ff3d34e
+	strncpy(info->persistent_address, s_info->persistent_address, NI_MAXHOST);
ff3d34e
+	info->tpgt = s_info->tpgt;
ff3d34e
+	info->persistent_port = s_info->persistent_port;
ff3d34e
+}
ff3d34e
+
ff3d34e
+static int get_sessions_helper(void *data, struct session_info *s_info)
ff3d34e
+{
ff3d34e
+	struct libiscsi_session_array *arr = (struct libiscsi_session_array *) data;
ff3d34e
+
ff3d34e
+	if (libiscsi_session_array_grow_ondemand(arr) != 0)
ff3d34e
+		return 1;
ff3d34e
+
ff3d34e
+	copy_session_info_to_libiscsi_session_info(&arr->data[arr->cnt++], s_info);
ff3d34e
+
ff3d34e
+	return 0;
ff3d34e
+}
ff3d34e
+
ff3d34e
+int libiscsi_get_session_infos(struct libiscsi_context *context,
ff3d34e
+	struct libiscsi_session_info **infos,
ff3d34e
+	int *nr_sessions)
ff3d34e
+{
ff3d34e
+	int rc = 0;
ff3d34e
+	int nr_found = 0;
ff3d34e
+	struct libiscsi_session_array arr;
ff3d34e
+
ff3d34e
+	if (!context || !infos || !nr_sessions)
ff3d34e
+		return 1;
ff3d34e
+
ff3d34e
+	libiscsi_session_array_init(&arr;;
ff3d34e
+
ff3d34e
+	rc = iscsi_sysfs_for_each_session((void *) &arr, &nr_found,
ff3d34e
+		get_sessions_helper, 0);
ff3d34e
+	if (rc != 0 || nr_found == 0) {
ff3d34e
+		strcpy(context->error_str, "No matching session");
ff3d34e
+		return ENODEV;
ff3d34e
+	}
ff3d34e
+
ff3d34e
+	if (libiscsi_session_array_resize_precize(&arr) != 0) {
ff3d34e
+		strcpy(context->error_str, "Can't allocate memory for session infos");
ff3d34e
+		return ENOMEM;
ff3d34e
+	}
ff3d34e
+
ff3d34e
+	*infos = arr.data;
ff3d34e
+	*nr_sessions = nr_found;
ff3d34e
+
ff3d34e
+	return 0;
ff3d34e
+}
ff3d34e
+
ff3d34e
+int libiscsi_get_session_info_by_id(struct libiscsi_context *context,
ff3d34e
+	struct libiscsi_session_info *info,
ff3d34e
+	const char *session)
ff3d34e
+{
ff3d34e
+	struct session_info s_info;
ff3d34e
+
ff3d34e
+	if (!context || !info || !session)
ff3d34e
+		return 1;
ff3d34e
+
ff3d34e
+	if (iscsi_sysfs_get_sessioninfo_by_id(&s_info, (char*) session) != 0) {
ff3d34e
+		strcpy(context->error_str, "No matching session");
ff3d34e
+		return ENODEV;
ff3d34e
+	}
ff3d34e
+
ff3d34e
+	copy_session_info_to_libiscsi_session_info(info, &s_info);
ff3d34e
+
ff3d34e
+	return 0;
ff3d34e
+}
ff3d34e
+
ff3d34e
 int libiscsi_node_set_parameter(struct libiscsi_context *context,
ff3d34e
 	const struct libiscsi_node *node,
ff3d34e
 	const char *parameter, const char *value)
ff3d34e
diff --git a/libiscsi/libiscsi.h b/libiscsi/libiscsi.h
ff3d34e
index 756590e..a9891f4 100644
ff3d34e
--- a/libiscsi/libiscsi.h
ff3d34e
+++ b/libiscsi/libiscsi.h
ff3d34e
@@ -3,6 +3,7 @@
ff3d34e
  *
ff3d34e
  * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
ff3d34e
  * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
ff3d34e
+ * Copyright (C) 2015      Peter Hatina <phatina@redhat.com>
ff3d34e
  * maintained by open-iscsi@googlegroups.com
ff3d34e
  *
ff3d34e
  * This program is free software; you can redistribute it and/or modify
ff3d34e
@@ -56,6 +57,17 @@ enum libiscsi_auth_t {
ff3d34e
  */
ff3d34e
 struct libiscsi_context;
ff3d34e
 
ff3d34e
+/** \brief iSCSI session timeouts
ff3d34e
+ *
ff3d34e
+ * Struct holding session timeouts.
ff3d34e
+ */
ff3d34e
+struct libiscsi_session_timeout {
ff3d34e
+    int abort_tmo;
ff3d34e
+    int lu_reset_tmo;
ff3d34e
+    int recovery_tmo;
ff3d34e
+    int tgt_reset_tmo;
ff3d34e
+};
ff3d34e
+
ff3d34e
 /** \brief iSCSI node record
ff3d34e
  *
ff3d34e
  * Struct holding data uniquely identifying an iSCSI node.
ff3d34e
@@ -84,6 +96,24 @@ struct libiscsi_chap_auth_info {
ff3d34e
     char reverse_password[LIBISCSI_VALUE_MAXLEN] /** Reverse Password */;
ff3d34e
 };
ff3d34e
 
ff3d34e
+/** \brief iSCSI session
ff3d34e
+ *
ff3d34e
+ * Struct hoding iSCSI session information.
ff3d34e
+ */
ff3d34e
+struct libiscsi_session_info {
ff3d34e
+    int sid;
ff3d34e
+
ff3d34e
+    struct libiscsi_session_timeout tmo;
ff3d34e
+    struct libiscsi_chap_auth_info chap;
ff3d34e
+
ff3d34e
+    char targetname[LIBISCSI_VALUE_MAXLEN];
ff3d34e
+    int tpgt;
ff3d34e
+    char address[NI_MAXHOST];
ff3d34e
+    int port;
ff3d34e
+    char persistent_address[NI_MAXHOST];
ff3d34e
+    int persistent_port;
ff3d34e
+};
ff3d34e
+
ff3d34e
 /** \brief generic libiscsi authentication information struct
ff3d34e
  *
ff3d34e
  * Struct holding authentication information for discovery and login.
ff3d34e
@@ -248,6 +278,32 @@ PUBLIC int libiscsi_node_login(struct libiscsi_context *context,
ff3d34e
 PUBLIC int libiscsi_node_logout(struct libiscsi_context *context,
ff3d34e
     const struct libiscsi_node *node);
ff3d34e
 
ff3d34e
+/** \brief Get an array of iSCSI sessions.
ff3d34e
+ *
ff3d34e
+ * Get the array containing iSCSI sessions' information.
ff3d34e
+ *
ff3d34e
+ * \param context       libiscsi context to operate on.
ff3d34e
+ * \param infos         Array of iSCSI sessions' information.
ff3d34e
+ *                      Release with free().
ff3d34e
+ * \param nr_sessions   The number of elements in \e infos.
ff3d34e
+ * \return              0 on success, otherwise a standard error code
ff3d34e
+ *                      (from errno.h).
ff3d34e
+ */
ff3d34e
+PUBLIC int libiscsi_get_session_infos(struct libiscsi_context *context,
ff3d34e
+    struct libiscsi_session_info **infos, int *nr_sessions);
ff3d34e
+
ff3d34e
+/** \brief Get session information by session ID.
ff3d34e
+ *
ff3d34e
+ * \param context       libiscsi context to operate on.
ff3d34e
+ * \param info          iSCSI session information.
ff3d34e
+ * \param session       Session name.
ff3d34e
+ * \return              0 on success, otherwise a standard error code
ff3d34e
+ *                      (from errno.h)
ff3d34e
+ */
ff3d34e
+PUBLIC int libiscsi_get_session_info_by_id(struct libiscsi_context *context,
ff3d34e
+    struct libiscsi_session_info *info,
ff3d34e
+    const char *session);
ff3d34e
+
ff3d34e
 /** \brief Set an iSCSI parameter for the given node
ff3d34e
  *
ff3d34e
  * Set the given nodes iSCSI parameter named by \e parameter to value \e value.
ff3d34e
diff --git a/usr/iscsi_sysfs.c b/usr/iscsi_sysfs.c
2abe1f9
index 3a37a48..1420421 100644
ff3d34e
--- a/usr/iscsi_sysfs.c
ff3d34e
+++ b/usr/iscsi_sysfs.c
ff3d34e
@@ -3,6 +3,7 @@
ff3d34e
  *
ff3d34e
  * Copyright (C) 2006 Mike Christie
ff3d34e
  * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
ff3d34e
+ * Copyright (C) 2015      Peter Hatina <phatina@redhat.com>
ff3d34e
  *
ff3d34e
  * This program is free software; you can redistribute it and/or modify
ff3d34e
  * it under the terms of the GNU General Public License as published
ff3d34e
@@ -1145,6 +1146,11 @@ free_info:
ff3d34e
 	return rc;
ff3d34e
 }
ff3d34e
 
ff3d34e
+const char *iscsi_sysfs_get_session_path(void)
ff3d34e
+{
ff3d34e
+	return ISCSI_SESSION_DIR;
ff3d34e
+}
ff3d34e
+
ff3d34e
 int iscsi_sysfs_for_each_iface_on_host(void *data, uint32_t host_no,
ff3d34e
 				       int *nr_found,
ff3d34e
 				       iscsi_sysfs_iface_op_fn *fn)
ff3d34e
diff --git a/usr/iscsi_sysfs.h b/usr/iscsi_sysfs.h
ff3d34e
index 9a56105..e4eaf20 100644
ff3d34e
--- a/usr/iscsi_sysfs.h
ff3d34e
+++ b/usr/iscsi_sysfs.h
ff3d34e
@@ -3,6 +3,7 @@
ff3d34e
  *
ff3d34e
  * Copyright (C) 2006 Mike Christie
ff3d34e
  * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
ff3d34e
+ * Copyright (C) 2015      Peter Hatina <phatina@redhat.com>
ff3d34e
  *
ff3d34e
  * This program is free software; you can redistribute it and/or modify
ff3d34e
  * it under the terms of the GNU General Public License as published
ff3d34e
@@ -47,6 +48,7 @@ typedef int (iscsi_sysfs_flashnode_op_fn)(void *, struct flashnode_rec *,
ff3d34e
 					  uint32_t, uint32_t);
ff3d34e
 typedef int (iscsi_sysfs_iface_op_fn)(void *, struct iface_rec *);
ff3d34e
 
ff3d34e
+extern const char *iscsi_sysfs_get_session_path(void);
ff3d34e
 extern int iscsi_sysfs_for_each_iface_on_host(void *data, uint32_t host_no,
ff3d34e
 					      int *nr_found,
ff3d34e
 					      iscsi_sysfs_iface_op_fn *fn);
2abe1f9
-- 
2abe1f9
2.1.0
2abe1f9