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 #include <ndrx_config.h>
0035 #include <string.h>
0036 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <signal.h>
0039 #include <errno.h>
0040 #include <memory.h>
0041 #include <unistd.h>
0042
0043 #include <ndrstandard.h>
0044 #include <ndrxd.h>
0045 #include <atmi_int.h>
0046 #include <atmi_shm.h>
0047
0048 #include <ndebug.h>
0049 #include <cmd_processor.h>
0050 #include <signal.h>
0051
0052 #include "userlog.h"
0053 #include "atmi_cache.h"
0054
0055
0056
0057 #define NDRX_Q_TRYLOCK_TIME 10
0058 #define NDRX_SVQ_SCANUNIT_NDRXD 200
0059
0060
0061
0062 expublic sigset_t ndrx_G_org_mask;
0063
0064 sys_config_t G_sys_config;
0065 exprivate int M_scanunit=250;
0066
0067
0068
0069
0070
0071
0072 exprivate int open_pid_file(void)
0073 {
0074 int ret=EXSUCCEED;
0075 FILE *f = NULL;
0076
0077 if (NULL==(f=NDRX_FOPEN(G_sys_config.pidfile, "w")))
0078 {
0079 NDRX_LOG(log_error, "Failed to open PID file %s for write: %s",
0080 G_sys_config.pidfile, strerror(errno));
0081 userlog("Failed to open PID file %s for write: %s",
0082 G_sys_config.pidfile, strerror(errno));
0083 ret=EXFAIL;
0084 goto out;
0085 }
0086
0087 if (fprintf(f, "%d", getpid()) < 0)
0088 {
0089 NDRX_LOG(log_error, "Failed to write to PID file %s: %s",
0090 G_sys_config.pidfile, strerror(errno));
0091 userlog("Failed to write to PID file %s: %s",
0092 G_sys_config.pidfile, strerror(errno));
0093 }
0094
0095 NDRX_FCLOSE(f);
0096 f=NULL;
0097 out:
0098 return ret;
0099 }
0100
0101
0102
0103
0104
0105
0106 expublic int ndrxd_unlink_pid_file(int second_call)
0107 {
0108
0109 if (second_call && !ndrx_file_exists(G_sys_config.pidfile))
0110 {
0111 return EXSUCCEED;
0112 }
0113
0114 if (EXSUCCEED!=unlink(G_sys_config.pidfile))
0115 {
0116 NDRX_LOG(log_error, "Failed to unlink to PID file %s: %s",
0117 G_sys_config.pidfile, strerror(errno));
0118 return EXFAIL;
0119 }
0120
0121 return EXSUCCEED;
0122 }
0123
0124
0125
0126
0127
0128
0129 int main_loop()
0130 {
0131 int finished = EXFALSE;
0132 int ret=EXSUCCEED;
0133
0134 if (EXSUCCEED!=open_pid_file())
0135 {
0136 ret=EXFAIL;
0137 goto out;
0138 }
0139
0140 while (!finished && EXSUCCEED==ret &&
0141
0142 !(G_sys_config.stat_flags & NDRXD_STATE_SHUTDOWN && is_srvs_down()))
0143 {
0144
0145 if (EXFAIL==command_wait_and_run(&finished, NDRXD_CTX_ZERO))
0146 {
0147 ret=EXFAIL;
0148 goto out;
0149 }
0150
0151 }
0152
0153 out:
0154 return ret;
0155 }
0156
0157
0158
0159
0160
0161 void clean_shutdown(int sig)
0162 {
0163 NDRX_LOG(log_warn, "Initiating ndrxd shutdown, signal: %d", sig);
0164 G_sys_config.stat_flags |= NDRXD_STATE_SHUTDOWN;
0165 }
0166
0167
0168
0169
0170
0171 exprivate void print_help(char *name)
0172 {
0173 fprintf(stderr, "Usage: %s [options] -k key \n", name);
0174 fprintf(stderr, "Options:\n");
0175 fprintf(stderr, " -k <key> Random key value\n");
0176 fprintf(stderr, " -r Start in recovery mode\n");
0177 fprintf(stderr, " -h Print this help\n");
0178 }
0179
0180
0181
0182
0183
0184
0185
0186 expublic int init_cmdline_opts(int argc, char **argv)
0187 {
0188 int ret=EXSUCCEED;
0189 int c;
0190 extern char *optarg;
0191 int have_key = EXFALSE;
0192 int do_print_help = EXFALSE;
0193
0194
0195 while ((c = getopt(argc, argv, "h?rk:")) != -1)
0196 {
0197 switch(c)
0198 {
0199 case 'r':
0200 fprintf(stderr, "Entering in restart mode\n");
0201 G_sys_config.restarting = EXTRUE;
0202 break;
0203 case 'k':
0204
0205 have_key = EXTRUE;
0206 break;
0207 case 'h': case '?':
0208 do_print_help = EXTRUE;
0209 break;
0210 }
0211 }
0212
0213 if (!have_key || do_print_help)
0214 {
0215 print_help(argv[0]);
0216 return EXFAIL;
0217 }
0218
0219 out:
0220 return ret;
0221 }
0222
0223
0224
0225
0226
0227
0228
0229 int main_init(int argc, char** argv)
0230 {
0231 int ret=EXSUCCEED;
0232 char *p;
0233
0234 pid_t ndrxd_pid;
0235
0236
0237
0238
0239
0240
0241
0242 if (EXSUCCEED!=ndrx_load_common_env())
0243 {
0244 NDRX_LOG(log_error, "Failed to load common env");
0245 EXFAIL_OUT(ret);
0246 }
0247
0248
0249 ndrxd_pid = ndrx_ndrxd_pid_get();
0250
0251 if (EXFAIL!=ndrxd_pid && EXSUCCEED==kill(ndrxd_pid, 0))
0252 {
0253 fprintf(stderr, "ERROR ! Duplicate startup, ndrxd with PID %d "
0254 "already exists\n", ndrxd_pid);
0255 NDRX_LOG(log_error, "ERROR ! Duplicate startup, ndrxd with PID %d "
0256 "already exists", ndrxd_pid);
0257 userlog("ERROR ! Duplicate startup, ndrxd with PID %d "
0258 "already exists", ndrxd_pid);
0259 exit(EXFAIL);
0260 }
0261
0262
0263
0264
0265
0266
0267
0268 signal(SIGHUP, SIG_IGN);
0269 signal(SIGTERM, SIG_IGN);
0270 signal(SIGINT, SIG_IGN);
0271
0272
0273 G_sys_config.qprefix = getenv(CONF_NDRX_QPREFIX);
0274 if (NULL==G_sys_config.qprefix)
0275 {
0276
0277 NDRX_LOG(log_error, "Missing config key %s - FAIL", CONF_NDRX_QPREFIX);
0278 userlog("Missing config key %s - FAIL", CONF_NDRX_QPREFIX);
0279 ret=EXFAIL;
0280 goto out;
0281 }
0282
0283 G_sys_config.config_file = getenv(CONF_NDRX_CONFIG);
0284 if (NULL==G_sys_config.config_file)
0285 {
0286
0287 NDRX_LOG(log_error, "Missing config key %s - FAIL", CONF_NDRX_CONFIG);
0288 userlog("Missing config key %s - FAIL", CONF_NDRX_CONFIG);
0289 ret=EXFAIL;
0290 goto out;
0291 }
0292
0293 G_sys_config.config_file_short = strrchr(G_sys_config.config_file, '/');
0294
0295 if (NULL==G_sys_config.config_file_short)
0296 {
0297 G_sys_config.config_file_short = G_sys_config.config_file;
0298 }
0299 else
0300 {
0301 G_sys_config.config_file_short++;
0302 }
0303
0304
0305 p = getenv(CONF_NDRX_DQMAX);
0306 if (NULL!=p)
0307 {
0308
0309 ndrx_get_G_atmi_env()->msg_max = atol(p);
0310 NDRX_LOG(log_debug, "NDRXD Max Q size to: %d (override)",
0311 ndrx_get_G_atmi_env()->msg_max);
0312 }
0313 else
0314 {
0315 NDRX_LOG(log_debug, "NDRXD Max Q size to: %d (default)",
0316 ndrx_get_G_atmi_env()->msg_max);
0317 }
0318
0319
0320 p = getenv(CONF_NDRX_CMDWAIT);
0321 if (NULL==p)
0322 {
0323
0324 G_sys_config.cmd_wait_time = COMMAND_WAIT_DEFAULT;
0325 NDRX_LOG(log_debug, "Command wait time defaulted to %ld sec",
0326 G_sys_config.cmd_wait_time);
0327 }
0328 else
0329 {
0330 G_sys_config.cmd_wait_time = atol(p);
0331 NDRX_LOG(log_debug, "Command wait time set to %ld sec",
0332 G_sys_config.cmd_wait_time);
0333 }
0334
0335 if (EXSUCCEED!=cmd_processor_init())
0336 {
0337
0338 NDRX_LOG(log_error, "Failed to initialize command processor!");
0339 userlog("Failed to initailize command processor!");
0340 ret=EXFAIL;
0341 goto out;
0342 }
0343
0344
0345 G_sys_config.pidfile = getenv(CONF_NDRX_DPID);
0346
0347 if (NULL==G_sys_config.pidfile)
0348 {
0349
0350 NDRX_LOG(log_error, "Missing config key %s - FAIL", CONF_NDRX_DPID);
0351 userlog("Missing config key %s - FAIL", CONF_NDRX_DPID);
0352 ret=EXFAIL;
0353 goto out;
0354 }
0355 else
0356 {
0357 NDRX_LOG(log_error, "Using PID file [%s]", G_sys_config.pidfile);
0358 }
0359
0360 G_sys_config.qpath = getenv(CONF_NDRX_QPATH);
0361
0362 if (NULL==G_sys_config.qpath)
0363 {
0364
0365 NDRX_LOG(log_error, "Missing config key %s - FAIL", CONF_NDRX_QPATH);
0366 userlog("Missing config key %s - FAIL", CONF_NDRX_QPATH);
0367 ret=EXFAIL;
0368 goto out;
0369 }
0370 else
0371 {
0372 NDRX_LOG(log_error, "Using QPath [%s]", G_sys_config.qpath);
0373 }
0374
0375
0376
0377 if (EXSUCCEED!=ndrxd_sem_init(G_sys_config.qprefix))
0378 {
0379 ret=EXFAIL;
0380 NDRX_LOG(log_error, "Failed to initialise share memory lib");
0381 goto out;
0382 }
0383
0384 if (EXSUCCEED!=ndrx_shm_init(G_sys_config.qprefix,
0385 ndrx_get_G_atmi_env()->max_servers,
0386 ndrx_get_G_atmi_env()->max_svcs,
0387 ndrx_get_G_atmi_env()->rtcrtmax,
0388 ndrx_get_G_atmi_env()->rtsvcmax))
0389 {
0390 ret=EXFAIL;
0391 NDRX_LOG(log_error, "Failed to initialise share memory lib");
0392 goto out;
0393 }
0394
0395 if (EXSUCCEED!=ndrx_sem_open_all(EXTRUE))
0396 {
0397 ret=EXFAIL;
0398 NDRX_LOG(log_error, "Failed to create/attach to Semaphores");
0399 goto out;
0400 }
0401 else
0402 {
0403 NDRX_LOG(log_error, "Create/attached to semaphores OK");
0404 }
0405
0406 if (EXSUCCEED!=ndrx_shm_open_all(NDRX_SHM_LEV_SVC | NDRX_SHM_LEV_SRV | NDRX_SHM_LEV_BR, EXTRUE))
0407 {
0408 ret=EXFAIL;
0409 NDRX_LOG(log_error, "Failed to create/attach to shared memory segments");
0410 goto out;
0411 }
0412 else
0413 {
0414 NDRX_LOG(log_error, "create/attached to shared memory OK");
0415 }
0416
0417 if (EXSUCCEED!=ndrxd_sigchld_init())
0418 {
0419 NDRX_LOG(log_error, "Failed to init signal handler thread!");
0420 EXFAIL_OUT(ret);
0421 }
0422
0423 out:
0424 return ret;
0425 }
0426
0427
0428
0429
0430
0431 int main_uninit(void)
0432 {
0433
0434 ndrxd_sigchld_uninit();
0435
0436
0437 ndrxd_sanity_finally();
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447 ndrxd_sem_close_all();
0448
0449
0450 ndrxd_sem_delete();
0451
0452
0453 ndrxd_shm_close_all();
0454
0455
0456 ndrxd_shm_delete();
0457
0458
0459 cmd_close_queue();
0460
0461
0462 ndrx_epoll_down(EXFALSE);
0463
0464
0465 ndrxd_unlink_pid_file(EXTRUE);
0466
0467 return EXSUCCEED;
0468 }
0469
0470
0471 exprivate void sig_hand(int sig) {}
0472
0473
0474
0475
0476 int main(int argc, char** argv)
0477 {
0478
0479 int ret=EXSUCCEED;
0480 struct sigaction sa;
0481 sigset_t blockMask;
0482
0483
0484
0485
0486 sigemptyset(&blockMask);
0487 sigaddset(&blockMask, SIGCHLD);
0488
0489
0490
0491
0492 if (sigprocmask(SIG_BLOCK, &blockMask, &ndrx_G_org_mask) == -1)
0493 {
0494 NDRX_LOG(log_always, "%s: sigprocmask failed: %s", __func__,
0495 strerror(errno));
0496 EXFAIL_OUT(ret);
0497 }
0498
0499
0500 sa.sa_handler = sig_hand;
0501 sigemptyset (&sa.sa_mask);
0502 sa.sa_flags = SA_RESTART;
0503 sigaction (SIGCHLD, &sa, 0);
0504
0505
0506
0507
0508 #ifdef EX_USE_SYSVQ
0509 ndrx_svq_scanunit_set(NDRX_SVQ_SCANUNIT_NDRXD);
0510 #endif
0511
0512 memset(&G_sys_config, 0, sizeof(G_sys_config));
0513
0514 if (EXSUCCEED!=init_cmdline_opts(argc, argv))
0515 {
0516 NDRX_LOG(log_error, "ndrxd - command line args failed");
0517 ret=EXFAIL;
0518 goto out;
0519 }
0520 else if (EXSUCCEED!=main_init(argc, argv))
0521 {
0522 NDRX_LOG(log_error, "ndrxd - INIT FAILED!");
0523 ret=EXFAIL;
0524 goto out;
0525 }
0526
0527 if (G_sys_config.restarting && EXSUCCEED!=do_restart_actions())
0528 {
0529 ret=EXFAIL;
0530 goto out;
0531 }
0532
0533 ret=main_loop();
0534
0535 out:
0536
0537 main_uninit();
0538
0539 NDRX_LOG(log_error, "exiting %d", ret);
0540
0541 return ret;
0542 }
0543