X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Flttng-ctl.c;h=165fef4dc5c412392fe49daec62be947d4de3853;hp=b57be223a73afce55723c858c66a5aedfa245b24;hb=09b72f7aa737f46196db18bcdf3bc947a08c27a2;hpb=bd3739b081f96057a93a234e6ac1c98a9a44ca39 diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index b57be223a..165fef4dc 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -287,6 +287,50 @@ end: return ret; } +static int check_enough_available_memory(size_t num_bytes_requested_per_cpu) +{ + int ret; + long num_cpu; + size_t best_mem_info; + size_t num_bytes_requested_total; + + /* + * Get the number of CPU currently online to compute the amount of + * memory needed to create a buffer for every CPU. + */ + num_cpu = sysconf(_SC_NPROCESSORS_ONLN); + if (num_cpu == -1) { + goto error; + } + + num_bytes_requested_total = num_bytes_requested_per_cpu * num_cpu; + + /* + * Try to get the `MemAvail` field of `/proc/meminfo`. This is the most + * reliable estimate we can get but it is only exposed by the kernel + * since 3.14. (See Linux kernel commit: + * 34e431b0ae398fc54ea69ff85ec700722c9da773) + */ + ret = utils_get_memory_available(&best_mem_info); + if (ret >= 0) { + goto success; + } + + /* + * As a backup plan, use `MemTotal` field of `/proc/meminfo`. This + * is a sanity check for obvious user error. + */ + ret = utils_get_memory_total(&best_mem_info); + if (ret >= 0) { + goto success; + } + +error: + return -1; +success: + return best_mem_info >= num_bytes_requested_total; +} + /* * Try connect to session daemon with sock_path. * @@ -1475,6 +1519,7 @@ int lttng_enable_channel(struct lttng_handle *handle, struct lttng_channel *in_chan) { struct lttcomm_session_msg lsm; + size_t total_buffer_size_needed_per_cpu = 0; /* NULL arguments are forbidden. No default values. */ if (handle == NULL || in_chan == NULL) { @@ -1510,6 +1555,16 @@ int lttng_enable_channel(struct lttng_handle *handle, memcpy(&lsm.u.channel.extended, extended, sizeof(*extended)); } + /* + * Verify that the amount of memory required to create the requested + * buffer is available on the system at the moment. + */ + total_buffer_size_needed_per_cpu = lsm.u.channel.chan.attr.num_subbuf * + lsm.u.channel.chan.attr.subbuf_size; + if (!check_enough_available_memory(total_buffer_size_needed_per_cpu)) { + return -LTTNG_ERR_NOMEM; + } + lsm.cmd_type = LTTNG_ENABLE_CHANNEL; lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);