From: Jérémie Galarneau Date: Mon, 20 Aug 2018 21:32:46 +0000 (-0400) Subject: Fix: consumers don't honor protocol on rotate pending relay command X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=commitdiff_plain;h=19990ed538f86bf0f32193a378c3faf36ce4f467 Fix: consumers don't honor protocol on rotate pending relay command The payload of a command should not be sent to the sessiond if its execution failed. The sessiond reports an error as soon as the return code of the command is returned and will never consume the payload, resulting in a protocol error down the line. Moreover, the ust-consumer's implementation doesn't check for errors as it stores the return value of lttng_consumer_rotate_pending_relay() to an unsigned variable and checks for negative values. Signed-off-by: Jérémie Galarneau --- diff --git a/src/common/kernel-consumer/kernel-consumer.c b/src/common/kernel-consumer/kernel-consumer.c index 66ae16bc8..f1c38ccbf 100644 --- a/src/common/kernel-consumer/kernel-consumer.c +++ b/src/common/kernel-consumer/kernel-consumer.c @@ -1183,19 +1183,20 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, } case LTTNG_CONSUMER_ROTATE_PENDING_RELAY: { + int pending; uint32_t pending_reply; DBG("Consumer rotate pending on relay for session %" PRIu64, msg.u.rotate_pending_relay.session_id); - ret = lttng_consumer_rotate_pending_relay( + pending = lttng_consumer_rotate_pending_relay( msg.u.rotate_pending_relay.session_id, msg.u.rotate_pending_relay.relayd_id, msg.u.rotate_pending_relay.chunk_id); - if (ret < 0) { + if (pending < 0) { ERR("Rotate pending relay failed"); ret_code = LTTCOMM_CONSUMERD_CHAN_NOT_FOUND; } else { - pending_reply = !!ret; + pending_reply = !!pending; } health_code_update(); @@ -1206,6 +1207,15 @@ int lttng_kconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, goto end_nosignal; } + if (pending < 0) { + /* + * An error occured while running the command; + * don't send the 'pending' flag as the sessiond + * will not read it. + */ + break; + } + /* Send back returned value to session daemon */ ret = lttcomm_send_unix_sock(sock, &pending_reply, sizeof(pending_reply)); diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index cb5743fad..81c9e72fe 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -2034,7 +2034,8 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, } case LTTNG_CONSUMER_ROTATE_PENDING_RELAY: { - uint32_t pending; + int pending; + uint32_t pending_reply; DBG("Consumer rotate pending on relay for session %" PRIu64, msg.u.rotate_pending_relay.session_id); @@ -2045,18 +2046,31 @@ int lttng_ustconsumer_recv_cmd(struct lttng_consumer_local_data *ctx, if (pending < 0) { ERR("Rotate pending relay failed"); ret_code = LTTCOMM_CONSUMERD_RELAYD_FAIL; + } else { + pending_reply = !!pending; } health_code_update(); + /* Send whether the command was successful. */ ret = consumer_send_status_msg(sock, ret_code); if (ret < 0) { /* Somehow, the session daemon is not responding anymore. */ goto end_nosignal; } - /* Send back returned value to session daemon */ - ret = lttcomm_send_unix_sock(sock, &pending, sizeof(pending)); + if (pending < 0) { + /* + * An error occured while running the command; + * don't send the 'pending' reply as the sessiond + * will not read it. + */ + break; + } + + /* Send back the command's payload (pending reply). */ + ret = lttcomm_send_unix_sock(sock, &pending_reply, + sizeof(pending_reply)); if (ret < 0) { PERROR("send data pending ret code"); goto error_fatal;