1 /* **************************************************************
2 Copyright (C) 2010 Hewlett-Packard Development Company, L.P.
3 Copyright (C) 2015 Siemens AG
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 version 2 as published by the Free Software Foundation.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 
18 ************************************************************** */
19 
20 #ifndef LIBFOSSSCHEDULER_H_INCLUDE
21 #define LIBFOSSSCHEDULER_H_INCLUDE
22 
23 /* local includes */
24 #include <fossconfig.h>
25 #include <libfossdbmanager.h>
26 
27 /* library includes */
28 #include <stdio.h>
29 #include <signal.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/file.h>
33 #include <unistd.h>
34 
35 /* other libraries */
36 #include <libpq-fe.h>
37 
38 #define ALARM_SECS 30
39 
40 
41 /* ************************************************************************** */
42 /* **** Data Types ********************************************************** */
43 /* ************************************************************************** */
44 
45 /**
46 * @brief The status that a job has.
47 *
48 *  - RUNNING: all agents will continue to work normally
49 *  - KILLED:  all agent associated with the job will die
50 *  - PAUSED:  all agents will stop and wait for instructions
51 */
52 enum job_status
53 {
54   RUNNING, ///< RUNNING
55   KILLED,  ///< KILLED
56   PAUSED   ///< PAUSED
57 };
58 
59 /**
60 * @brief Common verbose flags for the agents, this is used so that the scheduler can
61 * change the verbose level for a particular agent. All agents should use this
62 * flag for verbose instead of one declared within the agent. This can be set
63 * by the scheduler to enable different levels of verbose.
64 */
65 extern int agent_verbose;
66 
67 extern fo_conf* sysconfig;
68 extern char* sysconfigdir;
69 
70 /*
71  * The following macro definitions are meant to act as their own statement in
72  * the c language. To accomplish this, they needed to not only be able to be used
73  * in the situation of an "if" statement with no body, but also require that
74  * they are followed by a ";".
75  *
76  * To do this the "do {} while(0)" loop is used, the loop will not appear in
77  * result flow control since it does not modify the flow of control, but it is
78  * a single statement that requires a ";" at the end to be syntactically correct
79  */
80 
81 /**
82  * Log fatal error
83  * @param ... standard printf-style function call
84  */
85 #define LOG_FATAL(...) { \
86             fprintf(stdout, "FATAL %s.%d: ", __FILE__, __LINE__); \
87             fprintf(stdout, __VA_ARGS__); \
88             fprintf(stdout, "\n"); \
89             fflush(stdout); }
90 /**
91  * Log Postgres fatal error
92  * @param pg_r Postgres error code
93  * @param ... standard printf-style function call
94  */
95 #define LOG_PQ_FATAL(pg_r, ...) { \
96             fprintf(stdout, "FATAL %s.%d: ", __FILE__, __LINE__); \
97             fprintf(stdout, __VA_ARGS__); \
98             fprintf(stdout, "FATAL postgresql error: %s\n", PQresultErrorMessage(pg_r)); \
99             fflush(stdout); }
100 
101 /**
102  * Log general error
103  * @param ... standard printf-style function call
104  */
105 #define LOG_ERROR(...) { \
106             fprintf(stdout, "ERROR %s.%d: ", __FILE__, __LINE__); \
107             fprintf(stdout, __VA_ARGS__); \
108             fprintf(stdout, "\n"); \
109             fflush(stdout); }
110 
111 /**
112  * Log Postgres general error
113  * @param pg_r Postgres error code
114  * @param ... standard printf-style function call
115  */
116 #define LOG_PQ_ERROR(pg_r, ...) { \
117             fprintf(stdout, "ERROR %s.%d: ", __FILE__, __LINE__); \
118             fprintf(stdout, __VA_ARGS__); \
119             fprintf(stdout, "ERROR postgresql error: %s\n", PQresultErrorMessage(pg_r)); \
120             fflush(stdout); }
121 
122 /**
123  * Log warnings
124  * @param ... standard printf-style function call
125  */
126 #define LOG_WARNING(...) { \
127             fprintf(stdout, "WARNING %s.%d: ", __FILE__, __LINE__); \
128             fprintf(stdout, __VA_ARGS__); \
129             fprintf(stdout, "\n"); \
130             fflush(stdout); }
131 
132 /**
133  * Log debugging messages
134  * @param ... standard printf-style function call
135  */
136 #define LOG_DEBUG(...) { \
137             fprintf(stdout, "DEBUG %s.%d: ", __FILE__, __LINE__); \
138             fprintf(stdout, __VA_ARGS__); \
139             fprintf(stdout, "\n"); \
140             fflush(stdout); }
141 
142 /**
143  * Log notice messages
144  * @param ... standard printf-style function call
145  */
146 #define LOG_NOTICE(...) { \
147             fprintf(stdout, "NOTICE %s.%d: ", __FILE__, __LINE__); \
148             fprintf(stdout, __VA_ARGS__); \
149             fprintf(stdout, "\n"); \
150             fflush(stdout); }
151 
152 #define TVERBOSE   agent_verbose              ///< Agent verbose set
153 #define TVERBOSE0 (agent_verbose & (1 << 0))  ///< Verbose level 0
154 #define TVERBOSE1 (agent_verbose & (1 << 1))  ///< Verbose level 1
155 #define TVERBOSE2 (agent_verbose & (1 << 2))  ///< Verbose level 2
156 #define TVERBOSE3 (agent_verbose & (1 << 3))  ///< Verbose level 3
157 #define TVERBOSE4 (agent_verbose & (1 << 4))  ///< Verbose level 4
158 #define TVERBOSE5 (agent_verbose & (1 << 5))  ///< Verbose level 5
159 #define TVERBOSE6 (agent_verbose & (1 << 6))  ///< Verbose level 6
160 #define TVERBOSE7 (agent_verbose & (1 << 7))  ///< Verbose level 7
161 
162 /** @brief By using these macros the verbosity level of an agent can be changed
163 *         dynamically through the scheduler.
164 *
165 * For example, to print "this is a verbose test at line <line>" at verbose
166 * level 2 simply call:
167 *    `LOG_VERBOSE2("this is a verbose test at line %d", __LINE__);`
168 * Though you never have to put the caller's filename or line number
169 * in a message since they are added by LOG_NOTICE.
170 */
171 #define LOG_VERBOSE(...)  if(TVERBOSE)  LOG_NOTICE(__VA_ARGS__);
172 #define LOG_VERBOSE0(...) if(TVERBOSE0) LOG_NOTICE(__VA_ARGS__);
173 #define LOG_VERBOSE1(...) if(TVERBOSE1) LOG_NOTICE(__VA_ARGS__);
174 #define LOG_VERBOSE2(...) if(TVERBOSE2) LOG_NOTICE(__VA_ARGS__);
175 #define LOG_VERBOSE3(...) if(TVERBOSE3) LOG_NOTICE(__VA_ARGS__);
176 #define LOG_VERBOSE4(...) if(TVERBOSE4) LOG_NOTICE(__VA_ARGS__);
177 #define LOG_VERBOSE5(...) if(TVERBOSE5) LOG_NOTICE(__VA_ARGS__);
178 #define LOG_VERBOSE6(...) if(TVERBOSE6) LOG_NOTICE(__VA_ARGS__);
179 #define LOG_VERBOSE7(...) if(TVERBOSE7) LOG_NOTICE(__VA_ARGS__);
180 
181 /**
182 * @brief Special conditions to set for an agent execution.
183 *
184 * Possible options:
185 *   SPECIAL_NOKILL: instruct the scheduler not to kill the agent
186 */
187 #define SPECIAL_NOKILL (1 << 0)
188 
189 /* ************************************************************************** */
190 /* **** Agent api *********************************************************** */
191 /* ************************************************************************** */
192 
193 /**
194 * Used to set the message that will be sent with the notification email for the
195 * job that this agent is working on
196 *
197 * @param ... standard printf-style function call
198 */
199 #define NOTIFY_EMAIL(...)         \
200     fprintf(stdout, "EMAIL ");    \
201     fprintf(stdout, __VA_ARGS__); \
202     fprintf(stdout, "\n");        \
203     fflush(stdout)
204 
205 void fo_scheduler_heart(int i);
206 void fo_scheduler_connect(int* argc, char** argv, PGconn** db_conn);
207 void fo_scheduler_connect_dbMan(int* argc, char** argv, fo_dbManager** dbManager);
208 void fo_scheduler_disconnect(int retcode);
209 char* fo_scheduler_next();
210 
211 /* ************************************************************************** */
212 /* **** Accessor Functions ************************************************** */
213 /* ************************************************************************** */
214 
215 char* fo_scheduler_current();
216 int fo_scheduler_userID();
217 int fo_scheduler_groupID();
218 int fo_scheduler_jobId();
219 void fo_scheduler_set_special(int option, int value);
220 int fo_scheduler_get_special(int option);
221 char* fo_sysconfig(const char* sectionname, const char* variablename);
222 
223 #endif /* LIBFOSSSCHEDULER_H_INCLUDE */
224