CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
libcvmfs_legacy.cc
Go to the documentation of this file.
1 
9 #include <cstdio>
10 #include <cstring>
11 #include <string>
12 
13 #include "libcvmfs.h"
14 #include "libcvmfs_int.h"
15 #include "loader.h"
16 #include "options.h"
17 #include "util/string.h"
18 
19 using namespace std; // NOLINT
20 
21 static int set_option(char const *name, char const *value, bool *var) {
22  if (*value != '\0') {
23  fprintf(stderr, "Option %s=%s contains a value when none was expected.\n",
24  name, value);
25  return -1;
26  }
27  *var = true;
28  return 0;
29 }
30 
31 
32 static int set_option(char const *name, char const *value, unsigned *var) {
33  unsigned v = 0;
34  int end = 0;
35  const int rc = sscanf(value, "%u%n", &v, &end);
36  if (rc != 1 || value[end] != '\0') {
37  fprintf(stderr, "Invalid unsigned integer value for %s=%s\n", name, value);
38  return -1;
39  }
40  *var = v;
41  return 0;
42 }
43 
44 
45 static int set_option(char const *name, char const *value, int *var) {
46  int v = 0;
47  int end = 0;
48  const int rc = sscanf(value, "%d%n", &v, &end);
49  if (rc != 1 || value[end] != '\0') {
50  fprintf(stderr, "Invalid integer value for %s=%s\n", name, value);
51  return -1;
52  }
53  *var = v;
54  return 0;
55 }
56 
57 
58 static int set_option(char const *name, char const *value, string *var) {
59  *var = value;
60  return 0;
61 }
62 
63 
64 #define CVMFS_OPT(var) \
65  if (strcmp(name, #var) == 0) \
66  return ::set_option(name, value, &var)
67 
68 
70  int set_option(char const *name, char const *value) {
71  CVMFS_OPT(allow_unsigned);
72  CVMFS_OPT(blacklist);
73  CVMFS_OPT(deep_mount); // deprecated
74  CVMFS_OPT(fallback_proxies);
75  CVMFS_OPT(mountpoint);
76  CVMFS_OPT(proxies);
77  CVMFS_OPT(pubkey);
78  CVMFS_OPT(repo_name);
79  CVMFS_OPT(timeout);
80  CVMFS_OPT(timeout_direct);
81  CVMFS_OPT(tracefile);
82  CVMFS_OPT(url);
83 
84  fprintf(stderr, "Unknown repo option: %s\n", name);
85  return -1;
86  }
87 
88  int verify_sanity() {
89  if (mountpoint.empty() && !repo_name.empty()) {
90  mountpoint = "/cvmfs/";
91  mountpoint += repo_name;
92  }
93  while (mountpoint.length() > 0
94  && mountpoint[mountpoint.length() - 1] == '/') {
95  mountpoint.resize(mountpoint.length() - 1);
96  }
97 
98  return LIBCVMFS_FAIL_OK;
99  }
100 
102  : timeout(2)
103  , timeout_direct(2)
104  , pubkey("/etc/cvmfs/keys/cern.ch.pub")
105  , blacklist("")
106  , allow_unsigned(false) { }
107 
108  unsigned timeout;
109  unsigned timeout_direct;
110  std::string url;
111  std::string external_url;
112  std::string proxies;
113  std::string fallback_proxies;
114  std::string tracefile; // unused
115  std::string pubkey;
116  std::string deep_mount;
117  std::string blacklist;
118  std::string repo_name;
119  std::string root_hash;
120  std::string mountpoint;
122 };
123 
124 
126  int set_option(char const *name, char const *value) {
127  CVMFS_OPT(alien_cache);
128  CVMFS_OPT(alien_cachedir);
129  CVMFS_OPT(cache_directory);
130  CVMFS_OPT(cachedir);
131  CVMFS_OPT(lock_directory);
132  CVMFS_OPT(change_to_cache_directory);
133  CVMFS_OPT(logfile);
134  CVMFS_OPT(log_file);
135  CVMFS_OPT(log_prefix);
136  CVMFS_OPT(log_syslog_level);
138  CVMFS_OPT(max_open_files);
139  CVMFS_OPT(nofiles);
140  CVMFS_OPT(quota_limit);
141  CVMFS_OPT(quota_threshold);
142  CVMFS_OPT(rebuild_cachedb);
143 
144  fprintf(stderr, "Unknown global option: %s\n", name);
145  return LIBCVMFS_FAIL_BADOPT;
146  }
147 
149  // Alias handling
150  if ((nofiles >= 0) && (max_open_files != 0) && (nofiles != max_open_files))
151  return LIBCVMFS_FAIL_BADOPT;
152  if (nofiles >= 0)
153  max_open_files = nofiles;
154 
155  if ((syslog_level >= 0) && (log_syslog_level != 0)
156  && (syslog_level != log_syslog_level)) {
157  return LIBCVMFS_FAIL_BADOPT;
158  }
159  if (syslog_level >= 0)
160  log_syslog_level = syslog_level;
161  if (log_syslog_level < 0)
162  log_syslog_level = 3;
163 
164  if ((logfile != "") && (log_file != "") && (log_file != logfile))
165  return LIBCVMFS_FAIL_BADOPT;
166  if (logfile != "")
167  log_file = logfile;
168 
169  if ((cachedir != "") && (cache_directory != "")
170  && (cache_directory != cachedir)) {
171  return LIBCVMFS_FAIL_BADOPT;
172  }
173  if (cachedir != "")
174  cache_directory = cachedir;
175 
176  return LIBCVMFS_FAIL_OK;
177  }
178 
180  : change_to_cache_directory(false)
181  , alien_cache(false)
182  , syslog_level(-1)
183  , log_syslog_level(-1)
184  , nofiles(-1)
185  , max_open_files(0)
186  , quota_limit(0)
187  , quota_threshold(0)
188  , rebuild_cachedb(0) { }
189 
190  std::string cache_directory;
191  std::string cachedir; // Alias of cache_directory
192  std::string alien_cachedir;
193  std::string lock_directory;
196 
199  std::string log_prefix;
200  std::string logfile;
201  std::string log_file;
202 
203  int nofiles;
204  int max_open_files; // Alias of nofiles
205 
206  // Currently ignored
207  unsigned quota_limit;
208  unsigned quota_threshold;
210 };
211 
212 
216 template<class DerivedT>
217 struct cvmfs_options : public DerivedT {
218  int set_option(char const *name, char const *value) {
219  return DerivedT::set_option(name, value);
220  }
221 
222  int parse_options(char const *options) {
223  while (*options) {
224  char const *next = options;
225  string name;
226  string value;
227 
228  // get the option name
229  for (next = options; *next && *next != ',' && *next != '='; next++) {
230  if (*next == '\\') {
231  next++;
232  if (*next == '\0')
233  break;
234  }
235  name += *next;
236  }
237 
238  if (*next == '=') {
239  next++;
240  }
241 
242  // get the option value
243  for (; *next && *next != ','; next++) {
244  if (*next == '\\') {
245  next++;
246  if (*next == '\0')
247  break;
248  }
249  value += *next;
250  }
251 
252  if (!name.empty() || !value.empty()) {
253  const int result = set_option(name.c_str(), value.c_str());
254  if (result != 0) {
255  return result;
256  }
257  }
258 
259  if (*next == ',')
260  next++;
261  options = next;
262  }
263 
264  return DerivedT::verify_sanity();
265  }
266 };
267 
270 
274 static void usage() {
275  struct cvmfs_repo_options const defaults;
276  fprintf(
277  stderr,
278  "CernVM-FS version %s\n"
279  "Copyright (c) 2009- CERN\n"
280  "All rights reserved\n\n"
281  "Please visit http://cernvm.cern.ch/project/info for license details "
282  "and author list.\n\n"
283 
284  "libcvmfs options are expected in the form: option1,option2,option3,...\n"
285  "Within an option, the characters , and \\ must be preceded by \\.\n\n"
286 
287  "There are two types of options (global and repository specifics)\n"
288  " cvmfs_init() expects global options\n"
289  " cvmfs_attach_repo() expects repository specific options\n"
290 
291  "global options are:\n"
292  " cache_directory/cachedir=DIR Where to store disk cache\n"
293  " change_to_cache_directory Performs a cd to the cache directory "
294  "(performance tweak)\n"
295  " alien_cache Treat cache directory as alien cache\n"
296  " alien_cachedir=DIR Explicitly set an alien cache directory\n"
297  " lock_directory=DIR Directory for per instance lock files.\n"
298  " Needs to be on a file system with POSIX "
299  "locks.\n"
300  " Should be different from alien cache "
301  "directory."
302  " \nDefaults to cache_directory.\n"
303  " (log_)syslog_level=LEVEL Sets the level used for syslog to "
304  "DEBUG (1), INFO (2), or NOTICE (3).\n"
305  " Default is NOTICE.\n"
306  " log_prefix String to use as a log prefix in syslog\n"
307  " log_file/logfile Logs all messages to FILE instead of "
308  "stderr and daemonizes.\n"
309  " Makes only sense for the debug version\n"
310  " nofiles/max_open_files Set the maximum number of open files "
311  "for CernVM-FS process (soft limit)\n\n"
312 
313  "repository specific options are:"
314  " repo_name=REPO_NAME Unique name of the mounted repository, "
315  "e.g. atlas.cern.ch\n"
316  " url=REPOSITORY_URL The URL of the CernVM-FS server(s): "
317  "'url1;url2;...'\n"
318  " timeout=SECONDS Timeout for network operations (default is "
319  "%d)\n"
320  " timeout_direct=SECONDS Timeout for network operations without "
321  "proxy "
322  "(default is %d)\n"
323  " proxies=HTTP_PROXIES Set the HTTP proxy list, such as "
324  "'proxy1|proxy2;DIRECT'\n"
325  " fallback_proxies=PROXIES Set the fallback proxy list, such as "
326  "'proxy1;proxy2'\n"
327  " tracefile=FILE Trace FUSE opaerations into FILE\n"
328  " pubkey=PEMFILE Public RSA key that is used to verify the "
329  "whitelist signature.\n"
330  " allow_unsigned Accept unsigned catalogs "
331  "(allows man-in-the-middle attacks)\n"
332  " deep_mount=PREFIX Path prefix if a repository is mounted on a "
333  "nested catalog,\n"
334  " i.e. deep_mount=/software/15.0.1\n"
335  " mountpoint=PATH Path to root of repository, "
336  "e.g. /cvmfs/atlas.cern.ch\n"
337  " blacklist=FILE Local blacklist for invalid certificates. "
338  "Has precedence over the whitelist.\n",
339  CVMFS_VERSION, defaults.timeout, defaults.timeout_direct);
340 }
341 
342 
347  const int unknown = -10;
348 
349  switch (code) {
350  case loader::kFailOk:
351  return LIBCVMFS_FAIL_OK;
353  return unknown; // missing constant
355  return LIBCVMFS_FAIL_BADOPT;
357  return LIBCVMFS_FAIL_NOFILES;
358  case loader::kFailMount:
363  return unknown;
365  return LIBCVMFS_FAIL_MKCACHE;
366  case loader::kFailPeers:
368  return unknown;
369  case loader::kFailQuota:
372  case loader::kFailTalk:
373  return unknown;
384  return unknown;
385  case loader::kFailWpad:
388  return LIBCVMFS_FAIL_LOCKFILE;
389  default:
390  return unknown;
391  }
392 }
393 
394 
395 SimpleOptionsParser *cvmfs_options_init_legacy(char const *legacy_options) {
396  global_options global_opts;
397  const int parse_result = global_opts.parse_options(legacy_options);
398  if (parse_result != 0) {
399  fprintf(stderr, "Invalid CVMFS global options: %s.\n", legacy_options);
400  usage();
401  return NULL;
402  }
403 
404  SimpleOptionsParser *options_mgr = cvmfs_options_init();
405  options_mgr->SetValue("CVMFS_CACHE_DIR", global_opts.cache_directory);
406  if (!global_opts.lock_directory.empty()) {
407  options_mgr->SetValue("CVMFS_WORKSPACE", global_opts.lock_directory);
408  }
409  if (global_opts.alien_cache) {
410  options_mgr->SetValue("CVMFS_ALIEN_CACHE", global_opts.cache_directory);
411  }
412  if (!global_opts.alien_cachedir.empty()) {
413  options_mgr->SetValue("CVMFS_ALIEN_CACHE", global_opts.alien_cachedir);
414  }
415  // Note: as of version 2.4 CVMFS_CWD_CACHE support was dropped due to
416  // disproportional large complexity in the FileSystem class
417  // if (global_opts.change_to_cache_directory) {
418  // options_mgr->SetValue("CVMFS_CWD_CACHE", "on");
419  // }
420  options_mgr->SetValue("CVMFS_SYSLOG_LEVEL",
421  StringifyInt(global_opts.log_syslog_level));
422  if (!global_opts.log_prefix.empty()) {
423  options_mgr->SetValue("CVMFS_SYSLOG_PREFIX", global_opts.log_prefix);
424  }
425  if (!global_opts.log_file.empty()) {
426  options_mgr->SetValue("CVMFS_DEBUGLOG", global_opts.log_file);
427  }
428  if (global_opts.max_open_files > 0) {
429  options_mgr->SetValue("CVMFS_NFILES",
430  StringifyInt(global_opts.max_open_files));
431  }
432 
433  return options_mgr;
434 }
435 
436 
437 int cvmfs_init(char const *options) {
438  SimpleOptionsParser *options_mgr = cvmfs_options_init_legacy(options);
439  if (options_mgr == NULL) {
440  fprintf(stderr, "Invalid CVMFS global options: %s.\n", options);
441  usage();
442  return LIBCVMFS_FAIL_BADOPT;
443  }
444 
445  const loader::Failures result = LibGlobals::Initialize(options_mgr);
447  if (result != loader::kFailOk)
449  return TranslateReturnValue(result);
450 }
451 
452 
454  const char *legacy_options) {
455  // Parse options
456  repo_options repo_opts;
457  const int parse_result = repo_opts.parse_options(legacy_options);
458  if ((parse_result != 0) || repo_opts.url.empty()) {
459  return NULL;
460  }
461 
462  SimpleOptionsParser *options_mgr = cvmfs_options_clone(opts);
463  options_mgr->SwitchTemplateManager(
464  new DefaultOptionsTemplateManager(repo_opts.repo_name));
465  options_mgr->SetValue("CVMFS_FQRN", repo_opts.repo_name);
466  options_mgr->SetValue("CVMFS_TIMEOUT", StringifyInt(repo_opts.timeout));
467  options_mgr->SetValue("CVMFS_TIMEOUT_DIRECT",
468  StringifyInt(repo_opts.timeout_direct));
469  options_mgr->SetValue("CVMFS_SERVER_URL", repo_opts.url);
470  if (!repo_opts.external_url.empty()) {
471  options_mgr->SetValue("CVMFS_EXTERNAL_URL", repo_opts.external_url);
472  }
473  if (repo_opts.proxies.empty()) {
474  if (!options_mgr->IsDefined("CVMFS_HTTP_PROXY"))
475  options_mgr->SetValue("CVMFS_HTTP_PROXY", "DIRECT");
476  } else {
477  options_mgr->SetValue("CVMFS_HTTP_PROXY", repo_opts.proxies);
478  }
479  options_mgr->SetValue("CVMFS_FALLBACK_PROXY", repo_opts.fallback_proxies);
480  options_mgr->SetValue("CVMFS_PUBLIC_KEY", repo_opts.pubkey);
481  if (!repo_opts.blacklist.empty()) {
482  options_mgr->SetValue("CVMFS_BLACKLIST", repo_opts.blacklist);
483  }
484  if (!repo_opts.root_hash.empty()) {
485  options_mgr->SetValue("CVMFS_ROOT_HASH", repo_opts.root_hash);
486  }
487 
488  return options_mgr;
489 }
490 
491 
492 LibContext *cvmfs_attach_repo(char const *options) {
493  SimpleOptionsParser *options_mgr_base = cvmfs_options_init();
495  options_mgr_base, options);
496  cvmfs_options_fini(options_mgr_base);
497  if (options_mgr == NULL) {
498  fprintf(stderr, "Invalid CVMFS options: %s.\n", options);
499  usage();
500  return NULL;
501  }
502 
503  string repo_name;
504  const bool retval = options_mgr->GetValue("CVMFS_FQRN", &repo_name);
505  assert(retval);
506  LibContext *ctx = LibContext::Create(repo_name, options_mgr);
507  assert(ctx != NULL);
508  if (ctx->mount_point()->boot_status() != loader::kFailOk) {
509  LogCvmfs(kLogCvmfs, kLogDebug, "failed attaching %s, %s (%d)",
510  repo_name.c_str(), ctx->mount_point()->boot_error().c_str(),
511  ctx->mount_point()->boot_status());
512  delete ctx;
513  return NULL;
514  }
515  ctx->set_options_mgr(options_mgr);
516  return ctx;
517 }
static void usage()
struct cvmcache_context * ctx
static LibContext * Create(const std::string &fqrn, OptionsManager *options_mgr)
#define LIBCVMFS_FAIL_MKCACHE
Definition: libcvmfs.h:56
loader::Failures boot_status()
Definition: mountpoint.h:77
cvmfs_context * cvmfs_attach_repo(char const *options)
std::string external_url
cvmfs_option_map * cvmfs_options_clone(cvmfs_option_map *opts)
cvmfs_option_map * cvmfs_options_init()
assert((mem||(size==0))&&"Out Of Memory")
#define CVMFS_OPT(var)
void set_options_mgr(OptionsManager *value)
Definition: libcvmfs_int.h:120
cvmfs_options< cvmfs_global_options > global_options
static void cvmfs_init(void *userdata, struct fuse_conn_info *conn)
Definition: cvmfs.cc:2022
void SwitchTemplateManager(OptionsTemplateManager *opt_templ_mgr_param)
Definition: options.cc:91
#define LIBCVMFS_FAIL_NOFILES
Definition: libcvmfs.h:55
void SetValue(const std::string &key, const std::string &value)
Definition: options.cc:472
int set_option(char const *name, char const *value)
void cvmfs_options_fini(cvmfs_option_map *opts)
static loader::Failures Initialize(OptionsManager *options_mgr)
Definition: libcvmfs_int.cc:96
#define LIBCVMFS_FAIL_OK
Definition: libcvmfs.h:54
int set_option(char const *name, char const *value)
int parse_options(char const *options)
std::string boot_error()
Definition: mountpoint.h:78
#define LIBCVMFS_FAIL_BADOPT
Definition: libcvmfs.h:61
string StringifyInt(const int64_t value)
Definition: string.cc:77
cvmfs_option_map * cvmfs_options_init_legacy(const char *legacy_options)
#define LIBCVMFS_FAIL_INITCACHE
Definition: libcvmfs.h:59
Failures
Definition: loader.h:27
bool GetValue(const std::string &key, std::string *value) const
Definition: options.cc:369
std::string fallback_proxies
static LibGlobals * GetInstance()
Definition: libcvmfs_int.cc:87
cvmfs_options< cvmfs_repo_options > repo_options
MountPoint * mount_point()
Definition: libcvmfs_int.h:119
#define LIBCVMFS_FAIL_LOCKFILE
Definition: libcvmfs.h:58
cvmfs_option_map * cvmfs_options_clone_legacy(cvmfs_option_map *opts, const char *legacy_options)
static int set_option(char const *name, char const *value, bool *var)
#define LIBCVMFS_FAIL_INITQUOTA
Definition: libcvmfs.h:60
bool IsDefined(const std::string &key)
Definition: options.cc:363
int set_option(char const *name, char const *value)
void set_options_mgr(OptionsManager *value)
Definition: libcvmfs_int.h:68
static void CleanupInstance()
static int TranslateReturnValue(loader::Failures code)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:545