Home | History | Annotate | Download | only in lk
      1 #include <errno.h>
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <stdbool.h>
      6 #include <sys/vfs.h>
      7 #include <sys/mount.h>
      8 #include <linux/kernel.h>
      9 
     10 #include "debugfs.h"
     11 
     12 char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug";
     13 
     14 static const char * const debugfs_known_mountpoints[] = {
     15 	"/sys/kernel/debug/",
     16 	"/debug/",
     17 	0,
     18 };
     19 
     20 static bool debugfs_found;
     21 
     22 /* find the path to the mounted debugfs */
     23 const char *debugfs_find_mountpoint(void)
     24 {
     25 	const char * const *ptr;
     26 	char type[100];
     27 	FILE *fp;
     28 
     29 	if (debugfs_found)
     30 		return (const char *)debugfs_mountpoint;
     31 
     32 	ptr = debugfs_known_mountpoints;
     33 	while (*ptr) {
     34 		if (debugfs_valid_mountpoint(*ptr) == 0) {
     35 			debugfs_found = true;
     36 			strcpy(debugfs_mountpoint, *ptr);
     37 			return debugfs_mountpoint;
     38 		}
     39 		ptr++;
     40 	}
     41 
     42 	/* give up and parse /proc/mounts */
     43 	fp = fopen("/proc/mounts", "r");
     44 	if (fp == NULL)
     45 		return NULL;
     46 
     47 	while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n",
     48 		      debugfs_mountpoint, type) == 2) {
     49 		if (strcmp(type, "debugfs") == 0)
     50 			break;
     51 	}
     52 	fclose(fp);
     53 
     54 	if (strcmp(type, "debugfs") != 0)
     55 		return NULL;
     56 
     57 	debugfs_found = true;
     58 
     59 	return debugfs_mountpoint;
     60 }
     61 
     62 /* verify that a mountpoint is actually a debugfs instance */
     63 
     64 int debugfs_valid_mountpoint(const char *debugfs)
     65 {
     66 	struct statfs st_fs;
     67 
     68 	if (statfs(debugfs, &st_fs) < 0)
     69 		return -ENOENT;
     70 	else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
     71 		return -ENOENT;
     72 
     73 	return 0;
     74 }
     75 
     76 /* mount the debugfs somewhere if it's not mounted */
     77 char *debugfs_mount(const char *mountpoint)
     78 {
     79 #ifdef __APPLE__
     80 	goto out;
     81 #else
     82 	/* see if it's already mounted */
     83 	if (debugfs_find_mountpoint())
     84 		goto out;
     85 
     86 	/* if not mounted and no argument */
     87 	if (mountpoint == NULL) {
     88 		/* see if environment variable set */
     89 		mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT);
     90 		/* if no environment variable, use default */
     91 		if (mountpoint == NULL)
     92 			mountpoint = "/sys/kernel/debug";
     93 	}
     94 
     95 	if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0)
     96 		return NULL;
     97 
     98 	/* save the mountpoint */
     99 	debugfs_found = true;
    100 	strncpy(debugfs_mountpoint, mountpoint, sizeof(debugfs_mountpoint));
    101 #endif
    102 out:
    103 	return debugfs_mountpoint;
    104 }
    105