Esempio n. 1
0
int main(int argc, char **argv)
{
    int opt;
    int err = 0;
    int output_num;
    double policy_vals[GEOPMAGENT_DOUBLE_LENGTH] = {0};
    char error_str[GEOPMAGENT_STRING_LENGTH] = {0};
    char agent_str[GEOPMAGENT_STRING_LENGTH] = {0};
    char policy_vals_str[GEOPMAGENT_STRING_LENGTH] = {0};
    char output_str[NAME_MAX * GEOPMAGENT_DOUBLE_LENGTH];
    char *agent_ptr = NULL;
    char *policy_vals_ptr = NULL;
    char *arg_ptr = NULL;
    const char *usage = "\nUsage: geopmagent\n"
                        "       geopmagent [-a AGENT] [-p POLICY0,POLICY1,...]\n"
                        "       geopmagent [--help] [--version]\n"
                        "\n"
                        "Mandatory arguments to long options are mandatory for short options too.\n"
                        "\n"
                        "  -a, --agent=AGENT         specify the name of the agent\n"
                        "  -p, --policy=POLICY0,...  values to be set for each policy in a\n"
                        "                            comma-seperated list\n"
                        "  -h, --help                print  brief summary of the command line\n"
                        "                            usage information, then exit\n"
                        "  -v, --version             print version of GEOPM to standard output,\n"
                        "                            then exit\n"
                        "\n"
                        "Copyright (c) 2015, 2016, 2017, 2018, Intel Corporation. All rights reserved.\n"
                        "\n";

    static struct option long_options[] = {
        {"agent", required_argument, NULL, 'a'},
        {"policy", required_argument, NULL, 'p'},
        {"help", no_argument, NULL, 'h'},
        {"version", no_argument, NULL, 'v'},
        {NULL, 0, NULL, 0}
    };

    while (!err && (opt = getopt_long(argc, argv, "a:p:hv", long_options, NULL)) != -1) {
        arg_ptr = NULL;
        switch (opt) {
            case 'a':
                arg_ptr = agent_str;
                break;
            case 'p':
                arg_ptr = policy_vals_str;
                break;
            case 'h':
                printf("%s", usage);
                return 0;
            case 'v':
                printf("%s\n", geopm_version());
                printf("\n\nCopyright (c) 2015, 2016, 2017, 2018, Intel Corporation. All rights reserved.\n\n");
                return 0;
            case '?': // opt is ? when an option required an arg but it was missing
                fprintf(stderr, usage, argv[0]);
                err = EINVAL;
                break;
            default:
                fprintf(stderr, "Error: getopt returned character code \"0%o\"\n", opt);
                err = EINVAL;
                break;
        }

        if (!err) {
            strncpy(arg_ptr, optarg, GEOPMAGENT_STRING_LENGTH);
            if (arg_ptr[GEOPMAGENT_STRING_LENGTH - 1] != '\0') {
                fprintf(stderr, "Error: config_file name too long\n");
                err = EINVAL;
            }
        }
    }

    if (!err && optind != argc) {
        fprintf(stderr, "Error: The following positional argument(s) are in error:\n");
        while (optind < argc) {
            fprintf(stderr, "%s\n", argv[optind++]);
        }
        err = EINVAL;
    }

    if (!err) {
        if (strnlen(agent_str, GEOPMAGENT_STRING_LENGTH)) {
            agent_ptr = agent_str;
        }
        if (strnlen(policy_vals_str, GEOPMAGENT_STRING_LENGTH)) {
            policy_vals_ptr = policy_vals_str;
        }
    }

    if (!err && argc == 1) {
        err = geopm_agent_num_avail(&output_num);
        if (!err) {
            for(int i = 0; !err && i < output_num; ++i) {
                err = geopm_agent_name(i, sizeof(output_str), output_str);
                if (!err) {
                    printf("%s\n", output_str);
                }
            }
        }
    }
    else if (!err && agent_ptr != NULL && policy_vals_ptr == NULL) {
        err = geopm_agent_supported(agent_ptr);

        // Policies
        if (!err) {
            err = geopm_agent_num_policy(agent_ptr, &output_num);
        }

        if (!err) {
            printf("Policy: ");
            for (int i = 0; !err && i < output_num; ++i) {
                err = geopm_agent_policy_name(agent_ptr, i, sizeof(output_str), output_str);
                if (!err) {
                    if (i > 0) {
                        printf(",");
                    }
                    printf("%s", output_str);
                }
            }
            if (!err && output_num == 0) {
                printf("(none)\n");
            }
            else {
                printf("\n");
            }
        }

        // Samples
        if (!err) {
            err = geopm_agent_num_sample(agent_ptr, &output_num);
        }

        if (!err) {
            printf("Sample: ");
            for (int i = 0; !err && i < output_num; ++i) {
                err = geopm_agent_sample_name(agent_ptr, i, sizeof(output_str), output_str);
                if (!err) {
                    if (i > 0) {
                        printf(",");
                    }
                    printf("%s", output_str);
                }
            }
            if (!err && output_num == 0) {
                printf("(none)\n");
            }
            else {
                printf("\n");
            }
        }
    }
    else if (!err) {

        if (agent_ptr == NULL) {
            fprintf(stderr, "Error: Agent (-a) must be specified to create a policy.\n");
            err = EINVAL;
        }

        int num_policy = 0;
        if (!err) {
            err = geopm_agent_num_policy(agent_ptr, &num_policy);
        }

        if (!err) {
            if (num_policy) {
                int policy_count = 0;
                char *tok = strtok(policy_vals_ptr, ",");
                while (!err && tok != NULL) {
                    policy_vals[policy_count++] = atof(tok);
                    if (policy_count > GEOPMAGENT_DOUBLE_LENGTH) {
                        err = E2BIG;
                    }
                    tok = strtok(NULL, ",");
                }
                if (!err && num_policy != policy_count) {
                    fprintf(stderr, "Error: Number of policies read from command line does not match agent.\n");
                    err = EINVAL;
                }
            }
            else if (strncmp(policy_vals_ptr, "none", 4) != 0 &&
                     strncmp(policy_vals_ptr, "None", 4) != 0) {
                fprintf(stderr, "Error: Must specify \"None\" for the parameter option if agent takes no parameters.\n");
                err = EINVAL;
            }
        }
        if(!err) {
            err = geopm_agent_policy_json(agent_ptr, policy_vals, sizeof(output_str), output_str);
            printf("%s\n", output_str);
        }
    }

    if (err) {
        geopm_error_message(err, error_str, GEOPMAGENT_STRING_LENGTH);
        fprintf(stderr, "Error: %s\n", error_str);
    }

    return err;
}
Esempio n. 2
0
int main(int argc, char** argv)
{
    int opt;
    int err = 0;
    int exec_mode = 0;
    char file[GEOPMPOLICY_STRING_LENGTH] = {0};
    char mode_string[GEOPMPOLICY_STRING_LENGTH] = {0};
    char option_string[GEOPMPOLICY_STRING_LENGTH] = {0};
    char copy_string[GEOPMPOLICY_STRING_LENGTH] = {0};
    char error_string[GEOPMPOLICY_STRING_LENGTH] = {0};
    FILE *infile;
    FILE *outfile;
    char *arg_ptr = NULL;
    struct geopm_policy_c *policy = NULL;

    const char *usage = "   geopmpolicy --version | --help\n"
                        "   geopmpolicy -c -f output -m mode -d key0:value0,key1:value1...\n"
                        "   geopmpolicy -e (-f input | -m mode -d key0:value0,key1:value1...)\n"
                        "   geopmpolicy -s [-f output]\n"
                        "   geopmpolicy -r [-f input]\n"
                        "   geopmpolicy -w [-f output]\n"
                        "\n"
                        "   --version\n"
                        "      Print version of geopm to standard file, then exit.\n"
                        "\n"
                        "   --help\n"
                        "       Print  brief   summary  of   the  command   line  usage\n"
                        "       information, then exit.\n"
                        "\n"
                        "   -c\n"
                        "       Create a geopm(3) configuration file, -f must be specified\n"
                        "       when using this option which gives the path to the output\n"
                        "       configuration file.\n"
                        "\n"
                        "   -e\n"
                        "       Enforce a static power mode, this mode can be specified\n"
                        "       with the -m and -d options or the -f option.\n"
                        "\n"
                        "   -s\n"
                        "       Create an in MSR save state file for all MSR values that\n"
                        "       geopm(3)  may modify.  The file file can be specified\n"
                        "       with -f.\n"
                        "\n"
                        "   -r\n"
                        "       Restore the MSR values that are recorded in an existing\n"
                        "       MSR save state file.  The input file can be  specified\n"
                        "       with the -f option.\n"
                        "\n"
                        "   -w\n"
                        "       Create a Linux msr driver whitelist file for the current\n"
                        "       platform, -f must  be  specified when using this option which\n"
                        "       gives the path to the output whitelist file.\n"
                        "\n"
                        "   -m mode\n"
                        "       Power management mode, must be one of those described\n"
                        "       in the MODES section of geopmpolicy(3). The static modes do not\n"
                        "       require the geopm runtime to be running concurrently\n"
                        "       with the primary computational application, where as\n"
                        "       dynamic modes do have a runtime requirement on geopm.\n"
                        "\n"
                        "   -d key0:value0,key1:value1...\n"
                        "       Specifies a dictionary of key value pairs which modify\n"
                        "       the behavior of a mode. The key and value options for each\n"
                        "       mode are described in the MODES sections of geopmpolicy(3).\n"
                        "\n"
                        "   -f file_path\n"
                        "       When used with -c or -s file_path is an file file.  When\n"
                        "       used with -e or -r file_path is an file file.  This is a\n"
                        "       geopm(3) configuration file when used with -c or -e and an\n"
                        "       MSR save state file when used with -s or -r.\n"
                        "\n"
                        "     Copyright (C) 2015, 2016, Intel Corporation. All rights reserved.\n"
                        "\n";

    if (argc < 2) {
        fprintf(stderr, "Error: No arguments specified\n");
        fprintf(stderr, usage, argv[0]);
        return EINVAL;
    }
    if (strncmp(argv[1], "--version", strlen("--version") + 1) == 0) {
        printf("%s\n",geopm_version());
        printf("\n\nCopyright (C) 2015, 2016, Intel Corporation. All rights reserved.\n\n");
        return 0;
    }
    if (strncmp(argv[1], "--help", strlen("--help") + 1) == 0) {
        printf("%s\n",usage);
        return 0;
    }

    while (!err && (opt = getopt(argc, argv, "hcesrwm:d:f:")) != -1) {
        arg_ptr = NULL;
        switch (opt) {
            case 'c':
                exec_mode = GEOPMPOLICY_EXEC_MODE_CREATE;
                break;
            case 'e':
                exec_mode = GEOPMPOLICY_EXEC_MODE_ENFORCE;
                break;
            case 's':
                exec_mode = GEOPMPOLICY_EXEC_MODE_SAVE;
                break;
            case 'r':
                exec_mode = GEOPMPOLICY_EXEC_MODE_RESTORE;
                break;
            case 'w':
                exec_mode = GEOPMPOLICY_EXEC_MODE_WHITELIST;
                break;
            case 'm':
                arg_ptr = mode_string;
                break;
            case 'd':
                arg_ptr = option_string;
                break;
            case 'f':
                arg_ptr = file;
                break;
            case 'h':
                printf("%s\n",usage);
                return 0;
            default:
                fprintf(stderr, "Error: unknown parameter \"%c\"\n", opt);
                fprintf(stderr, usage, argv[0]);
                err = EINVAL;
                break;
        }
        if (!err && optarg != NULL) {
            strncpy(arg_ptr, optarg, GEOPMPOLICY_STRING_LENGTH);
            if (arg_ptr[GEOPMPOLICY_STRING_LENGTH - 1] != '\0') {
                fprintf(stderr, "Error: option string too long\n");
                err = EINVAL;
            }
        }
    }

    if (!err && optind != argc) {
        fprintf(stderr, "Error: %s does not take positional arguments\n", argv[0]);
        fprintf(stderr, usage, argv[0]);
        err = EINVAL;
    }

    if (!err && (exec_mode == GEOPMPOLICY_EXEC_MODE_CREATE &&
                 (strlen(mode_string) == 0 || strlen(option_string) == 0))) {
        fprintf(stderr, "Error: In execute mode create, -m and -d are not optional\n");
        err = EINVAL;
    }

    if (!err && (exec_mode == GEOPMPOLICY_EXEC_MODE_ENFORCE && strlen(file) == 0 &&
                 (strlen(mode_string) == 0 || strlen(option_string) == 0))) {
        fprintf(stderr, "Error: In execute mode enforce, either -i or -m and -d must be specified\n");
        err = EINVAL;
    }

    if (!err && exec_mode == GEOPMPOLICY_EXEC_MODE_ENFORCE && strlen(file) > 0) {
        infile = fopen(file, "r");
        if (infile == NULL) {
            fprintf(stderr, "Error: Cannot open specified file for reading: %s\n", file);
            err = EINVAL;
        }
        else {
            fclose(infile);
        }
    }

    if (!err && exec_mode == GEOPMPOLICY_EXEC_MODE_RESTORE) {
        if(strlen(file) == 0) {
            snprintf(file, GEOPMPOLICY_STRING_LENGTH, "/tmp/.geopm_msr_restore.log");
        }
        else {
            //Make sure we are using tempfs to keep these files local to the machine
            if (strncmp(file, "/tmp/", 5)) {
                if (strlen(file) > (GEOPMPOLICY_STRING_LENGTH - strlen("/tmp/"))) {
                    fprintf(stderr, "Error: Specified file path too long\n");
                    err = EINVAL;
                }
                if (!err) {
                    if (file[0] == '/') {
                        snprintf(copy_string, GEOPMPOLICY_STRING_LENGTH, "/tmp%s", file);
                        strncpy(file, copy_string, GEOPMPOLICY_STRING_LENGTH);
                    }
                    else {
                        snprintf(copy_string, GEOPMPOLICY_STRING_LENGTH, "/tmp/%s", file);
                        strncpy(file, copy_string, GEOPMPOLICY_STRING_LENGTH);
                    }
                }
            }
        }
        infile = fopen(file, "r");
        if (infile == NULL) {
            fprintf(stderr, "Error: Cannot open file for reading: %s\n", file);
            err = EINVAL;
        }
        else {
            fclose(infile);
        }
    }


    if (!err && exec_mode == GEOPMPOLICY_EXEC_MODE_CREATE) {
        outfile = fopen(file, "w");
        if (outfile == NULL) {
            fprintf(stderr, "Error: Cannot open specified file for writing: %s\n", file);
            err = EINVAL;
        }
        else {
            fclose(outfile);
        }
    }

    if (!err && exec_mode == GEOPMPOLICY_EXEC_MODE_SAVE) {
        struct stat statbuffer;
        char* pdir;

        if(strlen(file) == 0) {
            snprintf(file, GEOPMPOLICY_STRING_LENGTH, "/tmp/.geopm_msr_restore.log");
        }
        else {
            //Make sure we are using tempfs to keep these files local to the machine
            if (strncmp(file, "/tmp/", 5)) {
                if (strlen(file) > (GEOPMPOLICY_STRING_LENGTH - strlen("/tmp/"))) {
                    fprintf(stderr, "Error: Specified file path too long\n");
                    err = EINVAL;
                }
                if (!err) {
                    if (file[0] == '/') {
                        snprintf(copy_string, GEOPMPOLICY_STRING_LENGTH, "/tmp%s", file);
                        strncpy(file, copy_string, GEOPMPOLICY_STRING_LENGTH);
                    }
                    else {
                        printf("file = %s\n",file);
                        snprintf(copy_string, GEOPMPOLICY_STRING_LENGTH, "/tmp/%s", file);
                        strncpy(file, copy_string, GEOPMPOLICY_STRING_LENGTH);
                        printf("file = %s\n",file);
                    }
                }
            }
        }
        //make sure path exists, if not, create
        pdir = dirname(copy_string);
        for(int i = 1; i < strlen(pdir); i++) {
            if (pdir[i] == '/') {
                pdir[i] = 0;
                if(stat(pdir, &statbuffer) == -1) {
                    if(mkdir(pdir, S_IRWXU)) {
                        fprintf(stderr, "Error: Could not create directory %s\n", dirname(file));
                        return errno ? errno : GEOPM_ERROR_RUNTIME;
                    }
                }
                pdir[i] = '/';
            }
        }
        if(stat(pdir, &statbuffer) == -1) {
            if(mkdir(pdir, S_IRWXU)) {
                fprintf(stderr, "Error: Could not create directory %s\n", dirname(file));
                return errno ? errno : GEOPM_ERROR_RUNTIME;
            }
        }
        outfile = fopen(file, "w");
        if (outfile == NULL) {
            fprintf(stderr, "Error: Cannot open file for writing: %s\n", file);
            err = EINVAL;
        }
        else {
            fclose(outfile);
        }
    }

    if (!err) {
        FILE *fd;
        switch (exec_mode) {
            case GEOPMPOLICY_EXEC_MODE_CREATE:
                err = geopm_policy_create("", file, &policy);
                if (!err) {
                    err = _geopm_policy_mode_parse(policy, mode_string);
                }
                if (!err) {
                    err = _geopm_policy_dict_parse(policy, option_string);
                }
                if (!err) {
                    err = geopm_policy_write(policy);
                }
                if (policy) {
                    (void) geopm_policy_destroy(policy);
                }
                break;
            case GEOPMPOLICY_EXEC_MODE_ENFORCE:
                if (strlen(file) == 0) {
                    err = geopm_policy_create("", "/tmp/geopmpolicy_tmp", &policy);
                    if (!err) {
                        err = _geopm_policy_mode_parse(policy, mode_string);
                    }
                    if (!err) {
                        err = _geopm_policy_dict_parse(policy, option_string);
                    }
                }
                else {
                    err = geopm_policy_create(file, "", &policy);
                }
                if (!err) {
                    err = geopm_policy_enforce_static(policy);
                }
                if (policy) {
                    (void) geopm_policy_destroy(policy);
                }
                break;
            case GEOPMPOLICY_EXEC_MODE_SAVE:
                err = geopm_platform_msr_save(file);
                break;
            case GEOPMPOLICY_EXEC_MODE_RESTORE:
                err = geopm_platform_msr_restore(file);
                break;
            case GEOPMPOLICY_EXEC_MODE_WHITELIST:
                if (strlen(file) == 0) {
                    fd = stdout;
                }
                else {
                    fd = fopen(file, "w");
                    if (fd == NULL) {
                        err = errno ? errno : GEOPM_ERROR_RUNTIME;
                    }
                }
                if (!err) {
                    err = geopm_platform_msr_whitelist(fd);
                    fclose(fd);
                }
                break;
            default:
                fprintf(stderr, "Error: Invalid execution mode.\n");
                err = EINVAL;
                break;
        };
    }

    if (err) {
        geopm_error_message(err, error_string, GEOPMPOLICY_STRING_LENGTH);
        fprintf(stderr, "Error: %s.\n", error_string);
    }
    return err;
}