rvm  1.11
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vaulter.cc
Go to the documentation of this file.
1 #include "config.h"
2 
3 #include <iostream>
4 #include <vector>
5 #include <map>
6 #include <string>
7 
8 #include "asserts.h"
9 #include "error.h"
10 #include "rmath.h"
11 #include "fs.h"
12 #include "rconfig.h"
13 #include "logger.h"
14 #include "timer.h"
15 #include "estat.h"
16 #include "reporter.h"
17 #include "strfmt.h"
18 
19 #include "vaulter.h"
20 
21 /** C'tor */
23 {
24  if (this != &vaulter)
25  throw(INTERNAL_ERROR(0,"Attempt to allocate multiple vault managers"));
26  clear();
27 }
28 
29 /** Clear the vault manager */
31 {
32  m_lock.clear();
33  m_selected_vault.erase();
34  m_deleted_archives.clear();
35  m_da_err = false;
36  m_initialized = false;
37 }
38 
39 /** Initialize the vault manager */
41 {
42  clear();
43  m_initialized = true;
44 }
45 
46 /** Return the initialized status of the vault manager */
47 const bool vault_manager::initialized(void) const
48 {
49  return(m_initialized);
50 }
51 
52 /** Select a vault
53 
54  If an archive of the same timestamp for the given timestamp resolution
55  already exists on any vault, then that vault is selected. Otherwise select
56  a vault according to vault-selection-behavior.
57 
58  */
60 {
61  std::string es;
62  std::string ts;
63  configuration_manager::vaults_type::const_iterator vi;
64  std::string lockfile;
65  std::string lstr;
66 
67  if (!initialized())
68  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
69 
70  TRY_nomem(es = "Could not select a vault");
71  try {
72  // If an archive exists in any vault by the same timestamp as conf.stamp(),
73  // then use that vault regardless of the selection behavior.
74  for (
75  vi = config.vaults().begin();
76  vi != config.vaults().end();
77  vi++
78  )
79  {
80  subdirectory subdir;
81  subdirectory::iterator sdi;
82 
83  subdir.path(*vi);
84  for (sdi = subdir.begin(); sdi != subdir.end(); sdi++) {
85  TRY_nomem(ts = config.timestamp().str());
86 
87  if (*sdi == ts) {
88  TRY_nomem(lstr = "Existing archive directory found in vault: \"");
89  TRY_nomem(lstr += *vi);
90  TRY_nomem(lstr += "\"\n");
91  logger.write(lstr);
92 
93  if (config.vault_locking()) {
94  TRY_nomem(lockfile = *vi);
95  TRY_nomem(lockfile += "/.rvm_lock");
96  m_lock.clear();
97  m_lock.lockfile(lockfile);
98  if (!m_lock.lock()) {
99  error e(ENOLCK);
100  e.push_back(ERROR_INSTANCE(es));
101  TRY_nomem(es = "Could not lock vault: \"");
102  TRY_nomem(es += *vi);
103  TRY_nomem(es += "\"");
104  e.push_back(ERROR_INSTANCE(es));
105  if (m_lock.is_locked()) {
106  TRY_nomem(es = "Vault is locked by PID: ");
107  TRY_nomem(es += estring(m_lock.locked_by()));
108  e.push_back(ERROR_INSTANCE(es));
109  }
110  throw(e);
111  }
112  }
114  return;
115  }
116 
117  TRY_nomem(ts += ".incomplete");
118 
119  if (*sdi == ts) {
120  TRY_nomem(lstr = "Existing archive directory found in vault: \"");
121  TRY_nomem(lstr += *vi);
122  TRY_nomem(lstr += "\"\n");
123  logger.write(lstr);
124 
125  if (config.vault_locking()) {
126  TRY_nomem(lockfile = *vi);
127  TRY_nomem(lockfile += "/.rvm_lock");
128  m_lock.clear();
129  m_lock.lockfile(lockfile);
130  if (!m_lock.lock()) {
131  error e(ENOLCK);
132  e.push_back(ERROR_INSTANCE(es));
133  TRY_nomem(es = "Could not lock vault: \"");
134  TRY_nomem(es += *vi);
135  TRY_nomem(es += "\"");
136  e.push_back(ERROR_INSTANCE(es));
137  if (m_lock.is_locked()) {
138  TRY_nomem(es = "Vault is locked by PID: ");
139  TRY_nomem(es += estring(m_lock.locked_by()));
140  e.push_back(ERROR_INSTANCE(es));
141  }
142  throw(e);
143  }
144  }
146  return;
147  }
148  }
149  }
150 
151  // If an archive by the same timestamp does not already exist, then select
152  // a vault.
155  {
156  std::pair<std::string,std::string> youngest;
157 
158  for (
159  vi = config.vaults().begin();
160  vi != config.vaults().end();
161  vi++
162  )
163  {
164  subdirectory subdir;
165  subdirectory::iterator sdi;
166 
167  if (config.vault_locking()) {
168  TRY_nomem(lockfile = *vi);
169  TRY_nomem(lockfile += "/.rvm_lock");
170  m_lock.clear();
171  m_lock.lockfile(lockfile);
172  if (m_lock.is_locked()) {
173  std::string lstr;
174 
175  TRY_nomem(lstr = "Skipping locked vault: \"");
176  TRY_nomem(lstr += *vi);
177  TRY_nomem(lstr += "\"\n");
178  logger.write(lstr);
179 
180  continue;
181  }
182  }
183 
184  subdir.path(*vi);
185  for (sdi = subdir.begin(); sdi != subdir.end(); sdi++) {
186  if ((youngest.first < *sdi) || (youngest.first.size() == 0)) {
187  TRY_nomem(youngest.first = *sdi);
188  TRY_nomem(youngest.second = *vi);
189  }
190  }
191  }
192 
194  if (youngest.second.size() == 0) {
196  }
197  else {
198  for (
199  vi = config.vaults().begin();
200  vi != config.vaults().end();
201  vi++
202  )
203  {
204  if (*vi == youngest.second) {
205  if ((vi+1) == config.vaults().end()) {
207  }
208  else {
209  TRY_nomem(m_selected_vault = *(vi+1));
210  }
211  }
212  }
213  }
214  }
215  else {
216  std::pair<std::string,filesystem::size_type> most_space;
217  filesystem fsys;
218 
219  TRY_nomem(most_space.first = config.vaults()[0]);
220  fsys.path(config.vaults()[0]);
221  most_space.second = fsys.free_blocks();
222  for (
223  vi = (config.vaults().begin()+1);
224  vi != config.vaults().end();
225  vi++
226  )
227  {
228  fsys.path(*vi);
229  if (most_space.second < fsys.free_blocks()) {
230  TRY_nomem(most_space.first = *vi);
231  most_space.second = fsys.free_blocks();
232  }
233  }
234  TRY_nomem(m_selected_vault = most_space.first);
235  }
236  }
237  catch(error e) {
238  e.push_back(es);
239  throw(e);
240  }
241  catch(...) {
242  error e(0);
243  if (errno == ENOMEM) {
244  e = err_nomem;
245  e.push_back(es);
246  throw(e);
247  }
248  e = err_unknown;
249  e.push_back(es);
250  throw(e);
251  }
252 
253  if (m_selected_vault.size() == 0)
254  throw(ERROR(0,es));
255 }
256 
257 /** Return a list of archive directories in the selected vault
258 
259  Return a list of archive directories in the selected vault, including
260  incomplete archives. Ignore all other directories.
261  */
263 {
264  subdirectory subdir;
265  subdirectory::iterator sdi;
266 
267  if (!initialized())
268  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
269 
270  if (!selected())
271  throw(INTERNAL_ERROR(0,"No vault selected"));
272 
273  subdir.path(vault());
274 
275  sdi = subdir.begin();
276  while (sdi != subdir.end()) {
277  if (!is_timestamp((*sdi).substr(0,(*sdi).find(".incomplete"))))
278  {
279  subdir.erase(sdi);
280  sdi = subdir.begin();
281  }
282  else {
283  sdi++;
284  }
285  }
286 
287  return(subdir);
288 }
289 
290 /** Return the path to the selected vault */
291 const std::string vault_manager::vault(void) const
292 {
293  if (!initialized())
294  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
295 
296  if (!selected())
297  throw(INTERNAL_ERROR(0,"No vault selected"));
298 
299  return(m_selected_vault);
300 }
301 
302 /** Return whether or not a vault has been selected yet */
303 const bool vault_manager::selected(void) const
304 {
305  bool value = true;
306 
307  if (!initialized())
308  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
309 
310  if (m_selected_vault.size() == 0)
311  value = false;
312 
313  return(value);
314 }
315 
316 /** Return the percent of used blocks and used inodes in the selected vault */
317 void vault_manager::usage(uint16 &a_blocks, uint16 &a_inodes) const
318 {
319  filesystem fsys;
320  safe_num<uint64> blocks, inodes;
321 
322  if (!initialized())
323  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
324 
325  if (!selected())
326  throw(INTERNAL_ERROR(0,"No vault selected"));
327 
328  fsys.path(vault());
329 
330  if (fsys.total_blocks() == 0)
331  blocks = 0;
332  else {
333  try {
334  blocks = fsys.free_blocks();
335  // blocks *= 100;
336  // blocks /= fsys.total_blocks();
337  blocks /= fsys.total_blocks() / 100;
338  }
339  catch(error e) {
340  logger.write("*** ERROR: Overflow error detected in vault_manager::usage() while calculating percent blocks used\n");
341  logger.write(e.str());
342  blocks = 0;
343  }
344  catch(...) {
345  logger.write("*** ERROR: Unknown error detected in vault_manager::usage() while calculating percent blocks used\n");
346  blocks = 0;
347  }
348  }
349 
350  if (fsys.free_inodes() == 0)
351  inodes = 0;
352  else {
353  try {
354  inodes = fsys.free_inodes();
355  // inodes *= 100;
356  // inodes /= fsys.total_inodes();
357  inodes /= fsys.total_inodes() / 100;
358  }
359  catch(error e) {
360  logger.write("*** ERROR: Overflow error detected in vault_manager::usage() while calculating percent inodes used\n");
361  logger.write(e.str());
362  blocks = 0;
363  }
364  catch(...) {
365  logger.write("*** ERROR: Unknown error detected in vault_manager::usage() while calculating percent inodes used\n");
366  blocks = 0;
367  }
368  }
369 
370  ASSERT(blocks <= max_limit(blocks));
371  ASSERT(inodes <= max_limit(inodes));
372 
373  a_blocks = blocks.value();
374  a_inodes = inodes.value();
375 }
376 
377 /** Test to see if a vault has exceeded it's overflow threshold */
378 const bool vault_manager::overflow(bool a_report)
379 {
380  uint16 free_blocks;
381  uint16 free_inodes;
382  bool value = false;
383  std::string lstr;
384 
385  if (!initialized())
386  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
387 
388  if (!selected())
389  throw(INTERNAL_ERROR(0,"No vault selected"));
390 
391  usage(free_blocks, free_inodes);
392  if (free_blocks < config.vault_overflow_blocks())
393  value = true;
394  if (free_inodes < config.vault_overflow_inodes())
395  value = true;
396 
397  if (value && a_report) {
398  TRY_nomem(lstr = "Vault overflow detected: ");
399  TRY_nomem(lstr += vault());
400  TRY_nomem(lstr += "\n");
401  logger.write(lstr);
402 
403  TRY_nomem(lstr = " Threshold: ");
404  TRY_nomem(lstr +=
406  static_cast<uint16>(100)));
407  TRY_nomem(lstr += " free blocks, ");
408  TRY_nomem(lstr +=
410  static_cast<uint16>(100)));
411  TRY_nomem(lstr += " free inodes");
412  TRY_nomem(lstr += "\n");
413  logger.write(lstr);
414 
415  TRY_nomem(lstr = "Vault capacity: ");
416  TRY_nomem(lstr += percent_string(free_blocks,static_cast<uint16>(100)));
417  TRY_nomem(lstr += " free blocks, ");
418  TRY_nomem(lstr += percent_string(free_inodes,static_cast<uint16>(100)));
419  TRY_nomem(lstr += " free inodes");
420  TRY_nomem(lstr += "\n");
421  logger.write(lstr);
422 
423  estring __e = estring("Overflow Detected:");
425  vault_stats_report(estring("Overflow Detected:"),filesystem(vault()))
426  );
427  }
428 
429  return(value);
430 }
431 
432 /** Find the oldest archive in the vault and delete it */
434 {
435  std::string es;
436  estring ts;
437  estring tsi;
438  std::string lstr;
439  subdirectory archive_list;
440  std::string oldest;
441  std::string dir;
442  std::string delete_dir;
443  estring estr;
444  timer t;
445  uint16 free_blocks, free_inodes;
446  subdirectory logfile_list;
447  subdirectory::const_iterator ilf;
448 
449  if (!initialized())
450  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
451 
452  if (!selected())
453  throw(INTERNAL_ERROR(0,"No vault selected"));
454 
455  TRY_nomem(ts = config.timestamp().str());
456  TRY_nomem(tsi = ts + ".incomplete");
457 
458  archive_list = get_archive_list();
459  if (
460  (archive_list.size() == 0)
461  || (
462  (archive_list.size() == 1)
463  && (archive_list[0] == ts || archive_list[0] == tsi)
464  )
465  )
466  {
467  TRY_nomem(es = "Vault has insufficient space: \"");
468  TRY_nomem(es += vault());
469  TRY_nomem(es += "\"");
471  throw(ERROR(0,es));
472  }
473 
474  TRY_nomem(oldest = archive_list[0]);
475  if (oldest == ts || oldest == tsi) {
476  TRY_nomem(lstr = "Oldest is actually archive in use: \"");
477  TRY_nomem(lstr += oldest);
478  TRY_nomem(lstr += "\" Skipping to next archive...\n");
479  logger.write(lstr);
480  TRY_nomem(oldest = archive_list[1]);
481  }
482 
483  if (oldest.find(".incomplete") != std::string::npos) {
484  TRY_nomem(lstr = "WARNING: Oldest archive found is incomplete.\n");
485  logger.write(lstr);
486  }
487 
488  TRY_nomem(lstr = "Deleting oldest archive: \"");
489  TRY_nomem(lstr += oldest);
490  TRY_nomem(lstr += "\"\n");
491  logger.write(lstr);
492 
493  TRY_nomem(dir = vault());
494  TRY_nomem(dir += "/");
495  TRY_nomem(dir += oldest);
496  t.start();
497  try {
498  m_deleted_archives.push_back(oldest);
499  }
500  catch(...) {
501  m_da_err = true;
502  }
503 
504  delete_dir = dir;
505  if (delete_dir.find(".deleting") == std::string::npos)
506  delete_dir += ".deleting";
507  rename_file(dir, delete_dir);
508  if (config.delete_command_path().size() == 0)
509  rm_recursive(delete_dir);
510  else {
511  std::string es;
512  std::string cmdline;
513 
514  TRY_nomem(es = "Delete command returned non-zero exit value: \"");
515  TRY_nomem(es += oldest);
516  TRY_nomem(es += "\"");
517  cmdline = config.delete_command_path();
518  cmdline += " \"";
519  cmdline += delete_dir;
520  cmdline += "\"";
521  if (system(cmdline.c_str()) != 0)
522  throw(ERROR(1,es));
523  }
524  t.stop();
525 
526  TRY_nomem(lstr = "Deletion complete, duration: ");
527  TRY_nomem(lstr += t.duration());
528  TRY_nomem(lstr += "\n");
529  logger.write(lstr);
530 
531  usage(free_blocks, free_inodes);
532  TRY_nomem(lstr = "Vault capacity: ");
533  TRY_nomem(lstr += percent_string(free_blocks,static_cast<uint16>(100)));
534  TRY_nomem(lstr += " free blocks, ");
535  TRY_nomem(lstr += percent_string(free_inodes,static_cast<uint16>(100)));
536  TRY_nomem(lstr += " free inodes");
537  TRY_nomem(lstr += "\n");
538  logger.write(lstr);
539 
540  estr = "Deleted ";
541  estr += oldest;
542  estr += ":";
544 
545  // This is a grey area for me: Should log/report file removal be managed by
546  // log_manager/report_manager, or is it OK to do it here? For simplicity
547  // sake, I do it here.
548  //
550  estring wildcard;
551 
552  logger.write("Searching for old log files to delete...\n");
553  wildcard = oldest;
554  wildcard += ".log*";
555  logfile_list.path(config.log_dir(), wildcard);
556  for (ilf = logfile_list.begin(); ilf != logfile_list.end(); ilf++) {
557  estring file;
558 
559  file = config.log_dir();
560  file += "/";
561  file += *ilf;
562 
563  try {
564  rm_file(file);
565  }
566  catch(error e) {
567  estring es;
568 
569  es = "*** ERROR: Could not remove log file: ";
570  es += *ilf;
571 
572  logger.write(es);
573  logger.write(e.str());
574 
575  // Should I throw an error here, or should deletion of old log files
576  // not be considered important enough to interrupt archiving?
577  }
578  catch(...) {
579  estring es;
580 
581  es = "*** ERROR: Unknown error detected in vault_manager::delete_oldest_archive() while deleting old log file: ";
582  es += *ilf;
583  es += '\n';
584 
585  logger.write(es);
586 
587  // Should I throw an error here, or should deletion of old log files
588  // not be considered important enough to interrupt archiving?
589  }
590  }
591 
592  wildcard = oldest;
593  wildcard += ".relink*";
594  logfile_list.path(config.log_dir(), wildcard);
595  for (ilf = logfile_list.begin(); ilf != logfile_list.end(); ilf++) {
596  estring file;
597 
598  file = config.log_dir();
599  file += "/";
600  file += *ilf;
601 
602  try {
603  rm_file(file);
604  }
605  catch(error e) {
606  estring es;
607 
608  es = "*** ERROR: Could not remove relink file: ";
609  es += *ilf;
610 
611  logger.write(es);
612  logger.write(e.str());
613 
614  // Should I throw an error here, or should deletion of old log files
615  // not be considered important enough to interrupt archiving?
616  }
617  catch(...) {
618  estring es;
619 
620  es = "*** ERROR: Unknown error detected in vault_manager::delete_oldest_archive() while deleting old relink file: ";
621  es += *ilf;
622  es += '\n';
623 
624  logger.write(es);
625 
626  // Should I throw an error here, or should deletion of old log files
627  // not be considered important enough to interrupt archiving?
628  }
629  }
630  }
631 
633  estring wildcard;
634 
635  logger.write("Searching for old report files to delete...\n");
636  wildcard = oldest;
637  wildcard += ".report*";
638  logfile_list.path(config.log_dir(), wildcard);
639  for (ilf = logfile_list.begin(); ilf != logfile_list.end(); ilf++) {
640  estring file;
641 
642  file = config.log_dir();
643  file += "/";
644  file += *ilf;
645 
646  try {
647  rm_file(file);
648  }
649  catch(error e) {
650  estring es;
651 
652  es = "*** ERROR: Could not remove report file: ";
653  es += *ilf;
654 
655  logger.write(es);
656  logger.write(e.str());
657 
658  // Should I throw an error here, or should deletion of old log files
659  // not be considered important enough to interrupt archiving?
660  }
661  catch(...) {
662  estring es;
663 
664  es = "*** ERROR: Unknown error detected in vault_manager::delete_oldest_archive() while deleting old log file: ";
665  es += *ilf;
666  es += '\n';
667 
668  logger.write(es);
669 
670  // Should I throw an error here, or should deletion of old log files
671  // not be considered important enough to interrupt archiving?
672  }
673  }
674  }
675 }
676 
677 /** Prepare the selected vault
678 
679  Check the selected vault for overflow. If the overflow threshold has been
680  exceeded and the vault-overflow-behavior setting is not quit, then delete
681  the oldest archive in the vault. Depending on vault-overflow-behavior,
682  possibly repeat this action until either there is space free or there are no
683  archives left in the vault.
684 
685 */
686 void vault_manager::prepare(bool a_assume_overflow)
687 {
688  std::string es;
689  std::string lstr;
690 
691  /*
692  estring debug_estr;
693 
694  debug_estr = "[DEBUG]: vault_manager::prepare() - a_assume_overflow = ";
695  debug_estr += estring(a_assume_overflow);
696  debug_estr += "\n";
697  logger.write(debug_estr);
698  */
699 
700  if (!initialized())
701  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
702 
703  if (!selected())
704  throw(INTERNAL_ERROR(0,"No vault selected"));
705 
706  if (!overflow() && !a_assume_overflow)
707  return;
708 
709  // logger.write("Vault has insufficient space\n");
710  // logger.write("[DEBUG]: vault_manager::prepare() - Cleaning vault...\n");
711 
714  {
715  TRY_nomem(es = "Vault has insufficient space: \"");
716  TRY_nomem(es += vault());
717  TRY_nomem(es += "\"");
718  throw(ERROR(0,es));
719  }
720 
723  {
724  if (m_deleted_archives.size() == 0) {
725  TRY(delete_oldest_archive(),"Failure preparing vault");
726  a_assume_overflow = false;
727  }
728  else {
729  logger.write("Vault has insufficient space\n");
730  throw(ERROR(0,"Vault has insufficient space"));
731  }
732  }
733 
734  if (!overflow() && !a_assume_overflow)
735  return;
736 
739  {
740  while (overflow() || a_assume_overflow) {
741  // logger.write("Vault has insufficient space\n");
742  TRY(delete_oldest_archive(),"Failure preparing vault");
743  a_assume_overflow = false;
744  }
745  }
746  else {
747  // logger.write("Vault has insufficient space\n");
749  // throw(ERROR(0,"Vault has insufficient space"));
750  }
751 }
752 
753 /** Return a list of deleted archives */
754 const std::vector<std::string>& vault_manager::deleted_archives(void) const
755 {
756  if (!initialized())
757  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
758 
759  return(m_deleted_archives);
760 }
761 
762 /** Return whether or not there was an error deleting archives */
764 {
765  if (!initialized())
766  throw(INTERNAL_ERROR(0,"Vault manager not initialized"));
767 
768  return(m_da_err);
769 }
770 
771 /** The global vault manager */
773 
Safely manipulate numbers without worryiung about over/underflow error.
Definition: rmath.h:281
Retrieve information about a filesystem.
Definition: fs.h:316
const size_type total_inodes(void) const
Return the filesystem's total number of inodes, if supported by the filesystem, otherwise the result ...
Definition: fs.cc:1662
void clear(void)
Clear the vault manager.
Definition: vaulter.cc:30
log_manager logger
The global log manager.
Definition: logger.cc:138
void init(void)
Initialize the vault manager.
Definition: vaulter.cc:40
const uint16 & vault_overflow_blocks(void) const
Return the vault-overflow-blocks.
Definition: rconfig.cc:1622
simple_lock m_lock
Definition: vaulter.h:45
An extended string class.
Definition: estring.h:52
#define ASSERT(code)
Definition: asserts.h:9
void path(const std::string &a_path)
Retrieve information about the filesystem on which the given path resides.
Definition: fs.cc:1600
#define err_nomem
Definition: error.h:116
void usage(uint16 &a_blocks, uint16 &a_inodes) const
Return the percent of used blocks and used inodes in the selected vault.
Definition: vaulter.cc:317
const bool initialized(void) const
Return the initialized status of the vault manager.
Definition: vaulter.cc:47
const bool err_deleted_archives(void) const
Return whether or not there was an error deleting archives.
Definition: vaulter.cc:763
const std::vector< std::string > & deleted_archives(void) const
Return a list of deleted archives.
Definition: vaulter.cc:754
const T value(void) const
Return the value.
Definition: rmath.h:311
const bool delete_old_log_files(void) const
Return the value of delete-old-log-files.
Definition: rconfig.cc:1532
void push_back(const error_instance &a_e)
Definition: error.cc:215
std::string percent_string(const T &a_complete, const T &a_total)
Given a count complete and a count total, calculate a percentage.
Definition: strfmt.h:157
static const T max_limit()
A small set of numeric limits routines, since gcc prior to 3.x doesn't have numeric_limits.
Definition: rmath.h:20
void write(const std::string &a_str, const uint16 a_indention=0, const configuration_manager::logging_type a_logging_level=configuration_manager::logging_manager, const pid_t a_pid=pid())
Write a string to the log file.
Definition: logger.cc:96
bool lock(void)
Lock.
Definition: fs.cc:1778
const class timestamp & timestamp(void) const
Return the timestamp of this instance of rvm.
Definition: rconfig.cc:1505
const std::string & log_dir(void) const
Return the log-dir path.
Definition: rconfig.cc:1523
const bool delete_old_report_files(void) const
Return the value of delete-old-report-files.
Definition: rconfig.cc:1541
bool m_da_err
Definition: vaulter.h:43
vault_manager()
C'tor.
Definition: vaulter.cc:22
const uint16 & vault_overflow_inodes(void) const
Return the vault-overflow-inodes.
Definition: rconfig.cc:1631
const vaults_type & vaults(void) const
Return the vaults.
Definition: rconfig.cc:1604
const selection_type & vault_selection_behavior(void) const
Return the vault-selection-behavior.
Definition: rconfig.cc:1640
Select, monitor, and prepare vaults.
Definition: vaulter.h:9
#define err_unknown
Definition: error.h:114
void lockfile(const std::string &a_lockfile)
Set the lockfile path.
Definition: fs.cc:1733
std::vector< std::string > m_deleted_archives
Definition: vaulter.h:42
void assign(value_type a_value)
Definition: estat.cc:15
std::string m_selected_vault
Definition: vaulter.h:41
bool m_initialized
Definition: vaulter.h:44
Vault stats report.
Definition: reporter.h:13
report_manager reporter
The global report manager.
Definition: reporter.cc:1124
void select(void)
Select a vault.
Definition: vaulter.cc:59
#define TRY_nomem(code)
Definition: error.h:144
const subdirectory get_archive_list(void)
Return a list of archive directories in the selected vault.
Definition: vaulter.cc:262
void start(void)
Start (or restart) the timer.
Definition: timer.cc:137
An error class.
Definition: error.h:72
const type & path(const std::string a_path, const std::string a_filter="*")
Return a vector of strings of a list of files in a subdirectory.
Definition: fs.cc:1361
const std::string vault(void) const
Return the path to the selected vault.
Definition: vaulter.cc:291
const pid_type locked_by(void) const
Get the PID of the locking process.
Definition: fs.cc:1746
const size_type free_inodes(void) const
Return the filesystem's total number of free inodes, if supported by the filesystem, otherwise the result is system-dependent, but usually 0.
Definition: fs.cc:1674
#define TRY(code, es)
Definition: error.h:126
void rm_recursive(const std::string a_path)
Recursively delete the contents of a directory.
Definition: fs.cc:1414
void prepare(bool a_assume_overflow=false)
Prepare the selected vault.
Definition: vaulter.cc:686
#define INTERNAL_ERROR(e, s)
Definition: error.h:123
configuration_manager config
The global configuration manager instance.
Definition: rconfig.cc:3364
exitstat exit_manager
Definition: estat.cc:25
bool is_timestamp(const std::string &a_s)
Return true if the string is a valid timestamp.
Definition: tstamp.cc:502
void clear(void)
Clear the simple_lock object.
Definition: fs.cc:1724
vault_report & vault(void)
Return the vault reporter object.
Definition: reporter.cc:969
const size_type free_blocks(void) const
Return the filesystem's number of free blocks.
Definition: fs.cc:1640
const std::string duration(void) const
Generate a duration string.
Definition: timer.cc:385
void add_report(const vault_stats_report &a_class)
Add a vault report to the list.
Definition: reporter.cc:176
#define ERROR_INSTANCE(s)
Definition: error.h:67
void rm_file(const std::string a_path)
Remove a file.
Definition: fs.cc:637
void delete_oldest_archive(void)
Find the oldest archive in the vault and delete it.
Definition: vaulter.cc:433
const std::string str(void) const
Generate a string.
Definition: tstamp.cc:387
#define ERROR(e, s)
Definition: error.h:120
const bool overflow(bool a_report=false)
Test to see if a vault has exceeded it's overflow threshold.
Definition: vaulter.cc:378
const std::string & delete_command_path(void) const
Return the delete-command-path.
Definition: rconfig.cc:1559
void rename_file(const std::string a_from, const std::string a_to)
Rename a file or directory.
Definition: fs.cc:709
const overflow_type & vault_overflow_behavior(void) const
Return the vault-overflow-behavior.
Definition: rconfig.cc:1613
const bool vault_locking(void) const
Return the vault-locking selection.
Definition: rconfig.cc:1649
void stop(void)
Stop the timer.
Definition: timer.cc:143
Retrieve a list of files in a subdirectory that match a given wildcard filename.
Definition: fs.h:273
const std::string str(const std::string a_prefix="") const
Definition: error.cc:304
const size_type total_blocks(void) const
Return the filesystem's total number of blocks.
Definition: fs.cc:1630
const bool is_locked(void) const
Find out whether or not the lock is in place.
Definition: fs.cc:1765
const bool selected(void) const
Return whether or not a vault has been selected yet.
Definition: vaulter.cc:303
Used as a stopwatch.
Definition: timer.h:29
vault_manager vaulter
The global vault manager.
Definition: vaulter.cc:772