ndmp9_error ndmda_data_start_recover_fh (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; ndmp9_error error = NDMP9_NO_ERR; char cmd[NDMDA_MAX_CMD]; strcpy (cmd, "wrap_"); strcat (cmd, da->bu_type); ndmda_add_to_cmd (cmd, "-t"); ndmda_add_to_cmd (cmd, "-I#3"); add_env (&da->env_tab, cmd); add_nlist (&da->nlist_tab, cmd); ndma_send_logmsg (sess, NDMP9_LOG_DEBUG, sess->plumb.data, "CMD: %s", cmd); if (ndmda_pipe_fork_exec (sess, cmd, 0) < 0) { return NDMP9_UNDEFINED_ERR; } ndmis_data_start (sess, NDMCHAN_MODE_READ); da->data_state.state = NDMP9_DATA_STATE_ACTIVE; da->data_state.operation = NDMP9_DATA_OP_RECOVER_FILEHIST; return error; }
ndmp9_error ndmda_data_start_backup (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; ndmp9_error error = NDMP9_NO_ERR; char cmd[NDMDA_MAX_CMD]; strcpy (cmd, "wrap_"); strcat (cmd, da->bu_type); if (sess->param->log_level > 0) { char tmpbuf[40]; sprintf(tmpbuf, "-d%d", sess->param->log_level); ndmda_add_to_cmd (cmd, tmpbuf); } ndmda_add_to_cmd (cmd, "-c"); ndmda_add_to_cmd (cmd, "-I#3"); add_env (&da->env_tab, cmd); ndma_send_logmsg (sess, NDMP9_LOG_DEBUG, sess->plumb.data, "CMD: %s", cmd); if (ndmda_pipe_fork_exec (sess, cmd, 1) < 0) { return NDMP9_UNDEFINED_ERR; } ndmis_data_start (sess, NDMCHAN_MODE_WRITE); da->data_state.state = NDMP9_DATA_STATE_ACTIVE; da->data_state.operation = NDMP9_DATA_OP_BACKUP; return error; }
void ndmta_mover_start_active (struct ndm_session *sess) { struct ndm_tape_agent * ta = sess->tape_acb; ndmalogf (sess, 0, 6, "mover going active"); ndma_send_logmsg(sess, NDMP9_LOG_DEBUG, sess->plumb.control, "mover going active"); switch (ta->mover_state.mode) { case NDMP9_MOVER_MODE_READ: ndmis_tape_start (sess, NDMCHAN_MODE_READ); ndmta_mover_active (sess); break; case NDMP9_MOVER_MODE_WRITE: ndmis_tape_start (sess, NDMCHAN_MODE_WRITE); ndmta_mover_active (sess); break; default: ndmalogf (sess, 0, 0, "BOTCH mover listen, unknown mode"); break; } }
void ndmda_send_data_read (struct ndm_session *sess, unsigned long long offset, unsigned long long length) { struct ndm_data_agent * da = sess->data_acb; ndmp9_addr_type addr_type; addr_type = da->data_state.data_connection_addr.addr_type; #if 0 da->reco_read_offset = offset; da->reco_read_length = length; #endif if (NDMP9_ADDR_LOCAL == addr_type) { #ifndef NDMOS_OPTION_NO_TAPE_AGENT if (ndmta_local_mover_read (sess, offset, length) != 0) { ndma_send_logmsg (sess, NDMP9_LOG_ERROR, sess->plumb.data, "local_mover_read failed"); ndmda_data_halt (sess, NDMP9_DATA_HALT_INTERNAL_ERROR); } #else /* !NDMOS_OPTION_NO_TAPE_AGENT */ ndma_send_logmsg (sess, NDMP9_LOG_ERROR, sess->plumb.data, "local_mover_read not configured"); ndmda_data_halt (sess, NDMP9_DATA_HALT_INTERNAL_ERROR); #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */ return; } switch (addr_type) { case NDMP9_ADDR_TCP: ndma_notify_data_read (sess, offset, length); break; default: ndma_send_logmsg (sess, NDMP9_LOG_ERROR, sess->plumb.data, "bogus mover.addr_type"); ndmda_data_halt (sess, NDMP9_DATA_HALT_INTERNAL_ERROR); break; } }
int ndmda_quantum_stderr (struct ndm_session *sess) { struct ndm_data_agent * da = sess->data_acb; struct ndmchan * ch = &da->formatter_error; int did_something = 0; char * p; char * data; char * pend; unsigned n_ready; again: n_ready = ndmchan_n_ready (ch); if (n_ready == 0) return did_something; data = p = &ch->data[ch->beg_ix]; pend = p + n_ready; while (p < pend && *p != '\n') p++; if (p < pend && *p == '\n') { *p++ = 0; ndma_send_logmsg (sess, NDMP9_LOG_NORMAL, sess->plumb.data, "%s", data); ch->beg_ix += p - data; did_something++; goto again; } if (!ch->eof) return did_something; /* content w/o newline, and EOF */ /* p == pend */ if (ch->end_ix >= ch->data_size) { if (data != ch->data) { ndmchan_compress (ch); goto again; } /* that's one huge message */ p--; /* lose last byte */ } ch->data[ch->end_ix++] = '\n'; did_something++; goto again; }
void ndmda_send_logmsg (struct ndm_session *sess, char *fmt, ...) { struct ndmconn * conn = sess->plumb.control; char buf[4096]; va_list ap; va_start (ap, fmt); vsnprintf (buf, sizeof(buf), fmt, ap); va_end (ap); // we don't handle our own messages so don't send them.... if (conn->conn_type == NDMCONN_TYPE_RESIDENT) { ndmalogf(sess, 0, 2, "RESIDENT AGENT LOGMSG: %s", buf); return; } ndma_send_logmsg (sess, buf, conn); }
ndmp9_error ndmos_tape_open (struct ndm_session *sess, char *drive_name, int will_write) { ndmp9_error err; struct ndm_tape_agent * ta = sess->tape_acb; if (ta->tape_fd >= 0) { ndma_send_logmsg(sess, NDMP9_LOG_ERROR, sess->plumb.control, "device simulator is already open"); return NDMP9_DEVICE_OPENED_ERR; } if (sess->ntsc && sess->ntsc->tape_open) { err = sess->ntsc->tape_open(sess, drive_name, will_write); if (err != NDMP9_NO_ERR) return err; } return NDMP9_NO_ERR; }
ndmp9_error ndmos_tape_open (struct ndm_session *sess, char *drive_name, int will_write) { struct ndm_tape_agent * ta = &sess->tape_acb; struct simu_gap gap; struct stat st; int read_only, omode; int rc, fd; char *pos_symlink_name; char pos_buf[32]; off_t pos = -1; if (ta->tape_fd >= 0) { ndma_send_logmsg(sess, NDMP9_LOG_ERROR, sess->plumb.control, "device simulator is already open"); return NDMP9_DEVICE_OPENED_ERR; } if (stat (drive_name, &st) < 0) { return NDMP9_NO_DEVICE_ERR; } read_only = (st.st_mode & 0222) == 0; if (!will_write) { omode = 0; } else { if (read_only) return NDMP9_WRITE_PROTECT_ERR; omode = 2; /* ndmp_write means read/write */ } if (touch_tape_lockfile(drive_name) < 0) return NDMP9_DEVICE_BUSY_ERR; fd = open (drive_name, omode); if (fd < 0) { return NDMP9_PERMISSION_ERR; } pos_symlink_name = g_strdup_printf("%s.pos", drive_name); if (st.st_size == 0) { remove (pos_symlink_name); if (will_write) { gap.magic = SIMU_GAP_MAGIC; gap.rectype = SIMU_GAP_RT_BOT; gap.size = 0; gap.prev_size = 0; if (write (fd, &gap, sizeof gap) < (int)sizeof gap) { close(fd); return NDMP9_IO_ERR; } gap.rectype = SIMU_GAP_RT_EOT; if (write (fd, &gap, sizeof gap) < (int)sizeof gap) { close(fd); return NDMP9_IO_ERR; } lseek (fd, (off_t)0, 0); } else { goto skip_header_check; } } rc = read (fd, &gap, sizeof gap); if (rc != sizeof gap) { close (fd); return NDMP9_NO_TAPE_LOADED_ERR; } #if 1 if (gap.magic != SIMU_GAP_MAGIC) { close (fd); return NDMP9_IO_ERR; } #else if (gap.magic != SIMU_GAP_MAGIC || gap.rectype != SIMU_GAP_RT_BOT || gap.size != 0) { close (fd); return NDMP9_IO_ERR; } #endif rc = readlink (pos_symlink_name, pos_buf, sizeof pos_buf); if (rc > 0) { pos_buf[rc] = 0; pos = strtol (pos_buf, 0, 0); lseek (fd, pos, 0); rc = read (fd, &gap, sizeof gap); if (rc == sizeof gap && gap.magic == SIMU_GAP_MAGIC) { } else { pos = sizeof gap; } lseek (fd, pos, 0); } skip_header_check: remove (pos_symlink_name); g_free(pos_symlink_name); ta->tape_fd = fd; NDMOS_API_BZERO (ta->drive_name, sizeof ta->drive_name); g_strlcpy (ta->drive_name, drive_name, sizeof ta->drive_name); bzero (&ta->tape_state, sizeof ta->tape_state); ta->tape_state.error = NDMP9_NO_ERR; ta->tape_state.state = NDMP9_TAPE_STATE_OPEN; ta->tape_state.open_mode = will_write ? NDMP9_TAPE_RDWR_MODE : NDMP9_TAPE_READ_MODE; ta->tape_state.file_num.valid = NDMP9_VALIDITY_VALID; ta->tape_state.soft_errors.valid = NDMP9_VALIDITY_VALID; ta->tape_state.block_size.valid = NDMP9_VALIDITY_VALID; ta->tape_state.blockno.valid = NDMP9_VALIDITY_VALID; ta->tape_state.total_space.valid = NDMP9_VALIDITY_INVALID; ta->tape_state.space_remain.valid = NDMP9_VALIDITY_INVALID; ta->sent_leom = 0; if (o_tape_limit) { g_assert(o_tape_limit > st.st_size); ta->tape_state.total_space.valid = NDMP9_VALIDITY_VALID; ta->tape_state.total_space.value = o_tape_limit; ta->tape_state.space_remain.valid = NDMP9_VALIDITY_VALID; ta->tape_state.space_remain.value = o_tape_limit - st.st_size; } return NDMP9_NO_ERR; }
int ndmda_wrap_in (struct ndm_session *sess, char *wrap_line) { struct wrap_msg_buf _wmsg, *wmsg = &_wmsg; int rc; ndmp9_file_stat fstat9; NDMOS_MACRO_ZEROFILL (wmsg); rc = wrap_parse_msg (wrap_line, wmsg); if (rc != 0) { ndmalogf (sess, 0, 2, "Malformed wrap: %s", wrap_line); return -1; } switch (wmsg->msg_type) { case WRAP_MSGTYPE_LOG_MESSAGE: ndmalogf (sess, "WRAP", 2, "%s", wmsg->body.log_message.message); ndma_send_logmsg (sess, NDMP9_LOG_NORMAL, sess->plumb.data, "WRAP: %s", wmsg->body.log_message.message); break; case WRAP_MSGTYPE_ADD_FILE: ndmp9_fstat_from_wrap_fstat (&fstat9, &wmsg->body.add_file.fstat); fstat9.fh_info.valid = NDMP9_VALIDITY_VALID; fstat9.fh_info.value = wmsg->body.add_file.fhinfo; ndmda_fh_add_file (sess, &fstat9, wmsg->body.add_file.path); break; case WRAP_MSGTYPE_ADD_DIRENT: ndmda_fh_add_dir (sess, wmsg->body.add_dirent.dir_fileno, wmsg->body.add_dirent.name, wmsg->body.add_dirent.fileno); break; case WRAP_MSGTYPE_ADD_NODE: ndmp9_fstat_from_wrap_fstat (&fstat9, &wmsg->body.add_node.fstat); fstat9.fh_info.valid = NDMP9_VALIDITY_VALID; fstat9.fh_info.value = wmsg->body.add_node.fhinfo; ndmda_fh_add_node (sess, &fstat9); break; case WRAP_MSGTYPE_DATA_READ: ndmda_send_data_read (sess, wmsg->body.data_read.offset, wmsg->body.data_read.length); break; case WRAP_MSGTYPE_ADD_ENV: case WRAP_MSGTYPE_DATA_STATS: case WRAP_MSGTYPE_RECOVERY_RESULT: ndmalogf (sess, 0, 2, "Unimplemented wrap: %s", wrap_line); break; } return 0; }