0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <string.h>
0038 #include <stdio.h>
0039 #include <stdlib.h>
0040 #include <errno.h>
0041 #include <memory.h>
0042 #include <sys/types.h>
0043 #include <dirent.h>
0044 #include <sys/stat.h>
0045 #include <utlist.h>
0046 #include <fcntl.h>
0047
0048 #include <ndrstandard.h>
0049 #include <ndrxd.h>
0050 #include <atmi_int.h>
0051 #include <nstopwatch.h>
0052
0053 #include <ndebug.h>
0054 #include <cmd_processor.h>
0055 #include <signal.h>
0056
0057 #include "userlog.h"
0058
0059
0060
0061
0062 #define ROC_MAX_CYCLES_STAY_IN_RELOAD 5
0063
0064
0065
0066
0067
0068 typedef struct roc_exe_registry roc_exe_registry_t;
0069 struct roc_exe_registry
0070 {
0071 char binary_path[PATH_MAX+1];
0072 time_t mtime;
0073 unsigned sanity_cycle;
0074 int reload_issued;
0075
0076 EX_hash_handle hh;
0077 };
0078
0079
0080
0081 exprivate roc_exe_registry_t* M_binreg = NULL;
0082
0083
0084
0085
0086
0087
0088
0089 exprivate void roc_calc_tstamp(roc_exe_registry_t *bin, unsigned sanity_cycle)
0090 {
0091 struct stat file_stat;
0092
0093 if (EXSUCCEED==stat(bin->binary_path, &file_stat))
0094 {
0095 bin->mtime = file_stat.st_mtime;
0096 bin->sanity_cycle = sanity_cycle;
0097 }
0098 }
0099
0100
0101
0102
0103
0104
0105 exprivate roc_exe_registry_t *rco_get_binary(char *binary_path, unsigned sanity_cycle)
0106 {
0107 roc_exe_registry_t *ret = NULL;
0108
0109 EXHASH_FIND_STR( M_binreg, binary_path, ret);
0110
0111 if (NULL==ret)
0112 {
0113
0114 roc_exe_registry_t * ret = NDRX_CALLOC(1, sizeof(roc_exe_registry_t));
0115
0116 if (NULL==ret)
0117 {
0118 userlog("malloc failed: %s", strerror(errno));
0119 goto out;
0120 }
0121 NDRX_STRCPY_SAFE(ret->binary_path, binary_path);
0122
0123 EXHASH_ADD_STR(M_binreg, binary_path, ret);
0124
0125
0126 roc_calc_tstamp(ret, sanity_cycle);
0127 }
0128
0129 out:
0130 return ret;
0131 }
0132
0133
0134
0135
0136
0137
0138
0139 expublic int roc_is_reload_in_progress(unsigned sanity_cycle)
0140 {
0141 roc_exe_registry_t *el = NULL;
0142 roc_exe_registry_t *elt = NULL;
0143 long diff;
0144
0145
0146
0147 EXHASH_ITER(hh, M_binreg, el, elt)
0148 {
0149 if (el->reload_issued)
0150 {
0151
0152 if ((diff=labs((long)el->sanity_cycle-(long)sanity_cycle)) > ROC_MAX_CYCLES_STAY_IN_RELOAD)
0153 {
0154 NDRX_LOG(log_error, "Current cycle %u reload cycle %u - assume executed",
0155 el->sanity_cycle, sanity_cycle);
0156 break;
0157 }
0158 else
0159 {
0160 NDRX_LOG(log_error, "%s - enqueued for reload", el->binary_path);
0161 return EXTRUE;
0162 }
0163 }
0164 }
0165
0166 return EXFALSE;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175 expublic int roc_check_binary(char *binary_path, unsigned sanity_cycle)
0176 {
0177 int ret= EXFALSE;
0178 roc_exe_registry_t *bin = NULL;
0179 time_t old_mtime;
0180
0181
0182 if (roc_is_reload_in_progress(sanity_cycle))
0183 {
0184 ret=EXFALSE;
0185 goto out;
0186 }
0187
0188
0189 if (NULL==(bin=rco_get_binary(binary_path, sanity_cycle)))
0190 {
0191 NDRX_LOG(log_error, "Failed to get reload-on-change binary "
0192 "(%s) - memory issues", binary_path);
0193 ret=EXFALSE;
0194 goto out;
0195 }
0196
0197
0198 if (bin->sanity_cycle==sanity_cycle)
0199 {
0200
0201 NDRX_LOG(log_debug, "Already checked at this cycle... (cached)");
0202 ret=EXFALSE;
0203 goto out;
0204 }
0205
0206
0207 old_mtime = bin->mtime;
0208
0209 roc_calc_tstamp(bin, sanity_cycle);
0210
0211 if (old_mtime!=bin->mtime)
0212 {
0213 NDRX_LOG(log_warn, "Binary [%s] timestamp changed", binary_path);
0214 bin->reload_issued = EXTRUE;
0215
0216 ret = EXTRUE;
0217 goto out;
0218 }
0219
0220 out:
0221
0222 NDRX_LOG(log_debug, "roc_check_binary [%s]: %s", binary_path,
0223 ret?"issued reload":"reload not issued");
0224
0225 return ret;
0226 }
0227
0228
0229
0230
0231
0232
0233 expublic void roc_mark_as_reloaded(char *binary_path, unsigned sanity_cycle)
0234 {
0235 roc_exe_registry_t * bin = rco_get_binary(binary_path, sanity_cycle);
0236
0237 if (NULL==bin)
0238 {
0239 NDRX_LOG(log_error, "Binary [%s] not found in hash - mem error!",
0240 binary_path);
0241 }
0242 else
0243 {
0244 NDRX_LOG(log_error, "Marking binary [%s]/%d as reloaded!",
0245 binary_path, bin->reload_issued);
0246
0247 bin->reload_issued = EXFALSE;
0248 }
0249 }
0250