|
Packit Service |
3880ab |
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
/*
|
|
Packit Service |
3880ab |
* Helpers for handling qevents.
|
|
Packit Service |
3880ab |
*/
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
#include <stdio.h>
|
|
Packit Service |
3880ab |
#include <string.h>
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
#include "tc_qevent.h"
|
|
Packit Service |
3880ab |
#include "utils.h"
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
void qevents_init(struct qevent_util *qevents)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
if (!qevents)
|
|
Packit Service |
3880ab |
return;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
for (; qevents->id; qevents++)
|
|
Packit Service |
3880ab |
memset(qevents->data, 0, qevents->data_size);
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
int qevent_parse(struct qevent_util *qevents, int *p_argc, char ***p_argv)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
char **argv = *p_argv;
|
|
Packit Service |
3880ab |
int argc = *p_argc;
|
|
Packit Service |
3880ab |
const char *name = *argv;
|
|
Packit Service |
3880ab |
int err;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (!qevents)
|
|
Packit Service |
3880ab |
goto out;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
for (; qevents->id; qevents++) {
|
|
Packit Service |
3880ab |
if (strcmp(name, qevents->id) == 0) {
|
|
Packit Service |
3880ab |
NEXT_ARG();
|
|
Packit Service |
3880ab |
err = qevents->parse_qevent(qevents, &argc, &argv);
|
|
Packit Service |
3880ab |
if (err)
|
|
Packit Service |
3880ab |
return err;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
*p_argc = argc;
|
|
Packit Service |
3880ab |
*p_argv = argv;
|
|
Packit Service |
3880ab |
return 0;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
out:
|
|
Packit Service |
3880ab |
fprintf(stderr, "Unknown qevent `%s'\n", name);
|
|
Packit Service |
3880ab |
return -1;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
int qevents_read(struct qevent_util *qevents, struct rtattr **tb)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
int err;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (!qevents)
|
|
Packit Service |
3880ab |
return 0;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
for (; qevents->id; qevents++) {
|
|
Packit Service |
3880ab |
if (tb[qevents->attr]) {
|
|
Packit Service |
3880ab |
err = qevents->read_qevent(qevents, tb);
|
|
Packit Service |
3880ab |
if (err)
|
|
Packit Service |
3880ab |
return err;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
return 0;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
void qevents_print(struct qevent_util *qevents, FILE *f)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
int first = true;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (!qevents)
|
|
Packit Service |
3880ab |
return;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
for (; qevents->id; qevents++) {
|
|
Packit Service |
3880ab |
struct qevent_base *qeb = qevents->data;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (qeb->block_idx) {
|
|
Packit Service |
3880ab |
if (first) {
|
|
Packit Service |
3880ab |
open_json_array(PRINT_JSON, "qevents");
|
|
Packit Service |
3880ab |
first = false;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
open_json_object(NULL);
|
|
Packit Service |
3880ab |
print_string(PRINT_ANY, "kind", "qevent %s", qevents->id);
|
|
Packit Service |
3880ab |
qevents->print_qevent(qevents, f);
|
|
Packit Service |
3880ab |
print_string(PRINT_FP, NULL, "%s", " ");
|
|
Packit Service |
3880ab |
close_json_object();
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (!first)
|
|
Packit Service |
3880ab |
close_json_array(PRINT_ANY, "");
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
bool qevents_have_block(struct qevent_util *qevents, __u32 block_idx)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
if (!qevents)
|
|
Packit Service |
3880ab |
return false;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
for (; qevents->id; qevents++) {
|
|
Packit Service |
3880ab |
struct qevent_base *qeb = qevents->data;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (qeb->block_idx == block_idx)
|
|
Packit Service |
3880ab |
return true;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
return false;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
int qevents_dump(struct qevent_util *qevents, struct nlmsghdr *n)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
int err;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (!qevents)
|
|
Packit Service |
3880ab |
return 0;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
for (; qevents->id; qevents++) {
|
|
Packit Service |
3880ab |
struct qevent_base *qeb = qevents->data;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (qeb->block_idx) {
|
|
Packit Service |
3880ab |
err = qevents->dump_qevent(qevents, n);
|
|
Packit Service |
3880ab |
if (err)
|
|
Packit Service |
3880ab |
return err;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
return 0;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
static int parse_block_idx(const char *arg, struct qevent_base *qeb)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
if (qeb->block_idx) {
|
|
Packit Service |
3880ab |
fprintf(stderr, "Qevent block index already specified\n");
|
|
Packit Service |
3880ab |
return -1;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (get_unsigned(&qeb->block_idx, arg, 10) || !qeb->block_idx) {
|
|
Packit Service |
3880ab |
fprintf(stderr, "Illegal qevent block index\n");
|
|
Packit Service |
3880ab |
return -1;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
return 0;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
static int read_block_idx(struct rtattr *attr, struct qevent_base *qeb)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
if (qeb->block_idx) {
|
|
Packit Service |
3880ab |
fprintf(stderr, "Qevent block index already specified\n");
|
|
Packit Service |
3880ab |
return -1;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
qeb->block_idx = rta_getattr_u32(attr);
|
|
Packit Service |
3880ab |
if (!qeb->block_idx) {
|
|
Packit Service |
3880ab |
fprintf(stderr, "Illegal qevent block index\n");
|
|
Packit Service |
3880ab |
return -1;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
return 0;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
static void print_block_idx(FILE *f, __u32 block_idx)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
print_uint(PRINT_ANY, "block", " block %u", block_idx);
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
int qevent_parse_plain(struct qevent_util *qu, int *p_argc, char ***p_argv)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
struct qevent_plain *qe = qu->data;
|
|
Packit Service |
3880ab |
char **argv = *p_argv;
|
|
Packit Service |
3880ab |
int argc = *p_argc;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (qe->base.block_idx) {
|
|
Packit Service |
3880ab |
fprintf(stderr, "Duplicate qevent\n");
|
|
Packit Service |
3880ab |
return -1;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
while (argc > 0) {
|
|
Packit Service |
3880ab |
if (strcmp(*argv, "block") == 0) {
|
|
Packit Service |
3880ab |
NEXT_ARG();
|
|
Packit Service |
3880ab |
if (parse_block_idx(*argv, &qe->base))
|
|
Packit Service |
3880ab |
return -1;
|
|
Packit Service |
3880ab |
} else {
|
|
Packit Service |
3880ab |
break;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
NEXT_ARG_FWD();
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
if (!qe->base.block_idx) {
|
|
Packit Service |
3880ab |
fprintf(stderr, "Unspecified qevent block index\n");
|
|
Packit Service |
3880ab |
return -1;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
*p_argc = argc;
|
|
Packit Service |
3880ab |
*p_argv = argv;
|
|
Packit Service |
3880ab |
return 0;
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
int qevent_read_plain(struct qevent_util *qu, struct rtattr **tb)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
struct qevent_plain *qe = qu->data;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
return read_block_idx(tb[qu->attr], &qe->base);
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
void qevent_print_plain(struct qevent_util *qu, FILE *f)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
struct qevent_plain *qe = qu->data;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
print_block_idx(f, qe->base.block_idx);
|
|
Packit Service |
3880ab |
}
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
int qevent_dump_plain(struct qevent_util *qu, struct nlmsghdr *n)
|
|
Packit Service |
3880ab |
{
|
|
Packit Service |
3880ab |
struct qevent_plain *qe = qu->data;
|
|
Packit Service |
3880ab |
|
|
Packit Service |
3880ab |
return addattr32(n, 1024, qu->attr, qe->base.block_idx);
|
|
Packit Service |
3880ab |
}
|