From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751729AbcATLmI (ORCPT ); Wed, 20 Jan 2016 06:42:08 -0500 Received: from thoth.sbs.de ([192.35.17.2]:51793 "EHLO thoth.sbs.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750804AbcATLmH (ORCPT ); Wed, 20 Jan 2016 06:42:07 -0500 Subject: Re: [PATCH 4/5] scripts/gdb: Add mount point list command To: Kieran Bingham References: <1453288550-4706-1-git-send-email-kieran.bingham@linaro.org> <1453288550-4706-5-git-send-email-kieran.bingham@linaro.org> Cc: linux-kernel@vger.kernel.org, maxime.coquelin@st.com, peter.griffin@linaro.org, lee.jones@linaro.org From: Jan Kiszka Message-ID: <569F7288.1080107@siemens.com> Date: Wed, 20 Jan 2016 12:42:00 +0100 User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 In-Reply-To: <1453288550-4706-5-git-send-email-kieran.bingham@linaro.org> Content-Type: text/plain; charset=iso-8859-15 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Kieran, just a couple of quick comments: On 2016-01-20 12:15, Kieran Bingham wrote: > 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. current_task? See LxCurrentFunc, could be factored out if usable. Or what are you looking for? > > Optionally, a user can specify a PID to list from that process' > namespace > > This is somewhat limited vs the /proc/mounts file, as that calls into > vfs hooks through the s_op functions to obtain extra information. > > Signed-off-by: Kieran Bingham > --- > > > In this patch, I'm interested in your opinions on coding styles. > Would you prefer to see the function helpers, (dentry_name, info_opts) where > they are, or inside the command as class members? Or perhaps defined in utils? Need to look into this. > > This also shows where I need to take constant information from the kernel. > In this case, they are simple numerical bitflags, and unlikely to change but > I didn't want to duplicate their values. Maybe we can generate python files with the required constants from the C headers during build? Similar to asm-offsets.c stuff. > > > scripts/gdb/linux/constants.py.in | 21 ++++++++ > scripts/gdb/linux/proc.py | 110 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 131 insertions(+) > > diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in > index d84084ac945b..739a15d2e984 100644 > --- a/scripts/gdb/linux/constants.py.in > +++ b/scripts/gdb/linux/constants.py.in > @@ -12,7 +12,11 @@ > * > */ > > +#include > +#include > + > /* We need to stringify expanded macros so that they can be parsed */ > #define STRING(x) #x > #define XSTRING(x) STRING(x) > > @@ -20,3 +24,20 @@ > > > import gdb > + > +/* linux/fs.h */ > +LX_MS_RDONLY = MS_RDONLY > +LX_MS_SYNCHRONOUS = MS_SYNCHRONOUS > +LX_MS_MANDLOCK = MS_MANDLOCK > +LX_MS_DIRSYNC = MS_DIRSYNC > +LX_MS_NOATIME = MS_NOATIME > +LX_MS_NODIRATIME = MS_NODIRATIME > + > +/* linux/mount.h */ > +LX_MNT_NOSUID = MNT_NOSUID > +LX_MNT_NODEV = MNT_NODEV > +LX_MNT_NOEXEC = MNT_NOEXEC > +LX_MNT_NOATIME = MNT_NOATIME > +LX_MNT_NODIRATIME = MNT_NODIRATIME > +LX_MNT_RELATIME = MNT_RELATIME > + > diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py > index d855b2fd9a06..b79ce2a33a3d 100644 > --- a/scripts/gdb/linux/proc.py > +++ b/scripts/gdb/linux/proc.py > @@ -12,6 +12,10 @@ > # > > import gdb > +from linux import constants > +from linux import utils > +from linux import tasks > +from linux import lists > > > class LxCmdLine(gdb.Command): > @@ -96,3 +100,109 @@ Equivalent to cat /proc/ioports on a running target""" > return show_lx_resources("ioport_resource") > > LxIOPorts() > + > + > +# Mount namespace viewer > +# /proc/mounts > + > + > +def dentry_name(d): > + if d['d_parent'] == d: > + return "" > + p = dentry_name(d['d_parent']) + "/" > + return p + d['d_iname'].string() > + > + > +def info_opts(lst, opt): > + opts = "" > + for key, string in lst.items(): > + if opt & key: > + opts += string > + return opts > + > + > +FS_INFO = {constants.LX_MS_SYNCHRONOUS: ",sync", > + constants.LX_MS_MANDLOCK: ",mand", > + constants.LX_MS_DIRSYNC: ",dirsync", > + constants.LX_MS_NOATIME: ",noatime", > + constants.LX_MS_NODIRATIME: ",nodiratime"} > + > +MNT_INFO = {constants.LX_MNT_NOSUID: ",nosuid", > + constants.LX_MNT_NODEV: ",nodev", > + constants.LX_MNT_NOEXEC: ",noexec", > + constants.LX_MNT_NOATIME: ",noatime", > + constants.LX_MNT_NODIRATIME: ",nodiratime", > + constants.LX_MNT_RELATIME: ",relatime"} > + > +mount_type = utils.CachedType("struct mount") > +mount_ptr_type = mount_type.get_type().pointer() > + > + > +class LxMounts(gdb.Command): > + """Report the VFS mounts of the current process namespace. > + > +Equivalent to cat /proc/mounts on a running target > +An integer value can be supplied to display the mount > +values of that process namespace""" > + > + def __init__(self): > + super(LxMounts, self).__init__("lx-mounts", gdb.COMMAND_DATA) > + > + # Equivalent to proc_namespace.c:show_vfsmnt > + # However, that has the ability to call into s_op functions > + # whereas we cannot and must make do with the information we can obtain. > + def invoke(self, arg, from_tty): > + argv = gdb.string_to_argv(arg) > + if len(argv) >= 1: > + try: > + pid = int(argv[0]) > + except: > + raise gdb.GdbError("Provide a PID as integer value") > + else: > + pid = 1 > + > + task = tasks.get_task_by_pid(pid) > + if not task: > + raise gdb.GdbError("Couldn't find a process with PID {}" > + .format(pid)) > + > + namespace = task['nsproxy']['mnt_ns'] > + if not namespace: > + raise gdb.GdbError("No namespace for current process") > + > + for vfs in lists.items(mount_ptr_type, "mnt_list", namespace['list']): > + # There appears to be a null entry at the end of the list... > + if not vfs['mnt_parent']: > + break > + > + devname = vfs['mnt_devname'].string() > + devname = devname if devname else "none" > + > + pathname = "" > + parent = vfs > + while True: > + mntpoint = parent['mnt_mountpoint'] > + pathname = dentry_name(mntpoint) + pathname > + if (parent == parent['mnt_parent']): > + break > + parent = parent['mnt_parent'] > + > + if (pathname == ""): > + pathname = "/" > + > + superblock = vfs['mnt']['mnt_sb'] > + fstype = superblock['s_type']['name'].string() > + s_flags = int(superblock['s_flags']) > + m_flags = int(vfs['mnt']['mnt_flags']) > + rd = "ro" if (s_flags & constants.LX_MS_RDONLY) else "rw" > + > + gdb.write( > + "{} {} {} {}{}{} 0 0\n" > + .format(devname, > + pathname, > + fstype, > + rd, > + info_opts(FS_INFO, s_flags), > + info_opts(MNT_INFO, m_flags))) > + > +LxMounts() > -- Siemens AG, Corporate Technology, CT RDA ITP SES-DE Corporate Competence Center Embedded Linux