KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jts > CosTransactions > LogControl


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
26  * Use is subject to license terms.
27  */

28 //----------------------------------------------------------------------------
29
//
30
// Module: LogControl.java
31
//
32
// Description: Log control file interface.
33
//
34
// Product: com.sun.jts.CosTransactions
35
//
36
// Author: Simon Holdsworth
37
//
38
// Date: March, 1997
39
//
40
// Copyright (c): 1995-1997 IBM Corp.
41
//
42
// The source code for this program is not published or otherwise divested
43
// of its trade secrets, irrespective of what has been deposited with the
44
// U.S. Copyright Office.
45
//
46
// This software contains confidential and proprietary information of
47
// IBM Corp.
48
//----------------------------------------------------------------------------
49

50 package com.sun.jts.CosTransactions;
51
52 // Import required classes.
53

54 import java.util.*;
55 import java.io.*;
56
57 /**This class holds the top level information for an instance of the log,
58  *
59  * @version 0.01
60  *
61  * @author Simon Holdsworth, IBM Corporation
62  *
63  * @see
64 */

65 //----------------------------------------------------------------------------
66
// CHANGE HISTORY
67
//
68
// Version By Change Description
69
// 0.01 SAJH Initial implementation.
70
//------------------------------------------------------------------------------
71

72 class LogControl {
73
74     /**Constants for file name extensions.
75      */

76     private final static String JavaDoc CUSHION_NAME = "cushion"/*#Frozen*/;
77     private final static String JavaDoc EXTENT_NAME = "extent."/*#Frozen*/;
78     private final static String JavaDoc CONTROL_NAME = "control"/*#Frozen*/;
79     public final static String JavaDoc RECOVERY_STRING_FILE_NAME = "recoveryfile"/*#Frozen*/;
80     //START IASRI 4721336
81
//private final static String LOG_EXTENSION = ".ld"/*#Frozen*/;
82
private final static String JavaDoc LOG_EXTENSION = ""/*#Frozen*/;
83     //END IASRI 4721336
84
private final static char[] EXTENT_CHARS = { 'e','x','t','e','n','t','.','0','0','0' };
85
86     /**Internal instance members
87      */

88     boolean logInitialised = false;
89     boolean logReadOnly = false;
90     Vector logHandles = null;
91     String JavaDoc directoryPath = null;
92     File controlFile = null;
93     File cushionFile = null;
94
95     //static processSharedLog = GlobLock();
96

97     /**Initialises the log in the given directory.
98      *
99      * @param coldStart Cold start indicator.
100      * @param readOnly Read only log indicator.
101      * @param logDirectory Directory for log files.
102      *
103      * @return
104      *
105      * @see
106      */

107     synchronized void initLog( boolean coldStart,
108                                boolean readOnly,
109                                String JavaDoc logDirectory ) {
110
111         // Trace the global state of the log.
112

113         // IF logInitialised
114
// Unlock the LogGlobalMutex
115
// Return LOG_SUCCESS
116

117         if( logInitialised ) {
118             return;
119         }
120
121         logReadOnly = readOnly;
122
123         // Store the log directory name for use by subsequent log functions.
124

125         directoryPath = new String JavaDoc(logDirectory);
126
127         // If this is a cold start, then remove all files in the log directory
128

129         if( coldStart && !readOnly )
130             clearDirectory(logDirectory);
131
132         // Create the Vector which will hold the LogHandles.
133

134         logHandles = new Vector();
135
136         // Set the logInitialised flag to TRUE
137
// Unlock the logGlobalMutex
138
// Return LOG_SUCCESS
139

140         logInitialised = true;
141
142     }
143
144     /**Opens a log file with the given name and upcall.
145      *
146      * @param logName Name of log.
147      * @param upcallTarget Upcall for log file.
148      * @param baseNewName Base of new name for log file.
149      * @param newlyCreated A one-element array to hold the newly created indicator.
150      *
151      * @return Handle for the log file.
152      *
153      * @exception LogException The open failed.
154      *
155      * @see
156      */

157     synchronized LogHandle openFile( String JavaDoc logFileName,
158                                      LogUpcallTarget upcallTarget,
159                                      String JavaDoc baseNewName,
160                                      boolean[] newlyCreated )
161         throws LogException {
162
163         // IF not LogInitialised
164
// Return LOG_NOT_INITIALISED
165

166         if( !logInitialised )
167             throw new LogException(null,LogException.LOG_NOT_INITIALISED,1);
168
169         // If the logid provided is an Alias name, it could be more than 8
170
// characters. If so, to support the FAT file system, a unique
171
// 8 character must be generated
172
// If the name is an Alias name, then the base new name to use will have
173
// been passed in as a parameter.
174

175         String JavaDoc logName = null;
176
177         /* if( baseNewName != null )
178             {
179             int i = 0;
180
181             // Determine the index to start allocating from based on the base
182
183             if( baseNewName.length() != 0 )
184             {
185             try
186             { i = Integer.parseInt(baseNewName.substring(LogHandle.FILENAME_PREFIX_LEN+1,LogHandle.FILENAME_PREFIX_LEN+3),16); }
187             catch( Throwable e ) {}
188             i++;
189             }
190
191             // Generate a new name from the base.
192
193             boolean logExists;
194             for( logExists = true;
195             i <= LogHandle.MAX_NAMES && logExists;
196             i++)
197             {
198             logName = new String(FILENAME_PREFIX);
199             if( i < 100 ) logName += "0";
200             if( i < 10 ) logName += "0";
201             logName += Integer.toString(i);
202             logExists = checkFileExists(logName,directoryPath);
203             }
204             }
205             else
206         */
{
207
208             // If the log Id is provided is not an Alias make make sure it
209
// meets the FAT file system requirements
210

211             /* if( logFileName.length() != LogHandle.NAME_LENGTH )
212                   throw new LogException(null,LogException.LOG_INVALID_FILE_DESCRIPTOR,19);
213             */

214             logName = logFileName;
215             File logDir = directory(logName,directoryPath);
216             if( !logDir.exists() )
217                 logDir.mkdir();
218         }
219
220         // Build name of log's control file, e.g. (<logname>.control)
221
// Issue OPEN request for control file, specifying Read/Write, Create,
222
// No-share and 'guaranteed write to disk' options
223
// IF OPEN is not successful
224
// Return LOG_OPEN_FAILURE
225

226         controlFile = controlFile(logName,directoryPath);
227         cushionFile = cushionFile(logName);
228
229         int openOptions = LogFileHandle.OPEN_RDWR |
230             LogFileHandle.OPEN_CREAT |
231             LogFileHandle.OPEN_SYNC; // Default open options
232
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         // Allocate a Log_FileDescriptor block and initialise it
243
// IF allocate fails
244
// Close the control file
245
// Return LOG_INSUFFICIENT_MEMORY
246

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         // Call Log_RestoreCushion to create/check the cushion file exists
257
// for this logfile. If this fails the log cannot be opened.
258

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         // Issue a READ request for the control file, specifying the
267
// Log_ControlDescriptor structure within the Log_FileDescriptor
268
// block as the input buffer
269
// IF not successful (rc == -1)
270
// Close the control file
271
// Deallocate the Log_FileDescriptor block
272
// Return LOG_READ_FAILURE
273

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             // IF the READ returned EOF (rc == 0), continue with initialisation of
286
// the Log_ControlDescriptor structure within the
287
// Log_FileDescriptor block
288
// - Initialise the log head LSN to LOG_NULL_LSN
289
// - Initialise the log tail LSN to LOG_FIRST_LSN
290
// - Initialise the next free LSN to LOG_FIRST_LSN
291
// - Initialise the RestartDataLength in the Log_FileDescriptor
292
// block to 0
293
//
294
// Set NewlyCreated parameter to TRUE
295
//
296
// Pre-allocate all the file storage for the control file
297
//
298
// Set RecordsWritten to LOG_CONTROL_FORCE_INTERVAL so on
299
// the first write to the log the newly created control data
300
// is written to disk. If this is not done then data could be lost.
301
//
302
// Write the control data to file
303
//
304
// Open the first extent file and allocate the storage it requires.
305
// If either step fails close and erase the control file and
306
// return LOG_INSUFFICIENT_STORAGE.
307

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         // Otherwise the log already exists.
353

354         else {
355             int timeStampRec1; // The time stamp in restart rec 1
356
int timeStampRec2; // The time stamp in restart rec 2
357
int lengthRec1; // The length of restart record 1
358
int lengthRec2; // The length of restart record 1
359

360             // Set NewlyCreated parameter to FALSE
361

362             newlyCreated[0] = false;
363
364             // Open all of the active extents and
365
// rebuild the extent table, starting form the extent
366
// containing the Tail LSN and finishing with the extent
367
// containing the Head LSN
368

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             // Read the restart data for restart record one
384
// If the read failed then
385
// Close the control file
386
// Deallocate the Log_FileDescriptor block
387
// Return LOG_READ_FAILURE
388

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             // Check that the record length was not equal to zero
400
// IF the record length was not equal to zero
401
// READ the next restart record
402
// IF ( (Length2 !=0) && (Time2 > Time1)
403
// THEN CurrentValid is 2
404
// ELSE CurrentValid is 1
405

406             // BUGFIX(Ram Jeyaraman) Always check both the restart records,
407
// even though the first record might have zero data length.
408
// It is possible, that the second record might
409
// have non-zero data length with a later
410
// timestamp, even though the first record has zero data length.
411
// Fix is to comment out the check below.
412
//if (restartValues1[0] != 0)
413
{
414
415                 // If the read failed then
416
// Close the control file
417
// Deallocate the Log_FileDescriptor block
418
// Return LOG_READ_FAILURE
419

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         // Add the Log_FileDescriptor block to the head of the
442
// (LogFileDescriptorHead) chain hung off the RCA and update the backward
443
// chain pointer of the block which was previously at the head of the chain.
444

445         logHandles.addElement(logHandle);
446
447         // IF the head LSN in Log_ControlDescriptor != LOG_NULL_LSN
448
// Build the extent file name from the head LSN
449
// Issue an OPEN request for the file
450

451         if( !logHandle.logControlDescriptor.headLSN.isNULL() ) {
452             int offset; // Present offset in the open extent
453
LogRecordHeader extentRec, // An extent record header
454
headRec, // An extent record header
455
linkRec; // An extent record header
456
boolean lastValidRead = false; // Has the last valid record be read
457
LogExtent logEDP = null;
458
459             // IF not successful (rc == -1)
460
// Close the control file
461
// Unchain the LogFDP and free up the storage
462
// Return LOG_OPEN_FAILURE
463

464             // Allocate a Log_ExtentDescriptor block and initialise it
465
// Hash the extent number to find the anchor for this extent in the
466
// hash table and add it to the head of the chain
467
// Move the file pointer to the head LSN record (using LSEEK)
468

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             // Issue a READ for the record header
479
// IF the read is not successful (rc <= 0)
480
// Close the control file
481
// Deallocate newly acquired control blocks
482
// Return LOG_READ_FAILURE
483
//
484
// Check that the LSN in the record header matches the head LSN
485
// IF there is a mismatch
486
// Deallocate newly acquired control blocks
487
// Return LOG_CORRUPTED
488

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             // Copy the record header to HEADERCOPY
507
// Move the file pointer to the 'next LSN' in record header
508

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             // LOOP until last valid log record has been read
525

526             lastValidRead = false;
527             do {
528                 // Issue a read for the record header
529

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                 // IF the LSN in the record header matches the LSN of the
549
// current position in the extent file
550

551                 if( extentRec.currentLSN.offset == offset ) {
552                     // IF its a link record
553

554                     if( extentRec.recordType == LogHandle.LINK ) {
555                         // Copy it to LINKCOPY
556
// 'Move' the file pointer to the NextRecord value (in the next extent file)
557
// Iterate.
558

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                         // IF LINKCOPY is not null AND LINKCOPY.NextRecord LSN &lnot.= ThisRecord LSN
571
// Set LINKCOPY to null
572

573                         if( !linkRec.currentLSN.isNULL() &&
574                             !linkRec.nextLSN.equals(extentRec.currentLSN) )
575                             linkRec = new LogRecordHeader();
576
577                     // Copy the record header to HEADERCOPY
578
// Use the NextRecord value to move the file pointer to the next record header
579

580                     headRec.copy(extentRec);
581                     try {
582                         logEDP = logHandle.positionFilePointer(extentRec.nextLSN,0,LogExtent.ACCESSTYPE_READ);
583                     } catch( Throwable JavaDoc e ) {}
584                 } else {
585                     LogRecordEnding endRec; // An ending record type
586

587                     lastValidRead = true;
588
589                     // Use the ThisRecord value from HEADERCOPY together with the
590
// RecordLength value to calculate the position of the previous
591
// Log_RecordEnding structure
592
//
593
// LSEEK to this position and read it
594

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                     // IF its value is the same as ThisRecord LSN This is the last valid record
620
// Update head LSN in control data with ThisRecord LSN
621
// Update next LSN in control data with the NextRecord LSN
622

623                     if( endRec.currentLSN.equals(headRec.currentLSN) ) {
624                         logHandle.logControlDescriptor.headLSN.copy(headRec.currentLSN);
625                         logHandle.logControlDescriptor.nextLSN.copy(headRec.nextLSN);
626                     }
627
628                     // This is an invalid record, so record details of previous valid record
629
// IF LINKCOPY is null
630
// Update head LSN in control data with the PreviousRecord LSN
631
// Update next LSN in control data with ThisRecord LSN
632

633                     else {
634                         if( linkRec.currentLSN.isNULL() ) {
635                             logHandle.logControlDescriptor.headLSN.copy(headRec.previousLSN);
636                             logHandle.logControlDescriptor.nextLSN.copy(headRec.currentLSN);
637                         }
638
639                         // Otherwise update head LSN in control data with value from LINKCOPY
640

641                         else {
642                             logHandle.logControlDescriptor.headLSN.copy(linkRec.previousLSN);
643                             logHandle.logControlDescriptor.nextLSN.copy(linkRec.currentLSN);
644                         }
645                     }
646                 }
647
648                 // Increase the number of records written since the last force
649

650                 logHandle.recordsWritten++;
651             }
652             while( !lastValidRead );
653         }
654
655         // Store the address of the Log_FileDescriptor block into its BlockValid field
656

657         logHandle.blockValid = logHandle;
658
659         return logHandle;
660     }
661
662     /**Cleans up the given log file.
663      *
664      * @param logHandle The log to clean up.
665      *
666      * @return
667      *
668      * @exception LogException The operation failed.
669      *
670      * @see
671      */

672     synchronized void cleanUp( LogHandle logHandle )
673         throws LogException {
674
675         // IF not LogInitialised Return LOG_NOT_INITIALISED
676

677         if( !logInitialised )
678             throw new LogException(null,LogException.LOG_NOT_INITIALISED,1);
679
680         // Check BlockValid field in Log_FileDescriptor block and
681
// ensure it is valid
682
// IF not valid Log_FileDescriptor
683
// Return LOG_INVALID_FILE_DESCRIPTOR
684

685         if( logHandle == null || logHandle.blockValid != logHandle )
686             throw new LogException(null,LogException.LOG_INVALID_FILE_DESCRIPTOR,2);
687
688         // Set the block valid to NULL
689

690         logHandle.blockValid = null;
691
692         // Remove all extent entries from the log file's extent hash table
693

694         logHandle.cleanUpExtents();
695
696         // Unchain the Log_FileDescriptor block from the RCA chain. The
697
// mutices contained in the FD latch structure will already have been
698
// freed up when the AS process which owned them died. We indicate this
699
// by setting the ProcessOwnsLatch parameter to FALSE.
700

701         removeFile(logHandle);
702
703     }
704
705     /**Determines whether the given named log exists in the given directory.
706      *
707      * @param logId The log identifier.
708      * @param logDirectory The log directory.
709      *
710      * @return Indicates whether the file exists.
711      *
712      * @see
713      */

714
715     static boolean checkFileExists( String JavaDoc logId,
716                                     String JavaDoc logDirectory ) {
717
718         //START IASRI 4730519
719
if(logDirectory==null)
720             return false;
721         //END IASRI 4730519
722
boolean exists = controlFile(logId,logDirectory).exists();
723
724         return exists;
725     }
726
727     /**Removes the log file from the chain.
728      *
729      * @param logHandle
730      *
731      * @return
732      *
733      * @see
734      */

735     synchronized void removeFile( LogHandle logHandle ) {
736
737         // Unchain the Log_FileDescriptor block from the RCA chain
738

739         logHandles.removeElement(logHandle);
740
741         // Clear the BlockValid field in the Log_FileDescriptor block
742

743         logHandle.blockValid = null;
744
745     }
746
747     /**Dumps the state of the object.
748      *
749      * @param
750      *
751      * @return
752      *
753      * @see
754      */

755     //----------------------------------------------------------------------------
756
void dump() {
757         // If the log has been initialised the pointer to the global
758
// data will have been initialised. So, if the pointer to the
759
// global data is not NULL, dump out the its contents.
760
}
761
762     /**Clears out all log files from the given directory.
763      *
764      * @param logDir
765      *
766      * @return
767      *
768      * @see
769      */

770     static void clearDirectory( String JavaDoc logDir ) {
771         // Find each control file in turn and then delete all files that
772
// begin with the same name. This will delete all files associated
773
// with that log (including the control file so that it is not found
774
// again next time through the loop)
775

776         File directory = new File(logDir);
777         String JavaDoc[] allFiles = directory.list();
778
779         for( int i = 0; i < allFiles.length; i++ ) {
780
781             // Determine if the file is actually a log subdirectory. If so, use it's name
782
// to delete all associated log files.
783
if( allFiles[i].endsWith(LOG_EXTENSION) ) {
784                 //Start IASRI 4720539
785
final File logFileDir = new File(directory,allFiles[i]);
786                 if( logFileDir.isDirectory() ) {
787                     final String JavaDoc[] logFiles = logFileDir.list();
788                     /*
789                     for( int j = 0; j < logFiles.length; j++ )
790                         new File(logFileDir,logFiles[j]).delete();
791                     logFileDir.delete();
792                     */

793                     java.security.AccessController.doPrivileged(
794                         new java.security.PrivilegedAction JavaDoc() {
795                             public Object JavaDoc 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 JavaDoc() {
805                             public Object JavaDoc run(){
806                                 logFileDir.delete();
807                                 return null;
808                             }
809                         }
810                     );
811                 }
812                 //End IASRI 4720539
813
}
814         }
815
816     }
817
818     /**Builds a log extent file.
819      *
820      * @param logId Log identifier.
821      * @param extent Extent number.
822      *
823      * @return A File object representing the extent file.
824      *
825      * @see
826      */

827     File extentFile( String JavaDoc 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 JavaDoc fileName = new String JavaDoc(buff);
842         File result = new File(directory(logId,directoryPath),fileName);
843
844         return result;
845     }
846
847     /**Builds a log control file.
848      *
849      * @param logId Log identifier.
850      * @param logDir Log directory.
851      *
852      * @return A File object representing the control file.
853      *
854      * @see
855      */

856     final static File controlFile( String JavaDoc logId, String JavaDoc logDir ) {
857         File result = new File(directory(logId,logDir),CONTROL_NAME);
858         return result;
859     }
860
861     /**Builds a log cushion file.
862      *
863      * @param logId Log identifier.
864      *
865      * @return A File object representing the cushion file.
866      *
867      * @see
868      */

869     final File cushionFile( String JavaDoc logId ) {
870
871         File result = new File(directory(logId,directoryPath),CUSHION_NAME);
872
873         return result;
874     }
875
876     /**Builds a log directory file.
877      *
878      * @param logId Log identifier.
879      * @param logDir Base log directory.
880      *
881      * @return A File object representing the directory.
882      *
883      * @see
884      */

885     final static File directory( String JavaDoc logId, String JavaDoc logDir ) {
886
887     //START IASRI 4721336
888
//START IASRI 4730519
889
if(logDir==null) //It should not be null
890
return new File( "." + File.separator + logId + LOG_EXTENSION);
891     //END IASRI 4730519
892
return new File(logDir);
893     //END IASRI 4721336
894
}
895
896     final static File recoveryIdentifierFile(String JavaDoc logId, String JavaDoc logDir) {
897         File result = new File(directory(logId,logDir),RECOVERY_STRING_FILE_NAME);
898         return result;
899     }
900 }
901
Popular Tags