[icinga-checkins] icinga.org: icinga-core/mfriedrich/workers: libicinga: make send_kvvec() return what send() returned #2954

git at icinga.org git at icinga.org
Sun Aug 5 23:32:12 CEST 2012


Module: icinga-core
Branch: mfriedrich/workers
Commit: 3deebcc316f1c2f3dc52619eb96505def288f931
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=3deebcc316f1c2f3dc52619eb96505def288f931

Author: Michael Friedrich <michael.friedrich at univie.ac.at>
Date:   Sun Aug  5 14:17:55 2012 +0200

libicinga: make send_kvvec() return what send() returned #2954

using this we can forward possible write errors to the outer function
calls, as well report how many bytes actually written.

refs #2954

---

 lib/worker.c |   34 ++++++++++++++++++++--------------
 lib/worker.h |    3 ++-
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/lib/worker.c b/lib/worker.c
index 04f89dc..8518003 100644
--- a/lib/worker.c
+++ b/lib/worker.c
@@ -123,6 +123,7 @@ static void job_error(child_process *cp, struct kvvec *kvv, const char *fmt, ...
 	char msg[4096];
 	int len;
 	va_list ap;
+	int ret;
 
 	va_start(ap, fmt);
 	len = vsnprintf(msg, sizeof(msg) - 1, fmt, ap);
@@ -131,7 +132,14 @@ static void job_error(child_process *cp, struct kvvec *kvv, const char *fmt, ...
 		kvvec_addkv(kvv, "job_id", (char *)mkstr("%d", cp->id));
 	}
 	kvvec_addkv_wlen(kvv, "error_msg", 5, msg, len);
-	send_kvvec(master_sd, kvv);
+
+	ret = send_kvvec(master_sd, kvv);
+
+	if (ret < 0 && errno == EPIPE) {
+		/* master has died or abandoned us, so exit */
+		exit_worker();
+	}
+
 	kvvec_destroy(kvv, 0);
 }
 
@@ -181,7 +189,7 @@ const char *mkstr(const char *fmt, ...) {
 	return ret;
 }
 
-void send_kvvec(int sd, struct kvvec *kvv) {
+int send_kvvec(int sd, struct kvvec *kvv) {
 	int ret;
 	struct kvvec_buf *kvvb;
 
@@ -201,22 +209,14 @@ void send_kvvec(int sd, struct kvvec *kvv) {
 		 * reason is OOM, in which case the OOM-slayer will
 		 * probably kill us sooner or later.
 		 */
-		return;
+		return 0;
 	}
 
 	/* use bufsize here, as it gets us the nul string delimiter */
 	ret = write(sd, kvvb->buf, kvvb->bufsize);
-	if (ret < 0) {
-		if (errno == EPIPE) {
-			/*
-			 * master has crashed or abandoned us, so we die
-			 * with what grace we can.
-			 */
-			exit_worker();
-		}
-	}
 	free(kvvb->buf);
 	free(kvvb);
+	return ret;
 }
 
 #define kvvec_add_long(kvv, key, value) \
@@ -234,7 +234,7 @@ void send_kvvec(int sd, struct kvvec *kvv) {
 static int finish_job(child_process *cp, int reason) {
 	struct kvvec *resp;
 	struct rusage *ru = &cp->rusage;
-	int i;
+	int i, ret;
 
 	resp = kvvec_init(12 + cp->request->kv_pairs); /* how many key/value pairs do we need? */
 
@@ -296,7 +296,13 @@ static int finish_job(child_process *cp, int reason) {
 		kvvec_addkv(resp, "exited_ok", "0");
 		kvvec_addkv(resp, "error_code", (char *)mkstr("%d", reason));
 	}
-	send_kvvec(master_sd, resp);
+
+	ret = send_kvvec(master_sd, resp);
+
+	if (ret < 0 && errno == EPIPE) {
+		/* master has died or abandoned us, so exit */
+		exit_worker();
+	}
 
 	/*
 	 * we mustn't free() the key/value pairs here, as they're all
diff --git a/lib/worker.h b/lib/worker.h
index 8780cc8..4b713b8 100644
--- a/lib/worker.h
+++ b/lib/worker.h
@@ -91,8 +91,9 @@ extern worker_process *spawn_worker(void (init_func)(void *), void *init_arg);
  * Send a key/value vector as a bytestream through a socket
  * @param[in] sd The socket descriptor to send to
  * @param kvv The key/value vector to send
+ * @return The number of bytes sent, or -1 on errors
  */
-extern void send_kvvec(int sd, struct kvvec *kvv);
+extern int send_kvvec(int sd, struct kvvec *kvv);
 
 /**
  * Create a short-lived string in stack-allocated memory





More information about the icinga-checkins mailing list