CernVM-FS  2.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fuse_main.cc
Go to the documentation of this file.
1 
10 #include <dlfcn.h>
11 #include <unistd.h>
12 
13 #include <cassert>
14 #include <cstdlib>
15 #include <cstring>
16 #include <string>
17 #include <vector>
18 
19 #include "fuse_main.h"
20 #include "logging.h"
21 #include "platform.h"
22 #include "smalloc.h"
23 #include "util/string.h"
24 
25 using namespace stub; // NOLINT
26 
27 
28 int main(int argc, char **argv) {
29  // Getopt option parsing modifies globals and the argv vector
30  int opterr_save = opterr;
31  int optc = argc;
32  assert(optc > 0);
33  char **optv = reinterpret_cast<char **>(smalloc(optc * sizeof(char *)));
34  for (int i = 0; i < optc; ++i) {
35  optv[i] = strdup(argv[i]);
36  }
37 
38  bool debug = false;
39  unsigned enforce_libfuse = 0;
40  int c;
41  opterr = 0;
42  while ((c = getopt(optc, optv, "do:")) != -1) {
43  switch (c) {
44  case 'd':
45  debug = true;
46  break;
47  case 'o':
48  std::vector<std::string> mount_options = SplitString(optarg, ',');
49  for (unsigned i = 0; i < mount_options.size(); ++i) {
50  if (mount_options[i] == "debug") {
51  debug = true;
52  }
53 
54  if (HasPrefix(mount_options[i], "libfuse=", false /*ign_case*/)) {
55  std::vector<std::string> t = SplitString(mount_options[i], '=');
56  enforce_libfuse = String2Uint64(t[1]);
57  if (debug) {
59  "Debug: enforcing libfuse version %u", enforce_libfuse);
60  }
61  }
62  }
63  break;
64  }
65  }
66  opterr = opterr_save;
67  optind = 1;
68  for (int i = 0; i < optc; ++i) {
69  free(optv[i]);
70  }
71  free(optv);
72 
73  std::string libname_fuse2 = platform_libname("cvmfs_fuse_stub");
74  std::string libname_fuse3 = platform_libname("cvmfs_fuse3_stub");
75 
76  std::string error_messages;
77 
78  if (enforce_libfuse > 0) {
79  if ((enforce_libfuse < 2) || (enforce_libfuse > 3)) {
81  "Error: invalid libfuse version '%u', valid values are 2 or 3.",
82  enforce_libfuse);
83  return 1;
84  }
85  }
86 
87  std::string local_lib_path = "./";
88  if (getenv("CVMFS_LIBRARY_PATH") != NULL) {
89  local_lib_path = getenv("CVMFS_LIBRARY_PATH");
90  if (!local_lib_path.empty() && (*local_lib_path.rbegin() != '/'))
91  local_lib_path.push_back('/');
92  }
93 
94  // Try loading libfuse3 module, else fallback to version 2
95  std::vector<std::string> library_paths;
96  if ((enforce_libfuse == 0) || (enforce_libfuse == 3)) {
97  library_paths.push_back(local_lib_path + libname_fuse3);
98  library_paths.push_back("/usr/lib/" + libname_fuse3);
99  library_paths.push_back("/usr/lib64/" + libname_fuse3);
100 #ifdef __APPLE__
101  library_paths.push_back("/usr/local/lib/" + libname_fuse3);
102 #endif
103  }
104  if ((enforce_libfuse == 0) || (enforce_libfuse == 2)) {
105  library_paths.push_back(local_lib_path + libname_fuse2);
106  library_paths.push_back("/usr/lib/" + libname_fuse2);
107  library_paths.push_back("/usr/lib64/" + libname_fuse2);
108 #ifdef __APPLE__
109  library_paths.push_back("/usr/local/lib/" + libname_fuse2);
110 #endif
111  }
112 
113  void *library_handle;
114  std::vector<std::string>::const_iterator i = library_paths.begin();
115  std::vector<std::string>::const_iterator iend = library_paths.end();
116  for (; i != iend; ++i) {
117  library_handle = dlopen(i->c_str(), RTLD_NOW | RTLD_LOCAL);
118  if (library_handle != NULL) {
119  if (debug) {
120  LogCvmfs(kLogCvmfs, kLogDebug | kLogStdout, "Debug: using library %s",
121  i->c_str());
122  }
123  break;
124  }
125 
126  error_messages += std::string(dlerror()) + "\n";
127  }
128 
129  if (!library_handle) {
131  "Error: failed to load cvmfs library, tried: '%s'\n%s",
132  JoinStrings(library_paths, "' '").c_str(), error_messages.c_str());
133  return 1;
134  }
135 
136  CvmfsStubExports **exports_ptr = reinterpret_cast<CvmfsStubExports **>(
137  dlsym(library_handle, "g_cvmfs_stub_exports"));
138  if (exports_ptr == NULL) {
140  "Error: symbol g_cvmfs_stub_exports not found");
141  return 1;
142  }
143 
144  return (*exports_ptr)->fn_main(argc, argv);
145 }
146 
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
vector< string > SplitString(const string &str, const char delim, const unsigned max_chunks)
Definition: string.cc:287
string JoinStrings(const vector< string > &strings, const string &joint)
Definition: string.cc:317
assert((mem||(size==0))&&"Out Of Memory")
int main()
Definition: helper_allow.cc:16
std::string platform_libname(const std::string &base_name)
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
Definition: string.cc:264
uint64_t String2Uint64(const string &value)
Definition: string.cc:227