From: Clark Williams <williams@redhat.com>
To: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>,
Arnaldo Carvalho de Melo <acme@redhat.com>,
LKML <linux-kernel@vger.kernel.org>
Subject: [PATCH 1/3] debugfs utility routines for perf
Date: Sun, 1 Nov 2009 15:56:21 -0600 [thread overview]
Message-ID: <20091101155621.2b3503ee@torg> (raw)
In-Reply-To: <20091101155500.7dd22f19@torg>
[-- Attachment #1: Type: text/plain, Size: 6581 bytes --]
Add routines to locate the debugfs mount point and to manage the
mounting and unmountin of the debugfs.
Signed-off-by: Clark Williams <williams@redhat.com>
---
tools/perf/util/debugfs.c | 241 +++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/debugfs.h | 22 ++++
2 files changed, 263 insertions(+), 0 deletions(-)
create mode 100644 tools/perf/util/debugfs.c
create mode 100644 tools/perf/util/debugfs.h
diff --git a/tools/perf/util/debugfs.c b/tools/perf/util/debugfs.c
new file mode 100644
index 0000000..34f7983
--- /dev/null
+++ b/tools/perf/util/debugfs.c
@@ -0,0 +1,241 @@
+#include "util.h"
+#include "debugfs.h"
+#include "cache.h"
+
+static int debugfs_premounted = 0;
+static char debugfs_mountpoint[MAX_PATH+1];
+
+static const char *debugfs_known_mountpoints[] = {
+ "/sys/kernel/debug/",
+ "/debug/",
+ 0,
+};
+
+/* use this to force a umount */
+void debugfs_force_cleanup(void)
+{
+ debugfs_find_mountpoint();
+ debugfs_premounted = 0;
+ debugfs_umount();
+}
+
+/* construct a full path to a debugfs element */
+int debugfs_make_path(const char *element, char *buffer, int size)
+{
+ int len;
+
+ if (strlen(debugfs_mountpoint) == 0) {
+ buffer[0] = '\0';
+ return -1;
+ }
+
+ len = strlen(debugfs_mountpoint) + strlen(element) + 1;
+ if (len >= size)
+ return len+1;
+
+ snprintf(buffer, size-1, "%s/%s", debugfs_mountpoint, element);
+ return 0;
+}
+
+/* find the path to the mounted debugfs */
+const char *
+debugfs_find_mountpoint(void)
+{
+ static int debugfs_found = 0;
+ char type[100];
+ FILE *fp;
+ const char **ptr;
+
+ if (debugfs_found)
+ return (const char *) debugfs_mountpoint;
+
+ ptr = debugfs_known_mountpoints;
+ while(*ptr) {
+ if (debugfs_valid_mountpoint(*ptr) == 0) {
+ debugfs_found = 1;
+ strcpy(debugfs_mountpoint, *ptr);
+ return debugfs_mountpoint;
+ }
+ ptr++;
+ }
+
+ /* give up and parse /proc/mounts */
+ if ((fp = fopen("/proc/mounts","r")) == NULL)
+ die("Can't open /proc/mounts for read");
+
+ while (fscanf(fp, "%*s %"
+ STR(MAX_PATH)
+ "s %99s %*s %*d %*d\n",
+ debugfs_mountpoint, type) == 2) {
+ if (strcmp(type, "debugfs") == 0)
+ break;
+ }
+ fclose(fp);
+
+ if (strcmp(type, "debugfs") != 0)
+ return NULL;
+
+ debugfs_found = 1;
+
+ return debugfs_mountpoint;
+}
+
+/* verify that a mountpoint is actually a debugfs instance */
+
+int
+debugfs_valid_mountpoint(const char *debugfs)
+{
+ struct statfs st_fs;
+
+ if (statfs(debugfs, &st_fs) < 0)
+ return -ENOENT;
+ else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
+ return -ENOENT;
+ return 0;
+}
+
+
+int
+debugfs_valid_entry(const char *path)
+{
+ struct stat st;
+
+ if (stat(path, &st))
+ return -errno;
+ return 0;
+}
+
+/* mount the debugfs somewhere */
+
+int
+debugfs_mount(const char *mountpoint)
+{
+ char mountcmd[128];
+
+ /* see if it's already mounted */
+ if (debugfs_find_mountpoint()) {
+ debugfs_premounted = 1;
+ return 0;
+ }
+
+ /* if not mounted and no argument */
+ if (mountpoint == NULL) {
+ /* see if environment variable set */
+ mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT);
+ /* if no environment variable, use default */
+ if (mountpoint == NULL)
+ mountpoint = "/sys/kernel/debug";
+ }
+
+ /* save the mountpoint */
+ strncpy(debugfs_mountpoint, mountpoint, sizeof(debugfs_mountpoint));
+
+ /* mount it */
+ snprintf(mountcmd, sizeof(mountcmd),
+ "/bin/mount -t debugfs debugfs %s", mountpoint);
+ return system(mountcmd);
+}
+
+/* umount the debugfs */
+
+int
+debugfs_umount(void)
+{
+ int ret;
+ char umountcmd[128];
+
+ /* if it was already mounted, leave it */
+ if (debugfs_premounted)
+ return 0;
+
+ /* make sure it's a valid mount point */
+ if ((ret = debugfs_valid_mountpoint(debugfs_mountpoint)))
+ return ret;
+
+ snprintf(umountcmd, sizeof(umountcmd),
+ "/bin/umount %s", debugfs_mountpoint);
+ return system(umountcmd);
+}
+
+
+int
+debugfs_write(const char *entry, const char *value)
+{
+ int ret, count;
+ int fd;
+ char path[MAX_PATH+1];
+
+ /* construct the path */
+ snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry);
+
+ /* verify that it exists */
+ if ((ret = debugfs_valid_entry(path)))
+ return ret;
+
+ /* get how many chars we're going to write */
+ count = strlen(value);
+
+ /* open the debugfs entry */
+ if ((fd = open(path, O_RDWR)) < 0)
+ return -errno;
+
+ while (count > 0) {
+ /* write it */
+ ret = write(fd, value, count);
+ if (ret <= 0) {
+ if (ret == EAGAIN)
+ continue;
+ close(fd);
+ return -errno;
+ }
+ count -= ret;
+ }
+
+ /* close it */
+ close(fd);
+
+ /* return success */
+ return 0;
+}
+
+/*
+ * read a debugfs entry
+ * returns the number of chars read or a negative errno
+ */
+
+int
+debugfs_read(const char *entry, char *buffer, size_t size)
+{
+ int ret;
+ int fd;
+ char path[MAX_PATH+1];
+
+ /* construct the path */
+ snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry);
+
+ /* verify that it exists */
+ if ((ret = debugfs_valid_entry(path)))
+ return ret;
+
+ /* open the debugfs entry */
+ if ((fd = open(path, O_RDONLY)) < 0)
+ return -errno;
+
+ do {
+ /* read it */
+ ret = read(fd, buffer, size);
+ if (ret == 0) {
+ close(fd);
+ return EOF;
+ }
+ } while (ret < 0 && errno == EAGAIN);
+
+ /* close it */
+ close(fd);
+
+ /* make *sure* there's a null character at the end */
+ buffer[ret] = '\0';
+
+ /* return the number of chars read */
+ return ret;
+}
diff --git a/tools/perf/util/debugfs.h b/tools/perf/util/debugfs.h
new file mode 100644
index 0000000..df14c2a
--- /dev/null
+++ b/tools/perf/util/debugfs.h
@@ -0,0 +1,22 @@
+#ifndef __DEBUGFS_H__
+#define __DEBUGFS_H__
+#include <sys/mount.h>
+#ifndef MAX_PATH
+#define MAX_PATH 256
+#endif
+
+#ifndef STR
+#define _STR(x) #x
+#define STR(x) _STR(x)
+#endif
+
+extern const char * debugfs_find_mountpoint(void);
+extern int debugfs_valid_mountpoint(const char *debugfs);
+extern int debugfs_valid_entry(const char *path);
+extern int debugfs_mount(const char *mountpoint);
+extern int debugfs_umount(void);
+extern int debugfs_write(const char *entry, const char *value);
+extern int debugfs_read(const char *entry, char *buffer, size_t size);
+extern void debugfs_force_cleanup(void);
+extern int debugfs_make_path(const char *element, char *buffer, int size);
+#endif
--
1.6.2.5
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
next prev parent reply other threads:[~2009-11-01 21:57 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-01 21:55 [PATCH 0/3] perf latency command Clark Williams
2009-11-01 21:56 ` Clark Williams [this message]
2009-11-08 17:06 ` [tip:perf/core] perf tools: Add debugfs utility routines for perf tip-bot for Clark Williams
2009-11-01 21:57 ` [PATCH 2/3] modify perf routines to use new debugfs routines Clark Williams
2009-11-08 17:06 ` [tip:perf/core] perf tools: Modify " tip-bot for Clark Williams
2009-11-01 21:58 ` [PATCH 3/3] perf latency builtin command Clark Williams
2009-11-03 19:28 ` Ingo Molnar
2009-11-03 22:00 ` Clark Williams
2009-11-04 12:41 ` Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20091101155621.2b3503ee@torg \
--to=williams@redhat.com \
--cc=acme@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.