Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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