Merge branch 'master' of github.com:reverbrain/elliptics
[elliptics.git] / example / ioserv.c
blobd158f4c3667c27a9b57db6a696b847ef28d218bb
1 /*
2 * 2008+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
3 * All rights reserved.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <sys/socket.h>
19 #include <sys/time.h>
20 #include <sys/wait.h>
22 #include <ctype.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <signal.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <time.h>
32 #include <netinet/in.h>
34 #include "elliptics/packet.h"
35 #include "elliptics/interface.h"
37 #include "common.h"
39 #ifndef __unused
40 #define __unused __attribute__ ((unused))
41 #endif
43 static void dnet_usage(char *p)
45 fprintf(stderr, "Usage: %s\n"
46 " -c config - config file\n"
47 " -m - run under internal monitor\n"
48 " -l log - log file\n"
49 " -h - this help\n"
50 , p);
53 static int ioserv_monitor(void)
55 pid_t pid;
57 pid = fork();
58 if (pid == -1) {
59 fprintf(stderr, "Failed to fork to background: %s.\n", strerror(errno));
60 exit(pid);
63 if (pid != 0) {
64 printf("Children pid: %d\n", pid);
65 return pid;
67 setsid();
69 #if 0
70 close(0);
71 close(1);
72 close(2);
73 #endif
74 return 0;
77 static struct dnet_node *global_n;
78 static void ioserv_destroy_handler(int sig __unused, siginfo_t *si __unused, void *uc __unused)
80 dnet_set_need_exit(global_n);
83 extern char *dnet_logger_value;
84 struct dnet_config_backend;
85 extern int dnet_set_log(struct dnet_config_backend *b __unused, char *key __unused, char *value);
87 static void ioserv_reload_handler(int sig __unused, siginfo_t *si __unused, void *uc __unused)
89 dnet_set_log(NULL, NULL, dnet_logger_value);
92 static void ioserv_sigchild_handler(int sig __unused, siginfo_t *si __unused, void *uc __unused)
94 int status, pid;
96 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
97 dnet_srw_update(global_n, pid);
101 static int ioserv_setup_signals(void)
103 struct sigaction sa;
105 memset(&sa, 0, sizeof(sa));
106 sa.sa_flags = SA_SIGINFO;
107 sa.sa_sigaction = ioserv_destroy_handler;
108 sigemptyset(&sa.sa_mask);
109 sigaction(SIGTERM, &sa, NULL);
110 sigaction(SIGINT, &sa, NULL);
112 sa.sa_flags = SA_SIGINFO;
113 sa.sa_sigaction = ioserv_reload_handler;
114 sigemptyset(&sa.sa_mask);
115 sigaction(SIGHUP, &sa, NULL);
117 sa.sa_flags = SA_SIGINFO;
118 sa.sa_sigaction = ioserv_sigchild_handler;
119 sigemptyset(&sa.sa_mask);
120 sigaction(SIGCHLD, &sa, NULL);
122 sigemptyset(&sa.sa_mask);
123 sigaddset(&sa.sa_mask, SIGTERM);
124 sigaddset(&sa.sa_mask, SIGINT);
125 sigaddset(&sa.sa_mask, SIGHUP);
126 sigaddset(&sa.sa_mask, SIGCHLD);
127 pthread_sigmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
128 sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
130 return 0;
133 static void ioserv_cleanup_signals(void)
135 sigset_t sig;
137 sigemptyset(&sig);
138 sigaddset(&sig, SIGTERM);
139 sigaddset(&sig, SIGINT);
140 sigaddset(&sig, SIGHUP);
141 sigprocmask(SIG_BLOCK, &sig, NULL);
144 static int ioserv_start(char *conf, int mon)
146 struct dnet_node *n;
148 n = dnet_parse_config(conf, mon);
149 if (!n)
150 return -1;
152 global_n = n;
153 ioserv_setup_signals();
155 while (!dnet_need_exit(n))
156 sleep(1);
158 ioserv_cleanup_signals();
159 dnet_server_node_destroy(n);
160 return 0;
163 int main(int argc, char *argv[])
165 int ch, mon = 0, err;
166 char *conf = NULL;
168 while ((ch = getopt(argc, argv, "mc:h")) != -1) {
169 switch (ch) {
170 case 'm':
171 mon = 1;
172 break;
173 case 'c':
174 conf = optarg;
175 break;
176 case 'h':
177 default:
178 dnet_usage(argv[0]);
179 return -1;
183 if (!conf) {
184 fprintf(stderr, "No config file provided. Exiting.\n");
185 return -1;
188 if (mon) {
189 #if 0
190 err = ioserv_monitor();
191 if (err > 0)
192 exit();
193 #endif
194 while (1) {
195 err = ioserv_monitor();
196 if (err > 0) {
197 int status;
199 waitpid(err, &status, 0);
201 err = WEXITSTATUS(status);
202 fprintf(stderr, "child exited with status: %d\n", err);
203 if (WIFEXITED(status)) {
204 printf("exited, status=%d\n", WEXITSTATUS(status));
205 } else if (WIFSIGNALED(status)) {
206 printf("killed by signal %d\n", WTERMSIG(status));
207 } else if (WIFSTOPPED(status)) {
208 printf("stopped by signal %d\n", WSTOPSIG(status));
209 } else if (WIFCONTINUED(status)) {
210 printf("continued\n");
212 } else {
213 exit(ioserv_start(conf, mon));
216 sleep(1);
218 } else {
219 ioserv_start(conf, mon);
222 return 0;