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