1 /*
2  * Copyright (c) 1998,1999,2000
3  *	Traakan, Inc., Los Altos, CA
4  *	All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
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.
15  *
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
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *
35  */
36 
37 
38 #include "ndmagents.h"
39 
40 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
41 
42 
43 /*
44  * DATA Agent calls
45  ****************************************************************
46  */
47 
48 int
ndmca_data_get_state(struct ndm_session * sess)49 ndmca_data_get_state (struct ndm_session *sess)
50 {
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;
54 	int			rc;
55 
56 	NDMC_WITH_VOID_REQUEST(ndmp9_data_get_state, NDMP9VER)
57 		rc = NDMC_CALL(conn);
58 		if (rc) {
59 			NDMOS_MACRO_ZEROFILL (state);
60 			ca->data_state.state = -1;
61 		} else {
62 			*state = *reply;
63 		}
64 	NDMC_ENDWITH
65 
66 	return rc;
67 }
68 
69 int
ndmca_data_listen(struct ndm_session * sess)70 ndmca_data_listen (struct ndm_session *sess)
71 {
72 	struct ndmconn *	conn = sess->plumb.data;
73 	struct ndm_control_agent *ca = sess->control_acb;
74 	int			rc;
75 
76 	NDMC_WITH(ndmp9_data_listen, NDMP9VER)
77 		if (sess->plumb.tape == sess->plumb.data) {
78 			request->addr_type = NDMP9_ADDR_LOCAL;
79 		} else {
80 			request->addr_type = NDMP9_ADDR_TCP;
81 		}
82 		rc = NDMC_CALL(conn);
83 		if (rc) return rc;
84 
85 		if (request->addr_type
86 		 != reply->data_connection_addr.addr_type) {
87 			ndmalogf (sess, 0, 0,
88 				"DATA_LISTEN addr_type mismatch");
89 			return -1;
90 		}
91 
92 		ca->data_addr = reply->data_connection_addr;
93 	NDMC_ENDWITH
94 
95 	return 0;
96 }
97 
98 int
ndmca_data_connect(struct ndm_session * sess)99 ndmca_data_connect (struct ndm_session *sess)
100 {
101 	struct ndmconn *	conn = sess->plumb.data;
102 	struct ndm_control_agent *ca = sess->control_acb;
103 	int			rc;
104 	ndmp9_addr		addr;
105 
106 	if (ca->job.tape_tcp) {
107 		char *host;
108 		char *port;
109 		struct sockaddr_in sin;
110 
111 		host = ca->job.tape_tcp;
112 		port = strchr(ca->job.tape_tcp, ':');
113 		if (!port) {
114 		    return 1;
115 		}
116 		*port++ = '\0';
117 		rc = ndmhost_lookup(host, &sin);
118 		addr.addr_type = NDMP9_ADDR_TCP;
119 		addr.ndmp9_addr_u.tcp_addr.ip_addr = ntohl(sin.sin_addr.s_addr);
120 		addr.ndmp9_addr_u.tcp_addr.port = atoi(port);
121 	} else {
122 		addr = ca->mover_addr;
123 	}
124 
125 	NDMC_WITH(ndmp9_data_connect, NDMP9VER)
126 		request->addr = addr;
127 		rc = NDMC_CALL(conn);
128 	NDMC_ENDWITH
129 
130 	return rc;
131 }
132 
133 int
ndmca_data_start_backup(struct ndm_session * sess)134 ndmca_data_start_backup (struct ndm_session *sess)
135 {
136 	struct ndmconn *	conn = sess->plumb.data;
137 	struct ndm_control_agent *ca = sess->control_acb;
138 	unsigned		n_env;
139 	ndmp9_pval *		env;
140 	ndmp9_addr		addr;
141 	int			rc;
142 
143 	if (conn->protocol_version > 2) {
144 	    if (ca->swap_connect) {
145 		if ( (rc = ndmca_mover_connect (sess)) != 0) {
146 			return rc;
147 		}
148 	    } else {
149 		if ( (rc = ndmca_data_connect (sess)) != 0) {
150 			return rc;
151 		}
152 	    }
153 	    addr.addr_type = NDMP9_ADDR_AS_CONNECTED;
154 	} else {
155 		addr = ca->mover_addr;
156 	}
157 
158 	env = ndma_enumerate_env_list(&ca->job.env_tab);
159 	if (!env) {
160 		ndmalogf (sess, 0, 0,
161 			"Failed allocating enumerate buffer");
162 		return -1;
163 	}
164 	n_env = ca->job.env_tab.n_env;
165 	NDMC_WITH(ndmp9_data_start_backup, NDMP9VER)
166 		request->addr = addr;
167 		request->bu_type = ca->job.bu_type;
168 		request->env.env_len = n_env;
169 		request->env.env_val = env;
170 
171 		rc = NDMC_CALL(conn);
172 	NDMC_ENDWITH
173 
174 	return rc;
175 }
176 
177 int
ndmca_data_start_recover(struct ndm_session * sess)178 ndmca_data_start_recover (struct ndm_session *sess)
179 {
180 	struct ndmconn *	conn = sess->plumb.data;
181 	struct ndm_control_agent *ca = sess->control_acb;
182 	unsigned		n_env;
183 	ndmp9_pval *		env;
184 	unsigned		n_nlist;
185 	ndmp9_name *		nlist;
186 	ndmp9_addr		addr;
187 	int			rc;
188 
189 	if (conn->protocol_version > 2) {
190 	    if (ca->swap_connect) {
191 		if ( (rc = ndmca_mover_connect (sess)) != 0) {
192 			return rc;
193 		}
194 	    } else {
195 		if ( (rc = ndmca_data_connect (sess)) != 0) {
196 			return rc;
197 		}
198 	    }
199 	    addr.addr_type = NDMP9_ADDR_AS_CONNECTED;
200 	} else {
201 		addr = ca->mover_addr;
202 	}
203 
204 	env = ndma_enumerate_env_list(&ca->job.env_tab);
205 	if (!env) {
206 		ndmalogf (sess, 0, 0,
207 			"Failed allocating enumerate buffer");
208 		return -1;
209 	}
210 	n_env = ca->job.env_tab.n_env;
211 	nlist = ndma_enumerate_nlist(&ca->job.nlist_tab);
212 	n_nlist = ca->job.nlist_tab.n_nlist;
213 	NDMC_WITH(ndmp9_data_start_recover, NDMP9VER)
214 		request->addr = addr;
215 		request->bu_type = ca->job.bu_type;
216 		request->env.env_len = n_env;
217 		request->env.env_val = env;
218 		request->nlist.nlist_len = n_nlist;
219 		request->nlist.nlist_val = nlist;
220 
221 		rc = NDMC_CALL(conn);
222 	NDMC_ENDWITH
223 
224 	return rc;
225 }
226 
227 int
ndmca_data_start_recover_filehist(struct ndm_session * sess)228 ndmca_data_start_recover_filehist (struct ndm_session *sess)
229 {
230 	struct ndmconn *	conn = sess->plumb.data;
231 	struct ndm_control_agent *ca = sess->control_acb;
232 	unsigned		n_env;
233 	ndmp9_pval *		env;
234 	unsigned		n_nlist;
235 	ndmp9_name *		nlist;
236 	ndmp9_addr		addr;
237 	int			rc;
238 
239 	if (conn->protocol_version > 2) {
240 	    if (ca->swap_connect) {
241 		if ( (rc = ndmca_mover_connect (sess)) != 0) {
242 			return rc;
243 		}
244 	    } else {
245 		if ( (rc = ndmca_data_connect (sess)) != 0) {
246 			return rc;
247 		}
248 	    }
249 		addr.addr_type = NDMP9_ADDR_AS_CONNECTED;
250 	} else {
251 		addr = ca->mover_addr;
252 	}
253 
254 	env = ndma_enumerate_env_list(&ca->job.env_tab);
255 	if (!env) {
256 		ndmalogf (sess, 0, 0,
257 			"Failed allocating enumerate buffer");
258 		return -1;
259 	}
260 	n_env = ca->job.env_tab.n_env;
261 	nlist = ndma_enumerate_nlist(&ca->job.nlist_tab);
262 	n_nlist = ca->job.nlist_tab.n_nlist;
263 	NDMC_WITH(ndmp9_data_start_recover_filehist, NDMP9VER)
264 		request->addr = addr;
265 		request->bu_type = ca->job.bu_type;
266 		request->env.env_len = n_env;
267 		request->env.env_val = env;
268 		request->nlist.nlist_len = n_nlist;
269 		request->nlist.nlist_val = nlist;
270 
271 		rc = NDMC_CALL(conn);
272 	NDMC_ENDWITH
273 
274 	return rc;
275 }
276 
277 int
ndmca_data_abort(struct ndm_session * sess)278 ndmca_data_abort (struct ndm_session *sess)
279 {
280 	struct ndmconn *	conn = sess->plumb.data;
281 	int			rc;
282 
283 	NDMC_WITH_VOID_REQUEST(ndmp9_data_abort, NDMP9VER)
284 		rc = NDMC_CALL(conn);
285 	NDMC_ENDWITH
286 
287 	return rc;
288 }
289 
290 int
ndmca_data_get_env(struct ndm_session * sess)291 ndmca_data_get_env (struct ndm_session *sess)
292 {
293 	struct ndmconn *	conn = sess->plumb.data;
294 	struct ndm_control_agent *ca = sess->control_acb;
295 	int			rc;
296 	unsigned int		i;
297 
298 	NDMC_WITH_VOID_REQUEST(ndmp9_data_get_env, NDMP9VER)
299 		rc = NDMC_CALL(conn);
300 		if (rc) return rc;
301 
302 		for (i = 0; i < reply->env.env_len; i++) {
303 			ndma_store_env_list (&ca->job.result_env_tab, &reply->env.env_val[i]);
304 		}
305 
306 		NDMC_FREE_REPLY();
307 	NDMC_ENDWITH
308 
309 	return rc;
310 }
311 
312 int
ndmca_data_stop(struct ndm_session * sess)313 ndmca_data_stop (struct ndm_session *sess)
314 {
315 	struct ndmconn *	conn = sess->plumb.data;
316 	int			rc;
317 
318 	NDMC_WITH_VOID_REQUEST(ndmp9_data_stop, NDMP9VER)
319 		rc = NDMC_CALL(conn);
320 	NDMC_ENDWITH
321 
322 	return rc;
323 }
324 
325 
326 
327 
328 
329 /*
330  * TAPE Agent calls -- TAPE
331  ****************************************************************
332  */
333 
334 int
ndmca_tape_open(struct ndm_session * sess)335 ndmca_tape_open (struct ndm_session *sess)
336 {
337 	struct ndmconn *	conn = sess->plumb.tape;
338 	struct ndm_control_agent *ca = sess->control_acb;
339 	int			rc;
340 
341 	NDMC_WITH (ndmp9_tape_open, NDMP9VER)
342 		request->device = ca->job.tape_device;
343 		request->mode = ca->tape_mode;
344 		rc = NDMC_CALL(conn);
345 		ca->tape_state.error = reply->error;
346 	NDMC_ENDWITH
347 
348 	return rc;
349 }
350 
351 int
ndmca_tape_close(struct ndm_session * sess)352 ndmca_tape_close (struct ndm_session *sess)
353 {
354 	struct ndmconn *	conn = sess->plumb.tape;
355 	int			rc;
356 
357 	NDMC_WITH_VOID_REQUEST(ndmp9_tape_close, NDMP9VER)
358 		rc = NDMC_CALL(conn);
359 	NDMC_ENDWITH
360 
361 	return rc;
362 }
363 
364 int
ndmca_tape_get_state(struct ndm_session * sess)365 ndmca_tape_get_state (struct ndm_session *sess)
366 {
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;
370 	int			rc;
371 
372 	NDMC_WITH_VOID_REQUEST(ndmp9_tape_get_state, NDMP9VER)
373 		rc = NDMC_CALL(conn);
374 		if (rc) {
375 			NDMOS_MACRO_ZEROFILL (state);
376 			/* tape_state.state = -1; */
377 			state->error = reply->error;
378 		} else {
379 			*state = *reply;
380 		}
381 	NDMC_ENDWITH
382 
383 	return rc;
384 }
385 
386 int
ndmca_tape_get_state_no_tattle(struct ndm_session * sess)387 ndmca_tape_get_state_no_tattle (struct ndm_session *sess)
388 {
389 	struct ndmconn *	conn = sess->plumb.tape;
390 	struct ndm_control_agent *ca = sess->control_acb;
391 	struct ndmp9_tape_get_state_reply *state = &ca->tape_state;
392 	int			rc;
393 
394 	NDMC_WITH_VOID_REQUEST(ndmp9_tape_get_state, NDMP9VER)
395 		rc = ndma_call_no_tattle (conn, xa);
396 		if (rc) {
397 			NDMOS_MACRO_ZEROFILL (state);
398 			/* tape_state.state = -1; */
399 		} else {
400 			*state = *reply;
401 		}
402 		if (rc < 0
403 		 ||  (reply->error != NDMP9_DEV_NOT_OPEN_ERR
404 		   && reply->error != NDMP9_NO_ERR))
405 			ndma_tattle (sess->plumb.tape, xa, rc);
406 	NDMC_ENDWITH
407 
408 	return rc;
409 }
410 
411 int
ndmca_tape_mtio(struct ndm_session * sess,ndmp9_tape_mtio_op op,uint32_t count,uint32_t * resid)412 ndmca_tape_mtio (struct ndm_session *sess,
413   ndmp9_tape_mtio_op op, uint32_t count, uint32_t *resid)
414 {
415 	struct ndmconn *	conn = sess->plumb.tape;
416 	int			rc;
417 
418 	NDMC_WITH(ndmp9_tape_mtio, NDMP9VER)
419 		request->tape_op = op;
420 		request->count = count;
421 
422 		rc = NDMC_CALL(conn);
423 		if (!rc) {
424 			if (resid) {
425 				*resid = reply->resid_count;
426 			} else if (reply->resid_count != 0) {
427 				return -1;
428 			}
429 		}
430 	NDMC_ENDWITH
431 
432 	return rc;
433 }
434 
435 int
ndmca_tape_write(struct ndm_session * sess,char * buf,unsigned count)436 ndmca_tape_write (struct ndm_session *sess, char *buf, unsigned count)
437 {
438 	struct ndmconn *	conn = sess->plumb.tape;
439 	int			rc;
440 
441 	NDMC_WITH(ndmp9_tape_write, NDMP9VER)
442 		request->data_out.data_out_len = count;
443 		request->data_out.data_out_val = buf;
444 		rc = NDMC_CALL(conn);
445 		if (rc == 0) {
446 			if (reply->count != count)
447 				rc = -1;
448 		}
449 	NDMC_ENDWITH
450 
451 	return rc;
452 }
453 
454 int
ndmca_tape_read(struct ndm_session * sess,char * buf,unsigned count)455 ndmca_tape_read (struct ndm_session *sess, char *buf, unsigned count)
456 {
457 	struct ndmconn *	conn = sess->plumb.tape;
458 	int			rc;
459 
460 	NDMC_WITH(ndmp9_tape_read, NDMP9VER)
461 		request->count = count;
462 		rc = NDMC_CALL(conn);
463 		if (rc == 0) {
464 			if (reply->data_in.data_in_len == count) {
465 				bcopy (reply->data_in.data_in_val,
466 							buf, count);
467 			} else {
468 				rc = -1;
469 			}
470 		}
471 		NDMC_FREE_REPLY();
472 	NDMC_ENDWITH
473 
474 	return rc;
475 }
476 
477 
478 int
ndmca_tape_read_partial(struct ndm_session * sess,char * buf,unsigned count,int * read_count)479 ndmca_tape_read_partial (struct ndm_session *sess, char *buf, unsigned count, int *read_count)
480 {
481 	struct ndmconn *	conn = sess->plumb.tape;
482 	int			rc;
483 
484 	NDMC_WITH(ndmp9_tape_read, NDMP9VER)
485 		request->count = count;
486 		rc = NDMC_CALL(conn);
487 		if (rc == 0) {
488 			*read_count = reply->data_in.data_in_len;
489 			bcopy (reply->data_in.data_in_val, buf, *read_count);
490 		} else {
491 			rc = reply->error;
492 		}
493 		NDMC_FREE_REPLY();
494 	NDMC_ENDWITH
495 
496 	return rc;
497 }
498 
499 
500 /*
501  * TAPE Agent calls -- MOVER
502  ****************************************************************
503  */
504 
505 int
ndmca_mover_get_state(struct ndm_session * sess)506 ndmca_mover_get_state (struct ndm_session *sess)
507 {
508 	struct ndmconn *	conn = sess->plumb.tape;
509 	struct ndm_control_agent *ca = sess->control_acb;
510 	struct ndmp9_mover_get_state_reply *state = &ca->mover_state;
511 	int			rc;
512 
513 	NDMC_WITH_VOID_REQUEST(ndmp9_mover_get_state, NDMP9VER)
514 		rc = NDMC_CALL(conn);
515 		if (rc) {
516 			NDMOS_MACRO_ZEROFILL (state);
517 			ca->mover_state.state = -1;
518 		} else {
519 			*state = *reply;
520 		}
521 	NDMC_ENDWITH
522 
523 	return rc;
524 }
525 
526 int
ndmca_mover_listen(struct ndm_session * sess)527 ndmca_mover_listen (struct ndm_session *sess)
528 {
529 	struct ndmconn *	conn = sess->plumb.tape;
530 	struct ndm_control_agent *ca = sess->control_acb;
531 	int			rc;
532 
533 	NDMC_WITH(ndmp9_mover_listen, NDMP9VER)
534 		request->mode = ca->mover_mode;
535 
536 		if (sess->plumb.tape == sess->plumb.data) {
537 			request->addr_type = NDMP9_ADDR_LOCAL;
538 		} else {
539 			request->addr_type = NDMP9_ADDR_TCP;
540 		}
541 		rc = NDMC_CALL(conn);
542 		if (rc) return rc;
543 
544 		if (request->addr_type
545 		 != reply->data_connection_addr.addr_type) {
546 			ndmalogf (sess, 0, 0,
547 				"MOVER_LISTEN addr_type mismatch");
548 			return -1;
549 		}
550 
551 		ca->mover_addr = reply->data_connection_addr;
552 	NDMC_ENDWITH
553 
554 	return 0;
555 }
556 
557 int
ndmca_mover_connect(struct ndm_session * sess)558 ndmca_mover_connect (struct ndm_session *sess)
559 {
560 	struct ndmconn *	conn = sess->plumb.tape;
561 	struct ndm_control_agent *ca = sess->control_acb;
562 	int			rc;
563 
564 	NDMC_WITH(ndmp9_mover_connect, NDMP9VER)
565 		request->mode = ca->mover_mode;
566 		request->addr = ca->data_addr;
567 		rc = NDMC_CALL(conn);
568 	NDMC_ENDWITH
569 
570 	return rc;
571 }
572 
573 int
ndmca_mover_continue(struct ndm_session * sess)574 ndmca_mover_continue (struct ndm_session *sess)
575 {
576 	struct ndmconn *	conn = sess->plumb.tape;
577 	int			rc;
578 
579 	NDMC_WITH_VOID_REQUEST(ndmp9_mover_continue, NDMP9VER)
580 		rc = NDMC_CALL(conn);
581 	NDMC_ENDWITH
582 
583 	return rc;
584 }
585 
586 int
ndmca_mover_abort(struct ndm_session * sess)587 ndmca_mover_abort (struct ndm_session *sess)
588 {
589 	struct ndmconn *	conn = sess->plumb.tape;
590 	int			rc;
591 
592 	NDMC_WITH_VOID_REQUEST(ndmp9_mover_abort, NDMP9VER)
593 		rc = NDMC_CALL(conn);
594 	NDMC_ENDWITH
595 
596 	return rc;
597 }
598 
599 int
ndmca_mover_stop(struct ndm_session * sess)600 ndmca_mover_stop (struct ndm_session *sess)
601 {
602 	struct ndmconn *	conn = sess->plumb.tape;
603 	int			rc;
604 
605 	NDMC_WITH_VOID_REQUEST(ndmp9_mover_stop, NDMP9VER)
606 		rc = NDMC_CALL(conn);
607 	NDMC_ENDWITH
608 
609 	return rc;
610 }
611 
612 int
ndmca_connect_close(struct ndm_session * sess)613 ndmca_connect_close (struct ndm_session *sess)
614 {
615 	struct ndmconn *	conn = sess->plumb.tape;
616 	int			rc;
617 
618 	NDMC_WITH_NO_REPLY(ndmp9_connect_close, NDMP9VER)
619 		rc = NDMC_CALL(conn);
620 	NDMC_ENDWITH
621 
622 	return rc;
623 }
624 
625 int
ndmca_mover_set_window(struct ndm_session * sess,uint64_t offset,uint64_t length)626 ndmca_mover_set_window (struct ndm_session *sess,
627   uint64_t offset, uint64_t length)
628 {
629 	struct ndmconn *	conn = sess->plumb.tape;
630 	int			rc;
631 
632 	NDMC_WITH(ndmp9_mover_set_window, NDMP9VER)
633 		request->offset = offset;
634 		request->length = length;
635 		rc = NDMC_CALL(conn);
636 	NDMC_ENDWITH
637 
638 	return rc;
639 }
640 
641 int
ndmca_mover_read(struct ndm_session * sess,uint64_t offset,uint64_t length)642 ndmca_mover_read (struct ndm_session *sess,
643   uint64_t offset, uint64_t length)
644 {
645 	struct ndmconn *	conn = sess->plumb.tape;
646 	int			rc;
647 
648 	NDMC_WITH(ndmp9_mover_read, NDMP9VER)
649 		request->offset = offset;
650 		request->length = length;
651 		rc = NDMC_CALL(conn);
652 	NDMC_ENDWITH
653 
654 	return rc;
655 }
656 
657 int
ndmca_mover_close(struct ndm_session * sess)658 ndmca_mover_close (struct ndm_session *sess)
659 {
660 	struct ndmconn *	conn = sess->plumb.tape;
661 	int			rc;
662 
663 	NDMC_WITH_VOID_REQUEST(ndmp9_mover_close, NDMP9VER)
664 		rc = NDMC_CALL(conn);
665 	NDMC_ENDWITH
666 
667 	return rc;
668 }
669 
670 int
ndmca_mover_set_record_size(struct ndm_session * sess)671 ndmca_mover_set_record_size (struct ndm_session *sess)
672 {
673 	struct ndmconn *	conn = sess->plumb.tape;
674 	struct ndm_control_agent *ca = sess->control_acb;
675 	int			rc;
676 
677 	NDMC_WITH(ndmp9_mover_set_record_size, NDMP9VER)
678 		request->record_size = ca->job.record_size;
679 		rc = NDMC_CALL(conn);
680 	NDMC_ENDWITH
681 
682 	return rc;
683 }
684 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
685