1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker
3*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
4*4dc78e53SAndroid Build Coastguard Worker
5*4dc78e53SAndroid Build Coastguard Worker #include <linux/genetlink.h>
6*4dc78e53SAndroid Build Coastguard Worker
7*4dc78e53SAndroid Build Coastguard Worker #include <linux/taskstats.h>
8*4dc78e53SAndroid Build Coastguard Worker
9*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cli/utils.h>
10*4dc78e53SAndroid Build Coastguard Worker
11*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy attr_policy[TASKSTATS_TYPE_MAX+1] = {
12*4dc78e53SAndroid Build Coastguard Worker [TASKSTATS_TYPE_PID] = { .type = NLA_U32 },
13*4dc78e53SAndroid Build Coastguard Worker [TASKSTATS_TYPE_TGID] = { .type = NLA_U32 },
14*4dc78e53SAndroid Build Coastguard Worker [TASKSTATS_TYPE_STATS] = { .minlen = sizeof(struct taskstats) },
15*4dc78e53SAndroid Build Coastguard Worker [TASKSTATS_TYPE_AGGR_PID] = { .type = NLA_NESTED },
16*4dc78e53SAndroid Build Coastguard Worker [TASKSTATS_TYPE_AGGR_TGID] = { .type = NLA_NESTED },
17*4dc78e53SAndroid Build Coastguard Worker };
18*4dc78e53SAndroid Build Coastguard Worker
19*4dc78e53SAndroid Build Coastguard Worker
parse_cmd_new(struct nl_cache_ops * unused,struct genl_cmd * cmd,struct genl_info * info,void * arg)20*4dc78e53SAndroid Build Coastguard Worker static int parse_cmd_new(struct nl_cache_ops *unused, struct genl_cmd *cmd,
21*4dc78e53SAndroid Build Coastguard Worker struct genl_info *info, void *arg)
22*4dc78e53SAndroid Build Coastguard Worker {
23*4dc78e53SAndroid Build Coastguard Worker struct nlattr *attrs[TASKSTATS_TYPE_MAX+1];
24*4dc78e53SAndroid Build Coastguard Worker struct nlattr *nested;
25*4dc78e53SAndroid Build Coastguard Worker int err;
26*4dc78e53SAndroid Build Coastguard Worker
27*4dc78e53SAndroid Build Coastguard Worker if (info->attrs[TASKSTATS_TYPE_AGGR_PID])
28*4dc78e53SAndroid Build Coastguard Worker nested = info->attrs[TASKSTATS_TYPE_AGGR_PID];
29*4dc78e53SAndroid Build Coastguard Worker else if (info->attrs[TASKSTATS_TYPE_AGGR_TGID])
30*4dc78e53SAndroid Build Coastguard Worker nested = info->attrs[TASKSTATS_TYPE_AGGR_TGID];
31*4dc78e53SAndroid Build Coastguard Worker else {
32*4dc78e53SAndroid Build Coastguard Worker fprintf(stderr, "Invalid taskstats message: Unable to find "
33*4dc78e53SAndroid Build Coastguard Worker "nested attribute/\n");
34*4dc78e53SAndroid Build Coastguard Worker return NL_SKIP;
35*4dc78e53SAndroid Build Coastguard Worker }
36*4dc78e53SAndroid Build Coastguard Worker
37*4dc78e53SAndroid Build Coastguard Worker err = nla_parse_nested(attrs, TASKSTATS_TYPE_MAX, nested, attr_policy);
38*4dc78e53SAndroid Build Coastguard Worker if (err < 0) {
39*4dc78e53SAndroid Build Coastguard Worker nl_perror(err, "Error while parsing generic netlink message");
40*4dc78e53SAndroid Build Coastguard Worker return err;
41*4dc78e53SAndroid Build Coastguard Worker }
42*4dc78e53SAndroid Build Coastguard Worker
43*4dc78e53SAndroid Build Coastguard Worker
44*4dc78e53SAndroid Build Coastguard Worker if (attrs[TASKSTATS_TYPE_STATS]) {
45*4dc78e53SAndroid Build Coastguard Worker struct taskstats *stats = nla_data(attrs[TASKSTATS_TYPE_STATS]);
46*4dc78e53SAndroid Build Coastguard Worker
47*4dc78e53SAndroid Build Coastguard Worker printf("%s pid %u uid %u gid %u parent %u\n",
48*4dc78e53SAndroid Build Coastguard Worker stats->ac_comm, stats->ac_pid, stats->ac_uid,
49*4dc78e53SAndroid Build Coastguard Worker stats->ac_gid, stats->ac_ppid);
50*4dc78e53SAndroid Build Coastguard Worker }
51*4dc78e53SAndroid Build Coastguard Worker
52*4dc78e53SAndroid Build Coastguard Worker return 0;
53*4dc78e53SAndroid Build Coastguard Worker }
54*4dc78e53SAndroid Build Coastguard Worker
parse_cb(struct nl_msg * msg,void * arg)55*4dc78e53SAndroid Build Coastguard Worker static int parse_cb(struct nl_msg *msg, void *arg)
56*4dc78e53SAndroid Build Coastguard Worker {
57*4dc78e53SAndroid Build Coastguard Worker return genl_handle_msg(msg, NULL);
58*4dc78e53SAndroid Build Coastguard Worker }
59*4dc78e53SAndroid Build Coastguard Worker
60*4dc78e53SAndroid Build Coastguard Worker static struct genl_cmd cmds[] = {
61*4dc78e53SAndroid Build Coastguard Worker {
62*4dc78e53SAndroid Build Coastguard Worker .c_id = TASKSTATS_CMD_NEW,
63*4dc78e53SAndroid Build Coastguard Worker .c_name = "taskstats_new()",
64*4dc78e53SAndroid Build Coastguard Worker .c_maxattr = TASKSTATS_TYPE_MAX,
65*4dc78e53SAndroid Build Coastguard Worker .c_attr_policy = attr_policy,
66*4dc78e53SAndroid Build Coastguard Worker .c_msg_parser = &parse_cmd_new,
67*4dc78e53SAndroid Build Coastguard Worker },
68*4dc78e53SAndroid Build Coastguard Worker };
69*4dc78e53SAndroid Build Coastguard Worker
70*4dc78e53SAndroid Build Coastguard Worker static struct genl_ops ops = {
71*4dc78e53SAndroid Build Coastguard Worker .o_name = TASKSTATS_GENL_NAME,
72*4dc78e53SAndroid Build Coastguard Worker .o_cmds = cmds,
73*4dc78e53SAndroid Build Coastguard Worker .o_ncmds = ARRAY_SIZE(cmds),
74*4dc78e53SAndroid Build Coastguard Worker };
75*4dc78e53SAndroid Build Coastguard Worker
main(int argc,char * argv[])76*4dc78e53SAndroid Build Coastguard Worker int main(int argc, char *argv[])
77*4dc78e53SAndroid Build Coastguard Worker {
78*4dc78e53SAndroid Build Coastguard Worker struct nl_sock *sock;
79*4dc78e53SAndroid Build Coastguard Worker struct nl_msg *msg;
80*4dc78e53SAndroid Build Coastguard Worker void *hdr;
81*4dc78e53SAndroid Build Coastguard Worker int err;
82*4dc78e53SAndroid Build Coastguard Worker
83*4dc78e53SAndroid Build Coastguard Worker sock = nl_cli_alloc_socket();
84*4dc78e53SAndroid Build Coastguard Worker nl_cli_connect(sock, NETLINK_GENERIC);
85*4dc78e53SAndroid Build Coastguard Worker
86*4dc78e53SAndroid Build Coastguard Worker if ((err = genl_register_family(&ops)) < 0)
87*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(err, "Unable to register Generic Netlink family");
88*4dc78e53SAndroid Build Coastguard Worker
89*4dc78e53SAndroid Build Coastguard Worker if ((err = genl_ops_resolve(sock, &ops)) < 0)
90*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(err, "Unable to resolve family name");
91*4dc78e53SAndroid Build Coastguard Worker
92*4dc78e53SAndroid Build Coastguard Worker if (genl_ctrl_resolve(sock, "nlctrl") != GENL_ID_CTRL)
93*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(NLE_INVAL, "Resolving of \"nlctrl\" failed");
94*4dc78e53SAndroid Build Coastguard Worker
95*4dc78e53SAndroid Build Coastguard Worker msg = nlmsg_alloc();
96*4dc78e53SAndroid Build Coastguard Worker if (msg == NULL)
97*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(NLE_NOMEM, "Unable to allocate netlink message");
98*4dc78e53SAndroid Build Coastguard Worker
99*4dc78e53SAndroid Build Coastguard Worker hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ops.o_id,
100*4dc78e53SAndroid Build Coastguard Worker 0, 0, TASKSTATS_CMD_GET, TASKSTATS_GENL_VERSION);
101*4dc78e53SAndroid Build Coastguard Worker if (hdr == NULL)
102*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(ENOMEM, "Unable to write genl header");
103*4dc78e53SAndroid Build Coastguard Worker
104*4dc78e53SAndroid Build Coastguard Worker if ((err = nla_put_u32(msg, TASKSTATS_CMD_ATTR_PID, 1)) < 0)
105*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(err, "Unable to add attribute: %s", nl_geterror(err));
106*4dc78e53SAndroid Build Coastguard Worker
107*4dc78e53SAndroid Build Coastguard Worker if ((err = nl_send_auto(sock, msg)) < 0)
108*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(err, "Unable to send message: %s", nl_geterror(err));
109*4dc78e53SAndroid Build Coastguard Worker
110*4dc78e53SAndroid Build Coastguard Worker nlmsg_free(msg);
111*4dc78e53SAndroid Build Coastguard Worker
112*4dc78e53SAndroid Build Coastguard Worker if ((err = nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM,
113*4dc78e53SAndroid Build Coastguard Worker parse_cb, NULL)) < 0)
114*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(err, "Unable to modify valid message callback");
115*4dc78e53SAndroid Build Coastguard Worker
116*4dc78e53SAndroid Build Coastguard Worker if ((err = nl_recvmsgs_default(sock)) < 0)
117*4dc78e53SAndroid Build Coastguard Worker nl_cli_fatal(err, "Unable to receive message: %s", nl_geterror(err));
118*4dc78e53SAndroid Build Coastguard Worker
119*4dc78e53SAndroid Build Coastguard Worker nl_close(sock);
120*4dc78e53SAndroid Build Coastguard Worker nl_socket_free(sock);
121*4dc78e53SAndroid Build Coastguard Worker
122*4dc78e53SAndroid Build Coastguard Worker return 0;
123*4dc78e53SAndroid Build Coastguard Worker }
124