Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

smc dump:add dumpdev subcmd to specify dummy device used for data capture #14

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ endif
%.o: %.c
${CCC} ${ALL_CFLAGS} -c $< -o $@

smc: smc.o info.o ueid.o seid.o dev.o linkgroup.o libnetlink.o util.o
smc: smc.o info.o ueid.o seid.o dev.o linkgroup.o libnetlink.o util.o dumpdev.o
${CCC} ${ALL_CFLAGS} ${ALL_LDFLAGS} $^ -o $@

smcd: smcd.o infod.o ueidd.o seidd.o devd.o linkgroupd.o statsd.o libnetlink.o util.o
smcd: smcd.o infod.o ueidd.o seidd.o devd.o linkgroupd.o statsd.o libnetlink.o util.o dumpdev.o
${CCC} ${ALL_CFLAGS} $^ ${ALL_LDFLAGS} -o $@

smcr: smcr.o infor.o ueidr.o seidr.o devr.o linkgroupr.o statsr.o libnetlink.o util.o
smcr: smcr.o infor.o ueidr.o seidr.o devr.o linkgroupr.o statsr.o libnetlink.o util.o dumpdev.o
${CCC} ${ALL_CFLAGS} $^ ${ALL_LDFLAGS} -o $@

smc_pnet: smc_pnet.c smctools_common.h
Expand Down
208 changes: 208 additions & 0 deletions dumpdev.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "smctools_common.h"
#include "util.h"
#include "libnetlink.h"
#include "dumpdev.h"

static int set_cmd = 0;
static int reset_cmd = 0;
static int show_cmd = 0;

static char target_ndev[SMC_MAX_DUMP_DEV_LEN + 1] = { 0 };

extern int smc_id;
extern struct nl_sock *sk;

const struct nla_policy
smc_gen_dump_ndev_policy[SMC_NLA_DUMP_DEV_MAX + 1] = {
[SMC_NLA_DUMP_DEV_UNSPEC] = { .type = NLA_UNSPEC },
[SMC_NLA_DUMP_DEV_NAME] = { .type = NLA_NUL_STRING },
};

static void usage(void)
{
fprintf(stderr,
"Usage: smc{r|d} dumpdev [show]\n"
" smc{r|d} dumpdev set <dev_name>\n"
" smc{r|d} dumpdev [reset]\n"
);
exit(-1);
}

static int gen_nl_dump_ndev_handle(int cmd, char *dev, int (*cb_handler)(struct nl_msg *msg, void *arg))
{
int rc = EXIT_FAILURE, nlmsg_flags = 0;
struct nl_msg *msg;

nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, cb_handler, NULL);

/* Allocate a netlink message and set header information. */
msg = nlmsg_alloc();
if (!msg) {
nl_perror(NLE_NOMEM, "Error");
rc = EXIT_FAILURE;
goto err;
}

if (cmd == SMC_NETLINK_GET_DUMP_DEV)
nlmsg_flags = NLM_F_DUMP;

if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, smc_id, 0, nlmsg_flags,
cmd, SMC_GENL_FAMILY_VERSION)) {
nl_perror(rc, "Error");
rc = EXIT_FAILURE;
goto err;
}

if (dev && dev[0]) {
rc = nla_put_string(msg, SMC_NLA_DUMP_DEV_NAME, dev);
if (rc < 0) {
nl_perror(rc, "Error");
rc = EXIT_FAILURE;
goto err;
}

}

/* Send message */
rc = nl_send_auto(sk, msg);
if (rc < 0) {
nl_perror(rc, "Error");
rc = EXIT_FAILURE;
goto err;
}

/* Receive reply message, returns number of cb invocations. */
rc = nl_recvmsgs_default(sk);

if (rc < 0) {
if (rc == -NLE_OPNOTSUPP) {
fprintf(stderr, "Error: operation not supported by kernel\n");
} else if (cmd == SMC_NETLINK_SET_DUMP_DEV) {
if (rc == -NLE_NODEV) {
fprintf(stderr, "Error: specified dump device is not valid\n");
} else if (rc == -NLE_NOMEM) {
fprintf(stderr, "Error: lack memory to set dump device\n");
} else if (rc == -NLE_INVAL) {
fprintf(stderr, "Error: lack memory to set dump device\n");
} else {
fprintf(stderr, "Error: fail to set specified dump device: %d\n", rc);
}
} else if (cmd == SMC_NETLINK_RESET_DUMP_DEV) {
if (rc == -NLE_INVAL) {
fprintf(stderr, "Error: smc dump device was not set\n");
} else {
fprintf(stderr, "Error: resetting specified dump device fail: %d\n", rc);
}
} else {
nl_perror(rc, "Error");
}
rc = EXIT_FAILURE;
goto err;
}

nlmsg_free(msg);
return EXIT_SUCCESS;
err:
nlmsg_free(msg);
return rc;
}

static int handle_gen_dump_ndev_reply(struct nl_msg *msg, void *arg)
{
struct nlattr *attrs[SMC_NLA_DUMP_DEV_NAME + 1];
struct nlmsghdr *hdr = nlmsg_hdr(msg);
int rc = NL_OK;

if (genlmsg_parse(hdr, 0, attrs, SMC_NLA_DUMP_DEV_NAME,
(struct nla_policy *)smc_gen_dump_ndev_policy) < 0) {
fprintf(stderr, "Error: invalid data returned: smc_gen_dump_ndev_policy\n");
nl_msg_dump(msg, stderr);
return NL_STOP;
}

if (!attrs[SMC_NLA_DUMP_DEV_NAME])
return NL_STOP;

printf("%s\n", nla_get_string(attrs[SMC_NLA_DUMP_DEV_NAME]));
return rc;
}

static void set_ndev(char *dev)
{
if (strlen(dev) > SMC_MAX_DUMP_DEV_LEN) {
fprintf(stderr, "Error: Invalid interface specified: interface name is longer than 16 characters\n");
exit(-1);
}
strncpy(target_ndev, dev, SMC_MAX_DUMP_DEV_LEN);
}

static void handle_cmd_params(int argc, char **argv)
{
if (argc == 0) {
show_cmd = 1; /* no object given, so use the default "show" */
return;
}

while (1) {
if (set_cmd) {
set_ndev(argv[0]);
break;
} else if (contains(argv[0], "help") == 0) {
usage();
} else if (contains(argv[0], "set") == 0) {
set_cmd = 1;
} else if (contains(argv[0], "reset") == 0) {
reset_cmd = 1;
break;
} else if (contains(argv[0], "show") == 0) {
show_cmd = 1;
break;
} else {
usage();
}
if (!NEXT_ARG_OK())
break;
NEXT_ARG();
}
/* Too many parameters or wrong sequence of parameters */
if (NEXT_ARG_OK())
usage();

/* Only single cmd expected */
if ((set_cmd + reset_cmd + show_cmd) != 1)
usage();

/* device name required for command */
if (!target_ndev[0] && set_cmd)
usage();
}

int invoke_dumpdev(int argc, char **argv, int detail_level)
{
int rc = EXIT_SUCCESS;

handle_cmd_params(argc, argv);

if (set_cmd) {
rc = gen_nl_dump_ndev_handle(SMC_NETLINK_SET_DUMP_DEV, target_ndev,
handle_gen_dump_ndev_reply);
} else if (reset_cmd) {
rc = gen_nl_dump_ndev_handle(SMC_NETLINK_RESET_DUMP_DEV, NULL,
handle_gen_dump_ndev_reply);
} else if (show_cmd) {
rc = gen_nl_dump_ndev_handle(SMC_NETLINK_GET_DUMP_DEV, NULL,
handle_gen_dump_ndev_reply);
} else {
printf("Error: Unknown command\n"); /* we should never come here ... */
}

return rc;
}

6 changes: 6 additions & 0 deletions dumpdev.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef DUMP_DEV_H_
#define DUMP_DEV_H_

int invoke_dumpdev(int argc, char **argv, int detail_level);

#endif /* UEID_H_ */
6 changes: 4 additions & 2 deletions smc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "seid.h"
#include "info.h"
#include "stats.h"
#include "dumpdev.h"

static int option_detail = 0;
#if defined(SMCD)
Expand All @@ -53,10 +54,10 @@ static void usage(void)
fprintf(stderr,
"Usage: %s [ OPTIONS ] OBJECT {COMMAND | help}\n"
#if defined(SMCD)
"where OBJECT := {info | linkgroup | device | stats | ueid | seid}\n"
"where OBJECT := {info | linkgroup | device | stats | ueid | seid | dumpdev}\n"
" OPTIONS := {-v[ersion] | -d[etails] | -a[bsolute]}\n", myname);
#else
"where OBJECT := {info | linkgroup | device | stats | ueid}\n"
"where OBJECT := {info | linkgroup | device | stats | ueid | dumpdev}\n"
" OPTIONS := {-v[ersion] | -d[etails] | -dd[etails] | -a[bsolute]}\n", myname);
#endif
}
Expand All @@ -79,6 +80,7 @@ static const struct cmd {
#if defined(SMCD)
{ "seid", invoke_seid },
#endif
{ "dumpdev", invoke_dumpdev },
{ "help", invoke_help },
{ 0 }
};
Expand Down
12 changes: 12 additions & 0 deletions smctools_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#define SMC_MAX_UEID 8 /* Max number of eids */
#define SMC_MAX_PORTS 2 /* Max # of ports per ib device */
#define SMC_PCI_ID_STR_LEN 16 /* Max length of pci id string */
#define SMC_MAX_DUMP_DEV_LEN 16 /* Max length of dummy device name */

/* Netlink SMC_PNETID attributes */
enum {
Expand Down Expand Up @@ -80,6 +81,9 @@ enum {
SMC_NETLINK_DUMP_SEID,
SMC_NETLINK_ENABLE_SEID,
SMC_NETLINK_DISABLE_SEID,
SMC_NETLINK_GET_DUMP_DEV = 19,
SMC_NETLINK_SET_DUMP_DEV,
SMC_NETLINK_RESET_DUMP_DEV,
};

/* SMC_GENL_FAMILY top level attributes */
Expand Down Expand Up @@ -304,6 +308,14 @@ enum {
SMC_NLA_SEID_TABLE_MAX = __SMC_NLA_SEID_TABLE_MAX - 1
};

/* SMC_NETLINK_DUMP_DEV attributes */
enum {
SMC_NLA_DUMP_DEV_UNSPEC,
SMC_NLA_DUMP_DEV_NAME, /* string */
__SMC_NLA_DUMP_DEV_MAX,
SMC_NLA_DUMP_DEV_MAX = __SMC_NLA_DUMP_DEV_MAX - 1
};

/***********************************************************
* Mimic definitions in kernel/include/uapi/linux/smc_diag.h
***********************************************************/
Expand Down