When dumping flows into a file, allow appending to file rather than erasing
it and creating a new one.

Also, to disambiguate between "mode" in terms of appending, and "mode" in
terms of one vs. all flows, rename `mode` variable.

Signed-off-by: Anatoly Burakov <[email protected]>
---
 app/test-pmd/cmdline_flow.c | 45 ++++++++++++++++++++++++++++++++-----
 app/test-pmd/config.c       |  4 ++--
 app/test-pmd/testpmd.h      |  2 +-
 3 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index ebc036b14b..67f200f2e3 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -267,7 +267,10 @@ enum index {
        DUMP_ALL,
        DUMP_ONE,
        DUMP_IS_USER_ID,
+       DUMP_FILE_PATH,
 
+       DUMP_WRITE,
+       DUMP_APPEND,
        /* Configure arguments */
        CONFIG_QUEUES_NUMBER,
        CONFIG_QUEUES_SIZE,
@@ -1263,8 +1266,9 @@ struct buffer {
                } destroy; /**< Destroy arguments. */
                struct {
                        char file[128];
-                       bool mode;
+                       bool dump_all;
                        uint64_t rule;
+                       bool append_to_file;
                        bool is_user_id;
                } dump; /**< Dump arguments. */
                struct {
@@ -1550,8 +1554,7 @@ static const enum index next_destroy_attr[] = {
 };
 
 static const enum index next_dump_attr[] = {
-       COMMON_FILE_PATH,
-       END,
+       DUMP_FILE_PATH,
        ZERO,
 };
 
@@ -4296,6 +4299,27 @@ static const struct token token_list[] = {
                .next = NEXT(next_dump_subcmd),
                .call = parse_dump,
        },
+       [DUMP_FILE_PATH] = {
+               .name = "{file path}",
+               .type = "STRING",
+               .help = "file path",
+               .next = NEXT(NEXT_ENTRY(DUMP_WRITE, DUMP_APPEND, END)),
+               .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)),
+               .call = parse_string0,
+               .comp = comp_none,
+       },
+       [DUMP_WRITE] = {
+               .name = "write",
+               .help = "open file in write mode (default)",
+               .next = NEXT(NEXT_ENTRY(END)),
+               .call = parse_dump,
+       },
+       [DUMP_APPEND] = {
+               .name = "append",
+               .help = "open file in append mode",
+               .next = NEXT(NEXT_ENTRY(END)),
+               .call = parse_dump,
+       },
        /* Query arguments. */
        [QUERY_ACTION] = {
                .name = "{action}",
@@ -10733,7 +10757,9 @@ parse_dump(struct context *ctx, const struct token 
*token,
        switch (ctx->curr) {
        case DUMP_ALL:
        case DUMP_ONE:
-               out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false;
+               out->args.dump.dump_all = (ctx->curr == DUMP_ALL) ? true : 
false;
+               /* don't append to file by default */
+               out->args.dump.append_to_file = false;
                out->command = ctx->curr;
                ctx->objdata = 0;
                ctx->object = out;
@@ -10742,6 +10768,12 @@ parse_dump(struct context *ctx, const struct token 
*token,
        case DUMP_IS_USER_ID:
                out->args.dump.is_user_id = true;
                return len;
+       case DUMP_WRITE:
+               out->args.dump.append_to_file = false;
+               return len;
+       case DUMP_APPEND:
+               out->args.dump.append_to_file = true;
+               return len;
        default:
                return -1;
        }
@@ -13579,9 +13611,10 @@ cmd_flow_parsed(const struct buffer *in)
                break;
        case DUMP_ONE:
        case DUMP_ALL:
-               port_flow_dump(in->port, in->args.dump.mode,
+               port_flow_dump(in->port, in->args.dump.dump_all,
                                in->args.dump.rule, in->args.dump.file,
-                               in->args.dump.is_user_id);
+                               in->args.dump.is_user_id,
+                               in->args.dump.append_to_file);
                break;
        case QUERY:
                port_flow_query(in->port, in->args.query.rule,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 32c885de0b..c950793aaf 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -4162,7 +4162,7 @@ port_flow_flush(portid_t port_id)
 /** Dump flow rules. */
 int
 port_flow_dump(portid_t port_id, bool dump_all, uint64_t rule_id,
-               const char *file_name, bool is_user_id)
+               const char *file_name, bool is_user_id, bool append_to_file)
 {
        int ret = 0;
        FILE *file = stdout;
@@ -4198,7 +4198,7 @@ port_flow_dump(portid_t port_id, bool dump_all, uint64_t 
rule_id,
        }
 
        if (file_name && strlen(file_name)) {
-               file = fopen(file_name, "w");
+               file = fopen(file_name, append_to_file ? "a" : "w");
                if (!file) {
                        fprintf(stderr, "Failed to create file %s: %s\n",
                                file_name, strerror(errno));
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 9b60ebd7fc..1a54535470 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -1085,7 +1085,7 @@ int port_flow_update(portid_t port_id, uint32_t rule,
 int port_flow_flush(portid_t port_id);
 int port_flow_dump(portid_t port_id, bool dump_all,
                        uint64_t rule, const char *file_name,
-                       bool is_user_id);
+                       bool is_user_id, bool file_mode);
 int port_flow_query(portid_t port_id, uint64_t rule,
                    const struct rte_flow_action *action, bool is_user_id);
 void port_flow_list(portid_t port_id, uint32_t n, const uint32_t *group);
-- 
2.47.3

Reply via email to