/* * ndmp_tar_writer * * The backup writer thread that writes the TAR records to the * tape media (V2 only) */ int ndmp_tar_writer(ndmpd_session_t *session, ndmpd_module_params_t *mod_params, tlm_commands_t *cmds) { int bidx, nw; int err; tlm_buffer_t *buf; tlm_buffers_t *bufs; tlm_cmd_t *lcmd; /* Local command */ err = 0; if (session == NULL) { NDMP_LOG(LOG_DEBUG, "session == NULL"); err = -1; } else if (mod_params == NULL) { NDMP_LOG(LOG_DEBUG, "mod_params == NULL"); err = -1; } else if (cmds == NULL) { NDMP_LOG(LOG_DEBUG, "cmds == NULL"); err = -1; } if (err != 0) return (err); lcmd = cmds->tcs_command; bufs = lcmd->tc_buffers; lcmd->tc_ref++; cmds->tcs_writer_count++; nw = 0; buf = tlm_buffer_out_buf(bufs, &bidx); while (cmds->tcs_writer != (int)TLM_ABORT && lcmd->tc_writer != (int)TLM_ABORT) { if (buf->tb_full) { NDMP_LOG(LOG_DEBUG, "w%d", bidx); if (MOD_WRITE(mod_params, buf->tb_buffer_data, buf->tb_buffer_size) != 0) { NDMP_LOG(LOG_DEBUG, "Writing buffer %d, pos: %lld", bidx, session->ns_mover.md_position); err = -1; break; } tlm_buffer_mark_empty(buf); (void) tlm_buffer_advance_out_idx(bufs); buf = tlm_buffer_out_buf(bufs, &bidx); tlm_buffer_release_out_buf(bufs); nw++; } else { if (lcmd->tc_writer != TLM_BACKUP_RUN) { /* No more data is comming; time to exit. */ NDMP_LOG(LOG_DEBUG, "tc_writer!=TLM_BACKUP_RUN; time to exit"); break; } else { NDMP_LOG(LOG_DEBUG, "W%d", bidx); tlm_buffer_in_buf_timed_wait(bufs, 100); } } } NDMP_LOG(LOG_DEBUG, "nw: %d", nw); if (cmds->tcs_writer != (int)TLM_ABORT) { NDMP_LOG(LOG_DEBUG, "tcs_writer != TLM_ABORT"); } else { NDMP_LOG(LOG_DEBUG, "tcs_writer == TLM_ABORT"); } if (lcmd->tc_writer != (int)TLM_ABORT) { NDMP_LOG(LOG_DEBUG, "tc_writer != TLM_ABORT"); } else { NDMP_LOG(LOG_DEBUG, "tc_writer == TLM_ABORT"); } cmds->tcs_writer_count--; lcmd->tc_reader = TLM_STOP; lcmd->tc_ref--; return (err); }
/*ARGSUSED*/ char * tlm_get_read_buffer(int want, int *error, tlm_buffers_t *buffers, int *actual_size) { tlm_buffer_t *buffer; int align_size = RECORDSIZE - 1; int buf; int current_size; char *rec; buf = buffers->tbs_buffer_out; buffer = &buffers->tbs_buffer[buf]; /* * make sure the allocation is in chunks of 512 bytes */ want += align_size; want &= ~align_size; current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot; if (buffer->tb_full && current_size <= 0) { /* * no more data, release this * one and go get another */ /* * tell the reader that a buffer is available */ buffer->tb_full = FALSE; tlm_buffer_release_out_buf(buffers); buffer = tlm_buffer_advance_out_idx(buffers); current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot; } if (!buffer->tb_full) { /* * next buffer is not full yet. * wait for the reader. */ tlm_buffer_in_buf_timed_wait(buffers, 500); buffer = tlm_buffer_out_buf(buffers, NULL); if (!buffer->tb_full) { /* * we do not have anything from the tape yet */ return (0); } current_size = buffer->tb_buffer_size - buffer->tb_buffer_spot; } /* Make sure we got something */ if (current_size <= 0) return (NULL); current_size = min(want, current_size); rec = &buffer->tb_buffer_data[buffer->tb_buffer_spot]; buffer->tb_buffer_spot += current_size; *actual_size = current_size; /* * the error flag is only sent back one time, * since the flag refers to a previous read * attempt, not the data in this buffer. */ *error = buffer->tb_errno; return (rec); }