📄 rzdisk.c
字号:
#ifndef lintstatic char *sccsid = "@(#)rzdisk.c 4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1984,86,87,88 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * rzdisk.c 12-Sep-88 * * SCSI Disk Utility Source File * * Modification history: * * 13-Dec-88 Alan Frechette * Fixed a bug which caused a core dump when you type "rzdisk" * with no parameters. Changed some error messages. Fixed the * displaying of the menu. * * 09-Dec-88 Alan Frechette * Reworked getting and changing disk drive parameters. Made * extensive changes to these routines to get it to work in * all cases. Added the option of getting the CHANGEABLE * parameters from the disk drive. The CHANGEABLE parameters * returns a bit pattern of the bits that can be changed * within a particular field. * * 06-Dec-88 Alan Frechette * Fixed "reassign_bad_block()" to retry the read of the bad * block upto 5 times. Also always write the data back to * the reassigned block even if the data is bad. The user * may still be able to recover from this by running "fsck". * * Fixed a bug in "disk_mounted()" when searching for mounted * file systems. * * 12-Sep-88 Alan Frechette * Created this utility for the maintainence of scsi disks. * * IMPORTANT NOTE: * This utility is guarrenteed to support all DEC disk drives * only. The current DEC disk devices that are supported by * this utility are the (RZ55, RZ23, RZ22, and RRD40) disks. * This utility may not work correctly with NON-DEC scsi disk * drives due to the differences in scsi from one vendor to * the next. * ************************************************************************/#include <stdio.h>#include <signal.h>#include <sys/types.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/wait.h>#include <sys/param.h>#include <sys/mount.h>#include <sys/errno.h>#include <ufs/fs.h>#ifdef mips#include <sys/rzdisk.h>#else#include "rzdisk.h"#endif mipsint rzdev = -1;char rzdisk[40];int rzcom;int infobyte;int asc;struct read_defect_params rdp;struct format_params fp;struct reassign_params rp;struct verify_params vp;struct defect_descriptors dd;struct mode_sel_sns_params ms;struct mode_sel_sns_params msc;struct inquiry_info inq;#define MSIZE (NMOUNT*sizeof(struct fs_data))#define NUMTITLES 9int fields[2*NUMTITLES] = {-12,12,-8,8,-8,8,-8,8,-6,6,-8,8,-8,8,-4,4,-8,8};int num_fields[2*NUMTITLES] = {-12,12,8,8,8,8,8,8,6,0,8,8,8,8,6,0,-8,8}; main(argc,argv)int argc;char *argv[];{ int lbn,length,i,j; u_char defect_format; int fmt_defect_lists; int page_control; if(argc == 1) { print_help(); exit(0); } if(argv[1][0] != '-') { printf("\nNo option specified, type \"rzdisk -h\" for help.\n"); exit(1); } switch(argv[1][1]) { case 'h': if(argc != 2) { printf("\nUsage: rzdisk -h.\n"); exit(1); } print_help(); break; case 'i': if(argc != 3) { printf("\nUsage: rzdisk -i special.\n"); exit(1); } open_special_file(argv[2]); get_inquiry_info(); break; case 'c': if(argc != 3 && argc != 4 || (argc == 4 && strcmp(argv[2],"ask") != 0)) { printf("\nUsage: rzdisk -c [ask] special.\n"); exit(1); } if(argc == 4) { open_special_file(argv[3]); change_drive_parameters(1); } else { open_special_file(argv[2]); change_drive_parameters(0); } break; case 'g': if(argc != 4) { printf("\nUsage: rzdisk -g (current|saved|default|changeable) special.\n"); exit(1); } if(strcmp(argv[2],"current") == 0) page_control = CURRENT_VALUES; else if(strcmp(argv[2],"saved") == 0) page_control = SAVED_VALUES; else if(strcmp(argv[2],"default") == 0) page_control = DEFAULT_VALUES; else if(strcmp(argv[2],"changeable") == 0) page_control = CHANGED_VALUES; else { printf("\nUsage: rzdisk -g (current|saved|default|changeable) special.\n"); exit(1); } open_special_file(argv[3]); get_drive_parameters(page_control); break; case 'f': if(argc != 4) { printf("\nUsage: rzdisk -f (vendor|known) special.\n"); exit(1); } if(strcmp(argv[2],"vendor") == 0) fmt_defect_lists = VENDOR_DEFECTS; else if(strcmp(argv[2],"known") == 0) fmt_defect_lists = KNOWN_DEFECTS; else { printf("\nUsage: rzdisk -f (vendor|known) special.\n"); exit(1); } open_special_file(argv[3]); if(rzdisk[strlen(rzdisk) - 1] != 'c') { printf("\nMust specify (c) partition for -f option.\n"); exit(1); } format_a_disk(fmt_defect_lists); break; case 'r': if(argc != 4 || !isinteger(argv[2])) { printf("\nUsage: rzdisk -r LBN special.\n"); exit(1); } lbn = atoi(argv[2]); open_special_file(argv[3]); if(rzdisk[strlen(rzdisk) - 1] != 'c') { printf("\nMust specify (c) partition for -r option.\n"); exit(1); } reassign_bad_block(lbn); break; case 's': if(argc != 5 || !isinteger(argv[2]) || !isinteger(argv[3])) { printf("\nUsage: rzdisk -s LBN length special.\n"); exit(1); } lbn = atoi(argv[2]); length = atoi(argv[3]); open_special_file(argv[4]); scan_for_bad_blocks(lbn,length); break; case 'd': if(argc != 4) { printf("\nUsage: rzdisk -d (bfi|sector|block) special.\n"); exit(1); } if(strcmp(argv[2],"bfi") == 0) defect_format = BFI_FORMAT; else if(strcmp(argv[2],"sector") == 0) defect_format = PHY_FORMAT; else if(strcmp(argv[2],"block") == 0) defect_format = BLK_FORMAT; else { printf("\nUsage: rzdisk -d (bfi|sector|block) special.\n"); exit(1); } open_special_file(argv[3]); read_defects(defect_format); break; default: printf("\nBad option (-%c), type \"rzdisk -h\" for help.\n", argv[1][1]); exit(1); break; }}open_special_file(special)char *special;{ strcpy(rzdisk,special); if(strncmp(special,"/dev/",5) == 0 && strncmp(special,"/dev/rr",7) != 0) { printf("\nMust specify raw device special file.\n"); exit(1); } if(strncmp(special,"/dev/rrz",8) != 0) { printf("\nMust specify special file of the form (/dev/rrz??).\n"); exit(1); } if((rzdev = open(rzdisk, O_RDWR)) == -1) { printf("\nCannot open SCSI device (%s) exiting.\n",rzdisk); exit(1); }}isinteger(string)char *string;{ if(*string == '-' || *string == '+') ++string; while(*string) { if((*string >= '0' && *string <= '9') || (*string == '-') || (*string == '+')) ++string; else return(0); } return(1);}print_help(){ printf("\n\n"); printf("\t\t********************************\n"); printf("\t\t**** SCSI Disk Utility Menu ****\n"); printf("\t\t********************************\n"); printf("\n\tUsage: rzdisk -cdfghirs [LBN|command] [length] special.\n\n"); printf("rzdisk -f vendor /dev/rrz0c\tFormats disk with VENDOR only defects.\n"); printf("rzdisk -f known /dev/rrz0c\tFormats disk with all KNOWN defects.\n"); printf("rzdisk -r 1234 /dev/rrz0c\tReassigns bad block (1234).\n"); printf("rzdisk -s 0 -1 /dev/rrz0c\tScans the entire disk for bad blocks.\n"); printf("rzdisk -s 0 -1 /dev/rrz0g\tScans partition (g) for bad blocks.\n"); printf("rzdisk -i /dev/rrz0c\t\tPrints out the inquiry data info.\n"); printf("rzdisk -d bfi /dev/rrz0c\tReads defect list in BFI format.\n"); printf("rzdisk -d sector /dev/rrz0c\tReads defect list in SECTOR format.\n"); printf("rzdisk -d block /dev/rrz0c\tReads defect list in BLOCK format.\n"); printf("rzdisk -c /dev/rrz0c\t\tChanges disk parameters to DEFAULT VALUES.\n"); printf("rzdisk -c ask /dev/rrz0c\tChanges disk parameters interactively.\n"); printf("rzdisk -g current /dev/rrz0c\tGets CURRENT disk drive parameters.\n"); printf("rzdisk -g saved /dev/rrz0c\tGets SAVED disk drive parameters.\n"); printf("rzdisk -g default /dev/rrz0c\tGets DEFAULT disk drive parameters.\n"); printf("rzdisk -g changeable /dev/rrz0c\tGets CHANGEABLE disk drive parameters.\n"); printf("rzdisk -h\t\t\tPrints out this help menu.\n");}format_a_disk(fmt_defect_lists)int fmt_defect_lists;{ int pid, i; long thetime; char *ctime(); char prodid[17]; bzero((char *)&inq, sizeof(inq)); if(execute_rzcmd(SCSI_GET_INQUIRY_DATA, (char *)&inq) != SUCCESS) { geterror(); return; } else { for(i=0; i<16; i++) prodid[i] = inq.prodid[i]; prodid[i] = NULL; /* * FORMAT UNIT not supported on RRD40 disk. */ if(strncmp(prodid,"RRD40",5) == 0) { printf("\nFormat Unit unsupported on device (%s).\n", rzdisk); return; } } if(disk_mounted()) return; printf("\nFORMATTING A DISK DESTROYS ALL DATA!!!\n"); printstr("\nARE YOU SURE (y/n)? "); if(!confirm()) return; printf("\nYOU ARE FORMATTING THE DEVICE (%s)!!!\n",rzdisk); printstr("\nIS THIS CORRECT (y/n)? "); if(!confirm()) return; bzero((char *)&dd, sizeof(dd)); fp.fp_format = BLK_FORMAT; fp.fp_interleave = 1; fp.fp_pattern = 0; fp.fp_defects = fmt_defect_lists; fp.fp_length = (dd.dd_header.rdd_hdr.defect_len0 & 0x00ff) + ((dd.dd_header.rdd_hdr.defect_len1 << 8) & 0xff00); dd.dd_header.fu_hdr.vu = 0; dd.dd_header.fu_hdr.dcrt = 0; dd.dd_header.fu_hdr.dpry = 0; fp.fp_addr = (u_char *)ⅆ /* * Skip MODE SENSE/MODE SELECT for RZ22/RZ23 disks. */ if(strncmp(prodid,"RZ22",4) == 0 || strncmp(prodid,"RZ23",4) == 0) { dd.dd_header.fu_hdr.fov = 0; dd.dd_header.fu_hdr.stpf = 0; goto skip_mode_select; } else { dd.dd_header.fu_hdr.fov = 1; dd.dd_header.fu_hdr.stpf = 1; } bzero((char *)&ms, sizeof(ms)); ms.ms_pgcode = 0x3f; ms.ms_length = sizeof(ms) - 4; ms.ms_pgctrl = SAVED_VALUES; if(execute_rzcmd(SCSI_MODE_SENSE, (char *)&ms) != SUCCESS) { geterror(); return; } ms.ms_hdr.sense_len = 0; ms.ms_page1.ps = 0; ms.ms_page2.ps = 0; ms.ms_page3.ps = 0; ms.ms_page4.ps = 0; ms.ms_page37.ps = 0; ms.ms_setps = 1; if(ms.ms_page37.pgcode == 37) ms.ms_length = sizeof(ms) - 4; else ms.ms_length = sizeof(ms) - sizeof(ms.ms_page37) - 4; if(execute_rzcmd(SCSI_MODE_SELECT, (char *)&ms) != SUCCESS) { geterror(); return; }skip_mode_select: printf("\nFormatting device (%s).\n",rzdisk); if((pid = fork()) == 0) { for(;;) { time(&thetime); printf("\tworking ..... %s",ctime(&thetime)); sleep(120); } } sleep(2); if(execute_rzcmd(SCSI_FORMAT_UNIT, (char *)&fp) != SUCCESS) { kill(pid, SIGKILL); geterror(); } else { kill(pid, SIGKILL); printf("Done formatting device (%s).\n",rzdisk); }}disk_mounted(){ int i,ret; struct fs_data *fd; char *malloc(); int loc; int big; struct fs_data *mountbuffer; char temp[40]; char *p; mountbuffer = (struct fs_data *) malloc(MSIZE); if(mountbuffer == NULL) { printf("\nUnable to get system memory.\n"); return(-1); } loc = 0; ret = getmnt(&loc,mountbuffer,MSIZE,STAT_MANY,0); if(ret < 0) { printf("\nUnable to get mounted file system info.\n"); return(-1); } big = 0; for(fd=mountbuffer; fd < &mountbuffer[ret]; fd++) { i = strlen(fd->fd_devname); if(i > big) big=i; } fields[0] = -big; fields[1] = big; num_fields[0] = -big; num_fields[1] = big; strcpy(temp,"/dev/r"); p = &rzdisk[strlen("/dev/rr")]; i = 6; while(*p) temp[i++] = *p++; temp[--i] = NULL; for(fd=mountbuffer; fd < &mountbuffer[ret]; fd++) { if(strncmp(temp,fd->fd_devname,strlen(temp)) == 0) { printf("\nTHE DEVICE (%s) HAS MOUNTED FILESYSTEMS!!!\n", rzdisk); printf("\nCANNOT FORMAT A DISK THAT'S MOUNTED!!!\n"); printf("\nUNMOUNT ALL FILESYSTEMS BEFORE FORMATTING!!!\n"); return(1); } } return(0);}reassign_bad_block(lbn)int lbn;{ char buffer[512];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -