Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add time suffixes #12

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions doc/man/lttng.1
Original file line number Diff line number Diff line change
Expand Up @@ -284,20 +284,21 @@ Set the session in snapshot mode. Created in no-output mode and uses the
URL, if one is specified, as the default snapshot output. Every channel will be set
in overwrite mode and with mmap output (splice not supported).
.TP
.BR "\-\-live [USEC]"
Set the session exclusively in live mode. The parameter is the delay in micro
seconds before the data is flushed and streamed. The live mode allows you to
stream the trace and view it while it's being recorded by any tracer. For that,
you need a lttng-relayd and this session requires a network URL (\-U or
\-C/\-D). If no USEC nor URL is provided, the default is to use a timer value
set to 1000000 and the network URL set to net://127.0.0.1.
.BR "\-\-live [delay]"
Set the session exclusively in live mode. The parameter is the delay before
the data is flushed and streamed. The delay is expressed in microseconds by
default, but can also be suffixed with m (milliseconds) or s (seconds). The
live mode allows you to stream the trace and view it while it's being recorded
by any tracer. For that, you need a lttng-relayd and this session requires a
network URL (\-U or \-C/\-D). If no delay nor URL is provided, the default is
to use a timer value set to 1000000 and the network URL set to net://127.0.0.1.

To read a live session, you can use babeltrace(1) or the live streaming
protocol in doc/live-reading-protocol.txt. Here is an example:

.nf
$ lttng-relayd -o /tmp/lttng
$ lttng create --live 200000 -U net://localhost
$ lttng create --live 200m -U net://localhost
$ lttng enable-event -a --userspace
$ lttng start
.fi
Expand Down Expand Up @@ -451,12 +452,14 @@ to get the current page size on your system: \fB$ getconf PAGE_SIZE\fP
Number of subbuffers. (default UST uid: 4, UST pid: 4, kernel: 4,
metadata: 2) Rounded up to the next power of 2.
.TP
.BR "\-\-switch-timer USEC"
Switch subbuffer timer interval in µsec.
.BR "\-\-switch-timer TIME"
Switch subbuffer timer interval in microseconds. Can also be suffixed with
m (milliseconds) or s (seconds).
(default UST uid: 0, UST pid: 0, kernel: 0, metadata: 0)
.TP
.BR "\-\-read-timer USEC"
Read timer interval in µsec.
.BR "\-\-read-timer TIME"
Read timer interval in microseconds. Can also be suffixed with m (milliseconds)
or s (seconds).
(default UST uid: 0, UST pid: 0, kernel: 200000, metadata: 0)
.TP
.BR "\-\-output TYPE"
Expand Down
26 changes: 15 additions & 11 deletions src/bin/lttng/commands/create.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static char *opt_shm_path;
static int opt_no_consumer;
static int opt_no_output;
static int opt_snapshot;
static unsigned int opt_live_timer;
static uint32_t opt_live_timer;

enum {
OPT_HELP = 1,
Expand Down Expand Up @@ -100,13 +100,15 @@ static void usage(FILE *ofp)
fprintf(ofp, " if one, as the default snapshot output.\n");
fprintf(ofp, " Every channel will be set in overwrite mode\n");
fprintf(ofp, " and with mmap output (splice not supported).\n");
fprintf(ofp, " --live [USEC] Set the session in live-reading mode.\n");
fprintf(ofp, " The delay parameter in micro-seconds is the\n");
fprintf(ofp, " maximum time the user can wait for the data\n");
fprintf(ofp, " to be flushed. Can be set with a network\n");
fprintf(ofp, " URL (-U or -C/-D) and must have a relayd listening.\n");
fprintf(ofp, " --live [DELAY] Set the session in live-reading mode.\n");
fprintf(ofp, " The delay parameter is the maximum time the user\n");
fprintf(ofp, " can wait for the data to be flushed. The delay is\n");
fprintf(ofp, " expressed by default in microseconds, but can also\n");
fprintf(ofp, " be suffixed with m (milliseconds) or s (seconds).\n");
fprintf(ofp, " This option can be used with a network URL\n");
fprintf(ofp, " (-U or -C/-D) and must have a relayd listening.\n");
fprintf(ofp, " By default, %u is used for the timer and the\n",
DEFAULT_LTTNG_LIVE_TIMER);
DEFAULT_LTTNG_LIVE_TIMER);
fprintf(ofp, " network URL is set to net://127.0.0.1.\n");
fprintf(ofp, " --shm-path PATH Path where shared memory holding buffers\n");
fprintf(ofp, " should be created. Useful when used with pramfs\n");
Expand Down Expand Up @@ -574,7 +576,7 @@ int cmd_create(int argc, const char **argv)
goto end;
case OPT_LIVE_TIMER:
{
unsigned long v;
uint64_t v;

errno = 0;
opt_arg = poptGetOptArg(pc);
Expand All @@ -586,22 +588,24 @@ int cmd_create(int argc, const char **argv)
break;
}

v = strtoul(opt_arg, NULL, 0);
if (errno != 0 || !isdigit(opt_arg[0])) {
ERR("Wrong value in --live parameter: %s", opt_arg);
if (utils_parse_time_suffix(opt_arg, &v) < 0) {
ERR("Wrong value for --live parameter: %s", opt_arg);
ret = CMD_ERROR;
goto end;
}

if (v != (uint32_t) v) {
ERR("32-bit overflow in --live parameter: %s", opt_arg);
ret = CMD_ERROR;
goto end;
}

if (v == 0) {
ERR("Live timer interval must be greater than zero");
ret = CMD_ERROR;
goto end;
}

opt_live_timer = (uint32_t) v;
DBG("Session live timer interval set to %d", opt_live_timer);
break;
Expand Down
25 changes: 15 additions & 10 deletions src/bin/lttng/commands/enable_channels.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,13 @@ static void usage(FILE *ofp)
DEFAULT_UST_UID_CHANNEL_SUBBUF_NUM, DEFAULT_UST_PID_CHANNEL_SUBBUF_NUM,
DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM, DEFAULT_METADATA_SUBBUF_NUM);
fprintf(ofp, " Rounded up to the next power of 2.\n");
fprintf(ofp, " --switch-timer USEC Switch timer interval in usec\n");
fprintf(ofp, " --switch-timer TIME Switch timer interval in microseconds. Can also\n");
fprintf(ofp, " be suffixed with m (milliseconds) or s (seconds).\n");
fprintf(ofp, " (default UST uid: %u, UST pid: %u, kernel: %u, metadata: %u)\n",
DEFAULT_UST_UID_CHANNEL_SWITCH_TIMER, DEFAULT_UST_PID_CHANNEL_SWITCH_TIMER,
DEFAULT_KERNEL_CHANNEL_SWITCH_TIMER, DEFAULT_METADATA_SWITCH_TIMER);
fprintf(ofp, " --read-timer USEC Read timer interval in usec.\n");
fprintf(ofp, " --read-timer TIME Read timer interval in microseconds. Can also\n");
fprintf(ofp, " be suffixed with m (milliseconds) or s (seconds).\n");
fprintf(ofp, " (default UST uid: %u, UST pid: %u, kernel: %u, metadata: %u)\n",
DEFAULT_UST_UID_CHANNEL_READ_TIMER, DEFAULT_UST_UID_CHANNEL_READ_TIMER,
DEFAULT_KERNEL_CHANNEL_READ_TIMER, DEFAULT_METADATA_READ_TIMER);
Expand Down Expand Up @@ -485,16 +487,17 @@ int cmd_enable_channels(int argc, const char **argv)
}
case OPT_SWITCH_TIMER:
{
unsigned long v;
uint64_t v;

errno = 0;
opt_arg = poptGetOptArg(pc);
v = strtoul(opt_arg, NULL, 0);
if (errno != 0 || !isdigit(opt_arg[0])) {
ERR("Wrong value in --switch-timer parameter: %s", opt_arg);

if (utils_parse_time_suffix(opt_arg, &v) < 0) {
ERR("Wrong value for --switch-timer parameter: %s", opt_arg);
ret = CMD_ERROR;
goto end;
}

if (v != (uint32_t) v) {
ERR("32-bit overflow in --switch-timer parameter: %s", opt_arg);
ret = CMD_ERROR;
Expand All @@ -506,21 +509,23 @@ int cmd_enable_channels(int argc, const char **argv)
}
case OPT_READ_TIMER:
{
unsigned long v;
uint64_t v;

errno = 0;
opt_arg = poptGetOptArg(pc);
v = strtoul(opt_arg, NULL, 0);
if (errno != 0 || !isdigit(opt_arg[0])) {
ERR("Wrong value in --read-timer parameter: %s", opt_arg);

if (utils_parse_time_suffix(opt_arg, &v) < 0) {
ERR("Wrong value for --read-timer parameter: %s", opt_arg);
ret = CMD_ERROR;
goto end;
}

if (v != (uint32_t) v) {
ERR("32-bit overflow in --read-timer parameter: %s", opt_arg);
ret = CMD_ERROR;
goto end;
}

chan.attr.read_timer_interval = (uint32_t) v;
DBG("Channel read timer interval set to %d", chan.attr.read_timer_interval);
break;
Expand Down
81 changes: 81 additions & 0 deletions src/common/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,87 @@ int utils_parse_size_suffix(const char * const str, uint64_t * const size)
return ret;
}

int utils_parse_time_suffix(char const * const str, uint64_t * const time_us)
{
int ret;
uint64_t base_time;
long multiplier = 1;
const char *str_end;
char *num_end;

if (!str) {
DBG("utils_parse_time_suffix: received a NULL string.");
ret = -1;
goto end;
}

/* strtoull will accept a negative number, but we don't want to. */
if (strchr(str, '-') != NULL) {
DBG("utils_parse_time_suffix: invalid time string, should not contain '-'.");
ret = -1;
goto end;
}

/* str_end will point to the \0 */
str_end = str + strlen(str);
errno = 0;
base_time = strtoull(str, &num_end, 0);
if (errno != 0) {
PERROR("utils_parse_time_suffix strtoull");
ret = -1;
goto end;
}

if (num_end == str) {
/* strtoull parsed nothing, not good. */
DBG("utils_parse_time_suffix: strtoull had nothing good to parse.");
ret = -1;
goto end;
}

/* Check if a prefix is present. */
switch (*num_end) {
case 'u':
multiplier = 1;
num_end++;
break;
case 'm':
multiplier = 1000;
num_end++;
break;
case 's':
multiplier = 1000000;
num_end++;
break;
case '\0':
break;
default:
DBG("utils_parse_time_suffix: invalid suffix.");
ret = -1;
goto end;
}

/* Check for garbage after the valid input. */
if (num_end != str_end) {
DBG("utils_parse_time_suffix: Garbage after time string.");
ret = -1;
goto end;
}

*time_us = base_time * multiplier;

/* Check for overflow */
if ((*time_us / multiplier) != base_time) {
DBG("utils_parse_time_suffix: oops, overflow detected.");
ret = -1;
goto end;
}

ret = 0;
end:
return ret;
}

/*
* fls: returns the position of the most significant bit.
* Returns 0 if no bit is set, else returns the position of the most
Expand Down
1 change: 1 addition & 0 deletions src/common/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ int utils_rotate_stream_file(char *path_name, char *file_name, uint64_t size,
uint64_t count, int uid, int gid, int out_fd, uint64_t *new_count,
int *stream_fd);
int utils_parse_size_suffix(char const * const str, uint64_t * const size);
int utils_parse_time_suffix(char const * const str, uint64_t * const time_us);
int utils_get_count_order_u32(uint32_t x);
char *utils_get_home_dir(void);
char *utils_get_user_home_dir(uid_t uid);
Expand Down
8 changes: 7 additions & 1 deletion tests/unit/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ LIBRELAYD=$(top_builddir)/src/common/relayd/librelayd.la

# Define test programs
noinst_PROGRAMS = test_uri test_session test_kernel_data
noinst_PROGRAMS += test_utils_parse_size_suffix test_utils_expand_path
noinst_PROGRAMS += test_utils_parse_size_suffix test_utils_parse_time_suffix \
test_utils_expand_path

if HAVE_LIBLTTNG_UST_CTL
noinst_PROGRAMS += test_ust_data
Expand Down Expand Up @@ -94,6 +95,11 @@ test_utils_parse_size_suffix_SOURCES = test_utils_parse_size_suffix.c
test_utils_parse_size_suffix_LDADD = $(LIBTAP) $(LIBHASHTABLE) $(LIBCOMMON)
test_utils_parse_size_suffix_LDADD += $(UTILS_SUFFIX)

# parse_time_suffix unit test
test_utils_parse_time_suffix_SOURCES = test_utils_parse_time_suffix.c
test_utils_parse_time_suffix_LDADD = $(LIBTAP) $(LIBHASHTABLE) $(LIBCOMMON)
test_utils_parse_time_suffix_LDADD += $(UTILS_SUFFIX)

# expand_path unit test
test_utils_expand_path_SOURCES = test_utils_expand_path.c
test_utils_expand_path_LDADD = $(LIBTAP) $(LIBHASHTABLE) $(LIBCOMMON)
Expand Down
Loading