[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