X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=rdma%2Frdma.c;h=676e03c23088316fac634990b52168f1636d7ab0;hb=5a823593d65e946afe5d62f2146bed47fb145fa6;hp=d850e3964d1818fa8bf3ac3870bd89ca85381cbe;hpb=74bd75c2b68d8da63465f51d0c60f55e29d609bd;p=mirror_iproute2.git diff --git a/rdma/rdma.c b/rdma/rdma.c index d850e396..676e03c2 100644 --- a/rdma/rdma.c +++ b/rdma/rdma.c @@ -1,11 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* * rdma.c RDMA tool - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * * Authors: Leon Romanovsky */ @@ -15,8 +10,9 @@ static void help(char *name) { pr_out("Usage: %s [ OPTIONS ] OBJECT { COMMAND | help }\n" - "where OBJECT := { help }\n" - " OPTIONS := { -V[ersion] | -d[etails]}\n", name); + " %s [ -f[orce] ] -b[atch] filename\n" + "where OBJECT := { dev | link | resource | help }\n" + " OPTIONS := { -V[ersion] | -d[etails] | -j[son] | -p[retty]}\n", name, name); } static int cmd_help(struct rd *rd) @@ -25,26 +21,77 @@ static int cmd_help(struct rd *rd) return 0; } -static int rd_cmd(struct rd *rd) +static int rd_cmd(struct rd *rd, int argc, char **argv) { const struct rd_cmd cmds[] = { { NULL, cmd_help }, { "help", cmd_help }, + { "dev", cmd_dev }, + { "link", cmd_link }, + { "resource", cmd_res }, { 0 } }; + rd->argc = argc; + rd->argv = argv; + return rd_exec_cmd(rd, cmds, "object"); } -static int rd_init(struct rd *rd, int argc, char **argv, char *filename) +static int rd_batch(struct rd *rd, const char *name, bool force) +{ + char *line = NULL; + size_t len = 0; + int ret = 0; + + if (name && strcmp(name, "-") != 0) { + if (!freopen(name, "r", stdin)) { + pr_err("Cannot open file \"%s\" for reading: %s\n", + name, strerror(errno)); + return errno; + } + } + + cmdlineno = 0; + while (getcmdline(&line, &len, stdin) != -1) { + char *largv[512]; + int largc; + + largc = makeargs(line, largv, ARRAY_SIZE(largv)); + if (!largc) + continue; /* blank line */ + + ret = rd_cmd(rd, largc, largv); + if (ret) { + pr_err("Command failed %s:%d\n", name, cmdlineno); + if (!force) + break; + } + } + + free(line); + + return ret; +} + +static int rd_init(struct rd *rd, char *filename) { uint32_t seq; int ret; rd->filename = filename; - rd->argc = argc; - rd->argv = argv; INIT_LIST_HEAD(&rd->dev_map_list); + INIT_LIST_HEAD(&rd->filter_list); + + if (rd->json_output) { + rd->jw = jsonw_new(stdout); + if (!rd->jw) { + pr_err("Failed to create JSON writer\n"); + return -ENOMEM; + } + jsonw_pretty(rd->jw, rd->pretty_output); + } + rd->buff = malloc(MNL_SOCKET_BUFFER_SIZE); if (!rd->buff) return -ENOMEM; @@ -58,10 +105,11 @@ static int rd_init(struct rd *rd, int argc, char **argv, char *filename) return rd_recv_msg(rd, rd_dev_init_cb, rd, seq); } -static void rd_free(struct rd *rd) +static void rd_cleanup(struct rd *rd) { - free(rd->buff); - rd_free_devmap(rd); + if (rd->json_output) + jsonw_destroy(&rd->jw); + rd_free(rd); } int main(int argc, char **argv) @@ -69,30 +117,57 @@ int main(int argc, char **argv) static const struct option long_options[] = { { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, + { "json", no_argument, NULL, 'j' }, + { "pretty", no_argument, NULL, 'p' }, { "details", no_argument, NULL, 'd' }, + { "force", no_argument, NULL, 'f' }, + { "batch", required_argument, NULL, 'b' }, { NULL, 0, NULL, 0 } }; + bool show_driver_details = false; + const char *batch_file = NULL; + bool pretty_output = false; bool show_details = false; + bool json_output = false; + bool force = false; + struct rd rd = {}; char *filename; - struct rd rd; int opt; int err; filename = basename(argv[0]); - while ((opt = getopt_long(argc, argv, "Vhd", + while ((opt = getopt_long(argc, argv, ":Vhdpjfb:", long_options, NULL)) >= 0) { switch (opt) { case 'V': printf("%s utility, iproute2-ss%s\n", filename, SNAPSHOT); return EXIT_SUCCESS; + case 'p': + pretty_output = true; + break; case 'd': - show_details = true; + if (show_details) + show_driver_details = true; + else + show_details = true; + break; + case 'j': + json_output = true; + break; + case 'f': + force = true; + break; + case 'b': + batch_file = optarg; break; case 'h': help(filename); return EXIT_SUCCESS; + case ':': + pr_err("-%c option requires an argument\n", optopt); + return EXIT_FAILURE; default: pr_err("Unknown option.\n"); help(filename); @@ -103,14 +178,21 @@ int main(int argc, char **argv) argc -= optind; argv += optind; - err = rd_init(&rd, argc, argv, filename); + rd.show_details = show_details; + rd.show_driver_details = show_driver_details; + rd.json_output = json_output; + rd.pretty_output = pretty_output; + + err = rd_init(&rd, filename); if (err) goto out; - rd.show_details = show_details; - err = rd_cmd(&rd); + if (batch_file) + err = rd_batch(&rd, batch_file, force); + else + err = rd_cmd(&rd, argc, argv); out: /* Always cleanup */ - rd_free(&rd); + rd_cleanup(&rd); return err ? EXIT_FAILURE : EXIT_SUCCESS; }