[stgt] [PATCH 3/8] ssc: make the on-disk MAM structure big endian

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Sun Oct 12 06:38:48 CEST 2008


The on-disk MAM structure was stored in endian machines so the ssc
image file has no compatibility among big and little endian
architecutres. This patch makes the on-disk MAM structure big endian.

Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
---
 usr/Makefile    |   13 ++++-
 usr/bs_ssc.c    |    7 ++-
 usr/bs_ssc.h    |   60 ++++++++++++++++++
 usr/dump_tape.c |   11 ++-
 usr/libssc.c    |  180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 usr/libssc.h    |    7 ++
 usr/mktape.c    |   51 +++++++++-------
 usr/ssc.h       |   11 +---
 8 files changed, 301 insertions(+), 39 deletions(-)
 create mode 100644 usr/libssc.c
 create mode 100644 usr/libssc.h

diff --git a/usr/Makefile b/usr/Makefile
index 1174f7e..b0f3b20 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -57,7 +57,8 @@ LIBS += -lpthread
 PROGRAMS += tgtd tgtadm mktape dump_tape
 SCRIPTS += ../scripts/tgt-setup-lun ../scripts/tgt-admin
 TGTD_OBJS += tgtd.o mgmt.o target.o scsi.o log.o driver.o util.o work.o \
-		parser.o spc.o sbc.o mmc.o osd.o scc.o smc.o ssc.o bs_ssc.o \
+		parser.o spc.o sbc.o mmc.o osd.o scc.o smc.o \
+		ssc.o bs_ssc.o libssc.o \
 		bs_null.o bs.o libcrc32c.o
 MANPAGES = ../doc/manpages/tgtadm.8 ../doc/manpages/tgt-admin.8 \
 		../doc/manpages/tgt-setup-lun.8
@@ -77,6 +78,16 @@ tgtadm: tgtadm.o
 
 -include tgtadm.d
 
+mktape: mktape.o libssc.o
+	$(CC) $^ -o $@
+
+-include mktape.d libssc.d
+
+dump_tape: dump_tape.o libssc.o
+	$(CC) $^ -o $@
+
+-include dump_tape.d libssc.d
+
 %.o: %.c
 	$(CC) -c $(CFLAGS) $*.c -o $*.o
 	@$(CC) -MM $(CFLAGS) -MF $*.d -MT $*.o $*.c
diff --git a/usr/bs_ssc.c b/usr/bs_ssc.c
index 4919082..d9f7036 100644
--- a/usr/bs_ssc.c
+++ b/usr/bs_ssc.c
@@ -38,6 +38,7 @@
 #include "media.h"
 #include "bs_ssc.h"
 #include "ssc.h"
+#include "libssc.h"
 
 static void ssc_sense_data_build(struct scsi_cmd *cmd, uint8_t key,
 				 uint16_t asc, uint8_t *info, int info_len)
@@ -604,6 +605,7 @@ static int bs_tape_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 	struct ssc_info *ssc;
 	char *cart = NULL;
 	ssize_t rd;
+	int ret;
 
 	ssc = dtype_priv(lu);
 
@@ -634,11 +636,12 @@ static int bs_tape_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 		goto read_failed;
 	}
 
-	rd = pread(*fd, &ssc->mam, sizeof(struct MAM), rd);
-	if (rd < sizeof(struct MAM)) {
+	ret = ssc_read_mam_info(*fd, &ssc->mam);
+	if (ret) {
 		eprintf("Failed to read MAM: %d %m\n", (int)rd);
 		goto read_failed;
 	}
+
 	rd = pread(*fd, ssc->c_blk, sizeof(struct blk_header),
 					ssc->c_blk->next);
 	if (rd < sizeof(struct blk_header)) {
diff --git a/usr/bs_ssc.h b/usr/bs_ssc.h
index 7e9a7d9..85cf25f 100644
--- a/usr/bs_ssc.h
+++ b/usr/bs_ssc.h
@@ -1,3 +1,6 @@
+#ifndef __BS_SSC_H
+#define __BS_SSC_H
+
 /*
  * structure of a 'poor mans double linked list' on disk.
  */
@@ -38,3 +41,60 @@ struct blk_header {
 	uint8_t z;
 };
 
+/*
+ * MAM (media access memory) structure based from IBM Ultrium SCSI
+ * Reference WB1109-02
+ */
+struct MAM {
+	uint32_t tape_fmt_version;
+	uint32_t __pad1;
+
+	uint64_t remaining_capacity;
+	uint64_t max_capacity;
+	uint64_t TapeAlert;
+	uint64_t load_count;
+	uint64_t MAM_space_remaining;
+
+	uint8_t assigning_organization_1[8];
+	uint8_t formatted_density_code;
+	uint8_t __pad2[5];
+	uint8_t initialization_count[2];
+	uint8_t dev_make_serial_last_load[4][40];
+
+	uint64_t written_in_medium_life;
+	uint64_t read_in_medium_life;
+	uint64_t written_in_last_load;
+	uint64_t read_in_last_load;
+
+	uint8_t medium_manufacturer[8];
+	uint8_t medium_serial_number[32];
+	uint32_t medium_length;
+	uint32_t medium_width;
+	uint8_t assigning_organization_2[8];
+	uint8_t medium_density_code;
+	uint8_t __pad3[7];
+	uint8_t medium_manufacture_date[8];
+	uint64_t MAM_capacity;
+	uint8_t medium_type;
+	uint8_t __pad4;
+	uint16_t medium_type_information;
+	uint8_t __pad5[4];
+
+	uint8_t application_vendor[8];
+	uint8_t application_name[32];
+	uint8_t application_version[8];
+	uint8_t user_medium_text_label[160];
+	uint8_t date_time_last_written[12];
+	uint8_t __pad6[3];
+	uint8_t localization_identifier;
+	uint8_t barcode[32];
+	uint8_t owning_host_textual_name[80];
+	uint8_t media_pool[160];
+
+	uint8_t vendor_unique[256];
+
+	uint8_t dirty;
+	uint8_t __reserved[7];
+};
+
+#endif
diff --git a/usr/dump_tape.c b/usr/dump_tape.c
index ef6b6c3..ff2124d 100644
--- a/usr/dump_tape.c
+++ b/usr/dump_tape.c
@@ -33,6 +33,7 @@
 #include "media.h"
 #include "ssc.h"
 #include "bs_ssc.h"
+#include "libssc.h"
 
 void print_current_header(struct blk_header *pos)
 {
@@ -104,7 +105,7 @@ int main(int argc, char *argv[])
 	char *progname;
 	char datafile[1024] = "";
 	loff_t	nread;
-	struct MAM mam;
+	struct MAM_info mam;
 	struct blk_header current_position;
 	time_t t;
 	int a;
@@ -151,13 +152,15 @@ int main(int argc, char *argv[])
 		perror("Could not read blk header");
 		exit(1);
 	}
-	nread = read(ofp, &mam, sizeof(struct MAM));
-	if (nread < (sizeof(struct MAM))) {
+
+	nread = ssc_read_mam_info(ofp, &mam);
+	if (nread) {
 		perror("Could not read MAM");
 		exit(1);
 	}
 	if (mam.tape_fmt_version != TGT_TAPE_VERSION) {
-		printf("Unknown media format version\n");
+		printf("Unknown media format version %x\n",
+		       mam.tape_fmt_version);
 		exit(1);
 	}
 
diff --git a/usr/libssc.c b/usr/libssc.c
new file mode 100644
index 0000000..297867e
--- /dev/null
+++ b/usr/libssc.c
@@ -0,0 +1,180 @@
+/*
+ * helpers for assessing to ssc on-disk structures
+ *
+ * Copyright (C) 2008 FUJITA Tomonori <tomof at acm.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include "bs_ssc.h"
+#include "ssc.h"
+#include "be_byteshift.h"
+
+#define SSC_1ST_HDR_OFFSET (sizeof(struct MAM) + sizeof(struct blk_header))
+
+#define SSC_GET_MAM_INFO_VAL(member, bits)\
+{\
+	(i)->member = get_unaligned_be##bits(&((m)->member));\
+}
+
+#define SSC_GET_MAM_INFO_ARRAY(member)\
+{\
+	memcpy((i)->member, (m)->member, sizeof((m)->member));\
+}
+
+static inline uint8_t get_unaligned_be8(const uint8_t *p)
+{
+	return p[0];
+}
+
+int ssc_read_mam_info(int fd, struct MAM_info *i)
+{
+	struct MAM mam, *m;
+	int ret;
+
+	m = &mam;
+
+	ret = pread(fd, m, sizeof(struct MAM), sizeof(struct blk_header));
+	if (ret != sizeof(struct MAM))
+		return 1;
+
+	if (lseek64(fd, SSC_1ST_HDR_OFFSET, SEEK_SET) != SSC_1ST_HDR_OFFSET)
+		return 1;
+
+	SSC_GET_MAM_INFO_VAL(tape_fmt_version, 32);
+
+	SSC_GET_MAM_INFO_VAL(remaining_capacity, 64);
+	SSC_GET_MAM_INFO_VAL(max_capacity, 64);
+	SSC_GET_MAM_INFO_VAL(TapeAlert, 64);
+	SSC_GET_MAM_INFO_VAL(load_count, 64);
+	SSC_GET_MAM_INFO_VAL(MAM_space_remaining, 64);
+
+	SSC_GET_MAM_INFO_ARRAY(assigning_organization_1);
+	SSC_GET_MAM_INFO_VAL(formatted_density_code, 8);
+	SSC_GET_MAM_INFO_ARRAY(initialization_count);
+	SSC_GET_MAM_INFO_ARRAY(dev_make_serial_last_load);
+
+	SSC_GET_MAM_INFO_VAL(written_in_medium_life, 64);
+	SSC_GET_MAM_INFO_VAL(read_in_medium_life, 64);
+	SSC_GET_MAM_INFO_VAL(written_in_last_load, 64);
+	SSC_GET_MAM_INFO_VAL(read_in_last_load, 64);
+
+	SSC_GET_MAM_INFO_ARRAY(medium_manufacturer);
+	SSC_GET_MAM_INFO_ARRAY(medium_serial_number);
+	SSC_GET_MAM_INFO_VAL(medium_length, 32);
+	SSC_GET_MAM_INFO_VAL(medium_width, 32);
+	SSC_GET_MAM_INFO_ARRAY(assigning_organization_2);
+	SSC_GET_MAM_INFO_VAL(medium_density_code, 8);
+	SSC_GET_MAM_INFO_ARRAY(medium_manufacture_date);
+	SSC_GET_MAM_INFO_VAL(MAM_capacity, 64);
+	SSC_GET_MAM_INFO_VAL(medium_type, 8);
+	SSC_GET_MAM_INFO_VAL(medium_type_information, 16);
+
+	SSC_GET_MAM_INFO_ARRAY(application_vendor);
+	SSC_GET_MAM_INFO_ARRAY(application_name);
+	SSC_GET_MAM_INFO_ARRAY(application_version);
+	SSC_GET_MAM_INFO_ARRAY(user_medium_text_label);
+	SSC_GET_MAM_INFO_ARRAY(date_time_last_written);
+	SSC_GET_MAM_INFO_VAL(localization_identifier, 8);
+	SSC_GET_MAM_INFO_ARRAY(barcode);
+	SSC_GET_MAM_INFO_ARRAY(owning_host_textual_name);
+	SSC_GET_MAM_INFO_ARRAY(media_pool);
+
+	SSC_GET_MAM_INFO_ARRAY(vendor_unique);
+
+	SSC_GET_MAM_INFO_VAL(dirty, 8);
+
+	return 0;
+}
+
+#define SSC_PUT_MAM_INFO_VAL(member, bits)\
+{\
+	put_unaligned_be##bits((i)->member, &((m)->member));\
+}
+
+#define SSC_PUT_MAM_INFO_ARRAY(member)\
+{\
+	memcpy((m)->member, (i)->member, sizeof((m)->member));\
+}
+
+static inline void put_unaligned_be8(uint8_t val, uint8_t *p)
+{
+	*p = val;
+}
+
+int ssc_write_mam_info(int fd, struct MAM_info *i)
+{
+	struct MAM mam, *m;
+	int ret;
+
+	m = &mam;
+	memset(m, 0, sizeof(struct MAM));
+
+	SSC_PUT_MAM_INFO_VAL(tape_fmt_version, 32);
+
+	SSC_PUT_MAM_INFO_VAL(remaining_capacity, 64);
+	SSC_PUT_MAM_INFO_VAL(max_capacity, 64);
+	SSC_PUT_MAM_INFO_VAL(TapeAlert, 64);
+	SSC_PUT_MAM_INFO_VAL(load_count, 64);
+	SSC_PUT_MAM_INFO_VAL(MAM_space_remaining, 64);
+
+	SSC_PUT_MAM_INFO_ARRAY(assigning_organization_1);
+	SSC_PUT_MAM_INFO_VAL(formatted_density_code, 8);
+	SSC_PUT_MAM_INFO_ARRAY(initialization_count);
+	SSC_PUT_MAM_INFO_ARRAY(dev_make_serial_last_load);
+
+	SSC_PUT_MAM_INFO_VAL(written_in_medium_life, 64);
+	SSC_PUT_MAM_INFO_VAL(read_in_medium_life, 64);
+	SSC_PUT_MAM_INFO_VAL(written_in_last_load, 64);
+	SSC_PUT_MAM_INFO_VAL(read_in_last_load, 64);
+
+	SSC_PUT_MAM_INFO_ARRAY(medium_manufacturer);
+	SSC_PUT_MAM_INFO_ARRAY(medium_serial_number);
+	SSC_PUT_MAM_INFO_VAL(medium_length, 32);
+	SSC_PUT_MAM_INFO_VAL(medium_width, 32);
+	SSC_PUT_MAM_INFO_ARRAY(assigning_organization_2);
+	SSC_PUT_MAM_INFO_VAL(medium_density_code, 8);
+	SSC_PUT_MAM_INFO_ARRAY(medium_manufacture_date);
+	SSC_PUT_MAM_INFO_VAL(MAM_capacity, 64);
+	SSC_PUT_MAM_INFO_VAL(medium_type, 8);
+	SSC_PUT_MAM_INFO_VAL(medium_type_information, 16);
+
+	SSC_PUT_MAM_INFO_ARRAY(application_vendor);
+	SSC_PUT_MAM_INFO_ARRAY(application_name);
+	SSC_PUT_MAM_INFO_ARRAY(application_version);
+	SSC_PUT_MAM_INFO_ARRAY(user_medium_text_label);
+	SSC_PUT_MAM_INFO_ARRAY(date_time_last_written);
+	SSC_PUT_MAM_INFO_VAL(localization_identifier, 8);
+	SSC_PUT_MAM_INFO_ARRAY(barcode);
+	SSC_PUT_MAM_INFO_ARRAY(owning_host_textual_name);
+	SSC_PUT_MAM_INFO_ARRAY(media_pool);
+
+	SSC_PUT_MAM_INFO_ARRAY(vendor_unique);
+
+	SSC_PUT_MAM_INFO_VAL(dirty, 8);
+
+	ret = pwrite(fd, m, sizeof(struct MAM), sizeof(struct blk_header));
+	if (ret != sizeof(struct MAM))
+		return 1;
+
+	if (lseek64(fd, SSC_1ST_HDR_OFFSET, SEEK_SET) != SSC_1ST_HDR_OFFSET)
+		return 1;
+
+	return  0;
+}
diff --git a/usr/libssc.h b/usr/libssc.h
new file mode 100644
index 0000000..891bb30
--- /dev/null
+++ b/usr/libssc.h
@@ -0,0 +1,7 @@
+#ifndef __LIBSSC_H
+#define __LIBSSC_H
+
+extern int ssc_read_mam_info(int fd, struct MAM_info *i);
+extern int ssc_write_mam_info(int fd, struct MAM_info *i);
+
+#endif
diff --git a/usr/mktape.c b/usr/mktape.c
index 1abf948..8278317 100644
--- a/usr/mktape.c
+++ b/usr/mktape.c
@@ -33,6 +33,7 @@
 #include "media.h"
 #include "bs_ssc.h"
 #include "ssc.h"
+#include "libssc.h"
 
 const char *mktape_version = "0.01";
 
@@ -49,7 +50,7 @@ int main(int argc, char *argv[])
 {
 	int file;
 	struct blk_header h;
-	struct MAM mam;
+	struct MAM_info mi;
 	uint8_t current_media[1024];
 	long nwrite;
 	char *progname = argv[0];
@@ -57,6 +58,7 @@ int main(int argc, char *argv[])
 	char *media_type = NULL;
 	char *media_capacity = NULL;
 	uint32_t size;
+	int ret;
 
 	if (argc < 2) {
 		usage(progname);
@@ -124,38 +126,40 @@ int main(int argc, char *argv[])
 	h.blk_sz = size;
 	h.prev = 0;
 	h.curr = 0;
-	h.next = sizeof(mam) + sizeof(h);
+	h.next = sizeof(struct MAM) + sizeof(h);
 
 	printf("blk_sz: %d, next %" PRId64 ", %" PRId64 "\n",
 				h.blk_sz, h.next, h.next);
 	printf("Sizeof(mam): %" PRId64 ", sizeof(h): %" PRId64 "\n",
-			(uint64_t)sizeof(mam), (uint64_t)sizeof(h));
-	memset((uint8_t *)&mam, 0, sizeof(mam));
-
-	mam.tape_fmt_version = 2;
-	mam.max_capacity = size * 1048576;
-	mam.remaining_capacity = size * 1048576;
-	mam.MAM_space_remaining = sizeof(mam.vendor_unique);
-	mam.medium_length = 384;	/* 384 tracks */
-	mam.medium_width = 127;		/* 127 x tenths of mm (12.7 mm) */
-	memcpy(&mam.medium_manufacturer, "Foo     ", 8);
-	memcpy(&mam.application_vendor, "Bar     ", 8);
+	       (uint64_t)sizeof(struct MAM), (uint64_t)sizeof(h));
+
+	memset(&mi, 0, sizeof(mi));
+
+	mi.tape_fmt_version = TGT_TAPE_VERSION;
+	mi.max_capacity = size * 1048576;
+	mi.remaining_capacity = size * 1048576;
+	mi.MAM_space_remaining = sizeof(mi.vendor_unique);
+	mi.medium_length = 384;	/* 384 tracks */
+	mi.medium_width = 127;		/* 127 x tenths of mm (12.7 mm) */
+	memcpy(mi.medium_manufacturer, "Foo     ", 8);
+	memcpy(mi.application_vendor, "Bar     ", 8);
 
 	if (!strncmp("clean", media_type, 5)) {
-		mam.medium_type = CART_CLEAN;
-		mam.medium_type_information = 20; /* Max cleaning loads */
+		mi.medium_type = CART_CLEAN;
+		mi.medium_type_information = 20; /* Max cleaning loads */
 	} else if (!strncmp("WORM", media_type, 4)) {
-		mam.medium_type = CART_WORM;
+		mi.medium_type = CART_WORM;
 	} else {
-		mam.medium_type = CART_DATA;
+		mi.medium_type = CART_DATA;
 	}
 
-	sprintf((char *)mam.medium_serial_number, "%s_%d",
-					barcode, (int)time(NULL));
-	sprintf((char *)mam.barcode, "%-31s", barcode);
-
+	sprintf((char *)mi.medium_serial_number, "%s_%d", barcode,
+		(int)time(NULL));
+	sprintf((char *)mi.barcode, "%-31s", barcode);
 	sprintf((char *)current_media, "%s", barcode);
+
 	syslog(LOG_DAEMON|LOG_INFO, "%s being created", current_media);
+
 	file = creat((char *)current_media, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
 	if (file == -1) {
 		perror("Failed creating file");
@@ -166,8 +170,9 @@ int main(int argc, char *argv[])
 		perror("Unable to write header");
 		exit(1);
 	}
-	nwrite = write(file, &mam, sizeof(mam));
-	if (nwrite <= 0) {
+
+	ret = ssc_write_mam_info(file, &mi);
+	if (ret) {
 		perror("Unable to write MAM");
 		exit(1);
 	}
diff --git a/usr/ssc.h b/usr/ssc.h
index 308c8e5..dcd1337 100644
--- a/usr/ssc.h
+++ b/usr/ssc.h
@@ -8,9 +8,8 @@
 /*
  * MAM structure based from IBM Ultrium SCSI Reference WB1109-02
  */
-struct MAM {
+struct MAM_info {
 	uint32_t tape_fmt_version;
-	uint32_t __pad1;
 
 	uint64_t remaining_capacity;
 	uint64_t max_capacity;
@@ -20,7 +19,6 @@ struct MAM {
 
 	uint8_t assigning_organization_1[8];
 	uint8_t formatted_density_code;
-	uint8_t __pad2[5];
 	uint8_t initialization_count[2];
 	uint8_t dev_make_serial_last_load[4][40];
 
@@ -35,20 +33,16 @@ struct MAM {
 	uint32_t medium_width;
 	uint8_t assigning_organization_2[8];
 	uint8_t medium_density_code;
-	uint8_t __pad3[7];
 	uint8_t medium_manufacture_date[8];
 	uint64_t MAM_capacity;
 	uint8_t medium_type;
-	uint8_t __pad4;
 	uint16_t medium_type_information;
-	uint8_t __pad5[4];
 
 	uint8_t application_vendor[8];
 	uint8_t application_name[32];
 	uint8_t application_version[8];
 	uint8_t user_medium_text_label[160];
 	uint8_t date_time_last_written[12];
-	uint8_t __pad6[3];
 	uint8_t localization_identifier;
 	uint8_t barcode[32];
 	uint8_t owning_host_textual_name[80];
@@ -57,14 +51,13 @@ struct MAM {
 	uint8_t vendor_unique[256];
 
 	uint8_t dirty;
-	uint8_t __reserved[7];
 };
 
 struct ssc_info {
 	uint64_t bytes_read;	/* Bytes read this load */
 	uint64_t bytes_written;	/* Bytes written this load */
 
-	struct MAM mam;
+	struct MAM_info mam;
 
 	struct blk_header *c_blk;	/* Current block header */
 };
-- 
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list