예제 #1
0
파일: vtlcart.c 프로젝트: fishky/mhvtl
int format_tape(uint8_t *sam_stat)
{
	if (!tape_loaded(sam_stat))
		return -1;

	if (check_for_overwrite(sam_stat))
		return -1;

	zero_filemark_count();

	return mkEODHeader(raw_pos.hdr.blk_number, raw_pos.data_offset);
}
예제 #2
0
int format_tape(uint8_t *sam_stat)
{
	MHVTL_DBG(1, "format_tape");
	if (!tape_loaded(sam_stat))
		return -1;

	if (check_for_overwrite(sam_stat))
		return -1;

	zero_filemark_count();

	return mkEODHeader(raw_pos.hdr.blk_number);
}
예제 #3
0
파일: vtlcart.c 프로젝트: fishky/mhvtl
int write_tape_block(const uint8_t *buffer, uint32_t blk_size,
		uint32_t comp_size, const struct encryption *encryptp,
		uint8_t comp_type, uint8_t null_media_type, uint8_t *sam_stat)
{
	uint32_t blk_number, disk_blk_size;
	uint32_t max_blk_number;
	uint64_t data_offset;
	ssize_t nwrite;

	/* Medium format limits to unsigned 32bit blks */
	max_blk_number = 0xfffffff0;

	if (!tape_loaded(sam_stat))
		return -1;

	if (check_for_overwrite(sam_stat))
		return -1;

	/* Preserve existing raw_pos data we need, then clear out raw_pos and
	   fill it in with new data.
	*/

	blk_number = raw_pos.hdr.blk_number;
	data_offset = raw_pos.data_offset;

	if (blk_number > max_blk_number) {
		MHVTL_ERR("Too many tape blocks - 32byte overflow");
		return -1;
	}

	memset(&raw_pos, 0, sizeof(raw_pos));

	raw_pos.data_offset = data_offset;

	raw_pos.hdr.blk_type = B_DATA;	/* Header type */
	raw_pos.hdr.blk_flags = 0;
	raw_pos.hdr.blk_number = blk_number;
	raw_pos.hdr.blk_size = blk_size; /* Size of uncompressed data */

	if (comp_size) {
		if (comp_type == LZO)
			raw_pos.hdr.blk_flags |= BLKHDR_FLG_LZO_COMPRESSED;
		else
			raw_pos.hdr.blk_flags |= BLKHDR_FLG_ZLIB_COMPRESSED;
		raw_pos.hdr.disk_blk_size = disk_blk_size = comp_size;
	} else
		raw_pos.hdr.disk_blk_size = disk_blk_size = blk_size;

	if (encryptp != NULL) {
		unsigned int i;

		raw_pos.hdr.blk_flags |= BLKHDR_FLG_ENCRYPTED;
		raw_pos.hdr.encryption.ukad_length = encryptp->ukad_length;
		for (i = 0; i < encryptp->ukad_length; ++i)
			raw_pos.hdr.encryption.ukad[i] = encryptp->ukad[i];

		raw_pos.hdr.encryption.akad_length = encryptp->akad_length;
		for (i = 0; i < encryptp->akad_length; ++i)
			raw_pos.hdr.encryption.akad[i] = encryptp->akad[i];

		raw_pos.hdr.encryption.key_length = encryptp->key_length;
		for (i = 0; i < encryptp->key_length; ++i)
			raw_pos.hdr.encryption.key[i] = encryptp->key[i];
	}

	/* Now write out both the data and the header. */
	if (null_media_type) {
		nwrite = disk_blk_size;
	} else
		nwrite = pwrite(datafile, buffer, disk_blk_size, data_offset);
	if (nwrite != disk_blk_size) {
		sam_medium_error(E_WRITE_ERROR, sam_stat);

		MHVTL_ERR("Data file write failure, pos: %" PRId64 ": %s",
			data_offset, strerror(errno));

		/* Truncate last partital write */
		MHVTL_DBG(1, "Truncating data file size: %"PRId64, data_offset);
		if (ftruncate(datafile, data_offset) < 0) {
			MHVTL_ERR("Error truncating data: %s", strerror(errno));
		}

		mkEODHeader(blk_number, data_offset);
		return -1;
	}

	nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos),
						blk_number * sizeof(raw_pos));
	if (nwrite != sizeof(raw_pos)) {
		long indxsz = (blk_number - 1) * sizeof(raw_pos);

		sam_medium_error(E_WRITE_ERROR, sam_stat);

		MHVTL_ERR("Index file write failure, pos: %" PRId64 ": %s",
			(uint64_t)blk_number * sizeof(raw_pos),
			strerror(errno));

		MHVTL_DBG(1, "Truncating index file size to: %ld", indxsz);
		if (ftruncate(indxfile, indxsz) < 0) {
			MHVTL_ERR("Error truncating indx: %s", strerror(errno));
		}

		if (!null_media_type) {
			MHVTL_DBG(1, "Truncating data file size: %"PRId64,
							data_offset);
			if (ftruncate(datafile, data_offset) < 0) {
				MHVTL_ERR("Error truncating data: %s",
							strerror(errno));
			}
		}

		mkEODHeader(blk_number, data_offset);
		return -1;
	}

	MHVTL_DBG(3, "Successfully wrote block: %u", blk_number);

	return mkEODHeader(blk_number + 1, data_offset + disk_blk_size);
}
예제 #4
0
파일: vtlcart.c 프로젝트: fishky/mhvtl
int write_filemarks(uint32_t count, uint8_t *sam_stat)
{
	uint32_t blk_number;
	uint64_t data_offset;
	ssize_t nwrite;

	if (!tape_loaded(sam_stat))
		return -1;

	/* Applications assume that writing a filemark (even writing zero
	   filemarks) will force-flush any data buffered in the drive to media
	   so that after the write-filemarks call returns there is no
	   possibility that any data previously written could be lost due
	   to a power hit.  Provide a similar guarantee here.
	*/

	if (count == 0) {
		MHVTL_DBG(2, "Flushing data - 0 filemarks written");
		fsync(datafile);
		fsync(indxfile);
		fsync(metafile);

		return 0;
	}

	if (check_for_overwrite(sam_stat))
		return -1;

	/* Preserve existing raw_pos data we need, then clear raw_pos and
	   fill it in with new data.
	*/

	blk_number = raw_pos.hdr.blk_number;
	data_offset = raw_pos.data_offset;

	memset(&raw_pos, 0, sizeof(raw_pos));

	raw_pos.data_offset = data_offset;

	raw_pos.hdr.blk_type = B_FILEMARK;	/* Header type */
	raw_pos.hdr.blk_flags = 0;
	raw_pos.hdr.blk_number = blk_number;
	raw_pos.hdr.blk_size = 0;
	raw_pos.hdr.disk_blk_size = 0;

	/* Now write out one header per filemark. */

	for ( ; count > 0; count--, blk_number++) {
		raw_pos.hdr.blk_number = blk_number;

		MHVTL_DBG(3, "Writing filemark: block %d", blk_number);

		nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos),
			blk_number * sizeof(raw_pos));
		if (nwrite != sizeof(raw_pos)) {
			sam_medium_error(E_WRITE_ERROR, sam_stat);
			MHVTL_ERR("Index file write failure,"
					" pos: %" PRId64 ": %s",
				(uint64_t)blk_number * sizeof(raw_pos),
				strerror(errno));
			return -1;
		}
		add_filemark(blk_number);
	}

	/* Provide the force-flush guarantee. */

	fsync(datafile);
	fsync(indxfile);
	fsync(metafile);

	return mkEODHeader(blk_number, data_offset);
}
예제 #5
0
파일: vtlcart.c 프로젝트: aroundrobin/mhvtl
int
write_tape_block(const uint8_t *buffer, uint32_t blk_size, uint32_t comp_size,
	const struct encryption *encryptp, uint8_t comp_type, uint8_t *sam_stat)
{
	uint32_t blk_number, disk_blk_size;
	uint64_t data_offset;
	ssize_t nwrite;

	if (!tape_loaded(sam_stat)) {
		return -1;
	}

	if (check_for_overwrite(sam_stat)) {
		return -1;
	}

	/* Preserve existing raw_pos data we need, then clear out raw_pos and
	   fill it in with new data.
	*/

	blk_number = raw_pos.hdr.blk_number;
	data_offset = raw_pos.data_offset;

	memset(&raw_pos, 0, sizeof(raw_pos));

	raw_pos.data_offset = data_offset;

	raw_pos.hdr.blk_type = B_DATA;	/* Header type */
	raw_pos.hdr.blk_flags = 0;
	raw_pos.hdr.blk_number = blk_number;
	raw_pos.hdr.blk_size = blk_size; /* Size of uncompressed data */

	if (comp_size) {
		if (comp_type == LZO)
			raw_pos.hdr.blk_flags |= BLKHDR_FLG_LZO_COMPRESSED;
		else
			raw_pos.hdr.blk_flags |= BLKHDR_FLG_ZLIB_COMPRESSED;
		raw_pos.hdr.disk_blk_size = disk_blk_size = comp_size;
	} else {
		raw_pos.hdr.disk_blk_size = disk_blk_size = blk_size;
	}

	if (encryptp != NULL) {
		unsigned int i;

		raw_pos.hdr.blk_flags |= BLKHDR_FLG_ENCRYPTED;
		raw_pos.hdr.encryption.ukad_length = encryptp->ukad_length;
		for (i = 0; i < encryptp->ukad_length; ++i) {
			raw_pos.hdr.encryption.ukad[i] = encryptp->ukad[i];
		}

		raw_pos.hdr.encryption.akad_length = encryptp->akad_length;
		for (i = 0; i < encryptp->akad_length; ++i) {
			raw_pos.hdr.encryption.akad[i] = encryptp->akad[i];
		}

		raw_pos.hdr.encryption.key_length = encryptp->key_length;
		for (i = 0; i < encryptp->key_length; ++i) {
			raw_pos.hdr.encryption.key[i] = encryptp->key[i];
		}
	}

	/* Now write out both the header and the data. */

	nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos),
		blk_number * sizeof(raw_pos));
	if (nwrite != sizeof(raw_pos)) {
		mkSenseBuf(MEDIUM_ERROR, E_WRITE_ERROR, sam_stat);
		MHVTL_ERR("Index file write failure, pos: %" PRId64 ": %s",
			(uint64_t)blk_number * sizeof(raw_pos),
			strerror(errno));
		return -1;
	}

	nwrite = pwrite(datafile, buffer, disk_blk_size, data_offset);
	if (nwrite != disk_blk_size) {
		mkSenseBuf(MEDIUM_ERROR, E_WRITE_ERROR, sam_stat);
		MHVTL_ERR("Data file write failure, pos: %" PRId64 ": %s",
			data_offset, strerror(errno));
		return -1;
	}

	MHVTL_DBG(3, "Successfully wrote block: %u", blk_number);

	return mkEODHeader(blk_number + 1, data_offset + disk_blk_size);
}