From: Christian Brauner Date: Fri, 12 Jan 2018 15:29:46 +0000 (+0100) Subject: tools: move lxc-top to API symbols only X-Git-Tag: lxc-3.0.0.beta1~36^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=adc0914195a224d9575a2ae99a825d0e43317751;p=thirdparty%2Flxc.git tools: move lxc-top to API symbols only Closes #2073. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/tools/lxc_top.c b/src/lxc/tools/lxc_top.c index 5d5c08a25..868693866 100644 --- a/src/lxc/tools/lxc_top.c +++ b/src/lxc/tools/lxc_top.c @@ -21,25 +21,26 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define _GNU_SOURCE #define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */ #include #include #include #include +#include #include #include -#include +#include #include #include #include #include +#include + #include #include "arguments.h" -#include "log.h" -#include "lxc.h" -#include "mainloop.h" -#include "utils.h" +#include "tool_utils.h" #define USER_HZ 100 #define ESC "\033" @@ -181,24 +182,6 @@ static int stdin_tios_rows(void) return 25; } -static int stdin_handler(int fd, uint32_t events, void *data, - struct lxc_epoll_descr *descr) -{ - char *in_char = data; - - if (events & EPOLLIN) { - int rc; - - rc = read(fd, in_char, sizeof(*in_char)); - if (rc <= 0) - *in_char = '\0'; - } - - if (events & EPOLLHUP) - *in_char = 'q'; - return 1; -} - static void sig_handler(int sig) { exit(EXIT_SUCCESS); @@ -310,7 +293,7 @@ static void stat_get_blk_stats(struct lxc_container *c, const char *item, char **lines, **cols; len = c->get_cgroup_item(c, item, buf, sizeof(buf)); - if (len <= 0 || len >= sizeof(buf)) { + if (len <= 0 || (size_t)len >= sizeof(buf)) { fprintf(stderr, "unable to read cgroup item %s\n", item); return; } @@ -409,7 +392,7 @@ static void stats_print(const char *name, const struct stats *stats, size_humanize(stats->mem_used, mem_used_str, sizeof(mem_used_str)); ret = snprintf(iosb_str, sizeof(iosb_str), "%s(%s/%s)", iosb_total_str, iosb_read_str, iosb_write_str); - if (ret < 0 || ret >= sizeof(iosb_str)) + if (ret < 0 || (size_t)ret >= sizeof(iosb_str)) printf("snprintf'd too many characters: %d\n", ret); printf("%-18.18s %12.2f %12.2f %12.2f %36s %10s", @@ -429,7 +412,7 @@ static void stats_print(const char *name, const struct stats *stats, printf(" %10s", kmem_used_str); } } else { - gettimeofday(&time_val, NULL); + (void)gettimeofday(&time_val, NULL); time_ms = (unsigned long long) (time_val.tv_sec) * 1000 + (unsigned long long) (time_val.tv_usec) / 1000; printf("%" PRIu64 ",%s,%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64, @@ -554,6 +537,143 @@ static void ct_realloc(int active_cnt) } } +#define LXC_MAINLOOP_CONTINUE 0 +#define LXC_MAINLOOP_CLOSE 1 + +struct lxc_epoll_descr { + int epfd; + struct lxc_list handlers; +}; + +typedef int (*lxc_mainloop_callback_t)(int fd, uint32_t event, void *data, + struct lxc_epoll_descr *descr); + +struct mainloop_handler { + lxc_mainloop_callback_t callback; + int fd; + void *data; +}; + +#define MAX_EVENTS 10 + +int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms) +{ + int i, nfds, ret; + struct mainloop_handler *handler; + struct epoll_event events[MAX_EVENTS]; + + for (;;) { + nfds = epoll_wait(descr->epfd, events, MAX_EVENTS, timeout_ms); + if (nfds < 0) { + if (errno == EINTR) + continue; + + return -1; + } + + for (i = 0; i < nfds; i++) { + handler = events[i].data.ptr; + + /* If the handler returns a positive value, exit the + * mainloop. + */ + ret = handler->callback(handler->fd, events[i].events, + handler->data, descr); + if (ret == LXC_MAINLOOP_CLOSE) + return 0; + } + + if (nfds == 0) + return 0; + + if (lxc_list_empty(&descr->handlers)) + return 0; + } +} + +int lxc_mainloop_open(struct lxc_epoll_descr *descr) +{ + /* hint value passed to epoll create */ + descr->epfd = epoll_create1(EPOLL_CLOEXEC); + if (descr->epfd < 0) + return -1; + + lxc_list_init(&descr->handlers); + return 0; +} + +int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd, + lxc_mainloop_callback_t callback, void *data) +{ + struct epoll_event ev; + struct mainloop_handler *handler; + struct lxc_list *item; + + handler = malloc(sizeof(*handler)); + if (!handler) + return -1; + + handler->callback = callback; + handler->fd = fd; + handler->data = data; + + ev.events = EPOLLIN; + ev.data.ptr = handler; + + if (epoll_ctl(descr->epfd, EPOLL_CTL_ADD, fd, &ev) < 0) + goto out_free_handler; + + item = malloc(sizeof(*item)); + if (!item) + goto out_free_handler; + + item->elem = handler; + lxc_list_add(&descr->handlers, item); + return 0; + +out_free_handler: + free(handler); + return -1; +} + +int lxc_mainloop_close(struct lxc_epoll_descr *descr) +{ + struct lxc_list *iterator, *next; + + iterator = descr->handlers.next; + while (iterator != &descr->handlers) { + next = iterator->next; + + lxc_list_del(iterator); + free(iterator->elem); + free(iterator); + iterator = next; + } + + if (descr->epfd >= 0) + return close(descr->epfd); + + return 0; +} + +static int stdin_handler(int fd, uint32_t events, void *data, + struct lxc_epoll_descr *descr) +{ + char *in_char = data; + + if (events & EPOLLIN) { + int rc; + + rc = read(fd, in_char, sizeof(*in_char)); + if (rc <= 0) + *in_char = '\0'; + } + + if (events & EPOLLHUP) + *in_char = 'q'; + return 1; +} + int main(int argc, char *argv[]) { struct lxc_epoll_descr descr;