1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include "bus-internal.h"
28 #include "bus-socket.h"
29 #include "bus-container.h"
31 int bus_container_connect_socket(sd_bus *b) {
32 _cleanup_close_ int nsfd = -1, rootfd = -1;
38 assert(b->input_fd < 0);
39 assert(b->output_fd < 0);
41 r = container_get_leader(b->machine, &leader);
45 r = namespace_open(leader, &nsfd, &rootfd);
49 b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
53 b->output_fd = b->input_fd;
55 r = bus_socket_setup(b);
65 r = namespace_enter(nsfd, rootfd);
69 r = connect(b->input_fd, &b->sockaddr.sa, b->sockaddr_size);
71 if (errno == EINPROGRESS)
80 r = wait_for_terminate(child, &si);
84 if (si.si_code != CLD_EXITED)
87 if (si.si_status == 1)
90 if (si.si_status != EXIT_SUCCESS)
93 return bus_socket_start_auth(b);
96 int bus_container_connect_kernel(sd_bus *b) {
97 _cleanup_close_pipe_ int pair[2] = { -1, -1 };
98 _cleanup_close_ int nsfd = -1, rootfd = -1;
100 struct cmsghdr cmsghdr;
101 uint8_t buf[CMSG_SPACE(sizeof(int))];
104 .msg_control = &control,
105 .msg_controllen = sizeof(control),
107 struct cmsghdr *cmsg;
111 _cleanup_close_ int fd = -1;
114 assert(b->input_fd < 0);
115 assert(b->output_fd < 0);
117 r = container_get_leader(b->machine, &leader);
121 r = namespace_open(leader, &nsfd, &rootfd);
125 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
133 close_nointr_nofail(pair[0]);
136 r = namespace_enter(nsfd, rootfd);
140 fd = open(b->kernel, O_RDWR|O_NOCTTY|O_CLOEXEC);
144 cmsg = CMSG_FIRSTHDR(&mh);
145 cmsg->cmsg_level = SOL_SOCKET;
146 cmsg->cmsg_type = SCM_RIGHTS;
147 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
148 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
150 mh.msg_controllen = cmsg->cmsg_len;
152 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
158 close_nointr_nofail(pair[1]);
161 if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
164 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
165 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
169 fds = (int*) CMSG_DATA(cmsg);
170 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
173 close_many(fds, n_fds);
180 r = wait_for_terminate(child, &si);
184 if (si.si_code != CLD_EXITED)
187 if (si.si_status != EXIT_SUCCESS)
190 b->input_fd = b->output_fd = fd;
193 return bus_kernel_take_fd(b);