header.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Implementation of get_cpuid().
  3. *
  4. * Copyright IBM Corp. 2014, 2018
  5. * Author(s): Alexander Yarygin <yarygin@linux.vnet.ibm.com>
  6. * Thomas Richter <tmricht@linux.vnet.ibm.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License (version 2 only)
  10. * as published by the Free Software Foundation.
  11. */
  12. #include <sys/types.h>
  13. #include <unistd.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include "../../util/header.h"
  18. #include "../../util/util.h"
  19. #define SYSINFO_MANU "Manufacturer:"
  20. #define SYSINFO_TYPE "Type:"
  21. #define SYSINFO_MODEL "Model:"
  22. #define SRVLVL_CPUMF "CPU-MF:"
  23. #define SRVLVL_VERSION "version="
  24. #define SRVLVL_AUTHORIZATION "authorization="
  25. #define SYSINFO "/proc/sysinfo"
  26. #define SRVLVL "/proc/service_levels"
  27. int get_cpuid(char *buffer, size_t sz)
  28. {
  29. char *cp, *line = NULL, *line2;
  30. char type[8], model[33], version[8], manufacturer[32], authorization[8];
  31. int tpsize = 0, mdsize = 0, vssize = 0, mfsize = 0, atsize = 0;
  32. int read;
  33. unsigned long line_sz;
  34. size_t nbytes;
  35. FILE *sysinfo;
  36. /*
  37. * Scan /proc/sysinfo line by line and read out values for
  38. * Manufacturer:, Type: and Model:, for example:
  39. * Manufacturer: IBM
  40. * Type: 2964
  41. * Model: 702 N96
  42. * The first word is the Model Capacity and the second word is
  43. * Model (can be omitted). Both words have a maximum size of 16
  44. * bytes.
  45. */
  46. memset(manufacturer, 0, sizeof(manufacturer));
  47. memset(type, 0, sizeof(type));
  48. memset(model, 0, sizeof(model));
  49. memset(version, 0, sizeof(version));
  50. memset(authorization, 0, sizeof(authorization));
  51. sysinfo = fopen(SYSINFO, "r");
  52. if (sysinfo == NULL)
  53. return -1;
  54. while ((read = getline(&line, &line_sz, sysinfo)) != -1) {
  55. if (!strncmp(line, SYSINFO_MANU, strlen(SYSINFO_MANU))) {
  56. line2 = line + strlen(SYSINFO_MANU);
  57. while ((cp = strtok_r(line2, "\n ", &line2))) {
  58. mfsize += scnprintf(manufacturer + mfsize,
  59. sizeof(manufacturer) - mfsize, "%s", cp);
  60. }
  61. }
  62. if (!strncmp(line, SYSINFO_TYPE, strlen(SYSINFO_TYPE))) {
  63. line2 = line + strlen(SYSINFO_TYPE);
  64. while ((cp = strtok_r(line2, "\n ", &line2))) {
  65. tpsize += scnprintf(type + tpsize,
  66. sizeof(type) - tpsize, "%s", cp);
  67. }
  68. }
  69. if (!strncmp(line, SYSINFO_MODEL, strlen(SYSINFO_MODEL))) {
  70. line2 = line + strlen(SYSINFO_MODEL);
  71. while ((cp = strtok_r(line2, "\n ", &line2))) {
  72. mdsize += scnprintf(model + mdsize, sizeof(model) - mdsize,
  73. "%s%s", model[0] ? "," : "", cp);
  74. }
  75. break;
  76. }
  77. }
  78. fclose(sysinfo);
  79. /* Missing manufacturer, type or model information should not happen */
  80. if (!manufacturer[0] || !type[0] || !model[0])
  81. return -1;
  82. /*
  83. * Scan /proc/service_levels and return the CPU-MF counter facility
  84. * version number and authorization level.
  85. * Optional, does not exist on z/VM guests.
  86. */
  87. sysinfo = fopen(SRVLVL, "r");
  88. if (sysinfo == NULL)
  89. goto skip_sysinfo;
  90. while ((read = getline(&line, &line_sz, sysinfo)) != -1) {
  91. if (strncmp(line, SRVLVL_CPUMF, strlen(SRVLVL_CPUMF)))
  92. continue;
  93. line2 = line + strlen(SRVLVL_CPUMF);
  94. while ((cp = strtok_r(line2, "\n ", &line2))) {
  95. if (!strncmp(cp, SRVLVL_VERSION,
  96. strlen(SRVLVL_VERSION))) {
  97. char *sep = strchr(cp, '=');
  98. vssize += scnprintf(version + vssize,
  99. sizeof(version) - vssize, "%s", sep + 1);
  100. }
  101. if (!strncmp(cp, SRVLVL_AUTHORIZATION,
  102. strlen(SRVLVL_AUTHORIZATION))) {
  103. char *sep = strchr(cp, '=');
  104. atsize += scnprintf(authorization + atsize,
  105. sizeof(authorization) - atsize, "%s", sep + 1);
  106. }
  107. }
  108. }
  109. fclose(sysinfo);
  110. skip_sysinfo:
  111. free(line);
  112. if (version[0] && authorization[0] )
  113. nbytes = snprintf(buffer, sz, "%s,%s,%s,%s,%s",
  114. manufacturer, type, model, version,
  115. authorization);
  116. else
  117. nbytes = snprintf(buffer, sz, "%s,%s,%s", manufacturer, type,
  118. model);
  119. return (nbytes >= sz) ? -1 : 0;
  120. }
  121. char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
  122. {
  123. char *buf = malloc(128);
  124. if (buf && get_cpuid(buf, 128) < 0)
  125. zfree(&buf);
  126. return buf;
  127. }