1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
11 /*******************************************************************************
14 * find_test_session - find or create a test DMAPI session.
17 * find_test_session() is used to find a test DMAPI session to
18 * use. There is only one test session per host; all test processes
19 * share the same session. If the session does not already exist,
20 * then the first process to call find_test_session() causes
21 * the session to be created.
23 * Note: It is possible for N different programs to call this routine
24 * at the same time. Each would find that a test session does not
25 * exist, and each one would then create a new test session. Since
26 * excess test sessions are not automatically released on death of
27 * process, we need to make sure that we don't leave such excess
28 * sessions around. So, after creating a session we go back and find
29 * the test session with the lowest session number. If it is ours,
30 * great; we are done. If not, then we must destroy our session
31 * and use the one with the lower session ID. There is still a risk
32 * here of creating a session and crashing before it can be removed
33 * again. To deal with this, the daemon will periodically remove all
34 * test sessions except for the one with the lowest ID value.
39 *******************************************************************************/
41 #define TEST_MSG "DMAPI test session"
48 return(*((dm_sessid_t *)a) - *((dm_sessid_t *)b));
55 char buffer[DM_SESSION_INFO_LEN];
56 dm_sessid_t *sidbuf = NULL;
57 dm_sessid_t new_session;
64 /* Retrieve the list of all active sessions on the host. */
66 nelem = 100; /* a reasonable first guess */
68 if (allocelem < nelem) {
70 sidbuf = realloc(sidbuf, nelem * sizeof(*sidbuf));
72 fprintf(stderr, "realloc of %lu bytes failed\n",
73 (unsigned long) nelem * sizeof(*sidbuf));
77 error = dm_getall_sessions(allocelem, sidbuf, &nelem);
78 } while (error < 0 && errno == E2BIG);
80 /* If an error occurred, translate it into something meaningful. */
83 fprintf(stderr, "unexpected dm_getall_sessions failure, %s\n",
89 /* We have the list of all active sessions. Scan the list looking
90 for an existing "test" session that we can use. The list must
91 first be sorted in case other processes happen to be creating test
92 sessions at the same time; we need to make sure that we pick the one
93 with the lowest session ID.
96 qsort(sidbuf, nelem, sizeof(sidbuf[0]), session_compare);
98 for (i = 0; i < nelem; i++) {
99 error = dm_query_session(sidbuf[i], sizeof(buffer),
102 fprintf(stderr, "unexpected dm_query_session "
103 "failure, %s\n", strerror(errno));
108 if (!strncmp(buffer, TEST_MSG, strlen(TEST_MSG)))
112 *session = (dm_sessid_t)sidbuf[i];
117 /* No test session exists, so we have to create one ourselves. */
119 if (dm_create_session(DM_NO_SESSION, TEST_MSG, &new_session) != 0) {
120 fprintf(stderr, "dm_create_session failed, %s\n",
126 /* Now re-retrieve the list of active sessions. */
129 if (allocelem < nelem) {
131 sidbuf = realloc(sidbuf, nelem * sizeof(*sidbuf));
132 if (sidbuf == NULL) {
133 fprintf(stderr, "realloc of %lu bytes failed\n",
134 (unsigned long) nelem * sizeof(*sidbuf));
138 error = dm_getall_sessions(allocelem, sidbuf, &nelem);
139 } while (error < 0 && errno == E2BIG);
142 fprintf(stderr, "dm_getall_sessions failed, %s\n",
148 /* Sort the session ID list into ascending ID order, then find the
149 test session with the lowest session ID. We better find at
150 least one since we created one!
153 qsort(sidbuf, nelem, sizeof(sidbuf[0]), session_compare);
155 for (i = 0; i < nelem; i++) {
156 error = dm_query_session(sidbuf[i], sizeof(buffer),
159 fprintf(stderr, "dm_query_session failed, %s\n",
164 if (!strncmp(buffer, TEST_MSG, strlen(TEST_MSG)))
168 fprintf(stderr, "can't find the session we created\n");
172 *session = (dm_sessid_t)sidbuf[i];
175 /* If the session we are going to use is not the one we created,
176 then we need to get rid of the created one.
179 if (*session != new_session) {
180 if ((new_session) != 0) {
181 fprintf(stderr, "dm_destroy_session failed, %s\n",