示例#1
0
int
ndmca_monitor_backup_tape_tcp (struct ndm_session *sess)
{
	struct ndm_control_agent *ca = sess->control_acb;
	int			count;
	ndmp9_data_state	ds;
	char *estb;

	ndmalogf (sess, 0, 3, "Monitoring backup");

	for (count = 0; count < 10; count++) {
		ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10);
		if (ndmca_monitor_get_states(sess) < 0)
		    break;

#if 0
		if (count > 2)
			ndmca_mon_show_states(sess);
#endif

		ds = ca->data_state.state;

		estb = ndmca_data_est(ca);

		ndmalogf (sess, 0, 1,
			  "DATA: bytes %lldKB%s",
			  ca->data_state.bytes_processed/1024LL,
			  estb ? estb : "");

		ca->job.bytes_written = ca->data_state.bytes_processed;

		if (ds == NDMP9_DATA_STATE_ACTIVE) {
			count = 0;
			continue;
		}

		/*
		 * If DATA has halted, the show is over.
		 */
		if (ds == NDMP9_DATA_STATE_HALTED) {
			ndmalogf (sess, 0, 2, "Operation done, cleaning up");

			ndmca_monitor_get_post_backup_env (sess);

			return 0;
		}
	}

	ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling");
	return -1;
}
示例#2
0
int
ndmca_monitor_backup (struct ndm_session *sess)
{
	struct ndm_control_agent *ca = sess->control_acb;
	int			count;
	ndmp9_data_state	ds;
	ndmp9_mover_state	ms;
	char *estb;

	if (ca->job.tape_tcp) {
		return ndmca_monitor_backup_tape_tcp(sess);
	}

	ndmalogf (sess, 0, 3, "Monitoring backup");

	for (count = 0; count < 10; count++) {
		ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10);
		if (ndmca_monitor_get_states(sess) < 0)
		    break;

#if 0
		if (count > 2)
			ndmca_mon_show_states(sess);
#endif

		ds = ca->data_state.state;
		ms = ca->mover_state.state;

		estb = ndmca_data_est(ca);

		ndmalogf (sess, 0, 1,
			  "DATA: bytes %lldKB%s  MOVER: written %lldKB record %d",
			  ca->data_state.bytes_processed/1024LL,
			  estb ? estb : "",
			  ca->mover_state.bytes_moved/1024LL,
			  ca->mover_state.record_num);

		ca->job.bytes_written = ca->data_state.bytes_processed;

		if (ds == NDMP9_DATA_STATE_ACTIVE
		 && ms == NDMP9_MOVER_STATE_ACTIVE) {
			count = 0;
			continue;
		}

		/*
		 * Check MOVER for needed tape change during DATA_FLOW_TO_TAPE.
		 * Have to do this before checking DATA. Even if DATA halted,
		 * MOVER may be holding unwritten data. Have to perform
		 * the tape change.
		 */
		if (ms == NDMP9_MOVER_STATE_PAUSED) {
			ndmp9_mover_pause_reason	pr;

			pr = ca->mover_state.pause_reason;

			if (!ca->pending_notify_mover_paused) {
				/* count=count */
				continue;		/* wait for notice */
			}

			ca->pending_notify_mover_paused = 0;

			ndmalogf (sess, 0, 3, "Mover paused, reason=%s",
					ndmp9_mover_pause_reason_to_str (pr));

			/* backups are different then recoverys... When
                         * we reach the end of a window, we signal EOW
                         * except in V2 where we signal EOF. EOM occurs
			 * at EOT (or EOF does).
			 * This is based on reading comments in the email
			 * archives...
			 */
			if ((pr == NDMP9_MOVER_PAUSE_EOM) ||
			    (pr == NDMP9_MOVER_PAUSE_EOW)) {
				if (ndmca_monitor_load_next(sess) == 0) {
					/* count=count */
					continue;	/* Happy */
				}
				/* Something went wrong with tape change. */
			} else if ((sess->plumb.tape->protocol_version <= 2) &&
				   pr == NDMP9_MOVER_PAUSE_EOF) {
				if (ndmca_monitor_load_next(sess) == 0) {
					/* count=count */
					continue;	/* Happy */
				}
				/* Something went wrong with tape change. */
			} else {
				/* All other pause reasons
				 * are critically bogus. */

			}
			ndmalogf (sess, 0, 0,
				"Operation paused w/o remedy, cancelling");
			ndmca_mover_abort (sess);
			return -1;
		}

		/*
		 * If DATA has halted, the show is over.
		 */
		if (ds == NDMP9_DATA_STATE_HALTED) {
			if (ms != NDMP9_MOVER_STATE_HALTED) {
				ndmalogf (sess, 0, 3,
					"DATA halted, MOVER active");
				/*
				 * MOVER still occupied. It might be a
				 * heartbeat away from asking for another
				 * tape. Give it a chance.
				 */
				continue;
			}

			ndmalogf (sess, 0, 2, "Operation done, cleaning up");

			ndmca_monitor_get_post_backup_env (sess);

			return 0;
		}
#if 1
		if (ms == NDMP9_MOVER_STATE_HALTED) {
			if (ds == NDMP9_DATA_STATE_ACTIVE) {
				ndmalogf (sess, 0, 3,
					"MOVER halted, DATA active");
				/*
				 * DATA still occupied.
				 */
				continue;
			}
		}
#endif

		if (ms != NDMP9_MOVER_STATE_ACTIVE && count == 0) {
			/* Not active. Not paused. Something wrong */
			ndmalogf (sess, 0, 0,
				"Operation in unreasonable state, cancelling");
			return -1;
		}
	}

	ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling");
	return -1;
}
示例#3
0
int
ndmca_monitor_recover (struct ndm_session *sess)
{
	struct ndm_control_agent *ca = sess->control_acb;
	int			count, rc;
	ndmp9_data_state	ds;
	ndmp9_mover_state	ms;
	char *estb;
	int last_state_print = 0;

	if (ca->job.tape_tcp) {
		return (ndmca_monitor_recover_tape_tcp(sess));
	}

	ndmalogf (sess, 0, 3, "Monitoring recover");

	for (count = 0; count < 10; count++) {
		if (ca->pending_notify_data_read) {
			ca->pending_notify_data_read = 0;

			rc = ndmca_mover_read (sess,
				ca->last_notify_data_read.offset,
				ca->last_notify_data_read.length);
			if (rc) {
				ndmalogf (sess, 0, 0, "data-read failed");
				return -1;
			}
			if (count < 5)
				continue;
		}

		ndmca_mon_wait_for_something (sess, count <= 1 ? 30 : 10);

		if (ndmca_monitor_get_states(sess) < 0)
		    break;

#if 0
		if (count > 2)
			ndmca_mon_show_states(sess);
#endif

		ds = ca->data_state.state;
		ms = ca->mover_state.state;

		estb = ndmca_data_est(ca);

		if ((ds != NDMP9_DATA_STATE_ACTIVE) ||
		    (ms != NDMP9_MOVER_STATE_ACTIVE) ||
		    ((time(0) - last_state_print) >= 5)) {

		    ndmalogf (sess, 0, 1,
			      "DATA: bytes %lldKB%s  MOVER: read %lldKB record %d",
			      ca->data_state.bytes_processed/1024LL,
			      estb ? estb : "",
			      ca->mover_state.bytes_moved/1024LL,
			      ca->mover_state.record_num);
		    last_state_print = time(0);
		}

		ca->job.bytes_read = ca->data_state.bytes_processed;

		if (ds == NDMP9_DATA_STATE_ACTIVE
		 && ms == NDMP9_MOVER_STATE_ACTIVE) {
			count = 0;
			continue;
		}

		/*
		 * Check MOVER for needed tape change during DATA_FLOW_TO_TAPE.
		 * Have to do this before checking DATA. Even if DATA halted,
		 * MOVER may be holding unwritten data. Have to perform
		 * the tape change.
		 */
		if (ms == NDMP9_MOVER_STATE_PAUSED) {
			ndmp9_mover_pause_reason	pr;

			pr = ca->mover_state.pause_reason;

			if (!ca->pending_notify_mover_paused) {
				/* count=count */
				continue;		/* wait for notice */
			}

			ca->pending_notify_mover_paused = 0;

			ndmalogf (sess, 0, 3, "Mover paused, reason=%s",
					ndmp9_mover_pause_reason_to_str (pr));

			if (((pr == NDMP9_MOVER_PAUSE_EOF) ||
			     (pr == NDMP9_MOVER_PAUSE_SEEK))
			    && (ca->cur_media_ix == ca->job.media_tab.n_media)) {
				/*
				 * Last tape consumed by tape agent.
				 * The DATA agent may be just shy
				 * of done, but there is no way for
				 * us to tell. So, close the
				 * image stream from the TAPE
				 * agent side, thus indicating
				 * EOF to the DATA agent.
				 */
				ndmalogf (sess, 0, 2, "End of tapes");
				ndmca_mover_close (sess);
				/* count=count */
				continue;
			}

			if (pr == NDMP9_MOVER_PAUSE_EOM
			 || pr == NDMP9_MOVER_PAUSE_EOF) {
				if (ndmca_monitor_load_next(sess) == 0) {
					/* count=count */
					continue;	/* Happy */
				}
				/* Something went wrong with tape change. */
			} else if (pr == NDMP9_MOVER_PAUSE_SEEK) {
				if (ndmca_monitor_seek_tape(sess) == 0) {
					/* count=count */
					continue;	/* Happy */
				}
				/* Something went wrong with tape change. */
			} else {
				/* All other pause reasons
				 * are critically bogus. */
			}
			ndmalogf (sess, 0, 0,
				"Operation paused w/o remedy, cancelling");
			ndmca_mover_abort (sess);
			return -1;
		}

		/*
		 * If DATA has halted, the show is over.
		 */
		if (ds == NDMP9_DATA_STATE_HALTED) {
			if (ms != NDMP9_MOVER_STATE_HALTED) {
				ndmalogf (sess, 0, 3,
					"DATA halted, MOVER active");
				/*
				 * MOVER still occupied. It might
				 * figure it out. Then again, it might
				 * be awaiting a MOVER_READ. The NDMP
				 * design does not provide a state
				 * for awaiting MOVER_READ, so we have
				 * to guess.
				 */
				if (count > 0) {
					ndmca_mover_close(sess);
				}
				continue;
			}

			ndmalogf (sess, 0, 2, "Operation done, cleaning up");

			ndmca_monitor_get_post_backup_env (sess);

			return 0;
		}

		if (ms != NDMP9_MOVER_STATE_ACTIVE && count == 0) {
			/* Not active. Not paused. Something wrong */
			ndmalogf (sess, 0, 0,
				"Operation in unreasonable state, cancelling");
			return -1;
		}
	}

	ndmalogf (sess, 0, 0, "Operation monitoring mishandled, cancelling");
	return -1;
}