コード例 #1
0
/*
 * 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);
}
コード例 #2
0
ファイル: tlm_lib.c プロジェクト: mikess/illumos-gate
/*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);
}