Implement mount namespace support for native Linux targets
authorGary Benson <gbenson@redhat.com>
Wed, 10 Jun 2015 13:28:43 +0000 (14:28 +0100)
committerGary Benson <gbenson@redhat.com>
Wed, 10 Jun 2015 13:28:43 +0000 (14:28 +0100)
This commit allows GDB to access executables and shared libraries
on native Linux targets where GDB and the inferior have different
mount namespaces.

gdb/ChangeLog:

* linux-nat.c (nat/linux-namespaces.h): New include.
(fileio.h): Likewise.
(linux_nat_filesystem_is_local): New function.
(linux_nat_fileio_pid_of): Likewise.
(linux_nat_fileio_open): Likewise.
(linux_nat_fileio_readlink): Likewise.
(linux_nat_fileio_unlink): Likewise.
(linux_nat_add_target): Initialize to_filesystem_is_local,
to_fileio_open, to_fileio_readlink and to_fileio_unlink.
(_initialize_linux_nat): New "set/show debug linux-namespaces"
commands.
* NEWS: Mention new "set/show debug linux-namespaces" commands.

gdb/doc/ChangeLog:

* gdb.texinfo (Debugging Output): Document the "set/show debug
linux-namespaces" command.

gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/linux-nat.c

index 5cbc8d8..2e91c76 100644 (file)
@@ -1,5 +1,20 @@
 2015-06-10  Gary Benson <gbenson@redhat.com>
 
+       * linux-nat.c (nat/linux-namespaces.h): New include.
+       (fileio.h): Likewise.
+       (linux_nat_filesystem_is_local): New function.
+       (linux_nat_fileio_pid_of): Likewise.
+       (linux_nat_fileio_open): Likewise.
+       (linux_nat_fileio_readlink): Likewise.
+       (linux_nat_fileio_unlink): Likewise.
+       (linux_nat_add_target): Initialize to_filesystem_is_local,
+       to_fileio_open, to_fileio_readlink and to_fileio_unlink.
+       (_initialize_linux_nat): New "set/show debug linux-namespaces"
+       commands.
+       * NEWS: Mention new "set/show debug linux-namespaces" commands.
+
+2015-06-10  Gary Benson <gbenson@redhat.com>
+
        * target.h (struct inferior): New forward declaration.
        (struct target_ops) <to_filesystem_is_local>: Update comment.
        (struct target_ops) <to_fileio_open>: New argument inf.
index 11ccd4a..a309dbf 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -137,6 +137,10 @@ set|show record btrace bts buffer-size
   The obtained size may differ from the requested size.  Use "info
   record" to see the obtained buffer size.
 
+set debug linux-namespaces
+show debug linux-namespaces
+  Control display of debugging info regarding Linux namespaces.
+
 * The command 'thread apply all' can now support new option '-ascending'
   to call its specified command for all threads in ascending order.
 
index 4b2d75a..a9a8137 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-10  Gary Benson <gbenson@redhat.com>
+
+       * gdb.texinfo (Debugging Output): Document the "set/show debug
+       linux-namespaces" command.
+
 2015-06-10  Walfred Tedeschi  <walfred.tedeschi@intel.com>
             Mircea Gherzan  <mircea.gherzan@intel.com>
 
index 9e9138b..4bb092c 100644 (file)
@@ -23502,6 +23502,11 @@ Displays the current state of @value{GDBN} JIT debugging.
 Turns on or off debugging messages from the Linux LWP debug support.
 @item show debug lin-lwp
 Show the current state of Linux LWP debugging messages.
+@item set debug linux-namespaces
+@cindex @sc{gnu}/Linux namespaces debug messages
+Turns on or off debugging messages from the Linux namespaces debug support.
+@item show debug linux-namespaces
+Show the current state of Linux namespaces debugging messages.
 @item set debug mach-o
 @cindex Mach-O symbols processing
 Control display of debugging messages related to Mach-O symbols
index febee84..88f4e3e 100644 (file)
@@ -66,6 +66,8 @@
 #include "target-descriptions.h"
 #include "filestuff.h"
 #include "objfiles.h"
+#include "nat/linux-namespaces.h"
+#include "fileio.h"
 
 #ifndef SPUFS_MAGIC
 #define SPUFS_MAGIC 0x23c9b64e
@@ -4868,6 +4870,104 @@ linux_nat_core_of_thread (struct target_ops *ops, ptid_t ptid)
   return -1;
 }
 
+/* Implementation of to_filesystem_is_local.  */
+
+static int
+linux_nat_filesystem_is_local (struct target_ops *ops)
+{
+  struct inferior *inf = current_inferior ();
+
+  if (inf->fake_pid_p || inf->pid == 0)
+    return 1;
+
+  return linux_ns_same (inf->pid, LINUX_NS_MNT);
+}
+
+/* Convert the INF argument passed to a to_fileio_* method
+   to a process ID suitable for passing to its corresponding
+   linux_mntns_* function.  If INF is non-NULL then the
+   caller is requesting the filesystem seen by INF.  If INF
+   is NULL then the caller is requesting the filesystem seen
+   by the GDB.  We fall back to GDB's filesystem in the case
+   that INF is non-NULL but its PID is unknown.  */
+
+static pid_t
+linux_nat_fileio_pid_of (struct inferior *inf)
+{
+  if (inf == NULL || inf->fake_pid_p || inf->pid == 0)
+    return getpid ();
+  else
+    return inf->pid;
+}
+
+/* Implementation of to_fileio_open.  */
+
+static int
+linux_nat_fileio_open (struct target_ops *self,
+                      struct inferior *inf, const char *filename,
+                      int flags, int mode, int *target_errno)
+{
+  int nat_flags;
+  mode_t nat_mode;
+  int fd;
+
+  if (fileio_to_host_openflags (flags, &nat_flags) == -1
+      || fileio_to_host_mode (mode, &nat_mode) == -1)
+    {
+      *target_errno = FILEIO_EINVAL;
+      return -1;
+    }
+
+  fd = linux_mntns_open_cloexec (linux_nat_fileio_pid_of (inf),
+                                filename, nat_flags, nat_mode);
+  if (fd == -1)
+    *target_errno = host_to_fileio_error (errno);
+
+  return fd;
+}
+
+/* Implementation of to_fileio_readlink.  */
+
+static char *
+linux_nat_fileio_readlink (struct target_ops *self,
+                          struct inferior *inf, const char *filename,
+                          int *target_errno)
+{
+  char buf[PATH_MAX];
+  int len;
+  char *ret;
+
+  len = linux_mntns_readlink (linux_nat_fileio_pid_of (inf),
+                             filename, buf, sizeof (buf));
+  if (len < 0)
+    {
+      *target_errno = host_to_fileio_error (errno);
+      return NULL;
+    }
+
+  ret = xmalloc (len + 1);
+  memcpy (ret, buf, len);
+  ret[len] = '\0';
+  return ret;
+}
+
+/* Implementation of to_fileio_unlink.  */
+
+static int
+linux_nat_fileio_unlink (struct target_ops *self,
+                        struct inferior *inf, const char *filename,
+                        int *target_errno)
+{
+  int ret;
+
+  ret = linux_mntns_unlink (linux_nat_fileio_pid_of (inf),
+                           filename);
+  if (ret == -1)
+    *target_errno = host_to_fileio_error (errno);
+
+  return ret;
+}
+
 void
 linux_nat_add_target (struct target_ops *t)
 {
@@ -4921,6 +5021,11 @@ linux_nat_add_target (struct target_ops *t)
 
   t->to_core_of_thread = linux_nat_core_of_thread;
 
+  t->to_filesystem_is_local = linux_nat_filesystem_is_local;
+  t->to_fileio_open = linux_nat_fileio_open;
+  t->to_fileio_readlink = linux_nat_fileio_readlink;
+  t->to_fileio_unlink = linux_nat_fileio_unlink;
+
   /* We don't change the stratum; this target will sit at
      process_stratum and thread_db will set at thread_stratum.  This
      is a little strange, since this is a multi-threaded-capable
@@ -5038,6 +5143,15 @@ Enables printf debugging output."),
                             show_debug_linux_nat,
                             &setdebuglist, &showdebuglist);
 
+  add_setshow_boolean_cmd ("linux-namespaces", class_maintenance,
+                          &debug_linux_namespaces, _("\
+Set debugging of GNU/Linux namespaces module."), _("\
+Show debugging of GNU/Linux namespaces module."), _("\
+Enables printf debugging output."),
+                          NULL,
+                          NULL,
+                          &setdebuglist, &showdebuglist);
+
   /* Save this mask as the default.  */
   sigprocmask (SIG_SETMASK, NULL, &normal_mask);