From patchwork Wed Jan 20 11:15:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 60031 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp3109242lbb; Wed, 20 Jan 2016 03:16:42 -0800 (PST) X-Received: by 10.98.79.140 with SMTP id f12mr52130832pfj.102.1453288601212; Wed, 20 Jan 2016 03:16:41 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 27si11718813pfo.244.2016.01.20.03.16.40; Wed, 20 Jan 2016 03:16:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dkim=pass header.i=@linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935325AbcATLQh (ORCPT + 29 others); Wed, 20 Jan 2016 06:16:37 -0500 Received: from mail-wm0-f47.google.com ([74.125.82.47]:36894 "EHLO mail-wm0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934160AbcATLQ3 (ORCPT ); Wed, 20 Jan 2016 06:16:29 -0500 Received: by mail-wm0-f47.google.com with SMTP id n5so23643287wmn.0 for ; Wed, 20 Jan 2016 03:16:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=O09osduf74wOraFIMpyOjTRo2LN3S+XU+JABhIGZCts=; b=fbJFTysMaC914WIz07g8QFn3CY4Afw/84t9mkiFqFiwv5Liogy5iezBXZ+2pEUCWvy ZG+cp8tV7KOyw6NUff/Czv1i533LnZLrbXM4AElBJz2uc2DjddHh+FzbUEjHLdTcN177 /NpUfnqHR698ZQTaM2TeUhTIqKA+vAki3M6yU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=O09osduf74wOraFIMpyOjTRo2LN3S+XU+JABhIGZCts=; b=IyA67Ceg5HI7jEXhd2XPsyJltylNdJMjLqf4l5OVitg5M9j5sA0CsQ/Yc+ZnsuXWlC nbrPFPh/dywA5vDQ21cK0uOKaTyZ7RIgt3QbMObYOzrIfg8h/v65JaPTJvmavZW46OmB bMtFixxvhHXkqNqO+L0XDLatkilMbDHeeXmbDgGrFiFqM8Fsq9SNUjwtnlVyYCPB+Kfo Ioz8N5qF+DHSN25zoceAAZ38JdEGs4jKel6GlSxFhBiPRm2LMgwnyzo2YK+d+vF2QeoK YEc6hCkhSjGHJyUuDh/jbGxmmTqnMAjgQUSP6Bvpkf6uZjXdo+2QI5tgHc5KwjcSde8l I+yw== X-Gm-Message-State: ALoCoQlWyIvFUmXmFepJ34sFMi6VqIXvaFDMLz137aPO6q0f4VINra+7pPzE1yDajDFW9Lvno5ulYIaDQHIPm+rsBlAkCWGZZA== X-Received: by 10.194.143.104 with SMTP id sd8mr34963493wjb.35.1453288588009; Wed, 20 Jan 2016 03:16:28 -0800 (PST) Received: from localhost.localdomain (cpc87017-aztw30-2-0-cust65.18-1.cable.virginm.net. [92.232.232.66]) by smtp.gmail.com with ESMTPSA id bg1sm28398065wjc.27.2016.01.20.03.16.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 20 Jan 2016 03:16:27 -0800 (PST) From: Kieran Bingham To: jan.kiszka@siemens.com Cc: Kieran Bingham , linux-kernel@vger.kernel.org, maxime.coquelin@st.com, peter.griffin@linaro.org, lee.jones@linaro.org Subject: [PATCH 4/5] scripts/gdb: Add mount point list command Date: Wed, 20 Jan 2016 11:15:49 +0000 Message-Id: <1453288550-4706-5-git-send-email-kieran.bingham@linaro.org> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1453288550-4706-1-git-send-email-kieran.bingham@linaro.org> References: <1453288550-4706-1-git-send-email-kieran.bingham@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 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? 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. scripts/gdb/linux/constants.py.in | 21 ++++++++ scripts/gdb/linux/proc.py | 110 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) -- 2.5.0 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()