Apache Mesos
domain_sockets.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __COMMON_DOMAIN_SOCKETS_HPP__
18 #define __COMMON_DOMAIN_SOCKETS_HPP__
19 
20 #include <unistd.h> // unlink()
21 
22 #include <process/socket.hpp>
23 
24 #include <stout/nothing.hpp>
25 #include <stout/option.hpp>
26 #include <stout/os/open.hpp>
27 #include <stout/posix/os.hpp> // chmod()
28 #include <stout/try.hpp>
29 
30 
31 namespace mesos {
32 namespace internal {
33 namespace common {
34 
35 constexpr size_t DOMAIN_SOCKET_MAX_PATH_LENGTH = 108;
36 constexpr int DOMAIN_SOCKET_DEFAULT_MODE = 0666;
37 
38 
40  const std::string& path,
41  int mode = DOMAIN_SOCKET_DEFAULT_MODE)
42 {
43  // If the file exists, and it already is a socket, we assume that it is
44  // left over from a previous run and unlink it before creating a new socket.
45  //
46  // Note that existing connections using this socket will not be interrupted
47  // by deleting the socket file.
48  //
49  // Note also that if the file exists and is not a socket, we return an Error
50  // when we try to `bind()`.
51  if (os::stat::issocket(path)) {
52  // TODO(bevers): Move to `os::unlink()`.
53  LOG(INFO) << "Removing existing socket at " << path;
54  ::unlink(path.c_str());
55  }
56 
59 
60  if (socket.isError()) {
61  return Error(
62  "Failed to create unix domain socket: " + socket.error());
63  }
64 
67 
68  if (addr.isError()) {
69  return Error(
70  "Failed to parse path " + path + ": " + addr.error());
71  }
72 
73  Try<process::network::unix::Address> bound = socket->bind(addr.get());
74  if (bound.isError()) {
75  return Error(
76  "Failed to bind domain socket to path " + path + ": " +
77  bound.error());
78  }
79 
81  if (chmod.isError()) {
82  return Error("Couldn't change domain socket permissions: " +
83  chmod.error());
84  }
85 
86  return socket;
87 }
88 
89 } // namespace common {
90 } // namespace internal {
91 } // namespace mesos {
92 
93 #endif // __COMMON_DOMAIN_SOCKETS_HPP__
Definition: path.hpp:29
Definition: errorbase.hpp:36
bool issocket(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:117
Try< Nothing > chmod(const std::string &path, int mode)
Definition: os.hpp:195
Definition: check.hpp:33
constexpr size_t DOMAIN_SOCKET_MAX_PATH_LENGTH
Definition: domain_sockets.hpp:35
static Try< Socket > create(int_fd s, SocketImpl::Kind kind=SocketImpl::DEFAULT_KIND())
Returns an instance of a Socket using the specified kind of implementation.
Definition: socket.hpp:274
static Try< Address > create(const std::string &path)
Definition: address.hpp:210
Try< process::network::unix::Socket > createDomainSocket(const std::string &path, int mode=DOMAIN_SOCKET_DEFAULT_MODE)
Definition: domain_sockets.hpp:39
Definition: agent.hpp:25
constexpr int DOMAIN_SOCKET_DEFAULT_MODE
Definition: domain_sockets.hpp:36
Definition: attributes.hpp:24
Try< mode_t > mode(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:168
Try< Netlink< struct nl_sock > > socket(int protocol=NETLINK_ROUTE)
Definition: internal.hpp:91