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"
40 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
45 ****************************************************************
49 ndmca_data_get_state (struct ndm_session *sess)
51 struct ndmconn * conn = sess->plumb.data;
52 struct ndm_control_agent *ca = &sess->control_acb;
53 struct ndmp9_data_get_state_reply *state = &ca->data_state;
56 NDMC_WITH_VOID_REQUEST(ndmp9_data_get_state, NDMP9VER)
59 NDMOS_MACRO_ZEROFILL (state);
60 ca->data_state.state = -1;
70 ndmca_data_listen (struct ndm_session *sess)
72 struct ndmconn * conn = sess->plumb.data;
73 struct ndm_control_agent *ca = &sess->control_acb;
76 NDMC_WITH(ndmp9_data_listen, NDMP9VER)
77 if (sess->plumb.tape == sess->plumb.data) {
78 request->addr_type = NDMP9_ADDR_LOCAL;
80 request->addr_type = NDMP9_ADDR_TCP;
85 if (request->addr_type
86 != reply->data_connection_addr.addr_type) {
88 "DATA_LISTEN addr_type mismatch");
92 ca->data_addr = reply->data_connection_addr;
99 ndmca_data_connect (struct ndm_session *sess)
101 struct ndmconn * conn = sess->plumb.data;
102 struct ndm_control_agent *ca = &sess->control_acb;
106 if (ca->job.tape_tcp) {
109 struct sockaddr_in sin;
111 host = ca->job.tape_tcp;
112 port = strchr(ca->job.tape_tcp, ':');
114 rc = ndmhost_lookup(host, &sin);
115 addr.addr_type = NDMP9_ADDR_TCP;
116 addr.ndmp9_addr_u.tcp_addr.ip_addr = ntohl(sin.sin_addr.s_addr);
117 addr.ndmp9_addr_u.tcp_addr.port = atoi(port);
119 addr = ca->mover_addr;
122 NDMC_WITH(ndmp9_data_connect, NDMP9VER)
123 request->addr = addr;
124 rc = NDMC_CALL(conn);
131 ndmca_data_start_backup (struct ndm_session *sess)
133 struct ndmconn * conn = sess->plumb.data;
134 struct ndm_control_agent *ca = &sess->control_acb;
135 unsigned n_env = ca->job.env_tab.n_env;
136 ndmp9_pval * env = ca->job.env_tab.env;
140 if (conn->protocol_version > 2) {
141 if (ca->swap_connect) {
142 if ( (rc = ndmca_mover_connect (sess)) != 0) {
146 if ( (rc = ndmca_data_connect (sess)) != 0) {
150 addr.addr_type = NDMP9_ADDR_AS_CONNECTED;
152 addr = ca->mover_addr;
155 NDMC_WITH(ndmp9_data_start_backup, NDMP9VER)
156 request->addr = addr;
157 request->bu_type = ca->job.bu_type;
158 request->env.env_len = n_env;
159 request->env.env_val = env;
161 rc = NDMC_CALL(conn);
168 ndmca_data_start_recover (struct ndm_session *sess)
170 struct ndmconn * conn = sess->plumb.data;
171 struct ndm_control_agent *ca = &sess->control_acb;
172 unsigned n_env = ca->job.env_tab.n_env;
173 ndmp9_pval * env = ca->job.env_tab.env;
174 unsigned n_nlist = ca->job.nlist_tab.n_nlist;
175 ndmp9_name * nlist = ca->job.nlist_tab.nlist;
179 if (conn->protocol_version > 2) {
180 if (ca->swap_connect) {
181 if ( (rc = ndmca_mover_connect (sess)) != 0) {
185 if ( (rc = ndmca_data_connect (sess)) != 0) {
189 addr.addr_type = NDMP9_ADDR_AS_CONNECTED;
191 addr = ca->mover_addr;
194 NDMC_WITH(ndmp9_data_start_recover, NDMP9VER)
195 request->addr = addr;
196 request->bu_type = ca->job.bu_type;
197 request->env.env_len = n_env;
198 request->env.env_val = env;
199 request->nlist.nlist_len = n_nlist;
200 request->nlist.nlist_val = nlist;
202 rc = NDMC_CALL(conn);
209 ndmca_data_start_recover_filehist (struct ndm_session *sess)
211 struct ndmconn * conn = sess->plumb.data;
212 struct ndm_control_agent *ca = &sess->control_acb;
213 unsigned n_env = ca->job.env_tab.n_env;
214 ndmp9_pval * env = ca->job.env_tab.env;
215 unsigned n_nlist = ca->job.nlist_tab.n_nlist;
216 ndmp9_name * nlist = ca->job.nlist_tab.nlist;
220 if (conn->protocol_version > 2) {
221 if (ca->swap_connect) {
222 if ( (rc = ndmca_mover_connect (sess)) != 0) {
226 if ( (rc = ndmca_data_connect (sess)) != 0) {
230 addr.addr_type = NDMP9_ADDR_AS_CONNECTED;
232 addr = ca->mover_addr;
235 NDMC_WITH(ndmp9_data_start_recover_filehist, NDMP9VER)
236 request->addr = addr;
237 request->bu_type = ca->job.bu_type;
238 request->env.env_len = n_env;
239 request->env.env_val = env;
240 request->nlist.nlist_len = n_nlist;
241 request->nlist.nlist_val = nlist;
243 rc = NDMC_CALL(conn);
250 ndmca_data_abort (struct ndm_session *sess)
252 struct ndmconn * conn = sess->plumb.data;
255 NDMC_WITH_VOID_REQUEST(ndmp9_data_abort, NDMP9VER)
256 rc = NDMC_CALL(conn);
263 ndmca_data_get_env (struct ndm_session *sess)
265 struct ndmconn * conn = sess->plumb.data;
266 struct ndm_control_agent *ca = &sess->control_acb;
272 NDMC_WITH_VOID_REQUEST(ndmp9_data_get_env, NDMP9VER)
273 rc = NDMC_CALL(conn);
276 for (i = 0; i < reply->env.env_len; i++) {
277 s_pv = &reply->env.env_val[i];
278 d_pv = &ca->job.result_env_tab.env[i];
279 d_pv->name = NDMOS_API_STRDUP (s_pv->name);
280 d_pv->value = NDMOS_API_STRDUP (s_pv->value);
282 ca->job.result_env_tab.n_env = i;
291 ndmca_data_stop (struct ndm_session *sess)
293 struct ndmconn * conn = sess->plumb.data;
296 NDMC_WITH_VOID_REQUEST(ndmp9_data_stop, NDMP9VER)
297 rc = NDMC_CALL(conn);
308 * TAPE Agent calls -- TAPE
309 ****************************************************************
313 ndmca_tape_open (struct ndm_session *sess)
315 struct ndmconn * conn = sess->plumb.tape;
316 struct ndm_control_agent *ca = &sess->control_acb;
319 NDMC_WITH (ndmp9_tape_open, NDMP9VER)
320 request->device = ca->job.tape_device;
321 request->mode = ca->tape_mode;
322 rc = NDMC_CALL(conn);
323 ca->tape_state.error = reply->error;
330 ndmca_tape_close (struct ndm_session *sess)
332 struct ndmconn * conn = sess->plumb.tape;
335 NDMC_WITH_VOID_REQUEST(ndmp9_tape_close, NDMP9VER)
336 rc = NDMC_CALL(conn);
343 ndmca_tape_get_state (struct ndm_session *sess)
345 struct ndmconn * conn = sess->plumb.tape;
346 struct ndm_control_agent *ca = &sess->control_acb;
347 struct ndmp9_tape_get_state_reply *state = &ca->tape_state;
350 NDMC_WITH_VOID_REQUEST(ndmp9_tape_get_state, NDMP9VER)
351 rc = NDMC_CALL(conn);
353 NDMOS_MACRO_ZEROFILL (state);
354 /* tape_state.state = -1; */
355 state->error = reply->error;
365 ndmca_tape_get_state_no_tattle (struct ndm_session *sess)
367 struct ndmconn * conn = sess->plumb.tape;
368 struct ndm_control_agent *ca = &sess->control_acb;
369 struct ndmp9_tape_get_state_reply *state = &ca->tape_state;
372 NDMC_WITH_VOID_REQUEST(ndmp9_tape_get_state, NDMP9VER)
373 rc = ndma_call_no_tattle (conn, xa);
375 NDMOS_MACRO_ZEROFILL (state);
376 /* tape_state.state = -1; */
381 || (reply->error != NDMP9_DEV_NOT_OPEN_ERR
382 && reply->error != NDMP9_NO_ERR))
383 ndma_tattle (sess->plumb.tape, xa, rc);
390 ndmca_tape_mtio (struct ndm_session *sess,
391 ndmp9_tape_mtio_op op, u_long count, u_long *resid)
393 struct ndmconn * conn = sess->plumb.tape;
396 NDMC_WITH(ndmp9_tape_mtio, NDMP9VER)
397 request->tape_op = op;
398 request->count = count;
400 rc = NDMC_CALL(conn);
403 *resid = reply->resid_count;
404 } else if (reply->resid_count != 0) {
414 ndmca_tape_write (struct ndm_session *sess, char *buf, unsigned count)
416 struct ndmconn * conn = sess->plumb.tape;
419 NDMC_WITH(ndmp9_tape_write, NDMP9VER)
420 request->data_out.data_out_len = count;
421 request->data_out.data_out_val = buf;
422 rc = NDMC_CALL(conn);
424 if (reply->count != count)
433 ndmca_tape_read (struct ndm_session *sess, char *buf, unsigned count)
435 struct ndmconn * conn = sess->plumb.tape;
438 NDMC_WITH(ndmp9_tape_read, NDMP9VER)
439 request->count = count;
440 rc = NDMC_CALL(conn);
442 if (reply->data_in.data_in_len == count) {
443 bcopy (reply->data_in.data_in_val,
457 ndmca_tape_read_partial (struct ndm_session *sess, char *buf, unsigned count, int *read_count)
459 struct ndmconn * conn = sess->plumb.tape;
462 NDMC_WITH(ndmp9_tape_read, NDMP9VER)
463 request->count = count;
464 rc = NDMC_CALL(conn);
466 *read_count = reply->data_in.data_in_len;
467 bcopy (reply->data_in.data_in_val, buf, *read_count);
479 * TAPE Agent calls -- MOVER
480 ****************************************************************
484 ndmca_mover_get_state (struct ndm_session *sess)
486 struct ndmconn * conn = sess->plumb.tape;
487 struct ndm_control_agent *ca = &sess->control_acb;
488 struct ndmp9_mover_get_state_reply *state = &ca->mover_state;
491 NDMC_WITH_VOID_REQUEST(ndmp9_mover_get_state, NDMP9VER)
492 rc = NDMC_CALL(conn);
494 NDMOS_MACRO_ZEROFILL (state);
495 ca->mover_state.state = -1;
505 ndmca_mover_listen (struct ndm_session *sess)
507 struct ndmconn * conn = sess->plumb.tape;
508 struct ndm_control_agent *ca = &sess->control_acb;
511 NDMC_WITH(ndmp9_mover_listen, NDMP9VER)
512 request->mode = ca->mover_mode;
514 if (sess->plumb.tape == sess->plumb.data) {
515 request->addr_type = NDMP9_ADDR_LOCAL;
517 request->addr_type = NDMP9_ADDR_TCP;
519 rc = NDMC_CALL(conn);
522 if (request->addr_type
523 != reply->data_connection_addr.addr_type) {
524 ndmalogf (sess, 0, 0,
525 "MOVER_LISTEN addr_type mismatch");
529 ca->mover_addr = reply->data_connection_addr;
536 ndmca_mover_connect (struct ndm_session *sess)
538 struct ndmconn * conn = sess->plumb.tape;
539 struct ndm_control_agent *ca = &sess->control_acb;
542 NDMC_WITH(ndmp9_mover_connect, NDMP9VER)
543 request->mode = ca->mover_mode;
544 request->addr = ca->data_addr;
545 rc = NDMC_CALL(conn);
552 ndmca_mover_continue (struct ndm_session *sess)
554 struct ndmconn * conn = sess->plumb.tape;
557 NDMC_WITH_VOID_REQUEST(ndmp9_mover_continue, NDMP9VER)
558 rc = NDMC_CALL(conn);
565 ndmca_mover_abort (struct ndm_session *sess)
567 struct ndmconn * conn = sess->plumb.tape;
570 NDMC_WITH_VOID_REQUEST(ndmp9_mover_abort, NDMP9VER)
571 rc = NDMC_CALL(conn);
578 ndmca_mover_stop (struct ndm_session *sess)
580 struct ndmconn * conn = sess->plumb.tape;
583 NDMC_WITH_VOID_REQUEST(ndmp9_mover_stop, NDMP9VER)
584 rc = NDMC_CALL(conn);
591 ndmca_mover_set_window (struct ndm_session *sess,
592 unsigned long long offset, unsigned long long length)
594 struct ndmconn * conn = sess->plumb.tape;
597 NDMC_WITH(ndmp9_mover_set_window, NDMP9VER)
598 request->offset = offset;
599 request->length = length;
600 rc = NDMC_CALL(conn);
607 ndmca_mover_read (struct ndm_session *sess,
608 unsigned long long offset, unsigned long long length)
610 struct ndmconn * conn = sess->plumb.tape;
613 NDMC_WITH(ndmp9_mover_read, NDMP9VER)
614 request->offset = offset;
615 request->length = length;
616 rc = NDMC_CALL(conn);
623 ndmca_mover_close (struct ndm_session *sess)
625 struct ndmconn * conn = sess->plumb.tape;
628 NDMC_WITH_VOID_REQUEST(ndmp9_mover_close, NDMP9VER)
629 rc = NDMC_CALL(conn);
636 ndmca_mover_set_record_size (struct ndm_session *sess)
638 struct ndmconn * conn = sess->plumb.tape;
639 struct ndm_control_agent *ca = &sess->control_acb;
642 NDMC_WITH(ndmp9_mover_set_record_size, NDMP9VER)
643 request->record_size = ca->job.record_size;
644 rc = NDMC_CALL(conn);
649 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */