open-isns: Fix warnings reported by gcc-4.5.2
[open-iscsi.git] / usr / event_poll.c
blobf36fec162bf0f3f0971f6c35010f59a5d3468d67
1 /*
2 * iSCSI daemon event handler
4 * Copyright (C) 2004 Dmitry Yusupov, Alex Aizman
5 * Copyright (C) 2006 Mike Christie
6 * Copyright (C) 2006 Red Hat, Inc. All rights reserved.
7 * maintained by open-iscsi@googlegroups.com
9 * Originally based on:
10 * (C) 2004 FUJITA Tomonori <tomof@acm.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published
14 * by the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
22 * See the file COPYING included with this distribution for more details.
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <sys/poll.h>
27 #include <sys/types.h>
28 #include <sys/wait.h>
30 #include "mgmt_ipc.h"
31 #include "iscsi_ipc.h"
32 #include "sysfs.h"
33 #include "iscsid.h"
34 #include "log.h"
35 #include "iscsi_ipc.h"
36 #include "actor.h"
37 #include "initiator.h"
38 #include "iscsi_err.h"
40 static int reap_count;
42 void reap_inc(void)
44 reap_count++;
47 void reap_proc(void)
49 int rc, i, max_reaps;
52 * We don't really need reap_count, but calling wait() all the
53 * time seems execessive.
55 max_reaps = reap_count;
56 for (i = 0; i < max_reaps; i++) {
57 rc = waitpid(0, NULL, WNOHANG);
58 if (rc > 0) {
59 reap_count--;
60 log_debug(6, "reaped pid %d, reap_count now %d",
61 rc, reap_count);
66 static LIST_HEAD(shutdown_callbacks);
68 struct shutdown_callback {
69 struct list_head list;
70 pid_t pid;
73 int shutdown_callback(pid_t pid)
75 struct shutdown_callback *cb;
77 cb = calloc(1, sizeof(*cb));
78 if (!cb)
79 return ENOMEM;
81 INIT_LIST_HEAD(&cb->list);
82 cb->pid = pid;
83 log_debug(1, "adding %d for shutdown cb\n", pid);
84 list_add_tail(&cb->list, &shutdown_callbacks);
85 return 0;
88 static void shutdown_notify_pids(void)
90 struct shutdown_callback *cb;
92 list_for_each_entry(cb, &shutdown_callbacks, list) {
93 log_debug(1, "Killing %d\n", cb->pid);
94 kill(cb->pid, SIGTERM);
98 static int shutdown_wait_pids(void)
100 struct shutdown_callback *cb, *tmp;
102 list_for_each_entry_safe(cb, tmp, &shutdown_callbacks, list) {
104 * the proc reaper could clean it up, so wait for any
105 * sign that it is gone.
107 if (waitpid(cb->pid, NULL, WNOHANG)) {
108 log_debug(1, "%d done\n", cb->pid);
109 list_del(&cb->list);
110 free(cb);
114 return list_empty(&shutdown_callbacks);
117 #define POLL_CTRL 0
118 #define POLL_IPC 1
119 #define POLL_MAX 2
121 static int event_loop_stop;
122 static queue_task_t *shutdown_qtask;
125 void event_loop_exit(queue_task_t *qtask)
127 shutdown_qtask = qtask;
128 event_loop_stop = 1;
131 void event_loop(struct iscsi_ipc *ipc, int control_fd, int mgmt_ipc_fd)
133 struct pollfd poll_array[POLL_MAX];
134 int res, has_shutdown_children = 0;
136 poll_array[POLL_CTRL].fd = control_fd;
137 poll_array[POLL_CTRL].events = POLLIN;
138 poll_array[POLL_IPC].fd = mgmt_ipc_fd;
139 poll_array[POLL_IPC].events = POLLIN;
141 event_loop_stop = 0;
142 while (1) {
143 if (event_loop_stop) {
144 if (!has_shutdown_children) {
145 has_shutdown_children = 1;
146 shutdown_notify_pids();
148 if (shutdown_wait_pids())
149 break;
152 res = poll(poll_array, POLL_MAX, ACTOR_RESOLUTION);
153 if (res > 0) {
154 log_debug(6, "poll result %d", res);
155 if (poll_array[POLL_CTRL].revents)
156 ipc->ctldev_handle();
158 if (poll_array[POLL_IPC].revents)
159 mgmt_ipc_handle(mgmt_ipc_fd);
160 } else if (res < 0) {
161 if (errno == EINTR) {
162 log_debug(1, "event_loop interrupted");
163 } else {
164 log_error("got poll() error (%d), errno (%d), "
165 "exiting", res, errno);
166 break;
168 } else
169 actor_poll();
170 reap_proc();
172 * flush sysfs cache since kernel objs may
173 * have changed as a result of handling op
175 sysfs_cleanup();
177 if (shutdown_qtask)
178 mgmt_ipc_write_rsp(shutdown_qtask, ISCSI_SUCCESS);