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  * NDMP Elements of a backup/restore session
38  *
39  *                   +-----+     ###########
40  *                   | Job |----># CONTROL #      +----------------+
41  *                   +-----+     #  Agent  #<---->|FILE/MEDIA INDEX|
42  *                               #         #      +----------------+
43  *                               ###########
44  *                                 |  |  |
45  *                +----------------+  |  +---------------------+
46  *                |           control | connections            |
47  *                V                   V                        V
48  *           ############        ############  +-------+   #########
49  *           #  DATA    #        #  TAPE    #  |       |   # ROBOT #
50  *           #  Agent   #        #  Agent   #  | ROBOT |<-># Agent #
51  *  +-----+  # +------+ # image  # +------+ #  |+-----+|   #       #
52  *  |FILES|====|butype|============|mover |=====|DRIVE||   #       #
53  *  +-----+  # +------+ # stream # +------+ #  |+-----+|   #       #
54  *           ############        ############  +-------+   #########
55  *
56  *
57  ********************************************************************
58  *
59  * NDMAGENTS components overview
60  *
61  *
62  *    "job" -> ndma_client_session()    ndma_server_session()
63  *                   |                           |
64  *     /-------------/                           Q
65  *     |                                         v
66  *     |       +------------------------------------+      +-----------+
67  *     |    /->|           SESSION QUANTUM          |----->| disp conn |
68  *     |    |  +------------------------------------+ \    +-----------+
69  *     |    Q   Q       Q         Q       Q        Q  |         v    |
70  *     |    |   |       |         |       |        |  | +----------+ |
71  *     |  /-----|----+--|----+----|----+--|----+---|----| dispatch | |
72  *     |  | |   |    |  |    |    |    |  |    |   |  | | request  | |
73  *     |  v |   v    v  v    v    v    v  v    v   v  | +----------+ |
74  *     | +-------+  +----+  +------+  +----+  +-----+ |      ^       |
75  *     +>|CONTROL|  |DATA|  |IMAGE |  |TAPE|  |ROBOT| |      |       |
76  *       |       |  |    |->|STREAM|<-|    |  |     | |      |       |
77  *       |       |  |   *====*    *====*   |  |     | |      |  ndmconn_recv()
78  *       | ndmca |  ndmda|  |ndmis |  ndmta|  |ndmra| |      |       |
79  *       +-------+  +----+  +------+  +----+  +-----+ |      |resi   |
80  *              |     | |    |    |       |           |   +------+   |
81  *              \-----|-+----|----+-------+-------------->| call |   |
82  *                    |      |                        |   +------+   |
83  *           formatter|      |image_stream            |      |remo   |
84  *                    v      v                        |      v       v
85  *                   +---------+<---ndmchan_poll()----/     +---------+
86  *                   | ndmchan |<---------------------------| ndmconn |
87  *                   +---------+                            +---------+
88  *                 non-blocking I/O                         XDR wrapper
89  *
90  *   -----> caller/callee
91  *   --Q--> quantum (CPU scheduling)
92  *   ====== image stream shared data structures
93  *
94  ********************************************************************
95  */
96 
97 #ifndef BAREOS_NDMP_NDMAGENTS_H_
98 #define BAREOS_NDMP_NDMAGENTS_H_ 1
99 
100 #include "ndmp/ndmlib.h"
101 
102 #ifdef __cplusplus
103 extern "C" {
104 #endif
105 
106 /*
107  * VERSION AND RELEASE CONSTANTS -- KEEPER ONLY
108  ****************************************************************
109  *
110  * Revision constants for the source code. These may only be
111  * changed by the keeper of these sources. Contact ndmp-tech@ndmp.org
112  * for a pointer to the latest sources and the current keeper.
113  *
114  * The Version increases every time there is a significant
115  * design change. Significant means new functionality,
116  * reorganization of key data structures, etc. The Release
117  * increases every time the keeper releases an update to
118  * the current version, such as bug fixes or integration
119  * of new contributions.
120  *
121  * There are provisions for a free-form string for revisions
122  * of the O/S specific portions (NDMOS_CONST_NDMOS_REVISION)
123  * and for local revisions (NDMOS_CONST_NDMJOBLIB_REVISION)
124  * which reflect in-house change levels.
125  */
126 #define NDMJOBLIB_VERSION 1
127 #define NDMJOBLIB_RELEASE 2
128 
129 
130 struct ndm_session; /* forward decl */
131 
132 
133 /*
134  * NDM_ENV_TABLE and NDM_NLIST_TABLE
135  ****************************************************************
136  * Used by DATA and CONTROL agents
137  */
138 #ifndef NDM_MAX_ENV
139 #define NDM_MAX_ENV 1024
140 #endif
141 
142 struct ndm_env_entry {
143   ndmp9_pval pval;
144   struct ndm_env_entry* next;
145 };
146 
147 struct ndm_env_table {
148   int32_t n_env;
149   ndmp9_pval* enumerate;
150   int32_t enumerate_length;
151   struct ndm_env_entry* head;
152   struct ndm_env_entry* tail;
153 };
154 
155 /* ndma_listmgt.c */
156 extern ndmp9_pval* ndma_enumerate_env_list(struct ndm_env_table* envtab);
157 extern struct ndm_env_entry* ndma_store_env_list(struct ndm_env_table* envtab,
158                                                  ndmp9_pval* pv);
159 extern struct ndm_env_entry* ndma_update_env_list(struct ndm_env_table* envtab,
160                                                   ndmp9_pval* pv);
161 extern void ndma_destroy_env_list(struct ndm_env_table* envtab);
162 
163 #ifndef NDM_MAX_NLIST
164 #define NDM_MAX_NLIST 10240
165 #endif
166 
167 struct ndm_nlist_entry {
168   ndmp9_name name;
169   ndmp9_error result_err;
170   unsigned result_count;
171   struct ndm_nlist_entry* next;
172 };
173 
174 
175 struct ndm_nlist_table {
176   int32_t n_nlist;
177   ndmp9_name* enumerate;
178   int32_t enumerate_length;
179   struct ndm_nlist_entry* head;
180   struct ndm_nlist_entry* tail;
181 };
182 
183 
184 /* ndma_listmgt.c */
185 extern ndmp9_name* ndma_enumerate_nlist(struct ndm_nlist_table* nlist);
186 extern struct ndm_nlist_entry* ndma_store_nlist(struct ndm_nlist_table* nlist,
187                                                 ndmp9_name* nl);
188 extern void ndma_destroy_nlist(struct ndm_nlist_table* nlist);
189 
190 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
191 /*
192  * CONTROL AGENT
193  ****************************************************************
194  */
195 
196 #include "ndmp/smc.h" /* SCSI Media Changer */
197 
198 
199 #ifndef NDM_MAX_MEDIA
200 #define NDM_MAX_MEDIA 40
201 #endif
202 
203 struct ndm_media_table {
204   int32_t n_media;
205   struct ndmmedia* head;
206   struct ndmmedia* tail;
207 };
208 
209 /* ndma_listmgt.c */
210 extern struct ndmmedia* ndma_store_media(struct ndm_media_table* mtab,
211                                          uint16_t element_address);
212 extern struct ndmmedia* ndma_clone_media_entry(struct ndm_media_table* mtab,
213                                                struct ndmmedia* to_clone);
214 extern void ndmca_destroy_media_table(struct ndm_media_table* mtab);
215 
216 #define NDM_JOB_OP_BACKUP (0x100 | 'c')
217 #define NDM_JOB_OP_EXTRACT (0x100 | 'x')
218 #define NDM_JOB_OP_TOC (0x100 | 't')
219 #define NDM_JOB_OP_QUERY_AGENTS (0x100 | 'q')
220 #define NDM_JOB_OP_INIT_LABELS (0x100 | 'I')
221 #define NDM_JOB_OP_LIST_LABELS (0x100 | 'L')
222 #define NDM_JOB_OP_REMEDY_ROBOT (0x100 | 'Z')
223 
224 /* test operations */
225 #define NDM_JOB_OP_TEST_TAPE (0x200 | 'T')
226 #define NDM_JOB_OP_TEST_MOVER (0x200 | 'M')
227 #define NDM_JOB_OP_TEST_DATA (0x200 | 'D')
228 
229 /* tape handling operations */
230 #define NDM_JOB_OP_REWIND_TAPE (0x300 | 'r')
231 #define NDM_JOB_OP_EJECT_TAPE (0x300 | 'j')
232 #define NDM_JOB_OP_MOVE_TAPE (0x300 | 'm')
233 #define NDM_JOB_OP_LOAD_TAPE (0x300 | 'l')
234 #define NDM_JOB_OP_UNLOAD_TAPE (0x300 | 'u')
235 #define NDM_JOB_OP_IMPORT_TAPE (0x300 | 'i')
236 #define NDM_JOB_OP_EXPORT_TAPE (0x300 | 'e')
237 #define NDM_JOB_OP_INIT_ELEM_STATUS (0x300 | 'I')
238 
239 /* daemon operations */
240 #define NDM_JOB_OP_DAEMON 'd'
241 
242 struct ndm_job_param {
243   int32_t operation;  /* NDM_JOB_OP_... */
244   int32_t time_limit; /* command timeout, 0 is off */
245 
246   struct ndmagent data_agent;          /* DATA AGENT host/pw */
247   char* bu_type;                       /* e.g. "tar" */
248   int32_t bu_level;                    /* e.g. 0..9 for dump */
249   struct ndm_env_table env_tab;        /* for BACKUP+RECOVER ops */
250   struct ndm_nlist_table nlist_tab;    /* for RECOVER ops */
251   struct ndm_env_table result_env_tab; /* after BACKUP */
252   struct ndmlog index_log;             /* to log NDMP_FH_ADD_... */
253 
254   struct ndmagent tape_agent;         /* TAPE AGENT host/pw */
255   char* tape_device;                  /* eg "/dev/rmt0" */
256   unsigned tape_timeout;              /* secs total to retry open */
257   unsigned record_size;               /* in bytes, 10k typical */
258   uint64_t last_w_offset;             /* last window offset sent */
259   struct ndmscsi_target* tape_target; /* unused for now */
260   char* tape_tcp;                     /* tcp direct */
261   NDM_FLAG_DECL(use_eject)            /* eject upon close (unload) */
262 
263   struct ndmagent robot_agent;         /* ROBOT AGENT host/pw */
264   struct ndmscsi_target* robot_target; /* SCSI coord of robot */
265   unsigned robot_timeout;              /* secs total to retry move */
266   NDM_FLAG_DECL(have_robot)            /* yes, we have robot, today */
267   NDM_FLAG_DECL(auto_remedy)           /* if drive loaded, unload */
268   NDM_FLAG_DECL(remedy_all)            /* OP_REMEDY, all drives */
269   NDM_FLAG_DECL(drive_addr_given)
270   NDM_FLAG_DECL(from_addr_given)
271   NDM_FLAG_DECL(to_addr_given)
272   unsigned drive_addr; /* 0->first, !0->elem addr */
273   unsigned from_addr;  /* for MOVE and EXPORT */
274   unsigned to_addr;    /* for MOVE and IMPORT */
275                        /* use move for many I/E */
276 
277   struct ndm_media_table media_tab;        /* media to use, params */
278   struct ndm_media_table result_media_tab; /* results after job */
279 
280   uint32_t n_file_entry;
281   uint32_t n_dir_entry;
282   uint32_t n_node_entry;
283   uint64_t root_node;
284 
285   uint64_t bytes_written;
286   uint64_t bytes_read;
287 };
288 
289 /* ndma_job.c */
290 extern int ndma_job_audit(struct ndm_job_param* job, char* errbuf, int errskip);
291 extern int ndma_job_media_audit(struct ndm_job_param* job,
292                                 char* errbuf,
293                                 int errskip);
294 extern void ndma_job_auto_adjust(struct ndm_job_param* job);
295 
296 
297 struct ndm_control_agent {
298   /* The JOB, see immediately above */
299   struct ndm_job_param job;
300   NDM_FLAG_DECL(swap_connect)
301   NDM_FLAG_DECL(has_tcp_addr)
302   NDM_FLAG_DECL(has_local_addr)
303 
304   /* DATA agent */
305   ndmp9_data_operation data_op;
306   ndmp9_data_get_state_reply data_state;
307   NDM_FLAG_DECL(pending_notify_data_read)
308   NDM_FLAG_DECL(pending_notify_data_halted)
309   ndmp9_notify_data_read_request last_notify_data_read;
310   ndmp9_addr data_addr;
311   int32_t recover_log_file_count;
312   int32_t recover_log_file_ok;
313   int32_t recover_log_file_error;
314 
315   /* Image stream */
316   ndmp9_addr mover_addr;
317   ndmp9_mover_mode mover_mode;
318 
319   /* TAPE Agent */
320   ndmp9_mover_get_state_reply mover_state;
321   NDM_FLAG_DECL(pending_notify_mover_paused)
322   NDM_FLAG_DECL(pending_notify_mover_halted)
323   ndmp9_notify_mover_paused_request last_notify_mover_paused;
324 
325   ndmp9_tape_open_mode tape_mode;
326   ndmp9_tape_get_state_reply tape_state;
327 
328   /* Media management, media_table inside of job */
329   int32_t cur_media_ix; /* references struct ndmmedia index field */
330   NDM_FLAG_DECL(media_is_loaded)
331   NDM_FLAG_DECL(is_label_op)
332 
333   /* ROBOT Agent */
334   struct smc_ctrl_block* smc_cb;
335   unsigned drive_addr;
336 
337 #ifndef NDMOS_OPTION_NO_TEST_AGENTS
338   /* when testing */
339   char* active_test;        /* name of test or 0 if no test */
340   char* active_test_failed; /* active test failed */
341   char* active_test_warned; /* active test warned */
342 
343   char* test_phase;  /* name of sub-series test phase */
344   int32_t test_step; /* test sequence number */
345 
346   int32_t n_step_pass; /* per phase test stats */
347   int32_t n_step_fail;
348   int32_t n_step_warn;
349   int32_t n_step_tests;
350 
351   int32_t total_n_step_pass; /* total test stats */
352   int32_t total_n_step_fail;
353   int32_t total_n_step_warn;
354   int32_t total_n_step_tests;
355 #endif
356 
357 #ifdef NDMOS_MACRO_CONTROL_AGENT_ADDITIONS
358   NDMOS_MACRO_CONTROL_AGENT_ADDITIONS
359 #endif /* NDMOS_MACRO_CONTROL_AGENT_ADDITIONS */
360 };
361 
362 
363 /* ndma_control.c */
364 extern int ndmca_initialize(struct ndm_session* sess);
365 extern int ndmca_commission(struct ndm_session* sess);
366 extern int ndmca_decommission(struct ndm_session* sess);
367 extern int ndmca_destroy(struct ndm_session* sess);
368 extern int ndmca_control_agent(struct ndm_session* sess);
369 
370 /* ndma_cops_backreco.c */
371 extern int ndmca_op_create_backup(struct ndm_session* sess);
372 extern int ndmca_op_recover_files(struct ndm_session* sess);
373 extern int ndmca_op_recover_fh(struct ndm_session* sess);
374 extern int ndmca_monitor_backup(struct ndm_session* sess);
375 extern int ndmca_monitor_get_post_backup_env(struct ndm_session* sess);
376 extern int ndmca_monitor_recover(struct ndm_session* sess);
377 extern int ndmca_backreco_startup(struct ndm_session* sess);
378 extern int ndmca_monitor_startup(struct ndm_session* sess);
379 extern int ndmca_monitor_shutdown(struct ndm_session* sess);
380 extern int ndmca_monitor_get_states(struct ndm_session* sess);
381 extern int ndmca_monitor_load_next(struct ndm_session* sess);
382 extern int ndmca_monitor_seek_tape(struct ndm_session* sess);
383 extern int ndmca_monitor_unload_last_tape(struct ndm_session* sess);
384 extern int ndmca_mon_wait_for_something(struct ndm_session* sess,
385                                         int32_t max_delay_secs);
386 
387 struct ndmca_jobcontrol_callbacks {
388   int (*is_job_canceled)(struct ndm_session* sess);
389 };
390 
391 extern void ndmca_jobcontrol_register_callbacks(
392     struct ndm_session* sess,
393     struct ndmca_jobcontrol_callbacks* callbacks);
394 
395 extern void ndmca_jobcontrol_unregister_callbacks(struct ndm_session* sess);
396 
397 /* ndma_cops_labels.c */
398 extern int ndmca_op_init_labels(struct ndm_session* sess);
399 extern int ndmca_op_list_labels(struct ndm_session* sess);
400 
401 
402 /* ndma_cops_query.c */
403 
404 struct ndmca_query_callbacks {
405   int (*get_tape_info)(struct ndm_session* sess,
406                        ndmp9_device_info* info,
407                        unsigned n_info);
408   /*
409      int (*get_host_info)(struct ndm_session *sess);
410      int (*get_fs_info)(struct ndm_session *sess);
411      int (*get_scsi_info)(struct ndm_session *sess);
412    */
413 };
414 
415 extern void ndmca_query_register_callbacks(
416     struct ndm_session* sess,
417     struct ndmca_query_callbacks* callbacks);
418 
419 extern void ndmca_query_unregister_callbacks(struct ndm_session* sess);
420 
421 
422 extern int ndmca_op_query(struct ndm_session* sess);
423 extern int ndmca_opq_data(struct ndm_session* sess);
424 extern int ndmca_opq_tape(struct ndm_session* sess);
425 extern int ndmca_opq_robot(struct ndm_session* sess);
426 extern int ndmca_opq_host_info(struct ndm_session* sess, struct ndmconn* conn);
427 extern int ndmca_opq_get_mover_type(struct ndm_session* sess,
428                                     struct ndmconn* conn);
429 extern int ndmca_opq_get_butype_attr(struct ndm_session* sess,
430                                      struct ndmconn* conn);
431 extern int ndmca_opq_get_fs_info(struct ndm_session* sess,
432                                  struct ndmconn* conn);
433 extern int ndmca_opq_get_tape_info(struct ndm_session* sess,
434                                    struct ndmconn* conn);
435 extern int ndmca_opq_get_scsi_info(struct ndm_session* sess,
436                                    struct ndmconn* conn);
437 extern void ndmalogqr(struct ndm_session* sess, char* fmt, ...);
438 
439 
440 /* ndma_cops_robot.c */
441 extern int ndmca_op_robot_remedy(struct ndm_session* sess);
442 extern int ndmca_op_robot_startup(struct ndm_session* sess,
443                                   int32_t verify_media_flag);
444 extern int ndmca_op_init_elem_status(struct ndm_session* sess);
445 extern int ndmca_op_rewind_tape(struct ndm_session* sess);
446 extern int ndmca_op_eject_tape(struct ndm_session* sess);
447 extern int ndmca_op_mtio(struct ndm_session* sess, ndmp9_tape_mtio_op mtio_op);
448 
449 extern int ndmca_op_move_tape(struct ndm_session* sess);
450 extern int ndmca_op_import_tape(struct ndm_session* sess);
451 extern int ndmca_op_export_tape(struct ndm_session* sess);
452 extern int ndmca_op_load_tape(struct ndm_session* sess);
453 extern int ndmca_op_unload_tape(struct ndm_session* sess);
454 
455 
456 /* ndma_ctrl_calls.c */
457 extern int ndmca_connect_close(struct ndm_session* sess);
458 extern int ndmca_data_get_state(struct ndm_session* sess);
459 extern int ndmca_data_connect(struct ndm_session* sess);
460 extern int ndmca_data_listen(struct ndm_session* sess);
461 extern int ndmca_data_start_backup(struct ndm_session* sess);
462 extern int ndmca_data_start_recover(struct ndm_session* sess);
463 extern int ndmca_data_start_recover_filehist(struct ndm_session* sess);
464 extern int ndmca_data_abort(struct ndm_session* sess);
465 extern int ndmca_data_get_env(struct ndm_session* sess);
466 extern int ndmca_data_stop(struct ndm_session* sess);
467 extern int ndmca_tape_open(struct ndm_session* sess);
468 extern int ndmca_tape_close(struct ndm_session* sess);
469 extern int ndmca_tape_get_state(struct ndm_session* sess);
470 extern int ndmca_tape_get_state_no_tattle(struct ndm_session* sess);
471 extern int ndmca_tape_mtio(struct ndm_session* sess,
472                            ndmp9_tape_mtio_op op,
473                            uint32_t count,
474                            uint32_t* resid);
475 extern int ndmca_tape_write(struct ndm_session* sess,
476                             char* buf,
477                             unsigned count);
478 extern int ndmca_tape_read(struct ndm_session* sess, char* buf, unsigned count);
479 extern int ndmca_mover_get_state(struct ndm_session* sess);
480 extern int ndmca_mover_listen(struct ndm_session* sess);
481 extern int ndmca_mover_connect(struct ndm_session* sess);
482 extern int ndmca_mover_continue(struct ndm_session* sess);
483 extern int ndmca_mover_abort(struct ndm_session* sess);
484 extern int ndmca_mover_stop(struct ndm_session* sess);
485 extern int ndmca_mover_set_window(struct ndm_session* sess,
486                                   uint64_t offset,
487                                   uint64_t length);
488 extern int ndmca_mover_read(struct ndm_session* sess,
489                             uint64_t offset,
490                             uint64_t length);
491 extern int ndmca_mover_close(struct ndm_session* sess);
492 extern int ndmca_mover_set_record_size(struct ndm_session* sess);
493 
494 
495 /* ndma_ctrl_media.c */
496 
497 struct ndmca_media_callbacks {
498   int (*load_first)(struct ndm_session* sess);
499   int (*load_next)(struct ndm_session* sess);
500   int (*unload_current)(struct ndm_session* sess);
501 };
502 
503 extern void ndmca_media_register_callbacks(
504     struct ndm_session* sess,
505     struct ndmca_media_callbacks* callbacks);
506 extern void ndmca_media_unregister_callbacks(struct ndm_session* sess);
507 extern int ndmca_media_load_first(struct ndm_session* sess);
508 extern int ndmca_media_load_next(struct ndm_session* sess);
509 extern int ndmca_media_unload_last(struct ndm_session* sess);
510 extern int ndmca_media_change(struct ndm_session* sess);
511 extern int ndmca_media_load_seek(struct ndm_session* sess, uint64_t pos);
512 extern int ndmca_media_load_current(struct ndm_session* sess);
513 extern int ndmca_media_unload_current(struct ndm_session* sess);
514 extern int ndmca_media_unload_best_effort(struct ndm_session* sess);
515 extern int ndmca_media_open_tape(struct ndm_session* sess);
516 extern int ndmca_media_close_tape(struct ndm_session* sess);
517 extern int ndmca_media_mtio_tape(struct ndm_session* sess,
518                                  ndmp9_tape_mtio_op op,
519                                  uint32_t count,
520                                  uint32_t* resid);
521 extern int ndmca_media_write_filemarks(struct ndm_session* sess);
522 extern int ndmca_media_read_label(struct ndm_session* sess, char labbuf[]);
523 extern int ndmca_media_write_label(struct ndm_session* sess,
524                                    int32_t type,
525                                    char labbuf[]);
526 extern int ndmca_media_check_label(struct ndm_session* sess,
527                                    int32_t type,
528                                    char labbuf[]);
529 extern int ndmca_media_verify(struct ndm_session* sess);
530 extern int ndmca_media_tattle(struct ndm_session* sess);
531 extern uint64_t ndmca_media_capture_tape_offset(struct ndm_session* sess);
532 extern int ndmca_media_capture_mover_window(struct ndm_session* sess);
533 extern int ndmca_media_calculate_windows(struct ndm_session* sess);
534 extern int ndmca_media_calculate_offsets(struct ndm_session* sess);
535 extern int ndmca_media_set_window_current(struct ndm_session* sess);
536 
537 
538 /* ndma_ctrl_robot.c */
539 extern int ndmca_robot_issue_scsi_req(struct smc_ctrl_block* smc);
540 extern int ndmca_robot_prep_target(struct ndm_session* sess);
541 extern int ndmca_robot_obtain_info(struct ndm_session* sess);
542 extern int ndmca_robot_init_elem_status(struct ndm_session* sess);
543 extern int ndmca_robot_startup(struct ndm_session* sess);
544 extern int ndmca_robot_move(struct ndm_session* sess,
545                             int32_t src_addr,
546                             int32_t dst_addr);
547 extern int ndmca_robot_load(struct ndm_session* sess, int32_t slot_addr);
548 extern int ndmca_robot_unload(struct ndm_session* sess, int32_t slot_addr);
549 extern struct smc_element_descriptor* ndmca_robot_find_element(
550     struct ndm_session* sess,
551     int32_t element_address);
552 extern int ndmca_robot_check_ready(struct ndm_session* sess);
553 extern int ndmca_robot_remedy_ready(struct ndm_session* sess);
554 extern int ndmca_robot_query(struct ndm_session* sess);
555 extern int ndmca_robot_verify_media(struct ndm_session* sess);
556 extern int ndmca_robot_synthesize_media(struct ndm_session* sess);
557 
558 
559 /* ndma_ctrl_conn.c */
560 extern int ndmca_connect_xxx_agent(struct ndm_session* sess,
561                                    struct ndmconn** connp,
562                                    char* prefix,
563                                    struct ndmagent* agent);
564 extern int ndmca_connect_data_agent(struct ndm_session* sess);
565 extern int ndmca_connect_tape_agent(struct ndm_session* sess);
566 extern int ndmca_connect_robot_agent(struct ndm_session* sess);
567 extern int ndmca_connect_control_agent(struct ndm_session* sess);
568 
569 
570 /* ndma_ctst_tape.c */
571 extern int ndmca_op_test_tape(struct ndm_session* sess);
572 
573 /* ndma_ctst_mover.c */
574 extern int ndmca_op_test_mover(struct ndm_session* sess);
575 
576 /* ndma_ctst_data.c */
577 extern int ndmca_op_test_data(struct ndm_session* sess);
578 
579 /* ndma_ctst_subr.c */
580 extern int ndmca_test_query_conn_types(struct ndm_session* sess,
581                                        struct ndmconn* ref_conn);
582 extern int ndmca_test_load_tape(struct ndm_session* sess);
583 extern int ndmca_test_unload_tape(struct ndm_session* sess);
584 extern int ndmca_test_call(struct ndmconn* conn,
585                            struct ndmp_xa_buf* xa,
586                            ndmp9_error expect_err);
587 extern int ndmca_test_check_expect_errs(struct ndmconn* conn,
588                                         int32_t rc,
589                                         ndmp9_error expect_errs[]);
590 extern int ndmca_test_check_expect(struct ndmconn* conn,
591                                    int32_t rc,
592                                    ndmp9_error expect_err);
593 extern int ndmca_test_check_expect_no_err(struct ndmconn* conn, int32_t rc);
594 extern int ndmca_test_check_expect_illegal_state(struct ndmconn* conn,
595                                                  int32_t rc);
596 extern int ndmca_test_check_expect_illegal_args(struct ndmconn* conn,
597                                                 int32_t rc);
598 extern void ndmca_test_phase(struct ndm_session* sess,
599                              char* test_phase,
600                              char* desc);
601 extern void ndmca_test_log_step(struct ndm_session* sess,
602                                 int32_t level,
603                                 char* msg);
604 extern void ndmca_test_log_note(struct ndm_session* sess,
605                                 int32_t level,
606                                 char* msg);
607 extern void ndmca_test_done_phase(struct ndm_session* sess);
608 extern void ndmca_test_done_series(struct ndm_session* sess, char* series_name);
609 extern void ndmca_test_open(struct ndm_session* sess,
610                             char* test_name,
611                             char* sub_test_name);
612 extern void ndmca_test_warn(struct ndm_session* sess, char* warn_msg);
613 extern void ndmca_test_fail(struct ndm_session* sess, char* fail_msg);
614 extern void ndmca_test_close(struct ndm_session* sess);
615 
616 
617 extern void ndmca_test_fill_data(char* buf,
618                                  int32_t bufsize,
619                                  int32_t recno,
620                                  int32_t fileno);
621 
622 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
623 
624 
625 #ifndef NDMOS_OPTION_NO_DATA_AGENT
626 /*
627  * DATA AGENT
628  ****************************************************************
629  *
630  * NDMP Elements of Data Agent (backup)
631  *
632  *  +-----------+stderr
633  *  | bu_type   |--------formatter_err---------NDMP_LOG-------> to CONTROL
634  *  | formatter |
635  *  | process   |========formatter_data=+=====================> to image stream
636  *  +-----------+stdout                 |
637  *                                  +-------+
638  *                                  | snoop |--NDMP_FH_ADD_x--> to CONTROL
639  *                                  +-------+
640  *
641  ****************************************************************
642  *
643  * NDMP Elements of Data Agent (recover)
644  *
645  *  +-----------+stderr
646  *  | bu_type   |--------formatter_err---------NDMP_LOG-------> to CONTROL
647  *  | formatter |                 +--------+
648  *  | process   |<=======fmt_data=| direct |==================< from image str
649  *  +-----------+stdin            |        |-NOTIFY_DATA_READ-> to CONTROL
650  *                                | snoop  |
651  *                                +--------+
652  *
653  ****************************************************************
654  *
655  * NDMP Elements of Data Agent (recover filehist)
656  *
657  *                                +--------+
658  *                                | direct |==================< from image str
659  *                                |        |-NOTIFY_DATA_READ-> to CONTROL
660  *                                | snoop  |--NDMP_FH_ADD_x---> to CONTROL
661  *                                +--------+
662  *
663  ****************************************************************
664  */
665 
666 
667 #ifndef NDMDA_N_FMT_IMAGE_BUF
668 #define NDMDA_N_FMT_IMAGE_BUF (8 * 1024)
669 #endif
670 #ifndef NDMDA_N_FHH_BUF
671 #define NDMDA_N_FHH_BUF (8 * 1024)
672 #endif
673 #ifndef NDMDA_N_FMT_ERROR_BUF
674 #define NDMDA_N_FMT_ERROR_BUF (8 * 1024)
675 #endif
676 #ifndef NDMDA_N_FMT_WRAP_BUF
677 #define NDMDA_N_FMT_WRAP_BUF (4 * 1024)
678 #endif
679 #ifndef NDMDA_MAX_CMD
680 #define NDMDA_MAX_CMD (4 * 1024)
681 #endif
682 
683 
684 #ifndef NDMOS_OPTION_NO_GTAR_BUTYPE
685 extern int ndmda_butype_gtar_config_get_attrs(struct ndm_session* sess,
686                                               uint32_t* attrs_p,
687                                               int32_t protocol_version);
688 
689 extern int ndmda_butype_gtar_config_get_default_env(struct ndm_session* sess,
690                                                     ndmp9_pval** env_p,
691                                                     int32_t* n_env_p,
692                                                     int32_t protocol_version);
693 extern int ndmda_butype_gtar_attach(struct ndm_session* sess);
694 #endif
695 #ifndef NDMOS_OPTION_NO_DUMP_BUTYPE
696 extern int ndmda_butype_dump_config_get_attrs(struct ndm_session* sess,
697                                               uint32_t* attrs_p,
698                                               int32_t protocol_version);
699 
700 extern int ndmda_butype_dump_config_get_default_env(struct ndm_session* sess,
701                                                     ndmp9_pval** env_p,
702                                                     int32_t* n_env_p,
703                                                     int32_t protocol_version);
704 extern int ndmda_butype_dump_attach(struct ndm_session* sess);
705 #endif
706 
707 
708 struct ndm_data_recovery_interval {
709   ndmp9_u_quad offset;
710   ndmp9_u_quad length;
711 };
712 
713 enum ndm_data_recovery_access_method
714 {
715   NDMDA_RECO_ACCESS_SEQUENTIAL = 1,
716   NDMDA_RECO_ACCESS_DIRECT,
717   NDMDA_RECO_ACCESS_SEMI_DIRECT,
718   NDMDA_RECO_ACCESS_SEMI_DIRECT_PENDING
719 };
720 
721 enum ndm_data_recovery_state
722 {
723   NDMDA_RECO_STATE_START = 1,
724   NDMDA_RECO_STATE_PASS_THRU,
725   NDMDA_RECO_STATE_CHOOSE_NLENT,
726   NDMDA_RECO_STATE_ACQUIRE,
727   NDMDA_RECO_STATE_DISPOSE,
728   NDMDA_RECO_STATE_FINISH_NLENT,
729   NDMDA_RECO_STATE_ALL_DONE
730 };
731 
732 enum ndm_data_recovery_acquire_mode
733 {
734   NDMDA_RECO_ACQUIRE_EVERYTHING = 1,
735   NDMDA_RECO_ACQUIRE_SEARCHING,
736   NDMDA_RECO_ACQUIRE_MATCHING
737 };
738 
739 enum ndm_data_recovery_disposition
740 {
741   NDMDA_RECO_DISPOSITION_PASS = 1,
742   NDMDA_RECO_DISPOSITION_DISCARD
743 };
744 
745 
746 struct ndm_data_agent {
747   int32_t protocol_version;
748 
749   char bu_type[32];
750   struct ndm_env_table env_tab;
751   struct ndm_nlist_table nlist_tab;
752 
753   NDM_FLAG_DECL(enable_hist)
754   uint64_t pass_resid;
755 
756   ndmp9_data_get_state_reply data_state;
757   int32_t data_notify_pending;
758 
759   struct ndmchan formatter_image; /* stdin/out */
760   struct ndmchan formatter_error; /* stderr */
761   struct ndmchan formatter_wrap;  /* fd=3 */
762   int32_t formatter_pid;
763 
764   char* fmt_image_buf;
765   char* fmt_error_buf;
766   char* fmt_wrap_buf;
767 
768   struct ndmfhheap fhh;
769   uint32_t* fhh_buf;
770 
771 #ifdef NDMOS_MACRO_DATA_AGENT_ADDITIONS
772   NDMOS_MACRO_DATA_AGENT_ADDITIONS
773 #endif /* NDMOS_MACRO_DATA_AGENT_ADDITIONS */
774 };
775 
776 
777 /* ndma_data.c */
778 extern int ndmda_initialize(struct ndm_session* sess);
779 extern int ndmda_commission(struct ndm_session* sess);
780 extern int ndmda_decommission(struct ndm_session* sess);
781 extern int ndmda_destroy(struct ndm_session* sess);
782 extern int ndmda_belay(struct ndm_session* sess);
783 
784 extern ndmp9_error ndmda_data_start_backup(struct ndm_session* sess);
785 extern ndmp9_error ndmda_data_start_recover(struct ndm_session* sess);
786 extern ndmp9_error ndmda_data_start_recover_fh(struct ndm_session* sess);
787 
788 extern void ndmda_sync_state(struct ndm_session* sess);
789 extern ndmp9_error ndmda_data_listen(struct ndm_session* sess);
790 extern ndmp9_error ndmda_data_connect(struct ndm_session* sess);
791 extern void ndmda_data_abort(struct ndm_session* sess);
792 extern void ndmda_sync_environment(struct ndm_session* sess);
793 extern void ndmda_data_halt(struct ndm_session* sess,
794                             ndmp9_data_halt_reason reason);
795 extern void ndmda_data_stop(struct ndm_session* sess);
796 
797 extern int ndmda_quantum(struct ndm_session* sess);
798 extern int ndmda_quantum_image(struct ndm_session* sess);
799 extern int ndmda_quantum_stderr(struct ndm_session* sess);
800 extern int ndmda_quantum_wrap(struct ndm_session* sess);
801 
802 extern int ndmda_wrap_in(struct ndm_session* sess, char* wrap_line);
803 
804 extern void ndmda_send_logmsg(struct ndm_session* sess, char* fmt, ...);
805 
806 extern void ndmda_send_notice(struct ndm_session* sess);
807 extern void ndmda_send_data_read(struct ndm_session* sess,
808                                  uint64_t offset,
809                                  uint64_t length);
810 
811 extern int ndmda_copy_environment(struct ndm_session* sess,
812                                   ndmp9_pval* env,
813                                   unsigned n_env);
814 extern struct ndmp9_pval* ndmda_find_env(struct ndm_session* sess, char* name);
815 
816 extern int ndmda_interpret_boolean_value(char* value_str,
817                                          int32_t default_value);
818 
819 extern void ndmda_purge_environment(struct ndm_session* sess);
820 
821 extern int ndmda_copy_nlist(struct ndm_session* sess,
822                             ndmp9_name* nlist,
823                             unsigned n_nlist);
824 extern void ndmda_purge_nlist(struct ndm_session* sess);
825 extern int ndmda_count_invalid_fh_info(struct ndm_session* sess);
826 extern int ndmda_count_invalid_fh_info_pending(struct ndm_session* sess);
827 
828 /* in ndma_data_recover.c */
829 extern int ndmda_quantum_recover_common(struct ndm_session* sess);
830 extern int ndmda_reco_state_start(struct ndm_session* sess);
831 extern int ndmda_reco_pass_thru(struct ndm_session* sess);
832 extern int ndmda_reco_state_pass_thru(struct ndm_session* sess);
833 extern int ndmda_reco_state_choose_nlent(struct ndm_session* sess);
834 extern int ndmda_reco_state_acquire(struct ndm_session* sess);
835 extern int ndmda_reco_state_dispose(struct ndm_session* sess);
836 extern int ndmda_reco_state_finish_nlent(struct ndm_session* sess);
837 extern int ndmda_reco_state_all_done(struct ndm_session* sess);
838 extern int ndmda_reco_assess_channels(struct ndm_session* sess);
839 extern int ndmda_reco_assess_intervals(struct ndm_session* sess);
840 extern int ndmda_reco_align_to_wanted(struct ndm_session* sess);
841 extern int ndmda_reco_obtain_wanted(struct ndm_session* sess);
842 extern int ndmda_reco_send_data_read(struct ndm_session* sess,
843                                      uint64_t offset,
844                                      uint64_t length);
845 extern int ndmda_reco_internal_error(struct ndm_session* sess, char* why);
846 
847 /* ndma_data_fh.c */
848 extern int ndmda_fh_initialize(struct ndm_session* sess);
849 extern int ndmda_fh_commission(struct ndm_session* sess);
850 extern int ndmda_fh_decommission(struct ndm_session* sess);
851 extern int ndmda_fh_destroy(struct ndm_session* sess);
852 extern int ndmda_fh_belay(struct ndm_session* sess);
853 extern void ndmda_fh_add_file(struct ndm_session* sess,
854                               ndmp9_file_stat* filestat,
855                               char* name);
856 extern void ndmda_fh_add_dir(struct ndm_session* sess,
857                              uint64_t dir_fileno,
858                              char* name,
859                              uint64_t fileno);
860 extern void ndmda_fh_add_node(struct ndm_session* sess,
861                               ndmp9_file_stat* filestat);
862 
863 extern int ndmda_fh_prepare(struct ndm_session* sess,
864                             int vers,
865                             int msg,
866                             int entry_size,
867                             unsigned n_item,
868                             unsigned total_size_of_items);
869 extern void ndmda_fh_flush(struct ndm_session* sess);
870 
871 /* ndma_data_pfe.c (pipe-fork-exec) */
872 extern int ndmda_pipe_fork_exec(struct ndm_session* sess,
873                                 char* cmd,
874                                 int is_backup);
875 extern int ndmda_add_to_cmd_with_escapes(char* cmd, char* word, char* special);
876 extern int ndmda_add_to_cmd(char* cmd, char* word);
877 extern int ndmda_add_to_cmd_allow_file_wildcards(char* cmd, char* word);
878 
879 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
880 
881 
882 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
883 /*
884  * TAPE AGENT
885  ****************************************************************
886  */
887 
888 struct ndm_tape_agent {
889   int protocol_version;
890 
891   /* TAPE */
892   ndmp9_tape_get_state_reply tape_state;
893 
894   /* MOVER */
895   ndmp9_mover_get_state_reply mover_state;
896   uint32_t mover_window_first_blockno;
897   uint64_t mover_window_end;
898   uint64_t mover_want_pos;
899   int mover_notify_pending;
900 
901   int pending_change_after_drain;
902   ndmp9_mover_state pending_mover_state;
903   ndmp9_mover_halt_reason pending_mover_halt_reason;
904   ndmp9_mover_pause_reason pending_mover_pause_reason;
905 
906   char* tape_buffer;
907   uint32_t tb_blockno;
908 
909 #ifdef NDMOS_MACRO_TAPE_AGENT_ADDITIONS
910   NDMOS_MACRO_TAPE_AGENT_ADDITIONS
911 #endif /* NDMOS_MACRO_DATA_AGENT_ADDITIONS */
912 };
913 
914 #define NDMTA_TAPE_IS_WRITABLE(TA)                       \
915   ((TA)->tape_state.open_mode == NDMP9_TAPE_RDWR_MODE || \
916    (TA)->tape_state.open_mode == NDMP9_TAPE_RAW_MODE)
917 
918 extern int ndmta_initialize(struct ndm_session* sess);
919 extern int ndmta_commission(struct ndm_session* sess);
920 extern int ndmta_decommission(struct ndm_session* sess);
921 extern int ndmta_destroy(struct ndm_session* sess);
922 extern int ndmta_init_mover_state(struct ndm_session* sess);
923 
924 extern void ndmta_mover_sync_state(struct ndm_session* sess);
925 ndmp9_error ndmta_mover_listen(struct ndm_session* sess,
926                                ndmp9_mover_mode mover_mode);
927 ndmp9_error ndmta_mover_connect(struct ndm_session* sess,
928                                 ndmp9_mover_mode mover_mode);
929 extern void ndmta_mover_halt(struct ndm_session* sess,
930                              ndmp9_mover_halt_reason reason);
931 extern void ndmta_mover_pause(struct ndm_session* sess,
932                               ndmp9_mover_pause_reason reason);
933 extern void ndmta_mover_active(struct ndm_session* sess);
934 extern void ndmta_mover_start_active(struct ndm_session* sess);
935 extern void ndmta_mover_stop(struct ndm_session* sess);
936 extern void ndmta_mover_abort(struct ndm_session* sess);
937 extern void ndmta_mover_continue(struct ndm_session* sess);
938 extern void ndmta_mover_close(struct ndm_session* sess);
939 extern void ndmta_mover_read(struct ndm_session* sess,
940                              uint64_t offset,
941                              uint64_t length);
942 
943 extern int ndmta_quantum(struct ndm_session* sess);
944 extern int ndmta_read_quantum(struct ndm_session* sess);
945 extern int ndmta_write_quantum(struct ndm_session* sess);
946 extern void ndmta_mover_send_notice(struct ndm_session* sess);
947 
948 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
949 
950 
951 #ifndef NDMOS_OPTION_NO_ROBOT_AGENT
952 /*
953  * ROBOT AGENT
954  ****************************************************************
955  */
956 
957 struct ndm_robot_agent {
958   int protocol_version;
959 
960   ndmp9_scsi_get_state_reply scsi_state;
961 
962 #ifdef NDMOS_MACRO_ROBOT_AGENT_ADDITIONS
963   NDMOS_MACRO_ROBOT_AGENT_ADDITIONS
964 #endif /* NDMOS_MACRO_ROBOT_AGENT_ADDITIONS */
965 };
966 
967 extern int ndmra_initialize(struct ndm_session* sess);
968 extern int ndmra_commission(struct ndm_session* sess);
969 extern int ndmra_decommission(struct ndm_session* sess);
970 extern int ndmra_destroy(struct ndm_session* sess);
971 
972 /* all semantic operations are done directly to the ndmos_scsi layer */
973 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
974 
975 
976 /*
977  * IMAGE STREAM
978  ****************************************************************
979  */
980 
981 enum ndmis_connect_status
982 {
983   NDMIS_CONN_IDLE = 0,
984   NDMIS_CONN_LISTEN,
985   NDMIS_CONN_ACCEPTED,
986   NDMIS_CONN_CONNECTED,
987   NDMIS_CONN_DISCONNECTED,
988   NDMIS_CONN_CLOSED,
989   NDMIS_CONN_BOTCHED,
990   NDMIS_CONN_REMOTE,
991   NDMIS_CONN_EXCLUDE
992 };
993 typedef enum ndmis_connect_status ndmis_connect_status;
994 
995 struct ndmis_end_point {
996   char* name;
997   ndmis_connect_status connect_status;
998   int transfer_mode;
999   ndmp9_addr_type addr_type;
1000 };
1001 
1002 struct ndmis_remote {
1003   ndmis_connect_status connect_status;
1004   int transfer_mode;
1005   ndmp9_addr local_addr;
1006   ndmp9_addr peer_addr;
1007   ndmp9_addr listen_addr;
1008   struct ndmchan listen_chan;
1009   struct ndmchan sanity_chan;
1010 };
1011 
1012 struct ndm_image_stream {
1013   struct ndmis_end_point data_ep;
1014   struct ndmis_end_point tape_ep;
1015 
1016   struct ndmis_remote remote;
1017 
1018   /* transfer stuff */
1019   int transfer_mode;
1020   struct ndmchan chan;
1021   char* buf;
1022   int buflen;
1023 };
1024 
1025 extern int ndmis_initialize(struct ndm_session* sess);
1026 extern int ndmis_commission(struct ndm_session* sess);
1027 extern int ndmis_decommission(struct ndm_session* sess);
1028 extern int ndmis_destroy(struct ndm_session* sess);
1029 extern int ndmis_belay(struct ndm_session* sess);
1030 
1031 extern int ndmis_quantum(struct ndm_session* sess);
1032 
1033 extern ndmp9_error ndmis_data_listen(struct ndm_session* sess,
1034                                      ndmp9_addr_type addr_type,
1035                                      ndmp9_addr* ret_addr,
1036                                      char* reason);
1037 extern ndmp9_error ndmis_tape_listen(struct ndm_session* sess,
1038                                      ndmp9_addr_type addr_type,
1039                                      ndmp9_addr* ret_addr,
1040                                      char* reason);
1041 extern ndmp9_error ndmis_data_connect(struct ndm_session* sess,
1042                                       ndmp9_addr* addr,
1043                                       char* reason);
1044 extern ndmp9_error ndmis_tape_connect(struct ndm_session* sess,
1045                                       ndmp9_addr* addr,
1046                                       char* reason);
1047 extern int ndmis_data_start(struct ndm_session* sess, int chan_mode);
1048 extern int ndmis_tape_start(struct ndm_session* sess, int chan_mode);
1049 extern int ndmis_data_close(struct ndm_session* sess);
1050 extern int ndmis_tape_close(struct ndm_session* sess);
1051 
1052 
1053 extern ndmp9_error ndmis_audit_data_listen(struct ndm_session* sess,
1054                                            ndmp9_addr_type addr_type,
1055                                            char* reason);
1056 extern ndmp9_error ndmis_audit_tape_listen(struct ndm_session* sess,
1057                                            ndmp9_addr_type addr_type,
1058                                            char* reason);
1059 extern ndmp9_error ndmis_audit_data_connect(struct ndm_session* sess,
1060                                             ndmp9_addr_type addr_type,
1061                                             char* reason);
1062 extern ndmp9_error ndmis_audit_tape_connect(struct ndm_session* sess,
1063                                             ndmp9_addr_type addr_type,
1064                                             char* reason);
1065 
1066 extern ndmp9_error ndmis_audit_ep_listen(struct ndm_session* sess,
1067                                          ndmp9_addr_type addr_type,
1068                                          char* reason,
1069                                          struct ndmis_end_point* mine_ep,
1070                                          struct ndmis_end_point* peer_ep);
1071 
1072 extern ndmp9_error ndmis_audit_ep_connect(struct ndm_session* sess,
1073                                           ndmp9_addr_type addr_type,
1074                                           char* reason,
1075                                           struct ndmis_end_point* mine_ep,
1076                                           struct ndmis_end_point* peer_ep);
1077 
1078 extern ndmp9_error ndmis_ep_listen(struct ndm_session* sess,
1079                                    ndmp9_addr_type addr_type,
1080                                    ndmp9_addr* ret_addr,
1081                                    char* reason,
1082                                    struct ndmis_end_point* mine_ep,
1083                                    struct ndmis_end_point* peer_ep);
1084 
1085 extern ndmp9_error ndmis_ep_connect(struct ndm_session* sess,
1086                                     ndmp9_addr* addr,
1087                                     char* reason,
1088                                     struct ndmis_end_point* mine_ep,
1089                                     struct ndmis_end_point* peer_ep);
1090 
1091 extern int ndmis_ep_close(struct ndm_session* sess,
1092                           struct ndmis_end_point* mine_ep,
1093                           struct ndmis_end_point* peer_ep);
1094 
1095 extern int ndmis_tcp_listen(struct ndm_session* sess,
1096                             struct ndmp9_addr* listen_addr);
1097 extern int ndmis_tcp_accept(struct ndm_session* sess);
1098 extern int ndmis_tcp_connect(struct ndm_session* sess,
1099                              struct ndmp9_addr* connect_addr);
1100 extern int ndmis_tcp_close(struct ndm_session* sess);
1101 
1102 extern int ndmis_tcp_get_local_and_peer_addrs(struct ndm_session* sess);
1103 extern int ndmis_tcp_green_light(struct ndm_session* sess,
1104                                  int sock,
1105                                  ndmis_connect_status new_status);
1106 
1107 
1108 /*
1109  * PLUMBING
1110  ****************************************************************
1111  */
1112 
1113 struct ndm_plumbing {
1114   struct ndmconn* control;
1115   struct ndmconn* data;
1116   struct ndmconn* tape;
1117   struct ndmconn* robot;
1118 
1119   struct ndm_image_stream* image_stream;
1120 };
1121 
1122 
1123 /*
1124  * SESSION
1125  ****************************************************************
1126  */
1127 
1128 struct ndm_session_param {
1129   struct ndmlog log;
1130   char* log_tag;
1131   int log_level;
1132   char* config_file_name;
1133 };
1134 
1135 struct ndm_session {
1136 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
1137   struct ndm_control_agent* control_acb;
1138   struct ndmca_media_callbacks* media_cbs;
1139   struct ndmca_query_callbacks* query_cbs;
1140   struct ndmca_jobcontrol_callbacks* jobcontrol_cbs;
1141 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
1142 #ifndef NDMOS_OPTION_NO_DATA_AGENT
1143   struct ndm_data_agent* data_acb;
1144 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
1145 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
1146   struct ndm_tape_agent* tape_acb;
1147   struct ndm_tape_simulator_callbacks* ntsc;
1148 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
1149 #ifndef NDMOS_OPTION_NO_ROBOT_AGENT
1150   struct ndm_robot_agent* robot_acb;
1151   struct ndm_robot_simulator_callbacks* nrsc;
1152 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
1153 
1154   struct ndm_auth_callbacks* nac;
1155 
1156   struct ndm_plumbing plumb;
1157 
1158   struct ndm_session_param* param;
1159 
1160   /* scratch pad stuff */
1161   ndmp9_config_info* config_info;
1162   char md5_challenge[64]; /* CONNECT_AUTH MD5 */
1163 
1164   NDM_FLAG_DECL(conn_open)
1165   NDM_FLAG_DECL(conn_authorized)
1166   NDM_FLAG_DECL(conn_snooping)
1167   NDM_FLAG_DECL(md5_challenge_valid)
1168   NDM_FLAG_DECL(control_agent_enabled)
1169   NDM_FLAG_DECL(data_agent_enabled)
1170   NDM_FLAG_DECL(tape_agent_enabled)
1171   NDM_FLAG_DECL(robot_agent_enabled)
1172   NDM_FLAG_DECL(dump_media_info)
1173   NDM_FLAG_DECL(error_raised)
1174 
1175   int connect_status;
1176 
1177   /* Void pointer to session specific data the calling process wants to
1178    * associate */
1179   void* session_handle;
1180 
1181 #ifdef NDMOS_MACRO_SESSION_ADDITIONS
1182   NDMOS_MACRO_SESSION_ADDITIONS
1183 #endif /* NDMOS_MACRO_SESSION_ADDITIONS */
1184 };
1185 
1186 
1187 /* ndma_session.c */
1188 extern int ndma_client_session(struct ndm_session* sess,
1189                                struct ndm_job_param* job,
1190                                int swap_connect);
1191 extern int ndma_server_session(struct ndm_session* sess, int control_sock);
1192 extern int ndma_daemon_session(struct ndm_session* sess, int port);
1193 extern int ndma_session_quantum(struct ndm_session* sess, int max_delay_secs);
1194 extern int ndma_session_initialize(struct ndm_session* sess);
1195 extern int ndma_session_commission(struct ndm_session* sess);
1196 extern int ndma_session_decommission(struct ndm_session* sess);
1197 extern int ndma_session_destroy(struct ndm_session* sess);
1198 
1199 
1200 /* ndma_comm_subr.c */
1201 extern void ndmalogf(struct ndm_session* sess,
1202                      char* tag,
1203                      int level,
1204                      char* fmt,
1205                      ...);
1206 extern void ndmalogfv(struct ndm_session* sess,
1207                       char* tag,
1208                       int level,
1209                       char* fmt,
1210                       va_list ap);
1211 
1212 
1213 /*
1214  * Dispatch Version/Reqeust Tables (DVT, DRT)
1215  ****************************************************************
1216  */
1217 
1218 struct ndm_dispatch_request_table {
1219   uint16_t message;
1220   uint16_t flags;
1221   int (*dispatch_request)(/* "dr" for short */
1222                           struct ndm_session* sess,
1223                           struct ndmp_xa_buf* xa,
1224                           struct ndmconn* ref_conn);
1225 };
1226 
1227 struct ndm_dispatch_version_table {
1228   int protocol_version;
1229   struct ndm_dispatch_request_table* dispatch_request_table;
1230 };
1231 
1232 #define NDM_DRT_FLAG_OK_NOT_CONNECTED 0x0001
1233 #define NDM_DRT_FLAG_OK_NOT_AUTHORIZED 0x0002
1234 
1235 
1236 /* ndma_comm_dispatch.c */
1237 extern int ndma_dispatch_request(struct ndm_session* sess,
1238                                  struct ndmp_xa_buf* xa,
1239                                  struct ndmconn* ref_conn);
1240 extern int ndma_dispatch_raise_error(struct ndm_session* sess,
1241                                      struct ndmp_xa_buf* xa,
1242                                      struct ndmconn* ref_conn,
1243                                      ndmp9_error error,
1244                                      char* errstr);
1245 extern int ndma_dispatch_conn(struct ndm_session* sess, struct ndmconn* conn);
1246 extern void ndma_dispatch_ctrl_unexpected(struct ndmconn* conn,
1247                                           struct ndmp_msg_buf* nmb);
1248 extern int ndmta_local_mover_read(struct ndm_session* sess,
1249                                   uint64_t offset,
1250                                   uint64_t length);
1251 extern int ndma_call_no_tattle(struct ndmconn* conn, struct ndmp_xa_buf* xa);
1252 extern int ndma_call(struct ndmconn* conn, struct ndmp_xa_buf* xa);
1253 extern int ndma_send_to_control(struct ndm_session* sess,
1254                                 struct ndmp_xa_buf* xa,
1255                                 struct ndmconn* from_conn);
1256 extern int ndma_tattle(struct ndmconn* conn, struct ndmp_xa_buf* xa, int rc);
1257 extern struct ndm_dispatch_request_table* ndma_drt_lookup(
1258     struct ndm_dispatch_version_table* dvt,
1259     unsigned protocol_version,
1260     unsigned message);
1261 
1262 #define NDMADR_RAISE(ERROR, ERRSTR) \
1263   return ndma_dispatch_raise_error(sess, xa, ref_conn, ERROR, ERRSTR)
1264 
1265 #define NDMADR_RAISE_ILLEGAL_ARGS(ERRSTR) \
1266   NDMADR_RAISE(NDMP9_ILLEGAL_ARGS_ERR, ERRSTR)
1267 #define NDMADR_RAISE_ILLEGAL_STATE(ERRSTR) \
1268   NDMADR_RAISE(NDMP9_ILLEGAL_STATE_ERR, ERRSTR)
1269 
1270 
1271 #define NDMADR_UNIMPLEMENTED_MESSAGE (-1)    /* aka "TODO" */
1272 #define NDMADR_UNSPECIFIED_MESSAGE (-123)    /* no such per specs */
1273 #define NDMADR_UNIMPLEMENTED_VERSION (-1234) /* implementation error */
1274 
1275 
1276 /*
1277  * Operating System Specific
1278  ****************************************************************
1279  * Must be implemented in ndmos_xxx.c
1280  */
1281 
1282 /* from ndma_dispatch_request() in ndma_dispatch.c */
1283 extern int ndmos_dispatch_request(struct ndm_session* sess,
1284                                   struct ndmp_xa_buf* xa,
1285                                   struct ndmconn* ref_conn);
1286 
1287 /* from ndmadr_connect_client_auth() in ndma_dispatch.c */
1288 struct ndm_auth_callbacks {
1289   int (*validate_password)(struct ndm_session* sess, char* name, char* pass);
1290   int (*validate_md5)(struct ndm_session* sess, char* name, char digest[16]);
1291 };
1292 
1293 extern void ndmos_auth_register_callbacks(struct ndm_session* sess,
1294                                           struct ndm_auth_callbacks* callbacks);
1295 extern void ndmos_auth_unregister_callbacks(struct ndm_session* sess);
1296 extern int ndmos_ok_name_password(struct ndm_session* sess,
1297                                   char* name,
1298                                   char* pass);
1299 extern int ndmos_get_md5_challenge(struct ndm_session* sess);
1300 extern int ndmos_ok_name_md5_digest(struct ndm_session* sess,
1301                                     char* name,
1302                                     char digest[16]);
1303 
1304 /* from ndmadr_config_get_{host,server}_info() in ndma_dispatch.c */
1305 extern void ndmos_sync_config_info(struct ndm_session* sess);
1306 
1307 /* from ndma_image_stream.c and ndma_ctrl_conn.c and others */
1308 extern void ndmos_condition_pipe_fd(struct ndm_session* sess, int fd);
1309 extern void ndmos_condition_listen_socket(struct ndm_session* sess, int sock);
1310 extern void ndmos_condition_control_socket(struct ndm_session* sess, int sock);
1311 extern void ndmos_condition_image_stream_socket(struct ndm_session* sess,
1312                                                 int sock);
1313 
1314 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
1315 
1316 struct ndm_tape_simulator_callbacks {
1317   ndmp9_error (*tape_open)(struct ndm_session* sess,
1318                            char* drive_name,
1319                            int will_write);
1320   ndmp9_error (*tape_close)(struct ndm_session* sess);
1321   ndmp9_error (*tape_mtio)(struct ndm_session* sess,
1322                            ndmp9_tape_mtio_op op,
1323                            uint32_t count,
1324                            uint32_t* resid);
1325   ndmp9_error (*tape_write)(struct ndm_session* sess,
1326                             char* buf,
1327                             uint32_t count,
1328                             uint32_t* done_count);
1329   ndmp9_error (*tape_wfm)(struct ndm_session* sess);
1330   ndmp9_error (*tape_read)(struct ndm_session* sess,
1331                            char* buf,
1332                            uint32_t count,
1333                            uint32_t* done_count);
1334 };
1335 
1336 extern void ndmos_tape_register_callbacks(
1337     struct ndm_session* sess,
1338     struct ndm_tape_simulator_callbacks* callbacks);
1339 extern void ndmos_tape_unregister_callbacks(struct ndm_session* sess);
1340 extern int ndmos_tape_initialize(struct ndm_session* sess);
1341 extern ndmp9_error ndmos_tape_open(struct ndm_session* sess,
1342                                    char* drive_name,
1343                                    int will_write);
1344 extern ndmp9_error ndmos_tape_close(struct ndm_session* sess);
1345 extern void ndmos_tape_sync_state(struct ndm_session* sess);
1346 extern ndmp9_error ndmos_tape_mtio(struct ndm_session* sess,
1347                                    ndmp9_tape_mtio_op op,
1348                                    uint32_t count,
1349                                    uint32_t* resid);
1350 extern ndmp9_error ndmos_tape_write(struct ndm_session* sess,
1351                                     char* buf,
1352                                     uint32_t count,
1353                                     uint32_t* done_count);
1354 extern ndmp9_error ndmos_tape_wfm(struct ndm_session* sess);
1355 extern ndmp9_error ndmos_tape_read(struct ndm_session* sess,
1356                                    char* buf,
1357                                    uint32_t count,
1358                                    uint32_t* done_count);
1359 extern ndmp9_error ndmos_tape_execute_cdb(struct ndm_session* sess,
1360                                           ndmp9_execute_cdb_request* request,
1361                                           ndmp9_execute_cdb_reply* reply);
1362 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
1363 
1364 #ifndef NDMOS_OPTION_NO_ROBOT_AGENT
1365 
1366 struct ndm_robot_simulator_callbacks {
1367   ndmp9_error (*scsi_open)(struct ndm_session* sess, char* name);
1368   ndmp9_error (*scsi_close)(struct ndm_session* sess);
1369   ndmp9_error (*scsi_reset)(struct ndm_session* sess);
1370   ndmp9_error (*scsi_execute_cdb)(struct ndm_session* sess,
1371                                   ndmp9_execute_cdb_request* request,
1372                                   ndmp9_execute_cdb_reply* reply);
1373 };
1374 
1375 extern void ndmos_scsi_register_callbacks(
1376     struct ndm_session* sess,
1377     struct ndm_robot_simulator_callbacks* callbacks);
1378 extern void ndmos_scsi_unregister_callbacks(struct ndm_session* sess);
1379 extern int ndmos_scsi_initialize(struct ndm_session* sess);
1380 extern void ndmos_scsi_sync_state(struct ndm_session* sess);
1381 extern void ndmos_scsi_sync_config_info(struct ndm_session* sess);
1382 extern ndmp9_error ndmos_scsi_open(struct ndm_session* sess, char* name);
1383 extern ndmp9_error ndmos_scsi_close(struct ndm_session* sess);
1384 extern ndmp9_error ndmos_scsi_set_target(struct ndm_session* sess);
1385 extern ndmp9_error ndmos_scsi_reset_device(struct ndm_session* sess);
1386 extern ndmp9_error ndmos_scsi_reset_bus(struct ndm_session* sess);
1387 extern ndmp9_error ndmos_scsi_execute_cdb(struct ndm_session* sess,
1388                                           ndmp9_execute_cdb_request* request,
1389                                           ndmp9_execute_cdb_reply* reply);
1390 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
1391 
1392 
1393 /* ndma_noti_calls.c */
1394 #ifndef NDMOS_OPTION_NO_DATA_AGENT
1395 extern int ndma_notify_data_halted(struct ndm_session* sess);
1396 extern int ndma_notify_data_read(struct ndm_session* sess,
1397                                  uint64_t offset,
1398                                  uint64_t length);
1399 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
1400 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
1401 extern int ndma_notify_mover_halted(struct ndm_session* sess);
1402 extern int ndma_notify_mover_paused(struct ndm_session* sess);
1403 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
1404 #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS
1405 extern void ndma_send_logmsg(struct ndm_session* sess,
1406                              ndmp9_log_type ltype,
1407                              struct ndmconn* from_conn,
1408                              char* fmt,
1409                              ...);
1410 
1411 #ifdef __cplusplus
1412 }
1413 #endif
1414 
1415 #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */
1416 
1417 #endif /* BAREOS_NDMP_NDMAGENTS_H_ */
1418