Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* Copyright (c) 2015-2017 Daniel Borkmann */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) /* Copyright (c) 2018 Netronome Systems, Inc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <sys/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <sys/vfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "main.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #ifndef TRACEFS_MAGIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) # define TRACEFS_MAGIC	0x74726163
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define _textify(x)	#x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define textify(x)	_textify(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) FILE *trace_pipe_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) char *buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static int validate_tracefs_mnt(const char *mnt, unsigned long magic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	struct statfs st_fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	if (statfs(mnt, &st_fs) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	if ((unsigned long)st_fs.f_type != magic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) find_tracefs_mnt_single(unsigned long magic, char *mnt, const char *mntpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	size_t src_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	if (validate_tracefs_mnt(mntpt, magic))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	src_len = strlen(mntpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	if (src_len + 1 >= PATH_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		p_err("tracefs mount point name too long");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	strcpy(mnt, mntpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static bool get_tracefs_pipe(char *mnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	static const char * const known_mnts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		"/sys/kernel/debug/tracing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		"/sys/kernel/tracing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		"/tracing",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		"/trace",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	const char *pipe_name = "/trace_pipe";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	const char *fstype = "tracefs";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	char type[100], format[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	const char * const *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	FILE *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	for (ptr = known_mnts; ptr < known_mnts + ARRAY_SIZE(known_mnts); ptr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		if (find_tracefs_mnt_single(TRACEFS_MAGIC, mnt, *ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			goto exit_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	fp = fopen("/proc/mounts", "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	if (!fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	/* Allow room for NULL terminating byte and pipe file name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	snprintf(format, sizeof(format), "%%*s %%%zds %%99s %%*s %%*d %%*d\\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		 PATH_MAX - strlen(pipe_name) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	while (fscanf(fp, format, mnt, type) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		if (strcmp(type, fstype) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	fclose(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	/* The string from fscanf() might be truncated, check mnt is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (found && validate_tracefs_mnt(mnt, TRACEFS_MAGIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		goto exit_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (block_mount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	p_info("could not find tracefs, attempting to mount it now");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	/* Most of the time, tracefs is automatically mounted by debugfs at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	 * /sys/kernel/debug/tracing when we try to access it. If we could not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	 * find it, it is likely that debugfs is not mounted. Let's give one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	 * attempt at mounting just tracefs at /sys/kernel/tracing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	strcpy(mnt, known_mnts[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	if (mount_tracefs(mnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) exit_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	strcat(mnt, pipe_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void exit_tracelog(int signum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	fclose(trace_pipe_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	free(buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (json_output) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		jsonw_end_array(json_wtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		jsonw_destroy(&json_wtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int do_tracelog(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	const struct sigaction act = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		.sa_handler = exit_tracelog
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	char trace_pipe[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	size_t buff_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (json_output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		jsonw_start_array(json_wtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (!get_tracefs_pipe(trace_pipe))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	trace_pipe_fd = fopen(trace_pipe, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	if (!trace_pipe_fd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		p_err("could not open trace pipe: %s", strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	sigaction(SIGHUP, &act, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	sigaction(SIGINT, &act, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	sigaction(SIGTERM, &act, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		ret = getline(&buff, &buff_len, trace_pipe_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		if (ret <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			p_err("failed to read content from trace pipe: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			      strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		if (json_output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			jsonw_string(json_wtr, buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			printf("%s", buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	fclose(trace_pipe_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	free(buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }