CernVM-FS  2.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cvmfs_talk.cc
Go to the documentation of this file.
1 
7 #include <errno.h>
8 #include <unistd.h>
9 
10 #include <cassert>
11 #include <cstring>
12 #include <string>
13 #include <vector>
14 
15 #include "logging.h"
16 #include "options.h"
17 #include "util/pointer.h"
18 #include "util/posix.h"
19 #include "util/string.h"
20 
21 
22 struct InstanceInfo {
23  bool IsDefined() {
24  return !socket_path.empty() || !instance_name.empty();
25  }
26 
27  // Called at most once by DeterminePath
28  static std::string GetDefaultDomain() {
29  std::string result;
30  BashOptionsManager options_mgr;
31  options_mgr.ParseDefault("");
32  bool retval = options_mgr.GetValue("CVMFS_DEFAULT_DOMAIN", &result);
33  if (!retval) {
35  "Error: could not determin CVMFS_DEFAULT_DOMAIN");
36  }
37  return result;
38  }
39 
40  bool DeterminePaths() {
41  std::string fqrn = instance_name;
42  if (fqrn.find('.') == std::string::npos) {
43  static std::string default_domain = GetDefaultDomain();
44  fqrn = fqrn + "." + default_domain;
45  }
46 
47  BashOptionsManager options_mgr;
48  options_mgr.ParseDefault(fqrn);
49  if (!options_mgr.GetValue("CVMFS_WORKSPACE", &workspace)) {
50  if (!options_mgr.GetValue("CVMFS_CACHE_DIR", &workspace)) {
51  bool retval = options_mgr.GetValue("CVMFS_CACHE_BASE", &workspace);
52  if (!retval) {
54  "CVMFS_WORKSPACE, CVMFS_CACHE_DIR, and CVMFS_CACHE_BASE "
55  "missing");
56  return false;
57  }
58 
59  std::string optarg;
60  if (options_mgr.GetValue("CVMFS_SHARED_CACHE", &optarg) &&
61  options_mgr.IsOn(optarg))
62  {
63  workspace += "/shared";
64  } else {
65  workspace += "/" + fqrn;
66  }
67  }
68  }
69 
70  socket_path = workspace + "/cvmfs_io." + fqrn;
71  return true;
72  }
73 
74  bool CompleteInfo() {
75  assert(IsDefined());
76 
77  if (socket_path.empty()) {
78  bool retval = DeterminePaths();
79  if (!retval)
80  return false;
81  identifier = "instance '" + instance_name + "' active in " + workspace;
82  } else {
84  identifier = "instance listening at " + socket_path;
85  }
86  return true;
87  }
88 
89  std::string socket_path;
90  std::string instance_name;
91  std::string workspace;
92  std::string identifier;
93 };
94 
95 
96 static bool ReadResponse(int fd) {
97  std::string line;
98  char buf;
99  int retval;
100  while ((retval = read(fd, &buf, 1)) == 1) {
101  if (buf == '\n') {
102  LogCvmfs(kLogCvmfs, kLogStdout, "%s", line.c_str());
103  line.clear();
104  continue;
105  }
106  line.push_back(buf);
107  }
108  return retval == 0;
109 }
110 
111 
112 bool SendCommand(const std::string &command, InstanceInfo instance_info) {
113  bool retval = instance_info.CompleteInfo();
114  if (!retval) return false;
115 
116  int fd = ConnectSocket(instance_info.socket_path);
117  if (fd < 0) {
118  if (errno == ENOENT) {
120  "Seems like CernVM-FS is not running in %s (not found: %s)",
121  instance_info.workspace.c_str(),
122  instance_info.socket_path.c_str());
123  } else {
124  LogCvmfs(kLogCvmfs, kLogStderr, "Could not access %s (%d - %s)",
125  instance_info.identifier.c_str(), errno, strerror(errno));
126  }
127  return false;
128  }
129 
130  WritePipe(fd, command.data(), command.size());
131  retval = ReadResponse(fd);
132  close(fd);
133 
134  if (!retval) {
135  LogCvmfs(kLogCvmfs, kLogStderr, "Broken connection to %s (%d - %s)",
136  instance_info.identifier.c_str(), errno, strerror(errno));
137  return false;
138  }
139  return true;
140 }
141 
142 
143 static void Usage(const std::string &exe) {
145  "Usage: %s [-i instance | -p socket] <command> \n"
146  " By default, iteratate through all instances. \n"
147  "\n"
148  "Example: \n"
149  " %s -i atlas.cern.ch pid \n"
150  "\n"
151  "Commands: \n"
152  " tracebuffer flush flushes the trace buffer to disk \n"
153  " cache instance describes the active cache manager \n"
154  " cache size gets current size of file cache \n"
155  " cache list gets files in cache \n"
156  " cache list pinned gets pinned file catalogs in cache \n"
157  " cache list catalogs gets all file catalogs in cache \n"
158  " cleanup <MB> cleans file cache until size <= <MB> \n"
159  " cleanup rate <period> n.o. cleanups in the last <period> min \n"
160  " evict <path> removes <path> from the cache \n"
161  " pin <path> pins <path> in the cache \n"
162  " mountpoint returns the mount point \n"
163  " device id returns major:minor virtual device id \n"
164  " on Linux and 0:0 on macOS \n"
165  " remount [sync] look for new catalogs \n"
166  " revision gets the repository revision \n"
167  " max ttl info gets the maximum ttl \n"
168  " max ttl set <minutes> sets the maximum ttl \n"
169  " nameserver get get the DNS server \n"
170  " nameserver set <host> sets a DNS server \n"
171  " host info get host chain and their rtt, \n"
172  " if already probed \n"
173  " host probe orders the host chain according to rtt \n"
174  " host probe geo let Stratum 1s order the host chain and \n"
175  " fallback proxies using the Geo-API \n"
176  " host switch switches to the next host in the chain \n"
177  " host set <host list> sets a new host chain \n"
178  " proxy info gets load-balance proxy groups \n"
179  " proxy rebalance randomly selects a new proxy server \n"
180  " from the current load-balance group \n"
181  " proxy group switch switches to the next load-balance \n"
182  " proxy group in the chain \n"
183  " proxy set <proxy list> sets a new chain of load-balance proxy \n"
184  " groups (not including fallback proxies) \n"
185  " proxy fallback <list> sets a new list of fallback proxies \n"
186  " external host info gets info about external host chain \n"
187  " external host switch switches to the next external host \n"
188  " external host set \n"
189  " <host list> sets external host chain \n"
190  " external proxy info gets info about external proxy groups \n"
191  " external proxy set \n"
192  " <proxy list> sets chain of external proxy groups \n"
193  " timeout info gets the network timeouts \n"
194  " timeout set \n"
195  " <proxy> <direct> sets the network timeouts in seconds \n"
196  " pid gets the pid \n"
197  " pid cachemgr gets the pid of the shared cache manager \n"
198  " pid watchdog gets the pid of the crash handler process\n"
199  " parameters dumps the effective parameters \n"
200  " reset error counters resets the counter for I/O errors \n"
201  " hotpatch history shows timestamps and version info of \n"
202  " loaded (hotpatched) Fuse modules \n"
203  " version gets cvmfs version \n"
204  " version patchlevel gets cvmfs patchlevel \n"
205  " open catalogs shows information about currently \n"
206  " loaded catalogs (_not_ all cached ones) \n"
207  " latency show the latencies of different fuse \n"
208  " calls (requires CVMFS_INSTRUMENT_FUSE) \n"
209  "\n",
210  exe.c_str(), exe.c_str());
211 }
212 
213 
214 int main(int argc, char *argv[]) {
215  InstanceInfo instance_info;
216  std::string command;
217 
218  int c;
219  // 's' for socket would have been a better option letter but we keep 'p'
220  // for backwards compatibility. The '+' at the beginning of the option stirng
221  // prevents permutation of the option and non-option arguments.
222  while ((c = getopt(argc, argv, "+hi:p:")) != -1) {
223  switch (c) {
224  case 'h':
225  Usage(argv[0]);
226  return 0;
227  case 'p':
228  instance_info.socket_path = optarg;
229  break;
230  case 'i':
231  instance_info.instance_name = optarg;
232  break;
233  case '?':
234  default:
235  Usage(argv[0]);
236  return 1;
237  }
238  }
239 
240  for (; optind < argc; ++optind) {
241  command += argv[optind];
242  if (optind < (argc - 1))
243  command.push_back(' ');
244  }
245  if (command.empty()) {
246  LogCvmfs(kLogCvmfs, kLogStderr, "Command missing");
247  return 1;
248  }
249 
250  int retcode = 0;
251  if (!instance_info.IsDefined()) {
252  BashOptionsManager options_mgr;
253  options_mgr.ParseDefault("");
254  std::string opt_repos;
255  options_mgr.GetValue("CVMFS_REPOSITORIES", &opt_repos);
256  std::vector<std::string> repos = SplitString(opt_repos, ',');
257  for (unsigned i = 0; i < repos.size(); ++i) {
258  if (repos[i].empty())
259  continue;
260  instance_info.instance_name = repos[i];
261  LogCvmfs(kLogCvmfs, kLogStdout, "%s:", repos[i].c_str());
262  bool retval = SendCommand(command, instance_info);
263  if (!retval) retcode = 1;
264  }
265  } else {
266  bool retval = SendCommand(command, instance_info);
267  if (!retval) retcode = 1;
268  }
269  return retcode;
270 }
bool DeterminePaths()
Definition: cvmfs_talk.cc:40
std::string identifier
Definition: cvmfs_talk.cc:92
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
bool GetValue(const std::string &key, std::string *value)
Definition: options.cc:376
bool CompleteInfo()
Definition: cvmfs_talk.cc:74
static void Usage(const char *progname)
vector< string > SplitString(const string &str, const char delim, const unsigned max_chunks)
Definition: string.cc:288
assert((mem||(size==0))&&"Out Of Memory")
std::string GetParentPath(const std::string &path)
Definition: posix.cc:131
void ParseDefault(const std::string &fqrn)
Definition: options.cc:282
int main()
Definition: helper_allow.cc:16
std::string instance_name
Definition: cvmfs_talk.cc:90
int ConnectSocket(const std::string &path)
Definition: posix.cc:460
std::string workspace
Definition: cvmfs_talk.cc:91
bool IsDefined()
Definition: cvmfs_talk.cc:23
bool SendCommand(const std::string &command, InstanceInfo instance_info)
Definition: cvmfs_talk.cc:112
void WritePipe(int fd, const void *buf, size_t nbyte)
Definition: posix.cc:534
std::string socket_path
Definition: cvmfs_talk.cc:89
static bool ReadResponse(int fd)
Definition: cvmfs_talk.cc:96
bool IsOn(const std::string &param_value)
Definition: options.cc:409
static std::string GetDefaultDomain()
Definition: cvmfs_talk.cc:28