X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=libustcmd%2Fustcmd.c;h=c51232000310340d81144ed8e6607c412a6b405a;hb=dc46f6e66144edead3c54d69eaa0b4bec56e4eaf;hp=223280cc238201130166b94f3399e447913b21c4;hpb=772030fed323e388da467735cf4b5e8781acb710;p=ust.git diff --git a/libustcmd/ustcmd.c b/libustcmd/ustcmd.c index 223280c..c512320 100644 --- a/libustcmd/ustcmd.c +++ b/libustcmd/ustcmd.c @@ -25,14 +25,13 @@ #include #include "ustcomm.h" -#include "ustcmd.h" +#include "ust/ustcmd.h" +#include "usterr.h" -#define _GNU_SOURCE - -pid_t* ustcmd_get_online_pids(void) +pid_t *ustcmd_get_online_pids(void) { - struct dirent* dirent; - DIR* dir; + struct dirent *dirent; + DIR *dir; unsigned int ret_size = 1 * sizeof(pid_t), i = 0; dir = opendir(SOCK_DIR); @@ -40,7 +39,7 @@ pid_t* ustcmd_get_online_pids(void) return NULL; } - pid_t* ret = (pid_t*) malloc(ret_size); + pid_t *ret = (pid_t *) malloc(ret_size); while ((dirent = readdir(dir))) { if (!strcmp(dirent->d_name, ".") || @@ -52,10 +51,10 @@ pid_t* ustcmd_get_online_pids(void) if (dirent->d_type != DT_DIR && !!strcmp(dirent->d_name, "ustd")) { - sscanf(dirent->d_name, "%u", (unsigned int*) &ret[i]); + sscanf(dirent->d_name, "%u", (unsigned int *) &ret[i]); if (pid_is_online(ret[i])) { ret_size += sizeof(pid_t); - ret = (pid_t*) realloc(ret, ret_size); + ret = (pid_t *) realloc(ret, ret_size); ++i; } } @@ -63,7 +62,8 @@ pid_t* ustcmd_get_online_pids(void) ret[i] = 0; /* Array end */ - if (ret[0] == 0) { /* No PID at all.. */ + if (ret[0] == 0) { + /* No PID at all */ free(ret); return NULL; } @@ -80,20 +80,24 @@ pid_t* ustcmd_get_online_pids(void) * @param pid Traced process ID * @return 0 if successful, or errors {USTCMD_ERR_GEN, USTCMD_ERR_ARG} */ -int ustcmd_set_marker_state(const char* mn, int state, pid_t pid) +int ustcmd_set_marker_state(const char *mn, int state, pid_t pid) { - char* cmd_str [] = {"disable_marker", "enable_marker"}; - char* cmd; + char *cmd_str [] = {"disable_marker", "enable_marker"}; + char *cmd; int result; if (mn == NULL) { return USTCMD_ERR_ARG; } - asprintf(&cmd, "%s %s", cmd_str[state], mn); + if (asprintf(&cmd, "%s %s", cmd_str[state], mn) < 0) { + ERR("ustcmd_set_marker_state : asprintf failed (%s %s)", + cmd_str[state], mn); + return USTCMD_ERR_GEN; + } - result = ustcmd_shoot(cmd, pid, NULL); - if (result) { + result = ustcmd_send_cmd(cmd, pid, NULL); + if (result != 1) { free(cmd); return USTCMD_ERR_GEN; } @@ -102,6 +106,124 @@ int ustcmd_set_marker_state(const char* mn, int state, pid_t pid) return 0; } +/** + * Set subbuffer size. + * + * @param channel_size Channel name and size + * @param pid Traced process ID + * @return 0 if successful, or error + */ +int ustcmd_set_subbuf_size(const char *channel_size, pid_t pid) +{ + char *cmd; + int result; + + if (asprintf(&cmd, "%s %s", "set_subbuf_size", channel_size) < 0) { + ERR("ustcmd_set_subbuf_size : asprintf failed (set_subbuf_size %s)", + channel_size); + return -1; + } + + result = ustcmd_send_cmd(cmd, pid, NULL); + if (result != 1) { + free(cmd); + return 1; + } + + free(cmd); + return 0; +} + +/** + * Set subbuffer num. + * + * @param channel_num Channel name and num + * @param pid Traced process ID + * @return 0 if successful, or error + */ +int ustcmd_set_subbuf_num(const char *channel_size, pid_t pid) +{ + char *cmd; + int result; + + if (asprintf(&cmd, "%s %s", "set_subbuf_num", channel_size) < 0) { + ERR("ustcmd_set_subbuf_num : asprintf failed (set_subbuf_num %s", + channel_size); + return -1; + } + + result = ustcmd_send_cmd(cmd, pid, NULL); + if (result != 1) { + free(cmd); + return 1; + } + + free(cmd); + return 0; +} + +/** + * Get subbuffer size. + * + * @param channel Channel name + * @param pid Traced process ID + * @return subbuf size if successful, or error + */ +int ustcmd_get_subbuf_size(const char *channel, pid_t pid) +{ + char *cmd, *reply; + int result; + + /* format: channel_cpu */ + if (asprintf(&cmd, "%s %s_0", "get_subbuf_size", channel) < 0) { + ERR("ustcmd_get_subbuf_size : asprintf failed (get_subbuf_size, %s_0", + channel); + return -1; + } + + result = ustcmd_send_cmd(cmd, pid, &reply); + if (result != 1) { + free(cmd); + return -1; + } + + result = atoi(reply); + free(cmd); + free(reply); + return result; +} + +/** + * Get subbuffer num. + * + * @param channel Channel name + * @param pid Traced process ID + * @return subbuf cnf if successful, or error + */ +int ustcmd_get_subbuf_num(const char *channel, pid_t pid) +{ + char *cmd, *reply; + int result; + + /* format: channel_cpu */ + if (asprintf(&cmd, "%s %s_0", "get_n_subbufs", channel) < 0) { + ERR("ustcmd_get_subbuf_num : asprintf failed (get_n_subbufs, %s_0", + channel); + return -1; + } + + result = ustcmd_send_cmd(cmd, pid, &reply); + if (result != 1) { + free(cmd); + return -1; + } + + result = atoi(reply); + free(cmd); + free(reply); + return result; +} + /** * Destroys an UST trace according to a PID. * @@ -112,8 +234,8 @@ int ustcmd_destroy_trace(pid_t pid) { int result; - result = ustcmd_shoot("destroy", pid, NULL); - if (result) { + result = ustcmd_send_cmd("trace_destroy", pid, NULL); + if (result != 1) { return USTCMD_ERR_GEN; } @@ -130,8 +252,26 @@ int ustcmd_setup_and_start(pid_t pid) { int result; - result = ustcmd_shoot("start", pid, NULL); - if (result) { + result = ustcmd_send_cmd("start", pid, NULL); + if (result != 1) { + return USTCMD_ERR_GEN; + } + + return 0; +} + +/** + * Creates an UST trace according to a PID. + * + * @param pid Traced process ID + * @return 0 if successful, or error USTCMD_ERR_GEN + */ +int ustcmd_create_trace(pid_t pid) +{ + int result; + + result = ustcmd_send_cmd("trace_create", pid, NULL); + if (result != 1) { return USTCMD_ERR_GEN; } @@ -148,8 +288,26 @@ int ustcmd_start_trace(pid_t pid) { int result; - result = ustcmd_shoot("trace_start", pid, NULL); - if (result) { + result = ustcmd_send_cmd("trace_start", pid, NULL); + if (result != 1) { + return USTCMD_ERR_GEN; + } + + return 0; +} + +/** + * Alloc an UST trace according to a PID. + * + * @param pid Traced process ID + * @return 0 if successful, or error USTCMD_ERR_GEN + */ +int ustcmd_alloc_trace(pid_t pid) +{ + int result; + + result = ustcmd_send_cmd("trace_alloc", pid, NULL); + if (result != 1) { return USTCMD_ERR_GEN; } @@ -166,8 +324,8 @@ int ustcmd_stop_trace(pid_t pid) { int result; - result = ustcmd_shoot("trace_stop", pid, NULL); - if (result) { + result = ustcmd_send_cmd("trace_stop", pid, NULL); + if (result != 1) { return USTCMD_ERR_GEN; } @@ -180,7 +338,7 @@ int ustcmd_stop_trace(pid_t pid) * @param str String to search in * @return Total newlines count */ -unsigned int ustcmd_count_nl(const char* str) +unsigned int ustcmd_count_nl(const char *str) { unsigned int i = 0, tot = 0; @@ -200,7 +358,7 @@ unsigned int ustcmd_count_nl(const char* str) * @param cmsf CMSF array to free * @return 0 if successful, or error USTCMD_ERR_ARG */ -int ustcmd_free_cmsf(struct USTcmd_cmsf* cmsf) +int ustcmd_free_cmsf(struct marker_status *cmsf) { if (cmsf == NULL) { return USTCMD_ERR_ARG; @@ -224,39 +382,36 @@ int ustcmd_free_cmsf(struct USTcmd_cmsf* cmsf) * @param cmsf Pointer to CMSF array to be filled (callee allocates, caller * frees with `ustcmd_free_cmsf') * @param pid Targeted PID - * @return 0 if successful, or errors {USTCMD_ERR_ARG, USTCMD_ERR_GEN} + * @return 0 if successful, or -1 on error */ -int ustcmd_get_cmsf(struct USTcmd_cmsf** cmsf, const pid_t pid) +int ustcmd_get_cmsf(struct marker_status **cmsf, const pid_t pid) { - char* big_str = NULL; + char *big_str = NULL; int result; - struct USTcmd_cmsf* tmp_cmsf = NULL; + struct marker_status *tmp_cmsf = NULL; unsigned int i = 0, cmsf_ind = 0; if (cmsf == NULL) { - return USTCMD_ERR_ARG; - } - result = ustcmd_shoot("list_markers", pid, &big_str); - if (result) { - return USTCMD_ERR_GEN; + return -1; } - - if (big_str == NULL) { - fprintf(stderr, "ustcmd: error while getting markers list\n"); - return USTCMD_ERR_GEN; + result = ustcmd_send_cmd("list_markers", pid, &big_str); + if (result != 1) { + ERR("error while getting markers list"); + return -1; } - tmp_cmsf = (struct USTcmd_cmsf*) malloc(sizeof(struct USTcmd_cmsf) * + tmp_cmsf = (struct marker_status *) malloc(sizeof(struct marker_status) * (ustcmd_count_nl(big_str) + 1)); if (tmp_cmsf == NULL) { - return USTCMD_ERR_GEN; + ERR("Failed to allocate CMSF array"); + return -1; } /* Parse received reply string (format: "[chan]/[mark] [st] [fs]"): */ while (big_str[i] != '\0') { char state; - sscanf(big_str + i, "%a[^/]/%a[^ ] %c %a[^\n]", + sscanf(big_str + i, "marker: %a[^/]/%a[^ ] %c %a[^\n]", &tmp_cmsf[cmsf_ind].channel, &tmp_cmsf[cmsf_ind].marker, &state, @@ -280,31 +435,174 @@ int ustcmd_get_cmsf(struct USTcmd_cmsf** cmsf, const pid_t pid) return 0; } + +/** + * Frees a TES array. + * + * @param tes TES array to free + * @return 0 if successful, or error USTCMD_ERR_ARG + */ +int ustcmd_free_tes(struct trace_event_status *tes) +{ + if (tes == NULL) { + return USTCMD_ERR_ARG; + } + + unsigned int i = 0; + while (tes[i].name != NULL) { + free(tes[i].name); + ++i; + } + free(tes); + + return 0; +} + /** - * Shoots a given command using ustcomm. + * Gets trace_events string for a given PID. * - * @param cmd Null-terminated command to shoot + * @param tes Pointer to TES array to be filled (callee allocates, caller + * frees with `ustcmd_free_tes') + * @param pid Targeted PID + * @return 0 if successful, or -1 on error + */ +int ustcmd_get_tes(struct trace_event_status **tes, + const pid_t pid) +{ + char *big_str = NULL; + int result; + struct trace_event_status *tmp_tes = NULL; + unsigned int i = 0, tes_ind = 0; + + if (tes == NULL) { + return -1; + } + + result = ustcmd_send_cmd("list_trace_events", pid, &big_str); + if (result != 1) { + ERR("error while getting trace_event list"); + return -1; + } + + tmp_tes = (struct trace_event_status *) + zmalloc(sizeof(struct trace_event_status) * + (ustcmd_count_nl(big_str) + 1)); + if (tmp_tes == NULL) { + ERR("Failed to allocate TES array"); + return -1; + } + + /* Parse received reply string (format: "[name]"): */ + while (big_str[i] != '\0') { + char state; + + sscanf(big_str + i, "trace_event: %a[^\n]", + &tmp_tes[tes_ind].name); + while (big_str[i] != '\n') { + ++i; /* Go to next '\n' */ + } + ++i; /* Skip current pointed '\n' */ + ++tes_ind; + } + tmp_tes[tes_ind].name = NULL; + + *tes = tmp_tes; + + free(big_str); + return 0; +} + +/** + * Set socket path + * + * @param sock_path Socket path + * @param pid Traced process ID + * @return 0 if successful, or error + */ +int ustcmd_set_sock_path(const char *sock_path, pid_t pid) +{ + char *cmd; + int result; + + if (asprintf(&cmd, "%s %s", "set_sock_path", sock_path) < 0) { + ERR("ustcmd_set_sock_path : asprintf failed (set_sock_path, %s", + sock_path); + return -1; + } + + result = ustcmd_send_cmd(cmd, pid, NULL); + if (result != 1) { + free(cmd); + return USTCMD_ERR_GEN; + } + + free(cmd); + return 0; +} + +/** + * Get socket path + * + * @param sock_path Pointer to where the socket path will be returned + * @param pid Traced process ID + * @return 0 if successful, or error + */ +int ustcmd_get_sock_path(char **sock_path, pid_t pid) +{ + char *cmd, *reply; + int result; + + if (asprintf(&cmd, "%s", "get_sock_path") < 0) { + ERR("ustcmd_get_sock_path : asprintf failed"); + return USTCMD_ERR_GEN; + } + + result = ustcmd_send_cmd(cmd, pid, &reply); + if (result != 1) { + free(cmd); + return USTCMD_ERR_GEN; + } + + free(cmd); + *sock_path = reply; + return 0; +} + +int ustcmd_force_switch(pid_t pid) +{ + int result; + + result = ustcmd_send_cmd("force_switch", pid, NULL); + if (result != 1) { + return USTCMD_ERR_GEN; + } + + return 0; +} + +/** + * Sends a given command to a traceable process + * + * @param cmd Null-terminated command to send * @param pid Targeted PID * @param reply Pointer to string to be filled with a reply string (must * be NULL if no reply is needed for the given command). - * @return 0 if successful, or errors {USTCMD_ERR_ARG, USTCMD_ERR_CONN} + * @return -1 if not successful, 0 on EOT, 1 on success */ -int ustcmd_shoot(const char* cmd, const pid_t pid, char** reply) +int ustcmd_send_cmd(const char *cmd, const pid_t pid, char **reply) { struct ustcomm_connection conn; - - if (cmd == NULL) { - return USTCMD_ERR_ARG; - } + int retval; if (ustcomm_connect_app(pid, &conn)) { - fprintf(stderr, "ustcmd_shoot: could not connect to PID %u\n", - (unsigned int) pid); - return USTCMD_ERR_CONN; + ERR("could not connect to PID %u", (unsigned int) pid); + return -1; } - ustcomm_send_request(&conn, cmd, reply); + retval = ustcomm_send_request(&conn, cmd, reply); - return 0; + ustcomm_close_app(&conn); + + return retval; }