[6/9,v2] Implement mount namespace support for native Linux targets
Commit Message
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 lin-ns" commands.
* NEWS: Mention new "set/show debug lin-ns" commands.
---
gdb/ChangeLog | 14 +++++++
gdb/NEWS | 4 ++
gdb/linux-nat.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 132 insertions(+), 0 deletions(-)
Comments
> From: Gary Benson <gbenson@redhat.com>
> Cc: Eli Zaretskii <eliz@gnu.org>, Pedro Alves <palves@redhat.com>,
> Doug Evans <dje@google.com>,
> Iago López Galeiras <iago@endocode.com>
> Date: Thu, 30 Apr 2015 13:05:39 +0100
>
> +set debug lin-ns
> +show debug lin-ns
> + Control display of debugging info regarding Linux namespaces.
Would it be better to have a more mnemonic name, like
"linux-namespace", for example? IMO, "lin-ns" goes too far in making
its name shorter.
Otherwise, the documentation parts are OK.
Thanks.
Eli Zaretskii wrote:
> > From: Gary Benson <gbenson@redhat.com>
> > Cc: Eli Zaretskii <eliz@gnu.org>, Pedro Alves <palves@redhat.com>,
> > Doug Evans <dje@google.com>,
> > Iago López Galeiras <iago@endocode.com>
> > Date: Thu, 30 Apr 2015 13:05:39 +0100
> >
> > +set debug lin-ns
> > +show debug lin-ns
> > + Control display of debugging info regarding Linux namespaces.
>
> Would it be better to have a more mnemonic name, like
> "linux-namespace", for example? IMO, "lin-ns" goes too far in
> making its name shorter.
I can change that. (I think I modelled it after the lin-lwp option).
Cheers,
Gary
On 04/30/2015 01:05 PM, Gary Benson wrote:
> This commit allows GDB to access executables and shared libraries
> on native Linux targets where GDB and the inferior have different
> mount namespaces.
> +/* 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;
> + int fd;
> +
> + if (fileio_to_host_openflags (flags, &nat_flags) == -1)
> + {
> + *target_errno = FILEIO_EINVAL;
> + return -1;
> + }
> +
> + /* We do not need to convert MODE, since the fileio protocol
> + uses the standard values. */
Hmm, I'm not seeing how the fileio constants have to necessarily
match the host's. So I don't understand this comment. What
are these standard values?
> + fd = linux_mntns_open_cloexec (linux_nat_fileio_pid_of (inf),
> + filename, nat_flags, mode);
> + if (fd == -1)
> + *target_errno = host_to_fileio_error (errno);
> +
> + return fd;
> +}
> +
Otherwise this looks good to me. I'll leave the "set debug" flag's
name up to you.
Thanks,
Pedro Alves
Pedro Alves wrote:
> On 04/30/2015 01:05 PM, Gary Benson wrote:
> > This commit allows GDB to access executables and shared libraries
> > on native Linux targets where GDB and the inferior have different
> > mount namespaces.
>
> > +/* 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;
> > + int fd;
> > +
> > + if (fileio_to_host_openflags (flags, &nat_flags) == -1)
> > + {
> > + *target_errno = FILEIO_EINVAL;
> > + return -1;
> > + }
> > +
> > + /* We do not need to convert MODE, since the fileio protocol
> > + uses the standard values. */
>
> Hmm, I'm not seeing how the fileio constants have to necessarily
> match the host's. So I don't understand this comment. What
> are these standard values?
Hmmm, I just copied this from inf_child_fileio_open. Maybe I should
fix that first, with some convertor function that the compiler can
essentially optimize away *if* the values really do match.
> Otherwise this looks good to me. I'll leave the "set debug" flag's
> name up to you.
Cool, thanks.
Cheers,
Gary
@@ -89,6 +89,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 lin-ns
+show debug lin-ns
+ 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.
@@ -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
@@ -4842,6 +4844,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;
+ int fd;
+
+ if (fileio_to_host_openflags (flags, &nat_flags) == -1)
+ {
+ *target_errno = FILEIO_EINVAL;
+ return -1;
+ }
+
+ /* We do not need to convert MODE, since the fileio protocol
+ uses the standard values. */
+ fd = linux_mntns_open_cloexec (linux_nat_fileio_pid_of (inf),
+ filename, nat_flags, 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)
{
@@ -4895,6 +4995,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
@@ -5012,6 +5117,15 @@ Enables printf debugging output."),
show_debug_linux_nat,
&setdebuglist, &showdebuglist);
+ add_setshow_boolean_cmd ("lin-ns", 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);