// SPDX-License-Identifier: GPL-2.0
/* procacct.c
 *
 * Demonstrator of fetching resource data on task exit, as a way
 * to accumulate accurate program resource usage statistics, without
 * prior identification of the programs. For that, the fields for
 * device and inode of the program executable binary file are also
 * extracted in addition to the command string.
 *
 * The TGID together with the PID and the AGROUP flag allow
 * identification of threads in a process and single-threaded processes.
 * The ac_tgetime field gives proper whole-process walltime.
 *
 * Written (changed) by Thomas Orgis, University of Hamburg in 2022
 *
 * This is a cheap derivation (inheriting the style) of getdelays.c:
 *
 * Utility to get per-pid and per-tgid delay accounting statistics
 * Also illustrates usage of the taskstats interface
 *
 * Copyright (C) Shailabh Nagar, IBM Corp. 2005
 * Copyright (C) Balbir Singh, IBM Corp. 2006
 * Copyright (c) Jay Lan, SGI. 2006
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <poll.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>

#include <linux/genetlink.h>
#include <linux/acct.h>
#include <linux/taskstats.h>
#include <linux/kdev_t.h>

/*
 * Generic macros for dealing with netlink sockets. Might be duplicated
 * elsewhere. It is recommended that commercial grade applications use
 * libnl or libnetlink and use the interfaces provided by the library
 */
#define GENLMSG_DATA(glh)	((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
#define GENLMSG_PAYLOAD(glh)	(NLMSG_PAYLOAD(glh, 0) - GENL_HDRLEN)
#define NLA_DATA(na)		((void *)((char *)(na) + NLA_HDRLEN))
#define NLA_PAYLOAD(len)	(len - NLA_HDRLEN)

#define err(code, fmt, arg...)			\
	do {					\
		fprintf(stderr, fmt, ##arg);	\
		exit(code);			\
	} while (0)

int rcvbufsz;
char name[100];
int dbg;
int print_delays;
int print_io_accounting;
int print_task_context_switch_counts;

#define PRINTF(fmt, arg...) {			\
		if (dbg) {			\
			printf(fmt, ##arg);	\
		}				\
	}

/* Maximum size of response requested or message sent */
#define MAX_MSG_SIZE	2048
/* Maximum number of cpus expected to be specified in a cpumask */
#define MAX_CPUS	32

struct msgtemplate {
	struct nlmsghdr n;
	struct genlmsghdr g;
	char buf[MAX_MSG_SIZE];
};

char cpumask[100+6*MAX_CPUS];

static void usage(void)
{
	fprintf(stderr, "procacct [-v] [-w logfile] [-r bufsize] [-m cpumask]\n");
	fprintf(stderr, "  -v: debug on\n");
}

/*
 * Create a raw netlink socket and bind
 */
static int create_nl_socket(int protocol)
{
	int fd;
	struct sockaddr_nl local;

	fd = socket(AF_NETLINK, SOCK_RAW, protocol);
	if (fd < 0)
		return -1;

	if (rcvbufsz)
		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
				&rcvbufsz, sizeof(rcvbufsz)) < 0) {
			fprintf(stderr, "Unable to set socket rcv buf size to %d\n",
				rcvbufsz);
			goto error;
		}

	memset(&local, 0, sizeof(local));
	local.nl_family = AF_NETLINK;

	if (bind(fd, (struct sockaddr *) &local, sizeof(local)) < 0)
		goto error;

	return fd;
error:
	close(fd);
	return -1;
}

static int recv_taskstats_msg(int sd, struct msgtemplate *msg)
{
	struct sockaddr_nl nladdr;
	struct iovec iov = {
		.iov_base = msg,
		.iov_len = sizeof(*msg),
	};
	struct msghdr hdr = {
		.msg_name = &nladdr,
		.msg_namelen = sizeof(nladdr),
		.msg_iov = &iov,
		.msg_iovlen = 1,
	};
	int ret;

	ret = recvmsg(sd, &hdr, 0);
	if (ret < 0)
		return -1;
	if (hdr.msg_flags & MSG_TRUNC) {
		errno = EMSGSIZE;
		return -1;
	}

	return ret;
}


static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
	     __u8 genl_cmd, __u16 nla_type,
	     void *nla_data, int nla_len)
{
	struct nlattr *na;
	struct sockaddr_nl nladdr;
	int r, buflen;
	char *buf;

	struct msgtemplate msg;

	msg.n.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
	msg.n.nlmsg_type = nlmsg_type;
	msg.n.nlmsg_flags = NLM_F_REQUEST;
	msg.n.nlmsg_seq = 0;
	msg.n.nlmsg_pid = nlmsg_pid;
	msg.g.cmd = genl_cmd;
	msg.g.version = 0x1;
	na = (struct nlattr *) GENLMSG_DATA(&msg);
	na->nla_type = nla_type;
	na->nla_len = nla_len + 1 + NLA_HDRLEN;
	memcpy(NLA_DATA(na), nla_data, nla_len);
	msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len);

	buf = (char *) &msg;
	buflen = msg.n.nlmsg_len;
	memset(&nladdr, 0, sizeof(nladdr));
	nladdr.nl_family = AF_NETLINK;
	while ((r = sendto(sd, buf, buflen, 0, (struct sockaddr *) &nladdr,
			   sizeof(nladdr))) < buflen) {
		if (r > 0) {
			buf += r;
			buflen -= r;
		} else if (errno != EAGAIN)
			return -1;
	}
	return 0;
}


/*
 * Probe the controller in genetlink to find the family id
 * for the TASKSTATS family
 */
static int get_family_id(int sd)
{
	struct {
		struct nlmsghdr n;
		struct genlmsghdr g;
		char buf[256];
	} ans;

	int id = 0, rc;
	struct nlattr *na;
	int rep_len;

	strcpy(name, TASKSTATS_GENL_NAME);
	rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
			CTRL_ATTR_FAMILY_NAME, (void *)name,
			strlen(TASKSTATS_GENL_NAME)+1);
	if (rc < 0)
		return 0;	/* sendto() failure? */

	rep_len = recv(sd, &ans, sizeof(ans), 0);
	if (ans.n.nlmsg_type == NLMSG_ERROR ||
	    (rep_len < 0) || !NLMSG_OK((&ans.n), rep_len))
		return 0;

	na = (struct nlattr *) GENLMSG_DATA(&ans);
	na = (struct nlattr *) ((char *) na + NLA_ALIGN(na->nla_len));
	if (na->nla_type == CTRL_ATTR_FAMILY_ID)
		id = *(__u16 *) NLA_DATA(na);

	return id;
}

#define average_ms(t, c) (t / 1000000ULL / (c ? c : 1))

static void print_procacct(struct taskstats *t)
{
	/* First letter: T is a mere thread, G the last in a group, U  unknown. */
	printf(
		"%c pid=%lu tgid=%lu uid=%lu wall=%llu gwall=%llu cpu=%llu vmpeak=%llu rsspeak=%llu dev=%lu:%lu inode=%llu comm=%s\n"
	,	t->version >= 12 ? (t->ac_flag & AGROUP ? 'P' : 'T') : '?'
	,	(unsigned long)t->ac_pid
	,	(unsigned long)(t->version >= 12 ? t->ac_tgid : 0)
	,	(unsigned long)t->ac_uid
	,	(unsigned long long)t->ac_etime
	,	(unsigned long long)(t->version >= 12 ? t->ac_tgetime : 0)
	,	(unsigned long long)(t->ac_utime+t->ac_stime)
	,	(unsigned long long)t->hiwater_vm
	,	(unsigned long long)t->hiwater_rss
	,	(unsigned long)(t->version >= 12 ? MAJOR(t->ac_exe_dev) : 0)
	,	(unsigned long)(t->version >= 12 ? MINOR(t->ac_exe_dev) : 0)
	,	(unsigned long long)(t->version >= 12 ? t->ac_exe_inode : 0)
	,	t->ac_comm
	);
}

void handle_aggr(int mother, struct nlattr *na, int fd)
{
	int aggr_len = NLA_PAYLOAD(na->nla_len);
	int len2 = 0;
	pid_t rtid = 0;

	na = (struct nlattr *) NLA_DATA(na);
	while (len2 < aggr_len) {
		switch (na->nla_type) {
		case TASKSTATS_TYPE_PID:
			rtid = *(int *) NLA_DATA(na);
			PRINTF("PID\t%d\n", rtid);
			break;
		case TASKSTATS_TYPE_TGID:
			rtid = *(int *) NLA_DATA(na);
			PRINTF("TGID\t%d\n", rtid);
			break;
		case TASKSTATS_TYPE_STATS:
			PRINTF("version %u\n",
			       ((struct taskstats *)NLA_DATA(na))->version);
			if (mother == TASKSTATS_TYPE_AGGR_PID)
				print_procacct((struct taskstats *) NLA_DATA(na));
			if (fd) {
				if (write(fd, NLA_DATA(na), na->nla_len) < 0)
					err(1, "write error\n");
			}
			break;
		case TASKSTATS_TYPE_NULL:
			break;
		default:
			fprintf(stderr, "Unknown nested nla_type %d\n",
				na->nla_type);
			break;
		}
		len2 += NLA_ALIGN(na->nla_len);
		na = (struct nlattr *)((char *)na +
						 NLA_ALIGN(na->nla_len));
	}
}

int main(int argc, char *argv[])
{
	int c, rc, rep_len;
	__u16 id;
	__u32 mypid;

	struct nlattr *na;
	int nl_sd = -1;
	int len = 0;

	int fd = 0;
	int write_file = 0;
	int maskset = 0;
	char *logfile = NULL;
	int cfd = 0;

	struct msgtemplate msg;

	while (1) {
		c = getopt(argc, argv, "m:vr:w:");
		if (c < 0)
			break;

		switch (c) {
		case 'w':
			logfile = strdup(optarg);
			printf("write to file %s\n", logfile);
			write_file = 1;
			break;
		case 'r':
			rcvbufsz = atoi(optarg);
			printf("receive buf size %d\n", rcvbufsz);
			if (rcvbufsz < 0)
				err(1, "Invalid rcv buf size\n");
			break;
		case 'm':
			strncpy(cpumask, optarg, sizeof(cpumask));
			cpumask[sizeof(cpumask) - 1] = '\0';
			maskset = 1;
			break;
		case 'v':
			printf("debug on\n");
			dbg = 1;
			break;
		default:
			usage();
			exit(-1);
		}
	}
	if (!maskset) {
		maskset = 1;
		strncpy(cpumask, "1", sizeof(cpumask));
		cpumask[sizeof(cpumask) - 1] = '\0';
	}
	printf("cpumask %s maskset %d\n", cpumask, maskset);

	if (write_file) {
		fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
		if (fd == -1) {
			perror("Cannot open output file\n");
			exit(1);
		}
	}

	nl_sd = create_nl_socket(NETLINK_GENERIC);
	if (nl_sd < 0)
		err(1, "error creating Netlink socket\n");

	mypid = getpid();
	id = get_family_id(nl_sd);
	if (!id) {
		fprintf(stderr, "Error getting family id, errno %d\n", errno);
		goto err;
	}
	PRINTF("family id %d\n", id);

	if (maskset) {
		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
			      TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
			      &cpumask, strlen(cpumask) + 1);
		PRINTF("Sent register cpumask, retval %d\n", rc);
		if (rc < 0) {
			fprintf(stderr, "error sending register cpumask\n");
			goto err;
		}
	}

	do {
		rep_len = recv_taskstats_msg(nl_sd, &msg);
		PRINTF("received %d bytes\n", rep_len);

		if (rep_len < 0) {
			if (errno == EMSGSIZE)
				fprintf(stderr,
					"dropped truncated taskstats netlink message, please increase MAX_MSG_SIZE\n");
			else
				fprintf(stderr, "nonfatal reply error: errno %d\n",
					errno);
			continue;
		}
		if (msg.n.nlmsg_type == NLMSG_ERROR ||
		    !NLMSG_OK((&msg.n), rep_len)) {
			struct nlmsgerr *err = NLMSG_DATA(&msg);

			fprintf(stderr, "fatal reply error,  errno %d\n",
				err->error);
			goto done;
		}

		PRINTF("nlmsghdr size=%zu, nlmsg_len=%d, rep_len=%d\n",
		       sizeof(struct nlmsghdr), msg.n.nlmsg_len, rep_len);


		rep_len = GENLMSG_PAYLOAD(&msg.n);

		na = (struct nlattr *) GENLMSG_DATA(&msg);
		len = 0;
		while (len < rep_len) {
			len += NLA_ALIGN(na->nla_len);
			int mother = na->nla_type;

			PRINTF("mother=%i\n", mother);
			switch (na->nla_type) {
			case TASKSTATS_TYPE_AGGR_PID:
			case TASKSTATS_TYPE_AGGR_TGID:
				/* For nested attributes, na follows */
				handle_aggr(mother, na, fd);
				break;
			default:
				fprintf(stderr, "Unexpected nla_type %d\n",
					na->nla_type);
			case TASKSTATS_TYPE_NULL:
				break;
			}
			na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
		}
	} while (1);
done:
	if (maskset) {
		rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET,
			      TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
			      &cpumask, strlen(cpumask) + 1);
		printf("Sent deregister mask, retval %d\n", rc);
		if (rc < 0)
			err(rc, "error sending deregister cpumask\n");
	}
err:
	close(nl_sd);
	if (fd)
		close(fd);
	if (cfd)
		close(cfd);
	return 0;
}
