2 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 /*******************************************************************************
26 * find_test_session - find or create a test DMAPI session.
29 * find_test_session() is used to find a test DMAPI session to
30 * use. There is only one test session per host; all test processes
31 * share the same session. If the session does not already exist,
32 * then the first process to call find_test_session() causes
33 * the session to be created.
35 * Note: It is possible for N different programs to call this routine
36 * at the same time. Each would find that a test session does not
37 * exist, and each one would then create a new test session. Since
38 * excess test sessions are not automatically released on death of
39 * process, we need to make sure that we don't leave such excess
40 * sessions around. So, after creating a session we go back and find
41 * the test session with the lowest session number. If it is ours,
42 * great; we are done. If not, then we must destroy our session
43 * and use the one with the lower session ID. There is still a risk
44 * here of creating a session and crashing before it can be removed
45 * again. To deal with this, the daemon will periodically remove all
46 * test sessions except for the one with the lowest ID value.
51 *******************************************************************************/
53 #define TEST_MSG "DMAPI test session"
60 return(*((dm_sessid_t *)a) - *((dm_sessid_t *)b));
67 char buffer[DM_SESSION_INFO_LEN];
68 dm_sessid_t *sidbuf = NULL;
69 dm_sessid_t new_session;
76 /* Retrieve the list of all active sessions on the host. */
78 nelem = 100; /* a reasonable first guess */
80 if (allocelem < nelem) {
82 sidbuf = realloc(sidbuf, nelem * sizeof(*sidbuf));
84 fprintf(stderr, "realloc of %lu bytes failed\n",
85 (unsigned long) nelem * sizeof(*sidbuf));
89 error = dm_getall_sessions(allocelem, sidbuf, &nelem);
90 } while (error < 0 && errno == E2BIG);
92 /* If an error occurred, translate it into something meaningful. */
95 fprintf(stderr, "unexpected dm_getall_sessions failure, %s\n",
101 /* We have the list of all active sessions. Scan the list looking
102 for an existing "test" session that we can use. The list must
103 first be sorted in case other processes happen to be creating test
104 sessions at the same time; we need to make sure that we pick the one
105 with the lowest session ID.
108 qsort(sidbuf, nelem, sizeof(sidbuf[0]), session_compare);
110 for (i = 0; i < nelem; i++) {
111 error = dm_query_session(sidbuf[i], sizeof(buffer),
114 fprintf(stderr, "unexpected dm_query_session "
115 "failure, %s\n", strerror(errno));
120 if (!strncmp(buffer, TEST_MSG, strlen(TEST_MSG)))
124 *session = (dm_sessid_t)sidbuf[i];
129 /* No test session exists, so we have to create one ourselves. */
131 if (dm_create_session(DM_NO_SESSION, TEST_MSG, &new_session) != 0) {
132 fprintf(stderr, "dm_create_session failed, %s\n",
138 /* Now re-retrieve the list of active sessions. */
141 if (allocelem < nelem) {
143 sidbuf = realloc(sidbuf, nelem * sizeof(*sidbuf));
144 if (sidbuf == NULL) {
145 fprintf(stderr, "realloc of %lu bytes failed\n",
146 (unsigned long) nelem * sizeof(*sidbuf));
150 error = dm_getall_sessions(allocelem, sidbuf, &nelem);
151 } while (error < 0 && errno == E2BIG);
154 fprintf(stderr, "dm_getall_sessions failed, %s\n",
160 /* Sort the session ID list into ascending ID order, then find the
161 test session with the lowest session ID. We better find at
162 least one since we created one!
165 qsort(sidbuf, nelem, sizeof(sidbuf[0]), session_compare);
167 for (i = 0; i < nelem; i++) {
168 error = dm_query_session(sidbuf[i], sizeof(buffer),
171 fprintf(stderr, "dm_query_session failed, %s\n",
176 if (!strncmp(buffer, TEST_MSG, strlen(TEST_MSG)))
180 fprintf(stderr, "can't find the session we created\n");
184 *session = (dm_sessid_t)sidbuf[i];
187 /* If the session we are going to use is not the one we created,
188 then we need to get rid of the created one.
191 if (*session != new_session) {
192 if ((new_session) != 0) {
193 fprintf(stderr, "dm_destroy_session failed, %s\n",