您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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