diff --git a/uvrrpd.c b/uvrrpd.c index 9bca432..a56ca67 100644 --- a/uvrrpd.c +++ b/uvrrpd.c @@ -41,6 +41,7 @@ unsigned long reg = 0UL; int background = 1; char *loglevel = NULL; char *pidfile_name = NULL; +char *ctrlfile_name = NULL; /* local methods */ static void signal_handler(int sig); @@ -49,6 +50,9 @@ static int pidfile_init(int vrid); static void pidfile_unlink(void); static void pidfile_check(int vrid); static void pidfile(int vrid); +static int ctrlfile_init(int vrid); +static void ctrlfile_unlink(void); +static void ctrlfile(int vrid, int *fd); /** * main() - entry point @@ -81,6 +85,10 @@ int main(int argc, char *argv[]) /* logs */ log_open("uvrrpd", (char const *) loglevel); + /* init and open control file fifo */ + ctrlfile_init(vrrp.vrid); + ctrlfile(vrrp.vrid, &vrrp.ctrl.fd); + /* open sockets */ if ((vrrp_net_socket(&vnet) != 0) || (vrrp_net_socket_xmit(&vnet) != 0)) exit(EXIT_FAILURE); @@ -133,6 +141,7 @@ int main(int argc, char *argv[]) log_close(); free(loglevel); pidfile_unlink(); + ctrlfile_unlink(); free(pidfile_name); return EXIT_SUCCESS; @@ -337,3 +346,59 @@ static void pidfile(int vrid) exit(EXIT_FAILURE); } } + + +/** + * ctrlfile_init() + */ +static int ctrlfile_init(int vrid) +{ + int max_len = NAME_MAX + PATH_MAX; + if (ctrlfile_name == NULL) { + ctrlfile_name = malloc(max_len); + if (ctrlfile_name == NULL) { + log_error("vrid %d :: malloc - %m", vrid); + return -1; + } + + snprintf(ctrlfile_name, max_len, CTRLFILE_NAME, vrid); + } + + return 0; +} + +/** + * ctrlfile_unlink() + */ +static void ctrlfile_unlink() +{ + if (ctrlfile_name) + unlink(ctrlfile_name); +} + +/** + * ctrlfile() + */ +static void ctrlfile(int vrid, int *fd) +{ + if (fd == NULL) { + log_error("vrid %d :: invalid use of ctrlfile(), fd NULL", vrid); + exit(EXIT_FAILURE); + } + + ctrlfile_unlink(); + if (mkfifo(ctrlfile_name, 0600) != 0) { + log_error("vrid %d :: error while creating control fifo %s: %m", vrid, + ctrlfile_name); + exit(EXIT_FAILURE); + } + + atexit(ctrlfile_unlink); + + *fd = open(ctrlfile_name, O_RDWR | O_NONBLOCK); + if (*fd == -1) { + log_error("vrid %d :: error while opening control fifo %s: %m", vrid, + ctrlfile_name); + exit(EXIT_FAILURE); + } +} diff --git a/uvrrpd.h b/uvrrpd.h index ef4048b..42874df 100644 --- a/uvrrpd.h +++ b/uvrrpd.h @@ -25,6 +25,7 @@ #include "bits.h" #define PIDFILE_NAME stringify(PATHRUN) "/uvrrpd_%d.pid" +#define CTRLFILE_NAME stringify(PATHRUN) "/uvrrpd_ctrl.%d" /** * uvrrpd_control diff --git a/vrrp.h b/vrrp.h index 1129b20..064c79e 100644 --- a/vrrp.h +++ b/vrrp.h @@ -107,6 +107,9 @@ struct vrrp { char *scriptname; char **argv; + /* control cmd fifo */ + struct vrrp_ctrl ctrl; + struct vrrp_timer adv_timer; struct vrrp_timer masterdown_timer; }; diff --git a/vrrp_options.c b/vrrp_options.c index f7f3d56..ebd16fa 100644 --- a/vrrp_options.c +++ b/vrrp_options.c @@ -34,6 +34,7 @@ extern int background; extern char *loglevel; extern char *pidfile_name; +extern char *ctrlfile_name; /** * vrrp_usage() @@ -59,8 +60,10 @@ static void vrrp_usage(void) " -a, --auth pass Simple text password (only in VRRPv2)\n" " -f, --foreground Execute uvrrpd in foreground\n" " -s, --script Path of hook script (default "stringify(PATH)"/vrrp-switch.sh)\n" - " -F --pidfile name Create pid file 'name'\n" + " -F --pidfile name Change pid file 'name'\n" " Default "stringify(PATHRUN)"/uvrrp_${vrid}.pid\n" + " -C --control name Change control file 'name'\n" + " Default "stringify(PATHRUN)"/uvrrpd_ctrl.${vrid}\n" " -d, --debug\n" " -h, --help\n"); } @@ -85,13 +88,14 @@ int vrrp_options(struct vrrp *vrrp, struct vrrp_net *vnet, int argc, {"foreground", no_argument, 0, 'f'}, {"script", required_argument, 0, 's'}, {"pidfile", required_argument, 0, 'F'}, + {"control", required_argument, 0, 'C'}, {"debug", no_argument, 0, 'd'}, {"help", no_argument, 0, 'h'}, {NULL, 0, 0, 0} }; while ((optc = - getopt_long(argc, argv, "v:i:p:t:P:r:6a:fs:F:dh", opts, + getopt_long(argc, argv, "v:i:p:t:P:r:6a:fs:F:C:dh", opts, NULL)) != EOF) { switch (optc) { @@ -233,6 +237,11 @@ int vrrp_options(struct vrrp *vrrp, struct vrrp_net *vnet, int argc, pidfile_name = strndup(optarg, NAME_MAX + PATH_MAX); break; + /* control file (fifo) */ + case 'C': + ctrlfile_name = strndup(optarg, NAME_MAX + PATH_MAX); + break; + /* debug */ case 'd': loglevel = strndup("debug", 6);