Page MenuHomeFreeBSD

D8234.diff
No OneTemporary

D8234.diff

Index: usr.sbin/pmcstat/pmcstat.h
===================================================================
--- usr.sbin/pmcstat/pmcstat.h
+++ usr.sbin/pmcstat/pmcstat.h
@@ -127,6 +127,11 @@
pid_t pt_pid;
};
+struct pmcstat_path {
+ STAILQ_ENTRY(pmcstat_path) pp_next;
+ char *pp_path; /* pathname */
+};
+
struct pmcstat_args {
int pa_flags; /* argument flags */
int pa_required; /* required features */
@@ -140,6 +145,7 @@
void *pa_logparser; /* log file parser */
const char *pa_fsroot; /* FS root where executables reside */
char *pa_kernel; /* pathname of the kernel */
+ char *pa_module_path; /* pathnames of the kernel modules */
const char *pa_samplesdir; /* directory for profile files */
const char *pa_mapfilename;/* mapfile name */
FILE *pa_graphfile; /* where to send the callgraph */
@@ -156,6 +162,7 @@
char **pa_argv;
STAILQ_HEAD(, pmcstat_ev) pa_events;
SLIST_HEAD(, pmcstat_target) pa_targets;
+ STAILQ_HEAD(, pmcstat_path) pa_modules;
};
extern int pmcstat_displayheight; /* current terminal height */
Index: usr.sbin/pmcstat/pmcstat.8
===================================================================
--- usr.sbin/pmcstat/pmcstat.8
+++ usr.sbin/pmcstat/pmcstat.8
@@ -38,6 +38,7 @@
.Op Fl E
.Op Fl F Ar pathname
.Op Fl G Ar pathname
+.Op Fl K Ar dir-list
.Op Fl M Ar mapfilename
.Op Fl N
.Op Fl O Ar logfilename
@@ -155,6 +156,18 @@
this information is sent to the output file specified by the
.Fl o
option.
+.It Fl K Ar dir-list
+Set the list of pathnames of the kernel module directories to argument
+.Ar dir-list .
+This directory list specifies where
+.Nm
+should look for the kernel modules.
+Argument
+.Ar dir-list
+is a colon separated list of paths to use in searching for modules.
+The default is to use the module path of the running kernel obtained from the
+.Va kern.module_path
+sysctl.
.It Fl M Ar mapfilename
Write the mapping between executable objects encountered in the event
log and the abbreviated pathnames used for
Index: usr.sbin/pmcstat/pmcstat.c
===================================================================
--- usr.sbin/pmcstat/pmcstat.c
+++ usr.sbin/pmcstat/pmcstat.c
@@ -497,6 +497,7 @@
"\t -F file\t write a system-wide callgraph (Kcachegrind format)"
" to \"file\"\n"
"\t -G file\t write a system-wide callgraph to \"file\"\n"
+ "\t -K dir-list\t set the paths to check for kernel modules\n"
"\t -M file\t print executable/gmon file map to \"file\"\n"
"\t -N\t\t (toggle) capture callchains\n"
"\t -O file\t send log output to \"file\"\n"
@@ -565,11 +566,12 @@
int pipefd[2], rfd;
int use_cumulative_counts;
short cf, cb;
- char *end, *tmp;
+ char *end, *modpath, *mp, *tmp;
const char *errmsg, *graphfilename;
enum pmcstat_state runstate;
struct pmc_driverstats ds_start, ds_end;
struct pmcstat_ev *ev;
+ struct pmcstat_path *pp;
struct sigaction sa;
struct kevent kev;
struct winsize ws;
@@ -607,6 +609,7 @@
args.pa_duration = 0.0;
STAILQ_INIT(&args.pa_events);
SLIST_INIT(&args.pa_targets);
+ STAILQ_INIT(&args.pa_modules);
bzero(&ds_start, sizeof(ds_start));
bzero(&ds_end, sizeof(ds_end));
ev = NULL;
@@ -622,6 +625,18 @@
if (sysctlbyname("kern.bootfile", args.pa_kernel, &len, NULL, 0) == -1)
err(EX_OSERR, "ERROR: Cannot determine path of running kernel");
+ len = 0;
+ if (sysctlbyname("kern.module_path", NULL, &len, NULL, 0) == -1)
+ err(EX_OSERR,
+ "ERROR: Cannot determine running kernel module paths");
+ args.pa_module_path = malloc(len);
+ if (args.pa_module_path == NULL)
+ errx(EX_SOFTWARE, "ERROR: Out of memory.");
+ if (sysctlbyname("kern.module_path", args.pa_module_path, &len, NULL,
+ 0) == -1)
+ err(EX_OSERR,
+ "ERROR: Cannot determine running kernel module paths");
+
/*
* The initial CPU mask specifies the root mask of this process
* which is usually all CPUs in the system.
@@ -632,7 +647,7 @@
CPU_COPY(&rootmask, &cpumask);
while ((option = getopt(argc, argv,
- "CD:EF:G:M:NO:P:R:S:TWa:c:def:gk:l:m:n:o:p:qr:s:t:vw:z:")) != -1)
+ "CD:EF:G:K:M:NO:P:R:S:TWa:c:def:gk:l:m:n:o:p:qr:s:t:vw:z:")) != -1)
switch (option) {
case 'a': /* Annotate + callgraph */
args.pa_flags |= FLAG_DO_ANNOTATE;
@@ -710,6 +725,13 @@
args.pa_flags |= FLAG_HAS_KERNELPATH;
break;
+ case 'K': /* paths to kernel modules */
+ free(args.pa_module_path);
+ args.pa_module_path = strdup(optarg);
+ if (args.pa_module_path == NULL)
+ errx(EX_SOFTWARE, "ERROR: Out of memory");
+ break;
+
case 'l': /* time duration in seconds */
duration = strtod(optarg, &end);
if (*end != '\0' || duration <= 0)
@@ -1111,6 +1133,20 @@
}
/*
+ * Build the kernel modules pathname list
+ */
+ mp = args.pa_module_path;
+ while ((modpath = strsep(&mp, ":;")) != NULL) {
+ if (*modpath == '\0')
+ continue;
+ pp = malloc(sizeof(*pp));
+ if (pp == NULL)
+ errx(EX_SOFTWARE, "ERROR: Out of memory.");
+ pp->pp_path = modpath;
+ STAILQ_INSERT_TAIL(&args.pa_modules, pp, pp_next);
+ }
+
+ /*
* If we have a callgraph be created, select the outputfile.
*/
if (args.pa_flags & FLAG_DO_CALLGRAPHS) {
Index: usr.sbin/pmcstat/pmcstat_log.c
===================================================================
--- usr.sbin/pmcstat/pmcstat_log.c
+++ usr.sbin/pmcstat/pmcstat_log.c
@@ -608,6 +608,27 @@
symptr->ps_end = (symptr+1)->ps_start;
}
+static int
+pmcstat_find_module(const char *path, char *buffer, size_t len)
+{
+ struct pmcstat_path *pp;
+
+ /* Try the module list */
+ STAILQ_FOREACH(pp, &args.pa_modules, pp_next) {
+ snprintf(buffer, len, "%s%s/%s", args.pa_fsroot, pp->pp_path,
+ path);
+ if (access(buffer, R_OK) != -1)
+ return (1);
+ }
+
+ /* Try the kernel path */
+ snprintf(buffer, len, "%s%s/%s", args.pa_fsroot, args.pa_kernel, path);
+ if (access(buffer, R_OK) != -1)
+ return (1);
+
+ return (0);
+}
+
/*
* Examine an ELF file to determine the size of its text segment.
* Sets image->pi_type if anything conclusive can be determined about
@@ -646,10 +667,11 @@
* Look for kernel modules under FSROOT/KERNELPATH/NAME,
* and user mode executable objects under FSROOT/PATHNAME.
*/
- if (image->pi_iskernelmodule)
- (void) snprintf(buffer, sizeof(buffer), "%s%s/%s",
- args.pa_fsroot, args.pa_kernel, path);
- else
+ if (image->pi_iskernelmodule) {
+ if (pmcstat_find_module(path, buffer, sizeof(buffer)) == 0)
+ warnx("WARNING: Cannot find kernel module \"%s\".",
+ path);
+ } else
(void) snprintf(buffer, sizeof(buffer), "%s%s",
args.pa_fsroot, path);

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 27, 10:00 PM (8 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15618010
Default Alt Text
D8234.diff (6 KB)

Event Timeline