Skip to content

Commit

Permalink
lib/worker: Introduce and use build_kvvec_buf()
Browse files Browse the repository at this point in the history
It's nifty to have send_kvvec() separated into one function
that builds the buffer and another one that sends is, since
we really (I mean, really) need to make sure commands to and
from our workers get sent properly, and the previous code
made it quite hard for the core process to figure out what,
if anything, went wrong.

Signed-off-by: Andreas Ericsson <[email protected]>

git-svn-id: https://nagios.svn.sourceforge.net/svnroot/nagios/nagioscore/trunk@2438 5f96b256-904b-4d8d-8c98-d829582c6739
  • Loading branch information
ageric committed Oct 29, 2012
1 parent 3e7b8a5 commit c889a4b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 18 deletions.
14 changes: 12 additions & 2 deletions base/workers.c
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,9 @@ static worker_process *get_worker(worker_job *job)
static int wproc_run_job(worker_job *job, nagios_macros *mac)
{
static struct kvvec kvv = KVVEC_INITIALIZER;
struct kvvec_buf *kvvb;
worker_process *wp;
int ret;

/*
* get_worker() also adds job to the workers list
Expand All @@ -889,12 +891,20 @@ static int wproc_run_job(worker_job *job, nagios_macros *mac)
kvvec_addkv(&kvv, "type", (char *)mkstr("%d", job->type));
kvvec_addkv(&kvv, "command", job->command);
kvvec_addkv(&kvv, "timeout", (char *)mkstr("%u", job->timeout));
send_kvvec(wp->sd, &kvv);
kvvb = build_kvvec_buf(&kvv);
ret = write(wp->sd, kvvb->buf, kvvb->bufsize);
wp->jobs_running++;
wp->jobs_started++;
loadctl.jobs_running++;
if (ret != kvvb->bufsize) {
logit(NSLOG_RUNTIME_ERROR, TRUE, "wproc: '%s' seems to be choked. ret = %d; bufsize = %lu: errno = %d (%s)\n",
wp->source_name, ret, kvvb->bufsize, errno, strerror(errno));
destroy_job(wp, job);
}
free(kvvb->buf);
free(kvvb);

return 0;
return ret;
}

static wproc_object_job *create_object_job(char *cname, char *hname, char *sdesc)
Expand Down
34 changes: 18 additions & 16 deletions lib/worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,35 +163,37 @@ const char *mkstr(const char *fmt, ...)
return ret;
}

int send_kvvec(int sd, struct kvvec *kvv)
struct kvvec_buf *build_kvvec_buf(struct kvvec *kvv)
{
int ret;
struct kvvec_buf *kvvb;

/*
* key=value, separated by nul bytes and two nul's
* delimit one message from another. We need to cut
* one from MSG_DELIM_LEN here though, since nul is
* added unconditionally after each value as well
* and we'd otherwise run into an off-by-one when
* parsing the messages back into sensible order.
* key=value, separated by PAIR_SEP and messages
* delimited by MSG_DELIM
*/
kvvb = kvvec2buf(kvv, KV_SEP, PAIR_SEP, MSG_DELIM_LEN_SEND);
if (!kvvb) {
/*
* XXX: do *something* sensible here to let the
* master know we failed, although the most likely
* reason is OOM, in which case the OOM-slayer will
* probably kill us sooner or later.
*/
return 0;
return NULL;
}
memcpy(kvvb->buf + (kvvb->bufsize - MSG_DELIM_LEN_SEND), MSG_DELIM, MSG_DELIM_LEN_SEND);

/* use bufsize here, as it gets us the nul string delimiter */
return kvvb;
}

int send_kvvec(int sd, struct kvvec *kvv)
{
int ret;
struct kvvec_buf *kvvb;

kvvb = build_kvvec_buf(kvv);
if (!kvvb)
return -1;

/* bufsize, not buflen, as it gets us the delimiter */
ret = write(sd, kvvb->buf, kvvb->bufsize);
free(kvvb->buf);
free(kvvb);

return ret;
}

Expand Down
10 changes: 10 additions & 0 deletions lib/worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ extern int finish_job(child_process *cp, int reason);
*/
extern void enter_worker(int sd, int (*cb)(child_process*));

/**
* Build a buffer from a key/value vector buffer.
* The resulting kvvec-buffer is suitable for sending between
* worker and master in either direction, as it has all the
* right delimiters in all the right places.
* @param kvv The key/value vector to build the buffer from
* @return NULL on errors, a newly allocated kvvec buffer on success
*/
extern struct kvvec_buf *build_kvvec_buf(struct kvvec *kvv);

/**
* Send a key/value vector as a bytestream through a socket
* @param[in] sd The socket descriptor to send to
Expand Down

0 comments on commit c889a4b

Please sign in to comment.