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