From 7671cd56d36a76e954318cbdce3f08fc40aa3fe4 Mon Sep 17 00:00:00 2001 From: Peter Hatina Date: Mon, 5 Oct 2015 16:50:36 -0700 Subject: [PATCH 19/32] 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 064e4b570d0b..755c18ca8e3b 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 + * Copyright (C) 2015 Peter Hatina * 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 756590e14d8b..a9891f48b7d6 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 + * Copyright (C) 2015 Peter Hatina * 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 fdc26c7bd9ba..80b7b0210fd1 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 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published @@ -1146,6 +1147,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 cdcefa65f683..12ad87f96c8c 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 * * 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.14.4