📄 tapetest.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)tapetest.c 1.1 92/07/30 Copyright Sun Micro";#endif/* * Copyright (c) 1988 by Sun Microsystems, Inc. */#include <stdio.h>#include <signal.h>#include <errno.h>#include <ctype.h>#include <sys/types.h>#include <sys/dir.h>#include <sys/file.h>#include <sys/param.h>#include <sys/ioctl.h>#include <sundev/tmreg.h>#include <sundev/xtreg.h>#include <sundev/arreg.h>#include "sdrtns.h" /* sundiag standard header file */#include "../../../lib/include/libonline.h"#include "tapetest.h"#include "tapetest_msg.h"#include <sys/mtio.h>#include <sys/buf.h>#include <sun/dkio.h>#include <sundev/scsi.h>extern char *sprintf();extern int process_tape_args();extern int routine_usage();static char *print_error_key();static short error_key_code=0;struct mt_tape_info tapes[]=MT_TAPE_INFO;short t_type;Tape_type tape_type;int pass = 0;char device_tapename[50];char tname[50];char device_file[50];char *device = device_tapename; int do_file = FALSE;int skip_retension = FALSE;int switch_8_and_0 = FALSE;int cart_tape = FALSE;int run_recon = FALSE;int read_only = FALSE;int test_all = FALSE;int flt=FALSE;#ifdef NEWint exb8500=FALSE;#endif NEWint no_comp=TRUE;int read_compare = FALSE;int after_op_sleep=1;int eot=TRUE; /* default to TRUE, if eot test */int do_sleep = TRUE; /* TRUE, if sleep between operation */char nonrewind[52];char *which_io;unsigned nblks= -1; /* initialized to MAXINT */struct commands com[] = { { "fsf", MTFSF, 1, 1 }, { "nbsf", MTNBSF, 1, 1 }, { "rewind", MTREW, 1, 0 }, { "status", MTNOP, 1, 0 }, { "retension", MTRETEN,1, 0 }, { "erase", MTERASE,0, 0 }, { 0 }};static u_long lcheck();static int density_code, device_arg = FALSE;/* * tapetest checks the status, rewinds the tape, erases/retensions it * if it's a cartridge tape, writes a pattern to nblks or eot(default), * rewinds the tape, and then does a read and compare of the pattern. * tapetest will first write "large blocks": * (NBLOCKS * BLOCKSIZE) = 126 * 512 = 64512 * and then writes out whatever "small blocks" are left: * BLOCKSIZE = 512 * If "file test(ft)" is enabled, tapetest also writes 3 files, * and tests the forward space file (Xylogics and SCSI) and backward space * file (SCSI only) tape options (see mtio(4)). * Note that the Xylogics tape driver does not currently support erase, * bsf, and eot(see bugs database on elmer). */main(argc, argv) int argc; char *argv[];{ versionid = "1.38"; /* get sccs version id */ test_init(argc, argv, process_tape_args, routine_usage, test_usage_msg); if (!device_arg) { display_usage(test_usage_msg); send_message (USAGE_ERROR, ERROR, devname_err_msg); } valid_dev_name(); mt_command(tape_status, device, 0, 0); setup_params(); run_tests(); test_end();}/* * process_test_args() - special tapetest arguments */process_tape_args(argv, arrcount)char *argv[];int arrcount;{ if (strncmp(argv[arrcount], "D=/dev/", 2) == 0) { device_name = device_file; (void)strcpy(device, &argv[arrcount][2]); (void)strcpy(device_name, device+6); if (*(device+6) == 'x') *(device+6) = 'm'; device_arg = TRUE; } else if (strcmp(argv[arrcount], "nr") == 0) skip_retension = TRUE; else if (strcmp(argv[arrcount], "sq") == 0) switch_8_and_0 = TRUE; else if (strcmp(argv[arrcount], "ns") == 0) do_sleep = FALSE; else if (strncmp(argv[arrcount], "b=", 2) == 0) { eot = FALSE; nblks = atoi(argv[arrcount]+2); } else if (strncmp(argv[arrcount], "ro", 2) == 0) read_only = TRUE; else if (strncmp(argv[arrcount], "ft", 2) == 0) do_file = TRUE; else if (strncmp(argv[arrcount], "rc", 2) == 0) run_recon = TRUE; else if (exec_by_sundiag && strncmp(argv[arrcount], "op=", 3) == 0) process_sundiag_option(atoi(argv[arrcount]+3)); else return (FALSE); return (TRUE);}/* * process_sundiag_option(), translates the encoded sundiag test options. */process_sundiag_option(code) unsigned code;{ int tmp; density_code = code & 7; if ((tmp = (code & 0x18) >> 3) != 0) eot = FALSE; if (tmp == 1) nblks = 25300; /* default */ else if (tmp == 2) /* long */ nblks = 70000; else if (tmp == 3) /* short */ nblks = 1000; read_only = code & 0x100; do_file = !(code & 0x20); do_sleep = !(code & 0x40); run_recon = code & 0x80; skip_retension = code & 0x200;}/* * routine_usage() - usage arguments specific to tapetest */routine_usage(){ send_message(0, CONSOLE, routine_msg, test_name);}/* * valid_dev_name(), * make sure that it's a character device, see if it's SCSI (st), * Archive (ar), or Xylogics (mt), and get the unit number -> */valid_dev_name(){ char *pbuf; func_name = "valid_dev_name"; TRACE_IN pbuf = device+5; if (*pbuf != 'r') send_message(-BAD_DEVICE_NAME, ERROR, devfile_err_msg, device); pbuf++; if (!strncmp(pbuf, "st", 2)) tape_type = st; else if (!strncmp(pbuf, "mt", 2)) tape_type = mt; else send_message(-BAD_DEVICE_NAME, ERROR, bad_devfile_msg, device); t_type = 0; mt_command(tape_status, device, 0, 0); /* Get tape information */ if (t_type == MT_ISHP || t_type == MT_ISKENNEDY) { flt_dev(); /* FLT device, check for "compression" mode */ }#ifdef NEW if (t_type == MT_ISEXB8500) { exb8500_dev(); /* EXB8500 device, check for "compression" mode */ } if (flt || exb8500) #else NEW if (flt) #endif NEW switch_8_and_0 = FALSE; /* always run one density at a time */ else if (tape_type == mt) { if (density_code == 2) switch_dev(); /* 6250-BPI */ else if (density_code == 0) switch_8_and_0 = TRUE;/* Both */ } else if (density_code == 1) switch_dev(); /* QIC-24 */ else if (density_code == 2) switch_8_and_0 = TRUE; /* QIC-11&QIC-24 */ TRACE_OUT}setup_params(){ func_name = "setup_params"; TRACE_IN if (read_only && do_file && !exec_by_sundiag) send_message(0, VERBOSE, read_only_msg); if (quick_test && nblks > 500) nblks = (3 * NBLOCKS) + 4; /* 3 large blocks, 4 small blocks */ if (tape_type == st) cart_tape = TRUE; if (do_sleep && nblks > 1000) after_op_sleep = 60; if (quick_test) do_sleep = FALSE; TRACE_OUT}run_tests(){ register max_pass; func_name = "run_tests"; TRACE_IN send_message(0, VERBOSE, "Test started."); if (do_sleep) { send_message(0, VERBOSE, sharing_msg); sleep(60); } send_message(0, VERBOSE, rewind_msg); mt_command(rewind, device, 0, 0); /* Rewind tape */ if (do_sleep) sleep(10);#ifdef NEW if (cart_tape && !skip_retension && !quick_test && !flt && !exb8500) {#else NEW if (cart_tape && !skip_retension && !quick_test && !flt) {#endif NEW if (read_only) { send_message(0, VERBOSE, retension_msg); mt_command(retension, device, 0, 0); } else { send_message(0, VERBOSE, erase_msg); mt_command(erase, device, 0, 0); } if (do_sleep) sleep(after_op_sleep); } pass = 0; while (TRUE) { /* until break */ if (flt) max_pass = 3;#ifdef NEW else if (exb8500) max_pass = 2;#endif NEW else max_pass = 0; ++pass; dev_test(); if (do_file && !read_only) file_test(); if (switch_8_and_0 && pass != 2) { send_message(0, VERBOSE, switch_2nd_msg); switch_dev(); } else if (test_all && (pass < max_pass || (pass == max_pass && !no_comp))) { send_message(0, VERBOSE, switch_next_msg, pass + 1); sprintf(device+8, "%d", atoi(device+8) + 8); /* next_dev */ } else break; }#ifdef NEW if (run_recon && !flt && !exb8500) {#else NEW if (run_recon && !flt) {#endif NEW send_message(0, VERBOSE, reconnect_msg); recon(); } send_message(0, VERBOSE, "Test passed."); if (!cart_tape && do_sleep) { /* if 1/2 tapes */ send_message(0, VERBOSE, sleep_msg); sleep(12*60); /* sleep for 12 minutes */ } TRACE_OUT}/* * switch_dev() - switches the device name between the QIC-11 * and QIC-24 SCSI tape device names */switch_dev(){ int dev_num; func_name = "switch_dev"; TRACE_IN if ((dev_num = atoi(device+8)) < 8) dev_num += 8; else dev_num -= 8; sprintf(device+8, "%d", dev_num); TRACE_OUT}/* * flt_dev() - generate proper device file for the front load tape drives. */flt_dev(){ int xfd ; func_name = "flt_dev"; TRACE_IN flt = TRUE; (void)sprintf(tname, "/dev/rst%d", 24 + atoi(device+8)); if ((xfd=open(tname, O_RDONLY)) != -1) no_comp = FALSE; /* yes it supports "compression" mode */ switch(density_code) { case 0: break; case 1: sprintf(device+8, "%d", 8 + atoi(device+8)); break; case 2: sprintf(device+8, "%d", 16 + atoi(device+8)); break; case 4: sprintf(device+8, "%d", 24 + atoi(device+8)); break; default: test_all = TRUE; } if ( xfd != -1 ) close(xfd); TRACE_OUT}#ifdef NEW/* * exb8500_dev() - generate proper device file for the exabyte 8500 tape drives. */exb8500_dev(){ int xfd ; func_name = "exb8500_dev"; TRACE_IN exb8500 = TRUE; (void)sprintf(tname, "/dev/rst%d", 16 + atoi(device+8)); if ((xfd=open(tname, O_RDONLY)) != -1) no_comp = FALSE; /* yes it supports "compression" mode */ switch(density_code) { case 0: break; case 1: sprintf(device+8, "%d", density_code*8 + atoi(device+8)); break; case 3: sprintf(device+8, "%d", 16 + atoi(device+8)); break; default: test_all = TRUE; } if ( xfd != -1 ) close(xfd); TRACE_OUT}#endif NEWdev_test(){ func_name = "dev_test"; TRACE_IN send_message(0, VERBOSE, start_test_msg, "tape", device); if (!read_only) { if (eot) send_message(0, VERBOSE, write_end_msg); else send_message(0, VERBOSE, write_blk_msg, nblks); write_file(FILE_1); send_message(0, VERBOSE, rewind_after_msg, "write"); mt_command(rewind, device, 0, 0); if (do_sleep) sleep(after_op_sleep); } if (eot) send_message(0, VERBOSE, read_end_msg); else send_message(0, VERBOSE, read_blk_msg, nblks); read_file(FILE_1); send_message(0, VERBOSE, rewind_after_msg, "read"); mt_command(rewind, device, 0, 0); if (do_sleep) sleep(after_op_sleep); TRACE_OUT}/* * file_test- write 4 files, and check out forward space and (SCSI only) * backward space file. */file_test(){ int save_eot, save_nblks; func_name = "file_test"; TRACE_IN send_message(0, VERBOSE, start_test_msg, "file", device); save_eot = eot; save_nblks = nblks; eot = FALSE; send_message(0, VERBOSE, file_test_msg, "writing"); nblks = (2 * NBLOCKS) + 2; /* 2 large blocks, 2 small blocks */ write_file(FILE_1); nblks = (3 * NBLOCKS) + 2; /* 3 large blocks, 2 small blocks */ write_file(FILE_2); nblks = (1 * NBLOCKS) + 2; /* 1 large block, 2 small blocks */ write_file(FILE_3); nblks = (2 * NBLOCKS) + 3; /* 2 large blocks, 3 small blocks */ write_file(FILE_4); send_message(0, VERBOSE, rewind_after_msg, "writing files."); mt_command(rewind, device, 0, 0); if (do_sleep) sleep(20); /* start reading here */ send_message(0, VERBOSE, file_test_msg, "reading"); nblks = (1 * NBLOCKS) + 0; /* read part way into first file */ read_file(FILE_1); mt_command(fsf, device, 1, 0); /* forward space file to second file */ nblks = (3 * NBLOCKS) + 2; /* read second file */ read_file(FILE_2); mt_command(fsf, device, 1, 0); /* forward space file to third file */ eot = TRUE; /* fake eot flag */ send_message(0, VERBOSE, "File test, reading to eof on 3rd file."); nblks = (1 * NBLOCKS) + 2 + 1; /* read to eof on third file */ read_file(FILE_3); send_message(0, VERBOSE, "File test, reading to eof on 4th file."); nblks = (2 * NBLOCKS) + 3 + 1; /* read to eof on 4th file */ read_file(FILE_4); eot = FALSE; if (tape_type == st) { /* if SCSI */ send_message(0, VERBOSE, "Backspacing to start of 2nd file."); mt_command(nbsf, device, 3, 0); /* back space file to second file */ send_message(0, VERBOSE, "Reading 2nd file again."); nblks = (3 * NBLOCKS) + 2; /* read second file */ read_file(FILE_2); } send_message(0, VERBOSE, rewind_after_msg, "reading files."); mt_command(rewind, device, 0, 0); if (do_sleep) sleep(20); eot = save_eot; nblks = save_nblks; TRACE_OUT}/* * write_file(file_num) - opens the device, writes * all the possible large blocks (126 * 512), then whatever small blocks (512), * closes the file, and returns 0 if no problem, otherwise returns -1 * if (eot), the write routines return 1 if the returned byte count <cc> * is not equal to <nbytes>. * Note that there is a bug in the Xylogics tape driver * w/writing to eot. file_num is used to encode which file is being written * to as part of the lfill/lcheck pattern, so we can make sure later that * we're reading the right file. */static int write_file(file_num)int file_num;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -