1 21 22 package org.apache.derby.impl.store.raw.data; 23 import org.apache.derby.iapi.reference.SQLState; 24 import org.apache.derby.iapi.services.context.ContextManager; 25 import org.apache.derby.iapi.services.daemon.Serviceable; 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 import org.apache.derby.iapi.error.StandardException; 28 import org.apache.derby.iapi.store.raw.data.RawContainerHandle; 29 import org.apache.derby.iapi.store.raw.ContainerKey; 30 import org.apache.derby.iapi.store.raw.LockingPolicy; 31 import org.apache.derby.iapi.store.raw.Transaction; 32 import org.apache.derby.iapi.store.raw.xact.RawTransaction; 33 import org.apache.derby.iapi.store.raw.ContainerHandle; 34 import org.apache.derby.iapi.store.access.TransactionController; 35 36 import org.apache.derby.io.StorageFactory; 37 import org.apache.derby.io.StorageFile; 38 import org.apache.derby.iapi.util.ReuseFactory; 39 import java.security.AccessController ; 40 import java.security.PrivilegedAction ; 41 42 43 65 66 public class EncryptData implements PrivilegedAction { 67 68 private BaseDataFileFactory dataFactory; 69 private StorageFactory storageFactory; 70 private StorageFile[] oldFiles; 71 private int noOldFiles = 0; 72 73 74 75 private static final int STORAGE_FILE_EXISTS_ACTION = 1; 76 private static final int STORAGE_FILE_DELETE_ACTION = 2; 77 private static final int STORAGE_FILE_RENAME_ACTION = 3; 78 private int actionCode; 79 private StorageFile actionStorageFile; 80 private StorageFile actionDestStorageFile; 81 82 public EncryptData(BaseDataFileFactory dataFactory) { 83 this.dataFactory = dataFactory; 84 this.storageFactory = dataFactory.getStorageFactory(); 85 } 86 87 88 95 public void encryptAllContainers(RawTransaction t) 96 throws StandardException { 97 98 102 103 String [] files = dataFactory.getContainerNames(); 104 if (files != null) { 105 oldFiles = new StorageFile[files.length]; 106 noOldFiles = 0; 107 long segmentId = 0; 108 109 for (int f = files.length-1; f >= 0 ; f--) { 112 long containerId; 113 try { 114 containerId = 115 Long.parseLong(files[f].substring(1, 116 (files[f].length() -4)), 16); 117 } 118 catch (Throwable th) 119 { 120 continue; 124 } 125 126 ContainerKey ckey = new ContainerKey(segmentId, 127 containerId); 128 oldFiles[noOldFiles++] = encryptContainer(t, ckey); 129 } 130 131 } else 135 { 136 if (SanityManager.DEBUG) 137 SanityManager.THROWASSERT("encryption process is unable to" + 138 "read container names in seg0"); 139 } 140 141 } 142 143 144 151 private StorageFile encryptContainer(RawTransaction t, 152 ContainerKey ckey) 153 throws StandardException 154 { 155 156 LockingPolicy cl = 157 t.newLockingPolicy( 158 LockingPolicy.MODE_CONTAINER, 159 TransactionController.ISOLATION_SERIALIZABLE, 160 true); 161 162 if (SanityManager.DEBUG ) 163 SanityManager.ASSERT(cl != null); 164 165 RawContainerHandle containerHdl = (RawContainerHandle) 166 t.openContainer(ckey, cl, ContainerHandle.MODE_FORUPDATE); 167 168 if (SanityManager.DEBUG ) 169 SanityManager.ASSERT(containerHdl != null); 170 171 EncryptContainerOperation lop = 172 new EncryptContainerOperation(containerHdl); 173 t.logAndDo(lop); 174 175 dataFactory.flush(t.getLastLogInstant()); 182 183 String newFilePath = getFilePath(ckey, false); 185 StorageFile newFile = storageFactory.newStorageFile(newFilePath); 186 containerHdl.encryptContainer(newFilePath); 187 containerHdl.close(); 188 189 190 197 198 if (!dataFactory.getPageCache().discard(ckey)) { 200 if (SanityManager.DEBUG ) 201 SanityManager.THROWASSERT("unable to discard pages releated to " + 202 "container " + ckey + 203 " from the page cache"); 204 } 205 206 207 if (!dataFactory.getContainerCache().discard(ckey)) { 209 if (SanityManager.DEBUG ) 210 SanityManager.THROWASSERT("unable to discard a container " + 211 ckey + " from the container cache"); 212 } 213 214 StorageFile currentFile = dataFactory.getContainerPath(ckey , false); 215 StorageFile oldFile = getFile(ckey, true); 216 217 if (!privRename(currentFile, oldFile)) { 218 throw StandardException. 219 newException(SQLState.RAWSTORE_ERROR_RENAMING_FILE, 220 currentFile, oldFile); 221 } 222 223 if (!privRename(newFile, currentFile)) { 225 throw StandardException. 226 newException(SQLState.RAWSTORE_ERROR_RENAMING_FILE, 227 newFile, currentFile); 228 229 } 230 231 return oldFile ; 232 } 233 234 235 239 private StorageFile getFile(ContainerKey containerId, boolean old) { 240 String path = getFilePath(containerId, old); 241 return storageFactory.newStorageFile(getFilePath(containerId, 242 old)); 243 } 244 245 249 private String getFilePath(ContainerKey containerId, boolean old) { 250 StringBuffer sb = new StringBuffer ("seg"); 251 sb.append(containerId.getSegmentId()); 252 sb.append(storageFactory.getSeparator()); 253 sb.append(old ? 'o' : 'n'); 254 sb.append(Long.toHexString(containerId.getContainerId())); 255 sb.append(".dat"); 256 return sb.toString(); 257 } 258 259 private boolean isOldContainerFile(String fileName) 260 { 261 if (fileName.startsWith("o") && fileName.endsWith(".dat")) 264 return true; 265 else 266 return false; 267 } 268 269 private StorageFile getFile(String ctrFileName) 270 { 271 long segmentId = 0; 272 StringBuffer sb = new StringBuffer ("seg"); 273 sb.append(segmentId); 274 sb.append(storageFactory.getSeparator()); 275 sb.append(ctrFileName); 276 return storageFactory.newStorageFile(sb.toString()); 277 } 278 279 287 void restoreContainer(ContainerKey containerId) 288 throws StandardException 289 { 290 291 295 if (!dataFactory.getContainerCache().discard(containerId)) { 296 if (SanityManager.DEBUG ) 297 SanityManager.THROWASSERT( 298 "unable to discard container from cache:" + 299 containerId); 300 } 301 302 StorageFile currentFile = dataFactory.getContainerPath(containerId, 303 false); 304 StorageFile oldFile = getFile(containerId, true); 305 StorageFile newFile = getFile(containerId, false); 306 307 if (privExists(oldFile)) { 310 if (privExists(currentFile)) { 311 if (!privRename(currentFile, newFile)) { 313 throw StandardException. 314 newException(SQLState.RAWSTORE_ERROR_RENAMING_FILE, 315 currentFile, newFile); 316 } 317 } 318 319 if (!privRename(oldFile, currentFile)) { 320 throw StandardException. 321 newException(SQLState.RAWSTORE_ERROR_RENAMING_FILE, 322 oldFile, currentFile); 323 } 324 } 325 326 if (privExists(newFile)) { 328 329 if (!privDelete(newFile)) 330 throw StandardException.newException( 331 SQLState.UNABLE_TO_DELETE_FILE, 332 newFile); 333 } 334 } 335 336 337 345 public void removeOldVersionOfContainers(boolean inRecovery) 346 throws StandardException 347 { 348 349 if (inRecovery) 350 { 351 String [] files = dataFactory.getContainerNames(); 354 if (files != null) 355 { 356 for (int i = files.length-1; i >= 0 ; i--) 359 { 360 if (isOldContainerFile(files[i])) 363 { 364 StorageFile oldFile = getFile(files[i]); 365 if (!privDelete(oldFile)) 366 { 367 throw StandardException.newException( 368 SQLState.FILE_CANNOT_REMOVE_FILE, 369 oldFile); 370 } 371 } 372 } 373 } 374 }else 375 { 376 for (int i = 0 ; i < noOldFiles ; i++) 378 { 379 if (!privDelete(oldFiles[i])) 380 { 381 throw StandardException.newException( 382 SQLState.FILE_CANNOT_REMOVE_FILE, 383 oldFiles[i]); 384 } 385 } 386 } 387 } 388 389 390 391 private synchronized boolean privExists(StorageFile file) 392 { 393 actionCode = STORAGE_FILE_EXISTS_ACTION; 394 actionStorageFile = file; 395 Object ret = AccessController.doPrivileged(this); 396 actionStorageFile = null; 397 return ((Boolean ) ret).booleanValue(); 398 399 } 400 401 402 private synchronized boolean privDelete(StorageFile file) 403 { 404 actionCode = STORAGE_FILE_DELETE_ACTION; 405 actionStorageFile = file; 406 Object ret = AccessController.doPrivileged(this); 407 actionStorageFile = null; 408 return ((Boolean ) ret).booleanValue(); 409 410 } 411 412 private synchronized boolean privRename(StorageFile fromFile, 413 StorageFile destFile) 414 { 415 actionCode = STORAGE_FILE_RENAME_ACTION; 416 actionStorageFile = fromFile; 417 actionDestStorageFile = destFile; 418 Object ret = AccessController.doPrivileged(this); 419 actionStorageFile = null; 420 actionDestStorageFile = null; 421 return ((Boolean ) ret).booleanValue(); 422 423 } 424 425 426 427 public Object run() 429 { 430 switch(actionCode) 431 { 432 case STORAGE_FILE_EXISTS_ACTION: 433 return ReuseFactory.getBoolean(actionStorageFile.exists()); 434 case STORAGE_FILE_DELETE_ACTION: 435 return ReuseFactory.getBoolean(actionStorageFile.delete()); 436 case STORAGE_FILE_RENAME_ACTION: 437 return ReuseFactory.getBoolean( 438 actionStorageFile.renameTo(actionDestStorageFile)); 439 } 440 441 return null; 442 } 443 } 444 | Popular Tags |