From: Łukasz Stelmach Date: Mon, 10 Jan 2022 21:15:35 +0000 (+0100) Subject: Import and build logger test X-Git-Tag: submit/tizen/20220113.112544^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a4db3fba78e2082e5df125bdcd6226bc6fa0d55f;p=platform%2Fkernel%2Flinux-tizen-modules-source.git Import and build logger test Change-Id: Ibe00dad3ebd319875748c682a614fd517ebc8a4c Signed-off-by: Łukasz Stelmach --- diff --git a/packaging/linux-tizen-modules-source.spec b/packaging/linux-tizen-modules-source.spec index ba359a1..a614f34 100644 --- a/packaging/linux-tizen-modules-source.spec +++ b/packaging/linux-tizen-modules-source.spec @@ -1,5 +1,5 @@ Name: linux-tizen-modules-source -Version: 7.0.4 +Version: 7.0.5 Release: 0 License: GPL-2.0+ Source0: %{name}-%{version}.tar.xz @@ -23,6 +23,7 @@ Summary: Tizen-specific kernel modules tests License: GPL-2.0+ Group: System/Kernel Provides: linux-kernel-kdbus-tests +Provides: linux-kernel-logger-tests BuildRequires: pkgconfig(libcap) %description -n linux-tizen-modules-tests This package contains tests for Tizen-specific kernel modules. @@ -33,10 +34,12 @@ cp %{SOURCE1} . %build make -C tests/kdbus +make -C tests/logger %install mkdir -p %{buildroot}/usr/src/%{name}/kdbus mkdir -p %{buildroot}/%{_includedir}/linux +mkdir -p %{buildroot}/%{_libexecdir}/%{name}/tests/logger-test cp -a include/ %{buildroot}/usr/src/%{name} cp kernel/*.[ch] kernel/Makefile COPYING %{buildroot}/usr/src/%{name} @@ -45,6 +48,7 @@ cp kernel/kdbus/*.[ch] kernel/kdbus/Makefile %{buildroot}/usr/src/%{name}/kdbus cp include/uapi/linux/kdbus.h %{buildroot}/%{_includedir}/linux cp include/uapi/linux/logger.h %{buildroot}/%{_includedir}/linux +cp tests/logger/logger-test %{buildroot}/%{_libexecdir}/%{name}/tests/logger-test cp tests/kdbus/kdbus-test %{buildroot}/%{_libexecdir}/%{name}/tests/kdbus-test %files @@ -67,4 +71,5 @@ cp tests/kdbus/kdbus-test %{buildroot}/%{_libexecdir}/%{name}/tests/kdbus-test %files -n linux-tizen-modules-tests %manifest %{name}.manifest %license COPYING +%{_libexecdir}/%{name}/tests/logger-test %{_libexecdir}/%{name}/tests/kdbus-test diff --git a/tests/logger/.gitignore b/tests/logger/.gitignore new file mode 100644 index 0000000..b1e5ec6 --- /dev/null +++ b/tests/logger/.gitignore @@ -0,0 +1 @@ +logger-test diff --git a/tests/logger/Makefile b/tests/logger/Makefile new file mode 100644 index 0000000..2faf0a7 --- /dev/null +++ b/tests/logger/Makefile @@ -0,0 +1,24 @@ +CC := $(CROSS_COMPILE)gcc +CFLAGS += -I../../include/uapi +CFLAGS += -std=gnu99 +CFLAGS += -D_GNU_SOURCE +LDFLAGS = -pthread + +.PHONY: all clean + +TEST_CUSTOM_PROGS := logger-test +all: $(TEST_CUSTOM_PROGS) + +OBJS = \ + logger.o + +$(TEST_CUSTOM_PROGS): $(OBJS) + $(CC) -o $(TEST_CUSTOM_PROGS) $(OBJS) $(LDFLAGS) + +$(OBJS): %.o: %.c + $(CC) -c $^ -o $@ $(CFLAGS) + +EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(OBJS) + +clean: + $(RM) -r $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) $(EXTRA_CLEAN) diff --git a/tests/logger/logger.c b/tests/logger/logger.c new file mode 100644 index 0000000..bd1637c --- /dev/null +++ b/tests/logger/logger.c @@ -0,0 +1,228 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define handle_error_en(en, msg) \ + do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) + +#define BIT(nr) ((1UL) << (nr)) + +void *tstart(void *arg) +{ + int *fd = arg; + write(*fd, "child thread msg #1\nchild thread msg #2", 39); + return 0; +} + +int dump_logger(const char *device) +{ + int fd; + int ret = 0; + char buf[sizeof(struct logger_entry) + LOGGER_ENTRY_MAX_PAYLOAD]; + struct logger_entry *e = buf; + int version = 2; + + fd = open(device, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + perror("open"); + exit(EXIT_FAILURE); + } + + ret = ioctl(fd, LOGGER_SET_VERSION, &version); + if (ret < 0) { + perror("ioctl(SET_VERSION)"); + exit(EXIT_FAILURE); + } + + while (1) { + int tag_len; + ret = read(fd, buf, sizeof(struct logger_entry) + LOGGER_ENTRY_MAX_PAYLOAD); + if (ret < 0) { + if (errno == EAGAIN) + ret = 0; + else + perror("read"); + break; + } + + if (e->hdr_size != sizeof(struct logger_entry)) { + fprintf(stderr, "%d != %d\n", e->hdr_size, sizeof(struct logger_entry)); + fprintf(stderr, "read: Invalid data\n"); + ret = EXIT_FAILURE; + break; + } + + tag_len = strlen(e->msg + 1) + 2; /* 2: priority, NUL */ + fprintf(stdout, "[%5d.%6d] %s<%u>: %s\n", e->sec, e->nsec / 1000, &e->msg[1], e->msg[0], &e->msg[tag_len]); + }; + + return ret; +} + +int main(int ac, char *av[]) { + + char *device = "/dev/log_main"; + char *msg = "The Foo"; + char *tag = "stdio"; + struct logger_set_tag struct_tag = { + .len = 6, + .ptr = (uintptr_t)tag, + }; + int c, fd, s, ret; + pid_t child; + int dump = 0; + pthread_t tid; + struct iovec vec[3]; + unsigned char prio = 4; + unsigned long test_mask = ~0UL; + + while (1) { + static struct option long_options[] = { + {"priority", required_argument, 0, 'p'}, + {"tag", required_argument, 0, 't'}, + {"test-mask", required_argument, 0, 'm'}, + {"device", required_argument, 0, 'd'}, + {0, 0, 0, 0} + }; + + c = getopt_long(ac, av, "p:t:m:d:D", long_options, NULL); + if (c == -1) + break; + + switch (c) { + case 'p': + prio = (unsigned char) strtol(optarg, NULL, 10); + break; + case 't': + tag = strdup(optarg); + break; + case 'm': + test_mask = (unsigned long) strtol(optarg, NULL, 16); + break; + case 'd': + device = strdup(optarg); + break; + case 'D': + dump = 1; + break; + default: + exit(1); + } + } + + if (dump) + return dump_logger(device); + + setlinebuf(stdout); + fd = open(device, O_WRONLY); + if (fd < 0) { + perror("open"); + exit(EXIT_FAILURE); + } + + if (test_mask & BIT(0)) { + vec[0].iov_base = &prio; + vec[0].iov_len = 1; + vec[1].iov_base = tag; + vec[1].iov_len = strlen(tag) + 1; + vec[2].iov_base = msg; + vec[2].iov_len = strlen(msg) + 1; + + writev(fd, vec, 3); + if (test_mask & BIT(1)) { + msg = "line #1\nline #2"; + vec[2].iov_base = msg; + vec[2].iov_len = strlen(msg) + 1; + + writev(fd, vec, 3); + } + } + + ret = ioctl(fd, LOGGER_SET_PRIO, prio); + if (ret < 0) { + perror("ioctl(SET_PRIO)"); + exit(EXIT_FAILURE); + } + ret = ioctl(fd, LOGGER_SET_TAG, &struct_tag); + if (ret < 0) { + perror("ioctl(SET_TAG)"); + exit(EXIT_FAILURE); + } + + if (test_mask & BIT(2)) { + int count; + count = write(fd, "The Foo From STDIO\n", 19); + if (count != 19) + fprintf(stderr, "%d != 19\n", count); + + write(fd, "LINE #1\nLINE #2", 15); + write(fd, " CONTINUED\nONCE", 15); + write(fd, " AGAIN\n", 7); + } + + if (test_mask & BIT(3)) { + msg = malloc(8000); + if (!msg) + return 1; + + for (int i = 0; i < 8000; i++) + msg[i] = '!' + (i % 95); + msg[7996] = 'E'; + msg[7997] = 'O'; + msg[7998] = 'F'; + msg[7999] = '\n'; + write(fd, msg, 8000); + + for (int i = 0; (test_mask & BIT(4)) && i < 40; i++) + write(fd, msg, 8000); + + for (int i = 0; (test_mask & BIT(5)) && i < 8000; i++) + write(fd, &msg[i], 1); + + free(msg); + msg = NULL; + } + + if (test_mask & BIT(6)) { + child = fork(); + if (child < 0) { + return -1; + } else if (child == 0) { + sleep(1); + printf("child: %d\n", getpid()); + write(fd, "child 1\n", 8); + sleep(1); + write(fd, "child 2\n", 8); + close(fd); + return 0; + } + write(fd, "PARENT\n", 7); + printf("PARENT: %d\n", getpid()); + wait(&s); + } + + if (test_mask & BIT(7)) { + s = pthread_create(&tid, NULL, &tstart, &fd); + if (s != 0) + handle_error_en(s, "pthread_create"); + sleep(1); + write(fd, "PARENT THREAD\n", 14); + + s = pthread_join(tid, NULL); + if (s != 0) + handle_error_en(s, "pthread_join"); + } + + return 0; +}