1 23 24 28 50 package com.sun.jts.CosTransactions; 51 52 54 import java.util.*; 55 import java.io.*; 56 57 65 72 class LogControl { 73 74 76 private final static String CUSHION_NAME = "cushion"; 77 private final static String EXTENT_NAME = "extent."; 78 private final static String CONTROL_NAME = "control"; 79 public final static String RECOVERY_STRING_FILE_NAME = "recoveryfile"; 80 private final static String LOG_EXTENSION = ""; 83 private final static char[] EXTENT_CHARS = { 'e','x','t','e','n','t','.','0','0','0' }; 85 86 88 boolean logInitialised = false; 89 boolean logReadOnly = false; 90 Vector logHandles = null; 91 String directoryPath = null; 92 File controlFile = null; 93 File cushionFile = null; 94 95 97 107 synchronized void initLog( boolean coldStart, 108 boolean readOnly, 109 String logDirectory ) { 110 111 113 117 if( logInitialised ) { 118 return; 119 } 120 121 logReadOnly = readOnly; 122 123 125 directoryPath = new String (logDirectory); 126 127 129 if( coldStart && !readOnly ) 130 clearDirectory(logDirectory); 131 132 134 logHandles = new Vector(); 135 136 140 logInitialised = true; 141 142 } 143 144 157 synchronized LogHandle openFile( String logFileName, 158 LogUpcallTarget upcallTarget, 159 String baseNewName, 160 boolean[] newlyCreated ) 161 throws LogException { 162 163 166 if( !logInitialised ) 167 throw new LogException(null,LogException.LOG_NOT_INITIALISED,1); 168 169 175 String logName = null; 176 177 { 207 208 211 214 logName = logFileName; 215 File logDir = directory(logName,directoryPath); 216 if( !logDir.exists() ) 217 logDir.mkdir(); 218 } 219 220 226 controlFile = controlFile(logName,directoryPath); 227 cushionFile = cushionFile(logName); 228 229 int openOptions = LogFileHandle.OPEN_RDWR | 230 LogFileHandle.OPEN_CREAT | 231 LogFileHandle.OPEN_SYNC; if( logReadOnly ) 233 openOptions = LogFileHandle.OPEN_RDONLY; 234 235 LogFileHandle controlFH; 236 try { 237 controlFH = new LogFileHandle(controlFile,openOptions); 238 } catch( LogException le ) { 239 throw new LogException(null,LogException.LOG_OPEN_FAILURE,3); 240 } 241 242 247 LogHandle logHandle = null; 248 try { 249 logHandle = new LogHandle(this,logName,controlFH,upcallTarget); } 250 catch( LogException le ) { 251 controlFH.finalize(); 252 throw new LogException(null,LogException.LOG_INSUFFICIENT_MEMORY,4); 253 } 254 255 256 259 try { 260 logHandle.restoreCushion(false); 261 } catch( LogException le ) { 262 controlFH.finalize(); 263 throw new LogException(null,LogException.LOG_INSUFFICIENT_MEMORY,9); 264 } 265 266 274 byte[] controlBytes = new byte[LogControlDescriptor.SIZEOF]; 275 int bytesRead = 0; 276 try { 277 bytesRead = controlFH.fileRead(controlBytes); 278 } catch( LogException le ) { 279 controlFH.finalize(); 280 throw new LogException(null,LogException.LOG_READ_FAILURE,5); 281 } 282 283 if( bytesRead == 0 ) { 284 285 308 logHandle.logControlDescriptor.headLSN.copy(LogLSN.NULL_LSN); 309 logHandle.logControlDescriptor.tailLSN.copy(LogLSN.FIRST_LSN); 310 logHandle.logControlDescriptor.nextLSN.copy(LogLSN.FIRST_LSN); 311 logHandle.restartDataLength = 0; 312 logHandle.recordsWritten = LogHandle.CONTROL_FORCE_INTERVAL; 313 newlyCreated[0] = true; 314 315 if( !logReadOnly ) { 316 int bytesWritten; 317 318 try { 319 controlFH.allocFileStorage(LogHandle.CONTROL_FILE_SIZE); 320 } catch( LogException le ) { 321 controlFH.finalize(); 322 throw new LogException(null,LogException.LOG_WRITE_FAILURE,6); 323 } 324 325 logHandle.logControlDescriptor.toBytes(controlBytes,0); 326 try { 327 bytesWritten = controlFH.fileWrite(controlBytes); 328 } catch( LogException le ) { 329 controlFH.finalize(); 330 throw new LogException(null,LogException.LOG_WRITE_FAILURE,7); 331 } 332 333 LogExtent logEDP = null; 334 try { 335 logEDP = logHandle.openExtent(logHandle.logControlDescriptor.nextLSN.extent); 336 } catch( LogException le ) { 337 controlFH.finalize(); 338 throw new LogException(null,LogException.LOG_NO_SPACE,10); 339 } 340 341 try { 342 logEDP.fileHandle.allocFileStorage(LogHandle.ALLOCATE_SIZE); 343 } catch( LogException le ) { 344 controlFH.finalize(); 345 throw new LogException(null,LogException.LOG_NO_SPACE,11); 346 } 347 348 logHandle.chunkRemaining = LogHandle.ALLOCATE_SIZE; 349 } 350 } 351 352 354 else { 355 int timeStampRec1; int timeStampRec2; int lengthRec1; int lengthRec2; 360 362 newlyCreated[0] = false; 363 364 369 logHandle.logControlDescriptor = new LogControlDescriptor(controlBytes,0); 370 371 LogExtent logEDP = null; 372 for( int currentExtent = logHandle.logControlDescriptor.tailLSN.extent; 373 currentExtent <= logHandle.logControlDescriptor.headLSN.extent || 374 currentExtent <= logHandle.logControlDescriptor.nextLSN.extent; 375 currentExtent++) 376 try { 377 logEDP = logHandle.openExtent(currentExtent); 378 } catch( LogException le ) { 379 controlFH.finalize(); 380 throw new LogException(null,LogException.LOG_OPEN_EXTENT_FAILURE,19); 381 } 382 383 389 int[] restartValues1 = new int[2]; 390 int[] restartValues2 = new int[2]; 391 392 try { 393 logHandle.checkRestart(controlFH,1,restartValues1); 394 } catch( LogException le ) { 395 controlFH.finalize(); 396 throw new LogException(null,LogException.LOG_READ_FAILURE,8); 397 } 398 399 406 { 414 415 420 try { 421 logHandle.checkRestart(controlFH,2,restartValues2); 422 } catch( LogException le ) { 423 controlFH.finalize(); 424 throw new LogException(null,LogException.LOG_READ_FAILURE,9); 425 } 426 427 if( restartValues2[0] != 0 && 428 restartValues2[1] > restartValues1[1] ) { 429 logHandle.activeRestartVersion = 2; 430 logHandle.restartDataLength = restartValues2[0]; 431 } else { 432 logHandle.activeRestartVersion = 1; 433 logHandle.restartDataLength = restartValues1[0]; 434 } 435 } 436 437 if( logHandle.logControlDescriptor.headLSN.isNULL() ) 438 logHandle.recordsWritten = LogHandle.CONTROL_FORCE_INTERVAL; 439 } 440 441 445 logHandles.addElement(logHandle); 446 447 451 if( !logHandle.logControlDescriptor.headLSN.isNULL() ) { 452 int offset; LogRecordHeader extentRec, headRec, linkRec; boolean lastValidRead = false; LogExtent logEDP = null; 458 459 464 469 try { 470 logEDP = logHandle.positionFilePointer(logHandle.logControlDescriptor.headLSN, 471 0,LogExtent.ACCESSTYPE_READ); } 472 catch( LogException le ) { 473 controlFH.finalize(); 474 removeFile(logHandle); 475 throw new LogException(null,LogException.LOG_OPEN_FAILURE,10); 476 } 477 478 489 byte[] headerBytes = new byte[LogRecordHeader.SIZEOF]; 490 491 try { 492 bytesRead = logEDP.fileHandle.fileRead(headerBytes); 493 } catch( LogException le ) { 494 controlFH.finalize(); 495 removeFile(logHandle); 496 throw new LogException(null,le.errorCode,11); 497 } 498 extentRec = new LogRecordHeader(headerBytes,0); 499 500 if( !extentRec.currentLSN.equals(logHandle.logControlDescriptor.headLSN) ) { 501 controlFH.finalize(); 502 removeFile(logHandle); 503 throw new LogException(null,LogException.LOG_CORRUPTED,12); 504 } 505 506 509 logEDP.cursorPosition += bytesRead; 510 headRec = new LogRecordHeader(); 511 headRec.copy(extentRec); 512 offset = headRec.nextLSN.offset; 513 514 try { 515 logEDP = logHandle.positionFilePointer(extentRec.nextLSN,0,LogExtent.ACCESSTYPE_READ); 516 } catch( LogException le ) { 517 controlFH.finalize(); 518 removeFile(logHandle); 519 throw new LogException(null,LogException.LOG_OPEN_FAILURE,13); 520 } 521 522 linkRec = new LogRecordHeader(); 523 524 526 lastValidRead = false; 527 do { 528 530 offset = extentRec.nextLSN.offset; 531 532 try { 533 bytesRead = logEDP.fileHandle.fileRead(headerBytes); 534 } catch( LogException le ) { 535 controlFH.finalize(); 536 removeFile(logHandle); 537 throw new LogException(null,LogException.LOG_READ_FAILURE,14); 538 } 539 if( bytesRead == -1 ) { 540 controlFH.finalize(); 541 removeFile(logHandle); 542 throw new LogException(null,LogException.LOG_READ_FAILURE,14); 543 } 544 545 extentRec = new LogRecordHeader(headerBytes,0); 546 logEDP.cursorPosition += bytesRead; 547 548 551 if( extentRec.currentLSN.offset == offset ) { 552 554 if( extentRec.recordType == LogHandle.LINK ) { 555 559 linkRec.copy(extentRec); 560 try { 561 logEDP = logHandle.positionFilePointer(extentRec.nextLSN,0,LogExtent.ACCESSTYPE_READ); 562 } catch( LogException le ) { 563 controlFH.finalize(); 564 removeFile(logHandle); 565 throw new LogException(null,le.errorCode,15); 566 } 567 continue; 568 } else 569 570 573 if( !linkRec.currentLSN.isNULL() && 574 !linkRec.nextLSN.equals(extentRec.currentLSN) ) 575 linkRec = new LogRecordHeader(); 576 577 580 headRec.copy(extentRec); 581 try { 582 logEDP = logHandle.positionFilePointer(extentRec.nextLSN,0,LogExtent.ACCESSTYPE_READ); 583 } catch( Throwable e ) {} 584 } else { 585 LogRecordEnding endRec; 587 lastValidRead = true; 588 589 595 try { 596 logEDP = logHandle.positionFilePointer(headRec.currentLSN, 597 LogRecordHeader.SIZEOF+headRec.recordLength, 598 LogExtent.ACCESSTYPE_READ); 599 } catch( LogException le ) { 600 controlFH.finalize(); 601 removeFile(logHandle); 602 throw new LogException(null,le.errorCode,16); 603 } 604 605 byte[] endingBytes = new byte[LogRecordEnding.SIZEOF]; 606 607 try { 608 bytesRead = logEDP.fileHandle.fileRead(endingBytes); 609 } catch( LogException le ) { 610 controlFH.finalize(); 611 removeFile(logHandle); 612 throw new LogException(null,le.errorCode,17); 613 } 614 615 endRec = new LogRecordEnding(endingBytes,0); 616 617 logEDP.cursorPosition += bytesRead; 618 619 623 if( endRec.currentLSN.equals(headRec.currentLSN) ) { 624 logHandle.logControlDescriptor.headLSN.copy(headRec.currentLSN); 625 logHandle.logControlDescriptor.nextLSN.copy(headRec.nextLSN); 626 } 627 628 633 else { 634 if( linkRec.currentLSN.isNULL() ) { 635 logHandle.logControlDescriptor.headLSN.copy(headRec.previousLSN); 636 logHandle.logControlDescriptor.nextLSN.copy(headRec.currentLSN); 637 } 638 639 641 else { 642 logHandle.logControlDescriptor.headLSN.copy(linkRec.previousLSN); 643 logHandle.logControlDescriptor.nextLSN.copy(linkRec.currentLSN); 644 } 645 } 646 } 647 648 650 logHandle.recordsWritten++; 651 } 652 while( !lastValidRead ); 653 } 654 655 657 logHandle.blockValid = logHandle; 658 659 return logHandle; 660 } 661 662 672 synchronized void cleanUp( LogHandle logHandle ) 673 throws LogException { 674 675 677 if( !logInitialised ) 678 throw new LogException(null,LogException.LOG_NOT_INITIALISED,1); 679 680 685 if( logHandle == null || logHandle.blockValid != logHandle ) 686 throw new LogException(null,LogException.LOG_INVALID_FILE_DESCRIPTOR,2); 687 688 690 logHandle.blockValid = null; 691 692 694 logHandle.cleanUpExtents(); 695 696 701 removeFile(logHandle); 702 703 } 704 705 714 715 static boolean checkFileExists( String logId, 716 String logDirectory ) { 717 718 if(logDirectory==null) 720 return false; 721 boolean exists = controlFile(logId,logDirectory).exists(); 723 724 return exists; 725 } 726 727 735 synchronized void removeFile( LogHandle logHandle ) { 736 737 739 logHandles.removeElement(logHandle); 740 741 743 logHandle.blockValid = null; 744 745 } 746 747 755 void dump() { 757 } 761 762 770 static void clearDirectory( String logDir ) { 771 776 File directory = new File(logDir); 777 String [] allFiles = directory.list(); 778 779 for( int i = 0; i < allFiles.length; i++ ) { 780 781 if( allFiles[i].endsWith(LOG_EXTENSION) ) { 784 final File logFileDir = new File(directory,allFiles[i]); 786 if( logFileDir.isDirectory() ) { 787 final String [] logFiles = logFileDir.list(); 788 793 java.security.AccessController.doPrivileged( 794 new java.security.PrivilegedAction () { 795 public Object run(){ 796 for( int j = 0; j < logFiles.length; j++ ){ 797 new File(logFileDir,logFiles[j]).delete(); 798 } 799 return null; 800 } 801 } 802 ); 803 java.security.AccessController.doPrivileged( 804 new java.security.PrivilegedAction () { 805 public Object run(){ 806 logFileDir.delete(); 807 return null; 808 } 809 } 810 ); 811 } 812 } 814 } 815 816 } 817 818 827 File extentFile( String logId, 828 int extent ) { 829 830 char[] buff = (char[])EXTENT_CHARS.clone(); 831 832 int tmpExtent = extent / LogExtent.EXTENT_RADIX; 833 int extentLow = extent % LogExtent.EXTENT_RADIX; 834 int extentMid = tmpExtent % LogExtent.EXTENT_RADIX; 835 int extentHigh = tmpExtent / LogExtent.EXTENT_RADIX; 836 837 buff[7] = (char)(extentHigh + (extentHigh > 9 ? 'A'-10 : '0')); 838 buff[8] = (char)(extentMid + (extentMid > 9 ? 'A'-10 : '0')); 839 buff[9] = (char)(extentLow + (extentLow > 9 ? 'A'-10 : '0')); 840 841 String fileName = new String (buff); 842 File result = new File(directory(logId,directoryPath),fileName); 843 844 return result; 845 } 846 847 856 final static File controlFile( String logId, String logDir ) { 857 File result = new File(directory(logId,logDir),CONTROL_NAME); 858 return result; 859 } 860 861 869 final File cushionFile( String logId ) { 870 871 File result = new File(directory(logId,directoryPath),CUSHION_NAME); 872 873 return result; 874 } 875 876 885 final static File directory( String logId, String logDir ) { 886 887 if(logDir==null) return new File( "." + File.separator + logId + LOG_EXTENSION); 891 return new File(logDir); 893 } 895 896 final static File recoveryIdentifierFile(String logId, String logDir) { 897 File result = new File(directory(logId,logDir),RECOVERY_STRING_FILE_NAME); 898 return result; 899 } 900 } 901 | Popular Tags |