]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Pass command exit status via sideband to client.
authorAndre Noll <maan@systemlinux.org>
Sun, 26 Feb 2012 13:14:18 +0000 (14:14 +0100)
committerAndre Noll <maan@systemlinux.org>
Mon, 7 May 2012 10:59:07 +0000 (12:59 +0200)
Currently the only way for the client side to tell whether a command
failed is to parse the command output. This patch changes command.c to
send an empty sideband packet at command termination. If the command
succeeded, the sideband designator is set to SBD_EXIT__SUCCESS,
otherwise it is SBD_EXIT__FAILURE.

The client checks for these sideband packets and terminates with
EXIT_FAILURE if it received the SBD_EXIT__FAILURE packet.

client.c
client_common.c
command.c
error.h

index 4998222ea7c89df98ad55879a08f9dea1b5f6c6b..c194e1929b9dfa2cb7704ca1f6b78dd704eb3815 100644 (file)
--- a/client.c
+++ b/client.c
@@ -606,6 +606,7 @@ int main(int argc, char *argv[])
        if (ret >= 0 && ct->task.error < 0) {
                switch(ct->task.error) {
                /* these are not errors */
+               case -E_SERVER_CMD_SUCCESS:
                case -E_EOF:
                case -E_SERVER_EOF:
                case -E_BTR_EOF:
index daead879faa7f4dff4d9016c68f95426269551f0..649a1b4fdf49579e653d7b6cd6d9c977524e6171 100644 (file)
@@ -242,14 +242,19 @@ static char **parse_features(char *buf)
 
 static int dispatch_sbb(struct client_task *ct, struct sb_buffer *sbb)
 {
-       int ret, ll;
+       int ret;
+       const char *designator[] = {SB_DESIGNATORS_ARRAY};
 
-       if (!sbb || !sbb->iov.iov_base || sbb->iov.iov_len == 0)
+       if (!sbb)
                return 0;
+       if (sbb->band < NUM_SB_DESIGNATORS)
+               PARA_DEBUG_LOG("band: %s\n", designator[sbb->band]);
 
        switch (sbb->band) {
        case SBD_OUTPUT:
-               btr_add_output(sbb->iov.iov_base, sbb->iov.iov_len, ct->btrn);
+               if (iov_valid(&sbb->iov))
+                       btr_add_output(sbb->iov.iov_base, sbb->iov.iov_len,
+                               ct->btrn);
                ret = 1;
                goto out;
        case SBD_DEBUG_LOG:
@@ -259,10 +264,18 @@ static int dispatch_sbb(struct client_task *ct, struct sb_buffer *sbb)
        case SBD_ERROR_LOG:
        case SBD_CRIT_LOG:
        case SBD_EMERG_LOG:
-               ll = sbb->band - SBD_DEBUG_LOG;
-               para_log(ll, "remote: %s", (char *)sbb->iov.iov_base);
+               if (iov_valid(&sbb->iov)) {
+                       int ll = sbb->band - SBD_DEBUG_LOG;
+                       para_log(ll, "remote: %s", (char *)sbb->iov.iov_base);
+               }
                ret = 1;
                goto deallocate;
+       case SBD_EXIT__SUCCESS:
+               ret = -E_SERVER_CMD_SUCCESS;
+               goto deallocate;
+       case SBD_EXIT__FAILURE:
+               ret = -E_SERVER_CMD_FAILURE;
+               goto deallocate;
        default:
                PARA_ERROR_LOG("invalid band %d\n", sbb->band);
                ret = -E_BAD_BAND;
@@ -546,7 +559,8 @@ static void client_post_select(struct sched *s, struct task *t)
 out:
        t->error = ret;
        if (ret < 0) {
-               if (ret != -E_SERVER_EOF && ret != -E_BTR_EOF && ret != -E_EOF)
+               if (!ct->use_sideband && ret != -E_SERVER_EOF &&
+                               ret != -E_BTR_EOF && ret != -E_EOF)
                        PARA_ERROR_LOG("%s\n", para_strerror(-t->error));
                btr_remove_node(btrn);
        }
index 7b474ab1e9337c85dfc5db7b1a997a0c81e59da0..2cac57f90637f8aa42635700a58b77a688b3ff5d 100644 (file)
--- a/command.c
+++ b/command.c
@@ -1100,7 +1100,8 @@ __noreturn void handle_connect(int fd, const char *peername)
        if (ret >= 0)
                goto out;
 err_out:
-       send_strerror(cc, -ret);
+       if (send_strerror(cc, -ret) >= 0 && cc->use_sideband)
+               send_sb(&cc->scc, NULL, 0, SBD_EXIT__FAILURE, true);
 net_err:
        PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
 out:
@@ -1113,5 +1114,12 @@ out:
                mmd->events++;
        mmd->active_connections--;
        mutex_unlock(mmd_mutex);
+       if (ret < 0)
+               exit(EXIT_FAILURE);
+       if (!cc->use_sideband)
+               exit(EXIT_SUCCESS);
+       ret = send_sb(&cc->scc, NULL, 0, SBD_EXIT__SUCCESS, true);
+       if (ret < 0)
+               PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
        exit(ret < 0? EXIT_FAILURE : EXIT_SUCCESS);
 }
diff --git a/error.h b/error.h
index 8ebf4ef8886c12b4564ad385614364a3df051ef9..3100b31299b3064fb47875bdbef971425e02fd11 100644 (file)
--- a/error.h
+++ b/error.h
@@ -263,6 +263,8 @@ extern const char **para_errlist[];
        PARA_ERROR(BAD_CONFIG, "syntax error in config file"), \
        PARA_ERROR(CLIENT_AUTH, "authentication failed"), \
        PARA_ERROR(SERVER_EOF, "connection closed by para_server"), \
+       PARA_ERROR(SERVER_CMD_SUCCESS, "command terminated successfully"), \
+       PARA_ERROR(SERVER_CMD_FAILURE, "command failed"), \
 
 
 #define SCHED_ERRORS \