On 19 Mar 2024, at 11:09, Jakob Meng wrote:
> On 15.03.24 11:15, Eelco Chaudron wrote:
>> [...]
>> Hi Jakob,
>>
>>
>> Thank you for submitting this series; I believe it's a valuable addition to
>> OVS! Apologies for the delayed response. I've reviewed the entire series,
>> and most of the comments are minor change requests. I'll hold off on sending
>> a new revision until Ilya has had a chance to review it, as he provided some
>> comments on the previous revision.
>>
>> Cheers,
>>
>> Eelco
>
> Thanks for your review ☺️ Some questions below..
>
> Best,
> Jakob
>
>>> diff --git a/utilities/ovs-appctl.c b/utilities/ovs-appctl.c
>>> index ba0c172e6..02df8ba97 100644
>>> --- a/utilities/ovs-appctl.c
>>> +++ b/utilities/ovs-appctl.c
>>> @@ -29,12 +29,22 @@
>>> #include "jsonrpc.h"
>>> #include "process.h"
>>> #include "timeval.h"
>>> +#include "svec.h"
>>> #include "unixctl.h"
>>> #include "util.h"
>>> #include "openvswitch/vlog.h"
>>>
>>> static void usage(void);
>>> -static const char *parse_command_line(int argc, char *argv[]);
>>> +
>>> +/* Parsed command line args. */
>>> +struct cmdl_args {
>>> + enum ovs_output_fmt format;
>>> + char *target;
>>> +};
>>> +
>>> +static struct cmdl_args *cmdl_args_create(void);
>>> +static void cmdl_args_destroy(struct cmdl_args *);
>>> +static struct cmdl_args *parse_command_line(int argc, char *argv[]);
>>> static struct jsonrpc *connect_to_target(const char *target);
>>>
>>> int
>>> @@ -43,30 +53,59 @@ main(int argc, char *argv[])
>>> char *cmd_result, *cmd_error;
>>> struct jsonrpc *client;
>>> char *cmd, **cmd_argv;
>>> - const char *target;
>>> + struct cmdl_args *args;
>>> int cmd_argc;
>>> int error;
>>> + struct svec opt_argv = SVEC_EMPTY_INITIALIZER;
>> Can we keep the variables in reversed Christmas tree order?
>>
>>> set_program_name(argv[0]);
>>>
>>> /* Parse command line and connect to target. */
>>> - target = parse_command_line(argc, argv);
>>> - client = connect_to_target(target);
>>> + args = parse_command_line(argc, argv);
>>> + client = connect_to_target(args->target);
>>> +
>>> + /* Transact options request (if required) and process reply */
>>> + if (args->format != OVS_OUTPUT_FMT_TEXT) {
>>> + svec_add(&opt_argv, "--format");
>>> + svec_add(&opt_argv, ovs_output_fmt_to_string(args->format));
>>> + }
>>> + svec_terminate(&opt_argv);
>>> +
>>> + if (opt_argv.n > 0) {
>> You can use svec_is_empty() here.
>>
>>> + error = unixctl_client_transact(client, "set-options",
>>> + opt_argv.n, opt_argv.names,
>>> + &cmd_result, &cmd_error);
>>> +
>>> + if (error) {
>>> + ovs_fatal(error, "%s: transaction error", args->target);
>>> + }
>>>
>>> - /* Transact request and process reply. */
>>> + if (cmd_error) {
>>> + jsonrpc_close(client);
>>> + fputs(cmd_error, stderr);
>>> + ovs_error(0, "%s: server returned an error", args->target);
>>> + exit(2);
>>> + }
>>> +
>>> + free(cmd_result);
>>> + free(cmd_error);
>> cmd_error will never end up here, as you call exit(2) above, so the free
>> should also move up.
>
> The error handling of this set-options call is intentionally kept very
> similar to the error handling of the later command call. Should I drop the
> "free(cmd_error);" in both sections because we exit anyway? Should I move it
> up in both cases?
>
>> Should we not exit on a transaction error also? I think error handling might
>> need some more cleanup.
>
> We exit on transaction error with ovs_fatal?! Just like in the next command
> call..
>
> What kind of cleanup do you have in mind?
I come from the pre-MMU era, where exiting without freeing memory meant losing
it forever. With MMUs in place, I suppose it's acceptable to leave this code
unchanged. My attempts to tidy it up only made it less readable.
>>> + }
>>> + svec_destroy(&opt_argv);
>>> +
>>> + /* Transact command request and process reply. */
>>> cmd = argv[optind++];
>>> cmd_argc = argc - optind;
>>> cmd_argv = cmd_argc ? argv + optind : NULL;
>>> error = unixctl_client_transact(client, cmd, cmd_argc, cmd_argv,
>>> &cmd_result, &cmd_error);
>>> if (error) {
>>> - ovs_fatal(error, "%s: transaction error", target);
>>> + ovs_fatal(error, "%s: transaction error", args->target);
>>> }
>>>
>>> if (cmd_error) {
>>> jsonrpc_close(client);
>>> fputs(cmd_error, stderr);
>>> - ovs_error(0, "%s: server returned an error", target);
>>> + ovs_error(0, "%s: server returned an error", args->target);
>>> exit(2);
>>> } else if (cmd_result) {
>>> fputs(cmd_result, stdout);
>>> @@ -74,6 +113,7 @@ main(int argc, char *argv[])
>>> OVS_NOT_REACHED();
>>> }
>>>
>>> + cmdl_args_destroy(args);
>>> jsonrpc_close(client);
>>> free(cmd_result);
>>> free(cmd_error);
>>> @@ -101,13 +141,34 @@ Common commands:\n\
>>> vlog/reopen Make the program reopen its log file\n\
>>> Other options:\n\
>>> --timeout=SECS wait at most SECS seconds for a response\n\
>>> + -f, --format=FMT Output format. One of: 'json', or 'text'\n\
>>> + ('text', by default)\n\
>>> -h, --help Print this helpful information\n\
>>> -V, --version Display ovs-appctl version information\n",
>>> program_name, program_name);
>>> exit(EXIT_SUCCESS);
>>> }
>>>
>>> -static const char *
>>> +static struct cmdl_args *
>>> +cmdl_args_create(void) {
>>> + struct cmdl_args *args = xmalloc(sizeof *args);
>>> +
>>> + args->format = OVS_OUTPUT_FMT_TEXT;
>>> + args->target = NULL;
>>> +
>>> + return args;
>>> +}
>>> +
>>> +static void
>>> +cmdl_args_destroy(struct cmdl_args *args) {
>>> + if (args->target) {
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev