static int ARCH_DEP(scedio_iov)(SCCB_SCEDIOV_BK *scediov_bk) { S64 seek; S64 length; S64 totread, totwrite; U64 sto; char fname[MAX_PATH]; switch(scediov_bk->type) { case SCCB_SCEDIOV_TYPE_INIT: return TRUE; break; case SCCB_SCEDIOV_TYPE_READ: /* Ensure file access is allowed and within specified directory */ if(!check_sce_filepath((char*)scediov_bk->filename,fname)) { if(errno != ENOENT) WRMSG (HHC00605, "E", fname, strerror(errno)); return FALSE; } FETCH_DW(sto,scediov_bk->sto); FETCH_DW(seek,scediov_bk->seek); FETCH_DW(length,scediov_bk->length); totread = ARCH_DEP(read_file)(fname, sto, seek, length); if(totread > 0) { STORE_DW(scediov_bk->length,totread); if(totread == length) STORE_DW(scediov_bk->ncomp,0); else STORE_DW(scediov_bk->ncomp,seek+totread); return TRUE; } else return FALSE; break; case SCCB_SCEDIOV_TYPE_CREATE: case SCCB_SCEDIOV_TYPE_APPEND: /* Ensure file access is allowed and within specified directory */ if(!check_sce_filepath((char*)scediov_bk->filename,fname)) { if(errno != ENOENT) WRMSG (HHC00605, "E", fname, strerror(errno)); /* A file not found error may be expected for a create request */ if(!(errno == ENOENT && scediov_bk->type == SCCB_SCEDIOV_TYPE_CREATE)) return FALSE; } FETCH_DW(sto,scediov_bk->sto); FETCH_DW(length,scediov_bk->length); totwrite = ARCH_DEP(write_file)(fname, ((scediov_bk->type == SCCB_SCEDIOV_TYPE_CREATE) ? (O_CREAT|O_TRUNC) : O_APPEND), sto, length); if(totwrite >= 0) { STORE_DW(scediov_bk->ncomp,totwrite); return TRUE; } else return FALSE; break; default: PTT(PTT_CL_ERR,"*SERVC",(U32)scediov_bk->type,(U32)scediov_bk->flag1,scediov_bk->flag2); return FALSE; } }
/*-------------------------------------------------------------------*/ static void ARCH_DEP(hwl_loadfile)(SCCB_HWL_BK *hwl_bk) { CREG sto; U32 size; int fd; fd = open (hwl_fn[hwl_bk->file], O_RDONLY|O_BINARY); if (fd < 0) { logmsg (_("HHCHL002I %s open error: %s\n"), hwl_fn[hwl_bk->file], strerror(errno)); return; } // else // logmsg(_("HHCHL004I Loading %s\n"),hwl_fn[hwl_bk->file]); FETCH_FW(size,hwl_bk->size); /* Segment Table Origin */ FETCH_DW(sto,hwl_bk->sto); #if defined(FEATURE_ESAME) sto &= ASCE_TO; #else /*!defined(FEATURE_ESAME)*/ sto &= STD_STO; #endif /*!defined(FEATURE_ESAME)*/ for( ; ; sto += sizeof(sto)) { #if defined(FEATURE_ESAME) DBLWRD *ste; #else /*!defined(FEATURE_ESAME)*/ FWORD *ste; #endif /*!defined(FEATURE_ESAME)*/ CREG pto, pti; /* Fetch segment table entry and calculate Page Table Origin */ if( sto >= sysblk.mainsize) goto eof; #if defined(FEATURE_ESAME) ste = (DBLWRD*)(sysblk.mainstor + sto); #else /*!defined(FEATURE_ESAME)*/ ste = (FWORD*)(sysblk.mainstor + sto); #endif /*!defined(FEATURE_ESAME)*/ FETCH_W(pto, ste); if( pto & SEGTAB_INVALID ) goto eof; #if defined(FEATURE_ESAME) pto &= ZSEGTAB_PTO; #else /*!defined(FEATURE_ESAME)*/ pto &= SEGTAB_PTO; #endif /*!defined(FEATURE_ESAME)*/ for(pti = 0; pti < 256 ; pti++, pto += sizeof(pto)) { #if defined(FEATURE_ESAME) DBLWRD *pte; #else /*!defined(FEATURE_ESAME)*/ FWORD *pte; #endif /*!defined(FEATURE_ESAME)*/ CREG pgo; BYTE *page; /* Fetch Page Table Entry to get page origin */ if( pto >= sysblk.mainsize) goto eof; #if defined(FEATURE_ESAME) pte = (DBLWRD*)(sysblk.mainstor + pto); #else /*!defined(FEATURE_ESAME)*/ pte = (FWORD*)(sysblk.mainstor + pto); #endif /*!defined(FEATURE_ESAME)*/ FETCH_W(pgo, pte); if( pgo & PAGETAB_INVALID ) goto eof; #if defined(FEATURE_ESAME) pgo &= ZPGETAB_PFRA; #else /*!defined(FEATURE_ESAME)*/ pgo &= PAGETAB_PFRA; #endif /*!defined(FEATURE_ESAME)*/ /* Read page into main storage */ if( pgo >= sysblk.mainsize) goto eof; page = sysblk.mainstor + pgo; if( !(size--) || !read(fd, page, STORAGE_KEY_PAGESIZE) ) goto eof; STORAGE_KEY(pgo, &sysblk) |= (STORKEY_REF|STORKEY_CHANGE); } } eof: close(fd); }
int main( int argc, char *argv[] ) { U64 nxtpos; /* file position of next read */ U64 altpos; /* file position of alternate track */ U64 orgpos; /* alternate track's file position of original track */ U32 numbad = 0; /* Counts defective tracks */ U32 reclaimed = 0; /* Counts reclaimed tracks */ U32 remaining; /* Counts number of tracks to process */ U32 total; /* Total number of tracks to process */ int infile = -1; /* Input file descriptor integer */ int outfile = -1; /* output file descriptor integer */ int cyl; /* Cylinder number */ int head; /* Head number */ int track; /* Track number */ int rc; /* Return code */ U8 trackbuf[TRACKSIZE]; /* Primary track buffer */ U8 alttrack[TRACKSIZE]; /* Alternate track buffer */ U8 altmark[6] = { BAD_TRACK_SIG }; /* Defective track signature */ U8 reclaim = 0; /* false: map, true: reclaim */ /*----------------*/ /* Initialization */ /*----------------*/ if (argc < 3 || argc > 4) return error( EINVAL, "invalid number of arguments" ); if (1 && strcmp( argv[1], "MAP" ) != 0 && strcmp( argv[1], "map" ) != 0 && strcmp( argv[1], "RECLAIM" ) != 0 && strcmp( argv[1], "reclaim" ) != 0 ) return error( EINVAL, "invalid 'action'" ); reclaim = ((strcmp( argv[1], "RECLAIM" ) == 0) || (strcmp( argv[1], "reclaim" ) == 0)); if (reclaim && argc < 4) return error( EINVAL, "missing outfile argument" ); printf( "Run option = %s\n", argv[1] ); printf( "Opening input file \"%s\"...\n", argv[2] ); if ((infile = HOPEN( argv[2], O_RDONLY | O_BINARY )) < 0) return error( errno, "could not open input file" ); /*------------------------------*/ /* Read and inspect file header */ /*------------------------------*/ if ((rc = read(infile, trackbuf, FILEHDRSIZE)) <= 0 || rc != FILEHDRSIZE) return error( EIO, "I/O error reading header from input file" ); if (memcmp(trackbuf, "CKD_P370", 8) != 0) return error(EINTR, "input file is no CKD dasd image"); if (trackbuf[16] != 0x90) return error(EINTR, "input file is no 3390 dasd image"); FETCH_FW( head, &trackbuf[8] ); FETCH_FW( track, &trackbuf[12] ); FETCH_HW( cyl, &trackbuf[18] ); if (bswap_32(track) != TRACKSIZE) return error(EINTR, "input file uses an unsupported track size"); printf("3390 DASD image: %d heads, %d cylinders\n\n", bswap_32(head), bswap_16(cyl)); remaining = total = TRACKSPERCYL * bswap_16(cyl); /*-----------------------------------------------------------*/ /* Open output file and copy file header (only on "reclaim") */ /*-----------------------------------------------------------*/ if (reclaim) { printf( "Opening output file \"%s\"...\n", argv[3] ); if ((outfile = HOPEN( argv[3], O_CREAT | O_EXCL | O_WRONLY | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP )) < 0) return error( errno, "could not open output file" ); if ((rc = write( outfile, trackbuf, FILEHDRSIZE )) < 0 || rc != FILEHDRSIZE) return error( EIO, "I/O error writing output file" ); } c: /*---------------------------*/ /* Start of copy tracks loop */ /*---------------------------*/ track = total - remaining; cyl = CYLNUM ( track ); head = HEADNUM( track ); if (!head) printf( "Inspecting cylinder %d...\r", cyl ); /* Read next track */ if ((rc = read( infile, trackbuf, TRACKSIZE )) <= 0 || rc != TRACKSIZE) return error( errno, "I/O error reading input file" ); /*------------------*/ /* Defective track? */ /*------------------*/ if (memcmp( &trackbuf[TRACKSIZE-16], altmark, 6 ) == 0) { numbad++; /* Count defective tracks */ if (reclaim) printf( "Reclaiming track %6d = Cyl %4d (%4.4X), Head %2d (%2.2X)...\n", track, cyl, cyl, head, head ); else printf( "Track %6d = Cyl %4d (%4.4X), Head %2d (%2.2X) is flagged\nas being defective and has an alternate track assigned.\n", track, cyl, cyl, head, head ); FETCH_DW( altpos, &trackbuf[ TRACKSIZE-8 ] ); /* get alternate track position */ nxtpos= lseek( infile, 0, SEEK_CUR ); /* save current file position */ lseek( infile, altpos, SEEK_SET ); /* position to alternate */ read ( infile, alttrack, TRACKSIZE ); /* read alternate track */ lseek( infile, nxtpos, SEEK_SET ); /* restore original file position */ FETCH_DW( orgpos, &alttrack[ TRACKSIZE-8 ] ); /* get original track position */ /*----------------------------------------------*/ #if (DEBUGOPT & DEBUG_POSITIONS) { int alttrk = POS2TRACK( altpos ); int altcyl = CYLNUM ( alttrk ); int althead = HEADNUM( alttrk ); int orgtrk = POS2TRACK( orgpos ); int orgcyl = CYLNUM ( orgtrk ); int orghead = HEADNUM( orgtrk ); printf("\n"); printf( "\taltpos = %llx ==> track %6d = Cyl %4d (%4.4X), Head %2d (%2.2X)\n", altpos, alttrk, altcyl, altcyl, althead, althead ); printf( "\torgpos = %llx ==> track %6d = Cyl %4d (%4.4X), Head %2d (%2.2X)\n", orgpos, orgtrk, orgcyl, orgcyl, orghead, orghead ); } #endif #if (DEBUGOPT & DEBUG_TRACKDATA) { char *dump = NULL; printf("\n"); hexdumpe( "\tPRI: ", &dump, trackbuf, 0, TRACKSIZE, orgpos, 4, 4 ); if (dump) printf( "%s\n", dump ); hexdumpe( "\tALT: ", &dump, alttrack, 0, TRACKSIZE, altpos, 4, 4 ); if (dump) printf( "%s", dump ); if (dump) free( dump ); } #endif #if (DEBUGOPT & DEBUG_BOTH) /* if EITHER debug option */ printf("\n"); /* if EITHER debug option */ #endif /*----------------------------------------------*/ if (reclaim) { /* Reclaim the original track: the alternate tracks's position of the original defective track must match, and the track header containing the cylinder and track numbers must also match. */ if (orgpos == (nxtpos-TRACKSIZE) && memcmp( &alttrack[0], &trackbuf[0], 16 ) == 0) { /* copy alternate track data to original track */ memcpy( trackbuf, alttrack, TRACKSIZE ); /* indicate original track is no longer defective */ memset( &trackbuf[TRACKSIZE-16], 0, 16 ); reclaimed++; /* Count reclaimed tracks */ } else fprintf( stderr, "\t*** ERROR *** Reclaim failed!\n\n" ); } } /*----------------------------*/ /* Write track to output file */ /*----------------------------*/ if (reclaim) if ((rc = write( outfile, trackbuf, TRACKSIZE )) < 0 || rc != TRACKSIZE) return error( EIO, "I/O error writing output file" ); /*------------------------------*/ /* Loop until all tracks copied */ /*------------------------------*/ if (--remaining) goto c; /*-----------------------*/ /* Print totals and exit */ /*-----------------------*/ if (infile > 0) close( infile ); if (outfile > 0) close( outfile ); printf( "%d tracks (%d cylinders) read.\n", total, CYLNUM(total) ); if (reclaim) printf( "%d tracks (%d cylinders) written.\n", total, CYLNUM(total) ); if (!reclaim) printf( "Image currently has %d defective tracks assigned to an alternate.\n", numbad ); else { printf( "Image had %d defective tracks assigned to an alternate.\n", numbad ); printf( "A total of %d defective tracks were reclaimed from their assigned alternate.\n", reclaimed ); printf( "Reclaim %s.\n", reclaimed >= numbad ? "was successful" : "function FAILED" ); } PAUSEIFBEINGDEBUGGED(); return (0); }