diff mbox series

[iproute2,v2] tc/mqprio: json-ify output

Message ID 20201128183015.15889-1-bluca@debian.org (mailing list archive)
State Changes Requested
Delegated to: David Ahern
Headers show
Series [iproute2,v2] tc/mqprio: json-ify output | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Luca Boccassi Nov. 28, 2020, 6:30 p.m. UTC
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.

New output:

{
    "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"
    }
}

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=972784

Reported-by: Roméo GINON <romeo.ginon@ilexia.com>
Signed-off-by: Luca Boccassi <bluca@debian.org>
---
v2: the original reporter tested the patch, new output added to commit message.
    Fixed empty tag in queues nested arrays.
    Output is accepted by python3 -m json.tool

 tc/q_mqprio.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

Comments

David Ahern Dec. 2, 2020, 4:42 p.m. UTC | #1
On 11/28/20 11:30 AM, Luca Boccassi wrote:
> @@ -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));

close_json_array?

>  		}
>  
>  		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));
>  		}

close_json_array?

>  	}
>  	return 0;
>
Luca Boccassi Dec. 2, 2020, 5:09 p.m. UTC | #2
On Wed, 2020-12-02 at 09:42 -0700, David Ahern wrote:
> On 11/28/20 11:30 AM, Luca Boccassi wrote:
> > @@ -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));
> 
> close_json_array?
> 
> >  		}
> >  
> >  		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));
> >  		}
> 
> close_json_array?
> 
> >  	}
> >  	return 0;
> > 

Whops, fixed in v3, thanks.
diff mbox series

Patch

diff --git a/tc/q_mqprio.c b/tc/q_mqprio.c
index f26ba8d7..a128fc11 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, NULL);
+		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, NULL);
+	}
+	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;