summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2022-01-28 17:32:18 +0100
committerLeah Neukirchen <leah@vuxu.org>2022-01-28 17:32:18 +0100
commit15f4656aeff6ca2f373b5e4e019da59f841caf83 (patch)
treeab4fc979117886cd8c7cabd86e4dbd968a9fb650
parent9114ff00c92459958b2319d56ff0bd36c60e5ccb (diff)
downloadrvnit-log-socket.tar.gz
rvnit-log-socket.tar.xz
rvnit-log-socket.zip
broken, wip log-socket
-rw-r--r--rvnit.c102
1 files changed, 85 insertions, 17 deletions
diff --git a/rvnit.c b/rvnit.c
index 345603b..0b65434 100644
--- a/rvnit.c
+++ b/rvnit.c
@@ -28,7 +28,7 @@
 #define MAX_SV 512
 
 // ## not truly portable :/
-#define LOG(fmt, ...) dprintf(selflogfd[1], fmt "\n", ## __VA_ARGS__);
+#define LOG(fmt, ...) dprintf(logsocks[1], fmt "\n", ## __VA_ARGS__);
 
 enum {
 	UNDEF,
@@ -61,6 +61,7 @@ pthread_t logger_thread;
 int selflogfd[2];
 int newlogfd[2];
 int globallogfd[2];
+int logsocks[2];
 int nullfd;
 
 int pid1;
@@ -108,13 +109,16 @@ restart(int i)
 	LOG("start %s", services[i].name);
 
 	if (services[i].logfd[0] == -1) {
-		pipe(services[i].logfd);
-		fcntl(services[i].logfd[0], F_SETFL, O_NONBLOCK);
-		fcntl(services[i].logfd[0], F_SETFD, FD_CLOEXEC);
-		fcntl(services[i].logfd[1], F_SETFD, FD_CLOEXEC);
-		write(newlogfd[1], "!", 1);
+//		pipe(services[i].logfd);
+//		fcntl(services[i].logfd[0], F_SETFL, O_NONBLOCK);
+//		fcntl(services[i].logfd[0], F_SETFD, FD_CLOEXEC);
+//		fcntl(services[i].logfd[1], F_SETFD, FD_CLOEXEC);
+//		write(newlogfd[1], "!", 1);
+//		services[i].logfd[0] = globallogfd[0];
+//		services[i].logfd[1] = globallogfd[1];
 	}
 
+#if 0
 	if (services[i].name[2] == 'L') {
 		for (int j = 0; j < MAX_SV; j++) {
 			if (strcmp(services[i].name + 3,
@@ -137,6 +141,7 @@ restart(int i)
 			}
 		}
 	}
+#endif
 
 	if (services[i].name[2] == 'G') {
 		// enable global logger
@@ -164,7 +169,7 @@ restart(int i)
 			dup2(2, 1);
 		} else {
 			// pass write end of logger pipe to capture stdout
-			dup2(services[i].logfd[1], 1);
+			dup2(logsocks[1], 1);
 		}
 		sleep(delay);
 		setsid();
@@ -351,6 +356,52 @@ socket_loop(void* ignored)
 	return 0;
 }
 
+ssize_t read_with_pid(int fd, void *buf, size_t count, pid_t *pid)
+{
+	struct msghdr msgh;
+	msgh.msg_name = NULL;
+	msgh.msg_namelen = 0;
+
+	struct iovec iov;
+	msgh.msg_iov = &iov;
+	msgh.msg_iovlen = 1;
+	iov.iov_base = buf;
+	iov.iov_len = count;
+
+	union {
+		char   buf[CMSG_SPACE(sizeof(struct ucred))];
+		/* Space large enough to hold a 'ucred' structure */
+		struct cmsghdr align;
+	} controlMsg;
+
+	msgh.msg_control = controlMsg.buf;
+	msgh.msg_controllen = sizeof(controlMsg.buf);
+
+	ssize_t nr = recvmsg(fd, &msgh, 0);
+	if (nr < 0 && errno == ENOTSOCK) {
+		*pid = 0;
+		return read(fd, buf, count);
+	}
+
+	struct cmsghdr *cmsgp = CMSG_FIRSTHDR(&msgh);
+
+	if (cmsgp == NULL || cmsgp->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
+		return -1;
+	if (cmsgp->cmsg_level != SOL_SOCKET)
+		return -1;
+	if (cmsgp->cmsg_type != SCM_CREDENTIALS)
+		return -1;
+
+	struct ucred rcred;
+	memcpy(&rcred, CMSG_DATA(cmsgp), sizeof(struct ucred));
+
+	printf("Received credentials pid=%ld, uid=%ld, gid=%ld\n",
+	    (long) rcred.pid, (long) rcred.uid, (long) rcred.gid);
+
+	*pid = rcred.pid;
+	return nr;
+}
+
 void *
 logger_loop(void* ignored)
 {
@@ -368,6 +419,7 @@ logger_loop(void* ignored)
 		fds[nfds].events = POLLIN;
 		nfds++;
 
+#if 0
 		pthread_mutex_lock(&services_lock);
 		for (int i = 0; i < MAX_SV; i++) {
 			if (!services[i].logged && services[i].logfd[0] > 0) {
@@ -377,6 +429,11 @@ logger_loop(void* ignored)
 			}
 		}
 		pthread_mutex_unlock(&services_lock);
+#endif
+
+		fds[nfds].fd = globallogfd[1];
+		fds[nfds].events = POLLIN;
+		nfds++;
 
 		int n = poll(fds, nfds, -1);
 		if (n < 0) {
@@ -400,7 +457,7 @@ logger_loop(void* ignored)
 
 		for (nfds_t j = 0; j < nfds; j++) {
 			if (fds[j].revents & POLLNVAL) {
-				dprintf(2, "invalid fd %d\n", fds[j].revents);
+				dprintf(2, "invalid fd %d\n", fds[j].fd);
 				continue;
 			}
 
@@ -430,12 +487,15 @@ logger_loop(void* ignored)
 			    "%Y-%m-%dT%H:%M:%S", gmtime(&now.tv_sec));
 
 			char buf[4096];
-			ssize_t rd = read(fds[j].fd, buf, sizeof buf);
+			pid_t pid = -1;
+			ssize_t rd = read_with_pid(fds[j].fd,
+			    buf, sizeof buf, &pid);
 			if (rd < 0) {
-				perror("rvnit: read");
+				perror("rvnit: read_with_pid");
 				continue;
 			}
 
+#if 0
 			if (rd < (int)sizeof buf && buf[rd - 1] != '\n') {
 				// sometimes processes use multiple write calls
 				// for one line, give them 25msec to do try to
@@ -445,9 +505,9 @@ logger_loop(void* ignored)
 				if (rd2 > 0)
 					rd += rd2;
 			}
+#endif
 
 			const char *sv = "<unknown>";
-			long pid = -1;
 			int pass_thru = 0;
 
 			if (fds[j].fd == selflogfd[0]) {
@@ -457,9 +517,8 @@ logger_loop(void* ignored)
 			} else {
 				pthread_mutex_lock(&services_lock);
 				for (int i = 0; i < MAX_SV; i++) {
-					if (services[i].logfd[0] == fds[j].fd) {
+					if (services[i].display_pid == pid) {
 						sv = services[i].name;
-						pid = services[i].display_pid;
 						break;
 					}
 				}
@@ -476,7 +535,7 @@ logger_loop(void* ignored)
 				int r = dprintf(globallogfd[1],
 				    "%s.%05ld %s[%ld]: %.*s\n",
 				    timestamp, now.tv_nsec / 10000,
-				    sv, pid, (int)(eol - s), s);
+				    sv, (long)pid, (int)(eol - s), s);
 				if (!use_global_log || pass_thru || r < 0) {
 					/* print own messages, and messages
 					   during boot/shutdown, or when writing
@@ -485,7 +544,7 @@ logger_loop(void* ignored)
 					   stall here) */
 					dprintf(2, "%s.%05ld %s[%ld]: %.*s\n",
 					    timestamp, now.tv_nsec / 10000,
-					    sv, pid, (int)(eol - s), s);
+					    sv, (long)pid, (int)(eol - s), s);
 				}
 
 				s = eol + 1;
@@ -713,12 +772,21 @@ main(int argc, char *argv[])
 	fcntl(newlogfd[0], F_SETFD, FD_CLOEXEC);
 	fcntl(newlogfd[1], F_SETFD, FD_CLOEXEC);
 
-	pipe(globallogfd);
+        pipe(globallogfd);
 	// don't care about read end
 	fcntl(globallogfd[1], F_SETFL, O_NONBLOCK);
 	fcntl(globallogfd[0], F_SETFD, FD_CLOEXEC);
 	fcntl(globallogfd[1], F_SETFD, FD_CLOEXEC);
 
+	socketpair(AF_UNIX, SOCK_STREAM, 0, logsocks);
+	int optval = 1;
+	setsockopt(logsocks[0], SOL_SOCKET, SO_PASSCRED, &optval, sizeof optval);
+	setsockopt(logsocks[1], SOL_SOCKET, SO_PASSCRED, &optval, sizeof optval);
+	// don't care about write end
+	fcntl(logsocks[0], F_SETFL, O_NONBLOCK);
+	fcntl(logsocks[0], F_SETFD, FD_CLOEXEC);
+	fcntl(logsocks[1], F_SETFD, FD_CLOEXEC);
+
 	LOG("booting");
 
 	pid1 = real_pid1 = (getpid() == 1);
@@ -1096,7 +1164,7 @@ cont4:
 	else
 		dprintf(selflogfd[1], "shutdown\n");
 
-	close(globallogfd[1]);
+//	close(globallogfd[1]);
 
 	close(selflogfd[1]);
 	pthread_join(logger_thread, 0);