[PMQA] cpuhotplug: add method to check uevents in userspace

Message ID 1397374194-7612-1-git-send-email-sanjay.rawat@linaro.org
State New
Headers show

Commit Message

Sanjay Singh Rawat April 13, 2014, 7:29 a.m.
- This util reads the NETLINK socket to receive messages from the kernel.
  For both ubuntu and android uevent_reader can be used to receive events.
- bug : 1304251

Signed-off-by: Sanjay Singh Rawat <sanjay.rawat@linaro.org>
---
 Test.mk                     |    7 +++--
 cpuhotplug/cpuhotplug_07.sh |   21 ++++---------
 utils/Android.mk            |    2 +-
 utils/uevent_reader.c       |   69 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 80 insertions(+), 19 deletions(-)
 create mode 100644 utils/uevent_reader.c

Patch hide | download patch | download mbox

diff --git a/Test.mk b/Test.mk
index 19d7346..7c2e0e0 100644
--- a/Test.mk
+++ b/Test.mk
@@ -20,7 +20,7 @@ 
 # Contributors:
 #     Daniel Lezcano <daniel.lezcano@linaro.org> (IBM Corporation)
 #       - initial API and implementation
-#
+
 SNT=$(wildcard *sanity.sh)
 TST=$(wildcard *[^(sanity)].sh)
 LOG=$(TST:.sh=.log)
@@ -29,7 +29,10 @@  CC?=gcc
 SRC=$(wildcard *.c)
 EXEC=$(SRC:%.c=%)
 
-check: run_tests
+check: build_utils run_tests
+
+build_utils:
+	gcc ../utils/uevent_reader.c -o ../utils/uevent_reader
 
 SANITY_STATUS:= $(shell if test $(SNT) && test -f $(SNT); then \
 		./$(SNT); if test "$$?" -eq 0; then echo 0; else \
diff --git a/cpuhotplug/cpuhotplug_07.sh b/cpuhotplug/cpuhotplug_07.sh
index d3674d2..eaeba77 100755
--- a/cpuhotplug/cpuhotplug_07.sh
+++ b/cpuhotplug/cpuhotplug_07.sh
@@ -28,17 +28,6 @@ 
 source ../include/functions.sh
 TMPFILE=cpuhotplug_07.tmp
 
-waitfor_udevadm() {
-    while [ 1 ]; do
-        lsof | grep udevadm | grep 'sock\|netlink' > /dev/null
-        if [ $? -eq 0 ]; then
-             return 0
-        fi
-	log_skip "warning: udev monitor not running"
-    done
-    return 1
-}
-
 check_notification() {
     local cpu=$1
     local cpuid=${cpu:3}
@@ -52,9 +41,9 @@  check_notification() {
     # damn ! udevadm is buffering the output, we have to use a temp file
     # to retrieve the output
     rm -f $TMPFILE
-    udevadm monitor --kernel --subsystem-match=cpu > $TMPFILE &
+    ../utils/uevent_reader $TMPFILE &
     pid=$!
-    waitfor_udevadm
+    sleep 1
 
     set_offline $cpu
     set_online $cpu
@@ -62,13 +51,13 @@  check_notification() {
     # let the time the notification to reach userspace
     # and buffered in the file
     sleep 1
-    kill $pid
+    kill -s INT $pid
 
-    grep "offline" $TMPFILE | grep -q "/devices/system/cpu/$cpu"
+    grep "offline@/devices/system/cpu/$cpu" $TMPFILE
     ret=$?
     check "offline event was received" "test $ret -eq 0"
 
-    grep "online" $TMPFILE | grep -q "/devices/system/cpu/$cpu"
+    grep "online@/devices/system/cpu/$cpu" $TMPFILE
     ret=$?
     check "online event was received" "test $ret -eq 0"
 
diff --git a/utils/Android.mk b/utils/Android.mk
index b49fa45..8c9c644 100644
--- a/utils/Android.mk
+++ b/utils/Android.mk
@@ -14,5 +14,5 @@  define $(module_name)_etc_add_executable
     include $(BUILD_EXECUTABLE)
 endef
 
-test_names := cpuburn cpucycle heat_cpu nanosleep
+test_names := cpuburn cpucycle heat_cpu nanosleep uevent_reader
 $(foreach item,$(test_names),$(eval $(call $(module_name)_etc_add_executable, $(item))))
diff --git a/utils/uevent_reader.c b/utils/uevent_reader.c
new file mode 100644
index 0000000..afbb426
--- /dev/null
+++ b/utils/uevent_reader.c
@@ -0,0 +1,69 @@ 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+FILE *fp;
+
+void exit_handler()
+{
+	fprintf(stdout, "exiting from uevent reader...\n");
+	fclose(fp);
+}
+
+int main(int argc, char *argv[])
+{
+	struct sockaddr_nl nls;
+	struct pollfd pfd;
+	char buf[512];
+
+	fp = fopen(argv[1], "w+");
+	if (fp == NULL) {
+		fprintf(stderr, "Can't open input file\n");
+		exit(1);
+	}
+
+	signal(SIGINT, exit_handler);
+
+	/* bind to uevent netlink socket */
+	memset(&nls, 0, sizeof(struct sockaddr_nl));
+	nls.nl_family = AF_NETLINK;
+	nls.nl_pid = getpid();
+	nls.nl_groups = -1;
+
+	pfd.events = POLLIN;
+	pfd.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+	if (pfd.fd == -1) {
+		perror("error: socket()");
+		exit_handler();
+	}
+
+	if (bind(pfd.fd, (struct sockaddr *) &nls,
+				sizeof(struct sockaddr_nl))) {
+		perror("error : bind()");
+		exit_handler();
+	}
+
+	while (-1 != poll(&pfd, 1, -1)) {
+		int i, len = recv(pfd.fd, buf, sizeof(buf), MSG_DONTWAIT);
+		if (len == -1) {
+			perror("error : recv()");
+			exit_handler();
+		}
+
+		i = 0;
+		while (i < len) {
+			fprintf(fp, "%s\n", buf+i);
+			i += strlen(buf+i)+1;
+		}
+	}
+
+	return 0;
+}