From 4f0b3096603eb71c1e0687e97f8d5cec5a770a4d Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Thu, 5 Mar 2020 09:01:12 +0100 Subject: [PATCH] (lib)dlogutil: getsize also returns current usage Change-Id: Ie92967e0206761d833e1f2661cdd100291266407 Signed-off-by: Michal Bloch --- include/dlogutil.h | 19 +++++++++++++++++++ include/fd_info.h | 3 +++ src/libdlogutil/fdi_logger.c | 13 +++++++++++++ src/libdlogutil/fdi_pipe.c | 30 ++++++++++++++++++++++++++++++ src/libdlogutil/lib.c | 9 +++++++++ src/logutil/logutil.c | 8 ++++++-- src/tests/fdi_logger_neg.c | 3 ++- src/tests/fdi_logger_pos.c | 20 +++++++++++++++++++- src/tests/fdi_logger_wrap.c | 13 +++++++++++-- src/tests/fdi_pipe_neg.c | 20 +++++++++++++++++++- src/tests/fdi_pipe_pos.c | 12 +++++++++++- tests/test_libdlogutil_legacy.c | 8 +++++++- 12 files changed, 149 insertions(+), 9 deletions(-) diff --git a/include/dlogutil.h b/include/dlogutil.h index 9520746..0a40e67 100644 --- a/include/dlogutil.h +++ b/include/dlogutil.h @@ -552,6 +552,25 @@ int dlogutil_buffer_get_name(dlogutil_buffer_e buffer, const char **name); int dlogutil_buffer_get_capacity(dlogutil_buffer_e buffer, unsigned int *capacity); /** + * @brief Gets the usage of a buffer. + * @since_tizen 6.0 + * @remarks Either CAP_SYSLOG or being in the log group is required. + * @bug This is currently evaluated using the config file, which can change at runtime. In particular, + * this can desync from the value of the server if the config file changes. Note that this is mostly + * a theoretical concern, since the file is not intended to change during the runtime (the daemon asks + * to reboot the system in such a case). + * @param[in] buffer A single buffer to be inspected + * @param[out] usage Buffer's current usage, in bytes + * @return An error code + * @retval TIZEN_ERROR_NONE Success + * @retval TIZEN_ERROR_INVALID_PARAMETER Invalid buffer + * @retval TIZEN_ERROR_INVALID_PARAMETER More than one buffer + * @retval TIZEN_ERROR_INVALID_PARAMETER The pointer was NULL + * @retval Other An arbitrary Tizen error code + */ +int dlogutil_buffer_get_usage(dlogutil_buffer_e buffer, unsigned int *usage); + +/** * @brief Gets the default timestamp type of a buffer. * @since_tizen 6.0 * @remarks This is the timestamp type that will be used for sorting by default. diff --git a/include/fd_info.h b/include/fd_info.h index 64574f1..b565833 100644 --- a/include/fd_info.h +++ b/include/fd_info.h @@ -62,6 +62,9 @@ struct fd_ops { /// Get the capacity of the buffer int (*get_capacity)(struct fd_info *fdi, unsigned int *capacity); + /// Get the current size (usage) of the buffer + int (*get_usage)(struct fd_info *fdi, unsigned int *used); + /// Check whether there will be no more logs on this FD bool (*eof)(const struct fd_info *fdi); diff --git a/src/libdlogutil/fdi_logger.c b/src/libdlogutil/fdi_logger.c index 27f8c76..f9f3f45 100644 --- a/src/libdlogutil/fdi_logger.c +++ b/src/libdlogutil/fdi_logger.c @@ -61,6 +61,18 @@ static int logger_get_capacity(struct fd_info *fdi, unsigned int *capacity) return 0; } +static int logger_get_usage(struct fd_info *fdi, unsigned int *usage) +{ + assert(fdi); + + int r = logger_ioctl(fdi->fd, LOGGER_GET_LOG_LEN); + if (r < 0) + return r; + + *usage = (unsigned int)r; + return 0; +} + /** * @brief Get buffer filled size * @details Sends a get log len ioctl to given fd @@ -339,6 +351,7 @@ const struct fd_ops ops_logger = { .prepare_print = logger_prepare_print, .clear = logger_clear, .get_capacity = logger_get_capacity, + .get_usage = logger_get_usage, .eof = logger_eof, .should_filter = true, }; diff --git a/src/libdlogutil/fdi_pipe.c b/src/libdlogutil/fdi_pipe.c index 9b79d69..ed1ce16 100644 --- a/src/libdlogutil/fdi_pipe.c +++ b/src/libdlogutil/fdi_pipe.c @@ -53,6 +53,35 @@ cleanup: return r; } +static int pipe_get_usage(struct fd_info *fdi, unsigned int *usage) +{ + assert(fdi); + struct pipe_priv_data *ppd = (struct pipe_priv_data *)fdi->priv_data; + assert(ppd); + assert(ppd->sock_fd >= 0); + + int r = send_dlog_request(ppd->sock_fd, DLOG_REQ_GET_USAGE, NULL, 0); + if (r < 0) + return r; + + unsigned int *data; + int datalen; + r = recv_dlog_reply(ppd->sock_fd, DLOG_REQ_GET_USAGE, (void **)&data, &datalen); + if (r < 0) + goto cleanup; + + if (!data || datalen != sizeof *data) { + r = -EINVAL; + goto cleanup; + } + + *usage = *data; + +cleanup: + free(data); + return r; +} + /** * @brief Clear request * @details Send a CLEAR request to the logger daemon @@ -301,6 +330,7 @@ const struct fd_ops ops_pipe = { .prepare_print = pipe_prepare_print, .clear = pipe_clear, .get_capacity = pipe_get_capacity, + .get_usage = pipe_get_usage, .eof = pipe_eof, .should_filter = false, }; diff --git a/src/libdlogutil/lib.c b/src/libdlogutil/lib.c index 52da108..fbc281a 100644 --- a/src/libdlogutil/lib.c +++ b/src/libdlogutil/lib.c @@ -206,6 +206,15 @@ EXPORT_API int dlogutil_buffer_get_capacity(dlogutil_buffer_e buffer, unsigned i return fdi_ptrs[0]->ops->get_capacity(fdi_ptrs[0], capacity); } +EXPORT_API int dlogutil_buffer_get_usage(dlogutil_buffer_e buffer, unsigned int *usage) +{ + CHECK_PARAM(usage); + + COMMON_INIT_SINGLE + + return fdi_ptrs[0]->ops->get_usage(fdi_ptrs[0], usage); +} + EXPORT_API int dlogutil_buffer_get_default_ts_type(dlogutil_buffer_e buffer, dlogutil_sorting_order_e *type) { CHECK_PARAM(type); diff --git a/src/logutil/logutil.c b/src/logutil/logutil.c index eda2fa0..450ce23 100644 --- a/src/logutil/logutil.c +++ b/src/logutil/logutil.c @@ -256,12 +256,16 @@ static int print_buffer_capacity(dlogutil_buffer_e buffer) if (r != 0) return r; - unsigned int capacity; + unsigned int usage, capacity; r = dlogutil_buffer_get_capacity(buffer, &capacity); if (r != 0) return r; - printf("%s: %u KiB\n", name, BtoKiB(capacity)); + r = dlogutil_buffer_get_usage(buffer, &usage); + if (r != 0) + return r; + + printf("%s: %u KiB, of which %u used (%u%%)\n", name, BtoKiB(capacity), BtoKiB(usage), 100 * usage / capacity); return 0; } diff --git a/src/tests/fdi_logger_neg.c b/src/tests/fdi_logger_neg.c index a41c4af..9862439 100644 --- a/src/tests/fdi_logger_neg.c +++ b/src/tests/fdi_logger_neg.c @@ -62,10 +62,11 @@ int main() ioctl_ret = -77; assert(-77 == ops_logger.clear(&fdi)); - unsigned int sz; + unsigned int us, sz; expected_ioctl = LOGGER_GET_LOG_BUF_SIZE; ioctl_ret = -EALREADY; assert(-EALREADY == ops_logger.get_capacity(&fdi, &sz)); + assert(-EALREADY == ops_logger.get_usage(&fdi, &us)); expected_ioctl = LOGGER_GET_LOG_LEN; ioctl_ret = -67; diff --git a/src/tests/fdi_logger_pos.c b/src/tests/fdi_logger_pos.c index b2b881a..1177919 100644 --- a/src/tests/fdi_logger_pos.c +++ b/src/tests/fdi_logger_pos.c @@ -39,11 +39,29 @@ int main() ioctl_ret = 15; assert(0 == ops_logger.clear(&fdi)); - unsigned int sz; + unsigned int us, sz; + expected_ioctl = LOGGER_GET_LOG_BUF_SIZE; + ioctl_ret = -EALREADY; + assert(-EALREADY == ops_logger.get_capacity(&fdi, &sz)); + assert(-EALREADY == ops_logger.get_usage(&fdi, &us)); + expected_ioctl = LOGGER_GET_LOG_BUF_SIZE; ioctl_ret = 2019; assert(0 == ops_logger.get_capacity(&fdi, &sz)); + assert(0 == ops_logger.get_usage(&fdi, &us)); assert(2019 == sz); + assert(2020 == us); + + expected_ioctl = LOGGER_GET_LOG_BUF_SIZE; + fail_next_ioctl = true; + sz = 0xBAADF00D; + us = 0xDEADBEEF; + + assert(0 == ops_logger.get_capacity(&fdi, &sz)); + assert(-4665 == ops_logger.get_usage(&fdi, &us)); + assert(2021 == sz); + assert(0xDEADBEEF == us); + fail_next_ioctl = false; expected_ioctl = LOGGER_GET_LOG_LEN; ioctl_ret = 0; diff --git a/src/tests/fdi_logger_wrap.c b/src/tests/fdi_logger_wrap.c index 5dc396a..4ca5a27 100644 --- a/src/tests/fdi_logger_wrap.c +++ b/src/tests/fdi_logger_wrap.c @@ -121,17 +121,26 @@ void *__wrap_calloc(size_t nmemb, size_t size) static int expected_ioctl; static int ioctl_ret; +static bool fail_next_ioctl; int __real_ioctl(int fd, int request, char *argp); int __wrap_ioctl(int fd, int request, char *argp) { assert(fd == 0xFD); assert(expected_ioctl == request); + if (LOGGER_GET_LOG_BUF_SIZE == expected_ioctl) + expected_ioctl = LOGGER_GET_LOG_LEN; + if (ioctl_ret < 0) { errno = -ioctl_ret; return -1; } - return ioctl_ret; -} + if (fail_next_ioctl) { + const int temp = ioctl_ret; + ioctl_ret = -4665; + return temp; + } + return ioctl_ret++; +} diff --git a/src/tests/fdi_pipe_neg.c b/src/tests/fdi_pipe_neg.c index 4de6f20..0e23ac8 100644 --- a/src/tests/fdi_pipe_neg.c +++ b/src/tests/fdi_pipe_neg.c @@ -96,14 +96,20 @@ int main() correct_request = DLOG_REQ_GET_CAPACITY; correct_send_data = NULL; correct_send_datalen = 0; - unsigned int size_target = 0; + unsigned int size_target = 0, usage_target = 0; send_return = -1; assert(ops_pipe.get_capacity(&info, &size_target) == -1); + correct_request = DLOG_REQ_GET_USAGE; + assert(ops_pipe.get_usage(&info, &usage_target) == -1); + send_return = 0; recv_return = -1; + correct_request = DLOG_REQ_GET_CAPACITY; assert(ops_pipe.get_capacity(&info, &size_target) == -1); + correct_request = DLOG_REQ_GET_USAGE; + assert(ops_pipe.get_usage(&info, &usage_target) == -1); recv_return = 0; const char *wrong_ans = "I won't tell you the pipe size :)"; @@ -112,12 +118,24 @@ int main() assert(recv_data); memcpy(recv_data, wrong_ans, recv_datalen); ptr_to_free = recv_data; + correct_request = DLOG_REQ_GET_CAPACITY; assert(ops_pipe.get_capacity(&info, &size_target) == -EINVAL); assert(ptr_to_free == NULL); + recv_data = malloc(recv_datalen); + assert(recv_data); + memcpy(recv_data, wrong_ans, recv_datalen); + ptr_to_free = recv_data; + correct_request = DLOG_REQ_GET_USAGE; + assert(ops_pipe.get_usage(&info, &usage_target) == -EINVAL); + assert(ptr_to_free == NULL); + recv_datalen = 0; recv_data = NULL; + correct_request = DLOG_REQ_GET_CAPACITY; assert(ops_pipe.get_capacity(&info, &size_target) == -EINVAL); + correct_request = DLOG_REQ_GET_USAGE; + assert(ops_pipe.get_usage(&info, &usage_target) == -EINVAL); ops_pipe.destroy(&info); ops_pipe.destroy(&info); diff --git a/src/tests/fdi_pipe_pos.c b/src/tests/fdi_pipe_pos.c index 92883b2..de689f7 100644 --- a/src/tests/fdi_pipe_pos.c +++ b/src/tests/fdi_pipe_pos.c @@ -130,7 +130,7 @@ ok: assert(ops_pipe.clear(&info) == 0); correct_request = DLOG_REQ_GET_CAPACITY; - unsigned int size_target = 0; + unsigned int size_target = 0, usage_target = 0; recv_return = 0; recv_datalen = sizeof(unsigned int); @@ -140,7 +140,17 @@ ok: ptr_to_free = recv_data; assert(ops_pipe.get_capacity(&info, &size_target) == 0); assert(ptr_to_free == NULL); + + correct_request = DLOG_REQ_GET_USAGE; + recv_data = malloc(recv_datalen); + assert(recv_data); + *(int *)recv_data = (unsigned int)235U; + ptr_to_free = recv_data; + assert(ops_pipe.get_usage(&info, &usage_target) == 0); + assert(ptr_to_free == NULL); + assert(size_target == 17); + assert(usage_target == 235U); ptr_to_free = ppd; ops_pipe.destroy(&info); diff --git a/tests/test_libdlogutil_legacy.c b/tests/test_libdlogutil_legacy.c index 0b58d9b..ecf14d9 100644 --- a/tests/test_libdlogutil_legacy.c +++ b/tests/test_libdlogutil_legacy.c @@ -162,8 +162,9 @@ void traits_main(bool pipe) assert(dlogutil_buffer_get_name(DLOGUTIL_BUF_KMSG, &name) == 0); assert(!strcmp(name, "kmsg")); - unsigned int capacity; + unsigned int usage, capacity; assert(dlogutil_buffer_get_capacity(DLOGUTIL_BUF_MAIN, &capacity) == 0); + assert(dlogutil_buffer_get_usage(DLOGUTIL_BUF_MAIN, &usage) == 0); if (pipe) assert(capacity == MB(1)); else { @@ -174,6 +175,7 @@ void traits_main(bool pipe) } assert(dlogutil_buffer_get_capacity(DLOGUTIL_BUF_KMSG, &capacity) == 0); + assert(dlogutil_buffer_get_usage(DLOGUTIL_BUF_KMSG, &usage) == 0); assert(capacity == MB(1)); dlogutil_sorting_order_e type; @@ -240,16 +242,19 @@ void negative_main() assert(dlogutil_buffer_clear(0) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_name(0, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_capacity(0, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); + assert(dlogutil_buffer_get_usage(0, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_default_ts_type(0, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_check_ts_type_available(0, DLOGUTIL_SORT_RECV_MONO, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_clear(1 << 16) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_name(1 << 16, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_capacity(1 << 16, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); + assert(dlogutil_buffer_get_usage(1 << 16, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_default_ts_type(1 << 16, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_check_ts_type_available(1 << 16, DLOGUTIL_SORT_RECV_MONO, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_clear(DLOGUTIL_BUF_MAIN | DLOGUTIL_BUF_KMSG) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_name(DLOGUTIL_BUF_MAIN | DLOGUTIL_BUF_KMSG, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_capacity(DLOGUTIL_BUF_MAIN | DLOGUTIL_BUF_KMSG, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); + assert(dlogutil_buffer_get_usage(DLOGUTIL_BUF_MAIN | DLOGUTIL_BUF_KMSG, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_default_ts_type(DLOGUTIL_BUF_MAIN | DLOGUTIL_BUF_KMSG, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_check_ts_type_available(DLOGUTIL_BUF_MAIN | DLOGUTIL_BUF_KMSG, DLOGUTIL_SORT_RECV_MONO, bad_ptr) == TIZEN_ERROR_INVALID_PARAMETER); @@ -270,6 +275,7 @@ void negative_main() assert(dlogutil_entry_get_message(bad_ptr, NULL) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_name(DLOGUTIL_BUF_MAIN, NULL) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_capacity(DLOGUTIL_BUF_MAIN, NULL) == TIZEN_ERROR_INVALID_PARAMETER); + assert(dlogutil_buffer_get_usage(DLOGUTIL_BUF_MAIN, NULL) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_get_default_ts_type(DLOGUTIL_BUF_MAIN, NULL) == TIZEN_ERROR_INVALID_PARAMETER); assert(dlogutil_buffer_check_ts_type_available(DLOGUTIL_BUF_MAIN, DLOGUTIL_SORT_RECV_MONO, NULL) == TIZEN_ERROR_INVALID_PARAMETER); -- 2.7.4