コード例 #1
0
ファイル: ndma_listmgmt.c プロジェクト: dl5rcw/bareos
/*
 * Env list mgmt.
 *
 * Return a chunk of memory with all entries from the envlist as
 * one big enumeration useable for rpc to use as return value.
 * We allacate the memory and keep the pointer in the table handle
 * which gets freed on destroy of the table.
 */
ndmp9_pval *
ndma_enumerate_env_list (struct ndm_env_table *envtab)
{
	int i;
	struct ndm_env_entry *	entry;

	/*
	 * See if we need to allocate memory or can reuse the memory
	 * already allocated in an earlier call.
	 */
	if (!envtab->enumerate) {
		envtab->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_pval) * envtab->n_env);
		envtab->enumerate_length = envtab->n_env;
	} else if (envtab->enumerate_length != envtab->n_env) {
		NDMOS_API_FREE (envtab->enumerate);
		envtab->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_pval) * envtab->n_env);
		envtab->enumerate_length = envtab->n_env;
	}

	if (!envtab->enumerate) {
		return NULL;
	}
	NDMOS_API_BZERO (envtab->enumerate, sizeof(ndmp9_pval) * envtab->n_env);

	i = 0;
	for (entry = envtab->head; entry; entry = entry->next) {
		memcpy (&envtab->enumerate[i], &entry->pval, sizeof(ndmp9_pval));
		i++;
	}

	return envtab->enumerate;
}
コード例 #2
0
ファイル: ndma_listmgmt.c プロジェクト: dl5rcw/bareos
/*
 * Nlist mgmt.
 *
 * Return a chunk of memory with all entries from the nlist as
 * one big enumeration useable for rpc to use as return value.
 * We allacate the memory and keep the pointer in the table handle
 * which gets freed on destroy of the table.
 */
ndmp9_name *
ndma_enumerate_nlist (struct ndm_nlist_table *nlist)
{
	int i;
	struct ndm_nlist_entry *	entry;

	/*
	 * See if we need to allocate memory or can reuse the memory
	 * already allocated in an earlier call.
	 */
	if (!nlist->enumerate) {
		nlist->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_name) * nlist->n_nlist);
		nlist->enumerate_length = nlist->n_nlist;
	} else if (nlist->enumerate_length != nlist->n_nlist) {
		NDMOS_API_FREE (nlist->enumerate);
		nlist->enumerate = NDMOS_API_MALLOC (sizeof(ndmp9_name) * nlist->n_nlist);
		nlist->enumerate_length = nlist->n_nlist;
	}

	if (!nlist->enumerate) {
		return NULL;
	}
	NDMOS_API_BZERO (nlist->enumerate, sizeof(ndmp9_name) * nlist->n_nlist);

	i = 0;
	for (entry = nlist->head; entry; entry = entry->next) {
		memcpy (&nlist->enumerate[i], &entry->name, sizeof(ndmp9_name));
		i++;
	}

	return nlist->enumerate;
}
コード例 #3
0
ファイル: ndmjob_job.c プロジェクト: TonyChiang/amanda
int
args_to_job_recover_nlist (void)
{
	int		not_found = 0;
	int		i, prefix_len, len;
	char *		dest;

	if (C_chdir) {
		prefix_len = strlen (C_chdir) + 2;
	} else {
		prefix_len = 0;
	}

	for (i = 0; (i < n_file_arg) && (i < NDM_MAX_NLIST); i++) {
	    if (file_arg_new[i]) {
		len = strlen (file_arg_new[i]) + prefix_len + 1;

		dest = NDMOS_API_MALLOC (len);
		*dest = 0;
		if (C_chdir) {
			strcpy (dest, C_chdir);
		}
		if (file_arg_new[i][0] != '/') {
			strcat (dest, "/");
		}
		strcat (dest, file_arg_new[i]);

		normalize_name (file_arg_new[i]);
		normalize_name (file_arg[i]);
		normalize_name (dest);

		nlist[i].original_path = file_arg[i];
		nlist[i].destination_path = dest;
	    } else {
		len = strlen (file_arg[i]) + prefix_len + 1;

		dest = NDMOS_API_MALLOC (len);
		*dest = 0;
		if (C_chdir) {
			strcpy (dest, C_chdir);
		}
		if (file_arg[i][0] != '/') {
			strcat (dest, "/");
		}

		strcat (dest, file_arg[i]);

		normalize_name (file_arg[i]);
		normalize_name (dest);

		nlist[i].original_path = file_arg[i];
		nlist[i].destination_path = dest;
	    }
	}

	return not_found;	/* should ALWAYS be 0 */
}
コード例 #4
0
ファイル: ndma_image_stream.c プロジェクト: dl5rcw/bareos
	END	========== LOCAL ============	END
	POINT					POINT
			REMOTE
#endif




#include "ndmagents.h"


int
ndmis_reinit_remote (struct ndm_session *sess)
{
	struct ndm_image_stream *is = sess->plumb.image_stream;
	struct ndm_tape_agent * ta = sess->tape_acb;

	NDMOS_MACRO_ZEROFILL (&is->remote);

	ndmchan_initialize (&is->remote.listen_chan, "image-stream-listen");
	ndmchan_initialize (&is->remote.sanity_chan, "image-stream-sanity");
	ndmchan_initialize (&is->chan, "image-stream");
	if (!is->buf) {
		is->buflen = ta->mover_state.record_size;
		is->buf = NDMOS_API_MALLOC (is->buflen);
		if (!is->buf) {
			return -1;
		}
		NDMOS_MACRO_ZEROFILL_SIZE (is->buf, is->buflen);
	}
	ndmchan_setbuf (&is->chan, is->buf, is->buflen);

	return 0;
}
コード例 #5
0
static ndmp9_error
scsi_fail_with_sense_code(struct ndm_session *sess,
	    ndmp9_execute_cdb_reply *reply,
	    int status, int sense_key, int asq)
{
	unsigned char ext_sense[] = {
		0x72, /* current errors */
		sense_key & SCSI_SENSE_SENSE_KEY_MASK,
		(asq >> 8) & 0xff,
		(asq     ) & 0xff,
		0,
		0,
		0,
		0 };

	ndmalogf(sess, 0, 3, "sending failure; status=0x%02x sense_key=0x%02x asq=0x%04x",
		    status, sense_key, asq);

	reply->status = status;
	reply->ext_sense.ext_sense_len = sizeof(ext_sense);
	reply->ext_sense.ext_sense_val = NDMOS_API_MALLOC(sizeof(ext_sense));
	NDMOS_API_BCOPY(ext_sense, reply->ext_sense.ext_sense_val, sizeof(ext_sense));

	return NDMP9_NO_ERR;
}
コード例 #6
0
ファイル: ndma_listmgmt.c プロジェクト: dl5rcw/bareos
/*
 * Clone an existing media entry and add it to the Media Table.
 * Return entry if caller want to modify it.
 */
struct ndmmedia *
ndma_clone_media_entry (struct ndm_media_table *mtab, struct ndmmedia *to_clone)
{
	struct ndmmedia *	me;

	if (mtab->n_media >= NDM_MAX_MEDIA)
		return NULL;

	me = NDMOS_API_MALLOC (sizeof(struct ndmmedia));
	if (!me) {
		return NULL;
	}

	memcpy (me, to_clone, sizeof(struct ndmmedia));
	me->index = mtab->n_media + 1;

	me->next = NULL;
	if (mtab->tail) {
		mtab->tail->next = me;
		mtab->tail = me;
	} else {
		mtab->head = me;
		mtab->tail = me;
	}

	mtab->n_media++;

	return me;
}
コード例 #7
0
ファイル: ndma_listmgmt.c プロジェクト: dl5rcw/bareos
/*
 * Media list mgmt.
 *
 * Create a new media entry and add it to the Media Table.
 * Return entry if caller want to modify it.
 */
struct ndmmedia *
ndma_store_media (struct ndm_media_table *mtab, uint16_t element_address)
{
	struct ndmmedia *	me;

	if (mtab->n_media >= NDM_MAX_MEDIA)
		return NULL;

	me = NDMOS_API_MALLOC (sizeof(struct ndmmedia));
	if (!me) {
		return NULL;
	}

	NDMOS_MACRO_ZEROFILL (me);

	me->valid_slot = 1;
	me->slot_addr = element_address;
	me->index = mtab->n_media + 1;

	me->next = NULL;
	if (mtab->tail) {
		mtab->tail->next = me;
		mtab->tail = me;
	} else {
		mtab->head = me;
		mtab->tail = me;
	}

	mtab->n_media++;

	return me;
}
コード例 #8
0
ファイル: ndma_control.c プロジェクト: bareos/bareos
/* Initialize -- Set data structure to know value, ignore current value */
int ndmca_initialize(struct ndm_session* sess)
{
  sess->control_acb = NDMOS_API_MALLOC(sizeof(struct ndm_control_agent));
  if (!sess->control_acb) { return -1; }
  NDMOS_MACRO_ZEROFILL(sess->control_acb);

  return 0;
}
コード例 #9
0
ファイル: ndma_data_fh.c プロジェクト: bareos/bareos
/* Commission -- Get agent ready. Entire session has been initialize()d */
int ndmda_fh_commission(struct ndm_session* sess)
{
  struct ndm_data_agent* da = sess->data_acb;
  struct ndmfhheap* fhh = &da->fhh;

  da->fhh_buf = NDMOS_API_MALLOC(NDMDA_N_FHH_BUF);
  if (!da->fhh_buf) return -1;
  // ndmfhh_commission (fhh, da->fhh_buf, sizeof *da->fhh_buf);
  ndmfhh_commission(fhh, da->fhh_buf, NDMDA_N_FHH_BUF);

  return 0;
}
コード例 #10
0
ファイル: ndma_tape_simulator.c プロジェクト: athompso/bareos
void
ndmos_tape_register_callbacks (struct ndm_session *sess,
  struct ndm_tape_simulator_callbacks *callbacks)
{
	/*
	 * Only allow one register.
	 */
	if (!sess->ntsc) {
		sess->ntsc = NDMOS_API_MALLOC (sizeof(struct ndm_tape_simulator_callbacks));
		memcpy(sess->ntsc, callbacks, sizeof(struct ndm_tape_simulator_callbacks));
	}
}
コード例 #11
0
ファイル: ndml_fhdb.c プロジェクト: bareos/bareos
void ndmfhdb_register_callbacks(struct ndmlog* ixlog,
                                struct ndm_fhdb_callbacks* callbacks)
{
  /*
   * Only allow one register.
   */
  if (!ixlog->nfc) {
    ixlog->nfc = NDMOS_API_MALLOC(sizeof(struct ndm_fhdb_callbacks));
    if (ixlog->nfc) {
      memcpy(ixlog->nfc, callbacks, sizeof(struct ndm_fhdb_callbacks));
    }
  }
}
コード例 #12
0
ファイル: ndma_image_stream.c プロジェクト: dl5rcw/bareos
/* Initialize -- Set data structure to know value, ignore current value */
int
ndmis_initialize (struct ndm_session *sess)
{
	sess->plumb.image_stream = NDMOS_API_MALLOC (sizeof(struct ndm_image_stream));
	if (!sess->plumb.image_stream)
		return -1;
	NDMOS_MACRO_ZEROFILL (sess->plumb.image_stream);
	NDMOS_MACRO_ZEROFILL (&sess->plumb.image_stream->chan);

	ndmis_reinit_remote (sess);

	sess->plumb.image_stream->data_ep.name = "DATA";
	sess->plumb.image_stream->tape_ep.name = "TAPE";

	return 0;
}
コード例 #13
0
ファイル: ndma_data.c プロジェクト: AlD/bareos
/* Initialize -- Set data structure to know value, ignore current value */
int
ndmda_initialize (struct ndm_session *sess)
{
        sess->data_acb = NDMOS_API_MALLOC (sizeof(struct ndm_data_agent));
	if (!sess->data_acb)
		return -1;
        NDMOS_MACRO_ZEROFILL (sess->data_acb);

	sess->data_acb->data_state.state = NDMP9_DATA_STATE_IDLE;
	ndmchan_initialize (&sess->data_acb->formatter_error, "dfp-error");
	ndmchan_initialize (&sess->data_acb->formatter_wrap, "dfp-wrap");
	ndmchan_initialize (&sess->data_acb->formatter_image, "dfp-image");
	ndmda_fh_initialize (sess);

	return 0;
}
コード例 #14
0
ファイル: ndma_tape.c プロジェクト: GnunuX/bareos
/* Initialize -- Set data structure to know value, ignore current value */
int
ndmta_initialize (struct ndm_session *sess)
{
	int			rc;

	sess->tape_acb = NDMOS_API_MALLOC (sizeof(struct ndm_tape_agent));
	if (!sess->tape_acb)
		return -1;
	NDMOS_MACRO_ZEROFILL (sess->tape_acb);

	ndmta_commission (sess);

	rc = ndmos_tape_initialize (sess);
	if (rc) return rc;

	return 0;
}
コード例 #15
0
static ndmp9_error
execute_cdb_inquiry (struct ndm_session *sess,
  ndmp9_execute_cdb_request *request,
  ndmp9_execute_cdb_reply *reply)
{
	unsigned char *cdb = (unsigned char *)request->cdb.cdb_val;
	char *response;
	int response_len;
	char *p;

	/* N.B.: only page code 0 is supported */
	if (request->cdb.cdb_len != 6
	    || request->data_dir != NDMP9_SCSI_DATA_DIR_IN
	    || cdb[1] & 0x01
	    || cdb[2] != 0
	    || request->datain_len < 96
	    || ((cdb[3] << 8) + cdb[4]) < 96)
		return scsi_fail_with_sense_code(sess, reply,
		    SCSI_STATUS_CHECK_CONDITION,
		    SCSI_SENSE_KEY_ILLEGAL_REQUEST,
		    ASQ_INVALID_FIELD_IN_CDB);

	response_len = 96;
	p = response = NDMOS_API_MALLOC(response_len);
	NDMOS_API_BZERO(response, response_len);
	*(p++) = 0x08;  /* media changer */
	*(p++) = 0;	/* RMB=0 */
	*(p++) = 6;	/* VERSION=SPC-4 */
	*(p++) = 2;	/* !NORMACA, !HISUP, RESPONSE DATA FORMAT = 2 */
	*(p++) = 92;	/* remaining bytes */
	*(p++) = 0;	/* lots of flags, all 0 */
	*(p++) = 0;	/* lots of flags, all 0 */
	*(p++) = 0;	/* lots of flags, all 0 */
	NDMOS_API_BCOPY("NDMJOB  ", p, 8); p += 8;
	NDMOS_API_BCOPY("FakeRobot        ", p, 16); p += 16;
	NDMOS_API_BCOPY("1.0 ", p, 4); p += 4;
	/* remainder is zero */

	reply->datain.datain_len = response_len;
	reply->datain.datain_val = response;

	return NDMP9_NO_ERR;
}
コード例 #16
0
ファイル: ndma_listmgmt.c プロジェクト: dl5rcw/bareos
/*
 * Add a new entry to an environment list table.
 * Return entry if caller want to modify it.
 */
struct ndm_env_entry *
ndma_store_env_list (struct ndm_env_table *envtab, ndmp9_pval *pv)
{
	struct ndm_env_entry *	entry;

	if (envtab->n_env >= NDM_MAX_ENV)
		return NULL;

	entry = NDMOS_API_MALLOC (sizeof(struct ndm_env_entry));
	if (!entry)
		return NULL;

	entry->pval.name = NDMOS_API_STRDUP (pv->name);
	if (!entry->pval.name) {
		NDMOS_API_FREE (entry);
		return NULL;
	}

	entry->pval.value = NDMOS_API_STRDUP (pv->value);
	if (!entry->pval.value) {
		NDMOS_API_FREE (entry->pval.name);
		NDMOS_API_FREE (entry);
		return NULL;
	}

	entry->next = NULL;
	if (envtab->tail) {
		envtab->tail->next = entry;
		envtab->tail = entry;
	} else {
		envtab->head = entry;
		envtab->tail = entry;
	}

	envtab->n_env++;

	return entry;
}
コード例 #17
0
ファイル: ndma_control.c プロジェクト: bareos/bareos
int ndmca_control_agent(struct ndm_session* sess)
{
  struct ndm_job_param* job = &sess->control_acb->job;
  int rc = -1;

  if (!sess->control_acb->smc_cb) {
    sess->control_acb->smc_cb = NDMOS_API_MALLOC(sizeof(struct smc_ctrl_block));
    NDMOS_MACRO_ZEROFILL(sess->control_acb->smc_cb);
  }


  switch (job->operation) {
    default:
      ndmalogf(sess, 0, 0, "Job operation invalid");
      break;

    case NDM_JOB_OP_INIT_LABELS:
      rc = ndmca_op_init_labels(sess);
      break;

    case NDM_JOB_OP_LIST_LABELS:
      rc = ndmca_op_list_labels(sess);
      break;

    case NDM_JOB_OP_BACKUP:
      rc = ndmca_op_create_backup(sess);
      break;

    case NDM_JOB_OP_EXTRACT:
      rc = ndmca_op_recover_files(sess);
      break;

    case NDM_JOB_OP_TOC:
      rc = ndmca_op_recover_fh(sess);
      break;

    case NDM_JOB_OP_REMEDY_ROBOT:
      rc = ndmca_op_robot_remedy(sess);
      break;

    case NDM_JOB_OP_QUERY_AGENTS:
      rc = ndmca_op_query(sess);
      break;

    case NDM_JOB_OP_TEST_TAPE:
#ifndef NDMOS_OPTION_NO_TEST_AGENTS
      rc = ndmca_op_test_tape(sess);
#endif
      break;

    case NDM_JOB_OP_TEST_MOVER:
#ifndef NDMOS_OPTION_NO_TEST_AGENTS
      rc = ndmca_op_test_mover(sess);
#endif
      break;

    case NDM_JOB_OP_TEST_DATA:
#ifndef NDMOS_OPTION_NO_TEST_AGENTS
      rc = ndmca_op_test_data(sess);
#endif
      break;

    case NDM_JOB_OP_REWIND_TAPE:
      rc = ndmca_op_rewind_tape(sess);
      break;

    case NDM_JOB_OP_EJECT_TAPE:
      rc = ndmca_op_eject_tape(sess);
      break;

    case NDM_JOB_OP_MOVE_TAPE:
      rc = ndmca_op_move_tape(sess);
      break;

    case NDM_JOB_OP_LOAD_TAPE:
      rc = ndmca_op_load_tape(sess);
      break;

    case NDM_JOB_OP_UNLOAD_TAPE:
      rc = ndmca_op_unload_tape(sess);
      break;

    case NDM_JOB_OP_IMPORT_TAPE:
      rc = ndmca_op_import_tape(sess);
      break;

    case NDM_JOB_OP_EXPORT_TAPE:
      rc = ndmca_op_export_tape(sess);
      break;

    case NDM_JOB_OP_INIT_ELEM_STATUS:
      rc = ndmca_op_init_elem_status(sess);
      break;
  }

  return rc;
}
コード例 #18
0
static ndmp9_error
execute_cdb_read_element_status (struct ndm_session *sess,
  ndmp9_execute_cdb_request *request,
  ndmp9_execute_cdb_reply *reply)
{
	unsigned char *cdb = (unsigned char *)request->cdb.cdb_val;
	struct robot_state rs;
	int min_addr, max_elts;
	char *response;
	int response_len;
	int required_len;
	int num_elts = IE_COUNT + MTE_COUNT + DTE_COUNT + STORAGE_COUNT;
	char *p;

	if (request->cdb.cdb_len != 12
	    || request->data_dir != NDMP9_SCSI_DATA_DIR_IN)
		return scsi_fail_with_sense_code(sess, reply,
		    SCSI_STATUS_CHECK_CONDITION,
		    SCSI_SENSE_KEY_ILLEGAL_REQUEST,
		    ASQ_INVALID_FIELD_IN_CDB);
	min_addr = (cdb[2] << 8) + cdb[3];
	max_elts = (cdb[4] << 8) + cdb[5];
	response_len = (cdb[7] << 16) + (cdb[8] << 8) + cdb[9];

	if (response_len < 8) {
		return scsi_fail_with_sense_code(sess, reply,
		    SCSI_STATUS_CHECK_CONDITION,
		    SCSI_SENSE_KEY_ILLEGAL_REQUEST,
		    ASQ_INVALID_FIELD_IN_CDB);
	}

	/* this is bogus, but we don't allow "partial" status requests */
	if (min_addr > IE_FIRST || max_elts < num_elts) {
		return scsi_fail_with_sense_code(sess, reply,
		    SCSI_STATUS_CHECK_CONDITION,
		    SCSI_SENSE_KEY_ILLEGAL_REQUEST,
		    ASQ_INVALID_FIELD_IN_CDB);
	}

	robot_state_load(sess, &rs);
	robot_state_save(sess, &rs);

	/* calculate the total space required */
	required_len = 8; /* element status data header */
	if (MTE_COUNT) {
		required_len += 8; /* element status page header */
		required_len += 12 * MTE_COUNT; /* element status descriptor w/o tags */
	}
	if (STORAGE_COUNT) {
		required_len += 8; /* element status page header */
		required_len += 84 * STORAGE_COUNT; /* element status descriptor w/ tags */
	}
	if (IE_COUNT) {
		required_len += 8; /* element status page header */
		required_len += 84 * IE_COUNT; /* element status descriptor w/ tags */
	}
	if (DTE_COUNT) {
		required_len += 8; /* element status page header */
		required_len += 84 * DTE_COUNT; /* element status descriptor w/ tags */
	}

	p = response = NDMOS_API_MALLOC(response_len);
	NDMOS_API_BZERO(response, response_len);

	/* write the element status data header */
	*(p++) = IE_FIRST >> 8; /* first element address */
	*(p++) = IE_FIRST & 0xff;
	*(p++) = num_elts >> 8; /* number of elements */
	*(p++) = num_elts & 0xff;
	*(p++) = 0; /* reserved */
	*(p++) = (required_len-8) >> 16; /* remaining byte count of report */
	*(p++) = ((required_len-8) >> 8) & 0xff;
	*(p++) = (required_len-8) & 0xff;

	/* only fill in the rest if we have space */
	if (required_len <= response_len) {
		int i;
		struct {
			int first, count, have_voltags, eltype;
			int empty_flags, full_flags;
			struct element_state *es;
		} page[4] = {
			{ IE_FIRST, IE_COUNT, 1, 3, 0x38, 0x39, &rs.ie[0] },
			{ MTE_FIRST, MTE_COUNT, 0, 1, 0x00, 0x01, &rs.mte[0] },
			{ DTE_FIRST, DTE_COUNT, 1, 4, 0x08, 0x81, &rs.dte[0] },
			{ STORAGE_FIRST, STORAGE_COUNT, 1, 2, 0x08, 0x09, &rs.storage[0] },
		};

		for (i = 0; i < 4; i++) {
			int descr_size = page[i].have_voltags? 84 : 12;
			int totalsize = descr_size * page[i].count;
			int j;

			if (page[i].count == 0)
				continue;

			/* write the page header */
			*(p++) = page[i].eltype;
			*(p++) = page[i].have_voltags? 0xc0 : 0;
			*(p++) = 0;
			*(p++) = descr_size;
			*(p++) = 0; /* reserved */
			*(p++) = totalsize >> 16;
			*(p++) = (totalsize >> 8) & 0xff;
			*(p++) = totalsize & 0xff;

			/* and write each descriptor */
			for (j = 0; j < page[i].count; j++) {
				int elt_addr = page[i].first + j;
				int src_elt = page[i].es[j].source_element;
				unsigned char byte9 = page[i].es[j].medium_type;
				if (src_elt!= 0)
					byte9 |= 0x80; /* SVALID */

				*(p++) = elt_addr >> 8;
				*(p++) = elt_addr & 0xff;
				*(p++) = page[i].es[j].full?
					    page[i].full_flags : page[i].empty_flags;
				*(p++) = 0;
				*(p++) = 0;
				*(p++) = 0;
				*(p++) = 0;
				*(p++) = 0;
				*(p++) = 0;
				*(p++) = byte9;
				*(p++) = src_elt >> 8;
				*(p++) = src_elt & 0xff;

				if (page[i].have_voltags) {
					int k;
					if (page[i].es[j].full) {
						for (k = 0; k < 32; k++) {
							if (!page[i].es[j].pvoltag[k])
								break;
							p[k] = page[i].es[j].pvoltag[k];
						}
						for (k = 0; k < 32; k++) {
							if (!page[i].es[j].avoltag[k])
								break;
							p[k+36] = page[i].es[j].avoltag[k];
						}
					} else {
						for (k = 0; k < 32; k++) {
							p[k] = p[k+36] = ' ';
						}
					}
					p += 72;
				}
			}
		}
	}
コード例 #19
0
static ndmp9_error
execute_cdb_mode_sense_6 (struct ndm_session *sess,
  ndmp9_execute_cdb_request *request,
  ndmp9_execute_cdb_reply *reply)
{
	unsigned char *cdb = (unsigned char *)request->cdb.cdb_val;
	int page, subpage;
	char *response;
	int response_len;
	char *p;

	if (request->cdb.cdb_len != 6
	    || request->data_dir != NDMP9_SCSI_DATA_DIR_IN)
		return scsi_fail_with_sense_code(sess, reply,
		    SCSI_STATUS_CHECK_CONDITION,
		    SCSI_SENSE_KEY_ILLEGAL_REQUEST,
		    ASQ_INVALID_FIELD_IN_CDB);
	page = cdb[2] & 0x3f;
	subpage = cdb[3];

	switch ((page << 8) + subpage) {
	case 0x1D00: /* Element Address Assignment */
		if (request->datain_len < 20 || cdb[4] < 20)
			return scsi_fail_with_sense_code(sess, reply,
			    SCSI_STATUS_CHECK_CONDITION,
			    SCSI_SENSE_KEY_ILLEGAL_REQUEST,
			    ASQ_INVALID_FIELD_IN_CDB);

		response_len = 24;
		p = response = NDMOS_API_MALLOC(response_len);
		NDMOS_API_BZERO(response, response_len);
		*(p++) = response_len;
		*(p++) = 0; /* reserved medium type */
		*(p++) = 0; /* reserved device-specific parameter */
		*(p++) = 0; /* block descriptor length (DBD = 0 above)*/
		*(p++) = 0x1D; /* page code */
		*(p++) = 18; /* remaining bytes */
		*(p++) = (MTE_FIRST >> 8) & 0xff;
		*(p++) = MTE_FIRST & 0xff;
		*(p++) = (MTE_COUNT >> 8) & 0xff;
		*(p++) = MTE_COUNT & 0xff;
		*(p++) = (STORAGE_FIRST >> 8) & 0xff;
		*(p++) = STORAGE_FIRST & 0xff;
		*(p++) = (STORAGE_COUNT >> 8) & 0xff;
		*(p++) = STORAGE_COUNT & 0xff;
		*(p++) = (IE_FIRST >> 8) & 0xff;
		*(p++) = IE_FIRST & 0xff;
		*(p++) = (IE_COUNT >> 8) & 0xff;
		*(p++) = IE_COUNT & 0xff;
		*(p++) = (DTE_FIRST >> 8) & 0xff;
		*(p++) = DTE_FIRST & 0xff;
		*(p++) = (DTE_COUNT >> 8) & 0xff;
		*(p++) = DTE_COUNT & 0xff;
		/* remainder is zero */
		break;

	default:
		return scsi_fail_with_sense_code(sess, reply,
		    SCSI_STATUS_CHECK_CONDITION,
		    SCSI_SENSE_KEY_ILLEGAL_REQUEST,
		    ASQ_INVALID_FIELD_IN_CDB);
	}

	reply->datain.datain_len = response_len;
	reply->datain.datain_val = response;

	return NDMP9_NO_ERR;
}
コード例 #20
0
ファイル: ndma_tape.c プロジェクト: GnunuX/bareos
int
ndmta_write_quantum (struct ndm_session *sess)
{
	struct ndm_tape_agent *	ta = sess->tape_acb;
	struct ndmchan *	ch = &sess->plumb.image_stream->chan;
	uint32_t		count = ta->mover_state.record_size;
	int			did_something = 0;
	uint64_t		max_read;
	uint64_t		want_window_off;
	uint32_t		block_size;
	uint32_t		want_blockno;
	uint32_t		cur_blockno;
	unsigned		n_avail, n_read, record_off;
	char *			data;
	uint32_t		done_count = 0;
	ndmp9_error		error;

  again:
	n_read = n_avail = ndmchan_n_avail_record (ch, count);
	if (n_avail < count) {
		/* allow to drain */
		return did_something;
	}

	if (ta->pending_change_after_drain) {
		if (ndmchan_n_ready (ch) > 0) {
			/* allow to drain */
		} else {
			ndmta_mover_apply_pending (sess);
			did_something++;
		}
		return did_something;
	}

	if (n_read > ta->mover_state.bytes_left_to_read)
		n_read = ta->mover_state.bytes_left_to_read;

	if (n_read < count) {
		/* Active, but paused awaiting MOVER_READ request */
		return did_something;	/* mover blocked */
	}

	if (ta->mover_want_pos < ta->mover_state.window_offset
	 || ta->mover_want_pos >= ta->mover_window_end) {
		ndmta_mover_pause_pending (sess, NDMP9_MOVER_PAUSE_SEEK);
		goto again;
	}

	max_read = ta->mover_window_end - ta->mover_want_pos;
	if (n_read > max_read)
		n_read = max_read;

	want_window_off = ta->mover_want_pos - ta->mover_state.window_offset;

	/* make an estimate of the block size - the tape agent's block size, or
	 * if it's in variable block size mode, the mover's record size: "When
	 * in variable block mode, as indicated by a tape block_size value of
	 * zero, the mover record size defines the actual block size used by
	 * the tape subsystem." (NDMPv4 RFC, Section 3.6.2.1) */
	block_size = ta->tape_state.block_size.value;
	if (!block_size)
		block_size = ta->mover_state.record_size;

	want_blockno = ta->mover_window_first_blockno + want_window_off / block_size;

	if (ta->tb_blockno != want_blockno) {
		uint32_t	xsr_count, xsr_resid;

		ndmos_tape_sync_state(sess);
		cur_blockno = ta->tape_state.blockno.value;
		if (cur_blockno < want_blockno) {
			xsr_count = want_blockno - cur_blockno;
			error = ndmos_tape_mtio (sess, NDMP9_MTIO_FSR,
						xsr_count, &xsr_resid);
			if (error == NDMP9_EOF_ERR) {
				ndmta_mover_pause_pending (sess,
						NDMP9_MOVER_PAUSE_EOF);
				goto again;
			}
			if (error != NDMP9_NO_ERR) {
				ndmta_mover_halt_pending (sess,
						NDMP9_MOVER_HALT_MEDIA_ERROR);
				goto again;
			}
			if (xsr_resid > 0) {
				ndmta_mover_pause_pending (sess,
						NDMP9_MOVER_PAUSE_EOF);
				goto again;
			}
		} else if (cur_blockno > want_blockno) {
			xsr_count = cur_blockno - want_blockno;
			error = ndmos_tape_mtio (sess, NDMP9_MTIO_BSR,
						xsr_count, &xsr_resid);
			if (error != NDMP9_NO_ERR || xsr_resid > 0) {
				ndmta_mover_halt_pending (sess,
						NDMP9_MOVER_HALT_MEDIA_ERROR);
				goto again;
			}
		} else {
			/* in position */
		}

		/*
		 * We are about to read data into a tape buffer so make sure
		 * we have it available. We delay allocating buffers to the
		 * moment we first need them.
		 */
		if (!ta->tape_buffer) {
			ta->tape_buffer = NDMOS_API_MALLOC (NDMOS_CONST_TAPE_REC_MAX);
			if (!ta->tape_buffer) {
				ndmta_mover_pause_pending (sess,
							NDMP9_MOVER_HALT_NA);
				goto again;
			}
		}

		data = ta->tape_buffer;
		done_count = 0;
		error = ndmos_tape_read (sess, data, count, &done_count);
		did_something++;

		if (error == NDMP9_EOF_ERR) {
			ndmta_mover_pause_pending (sess,
						NDMP9_MOVER_PAUSE_EOF);
			goto again;
		}
		/* N.B. - handling of done_count = 0 here is hacked to support
		 * non-blocking writes to a socket in amndmjob */
		if (error != NDMP9_NO_ERR) {
			ndmta_mover_halt_pending (sess,
				NDMP9_MOVER_HALT_MEDIA_ERROR);
			goto again;
		}
		if (done_count == 0) {
			return did_something - 1;
		}
		if (done_count != count) {
			goto again;
		}
		ta->tb_blockno = want_blockno;
		/* re-calcluate this, since record_size may be > block_size, in which
		 * case the record_num may not change for each block read from tape */
		ta->mover_state.record_num = ta->mover_want_pos / ta->mover_state.record_size;
	}

	record_off = ta->mover_want_pos % ta->mover_state.record_size;

	n_avail = ta->mover_state.record_size - record_off;
	if (n_read > n_avail)
		n_read = n_avail;
	if (n_read != done_count) {
		printf("lost %lu bytes %lu %u\n", done_count - n_read, done_count, n_read);
		n_read = done_count;
	}

	/*
	 * We are about to read data into a tape buffer so make sure
	 * we have it available. We delay allocating buffers to the
	 * moment we first need them.
	 */
	if (!ta->tape_buffer) {
		ta->tape_buffer = NDMOS_API_MALLOC (NDMOS_CONST_TAPE_REC_MAX);
		if (!ta->tape_buffer) {
			ndmta_mover_pause_pending (sess,
						NDMP9_MOVER_HALT_NA);
			goto again;
		}
	}

	data = &ta->tape_buffer[record_off];

	bcopy (data, ch->data + ch->end_ix, n_read);
	ch->end_ix += n_read;
	ta->mover_state.bytes_moved += n_read;
	ta->mover_want_pos += n_read;
	ta->mover_state.bytes_left_to_read -= n_read;

	did_something++;

	goto again;	/* do as much as possible */
}
コード例 #21
0
ファイル: ndma_listmgmt.c プロジェクト: dl5rcw/bareos
/*
 * Add a new entry to a nlist list table.
 * Return entry if caller want to modify it.
 */
struct ndm_nlist_entry *
ndma_store_nlist (struct ndm_nlist_table *nlist, ndmp9_name *nl)
{
	struct ndm_nlist_entry *	entry;

	if (nlist->n_nlist >= NDM_MAX_NLIST)
		return NULL;

	entry = NDMOS_API_MALLOC (sizeof(struct ndm_nlist_entry));
	if (!entry)
		return NULL;

	NDMOS_MACRO_ZEROFILL (entry);

	entry->name.original_path = NDMOS_API_STRDUP (nl->original_path);
	if (!entry->name.original_path)
		goto bail_out;

	entry->name.destination_path = NDMOS_API_STRDUP (nl->destination_path);
	if (!entry->name.destination_path)
		goto bail_out;

	entry->name.name = NDMOS_API_STRDUP (nl->name);
	if (!entry->name.name)
		goto bail_out;

	entry->name.other_name = NDMOS_API_STRDUP (nl->other_name);
	if (!entry->name.other_name)
		goto bail_out;

	entry->name.node = nl->node;
	entry->name.fh_info = nl->fh_info;
	entry->result_err = NDMP9_UNDEFINED_ERR;
	entry->result_count = 0;

	entry->next = NULL;
	if (nlist->tail) {
		nlist->tail->next = entry;
		nlist->tail = entry;
	} else {
		nlist->head = entry;
		nlist->tail = entry;
	}

	nlist->n_nlist++;

	return entry;

bail_out:
	if (entry->name.other_name)
		NDMOS_API_FREE (entry->name.other_name);

	if (entry->name.name)
		NDMOS_API_FREE (entry->name.name);

	if (entry->name.destination_path)
		NDMOS_API_FREE (entry->name.destination_path);

	if (entry->name.original_path)
		NDMOS_API_FREE (entry->name.original_path);

	NDMOS_API_FREE (entry);

	return NULL;
}