X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Flib%2Flttng-ust%2Flttng-ust-comm.c;h=5330e5c2a0c9ed2c6e63170203cc862d80199075;hb=92d3cba45e0f6ffd5d81bbba7b2d7011b0b18de1;hp=323ccaea915e8330392c1b1044a23115eec84ca1;hpb=b2be0f7bf1550b80316ec3703dbd9effdb1759dd;p=lttng-ust.git diff --git a/src/lib/lttng-ust/lttng-ust-comm.c b/src/lib/lttng-ust/lttng-ust-comm.c index 323ccaea..5330e5c2 100644 --- a/src/lib/lttng-ust/lttng-ust-comm.c +++ b/src/lib/lttng-ust/lttng-ust-comm.c @@ -854,6 +854,49 @@ end: return ret; } +static +void prepare_cmd_reply(struct ustcomm_ust_reply *lur, uint32_t handle, uint32_t cmd, int ret) +{ + lur->handle = handle; + lur->cmd = cmd; + lur->ret_val = ret; + if (ret >= 0) { + lur->ret_code = LTTNG_UST_OK; + } else { + /* + * Use -LTTNG_UST_ERR as wildcard for UST internal + * error that are not caused by the transport, except if + * we already have a more precise error message to + * report. + */ + if (ret > -LTTNG_UST_ERR) { + /* Translate code to UST error. */ + switch (ret) { + case -EEXIST: + lur->ret_code = -LTTNG_UST_ERR_EXIST; + break; + case -EINVAL: + lur->ret_code = -LTTNG_UST_ERR_INVAL; + break; + case -ENOENT: + lur->ret_code = -LTTNG_UST_ERR_NOENT; + break; + case -EPERM: + lur->ret_code = -LTTNG_UST_ERR_PERM; + break; + case -ENOSYS: + lur->ret_code = -LTTNG_UST_ERR_NOSYS; + break; + default: + lur->ret_code = -LTTNG_UST_ERR; + break; + } + } else { + lur->ret_code = ret; + } + } +} + static int handle_message(struct sock_info *sock_info, int sock, struct ustcomm_ust_msg *lum) @@ -878,6 +921,52 @@ int handle_message(struct sock_info *sock_info, goto error; } + switch (lum->cmd) { + case LTTNG_UST_ABI_FILTER: + case LTTNG_UST_ABI_EXCLUSION: + case LTTNG_UST_ABI_CHANNEL: + case LTTNG_UST_ABI_STREAM: + case LTTNG_UST_ABI_CONTEXT: + /* + * Those commands send additional payload after struct + * ustcomm_ust_msg, which makes it pretty much impossible to + * deal with "unknown command" errors without leaving the + * communication pipe in a out-of-sync state. This is part of + * the ABI between liblttng-ust-ctl and liblttng-ust, and + * should be fixed on the next breaking + * LTTNG_UST_ABI_MAJOR_VERSION protocol bump by indicating the + * total command message length as part of a message header so + * that the protocol can recover from invalid command errors. + */ + break; + + case LTTNG_UST_ABI_CAPTURE: + case LTTNG_UST_ABI_COUNTER: + case LTTNG_UST_ABI_COUNTER_GLOBAL: + case LTTNG_UST_ABI_COUNTER_CPU: + case LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE: + case LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE: + /* + * Those commands expect a reply to the struct ustcomm_ust_msg + * before sending additional payload. + */ + prepare_cmd_reply(&lur, lum->handle, lum->cmd, 0); + + ret = send_reply(sock, &lur); + if (ret < 0) { + DBG("error sending reply"); + goto error; + } + break; + + default: + /* + * Other commands either don't send additional payload, or are + * unknown. + */ + break; + } + switch (lum->cmd) { case LTTNG_UST_ABI_REGISTER_DONE: if (lum->handle == LTTNG_UST_ABI_ROOT_HANDLE) @@ -1295,44 +1384,8 @@ int handle_message(struct sock_info *sock_info, break; } - lur.handle = lum->handle; - lur.cmd = lum->cmd; - lur.ret_val = ret; - if (ret >= 0) { - lur.ret_code = LTTNG_UST_OK; - } else { - /* - * Use -LTTNG_UST_ERR as wildcard for UST internal - * error that are not caused by the transport, except if - * we already have a more precise error message to - * report. - */ - if (ret > -LTTNG_UST_ERR) { - /* Translate code to UST error. */ - switch (ret) { - case -EEXIST: - lur.ret_code = -LTTNG_UST_ERR_EXIST; - break; - case -EINVAL: - lur.ret_code = -LTTNG_UST_ERR_INVAL; - break; - case -ENOENT: - lur.ret_code = -LTTNG_UST_ERR_NOENT; - break; - case -EPERM: - lur.ret_code = -LTTNG_UST_ERR_PERM; - break; - case -ENOSYS: - lur.ret_code = -LTTNG_UST_ERR_NOSYS; - break; - default: - lur.ret_code = -LTTNG_UST_ERR; - break; - } - } else { - lur.ret_code = ret; - } - } + prepare_cmd_reply(&lur, lum->handle, lum->cmd, ret); + if (ret >= 0) { switch (lum->cmd) { case LTTNG_UST_ABI_TRACER_VERSION: