From 73180fc762f015935950f697822710af3f5bd23d Mon Sep 17 00:00:00 2001 From: ManikandanC Date: Fri, 6 Oct 2017 11:37:31 +0530 Subject: Use poll in the dlt-daemon for POSIX compliance The poll system call is now used in the daemon to enable DLT use in POSIX compliant systems. Also added introduced new unregister_app macro to avoid missing of logs in startup buffer. Signed-off-by: Frederic Berat Signed-off-by: ManikandanC Signed-off-by: Saya Sugiura Signed-off-by: S. Hameed --- src/console/dlt-receive.c | 21 +++- src/console/logstorage/CMakeLists.txt | 30 ++--- src/console/logstorage/dlt-logstorage-ctrl.c | 168 +++++++++++++-------------- src/console/logstorage/dlt-logstorage-list.c | 17 ++- 4 files changed, 132 insertions(+), 104 deletions(-) (limited to 'src/console') diff --git a/src/console/dlt-receive.c b/src/console/dlt-receive.c index 200add1..e22d15e 100644 --- a/src/console/dlt-receive.c +++ b/src/console/dlt-receive.c @@ -77,7 +77,11 @@ #include #include #include -#include /* for PATH_MAX */ +#ifdef __linux__ +#include +#else +#include +#endif #include #include "dlt_client.h" @@ -211,7 +215,7 @@ int dlt_receive_open_output_file(DltReceiveData * dltdata) { /* if (file_already_exists) */ glob_t outer; - if (glob(dltdata->ovalue, GLOB_TILDE_CHECK | GLOB_NOSORT, NULL, &outer) == 0) + if (glob(dltdata->ovalue, GLOB_TILDE | GLOB_NOSORT, NULL, &outer) == 0) { if (dltdata->vflag) { @@ -234,7 +238,7 @@ int dlt_receive_open_output_file(DltReceiveData * dltdata) * foo.1000.dlt * foo.11.dlt */ - if (glob(pattern, GLOB_TILDE_CHECK | GLOB_NOSORT, NULL, &inner) == 0) + if (glob(pattern, GLOB_TILDE | GLOB_NOSORT, NULL, &inner) == 0) { /* search for the highest number used */ size_t i; @@ -376,7 +380,16 @@ int main(int argc, char* argv[]) to_copy = to_copy - 4; } - dltdata.ovaluebase = strndup(dltdata.ovalue, to_copy); + dltdata.ovaluebase = (char *)calloc(1, to_copy + 1); + + if (dltdata.ovaluebase == NULL) + { + fprintf (stderr, "Memory allocation failed.\n"); + return -1; + } + + dltdata.ovaluebase[to_copy] = '\0'; + memcpy(dltdata.ovaluebase, dltdata.ovalue, to_copy); break; } case 'e': diff --git a/src/console/logstorage/CMakeLists.txt b/src/console/logstorage/CMakeLists.txt index 830bf5a..160d905 100644 --- a/src/console/logstorage/CMakeLists.txt +++ b/src/console/logstorage/CMakeLists.txt @@ -16,24 +16,26 @@ ####### add_definitions( -Werror ) -if(WITH_DLT_LOGSTORAGE_CTRL_UDEV AND WITH_DLT_LOGSTORAGE_CTRL_PROP) - set(dlt_logstorage_ctrl_SRCS dlt-logstorage-ctrl.c dlt-logstorage-common.c dlt-logstorage-prop.c dlt-logstorage-udev.c dlt-logstorage-list.c) -elseif(WITH_DLT_LOGSTORAGE_CTRL_PROP) - set(dlt_logstorage_ctrl_SRCS dlt-logstorage-ctrl.c dlt-logstorage-common.c dlt-logstorage-prop.c dlt-logstorage-list.c) -elseif(WITH_DLT_LOGSTORAGE_CTRL_UDEV) - set(dlt_logstorage_ctrl_SRCS dlt-logstorage-ctrl.c dlt-logstorage-common.c dlt-logstorage-udev.c dlt-logstorage-list.c) -else(WITH_DLT_LOGSTORAGE_CTRL_UDEV) - set(dlt_logstorage_ctrl_SRCS dlt-logstorage-ctrl.c dlt-logstorage-common.c dlt-logstorage-list.c) -endif(WITH_DLT_LOGSTORAGE_CTRL_UDEV AND WITH_DLT_LOGSTORAGE_CTRL_PROP) - -add_executable(dlt-logstorage-ctrl ${dlt_logstorage_ctrl_SRCS} ${dlt_control_common_SRCS} ${dlt_most_SRCS} ${CMAKE_SOURCE_DIR}/systemd/3rdparty/sd-daemon.c ) +set(dlt_logstorage_ctrl_SRCS dlt-logstorage-ctrl.c dlt-logstorage-common.c dlt-logstorage-list.c) if(WITH_DLT_LOGSTORAGE_CTRL_UDEV) - target_link_libraries(dlt-logstorage-ctrl dlt udev ${EXPAT_LIBRARIES}) -else(WITH_DLT_LOGSTORAGE_CTRL_UDEV) - target_link_libraries(dlt-logstorage-ctrl dlt ${EXPAT_LIBRARIES}) + set(dlt_logstorage_ctrl_SRCS ${dlt_logstorage_ctrl_SRCS} dlt-logstorage-udev.c) endif(WITH_DLT_LOGSTORAGE_CTRL_UDEV) +if(WITH_SYSTEMD) + set(dlt_logstorage_ctrl_SRCS ${dlt_logstorage_ctrl_SRCS} ${CMAKE_SOURCE_DIR}/systemd/3rdparty/sd-daemon.c) +endif(WITH_SYSTEMD) + +add_executable(dlt-logstorage-ctrl ${dlt_logstorage_ctrl_SRCS} ${dlt_control_common_SRCS} ${dlt_most_SRCS}) + +set(DLT_LOGSTORAGE_LIBRARIES dlt-logstorage-ctrl dlt ${EXPAT_LIBRARIES}) + +if(WITH_DLT_LOGSTORAGE_CTRL_UDEV) + set(DLT_LOGSTORAGE_LIBRARIES ${DLT_LOGSTORAGE_LIBRARIES} udev) +endif(WITH_DLT_LOGSTORAGE_CTRL_UDEV) + +target_link_libraries(${DLT_LOGSTORAGE_LIBRARIES}) + set_target_properties(dlt-logstorage-ctrl PROPERTIES LINKER_LANGUAGE C) install(TARGETS dlt-logstorage-ctrl diff --git a/src/console/logstorage/dlt-logstorage-ctrl.c b/src/console/logstorage/dlt-logstorage-ctrl.c index 15ccc04..87e303b 100644 --- a/src/console/logstorage/dlt-logstorage-ctrl.c +++ b/src/console/logstorage/dlt-logstorage-ctrl.c @@ -63,9 +63,11 @@ #include #include -#include +#include +#if defined(__linux__) #include "sd-daemon.h" +#endif #include "dlt_protocol.h" #include "dlt_client.h" @@ -73,16 +75,19 @@ #include "dlt-logstorage-common.h" #include "dlt-logstorage-ctrl.h" -#define EPOLL_MAX_EVENTS 10 -#define EPOLL_TIME_OUT 500 +#define POLL_TIME_OUT 500 +#define EV_MASK_REJECTED (POLLERR | POLLHUP | POLLNVAL) #define DLT_LOGSTORAGE_CTRL_EXIT 1 static int must_exit; -static int efd; +struct dlt_event { + struct pollfd pfd; + void *func; +}; /** @brief Triggers the application exit * - * The application will exit on next epoll timeout. + * The application will exit on next poll timeout. */ void dlt_logstorage_exit(void) { @@ -91,7 +96,7 @@ void dlt_logstorage_exit(void) /** @brief Check if the application must exit * - * The application will exit on next epoll timeout. + * The application will exit on next poll timeout. */ int dlt_logstorage_must_exit(void) { @@ -203,22 +208,22 @@ static int analyze_response(char *data, void *payload, int len) return ret; } -/** @brief Add a new event to watch to the epoll instance +/** @brief Add a new event to watch * * This function could be exported to be used by udev/prop so that they can * register several events. - * There is no remove function as the removal is done on efd closure. * + * @param ev_hdl The structure containing the file descriptors * @param fd The file descriptor to watch * @param cb The callback to be called on event. * - * @return epoll_ctrl return value, or -1 on earlier failure. + * @return 0 on success, -1 if the parameters are invalid. */ -static int dlt_logstorage_ctrl_add_event(int fd, void *cb) +static int dlt_logstorage_ctrl_add_event(struct dlt_event *ev_hdl, + int fd, + void *cb) { - struct epoll_event event; - - if ((fd < 0) || !cb) + if ((fd < 0) || !cb || !ev_hdl) { pr_error("Wrong parameter to add event (%d %p)\n", fd, cb); return -1; @@ -226,96 +231,82 @@ static int dlt_logstorage_ctrl_add_event(int fd, void *cb) pr_verbose("Setting up the event handler with (%d, %p).\n", fd, cb); - event.data.ptr = cb; - event.events = EPOLLIN | EPOLLET; + ev_hdl->func = cb; + ev_hdl->pfd.fd = fd; - return epoll_ctl(efd, EPOLL_CTL_ADD, fd, &event); + return 0; } /** @brief Main execution loop * - * Waits on events from the epoll fd, and executes the callbacks retrieved + * Waits on events, and executes the callbacks retrieved * back from the event structure. * * @return 0 on success, -1 otherwise. */ -static int dlt_logstorage_ctrl_execute_event_loop(int efd) +static int dlt_logstorage_ctrl_execute_event_loop(struct dlt_event *ev) { - struct epoll_event *events; - int i; int ret = 0; - int n = 0; + int (*callback)() = ev->func; - events = calloc(10, sizeof(struct epoll_event)); + ret = poll(&ev->pfd, 1, POLL_TIME_OUT); - if (!events) + if (ret <= 0) { - pr_error("No memory available for events.\n"); - return -1; - } - - n = epoll_wait(efd, events, EPOLL_MAX_EVENTS, EPOLL_TIME_OUT); - - if (n < 0) - { - pr_error("epoll_wait error: %s\n", strerror(errno)); - if (errno == EINTR) { - /* Only exit if the daemon has received QUIT/INT/TERM */ - free(events); - return 0; + ret = 0; } - free(events); - return -1; + if (ret < 0) + { + pr_error("poll error: %s\n", strerror(errno)); + } + + return ret; } - for (i = 0 ; i < n ; i++) + if (ev->pfd.revents == 0) { - int (*callback)() = events[i].data.ptr; + return 0; + } - if (!(events[i].events & (EPOLLIN | EPOLLET))) - { - pr_error("Error while polling. Event received: 0x%x\n", - events[i].events); - /* We only support one event producer. - * Error means that this producer died. - */ - pr_error("Now closing fd and exiting.\n"); - close(events[i].data.fd); - dlt_logstorage_exit(); - ret = -1; - break; - } + if (ev->pfd.events & EV_MASK_REJECTED) + { + pr_error("Error while polling. Event received: 0x%x\n", ev->pfd.events); + /* We only support one event producer. + * Error means that this producer died. + */ + pr_error("Now closing fd and exiting.\n"); + close(ev->pfd.fd); + ev->pfd.fd = -1; + dlt_logstorage_exit(); + return -1; + } - if (!callback) - { - pr_error("Callback not found, exiting.\n"); - dlt_logstorage_exit(); - ret = -1; - break; - } + if (!callback) + { + pr_error("Callback not found, exiting.\n"); + dlt_logstorage_exit(); + return -1; + } - pr_verbose("Got new event, calling %p.\n", callback); + pr_verbose("Got new event, calling %p.\n", callback); - if (callback() < 0) - { - pr_error("Error while calling the callback, exiting.\n"); - dlt_logstorage_exit(); - ret = -1; - break; - } + if (callback() < 0) + { + pr_error("Error while calling the callback, exiting.\n"); + dlt_logstorage_exit(); + return -1; } - free(events); - return ret; + return 0; } /** @brief Start event loop and receive messages from DLT. * * The function will first install the signal handler, - * then create the epoll instance, initialize the communication controller, + * then create the poll instance, initialize the communication controller, * initialize the event handler and finally start the polling. * * @return 0 on success, -1 on error @@ -323,18 +314,16 @@ static int dlt_logstorage_ctrl_execute_event_loop(int efd) static int dlt_logstorage_ctrl_setup_event_loop(void) { int ret = 0; + struct dlt_event ev_hdl = { + .pfd = { + .fd = -1, + .events = POLLIN + } + }; install_signal_handler(); - pr_verbose("Creating epoll instance.\n"); - efd = epoll_create1(0); - - if (efd == -1) - { - pr_error("epoll_create error: %s\n", strerror(errno)); - dlt_logstorage_exit(); - return -errno; - } + pr_verbose("Creating poll instance.\n"); /* Initializing the communication with the daemon */ while (dlt_control_init(analyze_response, get_ecuid(), get_verbosity()) && @@ -360,21 +349,20 @@ static int dlt_logstorage_ctrl_setup_event_loop(void) return -1; } - if (dlt_logstorage_ctrl_add_event(dlt_logstorage_get_handler_fd(), + if (dlt_logstorage_ctrl_add_event(&ev_hdl, + dlt_logstorage_get_handler_fd(), dlt_logstorage_get_handler_cb()) < 0) { - pr_error("epoll_ctl error: %s\n", strerror(errno)); + pr_error("add_event error: %s\n", strerror(errno)); dlt_logstorage_exit(); } while (!dlt_logstorage_must_exit() && (ret == 0)) { - ret = dlt_logstorage_ctrl_execute_event_loop(efd); + ret = dlt_logstorage_ctrl_execute_event_loop(&ev_hdl); } /* Clean up */ - close(efd); - dlt_logstorage_deinit_handler(); dlt_control_deinit(); @@ -561,6 +549,16 @@ static int parse_args(int argc, char *argv[]) return 0; } +#if !defined(DLT_SYSTEMD_ENABLE) +int sd_notify(int unset_environment, const char *state) +{ + /* Satisfy Compiler for warnings */ + (void) unset_environment; + (void) state; + return 0; +} +#endif + /** @brief Entry point * * Execute the argument parser and call the main feature accordingly. diff --git a/src/console/logstorage/dlt-logstorage-list.c b/src/console/logstorage/dlt-logstorage-list.c index 0b7a8c0..a18fca6 100644 --- a/src/console/logstorage/dlt-logstorage-list.c +++ b/src/console/logstorage/dlt-logstorage-list.c @@ -143,6 +143,7 @@ static struct LogstorageDeviceInfo *logstorage_find_dev_info(const char *node) int logstorage_store_dev_info(const char *node, const char *path) { struct LogstorageDeviceInfo *ptr = NULL; + size_t path_len = 0; if ((node == NULL) || (path == NULL)) { @@ -166,7 +167,21 @@ int logstorage_store_dev_info(const char *node, const char *path) } ptr->dev_node = strdup(node); - ptr->mnt_point = strndup(path, DLT_MOUNT_PATH_MAX); + path_len = strlen(path); + if (path_len >DLT_MOUNT_PATH_MAX) + { + path_len = (size_t)DLT_MOUNT_PATH_MAX; + } + ptr->mnt_point = (char *)calloc(1, path_len + 1); + + if (ptr->mnt_point == NULL) + { + pr_error("memory allocation failed for mnt_point\n"); + return -1; + } + + ptr->mnt_point[path_len] = '\0'; + memcpy(ptr->mnt_point, path, path_len); /* Put it on head */ ptr->next = g_info; -- cgit v1.2.1