[ovs-dev] [PATCH] Make fatal signals cause an exit more promptly in special cases.
Ben Pfaff
blp at nicira.com
Mon Apr 12 21:47:29 UTC 2010
The fatal-signal library notices and records fatal signals (e.g. SIGTERM)
and terminates the process on the next trip through poll_block(). But
some special utilities do not always invoke poll_block() promptly, e.g.
"ovs-ofctl monitor" does not call poll_block() as long as OpenFlow messages
are available. But these special cases seem like they are all likely to
call into functions that themselves block (those with "_block" in their
names). So make a new rule that such functions should always call
fatal_signal_run(), either directly or through poll_block(). This commit
implements and documents that rule.
Bug #2625.
---
lib/fatal-signal.c | 10 ++++++++++
lib/jsonrpc.c | 4 ++++
lib/ovsdb-idl.c | 2 ++
lib/stream.c | 4 ++++
lib/vconn.c | 9 +++++++++
5 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c
index f6f913e..e2b6375 100644
--- a/lib/fatal-signal.c
+++ b/lib/fatal-signal.c
@@ -134,6 +134,16 @@ fatal_signal_handler(int sig_nr)
stored_sig_nr = sig_nr;
}
+/* Check whether a fatal signal has occurred and, if so, call the fatal signal
+ * hooks and exit.
+ *
+ * This function is called automatically by poll_block(), but specialized
+ * programs that may not always call poll_block() on a regular basis should
+ * also call it periodically. (Therefore, any function with "block" in its
+ * name is a candidate to call fatal_signal_run(), because such functions can
+ * only used by specialize programs that can afford to block outside their main
+ * loop around poll_block().)
+ */
void
fatal_signal_run(void)
{
diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c
index 72590a2..828bdac 100644
--- a/lib/jsonrpc.c
+++ b/lib/jsonrpc.c
@@ -23,6 +23,7 @@
#include "byteq.h"
#include "dynamic-string.h"
+#include "fatal-signal.h"
#include "json.h"
#include "list.h"
#include "ofpbuf.h"
@@ -293,6 +294,8 @@ jsonrpc_send_block(struct jsonrpc *rpc, struct jsonrpc_msg *msg)
{
int error;
+ fatal_signal_run();
+
error = jsonrpc_send(rpc, msg);
if (error) {
return error;
@@ -314,6 +317,7 @@ jsonrpc_recv_block(struct jsonrpc *rpc, struct jsonrpc_msg **msgp)
for (;;) {
int error = jsonrpc_recv(rpc, msgp);
if (error != EAGAIN) {
+ fatal_signal_run();
return error;
}
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
index 42c53b8..3f3ce55 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -25,6 +25,7 @@
#include "bitmap.h"
#include "dynamic-string.h"
+#include "fatal-signal.h"
#include "json.h"
#include "jsonrpc.h"
#include "ovsdb-data.h"
@@ -1281,6 +1282,7 @@ ovsdb_idl_txn_commit_block(struct ovsdb_idl_txn *txn)
{
enum ovsdb_idl_txn_status status;
+ fatal_signal_run();
while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
ovsdb_idl_run(txn->idl);
ovsdb_idl_wait(txn->idl);
diff --git a/lib/stream.c b/lib/stream.c
index 2349b0c..43b73af 100644
--- a/lib/stream.c
+++ b/lib/stream.c
@@ -25,6 +25,7 @@
#include <string.h>
#include "coverage.h"
#include "dynamic-string.h"
+#include "fatal-signal.h"
#include "flow.h"
#include "ofp-print.h"
#include "ofpbuf.h"
@@ -237,6 +238,8 @@ stream_open_block(int error, struct stream **streamp)
{
struct stream *stream = *streamp;
+ fatal_signal_run();
+
while (error == EAGAIN) {
stream_run(stream);
stream_run_wait(stream);
@@ -570,6 +573,7 @@ pstream_accept_block(struct pstream *pstream, struct stream **new_stream)
{
int error;
+ fatal_signal_run();
while ((error = pstream_accept(pstream, new_stream)) == EAGAIN) {
pstream_wait(pstream);
poll_block();
diff --git a/lib/vconn.c b/lib/vconn.c
index d8807fd..99d5a54 100644
--- a/lib/vconn.c
+++ b/lib/vconn.c
@@ -25,6 +25,7 @@
#include <string.h>
#include "coverage.h"
#include "dynamic-string.h"
+#include "fatal-signal.h"
#include "flow.h"
#include "ofp-print.h"
#include "ofpbuf.h"
@@ -273,6 +274,8 @@ vconn_open_block(const char *name, int min_version, struct vconn **vconnp)
struct vconn *vconn;
int error;
+ fatal_signal_run();
+
error = vconn_open(name, min_version, &vconn);
while (error == EAGAIN) {
vconn_run(vconn);
@@ -607,6 +610,9 @@ int
vconn_send_block(struct vconn *vconn, struct ofpbuf *msg)
{
int retval;
+
+ fatal_signal_run();
+
while ((retval = vconn_send(vconn, msg)) == EAGAIN) {
vconn_run(vconn);
vconn_run_wait(vconn);
@@ -621,6 +627,9 @@ int
vconn_recv_block(struct vconn *vconn, struct ofpbuf **msgp)
{
int retval;
+
+ fatal_signal_run();
+
while ((retval = vconn_recv(vconn, msgp)) == EAGAIN) {
vconn_run(vconn);
vconn_run_wait(vconn);
--
1.6.6.1
More information about the dev
mailing list