Exemple #1
0
gboolean
ndmp_connection_mover_listen(
	NDMPConnection *self,
	ndmp9_mover_mode mode,
	ndmp9_addr_type addr_type,
	DirectTCPAddr **addrs)
{
    unsigned int naddrs, i;
    *addrs = NULL;

    g_assert(!self->startup_err);

    NDMP_TRANS(self, ndmp4_mover_listen)
	request->mode = mode;
	request->addr_type = addr_type;
	NDMP_CALL(self);

	if (request->addr_type != reply->connect_addr.addr_type) {
	    g_warning("MOVER_LISTEN addr_type mismatch; got %d", reply->connect_addr.addr_type);
	}

	if (reply->connect_addr.addr_type == NDMP4_ADDR_TCP) {
	    naddrs = reply->connect_addr.ndmp4_addr_u.tcp_addr.tcp_addr_len;
	    *addrs = g_new0(DirectTCPAddr, naddrs+1);
	    for (i = 0; i < naddrs; i++) {
		ndmp4_tcp_addr *na = &reply->connect_addr.ndmp4_addr_u.tcp_addr.tcp_addr_val[i];
		(*addrs)[i].sin.sin_family = AF_INET;
		(*addrs)[i].sin.sin_addr.s_addr = htonl(na->ip_addr);
		SU_SET_PORT(&((*addrs)[i]), na->port);
	    }
	}
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #2
0
gboolean
ndmp_connection_mover_connect(
	NDMPConnection *self,
	ndmp9_mover_mode mode,
	DirectTCPAddr *addrs)
{
    unsigned int naddrs, i;
    ndmp4_tcp_addr *na;

    g_assert(!self->startup_err);

    /* count addrs */
    g_assert(addrs);
    for (naddrs = 0; SU_GET_FAMILY(&addrs[naddrs]) != 0; naddrs++) ;

    /* convert addrs to an ndmp4_tcp_addr */
    na = g_new0(ndmp4_tcp_addr, naddrs);
    for (i = 0; i < naddrs; i++) {
	na[i].ip_addr = ntohl(addrs[i].sin.sin_addr.s_addr);
	na[i].port = SU_GET_PORT(&addrs[i]);
    }


    NDMP_TRANS(self, ndmp4_mover_connect)
	request->mode = mode;
	request->addr.addr_type = NDMP4_ADDR_TCP;
	request->addr.ndmp4_addr_u.tcp_addr.tcp_addr_len = naddrs;
	request->addr.ndmp4_addr_u.tcp_addr.tcp_addr_val = na;
	NDMP_CALL(self);
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #3
0
gboolean
ndmp_connection_tape_get_state(
	NDMPConnection *self,
	guint64 *blocksize,
	guint64 *file_num,
	guint64 *blockno)
{
    g_assert(!self->startup_err);

    NDMP_TRANS_NO_REQUEST(self, ndmp4_tape_get_state)
	NDMP_CALL(self);

	if (reply->unsupported & NDMP4_TAPE_STATE_BLOCK_SIZE_UNS)
	    *blocksize = 0;
	else
	    *blocksize = reply->block_size;

	if (reply->unsupported & NDMP4_TAPE_STATE_FILE_NUM_UNS)
	    *file_num = G_MAXUINT64;
	else
	    *file_num = reply->file_num;

	if (reply->unsupported & NDMP4_TAPE_STATE_BLOCKNO_UNS)
	    *blockno = G_MAXUINT64;
	else
	    *blockno = reply->blockno;

	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #4
0
gboolean
ndmp_connection_mover_close(
	NDMPConnection *self)
{
    g_assert(!self->startup_err);

    NDMP_TRANS_NO_REQUEST(self, ndmp4_mover_close)
	NDMP_CALL(self);
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #5
0
gboolean
ndmp_connection_scsi_open(
	NDMPConnection *self,
	gchar *device)
{
    g_assert(!self->startup_err);

    NDMP_TRANS(self, ndmp4_scsi_open)
	request->device = device;
	NDMP_CALL(self);
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #6
0
gboolean
ndmp_connection_mover_set_record_size(
	NDMPConnection *self,
	guint32 record_size)
{
    g_assert(!self->startup_err);

    NDMP_TRANS(self, ndmp4_mover_set_record_size)
	/* this field is "len" in ndmp4, but "record_size" in ndmp9 */
	request->len = record_size;
	NDMP_CALL(self);
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #7
0
gboolean
ndmp_connection_mover_read(
	NDMPConnection *self,
	guint64 offset,
	guint64 length)
{
    g_assert(!self->startup_err);

    NDMP_TRANS(self, ndmp4_mover_read)
	request->offset = offset;
	request->length = length;
	NDMP_CALL(self);
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #8
0
gboolean
ndmp_connection_tape_open(
	NDMPConnection *self,
	gchar *device,
	ndmp9_tape_open_mode mode)
{
    g_assert(!self->startup_err);

    NDMP_TRANS(self, ndmp4_tape_open)
	request->device = device;
	request->mode = mode;
	NDMP_CALL(self);
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #9
0
gboolean
ndmp_connection_tape_mtio(
	NDMPConnection *self,
	ndmp9_tape_mtio_op tape_op,
	gint count,
	guint *resid_count)
{
    g_assert(!self->startup_err);

    NDMP_TRANS(self, ndmp4_tape_mtio)
	request->tape_op = tape_op;
	request->count = count;
	NDMP_CALL(self);
	*resid_count = reply->resid_count;
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #10
0
gboolean ndmp_connection_mover_get_state(
	NDMPConnection *self,
	ndmp9_mover_state *state,
	guint64 *bytes_moved,
	guint64 *window_offset,
	guint64 *window_length)
{
    g_assert(!self->startup_err);

    NDMP_TRANS_NO_REQUEST(self, ndmp4_mover_get_state)
	NDMP_CALL(self);
	if (state) *state = reply->state;
	if (bytes_moved) *bytes_moved = reply->bytes_moved;
	if (window_offset) *window_offset = reply->window_offset;
	if (window_length) *window_length = reply->window_length;
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #11
0
gboolean
ndmp_connection_tape_read(
	NDMPConnection *self,
	gpointer buf,
	guint64 count,
	guint64 *out_count)
{
    g_assert(!self->startup_err);

    *out_count = 0;

    NDMP_TRANS(self, ndmp4_tape_read)
	request->count = count;
	NDMP_CALL(self);
	*out_count = reply->data_in.data_in_len;
	g_memmove(buf, reply->data_in.data_in_val, *out_count);
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #12
0
gboolean
ndmp_connection_tape_write(
	NDMPConnection *self,
	gpointer buf,
	guint64 len,
	guint64 *count)
{
    g_assert(!self->startup_err);

    *count = 0;

    NDMP_TRANS(self, ndmp4_tape_write)
	request->data_out.data_out_val = buf;
	request->data_out.data_out_len = len;
	NDMP_CALL(self);
	*count = reply->count;
	NDMP_FREE();
    NDMP_END
    return TRUE;
}
Exemple #13
0
int
ndmpd_tar_restore_starter(void *arg)
{
	ndmpd_module_params_t *mod_params = arg;
	int err;
	ndmpd_session_t *session;
	ndmp_lbr_params_t *nlp;

	session = (ndmpd_session_t *)(mod_params->mp_daemon_cookie);
	*(mod_params->mp_module_cookie) = nlp = ndmp_get_nlp(session);
	ndmp_session_ref(session);

	err = ndmpd_tar_restore(session, mod_params, nlp);
	MOD_DONE(mod_params, err);

	/* nlp_params is allocated in start_recover() */
	NDMP_FREE(nlp->nlp_params);

	NS_DEC(nrs);
	ndmp_session_unref(session);
	return (err);
}
Exemple #14
0
/*
 * ndmpd_tar_backup_starter (V2 only)
 *
 * The main backup starter function. It creates a snapshot if necessary
 * and calls ndmp_tar_backup to perform the actual backup. It does the cleanup
 * and release the snapshot at the end.
 */
int
ndmpd_tar_backup_starter(void *arg)
{
	ndmpd_module_params_t *mod_params = arg;
	int err;
	ndmpd_session_t *session;
	ndmp_lbr_params_t *nlp;

	session = (ndmpd_session_t *)(mod_params->mp_daemon_cookie);
	*(mod_params->mp_module_cookie) = nlp = ndmp_get_nlp(session);
	ndmp_session_ref(session);

	err = 0;
	if (fs_is_chkpntvol(nlp->nlp_backup_path) ||
	    fs_is_rdonly(nlp->nlp_backup_path) ||
	    !fs_is_chkpnt_enabled(nlp->nlp_backup_path))
		NLP_SET(nlp, NLPF_CHKPNTED_PATH);
	else {
		NLP_UNSET(nlp, NLPF_CHKPNTED_PATH);
		if (ndmp_create_snapshot(nlp->nlp_backup_path,
		    nlp->nlp_jstat->js_job_name) < 0) {
			MOD_LOG(mod_params,
			    "Error: creating checkpoint on %s\n",
			    nlp->nlp_backup_path);
			/* -1 causes halt reason to become internal error. */
			err = -1;
		}
	}

	NDMP_LOG(LOG_DEBUG, "NLPF_CHKPNTED_PATH: %c",
	    NDMP_YORN(NLP_ISCHKPNTED(nlp)));
	NDMP_LOG(LOG_DEBUG, "err: %d, update %c",
	    err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp)));

	if (err == 0) {
		err = ndmp_get_cur_bk_time(nlp, &nlp->nlp_cdate,
		    nlp->nlp_jstat->js_job_name);
		if (err != 0) {
			NDMP_LOG(LOG_DEBUG, "err %d", err);
		} else {
			log_bk_params_v2(session, mod_params, nlp);
			err = ndmpd_tar_backup(session, mod_params, nlp);
		}
	}

	if (nlp->nlp_bkmap >= 0) {
		(void) dbm_free(nlp->nlp_bkmap);
		nlp->nlp_bkmap = -1;
	}

	if (!NLP_ISCHKPNTED(nlp))
		(void) ndmp_remove_snapshot(nlp->nlp_backup_path,
		    nlp->nlp_jstat->js_job_name);

	NDMP_LOG(LOG_DEBUG, "err %d, update %c",
	    err, NDMP_YORN(NLP_SHOULD_UPDATE(nlp)));

	if (err == 0 && NLP_SHOULD_UPDATE(nlp)) {
		if (ndmpd_put_dumptime(nlp->nlp_backup_path, nlp->nlp_clevel,
		    nlp->nlp_cdate) < 0) {
			err = EPERM;
			MOD_LOG(mod_params,
			    "Error: updating the dumpdates file on %s\n",
			    nlp->nlp_backup_path);
		}
	}

	MOD_DONE(mod_params, err);

	/* nlp_params is allocated in start_backup() */
	NDMP_FREE(nlp->nlp_params);

	NS_DEC(nbk);
	ndmp_session_unref(session);
	return (err);
}
Exemple #15
0
/*
 * ndmpd_tar_restore
 *
 * Restore function that launches TAR reader thread to read from the
 * tape and writes the extracted files/dirs to the filesystem
 */
static int
ndmpd_tar_restore(ndmpd_session_t *session, ndmpd_module_params_t *mod_params,
    ndmp_lbr_params_t *nlp)
{
	char jname[TLM_MAX_BACKUP_JOB_NAME];
	char *rspath;
	int err;
	tlm_commands_t *cmds;
	ndmp_tar_reader_arg_t arg;
	tlm_backup_restore_arg_t tlm_arg;
	ndmp_name *ent;
	pthread_t rdtp, wrtp;
	int i;

	if (mod_params->mp_operation != NDMP_DATA_OP_RECOVER) {
		NDMP_LOG(LOG_DEBUG,
		    "mod_params->mp_operation != NDMP_DATA_OP_RECOVER");
		return (-1);
	}

	if (nlp->nlp_restore_path[0] != '\0')
		rspath = nlp->nlp_restore_path;
	else if (nlp->nlp_restore_bk_path[0] != '\0')
		rspath = nlp->nlp_restore_bk_path;
	else
		rspath = "";

	(void) ndmp_new_job_name(jname);
	if (restore_create_structs(session, jname) < 0)
		return (-1);

	nlp->nlp_jstat->js_start_ltime = time(NULL);
	nlp->nlp_jstat->js_start_time = time(NULL);

	if (!session->ns_data.dd_abort) {
		cmds = &nlp->nlp_cmds;
		cmds->tcs_reader = cmds->tcs_writer = TLM_RESTORE_RUN;
		cmds->tcs_command->tc_reader = TLM_RESTORE_RUN;
		cmds->tcs_command->tc_writer = TLM_RESTORE_RUN;

		NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" started.", rspath);
		NDMP_LOG(LOG_DEBUG, "Restoring from %s tape(s).",
		    ndmp_data_get_mover_mode(session));

		arg.tr_session = session;
		arg.tr_mod_params = mod_params;
		arg.tr_cmds = cmds;

		err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader,
		    (void *)&arg);
		if (err == 0) {
			tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER);
		} else {
			NDMP_LOG(LOG_DEBUG, "Launch ndmp_tar_reader: %m");
			return (-1);
		}

		if (!ndmp_check_utf8magic(cmds->tcs_command)) {
			NDMP_LOG(LOG_DEBUG, "UTF8Magic not found!");
		} else {
			NDMP_LOG(LOG_DEBUG, "UTF8Magic found");
		}

		(void) memset(&tlm_arg, 0, sizeof (tlm_backup_restore_arg_t));
		(void) pthread_barrier_init(&tlm_arg.ba_barrier, 0, 2);

		/*
		 * Set up restore parameters
		 */
		tlm_arg.ba_commands = cmds;
		tlm_arg.ba_cmd = cmds->tcs_command;
		tlm_arg.ba_job = nlp->nlp_jstat->js_job_name;
		tlm_arg.ba_dir = nlp->nlp_restore_path;
		for (i = 0; i < nlp->nlp_nfiles; i++) {
			ent = (ndmp_name *)MOD_GETNAME(mod_params, i);
			tlm_arg.ba_sels[i] = ent->name;
		}


		if (tm_tar_ops.tm_getfile != NULL) {
			err = pthread_create(&wrtp, NULL,
			    (funct_t)tm_tar_ops.tm_getfile, (void *)&tlm_arg);
		} else {
			(void) pthread_barrier_destroy(&tlm_arg.ba_barrier);
			NDMP_LOG(LOG_DEBUG,
			    "Thread create tm_getfile: ops NULL");
			return (-1);
		}
		if (err == 0) {
			(void) pthread_barrier_wait(&tlm_arg.ba_barrier);
		} else {
			(void) pthread_barrier_destroy(&tlm_arg.ba_barrier);
			NDMP_LOG(LOG_DEBUG, "thread create tm_getfile: %m");
			return (-1);
		}

		(void) pthread_join(rdtp, NULL);
		(void) pthread_join(wrtp, NULL);
		(void) pthread_barrier_destroy(&tlm_arg.ba_barrier);

		nlp->nlp_jstat->js_stop_time = time(NULL);

		/* Send the list of un-recovered files/dirs to the client.  */
		(void) send_unrecovered_list(mod_params, nlp);

		ndmp_stop_local_reader(session, cmds);
		ndmp_wait_for_reader(cmds);
		ndmp_stop_remote_reader(session);
		NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" finished. (%d)",
		    rspath, err);
	} else {
		nlp->nlp_jstat->js_stop_time = time(NULL);

		/* nothing restored. */
		(void) send_unrecovered_list(mod_params, nlp);
		NDMP_LOG(LOG_DEBUG, "Restoring to \"%s\" aborted.",
		    rspath);
		err = -1;
	}

	NDMP_FREE(nlp->nlp_restore_path);
	backup_release_structs(session);

	return (err);
}
Exemple #16
0
gboolean
ndmp_connection_scsi_execute_cdb(
	NDMPConnection *self,
	guint32 flags, /* NDMP4_SCSI_DATA_{IN,OUT}; OUT = to device */
	guint32 timeout, /* in ms */
	gpointer cdb,
	gsize cdb_len,
	gpointer dataout,
	gsize dataout_len,
	gsize *actual_dataout_len, /* output */
	gpointer datain, /* output */
	gsize datain_max_len, /* output buffer size */
	gsize *actual_datain_len, /* output */
	guint8 *status, /* output */
	gpointer ext_sense, /* output */
	gsize ext_sense_max_len, /* output buffer size */
	gsize *actual_ext_sense_len /* output */
	)
{
    g_assert(!self->startup_err);

    if (status)
	*status = 0;
    if (actual_dataout_len)
	*actual_dataout_len = 0;
    if (actual_datain_len)
	*actual_datain_len = 0;
    if (actual_ext_sense_len)
	*actual_ext_sense_len = 0;

    NDMP_TRANS(self, ndmp4_scsi_execute_cdb)
	request->flags = flags;
	request->timeout = timeout;
	request->datain_len = datain_max_len;
	request->cdb.cdb_len = cdb_len;
	request->cdb.cdb_val = cdb;
	request->dataout.dataout_len = dataout_len;
	request->dataout.dataout_val = dataout;

	NDMP_CALL(self);

	if (status)
	    *status = reply->status;
	if (actual_dataout_len)
	    *actual_dataout_len = reply->dataout_len;

	reply->datain.datain_len = MIN(datain_max_len, reply->datain.datain_len);
	if (actual_datain_len)
	    *actual_datain_len = reply->datain.datain_len;
	if (datain_max_len && datain)
	    g_memmove(datain, reply->datain.datain_val, reply->datain.datain_len);

	reply->ext_sense.ext_sense_len = MIN(ext_sense_max_len, reply->ext_sense.ext_sense_len);
	if (actual_ext_sense_len)
	    *actual_ext_sense_len = reply->ext_sense.ext_sense_len;
	if (ext_sense_max_len && ext_sense)
	    g_memmove(ext_sense, reply->ext_sense.ext_sense_val, reply->ext_sense.ext_sense_len);

	NDMP_FREE();
    NDMP_END
    return TRUE;
}