Introduce nat/linux-namespaces.[ch]
[external/binutils.git] / gdb / nat / linux-namespaces.c
1 /* Linux namespaces(7) support.
2
3    Copyright (C) 2015 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "common-defs.h"
21 #include "nat/linux-namespaces.h"
22 #include "filestuff.h"
23 #include <fcntl.h>
24 #include <sys/syscall.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/socket.h>
28 #include <sys/wait.h>
29 #include <signal.h>
30 #include <sched.h>
31
32 /* See nat/linux-namespaces.h.  */
33 int debug_linux_namespaces;
34
35 /* Handle systems without setns.  */
36
37 #ifndef HAVE_SETNS
38 static int
39 setns (int fd, int nstype)
40 {
41 #ifdef __NR_setns
42   return syscall (__NR_setns, fd, nstype);
43 #else
44   errno = ENOSYS;
45   return -1;
46 #endif
47 }
48 #endif
49
50 /* A Linux namespace.  */
51
52 struct linux_ns
53 {
54   /* Filename of this namespace's entries in /proc/PID/ns.  */
55   const char *filename;
56
57   /* Nonzero if this object has been initialized.  */
58   int initialized;
59
60   /* Nonzero if this namespace is supported on this system.  */
61   int supported;
62
63   /* ID of the namespace the calling process is in, used to
64      see if other processes share the namespace.  The code in
65      this file assumes that the calling process never changes
66      namespace.  */
67   ino_t id;
68 };
69
70 /* Return the absolute filename of process PID's /proc/PID/ns
71    entry for namespace NS.  The returned value persists until
72    this function is next called.  */
73
74 static const char *
75 linux_ns_filename (struct linux_ns *ns, int pid)
76 {
77   static char filename[PATH_MAX];
78
79   gdb_assert (pid > 0);
80   xsnprintf (filename, sizeof (filename), "/proc/%d/ns/%s", pid,
81              ns->filename);
82
83   return filename;
84 }
85
86 /* Return a representation of the caller's TYPE namespace, or
87    NULL if TYPE namespaces are not supported on this system.  */
88
89 static struct linux_ns *
90 linux_ns_get_namespace (enum linux_ns_type type)
91 {
92   static struct linux_ns namespaces[NUM_LINUX_NS_TYPES] =
93     {
94       { "ipc" },
95       { "mnt" },
96       { "net" },
97       { "pid" },
98       { "user" },
99       { "uts" },
100     };
101   struct linux_ns *ns;
102
103   gdb_assert (type >= 0 && type < NUM_LINUX_NS_TYPES);
104   ns = &namespaces[type];
105
106   if (!ns->initialized)
107     {
108       struct stat sb;
109
110       if (stat (linux_ns_filename (ns, getpid ()), &sb) == 0)
111         {
112           ns->id = sb.st_ino;
113
114           ns->supported = 1;
115         }
116
117       ns->initialized = 1;
118     }
119
120   return ns->supported ? ns : NULL;
121 }
122
123 /* See nat/linux-namespaces.h.  */
124
125 int
126 linux_ns_same (pid_t pid, enum linux_ns_type type)
127 {
128   struct linux_ns *ns = linux_ns_get_namespace (type);
129   const char *filename;
130   struct stat sb;
131
132   /* If the kernel does not support TYPE namespaces then there's
133      effectively only one TYPE namespace that all processes on
134      the system share.  */
135   if (ns == NULL)
136     return 1;
137
138   /* Stat PID's TYPE namespace entry to get the namespace ID.  This
139      might fail if the process died, or if we don't have the right
140      permissions (though we should be attached by this time so this
141      seems unlikely).  In any event, we can't make any decisions and
142      must throw.  */
143   filename = linux_ns_filename (ns, pid);
144   if (stat (filename, &sb) != 0)
145     perror_with_name (filename);
146
147   return sb.st_ino == ns->id;
148 }
149
150 /* We need to use setns(2) to handle filesystem access in mount
151    namespaces other than our own, but this isn't permitted for
152    multithreaded processes.  GDB is multithreaded when compiled
153    with Guile support, and may become multithreaded if compiled
154    with Python support.  We deal with this by spawning a single-
155    threaded helper process to access mount namespaces other than
156    our own.
157
158    The helper process is started the first time a call to setns
159    is required.  The main process (GDB or gdbserver) communicates
160    with the helper via sockets, passing file descriptors where
161    necessary using SCM_RIGHTS.  Once started the helper process
162    runs until the main process terminates; when this happens the
163    helper will receive socket errors, notice that its parent died,
164    and exit accordingly (see mnsh_maybe_mourn_peer).
165
166    The protocol is that the main process sends a request in a
167    single message, and the helper replies to every message it
168    receives with a single-message response.  If the helper
169    receives a message it does not understand it will reply with
170    a MNSH_MSG_ERROR message.  The main process checks all
171    responses it receives with gdb_assert, so if the main process
172    receives something unexpected (which includes MNSH_MSG_ERROR)
173    the main process will call internal_error.
174
175    For avoidance of doubt, if the helper process receives a
176    message it doesn't handle it will reply with MNSH_MSG_ERROR.
177    If the main process receives MNSH_MSG_ERROR at any time then
178    it will call internal_error.  If internal_error causes the
179    main process to exit, the helper will notice this and also
180    exit.  The helper will not exit until the main process
181    terminates, so if the user continues through internal_error
182    the helper will still be there awaiting requests from the
183    main process.
184
185    Messages in both directions have the following payload:
186
187    - TYPE (enum mnsh_msg_type, always sent) - the message type.
188    - INT1 and
189    - INT2 (int, always sent, though not always used) - two
190            values whose meaning is message-type-dependent.
191            See enum mnsh_msg_type documentation below.
192    - FD (int, optional, sent using SCM_RIGHTS) - an open file
193          descriptor.
194    - BUF (unstructured data, optional) - some data with message-
195           type-dependent meaning.
196
197    Note that the helper process is the child of a call to fork,
198    so all code in the helper must be async-signal-safe.  */
199
200 /* Mount namespace helper message types.  */
201
202 enum mnsh_msg_type
203   {
204     /* A communication error occurred.  Receipt of this message
205        by either end will cause an assertion failure in the main
206        process.  */
207     MNSH_MSG_ERROR,
208
209     /* Requests, sent from the main process to the helper.  */
210
211     /* A request that the helper call setns.  Arguments should
212        be passed in FD and INT1.  Helper should respond with a
213        MNSH_RET_INT.  */
214     MNSH_REQ_SETNS,
215
216     /* A request that the helper call open.  Arguments should
217        be passed in BUF, INT1 and INT2.  The filename (in BUF)
218        should include a terminating NUL character.  The helper
219        should respond with a MNSH_RET_FD.  */
220     MNSH_REQ_OPEN,
221
222     /* A request that the helper call unlink.  The single
223        argument (the filename) should be passed in BUF, and
224        should include a terminating NUL character.  The helper
225        should respond with a MNSH_RET_INT.  */
226     MNSH_REQ_UNLINK,
227
228     /* A request that the helper call readlink.  The single
229        argument (the filename) should be passed in BUF, and
230        should include a terminating NUL character.  The helper
231        should respond with a MNSH_RET_INTSTR.  */
232     MNSH_REQ_READLINK,
233
234     /* Responses, sent to the main process from the helper.  */
235
236     /* Return an integer in INT1 and errno in INT2.  */
237     MNSH_RET_INT,
238
239     /* Return a file descriptor in FD if one was opened or an
240        integer in INT1 otherwise.  Return errno in INT2.  */
241     MNSH_RET_FD,
242
243     /* Return an integer in INT1, errno in INT2, and optionally
244        some data in BUF.  */
245     MNSH_RET_INTSTR,
246   };
247
248 /* Print a string representation of a message using debug_printf.
249    This function is not async-signal-safe so should never be
250    called from the helper.  */
251
252 static void
253 mnsh_debug_print_message (enum mnsh_msg_type type,
254                           int fd, int int1, int int2,
255                           const void *buf, int bufsiz)
256 {
257   gdb_byte *c = (gdb_byte *) buf;
258   gdb_byte *cl = c + bufsiz;
259
260   switch (type)
261     {
262     case MNSH_MSG_ERROR:
263       debug_printf ("ERROR");
264       break;
265
266     case MNSH_REQ_SETNS:
267       debug_printf ("SETNS");
268       break;
269
270     case MNSH_REQ_OPEN:
271       debug_printf ("OPEN");
272       break;
273
274     case MNSH_REQ_UNLINK:
275       debug_printf ("UNLINK");
276       break;
277
278     case MNSH_REQ_READLINK:
279       debug_printf ("READLINK");
280       break;
281
282     case MNSH_RET_INT:
283       debug_printf ("INT");
284       break;
285
286     case MNSH_RET_FD:
287       debug_printf ("FD");
288       break;
289
290     case MNSH_RET_INTSTR:
291       debug_printf ("INTSTR");
292       break;
293
294     default:
295       debug_printf ("unknown-packet-%d", type);
296     }
297
298   debug_printf (" %d %d %d \"", fd, int1, int2);
299
300   for (; c < cl; c++)
301     debug_printf (*c >= ' ' && *c <= '~' ? "%c" : "\\%o", *c);
302
303   debug_printf ("\"");
304 }
305
306 /* Forward declaration.  */
307
308 static void mnsh_maybe_mourn_peer (void);
309
310 /* Send a message.  The argument SOCK is the file descriptor of the
311    sending socket, the other arguments are the payload to send.
312    Return the number of bytes sent on success.  Return -1 on failure
313    and set errno appropriately.  This function is called by both the
314    main process and the helper so must be async-signal-safe.  */
315
316 static ssize_t
317 mnsh_send_message (int sock, enum mnsh_msg_type type,
318                    int fd, int int1, int int2,
319                    const void *buf, int bufsiz)
320 {
321   struct msghdr msg;
322   struct iovec iov[4];
323   char fdbuf[CMSG_SPACE (sizeof (fd))];
324   ssize_t size;
325
326   /* Build the basic TYPE, INT1, INT2 message.  */
327   memset (&msg, 0, sizeof (msg));
328   msg.msg_iov = iov;
329
330   iov[0].iov_base = &type;
331   iov[0].iov_len = sizeof (type);
332   iov[1].iov_base = &int1;
333   iov[1].iov_len = sizeof (int1);
334   iov[2].iov_base = &int2;
335   iov[2].iov_len = sizeof (int2);
336
337   msg.msg_iovlen = 3;
338
339   /* Append BUF if supplied.  */
340   if (buf != NULL && bufsiz > 0)
341     {
342       iov[3].iov_base = alloca (bufsiz);
343       memcpy (iov[3].iov_base, buf, bufsiz);
344       iov[3].iov_len = bufsiz;
345
346       msg.msg_iovlen ++;
347     }
348
349   /* Attach FD if supplied.  */
350   if (fd >= 0)
351     {
352       struct cmsghdr *cmsg;
353
354       msg.msg_control = fdbuf;
355       msg.msg_controllen = sizeof (fdbuf);
356
357       cmsg = CMSG_FIRSTHDR (&msg);
358       cmsg->cmsg_level = SOL_SOCKET;
359       cmsg->cmsg_type = SCM_RIGHTS;
360       cmsg->cmsg_len = CMSG_LEN (sizeof (int));
361
362       memcpy (CMSG_DATA (cmsg), &fd, sizeof (int));
363
364       msg.msg_controllen = cmsg->cmsg_len;
365     }
366
367   /* Send the message.  */
368   size = sendmsg (sock, &msg, 0);
369
370   if (size < 0)
371     mnsh_maybe_mourn_peer ();
372
373   if (debug_linux_namespaces)
374     {
375       debug_printf ("mnsh: send: ");
376       mnsh_debug_print_message (type, fd, int1, int2, buf, bufsiz);
377       debug_printf (" -> %ld\n", size);
378     }
379
380   return size;
381 }
382
383 /* Receive a message.  The argument SOCK is the file descriptor of
384    the receiving socket, the other arguments point to storage for
385    the received payload.  Returns the number of bytes stored into
386    BUF on success, which may be zero in the event no BUF was sent.
387    Return -1 on failure and set errno appropriately.  This function
388    is called from both the main process and the helper and must be
389    async-signal-safe.  */
390
391 static ssize_t
392 mnsh_recv_message (int sock, enum mnsh_msg_type *type,
393                    int *fd, int *int1, int *int2,
394                    void *buf, int bufsiz)
395 {
396   struct msghdr msg;
397   struct iovec iov[4];
398   char fdbuf[CMSG_SPACE (sizeof (*fd))];
399   struct cmsghdr *cmsg;
400   ssize_t size, fixed_size;
401   int i;
402
403   /* Build the message to receive data into.  */
404   memset (&msg, 0, sizeof (msg));
405   msg.msg_iov = iov;
406
407   iov[0].iov_base = type;
408   iov[0].iov_len = sizeof (*type);
409   iov[1].iov_base = int1;
410   iov[1].iov_len = sizeof (*int1);
411   iov[2].iov_base = int2;
412   iov[2].iov_len = sizeof (*int2);
413   iov[3].iov_base = buf;
414   iov[3].iov_len = bufsiz;
415
416   msg.msg_iovlen = 4;
417
418   for (fixed_size = i = 0; i < msg.msg_iovlen - 1; i++)
419     fixed_size += iov[i].iov_len;
420
421   msg.msg_control = fdbuf;
422   msg.msg_controllen = sizeof (fdbuf);
423
424   /* Receive the message.  */
425   size = recvmsg (sock, &msg, MSG_CMSG_CLOEXEC);
426   if (size < 0)
427     {
428       if (debug_linux_namespaces)
429         debug_printf ("namespace-helper: recv failed (%ld)\n", size);
430
431       mnsh_maybe_mourn_peer ();
432
433       return size;
434     }
435
436   /* Check for truncation.  */
437   if (size < fixed_size || (msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)))
438     {
439       if (debug_linux_namespaces)
440         debug_printf ("namespace-helper: recv truncated (%ld 0x%x)\n",
441                       size, msg.msg_flags);
442
443       mnsh_maybe_mourn_peer ();
444
445       errno = EBADMSG;
446       return -1;
447     }
448
449   /* Unpack the file descriptor if supplied.  */
450   cmsg = CMSG_FIRSTHDR (&msg);
451   if (cmsg != NULL
452       && cmsg->cmsg_len == CMSG_LEN (sizeof (int))
453       && cmsg->cmsg_level == SOL_SOCKET
454       && cmsg->cmsg_type == SCM_RIGHTS)
455     memcpy (fd, CMSG_DATA (cmsg), sizeof (int));
456   else
457     *fd = -1;
458
459   if (debug_linux_namespaces)
460     {
461       debug_printf ("mnsh: recv: ");
462       mnsh_debug_print_message (*type, *fd, *int1, *int2, buf,
463                                 size - fixed_size);
464       debug_printf ("\n");
465     }
466
467   /* Return the number of bytes of data in BUF.  */
468   return size - fixed_size;
469 }
470
471 /* Shortcuts for returning results from the helper.  */
472
473 #define mnsh_return_int(sock, result, error) \
474   mnsh_send_message (sock, MNSH_RET_INT, -1, result, error, NULL, 0)
475
476 #define mnsh_return_fd(sock, fd, error) \
477   mnsh_send_message (sock, MNSH_RET_FD, \
478                      (fd) < 0 ? -1 : (fd), \
479                      (fd) < 0 ? (fd) : 0, \
480                      error, NULL, 0)
481
482 #define mnsh_return_intstr(sock, result, buf, bufsiz, error) \
483   mnsh_send_message (sock, MNSH_RET_INTSTR, -1, result, error, \
484                      buf, bufsiz)
485
486 /* Handle a MNSH_REQ_SETNS message.  Must be async-signal-safe.  */
487
488 static ssize_t
489 mnsh_handle_setns (int sock, int fd, int nstype)
490 {
491   int result = setns (fd, nstype);
492
493   return mnsh_return_int (sock, result, errno);
494 }
495
496 /* Handle a MNSH_REQ_OPEN message.  Must be async-signal-safe.  */
497
498 static ssize_t
499 mnsh_handle_open (int sock, const char *filename,
500                   int flags, mode_t mode)
501 {
502   int fd = gdb_open_cloexec (filename, flags, mode);
503   ssize_t result = mnsh_return_fd (sock, fd, errno);
504
505   if (fd >= 0)
506     close (fd);
507
508   return result;
509 }
510
511 /* Handle a MNSH_REQ_UNLINK message.  Must be async-signal-safe.  */
512
513 static ssize_t
514 mnsh_handle_unlink (int sock, const char *filename)
515 {
516   int result = unlink (filename);
517
518   return mnsh_return_int (sock, result, errno);
519 }
520
521 /* Handle a MNSH_REQ_READLINK message.  Must be async-signal-safe.  */
522
523 static ssize_t
524 mnsh_handle_readlink (int sock, const char *filename)
525 {
526   char buf[PATH_MAX];
527   int len = readlink (filename, buf, sizeof (buf));
528
529   return mnsh_return_intstr (sock, len,
530                              buf, len < 0 ? 0 : len,
531                              errno);
532 }
533
534 /* The helper process.  Never returns.  Must be async-signal-safe.  */
535
536 static void mnsh_main (int sock) ATTRIBUTE_NORETURN;
537
538 static void
539 mnsh_main (int sock)
540 {
541   while (1)
542     {
543       enum mnsh_msg_type type;
544       int fd, int1, int2;
545       char buf[PATH_MAX];
546       ssize_t size, response = -1;
547
548       size = mnsh_recv_message (sock, &type,
549                                 &fd, &int1, &int2,
550                                 buf, sizeof (buf));
551
552       if (size >= 0 && size < sizeof (buf))
553         {
554           switch (type)
555             {
556             case MNSH_REQ_SETNS:
557               if (fd > 0)
558                 response = mnsh_handle_setns (sock, fd, int1);
559               break;
560
561             case MNSH_REQ_OPEN:
562               if (size > 0 && buf[size - 1] == '\0')
563                 response = mnsh_handle_open (sock, buf, int1, int2);
564               break;
565
566             case MNSH_REQ_UNLINK:
567               if (size > 0 && buf[size - 1] == '\0')
568                 response = mnsh_handle_unlink (sock, buf);
569               break;
570
571             case MNSH_REQ_READLINK:
572               if (size > 0 && buf[size - 1] == '\0')
573                 response = mnsh_handle_readlink (sock, buf);
574               break;
575
576             default:
577               break; /* Handled below.  */
578             }
579         }
580
581       /* Close any file descriptors we were passed.  */
582       if (fd >= 0)
583         close (fd);
584
585       /* Can't handle this message, bounce it back.  */
586       if (response < 0)
587         {
588           if (size < 0)
589             size = 0;
590
591           mnsh_send_message (sock, MNSH_MSG_ERROR,
592                              -1, int1, int2, buf, size);
593         }
594     }
595 }
596
597 /* The mount namespace helper process.  */
598
599 struct linux_mnsh
600 {
601   /* PID of helper.  */
602   pid_t pid;
603
604   /* Socket for communication.  */
605   int sock;
606
607   /* ID of the mount namespace the helper is currently in.  */
608   ino_t nsid;
609 };
610
611 /* In the helper process this is set to the PID of the process that
612    created the helper (i.e. GDB or gdbserver).  In the main process
613    this is set to zero.  Used by mnsh_maybe_mourn_peer.  */
614 static int mnsh_creator_pid = 0;
615
616 /* Return an object representing the mount namespace helper process.
617    If no mount namespace helper process has been started then start
618    one.  Return NULL if no mount namespace helper process could be
619    started.  */
620
621 static struct linux_mnsh *
622 linux_mntns_get_helper (void)
623 {
624   static struct linux_mnsh *helper = NULL;
625
626   if (helper == NULL)
627     {
628       static struct linux_mnsh h;
629       struct linux_ns *ns;
630       pid_t helper_creator = getpid ();
631       int sv[2];
632
633       ns = linux_ns_get_namespace (LINUX_NS_MNT);
634       if (ns == NULL)
635         return NULL;
636
637       if (gdb_socketpair_cloexec (AF_UNIX, SOCK_STREAM, 0, sv) < 0)
638         return NULL;
639
640       h.pid = fork ();
641       if (h.pid < 0)
642         {
643           int saved_errno = errno;
644
645           close (sv[0]);
646           close (sv[1]);
647
648           errno = saved_errno;
649           return NULL;
650         }
651
652       if (h.pid == 0)
653         {
654           /* Child process.  */
655           close (sv[0]);
656
657           mnsh_creator_pid = helper_creator;
658
659           /* Debug printing isn't async-signal-safe.  */
660           debug_linux_namespaces = 0;
661
662           mnsh_main (sv[1]);
663         }
664
665       /* Parent process.  */
666       close (sv[1]);
667
668       helper = &h;
669       helper->sock = sv[0];
670       helper->nsid = ns->id;
671
672       if (debug_linux_namespaces)
673         debug_printf ("Started mount namespace helper process %d\n",
674                       helper->pid);
675     }
676
677   return helper;
678 }
679
680 /* Check whether the other process died and act accordingly.  Called
681    whenever a socket error occurs, from both the main process and the
682    helper.  Must be async-signal-safe when called from the helper.  */
683
684 static void
685 mnsh_maybe_mourn_peer (void)
686 {
687   if (mnsh_creator_pid != 0)
688     {
689       /* We're in the helper.  Check if our current parent is the
690          process that started us.  If it isn't, then our original
691          parent died and we've been reparented.  Exit immediately
692          if that's the case.  */
693       if (getppid () != mnsh_creator_pid)
694         _exit (0);
695     }
696   else
697     {
698       /* We're in the main process.  */
699
700       struct linux_mnsh *helper = linux_mntns_get_helper ();
701       int status;
702       pid_t pid;
703
704       if (helper->pid < 0)
705         {
706           /* We already mourned it.  */
707           return;
708         }
709
710       pid = waitpid (helper->pid, &status, WNOHANG);
711       if (pid == 0)
712         {
713           /* The helper is still alive.  */
714           return;
715         }
716       else if (pid == -1)
717         {
718           if (errno == ECHILD)
719             warning (_("mount namespace helper vanished?"));
720           else
721             internal_warning (__FILE__, __LINE__,
722                               _("unhandled error %d"), errno);
723         }
724       else if (pid == helper->pid)
725         {
726           if (WIFEXITED (status))
727             warning (_("mount namespace helper exited with status %d"),
728                      WEXITSTATUS (status));
729           else if (WIFSIGNALED (status))
730             warning (_("mount namespace helper killed by signal %d"),
731                      WTERMSIG (status));
732           else
733             internal_warning (__FILE__, __LINE__,
734                               _("unhandled status %d"), status);
735         }
736       else
737         internal_warning (__FILE__, __LINE__,
738                           _("unknown pid %d"), pid);
739
740       /* Something unrecoverable happened.  */
741       helper->pid = -1;
742     }
743 }
744
745 /* Shortcuts for sending messages to the helper.  */
746
747 #define mnsh_send_setns(helper, fd, nstype) \
748   mnsh_send_message (helper->sock, MNSH_REQ_SETNS, fd, nstype, 0, \
749                      NULL, 0)
750
751 #define mnsh_send_open(helper, filename, flags, mode) \
752   mnsh_send_message (helper->sock, MNSH_REQ_OPEN, -1, flags, mode, \
753                      filename, strlen (filename) + 1)
754
755 #define mnsh_send_unlink(helper, filename) \
756   mnsh_send_message (helper->sock, MNSH_REQ_UNLINK, -1, 0, 0, \
757                      filename, strlen (filename) + 1)
758
759 #define mnsh_send_readlink(helper, filename) \
760   mnsh_send_message (helper->sock, MNSH_REQ_READLINK, -1, 0, 0, \
761                      filename, strlen (filename) + 1)
762
763 /* Receive a message from the helper.  Issue an assertion failure if
764    the message isn't a correctly-formatted MNSH_RET_INT.  Set RESULT
765    and ERROR and return 0 on success.  Set errno and return -1 on
766    failure.  */
767
768 static int
769 mnsh_recv_int (struct linux_mnsh *helper, int *result, int *error)
770 {
771   enum mnsh_msg_type type;
772   char buf[PATH_MAX];
773   ssize_t size;
774   int fd;
775
776   size = mnsh_recv_message (helper->sock, &type, &fd,
777                             result, error,
778                             buf, sizeof (buf));
779   if (size < 0)
780     return -1;
781
782   gdb_assert (type == MNSH_RET_INT);
783   gdb_assert (fd == -1);
784   gdb_assert (size == 0);
785
786   return 0;
787 }
788
789 /* Receive a message from the helper.  Issue an assertion failure if
790    the message isn't a correctly-formatted MNSH_RET_FD.  Set FD and
791    ERROR and return 0 on success.  Set errno and return -1 on
792    failure.  */
793
794 static int
795 mnsh_recv_fd (struct linux_mnsh *helper, int *fd, int *error)
796 {
797   enum mnsh_msg_type type;
798   char buf[PATH_MAX];
799   ssize_t size;
800   int result;
801
802   size = mnsh_recv_message (helper->sock, &type, fd,
803                             &result, error,
804                             buf, sizeof (buf));
805   if (size < 0)
806     return -1;
807
808   gdb_assert (type == MNSH_RET_FD);
809   gdb_assert (size == 0);
810
811   if (*fd < 0)
812     {
813       gdb_assert (result < 0);
814       *fd = result;
815     }
816
817   return 0;
818 }
819
820 /* Receive a message from the helper.  Issue an assertion failure if
821    the message isn't a correctly-formatted MNSH_RET_INTSTR.  Set
822    RESULT and ERROR and optionally store data in BUF, then return
823    the number of bytes stored in BUF on success (this may be zero).
824    Set errno and return -1 on error.  */
825
826 static ssize_t
827 mnsh_recv_intstr (struct linux_mnsh *helper,
828                   int *result, int *error,
829                   void *buf, int bufsiz)
830 {
831   enum mnsh_msg_type type;
832   ssize_t size;
833   int fd;
834
835   size = mnsh_recv_message (helper->sock, &type, &fd,
836                             result, error,
837                             buf, bufsiz);
838
839   if (size < 0)
840     return -1;
841
842   gdb_assert (type == MNSH_RET_INTSTR);
843   gdb_assert (fd == -1);
844
845   return size;
846 }
847
848 /* Return values for linux_mntns_access_fs.  */
849
850 enum mnsh_fs_code
851   {
852     /* Something went wrong, errno is set.  */
853     MNSH_FS_ERROR = -1,
854
855     /* The main process is in the correct mount namespace.
856        The caller should access the filesystem directly.  */
857     MNSH_FS_DIRECT,
858
859     /* The helper is in the correct mount namespace.
860        The caller should access the filesystem via the helper.  */
861     MNSH_FS_HELPER
862   };
863
864 /* Return a value indicating how the caller should access the
865    mount namespace of process PID.  */
866
867 static enum mnsh_fs_code
868 linux_mntns_access_fs (pid_t pid)
869 {
870   struct cleanup *old_chain;
871   struct linux_ns *ns;
872   struct stat sb;
873   struct linux_mnsh *helper;
874   ssize_t size;
875   int fd, saved_errno;
876
877   if (pid == getpid ())
878     return MNSH_FS_DIRECT;
879
880   ns = linux_ns_get_namespace (LINUX_NS_MNT);
881   if (ns == NULL)
882     return MNSH_FS_DIRECT;
883
884   old_chain = make_cleanup (null_cleanup, NULL);
885
886   fd = gdb_open_cloexec (linux_ns_filename (ns, pid), O_RDONLY, 0);
887   if (fd < 0)
888     goto error;
889
890   old_chain = make_cleanup_close (fd);
891
892   if (fstat (fd, &sb) != 0)
893     goto error;
894
895   if (sb.st_ino == ns->id)
896     {
897       do_cleanups (old_chain);
898
899       return MNSH_FS_DIRECT;
900     }
901
902   helper = linux_mntns_get_helper ();
903   if (helper == NULL)
904     goto error;
905
906   if (sb.st_ino != helper->nsid)
907     {
908       int result, error;
909
910       size = mnsh_send_setns (helper, fd, 0);
911       if (size < 0)
912         goto error;
913
914       if (mnsh_recv_int (helper, &result, &error) != 0)
915         goto error;
916
917       if (result != 0)
918         {
919           /* ENOSYS indicates that an entire function is unsupported
920              (it's not appropriate for our versions of open/unlink/
921              readlink to sometimes return with ENOSYS depending on how
922              they're called) so we convert ENOSYS to ENOTSUP if setns
923              fails.  */
924           if (error == ENOSYS)
925             error = ENOTSUP;
926
927           errno = error;
928           goto error;
929         }
930
931       helper->nsid = sb.st_ino;
932     }
933
934   do_cleanups (old_chain);
935
936   return MNSH_FS_HELPER;
937
938 error:
939   saved_errno = errno;
940
941   do_cleanups (old_chain);
942
943   errno = saved_errno;
944   return MNSH_FS_ERROR;
945 }
946
947 /* See nat/linux-namespaces.h.  */
948
949 int
950 linux_mntns_open_cloexec (pid_t pid, const char *filename,
951                           int flags, mode_t mode)
952 {
953   enum mnsh_fs_code access = linux_mntns_access_fs (pid);
954   struct linux_mnsh *helper;
955   int fd, error;
956   ssize_t size;
957
958   if (access == MNSH_FS_ERROR)
959     return -1;
960
961   if (access == MNSH_FS_DIRECT)
962     return gdb_open_cloexec (filename, flags, mode);
963
964   gdb_assert (access == MNSH_FS_HELPER);
965
966   helper = linux_mntns_get_helper ();
967
968   size = mnsh_send_open (helper, filename, flags, mode);
969   if (size < 0)
970     return -1;
971
972   if (mnsh_recv_fd (helper, &fd, &error) != 0)
973     return -1;
974
975   if (fd < 0)
976     errno = error;
977
978   return fd;
979 }
980
981 /* See nat/linux-namespaces.h.  */
982
983 int
984 linux_mntns_unlink (pid_t pid, const char *filename)
985 {
986   enum mnsh_fs_code access = linux_mntns_access_fs (pid);
987   struct linux_mnsh *helper;
988   int ret, error;
989   ssize_t size;
990
991   if (access == MNSH_FS_ERROR)
992     return -1;
993
994   if (access == MNSH_FS_DIRECT)
995     return unlink (filename);
996
997   gdb_assert (access == MNSH_FS_HELPER);
998
999   helper = linux_mntns_get_helper ();
1000
1001   size = mnsh_send_unlink (helper, filename);
1002   if (size < 0)
1003     return -1;
1004
1005   if (mnsh_recv_int (helper, &ret, &error) != 0)
1006     return -1;
1007
1008   if (ret != 0)
1009     errno = error;
1010
1011   return ret;
1012 }
1013
1014 /* See nat/linux-namespaces.h.  */
1015
1016 ssize_t
1017 linux_mntns_readlink (pid_t pid, const char *filename,
1018                       char *buf, size_t bufsiz)
1019 {
1020   enum mnsh_fs_code access = linux_mntns_access_fs (pid);
1021   struct linux_mnsh *helper;
1022   int ret, error;
1023   ssize_t size;
1024
1025   if (access == MNSH_FS_ERROR)
1026     return -1;
1027
1028   if (access == MNSH_FS_DIRECT)
1029     return readlink (filename, buf, bufsiz);
1030
1031   gdb_assert (access == MNSH_FS_HELPER);
1032
1033   helper = linux_mntns_get_helper ();
1034
1035   size = mnsh_send_readlink (helper, filename);
1036   if (size < 0)
1037     return -1;
1038
1039   size = mnsh_recv_intstr (helper, &ret, &error, buf, bufsiz);
1040
1041   if (size < 0)
1042     {
1043       ret = -1;
1044       errno = error;
1045     }
1046   else
1047     gdb_assert (size == ret);
1048
1049   return ret;
1050 }