diff options
| author | Kieran Bingham <kieran.bingham@linaro.org> | 2016-05-23 19:24:59 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-23 20:04:14 -0400 |
| commit | c1a153992ea86307d2b8c3c0be2e060102b02aff (patch) | |
| tree | 94895f6c467a6ff1e8b2b59cb6932b7f144a6400 /scripts/gdb/linux | |
| parent | e7165a2d7d87cd397d166ebf4d49763d28f5fc3d (diff) | |
scripts/gdb: add mount point list command
lx-mounts will identify current mount points based on the 'init_task'
namespace by default, as we do not yet have a kernel thread list
implementation to select the current running thread.
Optionally, a user can specify a PID to list from that process'
namespace
Link: http://lkml.kernel.org/r/e614c7bc32d2350b4ff1627ec761a7148e65bfe6.1462865983.git.jan.kiszka@siemens.com
Signed-off-by: Kieran Bingham <kieran.bingham@linaro.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts/gdb/linux')
| -rw-r--r-- | scripts/gdb/linux/constants.py.in | 20 | ||||
| -rw-r--r-- | scripts/gdb/linux/proc.py | 99 |
2 files changed, 119 insertions, 0 deletions
diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index 79d9d0092452..7986f4e0da12 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in | |||
| @@ -12,7 +12,11 @@ | |||
| 12 | * | 12 | * |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/fs.h> | ||
| 16 | #include <linux/mount.h> | ||
| 17 | |||
| 15 | /* We need to stringify expanded macros so that they can be parsed */ | 18 | /* We need to stringify expanded macros so that they can be parsed */ |
| 19 | |||
| 16 | #define STRING(x) #x | 20 | #define STRING(x) #x |
| 17 | #define XSTRING(x) STRING(x) | 21 | #define XSTRING(x) STRING(x) |
| 18 | 22 | ||
| @@ -30,3 +34,19 @@ | |||
| 30 | <!-- end-c-headers --> | 34 | <!-- end-c-headers --> |
| 31 | 35 | ||
| 32 | import gdb | 36 | import gdb |
| 37 | |||
| 38 | /* linux/fs.h */ | ||
| 39 | LX_VALUE(MS_RDONLY) | ||
| 40 | LX_VALUE(MS_SYNCHRONOUS) | ||
| 41 | LX_VALUE(MS_MANDLOCK) | ||
| 42 | LX_VALUE(MS_DIRSYNC) | ||
| 43 | LX_VALUE(MS_NOATIME) | ||
| 44 | LX_VALUE(MS_NODIRATIME) | ||
| 45 | |||
| 46 | /* linux/mount.h */ | ||
| 47 | LX_VALUE(MNT_NOSUID) | ||
| 48 | LX_VALUE(MNT_NODEV) | ||
| 49 | LX_VALUE(MNT_NOEXEC) | ||
| 50 | LX_VALUE(MNT_NOATIME) | ||
| 51 | LX_VALUE(MNT_NODIRATIME) | ||
| 52 | LX_VALUE(MNT_RELATIME) | ||
diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index d855b2fd9a06..38b1f09d1cd9 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | # | 12 | # |
| 13 | 13 | ||
| 14 | import gdb | 14 | import gdb |
| 15 | from linux import constants | ||
| 16 | from linux import utils | ||
| 17 | from linux import tasks | ||
| 18 | from linux import lists | ||
| 15 | 19 | ||
| 16 | 20 | ||
| 17 | class LxCmdLine(gdb.Command): | 21 | class LxCmdLine(gdb.Command): |
| @@ -96,3 +100,98 @@ Equivalent to cat /proc/ioports on a running target""" | |||
| 96 | return show_lx_resources("ioport_resource") | 100 | return show_lx_resources("ioport_resource") |
| 97 | 101 | ||
| 98 | LxIOPorts() | 102 | LxIOPorts() |
| 103 | |||
| 104 | |||
| 105 | # Mount namespace viewer | ||
| 106 | # /proc/mounts | ||
| 107 | |||
| 108 | def info_opts(lst, opt): | ||
| 109 | opts = "" | ||
| 110 | for key, string in lst.items(): | ||
| 111 | if opt & key: | ||
| 112 | opts += string | ||
| 113 | return opts | ||
| 114 | |||
| 115 | |||
| 116 | FS_INFO = {constants.LX_MS_SYNCHRONOUS: ",sync", | ||
| 117 | constants.LX_MS_MANDLOCK: ",mand", | ||
| 118 | constants.LX_MS_DIRSYNC: ",dirsync", | ||
| 119 | constants.LX_MS_NOATIME: ",noatime", | ||
| 120 | constants.LX_MS_NODIRATIME: ",nodiratime"} | ||
| 121 | |||
| 122 | MNT_INFO = {constants.LX_MNT_NOSUID: ",nosuid", | ||
| 123 | constants.LX_MNT_NODEV: ",nodev", | ||
| 124 | constants.LX_MNT_NOEXEC: ",noexec", | ||
| 125 | constants.LX_MNT_NOATIME: ",noatime", | ||
| 126 | constants.LX_MNT_NODIRATIME: ",nodiratime", | ||
| 127 | constants.LX_MNT_RELATIME: ",relatime"} | ||
| 128 | |||
| 129 | mount_type = utils.CachedType("struct mount") | ||
| 130 | mount_ptr_type = mount_type.get_type().pointer() | ||
| 131 | |||
| 132 | |||
| 133 | class LxMounts(gdb.Command): | ||
| 134 | """Report the VFS mounts of the current process namespace. | ||
| 135 | |||
| 136 | Equivalent to cat /proc/mounts on a running target | ||
| 137 | An integer value can be supplied to display the mount | ||
| 138 | values of that process namespace""" | ||
| 139 | |||
| 140 | def __init__(self): | ||
| 141 | super(LxMounts, self).__init__("lx-mounts", gdb.COMMAND_DATA) | ||
| 142 | |||
| 143 | # Equivalent to proc_namespace.c:show_vfsmnt | ||
| 144 | # However, that has the ability to call into s_op functions | ||
| 145 | # whereas we cannot and must make do with the information we can obtain. | ||
| 146 | def invoke(self, arg, from_tty): | ||
| 147 | argv = gdb.string_to_argv(arg) | ||
| 148 | if len(argv) >= 1: | ||
| 149 | try: | ||
| 150 | pid = int(argv[0]) | ||
| 151 | except: | ||
| 152 | raise gdb.GdbError("Provide a PID as integer value") | ||
| 153 | else: | ||
| 154 | pid = 1 | ||
| 155 | |||
| 156 | task = tasks.get_task_by_pid(pid) | ||
| 157 | if not task: | ||
| 158 | raise gdb.GdbError("Couldn't find a process with PID {}" | ||
| 159 | .format(pid)) | ||
| 160 | |||
| 161 | namespace = task['nsproxy']['mnt_ns'] | ||
| 162 | if not namespace: | ||
| 163 | raise gdb.GdbError("No namespace for current process") | ||
| 164 | |||
| 165 | for vfs in lists.list_for_each_entry(namespace['list'], | ||
| 166 | mount_ptr_type, "mnt_list"): | ||
| 167 | devname = vfs['mnt_devname'].string() | ||
| 168 | devname = devname if devname else "none" | ||
| 169 | |||
| 170 | pathname = "" | ||
| 171 | parent = vfs | ||
| 172 | while True: | ||
| 173 | mntpoint = parent['mnt_mountpoint'] | ||
| 174 | pathname = utils.dentry_name(mntpoint) + pathname | ||
| 175 | if (parent == parent['mnt_parent']): | ||
| 176 | break | ||
| 177 | parent = parent['mnt_parent'] | ||
| 178 | |||
| 179 | if (pathname == ""): | ||
| 180 | pathname = "/" | ||
| 181 | |||
| 182 | superblock = vfs['mnt']['mnt_sb'] | ||
| 183 | fstype = superblock['s_type']['name'].string() | ||
| 184 | s_flags = int(superblock['s_flags']) | ||
| 185 | m_flags = int(vfs['mnt']['mnt_flags']) | ||
| 186 | rd = "ro" if (s_flags & constants.LX_MS_RDONLY) else "rw" | ||
| 187 | |||
| 188 | gdb.write( | ||
| 189 | "{} {} {} {}{}{} 0 0\n" | ||
| 190 | .format(devname, | ||
| 191 | pathname, | ||
| 192 | fstype, | ||
| 193 | rd, | ||
| 194 | info_opts(FS_INFO, s_flags), | ||
| 195 | info_opts(MNT_INFO, m_flags))) | ||
| 196 | |||
| 197 | LxMounts() | ||
