|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] xenpm: make argument parsing and error handling more consistent
On 14/09/2012 14:02, "Jan Beulich" <JBeulich@xxxxxxxx> wrote:
> Specifically, what values are or aren't accepted as CPU identifier, and
> how the values get interpreted should be consistent across sub-commands
> (intended behavior now: non-negative values are okay, and along with
> omitting the argument, specifying "all" will also be accepted).
>
> For error handling, error messages should get consistently issued to
> stderr, and the tool should now (hopefully) produce an exit code of
> zero only in the (partial) success case (there may still be a small
> number of questionable cases).
>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: Keir Fraser <keir@xxxxxxx>
You can apply this one if you get no furthe feedback.
-- Keir
> --- a/tools/misc/xenpm.c
> +++ b/tools/misc/xenpm.c
> @@ -36,7 +36,7 @@
> #define CPUFREQ_TURBO_ENABLED 1
>
> static xc_interface *xc_handle;
> -static int max_cpu_nr;
> +static unsigned int max_cpu_nr;
>
> /* help message */
> void show_help(void)
> @@ -77,6 +77,33 @@ void help_func(int argc, char *argv[])
> show_help();
> }
>
> +static void parse_cpuid(const char *arg, int *cpuid)
> +{
> + if ( sscanf(arg, "%d", cpuid) != 1 || *cpuid < 0 )
> + {
> + if ( strcasecmp(arg, "all") )
> + {
> + fprintf(stderr, "Invalid CPU identifier: '%s'\n", arg);
> + exit(EINVAL);
> + }
> + *cpuid = -1;
> + }
> +}
> +
> +static void parse_cpuid_and_int(int argc, char *argv[],
> + int *cpuid, int *val, const char *what)
> +{
> + if ( argc > 1 )
> + parse_cpuid(argv[0], cpuid);
> +
> + if ( argc == 0 || sscanf(argv[argc > 1], "%d", val) != 1 )
> + {
> + fprintf(stderr, argc ? "Invalid %s '%s'\n" : "Missing %s\n",
> + what, argv[argc > 1]);
> + exit(EINVAL);
> + }
> +}
> +
> static void print_cxstat(int cpuid, struct xc_cx_stat *cxstat)
> {
> int i;
> @@ -166,7 +193,8 @@ static int show_cxstat_by_cpuid(xc_inter
> if ( ret )
> {
> if ( ret == -ENODEV )
> - printf("Either xen cpuidle is disabled or no valid information is
> registered!\n");
> + fprintf(stderr,
> + "Either Xen cpuidle is disabled or no valid information
> is registered!\n");
> return ret;
> }
>
> @@ -181,11 +209,8 @@ void cxstat_func(int argc, char *argv[])
> {
> int cpuid = -1;
>
> - if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
> - cpuid = -1;
> -
> - if ( cpuid >= max_cpu_nr )
> - cpuid = -1;
> + if ( argc > 0 )
> + parse_cpuid(argv[0], &cpuid);
>
> show_max_cstate(xc_handle);
>
> @@ -294,11 +319,8 @@ void pxstat_func(int argc, char *argv[])
> {
> int cpuid = -1;
>
> - if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
> - cpuid = -1;
> -
> - if ( cpuid >= max_cpu_nr )
> - cpuid = -1;
> + if ( argc > 0 )
> + parse_cpuid(argv[0], &cpuid);
>
> if ( cpuid < 0 )
> {
> @@ -338,10 +360,10 @@ static void signal_int_handler(int signo
> goto out;
> }
>
> - if ( gettimeofday(&tv, NULL) == -1 )
> + if ( gettimeofday(&tv, NULL) )
> {
> fprintf(stderr, "failed to get timeofday\n");
> - goto out ;
> + goto out;
> }
> usec_end = tv.tv_sec * 1000000UL + tv.tv_usec;
>
> @@ -541,7 +563,7 @@ void start_gather_func(int argc, char *a
> printf("Timeout set to %d seconds\n", timeout);
> }
>
> - if ( gettimeofday(&tv, NULL) == -1 )
> + if ( gettimeofday(&tv, NULL) )
> {
> fprintf(stderr, "failed to get timeofday\n");
> return ;
> @@ -766,11 +788,8 @@ void cpufreq_para_func(int argc, char *a
> {
> int cpuid = -1;
>
> - if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
> - cpuid = -1;
> -
> - if ( cpuid >= max_cpu_nr )
> - cpuid = -1;
> + if ( argc > 0 )
> + parse_cpuid(argv[0], &cpuid);
>
> if ( cpuid < 0 )
> {
> @@ -788,26 +807,22 @@ void scaling_max_freq_func(int argc, cha
> {
> int cpuid = -1, freq = -1;
>
> - if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
> - sscanf(argv[0], "%d", &cpuid) != 1)) ||
> - (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
> - argc == 0 )
> - {
> - fprintf(stderr, "failed to set scaling max freq\n");
> - return ;
> - }
> + parse_cpuid_and_int(argc, argv, &cpuid, &freq, "frequency");
>
> if ( cpuid < 0 )
> {
> int i;
> for ( i = 0; i < max_cpu_nr; i++ )
> if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MAX_FREQ, freq) )
> - fprintf(stderr, "[CPU%d] failed to set scaling max freq\n",
> i);
> + fprintf(stderr,
> + "[CPU%d] failed to set scaling max freq (%d - %s)\n",
> + i, errno, strerror(errno));
> }
> else
> {
> if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MAX_FREQ, freq) )
> - fprintf(stderr, "failed to set scaling max freq\n");
> + fprintf(stderr, "failed to set scaling max freq (%d - %s)\n",
> + errno, strerror(errno));
> }
> }
>
> @@ -815,26 +830,22 @@ void scaling_min_freq_func(int argc, cha
> {
> int cpuid = -1, freq = -1;
>
> - if ( (argc >= 2 && (sscanf(argv[1], "%d", &freq) != 1 ||
> - sscanf(argv[0], "%d", &cpuid) != 1) ) ||
> - (argc == 1 && sscanf(argv[0], "%d", &freq) != 1 ) ||
> - argc == 0 )
> - {
> - fprintf(stderr, "failed to set scaling min freq\n");
> - return ;
> - }
> + parse_cpuid_and_int(argc, argv, &cpuid, &freq, "frequency");
>
> if ( cpuid < 0 )
> {
> int i;
> for ( i = 0; i < max_cpu_nr; i++ )
> if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MIN_FREQ, freq) )
> - fprintf(stderr, "[CPU%d] failed to set scaling min freq\n",
> i);
> + fprintf(stderr,
> + "[CPU%d] failed to set scaling min freq (%d - %s)\n",
> + i, errno, strerror(errno));
> }
> else
> {
> if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MIN_FREQ, freq) )
> - fprintf(stderr, "failed to set scaling min freq\n");
> + fprintf(stderr, "failed to set scaling min freq (%d - %s)\n",
> + errno, strerror(errno));
> }
> }
>
> @@ -842,26 +853,22 @@ void scaling_speed_func(int argc, char *
> {
> int cpuid = -1, speed = -1;
>
> - if ( (argc >= 2 && (sscanf(argv[1], "%d", &speed) != 1 ||
> - sscanf(argv[0], "%d", &cpuid) != 1) ) ||
> - (argc == 1 && sscanf(argv[0], "%d", &speed) != 1 ) ||
> - argc == 0 )
> - {
> - fprintf(stderr, "failed to set scaling speed\n");
> - return ;
> - }
> + parse_cpuid_and_int(argc, argv, &cpuid, &speed, "speed");
>
> if ( cpuid < 0 )
> {
> int i;
> for ( i = 0; i < max_cpu_nr; i++ )
> if ( xc_set_cpufreq_para(xc_handle, i, SCALING_SETSPEED, speed) )
> - fprintf(stderr, "[CPU%d] failed to set scaling speed\n", i);
> + fprintf(stderr,
> + "[CPU%d] failed to set scaling speed (%d - %s)\n",
> + i, errno, strerror(errno));
> }
> else
> {
> if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_SETSPEED, speed) )
> - fprintf(stderr, "failed to set scaling speed\n");
> + fprintf(stderr, "failed to set scaling speed (%d - %s)\n",
> + errno, strerror(errno));
> }
> }
>
> @@ -869,14 +876,7 @@ void scaling_sampling_rate_func(int argc
> {
> int cpuid = -1, rate = -1;
>
> - if ( (argc >= 2 && (sscanf(argv[1], "%d", &rate) != 1 ||
> - sscanf(argv[0], "%d", &cpuid) != 1) ) ||
> - (argc == 1 && sscanf(argv[0], "%d", &rate) != 1 ) ||
> - argc == 0 )
> - {
> - fprintf(stderr, "failed to set scaling sampling rate\n");
> - return ;
> - }
> + parse_cpuid_and_int(argc, argv, &cpuid, &rate, "rate");
>
> if ( cpuid < 0 )
> {
> @@ -884,12 +884,14 @@ void scaling_sampling_rate_func(int argc
> for ( i = 0; i < max_cpu_nr; i++ )
> if ( xc_set_cpufreq_para(xc_handle, i, SAMPLING_RATE, rate) )
> fprintf(stderr,
> - "[CPU%d] failed to set scaling sampling rate\n", i);
> + "[CPU%d] failed to set scaling sampling rate (%d -
> %s)\n",
> + i, errno, strerror(errno));
> }
> else
> {
> if ( xc_set_cpufreq_para(xc_handle, cpuid, SAMPLING_RATE, rate) )
> - fprintf(stderr, "failed to set scaling sampling rate\n");
> + fprintf(stderr, "failed to set scaling sampling rate (%d -
> %s)\n",
> + errno, strerror(errno));
> }
> }
>
> @@ -897,14 +899,7 @@ void scaling_up_threshold_func(int argc,
> {
> int cpuid = -1, threshold = -1;
>
> - if ( (argc >= 2 && (sscanf(argv[1], "%d", &threshold) != 1 ||
> - sscanf(argv[0], "%d", &cpuid) != 1) ) ||
> - (argc == 1 && sscanf(argv[0], "%d", &threshold) != 1 ) ||
> - argc == 0 )
> - {
> - fprintf(stderr, "failed to set up scaling threshold\n");
> - return ;
> - }
> + parse_cpuid_and_int(argc, argv, &cpuid, &threshold, "threshold");
>
> if ( cpuid < 0 )
> {
> @@ -912,57 +907,49 @@ void scaling_up_threshold_func(int argc,
> for ( i = 0; i < max_cpu_nr; i++ )
> if ( xc_set_cpufreq_para(xc_handle, i, UP_THRESHOLD, threshold) )
> fprintf(stderr,
> - "[CPU%d] failed to set up scaling threshold\n", i);
> + "[CPU%d] failed to set up scaling threshold (%d -
> %s)\n",
> + i, errno, strerror(errno));
> }
> else
> {
> if ( xc_set_cpufreq_para(xc_handle, cpuid, UP_THRESHOLD, threshold) )
> - fprintf(stderr, "failed to set up scaling threshold\n");
> + fprintf(stderr, "failed to set up scaling threshold (%d - %s)\n",
> + errno, strerror(errno));
> }
> }
>
> void scaling_governor_func(int argc, char *argv[])
> {
> int cpuid = -1;
> - char *name = NULL;
> + char *name;
>
> if ( argc >= 2 )
> {
> - name = strdup(argv[1]);
> - if ( name == NULL )
> - goto out;
> - if ( sscanf(argv[0], "%d", &cpuid) != 1 )
> - {
> - free(name);
> - goto out;
> - }
> + parse_cpuid(argv[0], &cpuid);
> + name = argv[1];
> }
> else if ( argc > 0 )
> + name = argv[0];
> + else
> {
> - name = strdup(argv[0]);
> - if ( name == NULL )
> - goto out;
> + fprintf(stderr, "Missing argument(s)\n");
> + exit(EINVAL);
> }
> - else
> - goto out;
>
> if ( cpuid < 0 )
> {
> int i;
> for ( i = 0; i < max_cpu_nr; i++ )
> if ( xc_set_cpufreq_gov(xc_handle, i, name) )
> - fprintf(stderr, "[CPU%d] failed to set governor name\n", i);
> + fprintf(stderr, "[CPU%d] failed to set governor name (%d -
> %s)\n",
> + i, errno, strerror(errno));
> }
> else
> {
> if ( xc_set_cpufreq_gov(xc_handle, cpuid, name) )
> - fprintf(stderr, "failed to set governor name\n");
> + fprintf(stderr, "failed to set governor name (%d - %s)\n",
> + errno, strerror(errno));
> }
> -
> - free(name);
> - return ;
> -out:
> - fprintf(stderr, "failed to set governor name\n");
> }
>
> void cpu_topology_func(int argc, char *argv[])
> @@ -971,7 +958,7 @@ void cpu_topology_func(int argc, char *a
> DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_socket);
> DECLARE_HYPERCALL_BUFFER(uint32_t, cpu_to_node);
> xc_topologyinfo_t info = { 0 };
> - int i;
> + int i, rc = ENOMEM;
>
> cpu_to_core = xc_hypercall_buffer_alloc(xc_handle, cpu_to_core,
> sizeof(*cpu_to_core) * MAX_NR_CPU);
> cpu_to_socket = xc_hypercall_buffer_alloc(xc_handle, cpu_to_socket,
> sizeof(*cpu_to_socket) * MAX_NR_CPU);
> @@ -990,7 +977,9 @@ void cpu_topology_func(int argc, char *a
>
> if ( xc_topologyinfo(xc_handle, &info) )
> {
> - printf("Can not get Xen CPU topology: %d\n", errno);
> + rc = errno;
> + fprintf(stderr, "Cannot get Xen CPU topology (%d - %s)\n",
> + errno, strerror(errno));
> goto out;
> }
>
> @@ -1005,116 +994,95 @@ void cpu_topology_func(int argc, char *a
> printf("CPU%d\t %d\t %d\t %d\n",
> i, cpu_to_core[i], cpu_to_socket[i], cpu_to_node[i]);
> }
> + rc = 0;
> out:
> xc_hypercall_buffer_free(xc_handle, cpu_to_core);
> xc_hypercall_buffer_free(xc_handle, cpu_to_socket);
> xc_hypercall_buffer_free(xc_handle, cpu_to_node);
> + if ( rc )
> + exit(rc);
> }
>
> void set_sched_smt_func(int argc, char *argv[])
> {
> - int value, rc;
> + int value;
>
> - if (argc != 1){
> - show_help();
> - exit(-1);
> + if ( argc != 1 ) {
> + fprintf(stderr, "Missing or invalid argument(s)\n");
> + exit(EINVAL);
> }
>
> - if ( !strncmp(argv[0], "disable", sizeof("disable")) )
> - {
> + if ( !strcasecmp(argv[0], "disable") )
> value = 0;
> - }
> - else if ( !strncmp(argv[0], "enable", sizeof("enable")) )
> - {
> + else if ( !strcasecmp(argv[0], "enable") )
> value = 1;
> - }
> else
> {
> - show_help();
> - exit(-1);
> + fprintf(stderr, "Invalid argument: %s\n", argv[0]);
> + exit(EINVAL);
> }
>
> - rc = xc_set_sched_opt_smt(xc_handle, value);
> - printf("%s sched_smt_power_savings %s\n", argv[0],
> - rc? "failed":"succeeded" );
> -
> - return;
> + if ( !xc_set_sched_opt_smt(xc_handle, value) )
> + printf("%s sched_smt_power_savings succeeded\n", argv[0]);
> + else
> + fprintf(stderr, "%s sched_smt_power_savings failed (%d - %s)\n",
> + argv[0], errno, strerror(errno));
> }
>
> void set_vcpu_migration_delay_func(int argc, char *argv[])
> {
> int value;
> - int rc;
> -
> - if (argc != 1){
> - show_help();
> - exit(-1);
> - }
> -
> - value = atoi(argv[0]);
>
> - if (value < 0)
> - {
> - printf("Please try non-negative vcpu migration delay\n");
> - exit(-1);
> + if ( argc != 1 || (value = atoi(argv[0])) < 0 ) {
> + fprintf(stderr, "Missing or invalid argument(s)\n");
> + exit(EINVAL);
> }
>
> - rc = xc_set_vcpu_migration_delay(xc_handle, value);
> - printf("%s to set vcpu migration delay to %d us\n",
> - rc? "Fail":"Succeed", value );
> -
> - return;
> + if ( !xc_set_vcpu_migration_delay(xc_handle, value) )
> + printf("set vcpu migration delay to %d us succeeded\n", value);
> + else
> + fprintf(stderr, "set vcpu migration delay failed (%d - %s)\n",
> + errno, strerror(errno));
> }
>
> void get_vcpu_migration_delay_func(int argc, char *argv[])
> {
> uint32_t value;
> - int rc;
>
> - if (argc != 0){
> - show_help();
> - exit(-1);
> - }
> + if ( argc )
> + fprintf(stderr, "Ignoring argument(s)\n");
>
> - rc = xc_get_vcpu_migration_delay(xc_handle, &value);
> - if (!rc)
> - {
> - printf("Schduler vcpu migration delay is %d us\n", value);
> - }
> + if ( !xc_get_vcpu_migration_delay(xc_handle, &value) )
> + printf("Scheduler vcpu migration delay is %d us\n", value);
> else
> - {
> - printf("Failed to get scheduler vcpu migration delay, errno=%d\n",
> errno);
> - }
> -
> - return;
> + fprintf(stderr,
> + "Failed to get scheduler vcpu migration delay (%d - %s)\n",
> + errno, strerror(errno));
> }
>
> void set_max_cstate_func(int argc, char *argv[])
> {
> - int value, rc;
> + int value;
>
> if ( argc != 1 || sscanf(argv[0], "%d", &value) != 1 || value < 0 )
> {
> - show_help();
> - exit(-1);
> + fprintf(stderr, "Missing or invalid argument(s)\n");
> + exit(EINVAL);
> }
>
> - rc = xc_set_cpuidle_max_cstate(xc_handle, (uint32_t)value);
> - printf("set max_cstate to C%d %s\n", value,
> - rc? "failed":"succeeded" );
> -
> - return;
> + if ( !xc_set_cpuidle_max_cstate(xc_handle, (uint32_t)value) )
> + printf("set max_cstate to C%d succeeded\n", value);
> + else
> + fprintf(stderr, "set max_cstate to C%d failed (%d - %s)\n",
> + value, errno, strerror(errno));
> }
>
> void enable_turbo_mode(int argc, char *argv[])
> {
> int cpuid = -1;
>
> - if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
> - cpuid = -1;
> -
> - if ( cpuid >= max_cpu_nr )
> - cpuid = -1;
> + if ( argc > 0 )
> + parse_cpuid(argv[0], &cpuid);
>
> if ( cpuid < 0 )
> {
> @@ -1122,21 +1090,22 @@ void enable_turbo_mode(int argc, char *a
> * only make effects on dbs governor */
> int i;
> for ( i = 0; i < max_cpu_nr; i++ )
> - xc_enable_turbo(xc_handle, i);
> + if ( xc_enable_turbo(xc_handle, i) )
> + fprintf(stderr,
> + "[CPU%d] failed to enable turbo mode (%d - %s)\n",
> + i, errno, strerror(errno));
> }
> - else
> - xc_enable_turbo(xc_handle, cpuid);
> + else if ( xc_enable_turbo(xc_handle, cpuid) )
> + fprintf(stderr, "failed to enable turbo mode (%d - %s)\n",
> + errno, strerror(errno));
> }
>
> void disable_turbo_mode(int argc, char *argv[])
> {
> int cpuid = -1;
>
> - if ( argc > 0 && sscanf(argv[0], "%d", &cpuid) != 1 )
> - cpuid = -1;
> -
> - if ( cpuid >= max_cpu_nr )
> - cpuid = -1;
> + if ( argc > 0 )
> + parse_cpuid(argv[0], &cpuid);
>
> if ( cpuid < 0 )
> {
> @@ -1144,10 +1113,14 @@ void disable_turbo_mode(int argc, char *
> * only make effects on dbs governor */
> int i;
> for ( i = 0; i < max_cpu_nr; i++ )
> - xc_disable_turbo(xc_handle, i);
> + if ( xc_disable_turbo(xc_handle, i) )
> + fprintf(stderr,
> + "[CPU%d] failed to disable turbo mode (%d - %s)\n",
> + i, errno, strerror(errno));
> }
> - else
> - xc_disable_turbo(xc_handle, cpuid);
> + else if ( xc_disable_turbo(xc_handle, cpuid) )
> + fprintf(stderr, "failed to disable turbo mode (%d - %s)\n",
> + errno, strerror(errno));
> }
>
> struct {
> @@ -1191,15 +1164,17 @@ int main(int argc, char *argv[])
> if ( !xc_handle )
> {
> fprintf(stderr, "failed to get the handler\n");
> - return 0;
> + return EIO;
> }
>
> ret = xc_physinfo(xc_handle, &physinfo);
> if ( ret )
> {
> - fprintf(stderr, "failed to get the processor information\n");
> + ret = errno;
> + fprintf(stderr, "failed to get processor information (%d - %s)\n",
> + ret, strerror(ret));
> xc_interface_close(xc_handle);
> - return 0;
> + return ret;
> }
> max_cpu_nr = physinfo.nr_cpus;
>
> @@ -1214,14 +1189,18 @@ int main(int argc, char *argv[])
> for ( i = 0; i < nr_matches; i++ )
> fprintf(stderr, " %s",
> main_options[matches_main_options[i]].name);
> fprintf(stderr, "\n");
> + ret = EINVAL;
> }
> else if ( nr_matches == 1 )
> /* dispatch to the corresponding function handler */
> main_options[matches_main_options[0]].function(argc - 2, argv + 2);
> else
> + {
> show_help();
> + ret = EINVAL;
> + }
>
> xc_interface_close(xc_handle);
> - return 0;
> + return ret;
> }
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |