CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
receiver.cc
Go to the documentation of this file.
1 
5 #include <string>
6 
7 #include "cvmfs_config.h"
8 
9 #include "monitor.h"
10 #include "swissknife.h"
11 #include "util/exception.h"
12 #include "util/logging.h"
13 #include "util/posix.h"
14 #include "util/string.h"
15 
16 #include "reactor.h"
17 
18 static const char *kDefaultReceiverLogDir = "/var/log/cvmfs_receiver/";
19 
22  params.push_back(
23  swissknife::Parameter::Optional('i', "File descriptor to use for input"));
24  params.push_back(swissknife::Parameter::Optional(
25  'o', "File descriptor to use for output"));
26  params.push_back(swissknife::Parameter::Optional(
27  'w', "Watchdog stacktrace output dir, "
28  "use without parameter to disable watchdog. "
29  "Default: " + std::string(kDefaultReceiverLogDir)));
30  return params;
31 }
32 
33 bool ReadCmdLineArguments(int argc, char** argv,
34  const swissknife::ParameterList& params,
35  swissknife::ArgumentList* arguments) {
36  // parse the command line arguments for the Command
37  optind = 1;
38  std::string option_string = "";
39 
40  for (unsigned j = 0; j < params.size(); ++j) {
41  option_string.push_back(params[j].key());
42  if (!params[j].switch_only()) option_string.push_back(':');
43  }
44 
45  int c;
46  while ((c = getopt(argc, argv, option_string.c_str())) != -1) {
47  bool valid_option = false;
48  for (unsigned j = 0; j < params.size(); ++j) {
49  if (c == params[j].key()) {
50  valid_option = true;
51  (*arguments)[c].Reset();
52  if (!params[j].switch_only()) {
53  (*arguments)[c].Reset(new std::string(optarg));
54  }
55  break;
56  }
57  }
58 
59  if (!valid_option) {
61  "CVMFS gateway services receiver component. Usage:");
62  for (size_t i = 0; i < params.size(); ++i) {
63  LogCvmfs(kLogReceiver, kLogSyslog, " \"%c\" - %s", params[i].key(),
64  params[i].description().c_str());
65  }
66  return false;
67  }
68  }
69 
70  for (size_t j = 0; j < params.size(); ++j) {
71  if (!params[j].optional()) {
72  if (arguments->find(params[j].key()) == arguments->end()) {
73  LogCvmfs(kLogReceiver, kLogSyslogErr, "parameter -%c missing",
74  params[j].key());
75  return false;
76  }
77  }
78  }
79 
80  return true;
81 }
82 
83 int main(int argc, char** argv) {
84  swissknife::ArgumentList arguments;
85  if (!ReadCmdLineArguments(argc, argv, MakeParameterList(), &arguments)) {
86  return 1;
87  }
88 
90  SetLogSyslogShowPID(true);
91 
92  int fdin = 0;
93  int fdout = 1;
94  std::string watchdog_out_dir = kDefaultReceiverLogDir;
95  if (arguments.find('i') != arguments.end()) {
96  fdin = std::atoi(arguments.find('i')->second->c_str());
97  }
98  if (arguments.find('o') != arguments.end()) {
99  fdout = std::atoi(arguments.find('o')->second->c_str());
100  }
101  if (arguments.find('w') != arguments.end()) {
102  watchdog_out_dir = *arguments.find('w')->second;
103  }
104 
105  // Spawn monitoring process (watchdog)
106  UniquePtr<Watchdog> watchdog;
107  if (watchdog_out_dir != "") {
108  if (!MkdirDeep(watchdog_out_dir, 0755)) {
110  "Failed to create stacktrace directory: %s",
111  watchdog_out_dir.c_str());
112  return 1;
113  }
114  std::string timestamp = GetGMTimestamp("%Y.%m.%d-%H.%M.%S");
115  watchdog = Watchdog::Create(NULL);
116  if (watchdog.IsValid() == false) {
118  "Failed to initialize watchdog");
119  return 1;
120  }
121  watchdog->Spawn(watchdog_out_dir + "/stacktrace." + timestamp);
122  }
123 
124  LogCvmfs(kLogReceiver, kLogSyslog, "CVMFS receiver started");
125 
126  receiver::Reactor reactor(fdin, fdout);
127 
128  try {
129  if (!reactor.Run()) {
131  "Error running CVMFS Receiver event loop");
132  return 1;
133  }
134  } catch (const ECvmfsException& e) {
136  "Runtime error during CVMFS Receiver event loop.\n"
137  "%s",
138  e.what());
139  return 2;
140  } catch (...) {
142  "Unknown error during CVMFS Receiver event loop.\n");
143  return 3;
144  }
145 
146  LogCvmfs(kLogReceiver, kLogSyslog, "CVMFS receiver finished");
147 
148  return 0;
149 }
static Parameter Optional(const char key, const std::string &desc)
Definition: swissknife.h:41
void SetLogSyslogFacility(const int local_facility)
Definition: logging.cc:183
std::string GetGMTimestamp(const std::string &format)
Definition: string.cc:615
void SetLogSyslogShowPID(bool flag)
Definition: logging.cc:254
std::vector< Parameter > ParameterList
Definition: swissknife.h:71
static const char * kDefaultReceiverLogDir
Definition: receiver.cc:18
int main()
Definition: helper_allow.cc:16
static Watchdog * Create(FnOnCrash on_crash)
Definition: monitor.cc:70
bool MkdirDeep(const std::string &path, const mode_t mode, bool verify_writable)
Definition: posix.cc:846
bool ReadCmdLineArguments(int argc, char **argv, const swissknife::ParameterList &params, swissknife::ArgumentList *arguments)
Definition: receiver.cc:33
swissknife::ParameterList MakeParameterList()
Definition: receiver.cc:20
std::map< char, SharedPtr< std::string > > ArgumentList
Definition: swissknife.h:72
void Spawn(const std::string &crash_dump_path)
Definition: monitor.cc:510
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:528