rvm 1.08
|
00001 #include "config.h" 00002 00003 #include <iostream> 00004 #include <vector> 00005 #include <map> 00006 #include <string> 00007 00008 #include "asserts.h" 00009 #include "error.h" 00010 #include "rmath.h" 00011 #include "fs.h" 00012 #include "rconfig.h" 00013 #include "logger.h" 00014 #include "timer.h" 00015 #include "estat.h" 00016 #include "reporter.h" 00017 #include "strfmt.h" 00018 00019 #include "vaulter.h" 00020 00021 /** C'tor */ 00022 vault_manager::vault_manager() 00023 { 00024 if (this != &vaulter) 00025 throw(INTERNAL_ERROR(0,"Attempt to allocate multiple vault managers")); 00026 clear(); 00027 } 00028 00029 /** Clear the vault manager */ 00030 void vault_manager::clear(void) 00031 { 00032 m_lock.clear(); 00033 m_selected_vault.erase(); 00034 m_deleted_archives.clear(); 00035 m_da_err = false; 00036 m_initialized = false; 00037 } 00038 00039 /** Initialize the vault manager */ 00040 void vault_manager::init(void) 00041 { 00042 clear(); 00043 m_initialized = true; 00044 } 00045 00046 /** Return the initialized status of the vault manager */ 00047 const bool vault_manager::initialized(void) const 00048 { 00049 return(m_initialized); 00050 } 00051 00052 /** Select a vault 00053 00054 If an archive of the same timestamp for the given timestamp resolution 00055 already exists on any vault, then that vault is selected. Otherwise select 00056 a vault according to vault-selection-behavior. 00057 00058 */ 00059 void vault_manager::select(void) 00060 { 00061 std::string es; 00062 std::string ts; 00063 configuration_manager::vaults_type::const_iterator vi; 00064 std::string lockfile; 00065 std::string lstr; 00066 00067 if (!initialized()) 00068 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00069 00070 TRY_nomem(es = "Could not select a vault"); 00071 try { 00072 // If an archive exists in any vault by the same timestamp as conf.stamp(), 00073 // then use that vault regardless of the selection behavior. 00074 for ( 00075 vi = config.vaults().begin(); 00076 vi != config.vaults().end(); 00077 vi++ 00078 ) 00079 { 00080 subdirectory subdir; 00081 subdirectory::iterator sdi; 00082 00083 subdir.path(*vi); 00084 for (sdi = subdir.begin(); sdi != subdir.end(); sdi++) { 00085 TRY_nomem(ts = config.timestamp().str()); 00086 00087 if (*sdi == ts) { 00088 TRY_nomem(lstr = "Existing archive directory found in vault: \""); 00089 TRY_nomem(lstr += *vi); 00090 TRY_nomem(lstr += "\"\n"); 00091 logger.write(lstr); 00092 00093 if (config.vault_locking()) { 00094 TRY_nomem(lockfile = *vi); 00095 TRY_nomem(lockfile += "/.rvm_lock"); 00096 m_lock.clear(); 00097 m_lock.lockfile(lockfile); 00098 if (!m_lock.lock()) { 00099 error e(ENOLCK); 00100 e.push_back(ERROR_INSTANCE(es)); 00101 TRY_nomem(es = "Could not lock vault: \""); 00102 TRY_nomem(es += *vi); 00103 TRY_nomem(es += "\""); 00104 e.push_back(ERROR_INSTANCE(es)); 00105 if (m_lock.is_locked()) { 00106 TRY_nomem(es = "Vault is locked by PID: "); 00107 TRY_nomem(es += estring(m_lock.locked_by())); 00108 e.push_back(ERROR_INSTANCE(es)); 00109 } 00110 throw(e); 00111 } 00112 } 00113 TRY_nomem(m_selected_vault = *vi); 00114 return; 00115 } 00116 00117 TRY_nomem(ts += ".incomplete"); 00118 00119 if (*sdi == ts) { 00120 TRY_nomem(lstr = "Existing archive directory found in vault: \""); 00121 TRY_nomem(lstr += *vi); 00122 TRY_nomem(lstr += "\"\n"); 00123 logger.write(lstr); 00124 00125 if (config.vault_locking()) { 00126 TRY_nomem(lockfile = *vi); 00127 TRY_nomem(lockfile += "/.rvm_lock"); 00128 m_lock.clear(); 00129 m_lock.lockfile(lockfile); 00130 if (!m_lock.lock()) { 00131 error e(ENOLCK); 00132 e.push_back(ERROR_INSTANCE(es)); 00133 TRY_nomem(es = "Could not lock vault: \""); 00134 TRY_nomem(es += *vi); 00135 TRY_nomem(es += "\""); 00136 e.push_back(ERROR_INSTANCE(es)); 00137 if (m_lock.is_locked()) { 00138 TRY_nomem(es = "Vault is locked by PID: "); 00139 TRY_nomem(es += estring(m_lock.locked_by())); 00140 e.push_back(ERROR_INSTANCE(es)); 00141 } 00142 throw(e); 00143 } 00144 } 00145 TRY_nomem(m_selected_vault = *vi); 00146 return; 00147 } 00148 } 00149 } 00150 00151 // If an archive by the same timestamp does not already exist, then select 00152 // a vault. 00153 if (config.vault_selection_behavior() 00154 == configuration_manager::selection_round_robin) 00155 { 00156 std::pair<std::string,std::string> youngest; 00157 00158 for ( 00159 vi = config.vaults().begin(); 00160 vi != config.vaults().end(); 00161 vi++ 00162 ) 00163 { 00164 subdirectory subdir; 00165 subdirectory::iterator sdi; 00166 00167 if (config.vault_locking()) { 00168 TRY_nomem(lockfile = *vi); 00169 TRY_nomem(lockfile += "/.rvm_lock"); 00170 m_lock.clear(); 00171 m_lock.lockfile(lockfile); 00172 if (m_lock.is_locked()) { 00173 std::string lstr; 00174 00175 TRY_nomem(lstr = "Skipping locked vault: \""); 00176 TRY_nomem(lstr += *vi); 00177 TRY_nomem(lstr += "\"\n"); 00178 logger.write(lstr); 00179 00180 continue; 00181 } 00182 } 00183 00184 subdir.path(*vi); 00185 for (sdi = subdir.begin(); sdi != subdir.end(); sdi++) { 00186 if ((youngest.first < *sdi) || (youngest.first.size() == 0)) { 00187 TRY_nomem(youngest.first = *sdi); 00188 TRY_nomem(youngest.second = *vi); 00189 } 00190 } 00191 } 00192 00193 TRY_nomem(m_selected_vault = ""); 00194 if (youngest.second.size() == 0) { 00195 TRY_nomem(m_selected_vault = config.vaults()[0]); 00196 } 00197 else { 00198 for ( 00199 vi = config.vaults().begin(); 00200 vi != config.vaults().end(); 00201 vi++ 00202 ) 00203 { 00204 if (*vi == youngest.second) { 00205 if ((vi+1) == config.vaults().end()) { 00206 TRY_nomem(m_selected_vault = config.vaults()[0]); 00207 } 00208 else { 00209 TRY_nomem(m_selected_vault = *(vi+1)); 00210 } 00211 } 00212 } 00213 } 00214 } 00215 else { 00216 std::pair<std::string,filesystem::size_type> most_space; 00217 filesystem fsys; 00218 00219 TRY_nomem(most_space.first = config.vaults()[0]); 00220 fsys.path(config.vaults()[0]); 00221 most_space.second = fsys.free_blocks(); 00222 for ( 00223 vi = (config.vaults().begin()+1); 00224 vi != config.vaults().end(); 00225 vi++ 00226 ) 00227 { 00228 fsys.path(*vi); 00229 if (most_space.second < fsys.free_blocks()) { 00230 TRY_nomem(most_space.first = *vi); 00231 most_space.second = fsys.free_blocks(); 00232 } 00233 } 00234 TRY_nomem(m_selected_vault = most_space.first); 00235 } 00236 } 00237 catch(error e) { 00238 e.push_back(es); 00239 throw(e); 00240 } 00241 catch(...) { 00242 error e(0); 00243 if (errno == ENOMEM) { 00244 e = err_nomem; 00245 e.push_back(es); 00246 throw(e); 00247 } 00248 e = err_unknown; 00249 e.push_back(es); 00250 throw(e); 00251 } 00252 00253 if (m_selected_vault.size() == 0) 00254 throw(ERROR(0,es)); 00255 } 00256 00257 /** Return a list of archive directories in the selected vault 00258 00259 Return a list of archive directories in the selected vault, including 00260 incomplete archives. Ignore all other directories. 00261 */ 00262 const subdirectory vault_manager::get_archive_list(void) 00263 { 00264 subdirectory subdir; 00265 subdirectory::iterator sdi; 00266 00267 if (!initialized()) 00268 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00269 00270 if (!selected()) 00271 throw(INTERNAL_ERROR(0,"No vault selected")); 00272 00273 subdir.path(vault()); 00274 00275 sdi = subdir.begin(); 00276 while (sdi != subdir.end()) { 00277 if (!is_timestamp((*sdi).substr(0,(*sdi).find(".incomplete")))) 00278 { 00279 subdir.erase(sdi); 00280 sdi = subdir.begin(); 00281 } 00282 else { 00283 sdi++; 00284 } 00285 } 00286 00287 return(subdir); 00288 } 00289 00290 /** Return the path to the selected vault */ 00291 const std::string vault_manager::vault(void) const 00292 { 00293 if (!initialized()) 00294 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00295 00296 if (!selected()) 00297 throw(INTERNAL_ERROR(0,"No vault selected")); 00298 00299 return(m_selected_vault); 00300 } 00301 00302 /** Return whether or not a vault has been selected yet */ 00303 const bool vault_manager::selected(void) const 00304 { 00305 bool value = true; 00306 00307 if (!initialized()) 00308 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00309 00310 if (m_selected_vault.size() == 0) 00311 value = false; 00312 00313 return(value); 00314 } 00315 00316 /** Return the percent of used blocks and used inodes in the selected vault */ 00317 void vault_manager::usage(uint16 &a_blocks, uint16 &a_inodes) const 00318 { 00319 filesystem fsys; 00320 safe_num<uint64> blocks, inodes; 00321 00322 if (!initialized()) 00323 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00324 00325 if (!selected()) 00326 throw(INTERNAL_ERROR(0,"No vault selected")); 00327 00328 fsys.path(vault()); 00329 00330 if (fsys.total_blocks() == 0) 00331 blocks = 0; 00332 else { 00333 try { 00334 blocks = fsys.free_blocks(); 00335 // blocks *= 100; 00336 // blocks /= fsys.total_blocks(); 00337 blocks /= fsys.total_blocks() / 100; 00338 } 00339 catch(error e) { 00340 logger.write("*** ERROR: Overflow error detected in vault_manager::usage() while calculating percent blocks used\n"); 00341 logger.write(e.str()); 00342 blocks = 0; 00343 } 00344 catch(...) { 00345 logger.write("*** ERROR: Unknown error detected in vault_manager::usage() while calculating percent blocks used\n"); 00346 blocks = 0; 00347 } 00348 } 00349 00350 if (fsys.free_inodes() == 0) 00351 inodes = 0; 00352 else { 00353 try { 00354 inodes = fsys.free_inodes(); 00355 // inodes *= 100; 00356 // inodes /= fsys.total_inodes(); 00357 inodes /= fsys.total_inodes() / 100; 00358 } 00359 catch(error e) { 00360 logger.write("*** ERROR: Overflow error detected in vault_manager::usage() while calculating percent inodes used\n"); 00361 logger.write(e.str()); 00362 blocks = 0; 00363 } 00364 catch(...) { 00365 logger.write("*** ERROR: Unknown error detected in vault_manager::usage() while calculating percent inodes used\n"); 00366 blocks = 0; 00367 } 00368 } 00369 00370 ASSERT(blocks <= max_limit(blocks)); 00371 ASSERT(inodes <= max_limit(inodes)); 00372 00373 a_blocks = blocks.value(); 00374 a_inodes = inodes.value(); 00375 } 00376 00377 /** Test to see if a vault has exceeded it's overflow threshold */ 00378 const bool vault_manager::overflow(bool a_report) 00379 { 00380 uint16 free_blocks; 00381 uint16 free_inodes; 00382 bool value = false; 00383 std::string lstr; 00384 00385 if (!initialized()) 00386 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00387 00388 if (!selected()) 00389 throw(INTERNAL_ERROR(0,"No vault selected")); 00390 00391 usage(free_blocks, free_inodes); 00392 if (free_blocks < config.vault_overflow_blocks()) 00393 value = true; 00394 if (free_inodes < config.vault_overflow_inodes()) 00395 value = true; 00396 00397 if (value && a_report) { 00398 TRY_nomem(lstr = "Vault overflow detected: "); 00399 TRY_nomem(lstr += vault()); 00400 TRY_nomem(lstr += "\n"); 00401 logger.write(lstr); 00402 00403 TRY_nomem(lstr = " Threshold: "); 00404 TRY_nomem(lstr += 00405 percent_string(config.vault_overflow_blocks(), 00406 static_cast<uint16>(100))); 00407 TRY_nomem(lstr += " free blocks, "); 00408 TRY_nomem(lstr += 00409 percent_string(config.vault_overflow_inodes(), 00410 static_cast<uint16>(100))); 00411 TRY_nomem(lstr += " free inodes"); 00412 TRY_nomem(lstr += "\n"); 00413 logger.write(lstr); 00414 00415 TRY_nomem(lstr = "Vault capacity: "); 00416 TRY_nomem(lstr += percent_string(free_blocks,static_cast<uint16>(100))); 00417 TRY_nomem(lstr += " free blocks, "); 00418 TRY_nomem(lstr += percent_string(free_inodes,static_cast<uint16>(100))); 00419 TRY_nomem(lstr += " free inodes"); 00420 TRY_nomem(lstr += "\n"); 00421 logger.write(lstr); 00422 00423 estring __e = estring("Overflow Detected:"); 00424 reporter.vault().add_report( 00425 vault_stats_report(estring("Overflow Detected:"),filesystem(vault())) 00426 ); 00427 } 00428 00429 return(value); 00430 } 00431 00432 /** Find the oldest archive in the vault and delete it */ 00433 void vault_manager::delete_oldest_archive(void) 00434 { 00435 std::string es; 00436 estring ts; 00437 estring tsi; 00438 std::string lstr; 00439 subdirectory archive_list; 00440 std::string oldest; 00441 std::string dir; 00442 estring estr; 00443 timer t; 00444 uint16 free_blocks, free_inodes; 00445 subdirectory logfile_list; 00446 subdirectory::const_iterator ilf; 00447 00448 if (!initialized()) 00449 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00450 00451 if (!selected()) 00452 throw(INTERNAL_ERROR(0,"No vault selected")); 00453 00454 TRY_nomem(ts = config.timestamp().str()); 00455 TRY_nomem(tsi = ts + ".incomplete"); 00456 00457 archive_list = get_archive_list(); 00458 if ( 00459 (archive_list.size() == 0) 00460 || ( 00461 (archive_list.size() == 1) 00462 && (archive_list[0] == ts || archive_list[0] == tsi) 00463 ) 00464 ) 00465 { 00466 TRY_nomem(es = "Vault has insufficient space: \""); 00467 TRY_nomem(es += vault()); 00468 TRY_nomem(es += "\""); 00469 exit_manager.assign(exitstat::vault_full); 00470 throw(ERROR(0,es)); 00471 } 00472 00473 TRY_nomem(oldest = archive_list[0]); 00474 if (oldest == ts || oldest == tsi) { 00475 TRY_nomem(lstr = "Oldest is actually archive in use: \""); 00476 TRY_nomem(lstr += oldest); 00477 TRY_nomem(lstr += "\" Skipping to next archive...\n"); 00478 logger.write(lstr); 00479 TRY_nomem(oldest = archive_list[1]); 00480 } 00481 00482 if (oldest.find(".incomplete") != std::string::npos) { 00483 TRY_nomem(lstr = "WARNING: Oldest archive found is incomplete.\n"); 00484 logger.write(lstr); 00485 } 00486 00487 TRY_nomem(lstr = "Deleting oldest archive: \""); 00488 TRY_nomem(lstr += oldest); 00489 TRY_nomem(lstr += "\"\n"); 00490 logger.write(lstr); 00491 00492 TRY_nomem(dir = vault()); 00493 TRY_nomem(dir += "/"); 00494 TRY_nomem(dir += oldest); 00495 t.start(); 00496 try { 00497 m_deleted_archives.push_back(oldest); 00498 } 00499 catch(...) { 00500 m_da_err = true; 00501 } 00502 rm_recursive(dir); 00503 t.stop(); 00504 00505 TRY_nomem(lstr = "Deletion complete, duration: "); 00506 TRY_nomem(lstr += t.duration()); 00507 TRY_nomem(lstr += "\n"); 00508 logger.write(lstr); 00509 00510 usage(free_blocks, free_inodes); 00511 TRY_nomem(lstr = "Vault capacity: "); 00512 TRY_nomem(lstr += percent_string(free_blocks,static_cast<uint16>(100))); 00513 TRY_nomem(lstr += " free blocks, "); 00514 TRY_nomem(lstr += percent_string(free_inodes,static_cast<uint16>(100))); 00515 TRY_nomem(lstr += " free inodes"); 00516 TRY_nomem(lstr += "\n"); 00517 logger.write(lstr); 00518 00519 estr = "Deleted "; 00520 estr += oldest; 00521 estr += ":"; 00522 reporter.vault().add_report(vault_stats_report(estr,filesystem(vault()))); 00523 00524 // This is a grey area for me: Should log/report file removal be managed by 00525 // log_manager/report_manager, or is it OK to do it here? For simplicity 00526 // sake, I do it here. 00527 // 00528 if (config.delete_old_log_files()) { 00529 estring wildcard; 00530 00531 logger.write("Searching for old log files to delete...\n"); 00532 wildcard = oldest; 00533 wildcard += ".log*"; 00534 logfile_list.path(config.log_dir(), wildcard); 00535 for (ilf = logfile_list.begin(); ilf != logfile_list.end(); ilf++) { 00536 estring file; 00537 00538 file = config.log_dir(); 00539 file += "/"; 00540 file += *ilf; 00541 00542 try { 00543 rm_file(file); 00544 } 00545 catch(error e) { 00546 estring es; 00547 00548 es = "*** ERROR: Could not remove log file: "; 00549 es += *ilf; 00550 00551 logger.write(es); 00552 logger.write(e.str()); 00553 00554 // Should I throw an error here, or should deletion of old log files 00555 // not be considered important enough to interrupt archiving? 00556 } 00557 catch(...) { 00558 estring es; 00559 00560 es = "*** ERROR: Unknown error detected in vault_manager::delete_oldest_archive() while deleting old log file: "; 00561 es += *ilf; 00562 es += '\n'; 00563 00564 logger.write(es); 00565 00566 // Should I throw an error here, or should deletion of old log files 00567 // not be considered important enough to interrupt archiving? 00568 } 00569 } 00570 00571 wildcard = oldest; 00572 wildcard += ".relink*"; 00573 logfile_list.path(config.log_dir(), wildcard); 00574 for (ilf = logfile_list.begin(); ilf != logfile_list.end(); ilf++) { 00575 estring file; 00576 00577 file = config.log_dir(); 00578 file += "/"; 00579 file += *ilf; 00580 00581 try { 00582 rm_file(file); 00583 } 00584 catch(error e) { 00585 estring es; 00586 00587 es = "*** ERROR: Could not remove relink file: "; 00588 es += *ilf; 00589 00590 logger.write(es); 00591 logger.write(e.str()); 00592 00593 // Should I throw an error here, or should deletion of old log files 00594 // not be considered important enough to interrupt archiving? 00595 } 00596 catch(...) { 00597 estring es; 00598 00599 es = "*** ERROR: Unknown error detected in vault_manager::delete_oldest_archive() while deleting old relink file: "; 00600 es += *ilf; 00601 es += '\n'; 00602 00603 logger.write(es); 00604 00605 // Should I throw an error here, or should deletion of old log files 00606 // not be considered important enough to interrupt archiving? 00607 } 00608 } 00609 } 00610 00611 if (config.delete_old_report_files()) { 00612 estring wildcard; 00613 00614 logger.write("Searching for old report files to delete...\n"); 00615 wildcard = oldest; 00616 wildcard += ".report*"; 00617 logfile_list.path(config.log_dir(), wildcard); 00618 for (ilf = logfile_list.begin(); ilf != logfile_list.end(); ilf++) { 00619 estring file; 00620 00621 file = config.log_dir(); 00622 file += "/"; 00623 file += *ilf; 00624 00625 try { 00626 rm_file(file); 00627 } 00628 catch(error e) { 00629 estring es; 00630 00631 es = "*** ERROR: Could not remove report file: "; 00632 es += *ilf; 00633 00634 logger.write(es); 00635 logger.write(e.str()); 00636 00637 // Should I throw an error here, or should deletion of old log files 00638 // not be considered important enough to interrupt archiving? 00639 } 00640 catch(...) { 00641 estring es; 00642 00643 es = "*** ERROR: Unknown error detected in vault_manager::delete_oldest_archive() while deleting old log file: "; 00644 es += *ilf; 00645 es += '\n'; 00646 00647 logger.write(es); 00648 00649 // Should I throw an error here, or should deletion of old log files 00650 // not be considered important enough to interrupt archiving? 00651 } 00652 } 00653 } 00654 } 00655 00656 /** Prepare the selected vault 00657 00658 Check the selected vault for overflow. If the overflow threshold has been 00659 exceeded and the vault-overflow-behavior setting is not quit, then delete 00660 the oldest archive in the vault. Depending on vault-overflow-behavior, 00661 possibly repeat this action until either there is space free or there are no 00662 archives left in the vault. 00663 00664 */ 00665 void vault_manager::prepare(bool a_assume_overflow) 00666 { 00667 std::string es; 00668 std::string lstr; 00669 00670 /* 00671 estring debug_estr; 00672 00673 debug_estr = "[DEBUG]: vault_manager::prepare() - a_assume_overflow = "; 00674 debug_estr += estring(a_assume_overflow); 00675 debug_estr += "\n"; 00676 logger.write(debug_estr); 00677 */ 00678 00679 if (!initialized()) 00680 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00681 00682 if (!selected()) 00683 throw(INTERNAL_ERROR(0,"No vault selected")); 00684 00685 if (!overflow() && !a_assume_overflow) 00686 return; 00687 00688 // logger.write("Vault has insufficient space\n"); 00689 // logger.write("[DEBUG]: vault_manager::prepare() - Cleaning vault...\n"); 00690 00691 if (config.vault_overflow_behavior() 00692 == configuration_manager::overflow_quit) 00693 { 00694 TRY_nomem(es = "Vault has insufficient space: \""); 00695 TRY_nomem(es += vault()); 00696 TRY_nomem(es += "\""); 00697 throw(ERROR(0,es)); 00698 } 00699 00700 if (config.vault_overflow_behavior() 00701 == configuration_manager::overflow_delete_oldest) 00702 { 00703 if (m_deleted_archives.size() == 0) { 00704 TRY(delete_oldest_archive(),"Failure preparing vault"); 00705 a_assume_overflow = false; 00706 } 00707 else { 00708 logger.write("Vault has insufficient space\n"); 00709 throw(ERROR(0,"Vault has insufficient space")); 00710 } 00711 } 00712 00713 if (!overflow() && !a_assume_overflow) 00714 return; 00715 00716 if (config.vault_overflow_behavior() 00717 == configuration_manager::overflow_delete_until_free) 00718 { 00719 while (overflow() || a_assume_overflow) { 00720 // logger.write("Vault has insufficient space\n"); 00721 TRY(delete_oldest_archive(),"Failure preparing vault"); 00722 a_assume_overflow = false; 00723 } 00724 } 00725 else { 00726 // logger.write("Vault has insufficient space\n"); 00727 exit_manager.assign(exitstat::vault_full); 00728 // throw(ERROR(0,"Vault has insufficient space")); 00729 } 00730 } 00731 00732 /** Return a list of deleted archives */ 00733 const std::vector<std::string>& vault_manager::deleted_archives(void) const 00734 { 00735 if (!initialized()) 00736 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00737 00738 return(m_deleted_archives); 00739 } 00740 00741 /** Return whether or not there was an error deleting archives */ 00742 const bool vault_manager::err_deleted_archives(void) const 00743 { 00744 if (!initialized()) 00745 throw(INTERNAL_ERROR(0,"Vault manager not initialized")); 00746 00747 return(m_da_err); 00748 } 00749 00750 /** The global vault manager */ 00751 vault_manager vaulter; 00752