return retval;
}
+unsigned int poweroftwo(unsigned int x)
+{
+ unsigned int power2 = 1;
+ unsigned int hardcoded = 2147483648; /* FIX max 2^31 */
+
+ if (x < 2)
+ return 2;
+
+ while (power2 < x && power2 < hardcoded)
+ power2 *= 2;
+
+ return power2;
+}
+
+static int do_cmd_set_subbuf_size(const char *recvbuf, struct ustcomm_source *src)
+{
+ char *channel_slash_size;
+ char ch_name[256]="";
+ unsigned int size, power;
+ int retval = 0;
+ struct ust_trace *trace;
+ char trace_name[] = "auto";
+ int i;
+ int found = 0;
+
+ DBG("set_subbuf_size");
+
+ channel_slash_size = nth_token(recvbuf, 1);
+ sscanf(channel_slash_size, "%255[^/]/%u", ch_name, &size);
+
+ if(ch_name == NULL) {
+ ERR("cannot parse channel");
+ goto end;
+ }
+
+ power = poweroftwo(size);
+ if (power != size)
+ WARN("using the next 2^n = %u\n", power);
+
+ ltt_lock_traces();
+ trace = _ltt_trace_find_setup(trace_name);
+ if(trace == NULL) {
+ ERR("cannot find trace!");
+ ltt_unlock_traces();
+ retval = -1;
+ goto end;
+ }
+
+ for(i = 0; i < trace->nr_channels; i++) {
+ struct ust_channel *channel = &trace->channels[i];
+
+ if(!strcmp(trace->channels[i].channel_name, ch_name)) {
+
+ channel->subbuf_size = power;
+ DBG("the set_subbuf_size for the requested channel is %zd", channel->subbuf_size);
+
+ found = 1;
+ break;
+ }
+ }
+ if(found == 0) {
+ ERR("unable to find channel");
+ }
+
+ ltt_unlock_traces();
+
+ end:
+ return retval;
+}
+
+static int do_cmd_set_subbuf_num(const char *recvbuf, struct ustcomm_source *src)
+{
+ char *channel_slash_num;
+ char ch_name[256]="";
+ unsigned int num;
+ int retval = 0;
+ struct ust_trace *trace;
+ char trace_name[] = "auto";
+ int i;
+ int found = 0;
+
+ DBG("set_subbuf_num");
+
+ channel_slash_num = nth_token(recvbuf, 1);
+ sscanf(channel_slash_num, "%255[^/]/%u", ch_name, &num);
+
+ if(ch_name == NULL) {
+ ERR("cannot parse channel");
+ goto end;
+ }
+ if (num < 2) {
+ ERR("subbuffer count should be greater than 2");
+ goto end;
+ }
+
+ ltt_lock_traces();
+ trace = _ltt_trace_find_setup(trace_name);
+ if(trace == NULL) {
+ ERR("cannot find trace!");
+ ltt_unlock_traces();
+ retval = -1;
+ goto end;
+ }
+
+ for(i = 0; i < trace->nr_channels; i++) {
+ struct ust_channel *channel = &trace->channels[i];
+
+ if(!strcmp(trace->channels[i].channel_name, ch_name)) {
+
+ channel->subbuf_cnt = num;
+ DBG("the set_subbuf_cnt for the requested channel is %zd", channel->subbuf_cnt);
+
+ found = 1;
+ break;
+ }
+ }
+ if(found == 0) {
+ ERR("unable to find channel");
+ }
+
+ ltt_unlock_traces();
+
+ end:
+ return retval;
+}
+
static int do_cmd_get_subbuffer(const char *recvbuf, struct ustcomm_source *src)
{
int retval = 0;
ERR("ltt_trace_alloc failed");
return (void *)1;
}
+ inform_consumer_daemon(trace_name);
}
else if(!strcmp(recvbuf, "trace_create")) {
DBG("trace create");
ERR("ltt_trace_set_type failed");
return (void *)1;
}
+ }
+ else if(!strcmp(recvbuf, "trace_start")) {
+ DBG("trace start");
result = ltt_trace_alloc(trace_name);
if(result < 0) {
ERR("ltt_trace_alloc failed");
return (void *)1;
}
-
- inform_consumer_daemon(trace_name);
- }
- else if(!strcmp(recvbuf, "trace_start")) {
- DBG("trace start");
+ if(!result) {
+ inform_consumer_daemon(trace_name);
+ }
result = ltt_trace_start(trace_name);
if(result < 0) {
else if(nth_token_is(recvbuf, "put_subbuffer", 0) == 1) {
do_cmd_put_subbuffer(recvbuf, &src);
}
+ else if(nth_token_is(recvbuf, "set_subbuf_size", 0) == 1) {
+ do_cmd_set_subbuf_size(recvbuf, &src);
+ }
+ else if(nth_token_is(recvbuf, "set_subbuf_num", 0) == 1) {
+ do_cmd_set_subbuf_num(recvbuf, &src);
+ }
else if(nth_token_is(recvbuf, "enable_marker", 0) == 1) {
char *channel_slash_name = nth_token(recvbuf, 1);
char channel_name[256]="";
ltt_lock_traces();
+ if (_ltt_trace_find(trace_name)) { /* Trace already allocated */
+ err = 1;
+ goto traces_error;
+ }
+
trace = _ltt_trace_find_setup(trace_name);
if (!trace) {
ERR("Trace not found %s", trace_name);
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;
+
+ asprintf(&cmd, "%s %s", "set_subbuf_size", channel_size);
+
+ result = ustcmd_send_cmd(cmd, pid, NULL);
+ if (result) {
+ 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;
+
+ asprintf(&cmd, "%s %s", "set_subbuf_num", channel_size);
+
+ result = ustcmd_send_cmd(cmd, pid, NULL);
+ if (result) {
+ free(cmd);
+ return 1;
+ }
+
+ free(cmd);
+ return 0;
+}
+
+
/**
* Destroys an UST trace according to a PID.
*
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) {
+ return USTCMD_ERR_GEN;
+ }
+
+ return 0;
+}
+
/**
* Stops an UST trace according to a PID.
*
extern pid_t *ustcmd_get_online_pids(void);
extern int ustcmd_set_marker_state(const char *, int, pid_t);
+extern int ustcmd_set_subbuf_size(const char *, pid_t);
+extern int ustcmd_set_subbuf_num(const char *, pid_t);
extern int ustcmd_destroy_trace(pid_t);
extern int ustcmd_setup_and_start(pid_t);
extern int ustcmd_stop_trace(pid_t);
extern int ustcmd_create_trace(pid_t);
extern int ustcmd_start_trace(pid_t);
+extern int ustcmd_alloc_trace(pid_t);
extern int ustcmd_free_cmsf(struct marker_status *);
extern unsigned int ustcmd_count_nl(const char *);
extern int ustcmd_send_cmd(const char *, pid_t, char **);
ENABLE_MARKER,
DISABLE_MARKER,
GET_ONLINE_PIDS,
+ SET_SUBBUF_SIZE,
+ SET_SUBBUF_NUM,
+ ALLOC_TRACE,
UNKNOWN
};
--start-trace\t\t\tStart tracing\n\
--stop-trace\t\t\tStop tracing\n\
--destroy-trace\t\t\tDestroy the trace\n\
+ --set-subbuf-size \"CHANNEL/bytes\"\tSet the size of subbuffers per channel\n\
+ --set-subbuf-num \"CHANNEL/n\"\tSet the number of subbuffers per channel\n\
--enable-marker \"CHANNEL/MARKER\"\tEnable a marker\n\
--disable-marker \"CHANNEL/MARKER\"\tDisable a marker\n\
--list-markers\t\t\tList the markers of the process, their\n\t\t\t\t\t state and format string\n\
int option_index = 0;
static struct option long_options[] = {
{"create-trace", 0, 0, 1012},
+ {"alloc-trace", 0, 0, 1015},
{"start-trace", 0, 0, 1000},
{"stop-trace", 0, 0, 1001},
{"destroy-trace", 0, 0, 1002},
{"help", 0, 0, 'h'},
{"version", 0, 0, 1010},
{"online-pids", 0, 0, 1011},
+ {"set-subbuf-size", 1, 0, 1013},
+ {"set-subbuf-num", 1, 0, 1014},
{0, 0, 0, 0}
};
case 1012:
opts->cmd = CREATE_TRACE;
break;
+ case 1013:
+ opts->cmd = SET_SUBBUF_SIZE;
+ opts->regex = strdup(optarg);
+ break;
+ case 1014:
+ opts->cmd = SET_SUBBUF_NUM;
+ opts->regex = strdup(optarg);
+ break;
+ case 1015:
+ opts->cmd = ALLOC_TRACE;
+ break;
default:
/* unknown option or other error; error is
printed by getopt, just return */
ustcmd_set_marker_state(opts.regex, 0, *pidit);
break;
+ case SET_SUBBUF_SIZE:
+ ustcmd_set_subbuf_size(opts.regex, *pidit);
+ break;
+
+ case SET_SUBBUF_NUM:
+ ustcmd_set_subbuf_num(opts.regex, *pidit);
+ break;
+
+ case ALLOC_TRACE:
+ result = ustcmd_alloc_trace(*pidit);
+ if (result) {
+ ERR("error while trying to alloc trace with PID %u\n", (unsigned int) *pidit);
+ break;
+ }
+ break;
+
default:
ERR("unknown command\n");
break;