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"
42 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
44 int ndmca_monitor_backup_tape_tcp (struct ndm_session *sess);
45 int ndmca_monitor_recover_tape_tcp (struct ndm_session *sess);
46 int ndmca_monitor_shutdown_tape_tcp (struct ndm_session *sess);
49 ndmca_op_create_backup (struct ndm_session *sess)
51 struct ndm_control_agent *ca = &sess->control_acb;
54 ca->tape_mode = NDMP9_TAPE_RDWR_MODE;
55 ca->mover_mode = NDMP9_MOVER_MODE_READ;
58 rc = ndmca_backreco_startup (sess);
61 rc = ndmca_data_start_backup (sess);
63 rc = ndmca_monitor_startup (sess);
65 rc = ndmca_monitor_backup (sess);
70 rc = ndmca_monitor_shutdown (sess);
72 ndmca_monitor_shutdown (sess);
74 ndmca_media_tattle (sess);
80 ndmca_op_recover_files (struct ndm_session *sess)
82 struct ndm_control_agent *ca = &sess->control_acb;
85 ca->tape_mode = NDMP9_TAPE_READ_MODE;
86 ca->mover_mode = NDMP9_MOVER_MODE_WRITE;
89 rc = ndmca_backreco_startup (sess);
92 rc = ndmca_data_start_recover (sess);
94 rc = ndmca_monitor_startup (sess);
96 rc = ndmca_monitor_recover (sess);
101 rc = ndmca_monitor_shutdown (sess);
103 ndmca_monitor_shutdown (sess);
106 if (ca->recover_log_file_count > 0) {
107 struct ndm_control_agent *ca = &sess->control_acb;
108 int n_nlist = ca->job.nlist_tab.n_nlist;
110 ndmalogf (sess, 0, 0,
111 "LOG_FILE messages: %d OK, %d ERROR, total %d of %d",
112 ca->recover_log_file_ok,
113 ca->recover_log_file_error,
114 ca->recover_log_file_count,
116 if (ca->recover_log_file_ok < n_nlist) {
120 ndmalogf (sess, 0, 1,
121 "DATA did not report any LOG_FILE messages");
125 if(!ca->job.tape_tcp)
126 ndmca_media_tattle (sess);
132 ndmca_op_recover_fh (struct ndm_session *sess)
134 struct ndm_control_agent *ca = &sess->control_acb;
137 ca->tape_mode = NDMP9_TAPE_READ_MODE;
138 ca->mover_mode = NDMP9_MOVER_MODE_WRITE;
141 rc = ndmca_backreco_startup (sess);
144 rc = ndmca_data_start_recover_filehist (sess);
146 rc = ndmca_monitor_startup (sess);
148 rc = ndmca_monitor_recover (sess);
153 rc = ndmca_monitor_shutdown (sess);
155 ndmca_monitor_shutdown (sess);
157 ndmca_media_tattle (sess);
162 char *ndmca_data_est(struct ndm_control_agent *ca)
165 static char estb_buf[64];
168 if (ca->data_state.est_bytes_remain.valid &&
169 (ca->data_state.est_bytes_remain.value >= 1024)) {
173 ca->data_state.est_bytes_remain.value/1024LL);
181 ndmca_monitor_backup (struct ndm_session *sess)
183 struct ndm_control_agent *ca = &sess->control_acb;
186 ndmp9_mover_state ms;
189 if (ca->job.tape_tcp) {
190 return ndmca_monitor_backup_tape_tcp(sess);
193 ndmalogf (sess, 0, 3, "Monitoring backup");
195 for (count = 0; count < 10; count++) {
196 ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10);
197 if (ndmca_monitor_get_states(sess) < 0)
202 ndmca_mon_show_states(sess);
205 ds = ca->data_state.state;
206 ms = ca->mover_state.state;
208 estb = ndmca_data_est(ca);
210 ndmalogf (sess, 0, 1,
211 "DATA: bytes %lldKB%s MOVER: written %lldKB record %d",
212 ca->data_state.bytes_processed/1024LL,
214 ca->mover_state.bytes_moved/1024LL,
215 ca->mover_state.record_num);
217 if (ds == NDMP9_DATA_STATE_ACTIVE
218 && ms == NDMP9_MOVER_STATE_ACTIVE) {
224 * Check MOVER for needed tape change during DATA_FLOW_TO_TAPE.
225 * Have to do this before checking DATA. Even if DATA halted,
226 * MOVER may be holding unwritten data. Have to perform
229 if (ms == NDMP9_MOVER_STATE_PAUSED) {
230 ndmp9_mover_pause_reason pr;
232 pr = ca->mover_state.pause_reason;
234 if (!ca->pending_notify_mover_paused) {
236 continue; /* wait for notice */
239 ca->pending_notify_mover_paused = 0;
241 ndmalogf (sess, 0, 3, "Mover paused, reason=%s",
242 ndmp9_mover_pause_reason_to_str (pr));
244 /* backups are different then recoverys... When
245 * we reach the end of a window, we signal EOW
246 * except in V2 where we signal EOF. EOM occurs
247 * at EOT (or EOF does).
248 * This is based on reading comments in the email
251 if ((pr == NDMP9_MOVER_PAUSE_EOM) ||
252 (pr == NDMP9_MOVER_PAUSE_EOW)) {
253 if (ndmca_monitor_load_next(sess) == 0) {
255 continue; /* Happy */
257 /* Something went wrong with tape change. */
258 } else if ((sess->plumb.tape->protocol_version <= 2) &&
259 pr == NDMP9_MOVER_PAUSE_EOF) {
260 if (ndmca_monitor_load_next(sess) == 0) {
262 continue; /* Happy */
264 /* Something went wrong with tape change. */
266 /* All other pause reasons
267 * are critically bogus. */
270 ndmalogf (sess, 0, 0,
271 "Operation paused w/o remedy, cancelling");
272 ndmca_mover_abort (sess);
277 * If DATA has halted, the show is over.
279 if (ds == NDMP9_DATA_STATE_HALTED) {
280 if (ms != NDMP9_MOVER_STATE_HALTED) {
281 ndmalogf (sess, 0, 3,
282 "DATA halted, MOVER active");
284 * MOVER still occupied. It might be a
285 * heartbeat away from asking for another
286 * tape. Give it a chance.
291 ndmalogf (sess, 0, 2, "Operation done, cleaning up");
293 ndmca_monitor_get_post_backup_env (sess);
298 if (ms == NDMP9_MOVER_STATE_HALTED) {
299 if (ds == NDMP9_DATA_STATE_ACTIVE) {
300 ndmalogf (sess, 0, 3,
301 "MOVER halted, DATA active");
303 * DATA still occupied.
310 if (ms != NDMP9_MOVER_STATE_ACTIVE && count == 0) {
311 /* Not active. Not paused. Something wrong */
312 ndmalogf (sess, 0, 0,
313 "Operation in unreasonable state, cancelling");
318 ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling");
323 ndmca_monitor_backup_tape_tcp (struct ndm_session *sess)
325 struct ndm_control_agent *ca = &sess->control_acb;
329 struct ndmlog * ixlog = &ca->job.index_log;
330 char * pname = get_pname();
332 ndmalogf (sess, 0, 3, "Monitoring backup");
334 for (count = 0; count < 10; count++) {
335 ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10);
336 if (ndmca_monitor_get_states(sess) < 0)
341 ndmca_mon_show_states(sess);
344 ds = ca->data_state.state;
346 estb = ndmca_data_est(ca);
348 ndmalogf (sess, 0, 1,
349 "DATA: bytes %lldKB%s",
350 ca->data_state.bytes_processed/1024LL,
353 if (strcmp(pname, "amndmjob") == 0) {
354 ndmlogf (ixlog, "DATA SIZE", 0, "%lldKB",
355 ca->data_state.bytes_processed/1024LL);
358 if (ds == NDMP9_DATA_STATE_ACTIVE) {
364 * If DATA has halted, the show is over.
366 if (ds == NDMP9_DATA_STATE_HALTED) {
367 ndmalogf (sess, 0, 2, "Operation done, cleaning up");
369 ndmca_monitor_get_post_backup_env (sess);
375 ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling");
380 ndmca_monitor_get_post_backup_env (struct ndm_session *sess)
382 struct ndm_control_agent *ca = &sess->control_acb;
383 struct ndmlog * ixlog = &ca->job.index_log;
387 rc = ndmca_data_get_env (sess);
388 if (rc && ca->data_state.error == NDMP9_ILLEGAL_STATE_ERR) {
389 ndmalogf (sess, 0, 2, "fetch post backup env failed");
393 ndmalogf (sess, 0, 0, "fetch post backup env failed");
397 for (i = 0; i < ca->job.result_env_tab.n_env; i++) {
398 pv = &ca->job.result_env_tab.env[i];
400 ndmlogf (ixlog, "DE", 0, "%s=%s", pv->name, pv->value);
407 ndmca_monitor_recover (struct ndm_session *sess)
409 struct ndm_control_agent *ca = &sess->control_acb;
412 ndmp9_mover_state ms;
414 int last_state_print = 0;
416 if (ca->job.tape_tcp) {
417 return (ndmca_monitor_recover_tape_tcp(sess));
420 ndmalogf (sess, 0, 3, "Monitoring recover");
422 for (count = 0; count < 10; count++) {
423 if (ca->pending_notify_data_read) {
424 ca->pending_notify_data_read = 0;
426 rc = ndmca_mover_read (sess,
427 ca->last_notify_data_read.offset,
428 ca->last_notify_data_read.length);
430 ndmalogf (sess, 0, 0, "data-read failed");
437 ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10);
439 if (ndmca_monitor_get_states(sess) < 0)
444 ndmca_mon_show_states(sess);
447 ds = ca->data_state.state;
448 ms = ca->mover_state.state;
450 estb = ndmca_data_est(ca);
452 if ((ds != NDMP9_DATA_STATE_ACTIVE) ||
453 (ms != NDMP9_MOVER_STATE_ACTIVE) ||
454 ((time(0) - last_state_print) >= 5)) {
456 ndmalogf (sess, 0, 1,
457 "DATA: bytes %lldKB%s MOVER: read %lldKB record %d",
458 ca->data_state.bytes_processed/1024LL,
460 ca->mover_state.bytes_moved/1024LL,
461 ca->mover_state.record_num);
462 last_state_print = time(0);
465 if (ds == NDMP9_DATA_STATE_ACTIVE
466 && ms == NDMP9_MOVER_STATE_ACTIVE) {
472 * Check MOVER for needed tape change during DATA_FLOW_TO_TAPE.
473 * Have to do this before checking DATA. Even if DATA halted,
474 * MOVER may be holding unwritten data. Have to perform
477 if (ms == NDMP9_MOVER_STATE_PAUSED) {
478 ndmp9_mover_pause_reason pr;
480 pr = ca->mover_state.pause_reason;
482 if (!ca->pending_notify_mover_paused) {
484 continue; /* wait for notice */
487 ca->pending_notify_mover_paused = 0;
489 ndmalogf (sess, 0, 3, "Mover paused, reason=%s",
490 ndmp9_mover_pause_reason_to_str (pr));
492 if (((pr == NDMP9_MOVER_PAUSE_EOF) ||
493 (pr == NDMP9_MOVER_PAUSE_SEEK))
494 && (ca->cur_media_ix+1 == ca->job.media_tab.n_media)) {
496 * Last tape consumed by tape agent.
497 * The DATA agent may be just shy
498 * of done, but there is no way for
499 * us to tell. So, close the
500 * image stream from the TAPE
501 * agent side, thus indicating
502 * EOF to the DATA agent.
504 ndmalogf (sess, 0, 2, "End of tapes");
505 ndmca_mover_close (sess);
510 if (pr == NDMP9_MOVER_PAUSE_EOM
511 || pr == NDMP9_MOVER_PAUSE_EOF) {
512 if (ndmca_monitor_load_next(sess) == 0) {
514 continue; /* Happy */
516 /* Something went wrong with tape change. */
517 } else if (pr == NDMP9_MOVER_PAUSE_SEEK) {
518 if (ndmca_monitor_seek_tape(sess) == 0) {
520 continue; /* Happy */
522 /* Something went wrong with tape change. */
524 /* All other pause reasons
525 * are critically bogus. */
527 ndmalogf (sess, 0, 0,
528 "Operation paused w/o remedy, cancelling");
529 ndmca_mover_abort (sess);
534 * If DATA has halted, the show is over.
536 if (ds == NDMP9_DATA_STATE_HALTED) {
537 if (ms != NDMP9_MOVER_STATE_HALTED) {
538 ndmalogf (sess, 0, 3,
539 "DATA halted, MOVER active");
541 * MOVER still occupied. It might
542 * figure it out. Then again, it might
543 * be awaiting a MOVER_READ. The NDMP
544 * design does not provide a state
545 * for awaiting MOVER_READ, so we have
549 ndmca_mover_close(sess);
554 ndmalogf (sess, 0, 2, "Operation done, cleaning up");
556 ndmca_monitor_get_post_backup_env (sess);
561 if (ms != NDMP9_MOVER_STATE_ACTIVE && count == 0) {
562 /* Not active. Not paused. Something wrong */
563 ndmalogf (sess, 0, 0,
564 "Operation in unreasonable state, cancelling");
569 ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling");
575 ndmca_monitor_recover_tape_tcp (struct ndm_session *sess)
577 struct ndm_control_agent *ca = &sess->control_acb;
581 int last_state_print = 0;
583 ndmalogf (sess, 0, 3, "Monitoring recover");
585 for (count = 0; count < 10; count++) {
587 ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10);
589 if (ndmca_monitor_get_states(sess) < 0)
594 ndmca_mon_show_states(sess);
597 ds = ca->data_state.state;
599 estb = ndmca_data_est(ca);
601 if ((ds != NDMP9_DATA_STATE_ACTIVE) ||
602 ((time(0) - last_state_print) >= 5)) {
604 ndmalogf (sess, 0, 1,
605 "DATA: bytes %lldKB%s MOVER: read %lldKB record %d",
606 ca->data_state.bytes_processed/1024LL,
608 ca->mover_state.bytes_moved/1024LL,
609 ca->mover_state.record_num);
610 last_state_print = time(0);
613 if (ds == NDMP9_DATA_STATE_ACTIVE) {
619 * If DATA has halted, the show is over.
621 if (ds == NDMP9_DATA_STATE_HALTED) {
622 ndmalogf (sess, 0, 2, "Operation done, cleaning up");
624 ndmca_monitor_get_post_backup_env (sess);
631 ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling");
637 ndmca_backreco_startup (struct ndm_session *sess)
639 struct ndm_control_agent *ca = &sess->control_acb;
642 if (!ca->job.tape_tcp)
643 rc = ndmca_op_robot_startup (sess, 1);
646 rc = ndmca_connect_data_agent(sess);
648 ndmconn_destruct (sess->plumb.data);
652 if (ca->job.tape_tcp) {
656 rc = ndmca_connect_tape_agent(sess);
658 ndmconn_destruct (sess->plumb.tape);
662 rc = ndmca_mover_set_record_size (sess);
665 rc = ndmca_media_load_first (sess);
668 ndmca_media_calculate_offsets (sess);
670 if (sess->control_acb.swap_connect &&
671 (sess->plumb.tape->protocol_version >= 3)) {
672 if (sess->plumb.tape->protocol_version < 4) {
673 rc = ndmca_data_listen (sess);
676 rc = ndmca_media_set_window_current (sess);
679 rc = ndmca_media_set_window_current (sess);
682 rc = ndmca_data_listen (sess);
686 if (sess->plumb.tape->protocol_version < 4) {
687 rc = ndmca_mover_listen (sess);
690 rc = ndmca_media_set_window_current (sess);
693 rc = ndmca_media_set_window_current (sess);
696 rc = ndmca_mover_listen (sess);
705 ndmca_monitor_startup (struct ndm_session *sess)
707 struct ndm_control_agent *ca = &sess->control_acb;
709 ndmp9_mover_state ms;
712 ndmalogf (sess, 0, 3, "Waiting for operation to start");
714 if (ca->job.tape_tcp)
717 for (count = 0; count < 10; count++) {
718 if (ndmca_monitor_get_states (sess) < 0)
721 ds = ca->data_state.state;
722 if (!ca->job.tape_tcp)
723 ms = ca->mover_state.state;
725 ms = NDMP9_MOVER_STATE_ACTIVE;
727 if (ds == NDMP9_DATA_STATE_ACTIVE
728 && ms == NDMP9_MOVER_STATE_ACTIVE) {
729 ndmalogf (sess, 0, 1, "Operation started");
733 if (ds == NDMP9_DATA_STATE_HALTED
734 && ms == NDMP9_MOVER_STATE_HALTED) {
735 /* operation finished immediately */
739 if (ds != NDMP9_DATA_STATE_IDLE
740 && ms != NDMP9_MOVER_STATE_IDLE
741 && ms != NDMP9_MOVER_STATE_LISTEN) {
742 ndmalogf (sess, 0, 1,
743 "Operation started in unusual fashion");
747 ndmca_mon_wait_for_something (sess, 2);
750 ndmalogf (sess, 0, 0, "Operation failed to start");
755 * Just make sure things get finished
758 ndmca_monitor_shutdown (struct ndm_session *sess)
760 struct ndm_control_agent *ca = &sess->control_acb;
762 ndmp9_data_halt_reason dhr;
763 ndmp9_mover_state ms;
764 ndmp9_mover_halt_reason mhr;
768 if (ca->job.tape_tcp) {
769 return ndmca_monitor_shutdown_tape_tcp(sess);
771 ndmalogf (sess, 0, 3, "Waiting for operation to halt");
773 for (count = 0; count < 10; count++) {
774 ndmca_mon_wait_for_something (sess, 2);
776 if (ndmca_monitor_get_states (sess) < 0)
781 ndmca_mon_show_states(sess);
784 ds = ca->data_state.state;
785 ms = ca->mover_state.state;
787 if (ds == NDMP9_DATA_STATE_HALTED
788 && ms == NDMP9_MOVER_STATE_HALTED) {
789 dhr = ca->data_state.halt_reason;
790 mhr = ca->mover_state.halt_reason;
795 if (ds != NDMP9_DATA_STATE_HALTED)
796 ndmca_data_abort(sess);
797 if (ms != NDMP9_MOVER_STATE_HALTED)
798 ndmca_mover_abort(sess);
802 if (ca->tape_state.error == NDMP9_NO_ERR) {
803 ndmca_monitor_unload_last_tape (sess);
807 ndmalogf (sess, 0, 0,
808 "Operation did not halt, something wrong");
811 ndmalogf (sess, 0, 2, "Operation halted, stopping");
813 ds = ca->data_state.state;
814 ms = ca->mover_state.state;
815 dhr = ca->data_state.halt_reason;
816 mhr = ca->mover_state.halt_reason;
818 if ((ds == NDMP9_DATA_STATE_HALTED)
819 && (ms == NDMP9_MOVER_STATE_HALTED)) {
820 if ((dhr == NDMP9_DATA_HALT_SUCCESSFUL) &&
821 (mhr == NDMP9_MOVER_HALT_CONNECT_CLOSED)) {
822 /* Successful operation */
823 ndmalogf (sess, 0, 0, "Operation ended OKAY");
826 /* Questionable success */
827 ndmalogf (sess, 0, 0, "Operation ended questionably");
831 ndmalogf (sess, 0, 0, "Operation ended in failure");
835 ndmca_data_stop (sess);
836 ndmca_mover_stop (sess);
838 for (count = 0; count < 10; count++) {
839 if (ndmca_monitor_get_states(sess) < 0)
844 ndmca_mon_show_states(sess);
847 ds = ca->data_state.state;
848 ms = ca->mover_state.state;
850 if (ds == NDMP9_DATA_STATE_IDLE
851 && ms == NDMP9_MOVER_STATE_IDLE) {
857 ndmalogf (sess, 0, 0,
858 "Operation did not stop, something wrong");
866 ndmca_monitor_shutdown_tape_tcp (struct ndm_session *sess)
868 struct ndm_control_agent *ca = &sess->control_acb;
870 ndmp9_data_halt_reason dhr;
874 ndmalogf (sess, 0, 3, "Waiting for operation to halt");
876 for (count = 0; count < 10; count++) {
877 ndmca_mon_wait_for_something (sess, 2);
879 if (ndmca_monitor_get_states (sess) < 0)
884 ndmca_mon_show_states(sess);
887 ds = ca->data_state.state;
889 if (ds == NDMP9_DATA_STATE_HALTED) {
890 dhr = ca->data_state.halt_reason;
895 if (ds != NDMP9_DATA_STATE_HALTED)
896 ndmca_data_abort(sess);
901 ndmalogf (sess, 0, 0,
902 "Operation did not halt, something wrong");
905 ndmalogf (sess, 0, 2, "Operation halted, stopping");
907 ds = ca->data_state.state;
908 dhr = ca->data_state.halt_reason;
910 if (ds == NDMP9_DATA_STATE_HALTED) {
911 if (dhr == NDMP9_DATA_HALT_SUCCESSFUL) {
912 /* Successful operation */
913 ndmalogf (sess, 0, 0, "Operation ended OKAY");
916 /* Questionable success */
917 ndmalogf (sess, 0, 0, "Operation ended questionably");
921 ndmalogf (sess, 0, 0, "Operation ended in failure");
925 ndmca_data_stop (sess);
927 for (count = 0; count < 10; count++) {
928 if (ndmca_monitor_get_states(sess) < 0)
933 ndmca_mon_show_states(sess);
936 ds = ca->data_state.state;
938 if (ds == NDMP9_DATA_STATE_IDLE) {
944 ndmalogf (sess, 0, 0,
945 "Operation did not stop, something wrong");
953 ndmca_monitor_get_states (struct ndm_session *sess)
955 struct ndm_control_agent *ca = &sess->control_acb;
958 if (ndmca_data_get_state (sess) < 0)
960 if (!ca->job.tape_tcp) {
961 if (ndmca_mover_get_state (sess) < 0)
963 ndmca_tape_get_state_no_tattle (sess);
970 ndmca_monitor_load_next (struct ndm_session *sess)
972 struct ndm_control_agent *ca = &sess->control_acb;
975 ndmalogf (sess, 0, 1, "Operation requires next tape");
977 ndmca_media_capture_mover_window (sess);
978 ndmca_media_calculate_offsets (sess);
980 if (ca->tape_mode == NDMP9_TAPE_RDWR_MODE) {
981 if (ca->mover_state.pause_reason != NDMP9_MOVER_PAUSE_EOM)
982 ndmca_media_write_filemarks (sess);
984 ndmalogf (sess, 0, 1, "At EOM, not writing filemarks");
987 rc = ndmca_media_unload_current(sess);
990 rc = ndmca_media_load_next(sess);
993 rc = ndmca_media_set_window_current (sess);
996 rc = ndmca_mover_continue(sess);
999 ndmalogf (sess, 0, 1, "Operation resuming");
1004 /* VERY VERY HARD */
1006 ndmca_monitor_seek_tape (struct ndm_session *sess)
1008 struct ndm_control_agent *ca = &sess->control_acb;
1010 unsigned long long pos;
1012 pos = ca->last_notify_mover_paused.seek_position;
1014 ndmalogf (sess, 0, 1, "Operation requires a different tape");
1016 /* ndmca_media_capture_mover_window (sess); // !!! */
1017 ndmca_media_calculate_offsets (sess);
1019 rc = ndmca_media_unload_current(sess);
1022 rc = ndmca_media_load_seek (sess, pos);
1025 rc = ndmca_media_set_window_current (sess);
1028 rc = ndmca_mover_continue(sess);
1031 ndmalogf (sess, 0, 1, "Operation resuming");
1037 ndmca_monitor_unload_last_tape (struct ndm_session *sess)
1039 struct ndm_control_agent *ca = &sess->control_acb;
1042 if (!ca->media_is_loaded)
1045 ndmca_media_capture_mover_window (sess);
1046 ndmca_media_calculate_offsets (sess);
1048 if (ca->tape_mode == NDMP9_TAPE_RDWR_MODE) {
1049 ndmca_media_write_filemarks (sess);
1052 rc = ndmca_media_unload_current(sess);
1059 ndmca_mon_wait_for_something (struct ndm_session *sess, int max_delay_secs)
1061 struct ndm_control_agent *ca = &sess->control_acb;
1063 int time_ref = time(0) + max_delay_secs;
1065 ndmalogf (sess, 0, 5, "mon_wait_for_something() entered");
1068 delta = time_ref - time(0);
1073 if (ca->pending_notify_data_read) {
1077 if (ca->pending_notify_data_halted) {
1078 /* just used to "wake up" */
1079 ca->pending_notify_data_halted = 0;
1082 if (ca->pending_notify_mover_paused) {
1086 if (ca->pending_notify_mover_halted) {
1087 /* just used to "wake up" */
1088 ca->pending_notify_mover_halted = 0;
1092 ndma_session_quantum (sess, notices ? 0 : delta);
1098 ndmalogf (sess, 0, 5, "mon_wait_for_something() happened, resid=%d",
1103 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */