- Timestamp:
- 07/20/10 12:34:13 (14 years ago)
- Location:
- Evidence
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
Evidence/Alarm.cc
r229 r253 36 36 char *AlarmText; 37 37 int MasterAlarm; 38 pthread_mutex_t Mutex;39 38 40 39 void infoHandler(); … … 68 67 AlarmText = NULL; 69 68 70 if (pthread_mutex_init(&Mutex, NULL) != 0) {71 Message(FATAL, "pthread_mutex_init failed");72 }73 74 69 // Handling of servies will only start after start() 75 70 autoStartOff(); … … 102 97 103 98 // Provide command to reset Level 104 Command = new DimCommand(" Alarm/ResetAlarm", (char *) "C", this);99 Command = new DimCommand("ResetAlarm", (char *) "C", this); 105 100 106 101 // List set up, can start handling … … 121 116 delete Summary; 122 117 delete[] AlarmText; 123 124 pthread_mutex_destroy(&Mutex);125 118 } 126 119 … … 143 136 void AlarmHandler::commandHandler() { 144 137 145 DimCommand *C = getCommand(); 146 147 // Check for valid command parameter 148 if (C != Command) return; 149 if (C->getSize() == 0) return; 150 if (*((char *) C->getData() + C->getSize() - 1) != '\0') return; 138 // Safety check 139 string Server = ToString((char *) "C", getCommand()->getData(), getCommand()->getSize()); 140 if (getCommand() != Command || Server.empty()) return; 151 141 152 142 // Reset alarm level and publish/log action 153 for (int i=0; i<List.size(); i++) if (List[i].Server == C->getString()) {154 Message(INFO, "Alarm level of server %s reset by %s (ID %d)", C->getString(), getClientName(), getClientId());143 for (int i=0; i<List.size(); i++) if (List[i].Server == Server) { 144 Message(INFO, "Alarm level of server %s reset by %s (ID %d)", Server.c_str(), getClientName(), getClientId()); 155 145 List[i].Level = 0; 156 146 List[i].WarnedLevel = 0; … … 161 151 162 152 163 // Update alarm status summary 153 // Update alarm status summary (locking since access can be from main thread and DIM handler threads) 164 154 void AlarmHandler::UpdateAlarmSummary() { 165 155 … … 167 157 int Alarm, Ret; 168 158 169 // Lock because access can be from main thread and DIM handler thread 170 if ((Ret = pthread_mutex_lock(&Mutex)) != 0) { 171 Message(FATAL, "pthread_mutex_lock() failed (%s)", strerror(Ret)); 172 } 173 159 Lock(); 160 174 161 for (int i=0; i<List.size(); i++) { 175 162 // Alarm level description … … 211 198 AlarmText = Tmp; 212 199 213 // Unlock 214 if ((Ret = pthread_mutex_unlock(&Mutex)) != 0) { 215 Message(FATAL, "pthread_mutex_unlock() failed (%s)", strerror(Ret)); 216 } 200 Unlock(); 217 201 } 218 202 -
Evidence/Bridge.cc
r232 r253 64 64 GetConfig("cmdallow", " "); 65 65 ActivateSignal(SIGUSR2); 66 67 ConfigChanged(); 66 68 } 67 69 … … 84 86 85 87 86 // Called by signal handler in case configuration changes (also initially)88 // Called by signal handler in case configuration changes and by constructor 87 89 void Bridge::ConfigChanged() { 88 90 -
Evidence/Config.cc
r229 r253 7 7 "Config/ModifyTime" contains the last modification UNIX time. 8 8 - The contents of the configuration file is available through Config/ConfigData. 9 - The currentparser removes all tabs, multiple, leading and trailing spaces, and10 concatenates lines ending with '+'.9 - The parser removes all tabs, multiple, leading and trailing spaces, and 10 concatenates all lines until the next item. 11 11 12 12 A mutex is used for preventing concurrent access to the configuration data from 13 13 the methods rpcHandler() and ConfigChanged(). 14 14 15 Oliver Grimm, April201015 Oliver Grimm, July 2010 16 16 17 17 \********************************************************************/ 18 18 19 #define DEFAULT_CONFIG "../config/Evidence.conf"20 19 #define SERVER_NAME "Config" 21 20 … … 35 34 36 35 private: 37 struct Item { 38 string Name; 39 string Data; 40 }; 41 vector<struct Item> List; 42 36 map<string, string> Map; 43 37 FILE *File; 44 38 char *FileContent; 45 39 DimService *ConfigModified; 46 40 DimService *ConfigContent; 47 pthread_mutex_t Mutex;48 41 49 42 void rpcHandler(); … … 67 60 FileContent = NULL; 68 61 69 // Signaling interferes with inotify() mechnism70 signal(SIGUSR2, SIG_IGN);71 72 // Initialise mutex (errno is not set by pthread_mutex_init())73 if (pthread_mutex_init(&Mutex, NULL) != 0) {74 Message(FATAL, "pthread_mutex_init() failed");75 }76 77 62 // Open configuration file 78 63 if ((File = fopen(Filename, "r")) == NULL) { … … 97 82 delete ConfigContent; 98 83 delete[] FileContent; 99 100 if (pthread_mutex_destroy(&Mutex) != 0) Message(ERROR, "pthread_mutex_destroy() failed");101 84 } 102 85 … … 105 88 void EvidenceConfig::rpcHandler() { 106 89 107 string Response; 108 109 // Lock because ConfigChange() might access concurrently 110 if (pthread_mutex_lock(&Mutex) != 0) Message(ERROR, "pthread_mutex_lock() failed in rpcHandler()"); 111 90 string Response, Item = ToString((char *) "C", getData(), getSize()); 91 112 92 // Search for config data in list (default response is empty string) 113 for (int i=0; i<List.size(); i++) { 114 if (List[i].Name == getString()) Response = List[i].Data; 115 } 116 117 // Unlock 118 if (pthread_mutex_unlock(&Mutex) != 0) Message(ERROR, "pthread_mutex_unlock() failed in rpcHandler()"); 93 // Lock because ConfigChange() might also access concurrently 94 Lock(); 95 if (Map.count(Item) != 0) Response = Map[Item]; 96 Unlock(); 119 97 120 98 // Send data and update Status … … 122 100 123 101 Message(INFO, "Client '%s' (ID %d) requested '%s'. Send '%s'.", 124 DimServer::getClientName(), 125 DimServer::getClientId(), 126 getString(), Response.c_str()); 102 DimServer::getClientName(), DimServer::getClientId(), 103 Item.c_str(), Response.c_str()); 127 104 } 128 105 … … 227 204 if (Section.empty() || Parameter.empty() || Data.empty()) return; 228 205 229 // Prepare new item of configuration list230 struct Item New;231 New.Name = Section + ' ' + Parameter;232 New.Data = Data;233 234 206 // Add to configuration list 235 if (pthread_mutex_lock(&Mutex) != 0) Message(ERROR, "pthread_mutex_lock() failed in ConfigChanged()");236 List.push_back(New);237 if (pthread_mutex_unlock(&Mutex) != 0) Message(ERROR, "pthread_mutex_unlock() failed in ConfigChanged()");207 Lock(); 208 Map[Section + " " + Parameter] = Data; 209 Unlock(); 238 210 } 239 211 … … 255 227 // 256 228 int main(int argc, char *argv[]) { 257 258 static EvidenceConfig Config(argc<2 ? DEFAULT_CONFIG : argv[1]); 259 229 230 if (argc != 2) { 231 printf("Usage: %s <Configuration-File>\n", argv[0]); 232 exit(EXIT_FAILURE); 233 } 234 235 static EvidenceConfig Config(argv[1]); 260 236 int Notify; 261 237 struct inotify_event Event; … … 264 240 Config.Message(EvidenceConfig::WARN, "inotify_init() failed, cannot monitor changes of configuration file (%s)\n", strerror(errno)); 265 241 } 266 else if (inotify_add_watch(Notify, arg c<2 ? DEFAULT_CONFIG : argv[1], IN_MODIFY) == -1) {242 else if (inotify_add_watch(Notify, argv[1], IN_MODIFY) == -1) { 267 243 Config.Message(EvidenceConfig::WARN, "Could not set inotify watch on configuration file (%s)\n", strerror(errno)); 268 244 close(Notify); -
Evidence/DColl.cc
r232 r253 274 274 fprintf(DataFile, "%s\n", Text.c_str()); 275 275 } 276 else fprintf(DataFile, "Cannot interpret format identifier\n");276 else fprintf(DataFile, "Cannot interpret service format\n"); 277 277 278 278 // Terminate if error because otherwise infinite loop might result as 279 279 // next call to this infoHandler() will try to (re-)open file 280 if(ferror(DataFile) ) {281 fclose(DataFile);280 if(ferror(DataFile) != 0) { 281 if (fclose(DataFile) != 0) Message(ERROR, "Error closing data file (%s)", strerror(errno)); 282 282 DataFile = NULL; 283 283 Message(FATAL, "Error writing to data file, closed file (%s)", strerror(errno)); … … 300 300 void DataHandler::commandHandler() { 301 301 302 if (getCommand() != LogCommand || LogFile == NULL) return; 303 302 // Translate text safely to string 303 string Text = ToString((char *) "C", getCommand()->getData(), getCommand()->getSize()); 304 305 // Safety check 306 if (getCommand() != LogCommand || LogFile == NULL || Text.empty()) return; 307 304 308 // Replace all carriage-return by line feed and non-printable characters 305 char *Text = getCommand()->getString(); 306 for (unsigned int i=0; i<strlen(Text); i++) { 309 for (unsigned int i=0; i<Text.size(); i++) { 307 310 if (Text[i] == '\r') Text[i] = '\n'; 308 311 if(isprint(Text[i])==0 && isspace(Text[i])==0) Text[i] = ' '; … … 314 317 fprintf(LogFile, "%.2d/%.2d/%4d %.2d:%.2d:%2.d %s (ID %d): %s\n", 315 318 TM->tm_mday, TM->tm_mon+1, TM->tm_year+1900, 316 TM->tm_hour, TM->tm_min, TM->tm_sec, getClientName(), getClientId(), Text );319 TM->tm_hour, TM->tm_min, TM->tm_sec, getClientName(), getClientId(), Text.c_str()); 317 320 fflush(LogFile); 318 321 -
Evidence/Evidence.cc
r232 r253 134 134 ////////////////////////// 135 135 136 // Initialise 136 137 int EvidenceServer::ConfigSignal = 0; 137 138 EvidenceServer *EvidenceServer::This = NULL; 138 139 139 // Constructor starts server with given name140 EvidenceServer::EvidenceServer( const char *ServerName): Name(ServerName) {140 // Constructor 141 EvidenceServer::EvidenceServer(string ServerName): Name(ServerName) { 141 142 142 143 // Initialize … … 176 177 177 178 // Start server 178 start(ServerName );179 start(ServerName.c_str()); 179 180 addExitHandler(this); 180 181 } … … 184 185 185 186 Message(INFO, "Server stopped"); 186 187 187 188 delete ConfClass; 188 delete MessageService; 189 delete[] MessageData; 190 189 191 190 int Ret; 192 191 if ((Ret = pthread_mutex_destroy(&Mutex)) != 0) { 193 192 Message(ERROR, "pthread_mutex_destroy() failed (%s)", strerror(Ret)); 194 193 } 194 195 delete MessageService; 196 delete[] MessageData; 195 197 } 196 198 … … 203 205 204 206 // DIM error handler 205 void EvidenceServer::errorHandler(int Severity, int Code, char *Text) { 207 void EvidenceServer::errorHandler(int Severity, int Code, char *Text) { 208 206 209 Message(ERROR, "%s (DIM error code %d, DIM severity %d)\n", Text, Code, Severity); 207 210 } … … 233 236 SendToLog("%s (%s): %s", MessageService->getName(), StateString[Severity], NewMsg->Text); 234 237 235 // Update DIM message service , then delete old message238 // Update DIM message service 236 239 if (MessageService != NULL) { 237 240 MessageService->updateService(NewMsg, sizeof(struct Message)+strlen(NewMsg->Text)+1); 238 241 } 242 243 // Terminate if severity if FATAL 244 if (Severity == FATAL) exit(EXIT_FAILURE); 245 246 // Delete old message 247 // Note that Lock()/Unlock() might fail with a FATAL message. To avoid an infinite loop, 248 // check for FATAL severity is done before here. 249 Lock(); 239 250 delete[] MessageData; 240 251 MessageData = NewMsg; 241 242 // Terminate if severity if FATAL 243 if (Severity == FATAL) exit(EXIT_FAILURE); 252 Unlock(); 244 253 } 245 254 -
Evidence/Evidence.h
r232 r253 38 38 std::map<std::string, struct Item> List; 39 39 40 void infoHandler(); 41 void rpcInfoHandler(); 42 40 43 public: 41 44 Config(std::string); … … 43 46 44 47 std::string GetConfig(std::string, std::string); 45 void infoHandler();46 void rpcInfoHandler();47 48 }; 48 49 … … 62 63 static void SignalHandler(int); // static for signal() 63 64 static void Terminate(); // static for set_terminate() 64 v oid errorHandler(int, int, char *);65 v oid exitHandler(int);65 virtual void errorHandler(int, int, char *); 66 virtual void exitHandler(int); 66 67 virtual void ConfigChanged() {}; 67 68 68 69 public: 69 EvidenceServer( const char *);70 EvidenceServer(std::string); 70 71 ~EvidenceServer(); 71 72 -
Evidence/History.cc
r232 r253 18 18 #include "Evidence.h" 19 19 20 const int MIN_SIZE_KB = 50; // Minimum and maximum history buffer in kByte (> 3*sizeof(int) !)21 const int MAX_SIZE_KB = 2000;22 const int REQUEST_NUM = 1000; // Requested number of entries in each history buffer23 24 20 #include <string> 25 21 #include <sstream> … … 31 27 32 28 using namespace std; 29 30 const int MIN_SIZE_KB = 50; // Min and max buffersize in kByte (> 3*sizeof(int) !) 31 const string DEFAULT_MAX_SIZE_KB = "2000"; 32 const string DEFAULT_NUM_ENTRIES = "1000"; // Number of entries in each history buffer 33 33 34 34 // … … 69 69 Directory(Dir) { 70 70 71 // Map of minimum required change for addition to history buffer71 // Get/initialize configuration 72 72 Change = GetConfig("minchange", " "); 73 GetConfig("maxsize_kb", DEFAULT_MAX_SIZE_KB); 74 GetConfig("numentries", DEFAULT_NUM_ENTRIES); 73 75 74 76 // Subscribe to top-level server list … … 139 141 // Check if service known and ignore empty or illegal time stamped service 140 142 if (Map.count(Service) == 0 || I->getSize()==0 || I->getTimestamp()<=0) return; 141 143 142 144 // Resize buffer if necessary 143 if (Map[Service].Buffer.size() < REQUEST_NUM*I->getSize()) { 144 if (REQUEST_NUM*I->getSize() < MAX_SIZE_KB*1024) Map[Service].Buffer.resize(REQUEST_NUM*I->getSize()); 145 int NEntries = atoi(GetConfig("numentries").c_str()); 146 if (Map[Service].Buffer.size() < NEntries*I->getSize()) { 147 if (NEntries*I->getSize() < atoi(GetConfig("maxsize_kb").c_str())*1024) { 148 Map[Service].Buffer.resize(NEntries*I->getSize()); 149 } 145 150 } 146 151 … … 212 217 void History::rpcHandler() { 213 218 214 char *Name = getString();219 string Name = ToString((char *) "C", getData(), getSize()); 215 220 216 221 // Search for history buffer in memory … … 237 242 fseek(File, sizeof(int), SEEK_SET); // Skip 'Next' pointer 238 243 if ((fread(Buffer, sizeof(char), Size-sizeof(int), File) != Size-sizeof(int)) || (ferror(File) != 0)) { 239 Message(WARN, "Error reading history file '%s' in rpcHandler()", Name );244 Message(WARN, "Error reading history file '%s' in rpcHandler()", Name.c_str()); 240 245 setData(NULL, 0); // Default response 241 246 } … … 244 249 } 245 250 246 if (fclose(File) != 0) Message(WARN, "Error closing history file '%s' in rpcHandler()", Name );251 if (fclose(File) != 0) Message(WARN, "Error closing history file '%s' in rpcHandler()", Name.c_str()); 247 252 } 248 253 -
Evidence/readme.txt
r232 r253 1 1 Short description of Evidence control system 2 2 3 This directory contains the backbone of the control system. 4 5 Config is the configuration server and needs to run before any other DIM 6 server that requests configuration information is started (if a configuration 7 request cannot be answered, a server will normally not start). A configuration 8 file can be given on the command line. 9 10 DColl is the central data collector. It subscribes to all services handled by 11 the name server and writes them to disk (except those excluded in the 12 configuration file). It also provides a history service for all DIM services 13 and a command for logging. 14 15 Alarm can be configured to check all servers for availability and status and 16 can produce a master alarm. 17 18 The DIMDIR environment variable needs to point to the DIM installation directory 19 when compiling. DIM_DNS_NODE must point to the name server for any DIM server 20 to run. 3 This directory contains the backbone of the control system. See directory Doc for documentation. 21 4 22 5 … … 54 37 in case signal is set with ActivateSignal() this signal will be blocked while locked. 55 38 Implemented experimental automatic full configuration tracking for Bridge. 39 7/7/2010 All commandHandler() and rpcHandler() safely translates data into string 40 using ToString(). EvidenceServer class constructor now takes std::string as argument. 41 Removed default configuration file from Config. 42 19/7/2010 Added documentation. Replaced std::vector by std::map at several locations. Access to 43 class-wide pointer in Message() protected by mutex (currently the memory of the 44 second-last message will not be freed correctly if severity is FATAL). Added 45 History server configuration parameters to adjust buffer size. 56 46 57 58 Preliminary firewall settings on eth-vme02 (rule 5 for DIM, rule 6 for X11 over ssh)59 60 Chain INPUT (policy ACCEPT)61 num target prot opt source destination62 1 RH-Firewall-1-INPUT all -- 0.0.0.0/0 0.0.0.0/063 64 Chain FORWARD (policy ACCEPT)65 num target prot opt source destination66 1 RH-Firewall-1-INPUT all -- 0.0.0.0/0 0.0.0.0/067 68 Chain OUTPUT (policy ACCEPT)69 num target prot opt source destination70 71 Chain RH-Firewall-1-INPUT (2 references)72 num target prot opt source destination73 1 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 25574 2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED75 3 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:2276 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:200077 5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:5100:6000 state NEW78 6 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpts:6000:6063 state NEW79 7 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Note:
See TracChangeset
for help on using the changeset viewer.