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
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.
27 #include <sys/types.h>
31 #include "iscsi_ipc.h"
35 #include "iscsi_ipc.h"
37 #include "initiator.h"
38 #include "iscsi_err.h"
40 static int reap_count
;
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
);
60 log_debug(6, "reaped pid %d, reap_count now %d",
66 static LIST_HEAD(shutdown_callbacks
);
68 struct shutdown_callback
{
69 struct list_head list
;
73 int shutdown_callback(pid_t pid
)
75 struct shutdown_callback
*cb
;
77 cb
= calloc(1, sizeof(*cb
));
81 INIT_LIST_HEAD(&cb
->list
);
83 log_debug(1, "adding %d for shutdown cb\n", pid
);
84 list_add_tail(&cb
->list
, &shutdown_callbacks
);
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
);
114 return list_empty(&shutdown_callbacks
);
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
;
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
;
143 if (event_loop_stop
) {
144 if (!has_shutdown_children
) {
145 has_shutdown_children
= 1;
146 shutdown_notify_pids();
148 if (shutdown_wait_pids())
152 res
= poll(poll_array
, POLL_MAX
, ACTOR_RESOLUTION
);
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");
164 log_error("got poll() error (%d), errno (%d), "
165 "exiting", res
, errno
);
172 * flush sysfs cache since kernel objs may
173 * have changed as a result of handling op
178 mgmt_ipc_write_rsp(shutdown_qtask
, ISCSI_SUCCESS
);