1 #include "../perf.h" 2 #include "util.h" 3 #include "debug.h" 4 #include <api/fs/fs.h> 5 #include <sys/mman.h> 6 #include <sys/stat.h> 7 #include <sys/utsname.h> 8 #include <dirent.h> 9 #include <inttypes.h> 10 #include <signal.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <errno.h> 15 #include <limits.h> 16 #include <linux/kernel.h> 17 #include <linux/log2.h> 18 #include <linux/time64.h> 19 #include <unistd.h> 20 #include "strlist.h" 21 22 /* 23 * XXX We need to find a better place for these things... 24 */ 25 unsigned int page_size; 26 int cacheline_size; 27 28 int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; 29 int sysctl_perf_event_max_contexts_per_stack = PERF_MAX_CONTEXTS_PER_STACK; 30 31 bool test_attr__enabled; 32 33 bool perf_host = true; 34 bool perf_guest = false; 35 36 void event_attr_init(struct perf_event_attr *attr) 37 { 38 if (!perf_host) 39 attr->exclude_host = 1; 40 if (!perf_guest) 41 attr->exclude_guest = 1; 42 /* to capture ABI version */ 43 attr->size = sizeof(*attr); 44 } 45 46 int mkdir_p(char *path, mode_t mode) 47 { 48 struct stat st; 49 int err; 50 char *d = path; 51 52 if (*d != '/') 53 return -1; 54 55 if (stat(path, &st) == 0) 56 return 0; 57 58 while (*++d == '/'); 59 60 while ((d = strchr(d, '/'))) { 61 *d = '\0'; 62 err = stat(path, &st) && mkdir(path, mode); 63 *d++ = '/'; 64 if (err) 65 return -1; 66 while (*d == '/') 67 ++d; 68 } 69 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 70 } 71 72 int rm_rf(const char *path) 73 { 74 DIR *dir; 75 int ret = 0; 76 struct dirent *d; 77 char namebuf[PATH_MAX]; 78 79 dir = opendir(path); 80 if (dir == NULL) 81 return 0; 82 83 while ((d = readdir(dir)) != NULL && !ret) { 84 struct stat statbuf; 85 86 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) 87 continue; 88 89 scnprintf(namebuf, sizeof(namebuf), "%s/%s", 90 path, d->d_name); 91 92 /* We have to check symbolic link itself */ 93 ret = lstat(namebuf, &statbuf); 94 if (ret < 0) { 95 pr_debug("stat failed: %s\n", namebuf); 96 break; 97 } 98 99 if (S_ISDIR(statbuf.st_mode)) 100 ret = rm_rf(namebuf); 101 else 102 ret = unlink(namebuf); 103 } 104 closedir(dir); 105 106 if (ret < 0) 107 return ret; 108 109 return rmdir(path); 110 } 111 112 /* A filter which removes dot files */ 113 bool lsdir_no_dot_filter(const char *name __maybe_unused, struct dirent *d) 114 { 115 return d->d_name[0] != '.'; 116 } 117 118 /* lsdir reads a directory and store it in strlist */ 119 struct strlist *lsdir(const char *name, 120 bool (*filter)(const char *, struct dirent *)) 121 { 122 struct strlist *list = NULL; 123 DIR *dir; 124 struct dirent *d; 125 126 dir = opendir(name); 127 if (!dir) 128 return NULL; 129 130 list = strlist__new(NULL, NULL); 131 if (!list) { 132 errno = ENOMEM; 133 goto out; 134 } 135 136 while ((d = readdir(dir)) != NULL) { 137 if (!filter || filter(name, d)) 138 strlist__add(list, d->d_name); 139 } 140 141 out: 142 closedir(dir); 143 return list; 144 } 145 146 static int slow_copyfile(const char *from, const char *to, struct nsinfo *nsi) 147 { 148 int err = -1; 149 char *line = NULL; 150 size_t n; 151 FILE *from_fp, *to_fp; 152 struct nscookie nsc; 153 154 nsinfo__mountns_enter(nsi, &nsc); 155 from_fp = fopen(from, "r"); 156 nsinfo__mountns_exit(&nsc); 157 if (from_fp == NULL) 158 goto out; 159 160 to_fp = fopen(to, "w"); 161 if (to_fp == NULL) 162 goto out_fclose_from; 163 164 while (getline(&line, &n, from_fp) > 0) 165 if (fputs(line, to_fp) == EOF) 166 goto out_fclose_to; 167 err = 0; 168 out_fclose_to: 169 fclose(to_fp); 170 free(line); 171 out_fclose_from: 172 fclose(from_fp); 173 out: 174 return err; 175 } 176 177 int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) 178 { 179 void *ptr; 180 loff_t pgoff; 181 182 pgoff = off_in & ~(page_size - 1); 183 off_in -= pgoff; 184 185 ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff); 186 if (ptr == MAP_FAILED) 187 return -1; 188 189 while (size) { 190 ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out); 191 if (ret < 0 && errno == EINTR) 192 continue; 193 if (ret <= 0) 194 break; 195 196 size -= ret; 197 off_in += ret; 198 off_out -= ret; 199 } 200 munmap(ptr, off_in + size); 201 202 return size ? -1 : 0; 203 } 204 205 static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, 206 struct nsinfo *nsi) 207 { 208 int fromfd, tofd; 209 struct stat st; 210 int err; 211 char *tmp = NULL, *ptr = NULL; 212 struct nscookie nsc; 213 214 nsinfo__mountns_enter(nsi, &nsc); 215 err = stat(from, &st); 216 nsinfo__mountns_exit(&nsc); 217 if (err) 218 goto out; 219 err = -1; 220 221 /* extra 'x' at the end is to reserve space for '.' */ 222 if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { 223 tmp = NULL; 224 goto out; 225 } 226 ptr = strrchr(tmp, '/'); 227 if (!ptr) 228 goto out; 229 ptr = memmove(ptr + 1, ptr, strlen(ptr) - 1); 230 *ptr = '.'; 231 232 tofd = mkstemp(tmp); 233 if (tofd < 0) 234 goto out; 235 236 if (fchmod(tofd, mode)) 237 goto out_close_to; 238 239 if (st.st_size == 0) { /* /proc? do it slowly... */ 240 err = slow_copyfile(from, tmp, nsi); 241 goto out_close_to; 242 } 243 244 nsinfo__mountns_enter(nsi, &nsc); 245 fromfd = open(from, O_RDONLY); 246 nsinfo__mountns_exit(&nsc); 247 if (fromfd < 0) 248 goto out_close_to; 249 250 err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size); 251 252 close(fromfd); 253 out_close_to: 254 close(tofd); 255 if (!err) 256 err = link(tmp, to); 257 unlink(tmp); 258 out: 259 free(tmp); 260 return err; 261 } 262 263 int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi) 264 { 265 return copyfile_mode_ns(from, to, 0755, nsi); 266 } 267 268 int copyfile_mode(const char *from, const char *to, mode_t mode) 269 { 270 return copyfile_mode_ns(from, to, mode, NULL); 271 } 272 273 int copyfile(const char *from, const char *to) 274 { 275 return copyfile_mode(from, to, 0755); 276 } 277 278 static ssize_t ion(bool is_read, int fd, void *buf, size_t n) 279 { 280 void *buf_start = buf; 281 size_t left = n; 282 283 while (left) { 284 /* buf must be treated as const if !is_read. */ 285 ssize_t ret = is_read ? read(fd, buf, left) : 286 write(fd, buf, left); 287 288 if (ret < 0 && errno == EINTR) 289 continue; 290 if (ret <= 0) 291 return ret; 292 293 left -= ret; 294 buf += ret; 295 } 296 297 BUG_ON((size_t)(buf - buf_start) != n); 298 return n; 299 } 300 301 /* 302 * Read exactly 'n' bytes or return an error. 303 */ 304 ssize_t readn(int fd, void *buf, size_t n) 305 { 306 return ion(true, fd, buf, n); 307 } 308 309 /* 310 * Write exactly 'n' bytes or return an error. 311 */ 312 ssize_t writen(int fd, const void *buf, size_t n) 313 { 314 /* ion does not modify buf. */ 315 return ion(false, fd, (void *)buf, n); 316 } 317 318 size_t hex_width(u64 v) 319 { 320 size_t n = 1; 321 322 while ((v >>= 4)) 323 ++n; 324 325 return n; 326 } 327 328 static int hex(char ch) 329 { 330 if ((ch >= '0') && (ch <= '9')) 331 return ch - '0'; 332 if ((ch >= 'a') && (ch <= 'f')) 333 return ch - 'a' + 10; 334 if ((ch >= 'A') && (ch <= 'F')) 335 return ch - 'A' + 10; 336 return -1; 337 } 338 339 /* 340 * While we find nice hex chars, build a long_val. 341 * Return number of chars processed. 342 */ 343 int hex2u64(const char *ptr, u64 *long_val) 344 { 345 const char *p = ptr; 346 *long_val = 0; 347 348 while (*p) { 349 const int hex_val = hex(*p); 350 351 if (hex_val < 0) 352 break; 353 354 *long_val = (*long_val << 4) | hex_val; 355 p++; 356 } 357 358 return p - ptr; 359 } 360 361 int perf_event_paranoid(void) 362 { 363 int value; 364 365 if (sysctl__read_int("kernel/perf_event_paranoid", &value)) 366 return INT_MAX; 367 368 return value; 369 } 370 static int 371 fetch_ubuntu_kernel_version(unsigned int *puint) 372 { 373 ssize_t len; 374 size_t line_len = 0; 375 char *ptr, *line = NULL; 376 int version, patchlevel, sublevel, err; 377 FILE *vsig; 378 379 if (!puint) 380 return 0; 381 382 vsig = fopen("/proc/version_signature", "r"); 383 if (!vsig) { 384 pr_debug("Open /proc/version_signature failed: %s\n", 385 strerror(errno)); 386 return -1; 387 } 388 389 len = getline(&line, &line_len, vsig); 390 fclose(vsig); 391 err = -1; 392 if (len <= 0) { 393 pr_debug("Reading from /proc/version_signature failed: %s\n", 394 strerror(errno)); 395 goto errout; 396 } 397 398 ptr = strrchr(line, ' '); 399 if (!ptr) { 400 pr_debug("Parsing /proc/version_signature failed: %s\n", line); 401 goto errout; 402 } 403 404 err = sscanf(ptr + 1, "%d.%d.%d", 405 &version, &patchlevel, &sublevel); 406 if (err != 3) { 407 pr_debug("Unable to get kernel version from /proc/version_signature '%s'\n", 408 line); 409 goto errout; 410 } 411 412 *puint = (version << 16) + (patchlevel << 8) + sublevel; 413 err = 0; 414 errout: 415 free(line); 416 return err; 417 } 418 419 int 420 fetch_kernel_version(unsigned int *puint, char *str, 421 size_t str_size) 422 { 423 struct utsname utsname; 424 int version, patchlevel, sublevel, err; 425 bool int_ver_ready = false; 426 427 if (access("/proc/version_signature", R_OK) == 0) 428 if (!fetch_ubuntu_kernel_version(puint)) 429 int_ver_ready = true; 430 431 if (uname(&utsname)) 432 return -1; 433 434 if (str && str_size) { 435 strncpy(str, utsname.release, str_size); 436 str[str_size - 1] = '\0'; 437 } 438 439 if (!puint || int_ver_ready) 440 return 0; 441 442 err = sscanf(utsname.release, "%d.%d.%d", 443 &version, &patchlevel, &sublevel); 444 445 if (err != 3) { 446 pr_debug("Unable to get kernel version from uname '%s'\n", 447 utsname.release); 448 return -1; 449 } 450 451 *puint = (version << 16) + (patchlevel << 8) + sublevel; 452 return 0; 453 } 454 455 const char *perf_tip(const char *dirpath) 456 { 457 struct strlist *tips; 458 struct str_node *node; 459 char *tip = NULL; 460 struct strlist_config conf = { 461 .dirname = dirpath, 462 .file_only = true, 463 }; 464 465 tips = strlist__new("tips.txt", &conf); 466 if (tips == NULL) 467 return errno == ENOENT ? NULL : 468 "Tip: check path of tips.txt or get more memory! ;-p"; 469 470 if (strlist__nr_entries(tips) == 0) 471 goto out; 472 473 node = strlist__entry(tips, random() % strlist__nr_entries(tips)); 474 if (asprintf(&tip, "Tip: %s", node->s) < 0) 475 tip = (char *)"Tip: get more memory! ;-)"; 476 477 out: 478 strlist__delete(tips); 479 480 return tip; 481 } 482