📄 rzdisk.c
字号:
ms.ms_length -= sizeof(ms.ms_page8); byteptr = (u_char *)&ms.ms_page8; ms_page37 = *((struct page_code_37 *)byteptr); } else ms_page37 = ms.ms_page37; /* Adjust the length if no page 37 */ if(ms_page37.pgcode != 37) ms.ms_length -= sizeof(ms_page37); /* * Write the DRIVE PARAMETERS using the MODE SELECT command. */ execute_rzcmd(SCSI_MODE_SELECT, (char *)&ms); /* * Start FORMATTING the disk. */start_format: 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) { if(geterror() != NO_ERROR) { kill(pid, SIGKILL); return; } } 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]; int baddata; off_t offset; int retries = 5; int i; char prodid[17]; bzero((char *)&inq, sizeof(inq)); execute_rzcmd(SCSI_GET_INQUIRY_DATA, (char *)&inq); for(i=0; i<16; i++) prodid[i] = inq.prodid[i]; prodid[i] = NULL; /* * REASSIGN BLOCK not supported on RRD40 disk. */ if(strncmp(prodid,"RRD40",5) == 0) { printf("\nReassign Block unsupported on device (%s).\n",rzdisk); return; } /* * Read the data from the bad block before doing * the reassign and save it in a temporary buffer. * Set "baddata" flag if we could not read the data * in the bad block. */ bzero(buffer, 512); offset = lbn * 512; while(retries--) { lseek(rzdev, offset, 0); if(read(rzdev, buffer, 512) == -1) baddata = 1; else { baddata = 0; break; } } /* * Initialize the defect header and the defect list. Note * that there is only 1 block that is reassigned at a time * so the defect list length is set to four (4). */ bzero((char *)&rp, sizeof(rp)); rp.rp_lbn3 = ((lbn >> 24) & 0xff); rp.rp_lbn2 = ((lbn >> 16) & 0xff); rp.rp_lbn1 = ((lbn >> 8) & 0xff); rp.rp_lbn0 = ((lbn >> 0) & 0xff); rp.rp_header.defect_len1 = 0; rp.rp_header.defect_len0 = 4;reassign: printf("\nReassigning bad block (%d) on device (%s).\n",lbn,rzdisk); if(execute_rzcmd(SCSI_REASSIGN_BLOCK, (char *)&rp) != SUCCESS) { if(geterror() != NO_ERROR) return; } /* * Write the saved data from the temporary buffer * back to the newly reassigned block. */ lseek(rzdev, offset, 0); if(write(rzdev, buffer, 512) == -1) goto reassign; /* * Inform user if the data is (GOOD) or (BAD). */ if(baddata) printf("\nThe data in the reassigned block is (BAD).\n"); else printf("\nThe data in the reassigned block is (GOOD).\n");}scan_for_bad_blocks(lbn,length)int lbn;int length;{ int modval,i; int lastblk,part,badlbn; char cpart; struct pt pt; char *print_error_code(); int err; bzero((char *)&vp, sizeof(vp)); /* * Get the partition table for the disk being scanned. */ if(execute_rzcmd(DIOCGETPT, (char *)&pt) != SUCCESS) { printf("\nCannot get partition table from device (%s).\n", rzdisk); return; } cpart = rzdisk[strlen(rzdisk) - 1]; part = cpart - 'a'; lastblk = pt.pt_part[part].pi_blkoff + pt.pt_part[part].pi_nblocks; /* * Check for a valid (LBN) entered. */ if(lbn < 0 || lbn > lastblk) { printf("\nInvalid LBN (%d) entered for device (%s).\n", lbn, rzdisk); printf("\nValid LBN range for device (%s) is [%d-%d].\n", rzdisk, pt.pt_part[part].pi_blkoff, pt.pt_part[part].pi_nblocks); return; } lbn = lbn + pt.pt_part[part].pi_blkoff; /* * Check for a valid (length) entered. */ if(length == -1) length = lastblk - lbn; else if((length + lbn) > lastblk) { printf("\nInvalid length (%d) entered for device (%s).\n", length, rzdisk); printf("\nLength plus LBN cannot exceed (%d) for device (%s).\n", lastblk, rzdisk); return; } printf("\nScanning for bad blocks on device (%s).\n",rzdisk); printf("\nBlock range being scanned is [%d-%d].\n\n", lbn, lbn+length-1); /* * Begin scanning 30000 blocks at a time. */ while(length != 0) { vp.vp_lbn = (u_long)lbn; modval = lbn % 30000; if(length > 30000) { vp.vp_length = (u_short) (30000 - modval); length -= (30000 - modval); lbn += (30000 - modval); } else { vp.vp_length = (u_short) length; length -= length; lbn += length; } printf("Scanning blocks [%d-%d]\n", vp.vp_lbn,(vp.vp_length+vp.vp_lbn-1));restart_scan: if(execute_rzcmd(SCSI_VERIFY_DATA, (char *)&vp) != SUCCESS) { err = geterror(); badlbn = infobyte; /* * Handle a FATAL ERROR. */ if(err == FATAL_ERROR) break; /* * Handle a RECOVERABLE ERROR. */ else if(err == SOFT_ERROR) { if(asc == 0x18) printf("\tRecoverable read error with ECC"); else if(asc == 0x17) printf("\tRecoverable read error with RETRIES"); else printf("\tRecoverable read error: (%s)", print_error_code(asc)); printf(" at (LBN = %d)\n", badlbn); } /* * Handle a UNRECOVERABLE ERROR. */ else if(err == HARD_ERROR) { if(asc == 0x11) printf("\tUnrecoverable read error"); else printf("\tUnrecoverable read error: (%s)", print_error_code(asc)); printf(" at (LBN = %d)\n", badlbn); } /* * Handle NO ERROR. */ else if(err == NO_ERROR) { continue; } vp.vp_length = (vp.vp_length + vp.vp_lbn - badlbn - 1); vp.vp_lbn = badlbn + 1; goto restart_scan; } } printf("\nDone scanning for bad blocks on device (%s).\n",rzdisk);}read_defects(defect_format)u_char defect_format;{ int value,i; char prodid[17]; bzero((char *)&inq, sizeof(inq)); execute_rzcmd(SCSI_GET_INQUIRY_DATA, (char *)&inq); for(i=0; i<16; i++) prodid[i] = inq.prodid[i]; prodid[i] = NULL; /* * BLOCK format not supported on RZ22/RZ23 disks. */ if((strncmp(prodid,"RZ22",4) == 0 || strncmp(prodid,"RZ23",4) == 0) && defect_format == BLK_FORMAT) { printf("\nBLOCK format unsupported on device (%s).\n", rzdisk); return; } /* * READ DEFECT DATA not supported on RRD40 disk. */ if(strncmp(prodid,"RRD40",5) == 0) { printf("\nRead Defect Data unsupported on device (%s).\n", rzdisk); return; } bzero((char *)&dd, sizeof(dd)); rdp.rdp_format = defect_format; rdp.rdp_alclen = sizeof(dd); rdp.rdp_addr = (u_char *)ⅆ printf("\nReading defects from device (%s).\n",rzdisk); if(execute_rzcmd(SCSI_READ_DEFECT_DATA, (char *)&rdp) != SUCCESS) { if(geterror() != NO_ERROR) return; } print_defects();}print_defects(){ int i, j, defect_length, ndefects, linecnt; int cylinder, bfi, sector, lba; printf("\nDefect list header:\n"); printf(" Format 0x%02x", dd.dd_header.rdd_hdr.format); if(dd.dd_header.rdd_hdr.mdl) printf(" MDL"); if(dd.dd_header.rdd_hdr.gdl) printf(" GDL"); switch(dd.dd_header.rdd_hdr.format) { case 4: printf(" BYTES\n"); break; case 5: printf(" SECTOR\n"); break; case 6: printf(" VENDOR\n"); break; case 7: printf(" RESERVED\n"); break; default:printf(" BLOCK\n"); break; } defect_length = (dd.dd_header.rdd_hdr.defect_len0 & 0x00ff) + ((dd.dd_header.rdd_hdr.defect_len1 << 8) & 0xff00); if(dd.dd_header.rdd_hdr.format == BLK_FORMAT) ndefects = defect_length / 4; else ndefects = defect_length / 8; printf(" Defect list length %d number of defects %d\n", defect_length, ndefects); i = 0; j = 0; linecnt = 0; while(i < defect_length) { switch (dd.dd_header.rdd_hdr.format) { case 0: case 1: case 2: case 3: lba = ((dd.BLK[j].lba3 << 24) & 0xff000000) + ((dd.BLK[j].lba2 << 16) & 0xff0000) + ((dd.BLK[j].lba1 << 8) & 0xff00) + ((dd.BLK[j].lba0 << 0) & 0xff); printf(" Block %8d\n", lba); i += 4; break; case 4: cylinder = ((dd.BFI[j].cyl2 << 16) & 0xff0000) + ((dd.BFI[j].cyl1 << 8) & 0xff00) + ((dd.BFI[j].cyl0 << 0) & 0xff); bfi = ((dd.BFI[j].bfi3 << 24) & 0xff000000) + ((dd.BFI[j].bfi2 << 16) & 0xff0000) + ((dd.BFI[j].bfi1 << 8) & 0xff00) + ((dd.BFI[j].bfi0 << 0) & 0xff); printf(" Cylinder %6d Head %2d Byte %6d\n", cylinder, dd.BFI[j].head, bfi); i += 8; break; case 5: cylinder = ((dd.PHY[j].cyl2 << 16) & 0xff0000) + ((dd.PHY[j].cyl1 << 8) & 0xff00) + ((dd.PHY[j].cyl0 << 0) & 0xff); sector = ((dd.PHY[j].sector3 << 24) & 0xff000000) + ((dd.PHY[j].sector2 << 16) & 0xff0000) + ((dd.PHY[j].sector1 << 8) & 0xff00) + ((dd.PHY[j].sector0 << 0) & 0xff); printf(" Cylinder %6d Head %2d Sector %4d\n", cylinder, dd.PHY[j].head, sector); i += 8; break; case 6: case 7: return; } ++j; if(++linecnt == 20) { linecnt = 0; if((i < defect_length) && !moreoutput()) return; } }}change_drive_parameters(ask)int ask;{ int setps; int value,i; char prodid[17]; char *ptr; int rz22_rz23_disk = 0; int rrd40_disk = 0; int rz55_disk = 0; struct page_code_37 ms_page37; u_char *byteptr; bzero((char *)&inq, sizeof(inq)); execute_rzcmd(SCSI_GET_INQUIRY_DATA, (char *)&inq); for(i=0; i<16; i++) prodid[i] = inq.prodid[i]; prodid[i] = NULL; /* * Can only change pages (1 and 37) for RZ22/RZ23 disks. */ if(strncmp(prodid,"RZ22",4) == 0 || strncmp(prodid,"RZ23",4) == 0) rz22_rz23_disk = 1; /* * Can only change page (1) for the RRD40 disk. */ if(strncmp(prodid,"RRD40",5) == 0) rrd40_disk = 1; /* * Can change all pages (1,2,3,4,8,37) for the RZ55 disk. */ if(strncmp(prodid,"RZ55",5) == 0) rz55_disk = 1; /* * User wants to enter new parameters interactively. */ if(ask) goto interactive;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -