Message ID | 20201127152625.61874-1-bluca@debian.org (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | David Ahern |
Headers | show |
Series | [RFC,iproute2] tc/mqprio: json-ify output | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
On Fri, 27 Nov 2020 15:26:25 +0000 Luca Boccassi <bluca@debian.org> wrote: > As reported by a Debian user, mqprio output in json mode is > invalid: > > { > "kind": "mqprio", > "handle": "8021:", > "dev": "enp1s0f0", > "root": true, > "options": { tc 2 map 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 > queues:(0:3) (4:7) > mode:channel > shaper:dcb} > } > > json-ify it, while trying to maintain the same formatting > for standard output. > > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972784 > > Signed-off-by: Luca Boccassi <bluca@debian.org> Did you try feeding that into the python parser? What is before/after?
On Fri, 2020-11-27 at 21:21 -0800, Stephen Hemminger wrote: > On Fri, 27 Nov 2020 15:26:25 +0000 > Luca Boccassi <bluca@debian.org> wrote: > > > As reported by a Debian user, mqprio output in json mode is > > invalid: > > > > { > > "kind": "mqprio", > > "handle": "8021:", > > "dev": "enp1s0f0", > > "root": true, > > "options": { tc 2 map 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 > > queues:(0:3) (4:7) > > mode:channel > > shaper:dcb} > > } > > > > json-ify it, while trying to maintain the same formatting > > for standard output. > > > > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972784 > > > > Signed-off-by: Luca Boccassi <bluca@debian.org> > > Did you try feeding that into the python parser? > What is before/after? Uh, which python parser? The reporter tested the patch, there's a small error. Before is above, after is: { "kind": "mqprio", "handle": "8001:", "root": true, "options": { "tc": 2, "map": [ 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0 ], "queues": [ "": [ 0,3 ], "": [ 4,7 ] ], "mode": "channel", "shaper": "dcb" } } Will fix the "queues" to remove the empty name in v2.
On Sat, 28 Nov 2020 12:17:00 +0000 Luca Boccassi <bluca@debian.org> wrote: > On Fri, 2020-11-27 at 21:21 -0800, Stephen Hemminger wrote: > > On Fri, 27 Nov 2020 15:26:25 +0000 > > Luca Boccassi <bluca@debian.org> wrote: > > > > > As reported by a Debian user, mqprio output in json mode is > > > invalid: > > > > > > { > > > "kind": "mqprio", > > > "handle": "8021:", > > > "dev": "enp1s0f0", > > > "root": true, > > > "options": { tc 2 map 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 > > > queues:(0:3) (4:7) > > > mode:channel > > > shaper:dcb} > > > } > > > > > > json-ify it, while trying to maintain the same formatting > > > for standard output. > > > > > > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972784 > > > > > > Signed-off-by: Luca Boccassi <bluca@debian.org> > > > > Did you try feeding that into the python parser? > > What is before/after? > > Uh, which python parser? > > The reporter tested the patch, there's a small error. Before is above, > after is: > > { > "kind": "mqprio", > "handle": "8001:", > "root": true, > "options": { > "tc": 2, > "map": [ 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0 ], > "queues": [ > "": [ 0,3 ], > "": [ 4,7 ] ], > "mode": "channel", > "shaper": "dcb" > } > } > > Will fix the "queues" to remove the empty name in v2. Try: $ tc -j qdisc | pythom -m json.tools The empty tags are non-standard practice can it be done better?
On Sat, 2020-11-28 at 09:34 -0800, Stephen Hemminger wrote: > On Sat, 28 Nov 2020 12:17:00 +0000 > Luca Boccassi <bluca@debian.org> wrote: > > > On Fri, 2020-11-27 at 21:21 -0800, Stephen Hemminger wrote: > > > On Fri, 27 Nov 2020 15:26:25 +0000 > > > Luca Boccassi <bluca@debian.org> wrote: > > > > > > > As reported by a Debian user, mqprio output in json mode is > > > > invalid: > > > > > > > > { > > > > "kind": "mqprio", > > > > "handle": "8021:", > > > > "dev": "enp1s0f0", > > > > "root": true, > > > > "options": { tc 2 map 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 > > > > queues:(0:3) (4:7) > > > > mode:channel > > > > shaper:dcb} > > > > } > > > > > > > > json-ify it, while trying to maintain the same formatting > > > > for standard output. > > > > > > > > https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972784 > > > > > > > > Signed-off-by: Luca Boccassi <bluca@debian.org> > > > > > > Did you try feeding that into the python parser? > > > What is before/after? > > > > Uh, which python parser? > > > > The reporter tested the patch, there's a small error. Before is > > above, > > after is: > > > > { > > "kind": "mqprio", > > "handle": "8001:", > > "root": true, > > "options": { > > "tc": 2, > > "map": [ 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0 ], > > "queues": [ > > "": [ 0,3 ], > > "": [ 4,7 ] ], > > "mode": "channel", > > "shaper": "dcb" > > } > > } > > > > Will fix the "queues" to remove the empty name in v2. > > Try: > $ tc -j qdisc | pythom -m json.tools > > The empty tags are non-standard practice can it be done better? Yes, v2 that I sent earlier fixed the empty tags. Python's json.tools is happy. The test of v2 from the reporter gave this output: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972784#27 [{"kind":"mqprio","handle":"8001:","root":true,"options":{"tc":2,"map":[0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0],"queues":[[0,3],[4,7]],"mode":"channel","shaper":"dcb"}},{"kind":"pfifo_fast","handle":"0:","parent":"8001:8","options":{"bands":3,"priomap ":[1,2,2,2,1,2,0,0,1,1,1,1,1,1,1,1],"multiqueue":false}},{"kind":"pfifo_fast","handle":"0:","parent":"8001:7","options":{"bands":3,"priomap ":[1,2,2,2,1,2,0,0,1,1,1,1,1,1,1,1],"multiqueue":false}},{"kind":"pfifo_fast","handle":"0:","parent":"8001:6","options":{"bands":3,"priomap ":[1,2,2,2,1,2,0,0,1,1,1,1,1,1,1,1],"multiqueue":false}},{"kind":"pfifo_fast","handle":"0:","parent":"8001:5","options":{"bands":3,"priomap ":[1,2,2,2,1,2,0,0,1,1,1,1,1,1,1,1],"multiqueue":false}},{"kind":"pfifo_fast","handle":"0:","parent":"8001:4","options":{"bands":3,"priomap ":[1,2,2,2,1,2,0,0,1,1,1,1,1,1,1,1],"multiqueue":false}},{"kind":"pfifo_fast","handle":"0:","parent":"8001:3","options":{"bands":3,"priomap ":[1,2,2,2,1,2,0,0,1,1,1,1,1,1,1,1],"multiqueue":false}},{"kind":"pfifo_fast","handle":"0:","parent":"8001:2","options":{"bands":3,"priomap ":[1,2,2,2,1,2,0,0,1,1,1,1,1,1,1,1],"multiqueue":false}},{"kind":"pfifo_fast","handle":"0:","parent":"8001:1","options":{"bands":3,"priomap ":[1,2,2,2,1,2,0,0,1,1,1,1,1,1,1,1],"multiqueue":false}}] Which when fed to python3 -m json.utils gives: [ { "kind": "mqprio", "handle": "8001:", "root": true, "options": { "tc": 2, "map": [ 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], "queues": [ [ 0, 3 ], [ 4, 7 ] ], "mode": "channel", "shaper": "dcb" } }, { "kind": "pfifo_fast", "handle": "0:", "parent": "8001:8", "options": { "bands": 3, "priomap ": [ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ], "multiqueue": false } }, { "kind": "pfifo_fast", "handle": "0:", "parent": "8001:7", "options": { "bands": 3, "priomap ": [ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ], "multiqueue": false } }, { "kind": "pfifo_fast", "handle": "0:", "parent": "8001:6", "options": { "bands": 3, "priomap ": [ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ], "multiqueue": false } }, { "kind": "pfifo_fast", "handle": "0:", "parent": "8001:5", "options": { "bands": 3, "priomap ": [ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ], "multiqueue": false } }, { "kind": "pfifo_fast", "handle": "0:", "parent": "8001:4", "options": { "bands": 3, "priomap ": [ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ], "multiqueue": false } }, { "kind": "pfifo_fast", "handle": "0:", "parent": "8001:3", "options": { "bands": 3, "priomap ": [ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ], "multiqueue": false } }, { "kind": "pfifo_fast", "handle": "0:", "parent": "8001:2", "options": { "bands": 3, "priomap ": [ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ], "multiqueue": false } }, { "kind": "pfifo_fast", "handle": "0:", "parent": "8001:1", "options": { "bands": 3, "priomap ": [ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 ], "multiqueue": false } } ]
diff --git a/tc/q_mqprio.c b/tc/q_mqprio.c index f26ba8d7..f62ccbc6 100644 --- a/tc/q_mqprio.c +++ b/tc/q_mqprio.c @@ -243,13 +243,19 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) qopt = RTA_DATA(opt); - fprintf(f, " tc %u map ", qopt->num_tc); + print_uint(PRINT_ANY, "tc", "tc %u ", qopt->num_tc); + open_json_array(PRINT_ANY, is_json_context() ? "map" : "map "); for (i = 0; i <= TC_PRIO_MAX; i++) - fprintf(f, "%u ", qopt->prio_tc_map[i]); - fprintf(f, "\n queues:"); - for (i = 0; i < qopt->num_tc; i++) - fprintf(f, "(%u:%u) ", qopt->offset[i], - qopt->offset[i] + qopt->count[i] - 1); + print_uint(PRINT_ANY, NULL, "%u ", qopt->prio_tc_map[i]); + close_json_array(PRINT_ANY, ""); + open_json_array(PRINT_ANY, is_json_context() ? "queues" : "\n queues:"); + for (i = 0; i < qopt->num_tc; i++) { + open_json_array(PRINT_JSON, ""); + print_uint(PRINT_ANY, NULL, "(%u:", qopt->offset[i]); + print_uint(PRINT_ANY, NULL, "%u) ", qopt->offset[i] + qopt->count[i] - 1); + close_json_array(PRINT_JSON, ""); + } + close_json_array(PRINT_ANY, ""); if (len > 0) { struct rtattr *tb[TCA_MQPRIO_MAX + 1]; @@ -262,18 +268,18 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) __u16 *mode = RTA_DATA(tb[TCA_MQPRIO_MODE]); if (*mode == TC_MQPRIO_MODE_CHANNEL) - fprintf(f, "\n mode:channel"); + print_string(PRINT_ANY, "mode", "\n mode:%s", "channel"); } else { - fprintf(f, "\n mode:dcb"); + print_string(PRINT_ANY, "mode", "\n mode:%s", "dcb"); } if (tb[TCA_MQPRIO_SHAPER]) { __u16 *shaper = RTA_DATA(tb[TCA_MQPRIO_SHAPER]); if (*shaper == TC_MQPRIO_SHAPER_BW_RATE) - fprintf(f, "\n shaper:bw_rlimit"); + print_string(PRINT_ANY, "shaper", "\n shaper:%s", "bw_rlimit"); } else { - fprintf(f, "\n shaper:dcb"); + print_string(PRINT_ANY, "shaper", "\n shaper:%s", "dcb"); } if (tb[TCA_MQPRIO_MIN_RATE64]) { @@ -287,9 +293,9 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) return -1; *(min++) = rta_getattr_u64(r); } - fprintf(f, " min_rate:"); + open_json_array(PRINT_ANY, is_json_context() ? "min_rate" : " min_rate:"); for (i = 0; i < qopt->num_tc; i++) - fprintf(f, "%s ", sprint_rate(min_rate64[i], b1)); + print_string(PRINT_ANY, NULL, "%s ", sprint_rate(min_rate64[i], b1)); } if (tb[TCA_MQPRIO_MAX_RATE64]) { @@ -303,9 +309,9 @@ static int mqprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) return -1; *(max++) = rta_getattr_u64(r); } - fprintf(f, " max_rate:"); + open_json_array(PRINT_ANY, is_json_context() ? "max_rate" : " max_rate:"); for (i = 0; i < qopt->num_tc; i++) - fprintf(f, "%s ", sprint_rate(max_rate64[i], b1)); + print_string(PRINT_ANY, NULL, "%s ", sprint_rate(max_rate64[i], b1)); } } return 0;
As reported by a Debian user, mqprio output in json mode is invalid: { "kind": "mqprio", "handle": "8021:", "dev": "enp1s0f0", "root": true, "options": { tc 2 map 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 queues:(0:3) (4:7) mode:channel shaper:dcb} } json-ify it, while trying to maintain the same formatting for standard output. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972784 Signed-off-by: Luca Boccassi <bluca@debian.org> --- I do not have hardware where I can configure mqprio, so I can't really test this apart from compiling it. Stephen and David, do you have machines where you can quickly check that this works as expected? Thanks! tc/q_mqprio.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-)