From a744d91046865416a50ea27f143ef0f02fcaf1c6 Mon Sep 17 00:00:00 2001 From: Chris Leech Date: Wed, 17 Feb 2021 12:22:17 -0800 Subject: [PATCH] libopeniscsiusr: skip over removed sessions When looping over all sessions with iscsi_sessions_get, it's possible to race against sessions being destroyed and have the sysfs attribute files be removed before they're read. Let's not treat this as an error, and simply drop the session that failed to read from the list. I think it makes sense to treat session that disapear while they're being read as if they were already gone when the sessions directory was first scanned. Apparently having iscsiadm exit with an error when trying to get a list of sessions is a problem for OpenStack deployments. Signed-off-by: Chris Leech --- libopeniscsiusr/session.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libopeniscsiusr/session.c b/libopeniscsiusr/session.c index f122fe3..4a724c8 100644 --- a/libopeniscsiusr/session.c +++ b/libopeniscsiusr/session.c @@ -246,6 +246,7 @@ int iscsi_sessions_get(struct iscsi_context *ctx, { int rc = LIBISCSI_OK; uint32_t i = 0; + uint32_t j = 0; uint32_t *sids = NULL; assert(ctx != NULL); @@ -264,9 +265,22 @@ int iscsi_sessions_get(struct iscsi_context *ctx, for (i = 0; i < *session_count; ++i) { _debug(ctx, "sid %" PRIu32, sids[i]); - _good(iscsi_session_get(ctx, sids[i], &((*sessions)[i])), - rc, out); + rc = iscsi_session_get(ctx, sids[i], &((*sessions)[j])); + if (rc == LIBISCSI_OK) { + /* if session info was successfully read from sysfs, advance the sessions pointer */ + j++; + } else { + /* if not, just ignore the issue and keep trying with the next session ID, + * there's always going to be an inherent race against session removal when collecting + * attribute data from sysfs + */ + _debug(ctx, "Problem reading session %" PRIu32 ", skipping.", sids[i]); + rc = LIBISCSI_OK; + } } + /* reset session count and sessions array length to what we were able to read from sysfs */ + *session_count = j; + *sessions = reallocarray(*sessions, *session_count, sizeof(struct iscsi_session *)); out: free(sids); -- 2.26.2