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