GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/loader_talk.cc Lines: 0 69 0.0 %
Date: 2019-02-03 02:48:13 Branches: 0 36 0.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 */
4
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/posix.h"
20
21
using namespace std;  // NOLINT
22
23
namespace loader {
24
namespace loader_talk {
25
26
bool spawned_ = false;
27
string *socket_path_ = NULL;
28
int socket_fd_ = -1;
29
pthread_t thread_talk_;
30
31
bool Init(const string &socket_path) {
32
  spawned_ = false;
33
  socket_path_ = new string(socket_path);
34
35
  socket_fd_ = MakeSocket(*socket_path_, 0600);
36
  if (socket_fd_ == -1)
37
    return false;
38
  if (listen(socket_fd_, 1) == -1) {
39
    LogCvmfs(kLogCvmfs, kLogDebug, "listening on socket failed (%d)", errno);
40
    return false;
41
  }
42
43
  unlink((socket_path + ".paused.crashed").c_str());
44
  unlink((socket_path + ".paused").c_str());
45
46
  return true;
47
}
48
49
50
static void *MainTalk(void *data __attribute__((unused))) {
51
  struct sockaddr_un remote;
52
  socklen_t socket_size = sizeof(remote);
53
  int con_fd = -1;
54
  while (true) {
55
    if (con_fd >= 0) {
56
      shutdown(con_fd, SHUT_RDWR);
57
      close(con_fd);
58
    }
59
    if ((con_fd = accept(socket_fd_, (struct sockaddr *)&remote, &socket_size))
60
         < 0)
61
    {
62
      break;
63
    }
64
65
    char command;
66
    if (recv(con_fd, &command, 1, 0) > 0) {
67
      if ((command != 'R') && (command != 'S')) {
68
        SendMsg2Socket(con_fd, "unknown command\n");
69
        continue;
70
      }
71
72
      SetLogMicroSyslog(*usyslog_path_);
73
      LogCvmfs(kLogCvmfs, kLogSyslog, "reloading Fuse module");
74
      int retval = Reload(con_fd, command == 'S');
75
      SendMsg2Socket(con_fd, "~");
76
      (void)send(con_fd, &retval, sizeof(retval), MSG_NOSIGNAL);
77
      if (retval != kFailOk) {
78
        LogCvmfs(kLogCvmfs, kLogSyslogErr, "reloading Fuse module failed "
79
                                           "(%d - %s)",
80
                 retval, Code2Ascii(static_cast<Failures>(retval)));
81
        abort();
82
      }
83
      SetLogMicroSyslog("");
84
    }
85
  }
86
87
  return NULL;
88
}
89
90
91
void Spawn() {
92
  int retval;
93
  retval = pthread_create(&thread_talk_, NULL, MainTalk, NULL);
94
  assert(retval == 0);
95
  spawned_ = true;
96
}
97
98
99
void Fini() {
100
  unlink(socket_path_->c_str());
101
  shutdown(socket_fd_, SHUT_RDWR);
102
  close(socket_fd_);
103
  if (spawned_) pthread_join(thread_talk_, NULL);
104
105
  delete socket_path_;
106
  socket_path_ = NULL;
107
  spawned_ = false;
108
  socket_fd_ = -1;
109
}
110
111
112
/**
113
 * Connects to a loader socket and triggers the reload
114
 */
115
int MainReload(const std::string &socket_path, const bool stop_and_go) {
116
  LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak,
117
           "Connecting to CernVM-FS loader... ");
118
  int socket_fd = ConnectSocket(socket_path);
119
  if (socket_fd < 0) {
120
    LogCvmfs(kLogCvmfs, kLogStdout, "failed!");
121
    return 100;
122
  }
123
  LogCvmfs(kLogCvmfs, kLogStdout, "done");
124
125
  const char command = stop_and_go ? 'S' : 'R';
126
  WritePipe(socket_fd, &command, 1);
127
  char buf;
128
  int retval;
129
  while ((retval = read(socket_fd, &buf, 1)) == 1) {
130
    if (buf == '~')
131
      break;
132
    LogCvmfs(kLogCvmfs, kLogStdout | kLogNoLinebreak, "%c", buf);
133
  }
134
  if (retval != 1) {
135
    LogCvmfs(kLogCvmfs, kLogStderr, "Reload CRASHED! "
136
             "CernVM-FS mountpoints unusable.");
137
    return 101;
138
  }
139
140
  int result = 102;
141
  if (read(socket_fd, &result, sizeof(result)) < 0) {
142
    LogCvmfs(kLogCvmfs, kLogStderr, "Socket read FAILED! "
143
             "CernVM-FS mountpoints unusable.");
144
  } else {
145
    if (result != kFailOk) {
146
      LogCvmfs(kLogCvmfs, kLogStderr, "Reload FAILED! "
147
               "CernVM-FS mountpoints unusable.");
148
    }
149
  }
150
151
  return result;
152
}
153
154
}  // namespace loader_talk
155
}  // namespace loader