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