CernVM-FS  2.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
loader_talk.cc
Go to the documentation of this file.
1 
5 #include "cvmfs_config.h"
6 #include "loader_talk.h"
7 
8 #include <errno.h>
9 #include <sys/socket.h>
10 #include <sys/un.h>
11 #include <unistd.h>
12 
13 #include <cassert>
14 #include <cstdlib>
15 
16 #include "loader.h"
17 #include "logging.h"
18 #include "platform.h"
19 #include "util/exception.h"
20 #include "util/posix.h"
21 
22 using namespace std; // NOLINT
23 
24 namespace loader {
25 namespace loader_talk {
26 
27 bool spawned_ = false;
28 string *socket_path_ = NULL;
29 int socket_fd_ = -1;
30 pthread_t thread_talk_;
31 
32 bool Init(const string &socket_path) {
33  spawned_ = false;
34  socket_path_ = new string(socket_path);
35 
37  if (socket_fd_ == -1)
38  return false;
39  if (listen(socket_fd_, 1) == -1) {
40  LogCvmfs(kLogCvmfs, kLogDebug, "listening on socket failed (%d)", errno);
41  return false;
42  }
43 
44  unlink((socket_path + ".paused.crashed").c_str());
45  unlink((socket_path + ".paused").c_str());
46 
47  return true;
48 }
49 
50 
51 static void *MainTalk(void *data __attribute__((unused))) {
52  struct sockaddr_un remote;
53  socklen_t socket_size = sizeof(remote);
54  int con_fd = -1;
55  while (true) {
56  if (con_fd >= 0) {
57  shutdown(con_fd, SHUT_RDWR);
58  close(con_fd);
59  }
60  if ((con_fd = accept(socket_fd_, (struct sockaddr *)&remote, &socket_size))
61  < 0)
62  {
63  break;
64  }
65 
66  char command;
67  if (recv(con_fd, &command, 1, 0) > 0) {
68  if ((command != 'R') && (command != 'S')) {
69  SendMsg2Socket(con_fd, "unknown command\n");
70  continue;
71  }
72 
74  LogCvmfs(kLogCvmfs, kLogSyslog, "reloading Fuse module");
75  int retval = Reload(con_fd, command == 'S');
76  SendMsg2Socket(con_fd, "~");
77  (void)send(con_fd, &retval, sizeof(retval), MSG_NOSIGNAL);
78  if (retval != kFailOk) {
79  PANIC(kLogSyslogErr, "reloading Fuse module failed (%d - %s)", retval,
80  Code2Ascii(static_cast<Failures>(retval)));
81  }
83  }
84  }
85 
86  return NULL;
87 }
88 
89 
90 void Spawn() {
91  int retval;
92  retval = pthread_create(&thread_talk_, NULL, MainTalk, NULL);
93  assert(retval == 0);
94  spawned_ = true;
95 }
96 
97 
98 void Fini() {
99  unlink(socket_path_->c_str());
100  shutdown(socket_fd_, SHUT_RDWR);
101  close(socket_fd_);
102  if (spawned_) pthread_join(thread_talk_, NULL);
103 
104  delete socket_path_;
105  socket_path_ = NULL;
106  spawned_ = false;
107  socket_fd_ = -1;
108 }
109 
110 
114 int MainReload(const std::string &socket_path, const bool stop_and_go) {
116  "Connecting to CernVM-FS loader... ");
117  int socket_fd = ConnectSocket(socket_path);
118  if (socket_fd < 0) {
119  LogCvmfs(kLogCvmfs, kLogStdout, "failed!");
120  return 100;
121  }
122  LogCvmfs(kLogCvmfs, kLogStdout, "done");
123 
124  const char command = stop_and_go ? 'S' : 'R';
125  WritePipe(socket_fd, &command, 1);
126  char buf;
127  int retval;
128  while ((retval = read(socket_fd, &buf, 1)) == 1) {
129  if (buf == '~')
130  break;
132  }
133  if (retval != 1) {
134  LogCvmfs(kLogCvmfs, kLogStderr, "Reload CRASHED! "
135  "CernVM-FS mountpoints unusable.");
136  return 101;
137  }
138 
139  int result = 102;
140  if (read(socket_fd, &result, sizeof(result)) < 0) {
141  LogCvmfs(kLogCvmfs, kLogStderr, "Socket read FAILED! "
142  "CernVM-FS mountpoints unusable.");
143  } else {
144  if (result != kFailOk) {
145  LogCvmfs(kLogCvmfs, kLogStderr, "Reload FAILED! "
146  "CernVM-FS mountpoints unusable.");
147  }
148  }
149 
150  return result;
151 }
152 
153 } // namespace loader_talk
154 } // namespace loader
Failures Reload(const int fd_progress, const bool stop_and_go)
Definition: loader.cc:548
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
const char * Code2Ascii(const ObjectFetcherFailures::Failures error)
static void * MainTalk(void *data __attribute__((unused)))
Definition: loader_talk.cc:51
int MakeSocket(const std::string &path, const int mode)
Definition: posix.cc:364
#define PANIC(...)
Definition: exception.h:26
string * usyslog_path_
Definition: loader.cc:131
pthread_t thread_talk_
Definition: loader_talk.cc:30
void SendMsg2Socket(const int fd, const std::string &msg)
Definition: posix.cc:692
assert((mem||(size==0))&&"Out Of Memory")
void SetLogMicroSyslog(const std::string &filename)
Definition: logging.cc:267
struct cvmcache_object_info __attribute__
Definition: atomic.h:24
string * socket_path_
Definition: loader.cc:130
int MainReload(const std::string &socket_path, const bool stop_and_go)
Definition: loader_talk.cc:114
static int Init(const loader::LoaderExports *loader_exports)
Definition: cvmfs.cc:1755
int ConnectSocket(const std::string &path)
Definition: posix.cc:460
static void Fini()
Definition: cvmfs.cc:1961
static void Spawn()
Definition: cvmfs.cc:1876
#define MSG_NOSIGNAL
Definition: platform_osx.h:53
void WritePipe(int fd, const void *buf, size_t nbyte)
Definition: posix.cc:534