tape390: Remove tape390_display and tape390_crypt

The tape390_display tool was used to send text to the display of tape
storage server. The corresponding command is still accepted by the
Virtual Tape Server (VTS) but no action is performed. The tool is
useless, remove it.

The tape390_crypt tool was used to manage encryption for tape devices.
However, only 3590/3592 models did support encryption. Support for these
models is removed from the Kernel as there is no support for these tape
models in general anymore. The tool is not required anymore, remove it.

Note: VTS uses encryption transparantly for its virtualized 3490 models.

Reviewed-by: Jens Remus <jremus@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Jan Höppner
2026-01-19 18:47:02 +01:00
parent d92f419836
commit 8f83002e37
10 changed files with 1 additions and 1269 deletions

2
.gitignore vendored
View File

@@ -97,8 +97,6 @@ qethqoat/qethqoat
systemd/cpacfstatsd.service
systemd/iucvtty-login@.service
systemd/ttyrun-getty@.service
tape390/tape390_crypt
tape390/tape390_display
tunedasd/src/tunedasd
vmcp/vmcp
vmur/vmur

View File

@@ -11,7 +11,7 @@ BASELIB_DIRS = libutil libseckey
LIB_DIRS = libvtoc libzds libdasd libccw libvmcp libekmfweb \
libkmipclient libcpumf libap libpv libzpci
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
osasnmpd qetharp ip_watcher qethconf scripts zconf \
vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \

View File

@@ -79,13 +79,6 @@ Package contents
* qetharp:
Read and flush the ARP cache on OSA Express network cards.
* tape390_display:
Display information on the message display facility of a s390 tape
device.
* tape390_crypt:
Control and query crypto settings for 3592 tape devices.
* osasnmpd:
NET-SNMP subagent implementing MIBs provided by OSA-Express
features Fast Ethernet, Gigabit Ethernet, 10 Gigabit Ethernet.

View File

@@ -1,25 +0,0 @@
include ../common.mak
ALL_CPPFLAGS += -D_FILE_OFFSET_BITS=64
all: tape390_display tape390_crypt
tape390_display: tape390_display.o tape390_common.o
tape390_crypt: tape390_crypt.o tape390_common.o
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 tape390_display \
$(DESTDIR)$(BINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 tape390_display.8 \
$(DESTDIR)$(MANDIR)/man8
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 tape390_crypt \
$(DESTDIR)$(BINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 tape390_crypt.8 \
$(DESTDIR)$(MANDIR)/man8
clean:
rm -f *.o *~ tape390_display tape390_crypt core
.PHONY: all install clean

View File

@@ -1,86 +0,0 @@
/*
* tape_390 - Common functions
*
* Copyright IBM Corp. 2006, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include "tape390_common.h"
#define PROC_DEVICES_FILE "/proc/devices"
#define PROC_DEVICES_FILE_WIDTH 100
char *prog_name; /* Name of tool */
/*
* Set name of tool
*/
void set_prog_name(char *name)
{
prog_name = name;
}
/*
* Check whether specified device node is tape device
*/
int is_not_tape(char *device)
{
FILE* fh;
char line[PROC_DEVICES_FILE_WIDTH];
char last_line[PROC_DEVICES_FILE_WIDTH];
int found = 0;
struct stat stat_struct;
if (stat(device, &stat_struct)) {
ERRMSG("%s: Unable to get device status for "
"'%s'. \n", prog_name, device);
perror("");
return 1;
}
fh = fopen(PROC_DEVICES_FILE,"r");
if (!fh) {
ERRMSG("%s: WARNING: Cannot check for tape in file "
PROC_DEVICES_FILE ".\n", prog_name);
perror("");
return(0); /* check not possible, just continue */
}
while (!found && (fscanf(fh, "%s", line) != EOF)) {
if (strcmp(line, "tape") == 0)
found = 1;
else
strcpy(last_line, line);
}
fclose(fh);
if (found && (major(stat_struct.st_rdev) ==
(unsigned int) atoi(last_line)))
return (0);
else {
ERRMSG("%s: '%s' is not a tape device. \n", prog_name, device);
return 1;
}
}
/*
* Open the tape device
*/
int open_tape(char *device)
{
int fd;
fd = open(device,O_RDONLY);
if (fd < 0) {
ERRMSG("%s: Cannot open device %s.\n",
prog_name,device);
perror("");
exit(EXIT_MISUSE);
}
return fd;
}

View File

@@ -1,22 +0,0 @@
/*
* tape_390 - Common functions
*
* Copyright IBM Corp. 2006, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef _TAPE390_COMMON_H
#define _TAPE390_COMMON_H
#define ERRMSG(x...) {fflush(stdout);fprintf(stderr,x);}
#define ERRMSG_EXIT(ec,x...) do {fflush(stdout);fprintf(stderr,x);exit(ec);} while(0)
#define EXIT_MISUSE 1
extern int is_not_tape(char *);
extern int open_tape(char *);
extern void set_prog_name(char *);
extern char *prog_name;
#endif

View File

@@ -1,108 +0,0 @@
.\" Copyright 2017 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH TAPE390_CRYPT 8 "Apr 2006" "s390-tools"
.SH NAME
tape390_crypt \- encryption support for zSeries tape devices.
.SH SYNOPSIS
.B tape390_crypt
[OPTION] [DEVICE]
.SH DESCRIPTION
.B tape390_crypt
exploits encryption features available in zSeries tape devices.
It can be used to enable or disable tape encryption and to set
KEK (Key Encrypting Key) labels.
.SH OPTIONS
.TP
.BR "\-h" " or " "\-\-help"
Print help information, then exit.
.TP
.BR "\-v" " or " "\-\-version"
Print version information, then exit.
.TP
.BR "\-q" " or " "\-\-query"
Print current encryption status of the specified tape device and of the
loaded medium.
If encryption is on and the medium is encrypted ,
additional information on the encryption keys is displayed.
.TP
.BR "\-e " { "on" | "off" } " " or " \-\-encryption=" { "on" | "off" }
sets tape encryption on or off.
.TP
.BR "\-k <value>" [ "<char>label" | "<char>hash" ] " " or " \-\-key=<value>" [ "<char>label" | "<char>hash" ]
sets tape encryption keys.
.br
<value> specifies the KEK
(Key Encrypting Key), which can be maximal 64 characters long.
.br
The store type (either label or hash) specifies how the KEK in <value> is to be stored on the tape medium. Since labels are
human readable strings and hence more user friendly than hashes,
the default store type is label.
.br
The \-k option can only be specified, if the tape medium is at load point.
.br
While processing the \-k option, the tape medium is initialized and all
data eventually contained on the tape medium is lost.
To avoid inadvertent data loss a prompt message is issued asking the user
whether he or she really wants to proceed.
.br
The \-k option can be specified maximal twice, because on the tape medium
maximal two EEDKs (External Encrypted Data Keys) can be stored.
If specified once, two identical EEDKs are stored.
.br
<char> is a character separating the KEK in <value> from the store type
(either label or hash). This
delimiter can be specified with the \-d option as explained below.
.TP
.BR "\-d <char>" " or " "\-\-delimiter=<char>
specifies the character which separates the KEK
in <value> from the store type (either label or hash).
The default delimiter is : (colon).
The \-d option can only be specified together with the \-k option.
.TP
.BR "\-f " " or " "\-\-force
specifies that no prompt message is to be issued before writing the KEK
information and initializing the tape medium.
The \-f option can only be specified together with the \-k option.
.TP
.BR device
specifies the device node of the tape device.
.SH EXAMPLES
1. Scenario:
.br
mount non-encrypted tape and write data with the
.B "default"
KEKs:
.br
tape390_crypt \-e on /dev/ntibm0
.br
tar cfz /dev/ntibm0 /data
2. Scenario:
.br
mount non-encrypted tape and write data with
.B "specific"
KEKs:
.br
tape390_crypt \-k my_first_key \-k my_second_key:hash /dev/ntibm0
.br
tar cfz /dev/ntibm0 /data
3. Scenario:
.br
mount tape and display current encryption status:
.br
tape390_crypt \-q /dev/ntibm0

View File

@@ -1,581 +0,0 @@
/*
* tape390_crypt: Provide encryption for tape devices
*
* Copyright 2006, 2017 IBM Corp.
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <libgen.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <unistd.h>
#include "lib/zt_common.h"
#include "tape390_common.h"
#define KEKL_LENGTH 65 /* 64 bytes plus trailing \0 */
#define TOT_KEKL_LENGTH KEKL_LENGTH+1+5 /* kekl plus colon plus LABEL or HASH */
#define ENCRYPTION_ON 1
#define ENCRYPTION_OFF 0
#define CRYPT_SET_FAILED_MSG "%s: Tape drive does not support encryption.\n"
#define CRYPT_QUERY_FAILED_MSG CRYPT_SET_FAILED_MSG
#define KEKL_QUERY_FAILED_MSG "%s: Query of encryption keys failed.\n"
#define KEKL_SET_FAILED_MSG "%s: Unable to set or modify encryption keys.\n"
#define PROC_DEVICES_FILE "/proc/devices"
#define PROC_DEVICES_FILE_WIDTH 100
#define MAX_BLOCKSIZE 65535 /* max blocksize supported by escon/ficon tapes */
#ifndef ENOKEY
#define ENOKEY 126
#endif
#ifndef EKEYREJECTED
#define EKEYREJECTED 129
#endif
#define CHECK_SPEC_MAX(i,j,numstr,str) \
{if (i>j) ERRMSG_EXIT(EXIT_MISUSE,"%s: " str " " \
"can only be specified " numstr ".\n",prog_name);}
#define PRINT_TYPE(byte) \
{if (byte==TAPE390_KEKL_TYPE_LABEL) printf("label\n");\
else if (byte == TAPE390_KEKL_TYPE_HASH) printf("hash\n");\
else printf("Unsupported type\n");}
/*
* Structure tape390_crypt is used to store the command line parameters
*/
struct tape390_crypt {
int e_switch;
char delimiter;
char devname[PATH_MAX];
char kekl_input[2][TOT_KEKL_LENGTH];
int encryption_specified;
int query_specified;
int key_specified;
int delimiter_specified;
int force_specified;
} __attribute__ ((packed));
/*
* The following ioctl's belong to linux-2.5/include/asm-s390/tape390.h
*
* The TAPE390_CRYPT_SET ioctl is used to switch on/off encryption.
* The "encryption_capable" field is ignored for this ioctl!
*/
#define TAPE390_CRYPT_SET _IOW('d', 2, struct tape390_crypt_info)
/*
* The TAPE390_CRYPT_QUERY ioctl is used to query the encryption state.
*/
#define TAPE390_CRYPT_QUERY _IOR('d', 3, struct tape390_crypt_info)
struct tape390_crypt_info {
char capability;
char status;
char medium_status;
} __attribute__ ((packed));
/* Macros for "capable" field */
#define TAPE390_CRYPT_SUPPORTED_MASK 0x01
#define TAPE390_CRYPT_SUPPORTED(x) \
((x.capability & TAPE390_CRYPT_SUPPORTED_MASK))
/* Macros for "status" field */
#define TAPE390_CRYPT_ON_MASK 0x01
#define TAPE390_CRYPT_ON(x) (((x.status) & TAPE390_CRYPT_ON_MASK))
/* Macros for "medium status" field */
#define TAPE390_MEDIUM_LOADED_MASK 0x01
#define TAPE390_MEDIUM_ENCRYPTED_MASK 0x02
#define TAPE390_MEDIUM_ENCRYPTED(x) \
(((x.medium_status) & TAPE390_MEDIUM_ENCRYPTED_MASK))
#define TAPE390_MEDIUM_LOADED(x) \
(((x.medium_status) & TAPE390_MEDIUM_LOADED_MASK))
/*
* The TAPE390_KEKL_SET ioctl is used to set Key Encrypting Key labels.
*/
#define TAPE390_KEKL_SET _IOW('d', 4, struct tape390_kekl_pair)
/*
* The TAPE390_KEKL_QUERY ioctl is used to query Key Encrypting Key labels.
*/
#define TAPE390_KEKL_QUERY _IOR('d', 5, struct tape390_kekl_pair)
struct tape390_kekl {
unsigned char type;
unsigned char type_on_tape;
char label[65];
} __attribute__ ((packed));
struct tape390_kekl_pair {
struct tape390_kekl kekl[2];
} __attribute__ ((packed));
/* Values for "kekl1/2_type" and "kekl1/2_type_on_tape" fields */
#define TAPE390_KEKL_TYPE_NONE 0
#define TAPE390_KEKL_TYPE_LABEL 1
#define TAPE390_KEKL_TYPE_HASH 2
/* Full tool name */
static const char tool_name[] = "tape390_crpyt: zSeries tape encryption program";
/* Copyright notice */
static const char copyright_notice[] = "Copyright IBM Corp. 2006, 2017";
/*
* Print version information.
*/
static void print_version (void)
{
printf ("%s version %s\n", tool_name, RELEASE_STRING);
printf ("%s\n", copyright_notice);
}
/*
* prints out the usage text
*/
static void tape390_crypt_usage (void)
{
printf ("Usage: tape390_crypt [OPTIONS] [DEVICE]\n"
"\n"
"Provide encryption for "
"tape devices.\n"
"DEVICE is the node of the tape device (e.g. '/dev/ntibm0')\n"
"\n"
"-h, --help Print this help, then exit\n"
"-v, --version Print version information, "
"then exit\n"
"-q, --query Query information on encryption "
"status and keys\n"
"-k, --key value:type Set encryption key(s)\n"
"-d, --delimiter char Specify character separating "
"key value from key type\n"
"-f, --force Do not prompt user\n"
"-e, --encryption on|off Switch encryption on or off\n");
}
/*
* initialize the tape390_crypt info structure
*/
static void init_info(struct tape390_crypt *info)
{
info->delimiter = ':';
info->encryption_specified = 0;
info->query_specified = 0;
info->key_specified = 0;
info->delimiter_specified = 0;
info->force_specified = 0;
}
/*
* parse the commandline options
*/
static void tape390_crypt_parse_opts(struct tape390_crypt *info, int argc,
char* argv[])
{
int opt, index, kekl_too_long=0, deli_too_long=0, e_switch_invalid=0;
int i;
static struct option crypt_long_options[] = {
{ "version", no_argument, NULL, 'v'},
{ "encryption", required_argument, NULL, 'e'},
{ "query", no_argument, NULL, 'q'},
{ "key", required_argument, NULL, 'k'},
{ "help", no_argument, NULL, 'h'},
{ "delimiter", required_argument, NULL, 'd'},
{ "force", no_argument, NULL, 'f'},
{ NULL, 0, NULL, 0 }
};
/* Command line option abbreviations */
static const char crypt_option_string[] = "ve:qk:hd:f";
while (1) {
opt = getopt_long(argc, argv, crypt_option_string,
crypt_long_options, &index);
if (opt == -1)
break;
switch (opt) {
case 'v':
print_version();
exit(0);
case 'h':
tape390_crypt_usage();
exit(0);
case 'q':
++info->query_specified;
break;
case 'k':
++info->key_specified;
if(strlen(optarg) >= TOT_KEKL_LENGTH)
kekl_too_long = 1;
else if (info->key_specified == 1)
for (i = 0; i < 2; i++)
strcpy(info->kekl_input[i], optarg);
else
strcpy(info->kekl_input[1], optarg);
break;
case 'e':
++info->encryption_specified;
if (strcmp(optarg,"off") == 0)
info->e_switch = ENCRYPTION_OFF;
else if (strcmp(optarg,"on") == 0)
info->e_switch = ENCRYPTION_ON;
else
e_switch_invalid = 1;
break;
case 'd':
++info->delimiter_specified;
if(strlen(optarg) > 1)
deli_too_long = 1;
else
info->delimiter = optarg[0];
break;
case 'f':
++info->force_specified;
break;
default:
fprintf(stderr, "Try '%s --help' for more"
" information.\n",prog_name);
exit(1);
}
}
CHECK_SPEC_MAX(info->query_specified, 1, "once", "query");
CHECK_SPEC_MAX(info->encryption_specified, 1, "once", "encryption");
CHECK_SPEC_MAX(info->delimiter_specified, 1, "once", "delimiter");
CHECK_SPEC_MAX(info->force_specified, 1, "once", "force");
CHECK_SPEC_MAX(info->key_specified,2, "twice", "key");
if (kekl_too_long)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: Specified key too long.\n",prog_name);
if (deli_too_long)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: Delimiter must be one character.\n",prog_name);
if (e_switch_invalid)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: ERROR: encryption can be set 'on' or 'off'.\n",
prog_name);
if (((info->query_specified) &&
(info->key_specified + info->encryption_specified > 0)) ||
((info->encryption_specified) &&
(info->key_specified + info->query_specified > 0)) ||
((info->force_specified) &&
(info->encryption_specified)) ||
((info->delimiter_specified) &&
(info->encryption_specified + info->query_specified > 0)))
ERRMSG_EXIT(EXIT_MISUSE,
"%s: Conflicting options specified.\n",prog_name);
if (info->query_specified + info->encryption_specified +
info->key_specified == 0)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: ERROR: Missing options.\n",prog_name);
/* save device */
if (optind >= argc)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: No device specified.\n",prog_name);
if (optind + 1 < argc)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: More than one device specified.\n",prog_name);
strcpy(info->devname, argv[optind]);
}
/*
* check and parse key operand, must be value:type
* where value is an arbitrary string, maximal 64 char long
* : is a 1-char delimiter specified with the -d option (default :)
* type is the type identifier, which can be either 'hash' or 'label'
* default is 'label'
*/
static void fill_kekl(char *s, char delimiter,
struct tape390_kekl *mykekl)
{
int i;
char typestring[TOT_KEKL_LENGTH] = {0};
for (i = strlen(s); i >= 0; i--)
if (*(s+i) == delimiter)
break;
if (i == -1) /* delimiter not found, no type specified */
mykekl->type_on_tape = TAPE390_KEKL_TYPE_LABEL; /* default type*/
else if (i == 0)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: ERROR: delimiter '%c' found as first "
"character.\n",prog_name,delimiter);
else if (i == (int) strlen(s) - 1)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: ERROR: Delimiter '%c' found as last "
"character.\n",prog_name,delimiter);
else {
strcpy(typestring,s+i+1);
*(s+i) = '\0';
if (strcmp(typestring,"hash") == 0)
mykekl->type_on_tape = TAPE390_KEKL_TYPE_HASH;
else if (strcmp(typestring,"label") == 0)
mykekl->type_on_tape = TAPE390_KEKL_TYPE_LABEL;
else
ERRMSG_EXIT(EXIT_MISUSE,
"%s: Invalid key type '%s',"
" must be either 'label' or 'hash'.\n",
prog_name,typestring);
}
if (strlen(s) >= KEKL_LENGTH)
ERRMSG_EXIT(EXIT_MISUSE,
"%s: Specified key value too long, has %d chars.\n",
prog_name,(int)strlen(s));
else {
strcpy(mykekl->label, s);
mykekl->type = TAPE390_KEKL_TYPE_LABEL;
}
}
/*
* Write two tapemarks on tape to initialize tape after kekl set
*/
static int init_tape(int fd)
{
struct mtop mtop;
int rc;
mtop.mt_op = MTWEOF;
mtop.mt_count = 2;
rc = ioctl(fd, MTIOCTOP, &mtop);
if (rc)
return rc;
mtop.mt_op = MTREW;
return ioctl(fd, MTIOCTOP, &mtop);
}
/*
* Tell the current block on tape
*/
static int tell_tape(int fd)
{
struct mtop mtop;
mtop.mt_op = MTTELL;
mtop.mt_count = 1;
return ioctl(fd, MTIOCTOP, &mtop);
}
/*
* Do read IO to tape in order to enforce update of KEKL information.
* Leave tape position unchanged.
*/
static int read_tape(int fd)
{
struct mtop mtop;
int block_number, n_read;
char buffer[MAX_BLOCKSIZE];
/* remember current block on tape */
block_number = tell_tape(fd);
n_read = read(fd, buffer, sizeof(buffer));
if (n_read == -1) {
/* tape read failed, ignore if caused by end-of-volume */
if (errno == ENOSPC)
return 0;
else
return 1;
}
if (block_number != tell_tape(fd)) {
/* re-position tape */
mtop.mt_op = MTSEEK;
mtop.mt_count = block_number;
if (ioctl(fd, MTIOCTOP, &mtop) != 0)
return 1;
}
return 0;
}
/*
* set Key Encrypting Key labels
*/
static int set_encryption_keys(int fd, struct tape390_crypt *info)
{
struct tape390_kekl_pair kekls;
char delim;
char *s, inp_buffer[5];
int i, rc;
delim = info->delimiter;
for (i = 0; i < 2; i++) {
s = info->kekl_input[i];
fill_kekl(s, delim, &kekls.kekl[i]);
}
if (info->force_specified == 0) {
printf("--->> ATTENTION! <<---\n");
printf("All data on tape %s will be lost.\nType "
"\"yes\" to continue: ", info->devname);
if (fgets(inp_buffer, sizeof(inp_buffer), stdin) == NULL) {
fprintf(stderr, "Reading from terminal failed.\n");
exit(1);
}
if (strcasecmp(inp_buffer,"yes\n")) {
printf("Tape and its encryption keys "
"remain unchanged.\n");
exit(0);
}
}
rc = ioctl(fd, TAPE390_KEKL_SET, &kekls);
if (rc)
return rc;
return init_tape(fd);
}
/*
* Switch on/off encryption
*/
static int switch_encryption_on_or_off(int fd,struct tape390_crypt *info)
{
struct tape390_crypt_info myinfo;
memset(&myinfo, 0, sizeof(myinfo));
if (info->e_switch == ENCRYPTION_ON)
myinfo.status |= TAPE390_CRYPT_ON_MASK;
return ioctl(fd, TAPE390_CRYPT_SET, &myinfo);
}
/*
* Query information on encryption and keys
*/
static int query_encryption(int fd,struct tape390_crypt *info)
{
struct tape390_crypt_info myinfo;
struct tape390_kekl_pair kekls;
int i, ret;
ret = ioctl(fd, TAPE390_CRYPT_QUERY, &myinfo);
if (ret)
return -1;
if (!TAPE390_MEDIUM_LOADED(myinfo)) {
printf("Medium not loaded\n");
return 0;
}
printf("ENCRYPTION: ");
if (TAPE390_CRYPT_ON(myinfo))
printf("ON\n");
else
printf("OFF\n");
printf("MEDIUM: ");
if (TAPE390_MEDIUM_ENCRYPTED(myinfo))
printf("ENCRYPTED\n");
else {
printf("NOT ENCRYPTED\n");
return 0;
}
/*
* do a dummy read in order to force the control unit to get
* the key information from the EKM
*/
ret = read_tape(fd);
if (ret && (info->force_specified == 0))
return -2;
ret = ioctl(fd, TAPE390_KEKL_QUERY, &kekls);
if (ret)
return -2;
printf("KEKLs on TAPE:\n");
if (kekls.kekl[0].type == TAPE390_KEKL_TYPE_NONE) {
ERRMSG("Unable to retrieve key information.\n");
return 0;
}
for (i = 0; i < 2; i++) {
printf(" KEY%i:\n",i+1);
if (kekls.kekl[i].type == TAPE390_KEKL_TYPE_NONE)
printf("None\n");
else {
printf(" value: %s\n",kekls.kekl[i].label);
printf(" type: ");
PRINT_TYPE(kekls.kekl[i].type);
printf(" ontape: ");
PRINT_TYPE(kekls.kekl[i].type_on_tape);
}
}
return 0;
}
int main(int argc, char *argv[])
{
struct tape390_crypt info;
char error_msg[80];
int rc=0, fd=-1;
/* set name of program */
set_prog_name(basename(argv[0]));
/* set default values */
init_info(&info);
/* parse command line options and check syntax */
tape390_crypt_parse_opts(&info, argc, argv);
/* check whether specified device node is tape */
if (is_not_tape(info.devname))
exit(EXIT_MISUSE);
/* open device */
fd = open_tape(info.devname);
/* process -k or -e or -q operand */
if (info.key_specified >= 1) {
rc = set_encryption_keys(fd, &info);
if (rc == 0)
printf("SUCCESS: key information set.\n");
strcpy(error_msg, KEKL_SET_FAILED_MSG);
} else if (info.encryption_specified) {
rc = switch_encryption_on_or_off(fd, &info);
strcpy(error_msg, CRYPT_SET_FAILED_MSG);
} else if (info.query_specified) {
rc = query_encryption(fd, &info);
if (rc == -1)
strcpy(error_msg, CRYPT_QUERY_FAILED_MSG);
else if (rc == -2)
strcpy(error_msg, KEKL_QUERY_FAILED_MSG);
}
if (rc) {
ERRMSG(error_msg, prog_name);
switch (errno) {
case ENOKEY:
ERRMSG("EKM error.\n");
break;
case ENOTCONN:
ERRMSG("Could not connect to EKM.\n");
break;
case EKEYREJECTED:
ERRMSG("Key not available on EKM.\n");
break;
case EUNATCH:
ERRMSG("Encryption must be set ON prior to "
"setting or querying encryption "
"keys.\n");
break;
case EBADSLT:
ERRMSG("Tape must be at load point in order "
"to set encryption keys.\n");
break;
case ENOSYS:
ERRMSG("Tape device does not support "
"encryption.\n");
break;
case EINVAL:
ERRMSG("Kernel does not support tape "
"encryption.\n");
break;
default:
perror("");
}
}
if (fd != -1)
close(fd);
return(rc);
}

View File

@@ -1,150 +0,0 @@
.\" Copyright 2017 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH TAPE390_DISPLAY 8 "Apr 2006" "s390-tools"
.SH NAME
tape390_display \- display messages on the display unit of a zSeries tape
device.
.SH SYNOPSIS
.TP 16
.B tape390_display
.RB [ \-b | \-\-blink ]
.br
.RB [ \-h | \-\-help ]
.br
.RB [ \-l | \-\-load ]
.br
.RB [ \-t <type>| \-\-type <type>]
.br
.RB [ \-q | \-\-quiet ]
.br
.RB [ \-v | \-\-version ]
.br
.IR message1
.RB [
.I message2
.RB ]
.I device
.SH DESCRIPTION
\fBtape390_display\fR displays one or two 8-byte messages on the display
unit of a zSeries tape device. Characters to be displayed include capital
letters A-Z, numerics 0-9 and special characters.
However some special characters may not display on all device types. The
characters that should display on model 3490 are:
.br
'@$#,./()*&+-=%|:_<>?;' and the <cent> character.
.br
Spaces and shell-sensitive characters have to be quoted.
.SH OPTIONS
.TP 8
\fB\-h\fR or \fB\-\-help\fR
Print help text.
.TP
\fB\-b\fR or \fB\-\-blink\fR
Display \fImessage1\fR repeatedly for 2 seconds at half-second intervals.
This option is ignored if two messages are specified on command line.
.TP
\fB\-l\fR or \fB\-\-load\fR
If this option is given the display request will cause a load request to be
sent to the automatic tape loader (if installed). The next indexed tape will
then be loaded if the loader is in 'system' mode. Otherwise the request is
ignored.
.TP
\fB\-q\fR or \fB\-\-quiet\fR
This option causes the command to run in quiet mode which will suppress
all warning messages.
.TP
\fB\-t\fR \fItype\fR or \fB\-\-type\fR \fItype\fR
Set the type of the message to be displayed. This influences how long
the message(s) stay on the display. Available types are:
.RS
.TP 16
.B standard
The message(s) stay displayed until the drive executes the next tape
movement command. This is the default.
.TP
.B load
Displays the message(s) until a tape is loaded. If there already is
a tape loaded to the device, nothing is displayed at all.
.TP
.B unload
This will display the message(s) until currently loaded tape is unloaded.
Again, if the drive \fIis\fR currently unloaded there is no output at all.
.TP
.B noop
For testing purposes only, this will access the drive but won't do anything
at all (no operation). This doesn't seem to work with 3590 tape devices.
.TP
.B reload
This display type \fBrequires\fR two messages. The first message is
displayed as long as there is a tape loaded up to the time the unload
operation is completed (or, if there isn't a tape loaded, it will be
ignored). The second message is displayed as soon as a tape gets loaded
into the drive.
.RE
.TP
\fB\-v\fR or \fB\-\-version\fR
Print the S/390 tools package version, the utility version and exit.
.TP 8
\fBmessage1\fR [ \fBmessage2\fR ]
The message(s) to be displayed. They stay displayed until either the
ending condition for the message type takes place or the display is
updated with another message.
.br
If two messages are specified, they are alternated on the display.
Each message is then displayed repeatedly for 2 seconds
at half-second intervals.
.TP
\fBdevice\fR
The tape device on which the message(s) will be displayed, e.g.:
.sp
\fB/dev/ntibm\fR\fI0\fR
.br
.SH EXAMPLES
\fBtape390_display \-\-blink \-\-type unload "TESTING" /dev/ntibm\fR\fI0\fR
.RS
Let the message TESTING blink on the display of the tape unit until the
tape is removed (or another message is given). If there is no tape in the
drive, nothing happens.
.RE
\fBtape390_display "BACKUP" "COMPLETE" /dev/ntibm\fR\fI0\fR
.RS
This will display the messages BACKUP and COMPLETE each for 2 seconds
until the tape is moved, ejected or (if there isn't a tape in the
device) inserted.
.RE
\fBtape390_display \-\-type reload "UNLOAD" "LOAD" /dev/ntibm\fR\fI0\fR
.RS
The UNLOAD message will be displayed if there is a tape inserted and as
long as the tape isn't removed. After that the LOAD message is displayed
until a tape is inserted. If there is no tape inserted when the command
.RE
\fBtape390_display \-\-load \-\-type load "LOADING" /dev/ntibm\fR\fI0\fR
.RS
Causes the device to display the message LOADING until a tape is inserted
and to instruct the automatic stacker to load the next tape (if the mode
of operation is \fIsystem\fR). If there already is a tape loaded, nothing
will happen at all.
.RE
.SH AUTHOR
.nf
This man-page was written by Despina Papadopoulou<despina_p@de.ibm.com>
.nf
Updates by Stefan Bader<shbader@de.ibm.com>
.fi

View File

@@ -1,287 +0,0 @@
/*
* tape390_display - Display messages on the display unit of a tape drive
*
* Copyright IBM Corp. 2002, 2017
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include <ctype.h>
#include <getopt.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "lib/zt_common.h"
#include "tape390_common.h"
#define TAPE390_DISPLAY _IOW('d', 1, struct display_struct)
/*
* The TAPE390_DISPLAY belongs to linux-2.5/include/asm-s390/tape390.h
*
* The TAPE390_DISPLAY ioctl calls the Load Display command
* which transfers 17 bytes of data from the channel to the subsystem:
* - 1 format control byte, and
* - two 8-byte messages
*
* Format control byte:
* 0-2: New Message Overlay
* 3: Alternate Messages
* 4: Blink Message
* 5: Display Low/High Message
* 6: Reserved
* 7: Automatic Load Request
*
*/
#define TAPE_MSGTYPE_STANDARD 0
#define TAPE_MSGTYPE_UNLOAD 1
#define TAPE_MSGTYPE_LOAD 2
#define TAPE_MSGTYPE_NOOP 3
#define TAPE_MSGTYPE_UNLOAD_LOAD 7
typedef struct display_struct {
struct {
unsigned char type :3;
unsigned char alternate :1;
unsigned char blink :1;
unsigned char use_second :1;
unsigned char reserved :1;
unsigned char load_request :1;
} cntrl;
char message1[8];
char message2[8];
} __attribute__ ((packed)) display_struct;
/* definitions */
static char *help_text =
"tape390_display: display one or two 8-byte messages on the display"
"unit of a tape drive\n"
"\n"
"Usage: tape390_display <options> \"<message1>\" [\"<message2>\"] "
"<device>"
"\n\n"
"where <options> are:\n"
"\t-b | --blink\n"
"\t\twill cause a single message to blink every 2 seconds\n"
"\t\t(this option has only effect with a single message)\n"
"\t-h | --help\n"
"\t\tprint this text\n"
"\t-v | --version\n"
"\t\toutput version information and exit\n"
"\t-l | --load\n"
"\t\twill try to load the next tape if the loader is in system mode\n"
"\t-q | --quiet\n"
"\t\twill suppress all warning messages\n"
"\t-t | --type \"standard|load|unload|noop|reload\"\n"
"\t\tcontrols how the message is displayed:\n"
"\t\t\tstandard = until the next tape movement (default)\n"
"\t\t\tload = until a tape is loaded\n"
"\t\t\tunload = until a tape is unloaded\n"
"\t\t\tnoop = not at all (test purposes)\n"
"\t\t\treload = message1 until tape is unloaded and message2\n"
"\t\t\t when the next tape is loaded\n"
"\n"
"Note: Characters to be displayed include capital letters (A-Z), "
"numerics (0-9)\n"
"and special characters within single quotes. However not all "
"characters\n"
"might be displayed on all tape devices. Special characters that "
"are supported\n"
"for 3490 are '@$#,./()*&+-=%|:_<>?;'.\n";
static int quiet;
/* end of definitions */
static int typename2int(char *name)
{
char *typenames[] = {
"standard",
"unload",
"load",
"noop",
NULL,
NULL,
NULL,
"reload"
};
int i;
for(i = 0; i < 8; i++) {
if(typenames[i] == NULL)
continue;
if(strcmp(typenames[i], name) == 0) {
return i;
}
}
fprintf(stderr, "Invalid message type <%s>\n", name);
return -1;
}
static void strchkcpy(char *tgt, const char *src)
{
static char *nowarn = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
"@$#,./'()*&+-=%:_<>?; ";
char c;
char warned;
warned = 0;
for(c=0; c<8 && *(src+c); c++) {
*(tgt+c) = toupper(*(src+c));
if (index(nowarn, *(tgt+c)) == NULL && !quiet && !warned) {
fprintf(
stderr,
"WARNING: Some special characters may not "
"display on all device types.\n"
);
warned = 1;
}
}
}
int main(int argc, char *argv[]) {
char *options = "hblqt:v";
struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "blink", no_argument, NULL, 'b' },
{ "load", no_argument, NULL, 'l' },
{ "quiet", no_argument, NULL, 'q' },
{ "type", required_argument, NULL, 't' },
{ "version", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
};
char *pathname;
int c;
int fd, ret = 0;
struct display_struct ds;
/* set name of program */
set_prog_name(basename(argv[0]));
memset(&ds, 0, sizeof(ds));
ds.cntrl.type = TAPE_MSGTYPE_STANDARD;
while(
(c = getopt_long(argc, argv, options, long_options, NULL))
!= EOF
) {
switch(c) {
case 'h':
fprintf(stdout, "%s", help_text);
exit(0);
case 'b':
ds.cntrl.blink = 1;
break;
case 'l':
ds.cntrl.load_request = 1;
break;
case 'q':
quiet = 1;
break;
case 't': {
int type = typename2int(optarg);
if(type < 0)
exit(1);
ds.cntrl.type = type;
break;
}
case 'v': {
printf("tape390_display: zSeries tape "
"display control program version %s\n",
RELEASE_STRING);
printf("Copyright IBM Corp. 2002, 2017\n");
exit(0);
}
default:
fprintf(stderr, "Try '%s --help' for more"
" information.\n",prog_name);
exit(1);
}
}
if(optind + 2 < argc ) {
if(
ds.cntrl.type == TAPE_MSGTYPE_LOAD &&
ds.cntrl.load_request
) {
if(!quiet) {
fprintf(
stderr,
"WARNING: "
"A <load> message with the "
"--load option will only "
"display the first"
"\nmessage.\n"
);
}
} else if(
ds.cntrl.type == TAPE_MSGTYPE_UNLOAD_LOAD &&
ds.cntrl.load_request
) {
if(!quiet) {
fprintf(
stderr,
"WARNING: "
"A <reload> message with the "
"--load option will only "
"display the second"
"\nmessage.\n"
);
}
} else {
ds.cntrl.alternate = 1;
if(ds.cntrl.blink) {
ds.cntrl.blink = 0;
if(!quiet) {
fprintf(
stderr,
"Alternate messages "
"override blinking\n"
);
}
}
}
strchkcpy(ds.message1, argv[optind]);
strchkcpy(ds.message2, argv[optind+1]);
pathname = argv[optind+2];
} else if(optind + 1 < argc) {
if(ds.cntrl.type == TAPE_MSGTYPE_UNLOAD_LOAD) {
fprintf(stderr, "Reload message type requires "
"two messages.\n");
exit(1);
} else if(ds.cntrl.type == TAPE_MSGTYPE_LOAD) {
strchkcpy(ds.message2, argv[optind]);
}
strchkcpy(ds.message1, argv[optind]);
pathname = argv[optind+1];
} else {
fprintf(stderr, "%s", help_text);
exit(1);
}
/* check whether specified device node is tape */
if (is_not_tape(pathname))
exit(EXIT_MISUSE);
/* open device */
fd = open_tape(pathname);
ret = ioctl(fd, TAPE390_DISPLAY, &ds);
if (ret != 0)
fprintf(stderr, "TAPE390_DISPLAY failed\n");
close(fd);
return ret;
}