2 * Copyright (c) 1998,1999,2000
3 * Traakan, Inc., Los Altos, CA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #include "ndmagents.h"
43 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
46 ndma_client_session (struct ndm_session *sess)
48 struct ndm_job_param * job = &sess->control_acb.job;
51 rc = ndma_job_audit (job, 0, 0);
55 rc = ndma_session_initialize (sess);
58 rc = ndma_session_commission (sess);
61 rc = ndmca_connect_control_agent (sess);
62 if (rc) return rc; /* already tattled */
65 sess->conn_authorized = 1;
67 rc = ndmca_control_agent (sess);
69 ndma_session_decommission (sess);
74 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
77 #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS
80 ndma_server_session (struct ndm_session *sess, int control_sock)
82 struct ndmconn * conn;
87 rc = ndma_session_initialize (sess);
90 rc = ndma_session_commission (sess);
94 rc = getpeername (control_sock, &sa, &len);
96 perror ("getpeername");
98 ndmalogf (sess, 0, 2, "Connection accepted from %s",
99 inet_ntoa ( ((struct sockaddr_in *)&sa)->sin_addr));
103 rc = getsockname (control_sock, &sa, &len);
105 perror ("getsockname");
107 ndmalogf (sess, 0, 2, "Connection accepted to %s",
108 inet_ntoa ( ((struct sockaddr_in *)&sa)->sin_addr));
111 conn = ndmconn_initialize (0, "#C");
113 ndmalogf (sess, 0, 0, "can't init connection");
114 close (control_sock);
118 ndmos_condition_control_socket (sess, control_sock);
120 ndmconn_set_snoop (conn, &sess->param.log, sess->param.log_level);
121 ndmconn_accept (conn, control_sock);
123 conn->call = ndma_call;
124 conn->context = sess;
126 sess->plumb.control = conn;
128 while (!conn->chan.eof) {
129 ndma_session_quantum (sess, 1000);
133 ndmalogf (sess, 0, 2, "Connection close %s",
134 inet_ntoa ( ((struct sockaddr_in *)sa)->sin_addr));
137 ndmconn_destruct (conn);
139 ndma_session_decommission (sess);
145 exit_on_stdin_eof_thread(gpointer data G_GNUC_UNUSED)
150 if (read(0, buf, sizeof(buf)) <= 0) {
159 ndma_daemon_session (struct ndm_session *sess, int port, int is_test_daemon)
166 listen_sock = socket (AF_INET, SOCK_STREAM, 0);
167 if (listen_sock < 0) {
172 ndmos_condition_listen_socket (sess, listen_sock);
174 NDMOS_MACRO_SET_SOCKADDR(&sa, 0, port);
176 if (bind (listen_sock, &sa, sizeof sa) < 0) {
181 if (listen (listen_sock, 1) < 0) {
186 if (is_test_daemon) {
187 /* the listen socket is running, so tell our invoker */
191 /* and exit when our stdin goes away */
193 g_thread_create(exit_on_stdin_eof_thread, NULL, FALSE, NULL);
198 conn_sock = accept (listen_sock, &sa, &len);
212 ndma_server_session (sess, conn_sock);
221 #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */
225 ndma_session_distribute_quantum (struct ndm_session *sess)
227 int total_did_something = 0;
233 did_something |= ndmis_quantum (sess);
235 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
236 if (sess->tape_acb.mover_state.state != NDMP9_MOVER_STATE_IDLE)
237 did_something |= ndmta_quantum (sess);
238 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
240 #ifndef NDMOS_OPTION_NO_DATA_AGENT
241 if (sess->data_acb.data_state.state != NDMP9_DATA_STATE_IDLE)
242 did_something |= ndmda_quantum (sess);
243 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
245 total_did_something |= did_something;
247 } while (did_something);
249 return total_did_something;
254 ndma_session_quantum (struct ndm_session *sess, int max_delay_secs)
256 struct ndm_image_stream *is = &sess->plumb.image_stream;
257 struct ndmconn * conn;
258 struct ndmconn * conntab[5];
260 struct ndmchan * chtab[16];
263 int max_delay_usec = max_delay_secs * 1000;
266 * Gather distinct connections
269 if ((conn = sess->plumb.control))
270 conntab[n_conntab++] = conn;
271 if ( (conn = sess->plumb.data)
272 && conn != sess->plumb.control)
273 conntab[n_conntab++] = conn;
274 if ( (conn = sess->plumb.tape)
275 && conn != sess->plumb.data
276 && conn != sess->plumb.control)
277 conntab[n_conntab++] = conn;
278 if ( (conn = sess->plumb.robot)
279 && conn != sess->plumb.tape
280 && conn != sess->plumb.data
281 && conn != sess->plumb.control)
282 conntab[n_conntab++] = conn;
285 * Add connections to channel table
288 for (i = 0; i < n_conntab; i++) {
290 chtab[n_chtab++] = &conn->chan;
293 #ifndef NDMOS_OPTION_NO_DATA_AGENT
295 * Add DATA AGENT channels to table if active (!IDLE)
297 if (sess->data_acb.data_state.state != NDMP9_DATA_STATE_IDLE) {
298 chtab[n_chtab++] = &sess->data_acb.formatter_image;
299 chtab[n_chtab++] = &sess->data_acb.formatter_error;
300 chtab[n_chtab++] = &sess->data_acb.formatter_wrap;
302 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
305 * Add image stream to channel table
307 if (is->remote.connect_status == NDMIS_CONN_LISTEN)
308 chtab[n_chtab++] = &is->remote.listen_chan;
310 chtab[n_chtab++] = &is->chan;
313 * Let TAPE and DATA AGENTS get a bit of work done.
314 * This fills channel buffers as much as possible prior to blocking.
316 if (ndma_session_distribute_quantum (sess))
320 #ifndef NDMOS_OPTION_NO_DATA_AGENT
322 if (sess->data_acb.data_state.state == NDMP9_DATA_STATE_ACTIVE
323 && sess->data_acb.data_state.data_connection_addr.addr_type
324 == NDMP9_ADDR_LOCAL) {
326 * There is no remote connection to cue forward
327 * progress between local DATA/MOVER.
328 * So, sniff all the connections, and immediately
329 * attempt the next tape record.
333 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
337 * Block awaiting ready I/O. Many channel buffers
338 * will have actual I/O (read/write) performed.
340 ndmchan_quantum (chtab, n_chtab, max_delay_usec);
345 if (sess->param.log_level > 7) {
346 for (i = 0; i < n_chtab; i++) {
347 struct ndmchan * ch = chtab[i];
350 ndmchan_pp (ch, buf);
351 ndmalogf (sess, 0, 7, "ch %s", buf);
356 * Let TAPE and DATA AGENTS get a bit more work done.
357 * This will mostly digest whatever data just arrived.
359 ndma_session_distribute_quantum (sess);
362 * Dispatch any pending activity on the control connections
364 for (i = 0; i < n_conntab; i++) {
366 if (conn->chan.ready) {
367 conn->chan.ready = 0;
368 ndma_dispatch_conn (sess, conn);
379 ndma_session_initialize (struct ndm_session *sess)
381 ndmis_initialize (sess);
383 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
384 /* ndmca_initialize (sess); */
385 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
387 #ifndef NDMOS_OPTION_NO_DATA_AGENT
388 ndmda_initialize (sess);
389 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
391 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
392 ndmta_initialize (sess);
393 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
395 #ifndef NDMOS_OPTION_NO_ROBOT_AGENT
396 ndmra_initialize (sess);
397 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
403 ndma_session_commission (struct ndm_session *sess)
405 ndmis_commission (sess);
407 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
408 /* ndmca_commission (sess); */
409 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
411 #ifndef NDMOS_OPTION_NO_DATA_AGENT
412 ndmda_commission (sess);
413 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
415 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
416 ndmta_commission (sess);
417 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
419 #ifndef NDMOS_OPTION_NO_ROBOT_AGENT
420 ndmra_commission (sess);
421 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
427 ndma_session_decommission (struct ndm_session *sess)
429 ndmis_decommission (sess);
431 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
432 /* ndmca_decommission (sess); */
433 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
435 #ifndef NDMOS_OPTION_NO_DATA_AGENT
436 ndmda_decommission (sess);
437 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
439 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
440 ndmta_decommission (sess);
441 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
443 #ifndef NDMOS_OPTION_NO_ROBOT_AGENT
444 ndmra_decommission (sess);
445 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */