Skip to content

Commit

Permalink
vtllibrary: To report correct media type - a helper added
Browse files Browse the repository at this point in the history
get_cart_type() is a cut-down version from vtlcart.c

Just enough to read the MAM information from the meta file and
return the correct media type.

This will result in open()/close() of each meta file on a robot initialisation

Signed-off-by: Mark Harvey <markh794@gmail.com>
  • Loading branch information
markh794 committed Mar 30, 2015
1 parent d0be03b commit d9fc6c9
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 22 deletions.
4 changes: 4 additions & 0 deletions usr/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ edit_tape: edit_tape.o vtlcart.o libvtlscsi.so vtltape.h vtllib.h \

vtllibrary: vtllibrary.o vtllib.h scsi.h \
libvtlscsi.so \
vtl_cart_type.o \
be_byteshift.h \
stklxx_pm.o \
hp_smc_pm.o \
Expand All @@ -110,6 +111,7 @@ vtllibrary: vtllibrary.o vtllib.h scsi.h \
default_smc_pm.o \
../kernel/vtl_common.h
$(CC) $(CFLAGS) -o vtllibrary vtllibrary.o -L. -lvtlscsi \
vtl_cart_type.o \
stklxx_pm.o \
hp_smc_pm.o \
overland_pm.o \
Expand Down Expand Up @@ -146,6 +148,7 @@ clean:
vtlcmd.o dump_messageQ.o core mktape.o vtllib.o \
libvtlscsi.o libvtlscsi.so libvtlcart.o libvtlcart.so \
z.o vtllibrary.o \
vtl_cart_type.o \
vtlcart.o spc.o smc.o ssc.o tapeexerciser.o \
default_ssc_pm.o \
ult3580_pm.o \
Expand Down Expand Up @@ -181,6 +184,7 @@ distclean:
core mktape mktape.o \
vtllib.o libvtlscsi.so \
libvtlcart.so vtlcart.o spc.o \
vtl_cart_type.o \
smc.o ssc.o \
default_ssc_pm.o \
ult3580_pm.o \
Expand Down
2 changes: 1 addition & 1 deletion usr/smc.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ static int fill_ed(struct scsi_cmd *cmd, uint8_t *p, struct s_info *s)
* 5 - Microcode image medium
*/
if (s->media)
p[j] |= (s->media->cart_type & 0x0f);
p[j] |= s->media->cart_type & 0x0f;

j++;

Expand Down
3 changes: 3 additions & 0 deletions usr/smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ uint8_t smc_read_element_status(struct scsi_cmd *cmd);
uint8_t smc_rezero(struct scsi_cmd *cmd);
uint8_t smc_open_close_import_export_element(struct scsi_cmd *cmd);

int get_cart_type(char *barcode);
void update_home_dir(long my_id); /* for the 'get_cart_type()' function only */

int slotOccupied(struct s_info *s);
void setImpExpStatus(struct s_info *s, int flg);
void setSlotEmpty(struct s_info *s);
Expand Down
195 changes: 195 additions & 0 deletions usr/vtl_cart_type.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* Version 2 of tape format.
*
* Each media contains 3 files.
* - The .data file contains each block of data written to the media
* - The .indx file consists of an array of one raw_header structure per
* written tape block or filemark.
* - The .meta file consists of a MAM structure followed by a meta_header
* structure, followed by a variable-length array of filemark block numbers.
*
* Copyright (C) 2009 - 2010 Kevan Rehm
*
* This is a vtllibrary 'helper'. This contains a function to open the media
* metadata file and return the media type (Data, WORM, Cleaning etc)
* Required to fill in details of READ ELEMENT STATUS - instead of just gussing
* based on barcode, open the actual media metadata and read 'from the horses
* mouth'
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#define _FILE_OFFSET_BITS 64

#define __STDC_FORMAT_MACROS /* for PRId64 */

/* for unistd.h pread/pwrite and fcntl.h posix_fadvise */
#define _XOPEN_SOURCE 600

#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "logging.h"
#include "list.h"
#include "vtltape.h"

/* The .meta file consists of a MAM structure followed by a meta_header
structure, followed by a variable-length array of filemark block numbers.
Both the MAM and meta_header structures also contain padding to allow
for future expansion with backwards compatibility.
*/

struct meta_header {
uint32_t filemark_count;
char pad[512 - sizeof(uint32_t)];
};

static char currentPCL[1024];
static struct meta_header meta;

static char home_directory[HOME_DIR_PATH_SZ + 1];

/*
* Attempt to open PCL metadata and read cart type
*
* Returns valid SMC media type values (READ ELEMENT STATUS):
* == 0 -> open failed or unknown cart type
* == 1 -> Data Cart type
* == 2 -> Cleaning
* == 3 -> Diagnostics
* == 4 -> WORM
*
* == 5 -> NULL media type (SMC specifies values > 4 as 'reserved')
*/

void update_home_dir(long lib_id)
{
if (strlen(home_directory) < 2) {
find_media_home_directory(home_directory, lib_id);
MHVTL_DBG(3, "Setting home dir to %s", home_directory);
}
}

int get_cart_type(const char *barcode)
{
char pcl_meta[1024];
char pcl[MAX_BARCODE_LEN + 1];
struct stat meta_stat;
uint64_t exp_size;
loff_t nread;
int rc = 0;
int i;
int metafile;
struct MAM tmp_mam;

/* copy barcode to &pcl and terminate at either ' ' or '\0' */
for (i = 0; i < MAX_BARCODE_LEN; i++) {
pcl[i] = barcode[i];
if (pcl[i] == ' ' || pcl[i] == '\0') {
pcl[i] = '\0';
break;
}
}

if (strlen(home_directory))
snprintf(currentPCL, ARRAY_SIZE(currentPCL), "%s/%s",
home_directory, pcl);
else
snprintf(currentPCL, ARRAY_SIZE(currentPCL), "%s/%s",
MHVTL_HOME_PATH, pcl);

snprintf(pcl_meta, ARRAY_SIZE(pcl_meta), "%s/meta", currentPCL);

if (stat(pcl_meta, &meta_stat) == -1) {
MHVTL_DBG(2, "Couldn't find %s, trying previous default: %s/%s",
pcl_meta, MHVTL_HOME_PATH, pcl);
snprintf(currentPCL, ARRAY_SIZE(currentPCL), "%s/%s",
MHVTL_HOME_PATH, pcl);
snprintf(pcl_meta, ARRAY_SIZE(pcl_meta), "%s/meta", currentPCL);
}

metafile = open(pcl_meta, O_RDONLY);
if (metafile == -1) {
MHVTL_ERR("open of pcl %s file %s failed, %s", pcl,
pcl_meta, strerror(errno));
rc = 0;
goto failed;
}

if (fstat(metafile, &meta_stat) < 0) {
MHVTL_ERR("stat of pcl %s file %s failed: %s", pcl,
pcl_meta, strerror(errno));
rc = 0;
goto failed;
}

/* Verify that the metafile size is at least reasonable. */

exp_size = sizeof(tmp_mam) + sizeof(meta);
if ((uint32_t)meta_stat.st_size < exp_size) {
MHVTL_ERR("pcl %s file %s is not the correct length, "
"expected at least %" PRId64 ", actual %" PRId64,
pcl, pcl_meta, exp_size, meta_stat.st_size);
rc = 0;
goto failed;
}

/* Read in the MAM and sanity-check it. */
nread = read(metafile, &tmp_mam, sizeof(tmp_mam));
if (nread < 0) {
MHVTL_ERR("Error reading pcl %s MAM from metafile: %s",
pcl, strerror(errno));
rc = 0;
goto failed;
} else if (nread != sizeof(tmp_mam)) {
MHVTL_ERR("Error reading pcl %s MAM from metafile: "
"unexpected read length", pcl);
rc = 0;
goto failed;
}

switch (tmp_mam.MediumType) {
case MEDIA_TYPE_NULL:
rc = 5; /* Reserved */
break;
case MEDIA_TYPE_DATA:
rc = 1;
break;
case MEDIA_TYPE_CLEAN:
rc = 2;
break;
case MEDIA_TYPE_DIAGNOSTIC:
rc = 3;
break;
case MEDIA_TYPE_WORM:
rc = 4;
break;
default:
rc = 0;
break;
}

failed:
close(metafile);
MHVTL_DBG(3, "Opening media: %s (barcode %s), returning type %d",
currentPCL, barcode, rc);
return rc;
}
2 changes: 2 additions & 0 deletions usr/vtllib.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@
#define MEDIA_TYPE_DATA 0
#define MEDIA_TYPE_WORM 1
#define MEDIA_TYPE_NULL 2
#define MEDIA_TYPE_DIAGNOSTIC 3
#define MEDIA_TYPE_FIRMWARE 4
#define MEDIA_TYPE_CLEAN 6

#define MHVTL_NO_COMPRESSION 0
Expand Down
26 changes: 5 additions & 21 deletions usr/vtllibrary.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,25 +342,6 @@ static void list_map(struct q_msg *msg)
send_msg(buf, msg->snd_id);
}

/*
* If barcode starts with string 'CLN' define it as a cleaning cart.
* else its a data cartridge
*
* Return 1 = Data cartridge
* 2 = Cleaning cartridge
*/
static uint8_t cart_type(char *barcode)
{
uint8_t retval = 0;

retval = (strncmp(barcode, "CLN", 3)) ? 1 : 2;
MHVTL_DBG(2, "%s cart found: %s",
(retval == 1) ? "Data" : "Cleaning", barcode);

return retval;
}


/* Check existing MAP & Storage slots for existing barcode */
int already_in_slot(char *barcode)
{
Expand Down Expand Up @@ -446,7 +427,7 @@ static struct m_info *add_barcode(struct lu_phy_attr *lu, char *barcode)
snprintf((char *)m->barcode, MAX_BARCODE_LEN + 1, LEFT_JUST_16_STR,
barcode);
m->barcode[MAX_BARCODE_LEN] = '\0';
m->cart_type = cart_type((char *)barcode);
m->cart_type = get_cart_type(barcode);
if (!strncmp((char *)m->barcode, "NOBAR", 5))
m->internal_status = INSTATUS_NO_BARCODE;
else
Expand Down Expand Up @@ -509,7 +490,7 @@ static int load_map(struct q_msg *msg)
mp->barcode[MAX_BARCODE_LEN] = '\0';

/* 1 = data, 2 = Clean */
mp->cart_type = cart_type(barcode);
mp->cart_type = get_cart_type(barcode);
sp->status = STATUS_InEnab | STATUS_ExEnab |
STATUS_Access | STATUS_ImpExp |
STATUS_Full;
Expand Down Expand Up @@ -1310,6 +1291,9 @@ static int init_lu(struct lu_phy_attr *lu, unsigned minor, struct vtl_ctl *ctl)
backoff = DEFLT_BACKOFF_VALUE;
lu->persist = FALSE;

/* Set static 'home_directory' var - used for get_cart_type() function */
update_home_dir(my_id);

/* Configure default inquiry data */
memset(&lu->inquiry, 0, MAX_INQUIRY_SZ);
lu->inquiry[0] = TYPE_MEDIUM_CHANGER; /* SMC device */
Expand Down

0 comments on commit d9fc6c9

Please sign in to comment.