You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // snfGBUdbmgr.cpp
  2. // Copyright (C) 2006 - 2009 ARM Research Labs, LLC.
  3. // See www.armresearch.com for the copyright terms.
  4. //
  5. // See snfGBUdbmgr.hpp for details.
  6. #include "snfGBUdbmgr.hpp"
  7. #include <unistd.h>
  8. using namespace std;
  9. const ThreadType snfGBUdbmgr::Type("snfGBUdbmgr"); // The thread's type.
  10. snfGBUdbmgr::snfGBUdbmgr() : // Clean init and start thread.
  11. Thread(snfGBUdbmgr::Type, "GBUdb Manager"), // XCI Manager type and Name.
  12. CondenseGuardTime(600000), // 10 minute guard time by default.
  13. TimeTriggerOnOff(true), // By default, condense once per day.
  14. TimeTrigger(84600000),
  15. PostsTriggerOnOff(false), // By default do not trigger on posts.
  16. PostsTriggerValue(262144), // but if we do, use a quarter million.
  17. RecordsTriggerOnOff(false), // By default do not trigger on records.
  18. RecordsTriggerValue(150000), // but if we do, use 150K.
  19. SizeTriggerOnOff(true), // By default trigger on size as a
  20. SizeTriggerValue(150), // safety valve at 150Mbytes.
  21. CheckpointOnOff(true), // By default save a snapshot once
  22. CheckpointTrigger(3600000), // every hour.
  23. MyGBUdb(NULL), // NULL our links to avoid
  24. MyLOGmgr(NULL), // any errors when the thread starts.
  25. TimeToStop(false) { // It is not time to stop ;-)
  26. run(); // Start our thread.
  27. }
  28. snfGBUdbmgr::~snfGBUdbmgr() { // Clean shutdown & stop thread.
  29. stop(); // Stop the thread if it's not already.
  30. MyGBUdb = NULL; // NULL our links and false our
  31. MyLOGmgr = NULL; // configuration for safety.
  32. Configured = false;
  33. }
  34. void snfGBUdbmgr::linkGBUdb(GBUdb& G) { // Connect to our GBUdb
  35. ScopeMutex JustMe(MyMutex); // Lock for the config change.
  36. MyGBUdb = &G; // Set the new link.
  37. }
  38. void snfGBUdbmgr::linkLOGmgr(snfLOGmgr& L) { // Connect to our LOGmgr
  39. ScopeMutex JustMe(MyMutex); // Lock for the config change.
  40. MyLOGmgr = &L; // Set the new link.
  41. }
  42. void snfGBUdbmgr::configure(snfCFGData& CFGData) { // Establish or change our CFG.
  43. ScopeMutex JustMe(MyMutex); // Only when we're not busy.
  44. // Set up our configuration from the CFGData provided.
  45. // Being careful not to muck with running timers unless their
  46. // configuration values have actually changed...
  47. const int SECsASms = 1000; // How to convert seconds to milliseconds.
  48. if(CondenseGuardTime.getDuration() != // If the condensation guard time is
  49. (SECsASms * CFGData.gbudb_database_condense_minimum_seconds_between)) { // new and different then set the
  50. CondenseGuardTime.setDuration( // condensation guard timer to the
  51. (SECsASms * CFGData.gbudb_database_condense_minimum_seconds_between) // new value.
  52. );
  53. }
  54. TimeTriggerOnOff = CFGData.gbudb_database_condense_time_trigger_on_off; // Time-Trigger On?
  55. if(TimeTrigger.getDuration() != // Time-Trigger different?
  56. (SECsASms * CFGData.gbudb_database_condense_time_trigger_seconds)) {
  57. TimeTrigger.setDuration( // If it is then adopt the new value.
  58. SECsASms * CFGData.gbudb_database_condense_time_trigger_seconds
  59. );
  60. }
  61. PostsTriggerOnOff = CFGData.gbudb_database_condense_posts_trigger_on_off; // Posts trigger on?
  62. PostsTriggerValue = CFGData.gbudb_database_condense_posts_trigger_posts; // What is the posts trigger threshold?
  63. RecordsTriggerOnOff = CFGData.gbudb_database_condense_records_trigger_on_off; // Records trigger on?
  64. RecordsTriggerValue = CFGData.gbudb_database_condense_records_trigger_records; // What is the records trigger threshold?
  65. SizeTriggerOnOff = CFGData.gbudb_database_condense_size_trigger_on_off; // Size trigger on?
  66. SizeTriggerValue = CFGData.gbudb_database_condense_size_trigger_megabytes; // What is the size trigger threshold?
  67. // Checkpoint
  68. CheckpointOnOff = CFGData.gbudb_database_checkpoint_on_off; // Checkpoint on?
  69. if(CheckpointTrigger.getDuration() != // If the Checkpoint time is
  70. (SECsASms * CFGData.gbudb_database_checkpoint_secs)) { // new and different then
  71. CheckpointTrigger.setDuration( // adopt the new value.
  72. (SECsASms * CFGData.gbudb_database_checkpoint_secs)
  73. );
  74. }
  75. // GBUdb file name
  76. string GBUdbFileName; // Formulate the correct GBUdb file name
  77. GBUdbFileName = CFGData.paths_workspace_path + // using the CFGData.
  78. CFGData.node_licenseid + ".gbx";
  79. if( // If the file name for our GBUdb
  80. NULL == (*MyGBUdb).FileName() || // is not yet set, or
  81. 0 != GBUdbFileName.compare((*MyGBUdb).FileName()) // if it is different than the
  82. ) { // formulated file name we have then
  83. (*MyGBUdb).FileName(GBUdbFileName.c_str()); // set the GBUdb file name.
  84. }
  85. // Safety check to set the Configured bit.
  86. if(NULL != MyGBUdb && NULL != MyLOGmgr) { // If we have all of our parts
  87. Configured = true; // then set our configured flag.
  88. } else { // If anything is missing then
  89. Configured = false; // make sure the flag is false.
  90. }
  91. }
  92. //// The snfGBUdbmgr::load() method isn't exactly what you would expect. It
  93. // will load the rulebase file if that file exists, but if not it does nothing.
  94. // The intention is that a new GBUdb will alread have been created. If a
  95. // pre-existing GBUdb is available then that one will be loaded for use. If
  96. // it does not exist, then the new, empty GBUdb will be used instead and will
  97. // eventually be saved for later re-use.
  98. void snfGBUdbmgr::load() { // Load the GBUdb as configured.
  99. ScopeMutex JustMe(MyMutex); // Just me while I do this.
  100. if( // Perform some sanity checks.
  101. NULL != MyGBUdb && // If we have a GBUdb and
  102. 0 < string(MyGBUdb->FileName()).length() && // it has a file name and
  103. 0 == access(MyGBUdb->FileName(),R_OK) // the file can be accessed
  104. ) { // then we can proceed:
  105. MyGBUdb->load(); // Load the GBUdb from disk.
  106. } // If that didn't work we'll assume
  107. } // we're starting up a new gbx file ;-)
  108. // DoMaintenanceWork encapsulates all of our maintenance functions. It runs
  109. // with the mutex locked so that the configuration is stable during each pass.
  110. void snfGBUdbmgr::DoMaintenanceWork() { // Do our watchdog work.
  111. if(!Configured) return; // Do nothing if we're not configured.
  112. ScopeMutex JustMe(MyMutex); // No CFG changes while I'm busy.
  113. if(CondenseGuardTime.isExpired()) { // If we are allowed to condense
  114. bool CondenseTriggered = false; // check to see if we should.
  115. // time-trigger
  116. if(
  117. TimeTriggerOnOff && // If the time-trigger is on
  118. TimeTrigger.isExpired() // and the time has expired
  119. ) { // then it is time to condense.
  120. CondenseTriggered = true; // Set the condense flag and
  121. TimeTrigger.restart(); // restart the timer.
  122. }
  123. // posts-trigger
  124. if(
  125. PostsTriggerOnOff && // If posts-trigger is on
  126. (*MyGBUdb).Posts() >= PostsTriggerValue // and the Posts() count is high
  127. ) { // enough then trigger the
  128. CondenseTriggered = true; // condense operation.
  129. }
  130. // records-trigger
  131. if(
  132. RecordsTriggerOnOff && // If records-trigger is on
  133. (*MyGBUdb).IPCount() >= RecordsTriggerValue // and the number of IPs is high
  134. ) { // enough then trigger the
  135. CondenseTriggered = true; // condense operation.
  136. }
  137. // size-trigger
  138. const int MByte = 1048576; // How big is a megabyte anyway?
  139. if(
  140. SizeTriggerOnOff && // If size-trigger is on
  141. ((*MyGBUdb).Size()/MByte) >= SizeTriggerValue // and the size of the db is high
  142. ) { // enough then trigger
  143. CondenseTriggered = true; // the condense operation.
  144. }
  145. if(CondenseTriggered) { // If we need to condense then
  146. (*MyGBUdb).reduce(); // reduce all counts in the db
  147. (*MyGBUdb).compress(); // and elminate any that drop to zero.
  148. CondenseGuardTime.restart(); // That done, reset the guard timer.
  149. (*MyLOGmgr).RecordCondenseEvent(); // Log the event.
  150. }
  151. }
  152. // Time to save a snapshot?
  153. if(
  154. CheckpointOnOff && // If checkpoints are turned on
  155. CheckpointTrigger.isExpired() // and it is time to create one
  156. ) {
  157. (*MyGBUdb).saveSnapshot(); // then save a snapshot and
  158. CheckpointTrigger.restart(); // restart the timer.
  159. (*MyLOGmgr).RecordSaveEvent(); // Log the event.
  160. }
  161. }
  162. // Stopping the thread...
  163. void snfGBUdbmgr::stop() { // To stop the manager thread we
  164. if(!TimeToStop) { // check to see we need to then
  165. TimeToStop = true; // set the time to stop flag
  166. join(); // and join the thread.
  167. }
  168. }
  169. // The thread's task is to call DoMaintenanceWork() once every second.
  170. void snfGBUdbmgr::myTask() { // This is what our thread does.
  171. Sleeper WaitATic(1000); // We need a 1 second sleeper.
  172. while(!TimeToStop) { // While it's not time to stop
  173. WaitATic(); // wait a tic and then do work.
  174. DoMaintenanceWork();
  175. }
  176. }
  177. void snfGBUdbmgr::GetAlertsForSync(list<GBUdbAlert>& AlertList) { // Fill AlertList w/ outgoing alerts.
  178. (*MyGBUdb).GetAlerts(AlertList); // For now, just pass this through.
  179. }
  180. void snfGBUdbmgr::ProcessReflections(list<GBUdbAlert>& Reflections) { // Integrate returning reflections.
  181. (*MyGBUdb).ImportAlerts(Reflections); // For now, just pass this through.
  182. }