CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
fs_traversal_libcvmfs.cc
Go to the documentation of this file.
1 
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 #include <cstring>
11 #include <string>
12 #include <vector>
13 
14 #include "fs_traversal_interface.h"
15 #include "libcvmfs.h"
16 #include "util/logging.h"
17 #include "util/smalloc.h"
18 #include "util/string.h"
19 
20 #define MAX_INTEGER_DIGITS 20
21 
22 
23 void libcvmfs_sw_log(const char *msg) { printf("(libcvmfs) %s\n", msg); }
24 
25 
27  const char *dir,
28  char ***buf,
29  size_t *len) {
30  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
31  size_t buf_len = 0;
32  struct cvmfs_nc_attr *nc_attr = cvmfs_nc_attr_init();
33  cvmfs_stat_nc(context, dir, nc_attr);
34  cvmfs_nc_attr_free(nc_attr);
35  cvmfs_listdir_contents(context, dir, buf, len, &buf_len);
36  return;
37 }
38 
39 
41  const char *path,
42  struct cvmfs_attr *stat_result,
43  bool get_hash) {
44  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
45  return cvmfs_stat_attr(context, path, stat_result);
46 }
47 
48 
50  const struct cvmfs_attr *stat) {
51  int length = 2 + strlen(stat->cvm_parent) + strlen(stat->cvm_name);
52  char *res = reinterpret_cast<char *>(smalloc(length));
53  snprintf(res, length, "%s/%s", stat->cvm_parent, stat->cvm_name);
54  return res;
55 }
56 
57 
58 bool libcvmfs_has_file(struct fs_traversal_context *ctx, const char *ident) {
59  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
60  struct cvmfs_attr *attr = cvmfs_attr_init();
61  int retval = cvmfs_stat_attr(context, ident, attr);
62  cvmfs_attr_free(attr);
63  return retval;
64 }
65 
66 
68  char *path;
69  int fd;
70  off_t off;
72 };
73 
74 
76  const char *identifier) {
78  *file_ctx = reinterpret_cast<libcvmfs_file_handle *>(
79  calloc(1, sizeof(*file_ctx)));
80  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
81  file_ctx->ctx = context;
82  file_ctx->path = strdup(identifier);
83 
84  return file_ctx;
85 }
86 
87 
88 int libcvmfs_do_fopen(void *file_ctx, fs_open_type op_mode) {
90  *handle = reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
91  handle->fd = cvmfs_open(handle->ctx, handle->path);
92  if (handle->fd == -1) {
93  return -1;
94  }
95  return 0;
96 }
97 
98 
99 int libcvmfs_do_fclose(void *file_ctx) {
100  struct libcvmfs_file_handle
101  *handle = reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
102  int res = cvmfs_close(handle->ctx, handle->fd);
103  if (res != 0)
104  return -1;
105  handle->fd = -1;
106  return 0;
107 }
108 
109 
110 int libcvmfs_do_fread(void *file_ctx,
111  char *buff,
112  size_t len,
113  size_t *read_len) {
114  struct libcvmfs_file_handle
115  *handle = reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
116  ssize_t read = cvmfs_pread(handle->ctx, handle->fd, buff, len, handle->off);
117  if (read == -1) {
118  return -1;
119  }
120  *read_len = read;
121  handle->off += *read_len;
122  return 0;
123 }
124 
125 
126 int libcvmfs_do_fwrite(void *file_ctx, const char *buff, size_t len) {
127  return -1;
128 }
129 
130 
131 void libcvmfs_do_ffree(void *file_ctx) {
132  struct libcvmfs_file_handle
133  *handle = reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
134  if (handle->fd > 0) {
135  libcvmfs_do_fclose(file_ctx);
136  }
137  free(handle->path);
138  free(handle);
139 }
140 
141 
143  const char *base,
144  const char *data,
145  const char *config,
146  int num_threads) {
147  if (!repo) {
148  LogCvmfs(kLogCvmfs, kLogStderr, "Repository name must be specified");
149  return NULL;
150  }
151  int retval = 0;
152 
153  struct fs_traversal_context *result = new struct fs_traversal_context;
154  result->version = 1;
155  char *major = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
156  snprintf(major, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_VERSION_MAJOR);
157  char *minor = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
158  snprintf(minor, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_VERSION_MINOR);
159  char *rev = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
160  snprintf(rev, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_REVISION);
161  size_t len = 3 + strlen(major) + strlen(minor) + strlen(rev);
162  char *lib_version = reinterpret_cast<char *>(smalloc(len));
163  snprintf(lib_version, len, "%s.%s:%s", major, minor, rev);
164 
165  result->lib_version = strdup(lib_version);
166 
167  free(major);
168  free(minor);
169  free(rev);
170  free(lib_version);
171 
172  result->size = sizeof(*result);
173  result->repo = strdup(repo);
174  result->base = NULL;
175  result->data = NULL;
176  result->config = NULL;
177 
178  // Make cvmfs options part of the environment
179  cvmfs_option_map *options_mgr = cvmfs_options_init_v2(1);
180  if (config) {
181  result->config = strdup(config);
182  } else {
183  size_t len = 8 + strlen(result->repo);
184  char *def_config = reinterpret_cast<char *>(smalloc(len * sizeof(char)));
185  snprintf(def_config, len, "%s.config", result->repo);
186  result->config = strdup(def_config);
187  free(def_config);
188  }
189  std::vector<std::string> config_files = SplitString(result->config, ':');
190  for (unsigned i = 0; i < config_files.size(); ++i) {
191  retval = cvmfs_options_parse(options_mgr, config_files[i].c_str());
192  if (retval) {
193  LogCvmfs(kLogCvmfs, kLogStderr, "CVMFS Options failed to parse from : %s",
194  config_files[i].c_str());
195  return NULL;
196  }
197  }
198 
199  // Override repository name even if specified
200  cvmfs_options_set(options_mgr, "CVMFS_REPOSITORY_NAME", repo);
201 
202  // Override Mount dir if not specified in configuration
203  if (base && !cvmfs_options_get(options_mgr, "CVMFS_MOUNT_DIR")) {
204  cvmfs_options_set(options_mgr, "CVMFS_MOUNT_DIR", base);
205  }
206 
207  // Override Cache base if not specified in configuration
208  if (data
209  && (!cvmfs_options_get(options_mgr, "CVMFS_CACHE_BASE")
210  && !cvmfs_options_get(options_mgr, "CVMFS_CACHE_DIR"))) {
211  cvmfs_options_set(options_mgr, "CVMFS_CACHE_BASE", data);
212  result->data = strdup(data);
213  }
214 
215  retval = cvmfs_init_v2(options_mgr);
216  if (retval) {
217  LogCvmfs(kLogCvmfs, kLogStderr, "CVMFS Initialization failed : %s", repo);
218  return NULL;
219  }
220 
222 
224  retval = cvmfs_attach_repo_v2(repo, options_mgr, &ctx);
225  if (retval) {
226  LogCvmfs(kLogCvmfs, kLogStderr, "CVMFS Attach to %s failed", repo);
227  return NULL;
228  }
230  result->ctx = ctx;
231  cvmfs_adopt_options(ctx, options_mgr);
232  return result;
233 }
234 
235 
237  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
238  cvmfs_detach_repo(context);
239  cvmfs_fini();
240  free(ctx->repo);
241  free(ctx->base);
242  free(ctx->data);
243  free(ctx->config);
244  free(ctx->lib_version);
245  delete ctx;
246 }
247 
248 
250  struct fs_traversal *result = new struct fs_traversal;
252  result->finalize = libcvmfs_finalize;
253  result->list_dir = libcvmfs_list_dir;
254  result->get_stat = libcvmfs_get_stat;
255  result->has_file = libcvmfs_has_file;
258 
259  result->do_fopen = libcvmfs_do_fopen;
260  result->do_fclose = libcvmfs_do_fclose;
261  result->do_fread = libcvmfs_do_fread;
262  result->do_fwrite = libcvmfs_do_fwrite;
263  result->do_ffree = libcvmfs_do_ffree;
264 
265  return result;
266 }
int cvmfs_options_parse(cvmfs_option_map *opts, const char *path)
int libcvmfs_get_stat(struct fs_traversal_context *ctx, const char *path, struct cvmfs_attr *stat_result, bool get_hash)
struct cvmcache_context * ctx
void cvmfs_detach_repo(LibContext *ctx)
Definition: libcvmfs.cc:477
char * cvm_name
Definition: libcvmfs.h:174
int(* do_fopen)(void *file_ctx, fs_open_type op_mode)
int cvmfs_listdir_contents(LibContext *ctx, const char *path, char ***buf, size_t *listlen, size_t *buflen)
Definition: libcvmfs.cc:354
bool libcvmfs_has_file(struct fs_traversal_context *ctx, const char *ident)
#define MAX_INTEGER_DIGITS
void cvmfs_fini()
Definition: libcvmfs.cc:492
void cvmfs_attr_free(struct cvmfs_attr *attr)
Definition: libcvmfs.cc:52
struct cvmfs_nc_attr * cvmfs_nc_attr_init()
Definition: libcvmfs.cc:64
cvmfs_errors cvmfs_init_v2(SimpleOptionsParser *opts)
Definition: libcvmfs.cc:480
int cvmfs_stat_attr(LibContext *ctx, const char *path, struct cvmfs_attr *attr)
Definition: libcvmfs.cc:313
struct fs_traversal * libcvmfs_get_interface()
int cvmfs_stat_nc(LibContext *ctx, const char *path, struct cvmfs_nc_attr *nc_attr)
Definition: libcvmfs.cc:397
char * cvm_parent
Definition: libcvmfs.h:173
void libcvmfs_sw_log(const char *msg)
void libcvmfs_finalize(struct fs_traversal_context *ctx)
int libcvmfs_do_fclose(void *file_ctx)
void cvmfs_options_set(cvmfs_option_map *opts, const char *key, const char *value)
void *(* get_handle)(struct fs_traversal_context *ctx, const char *identifier)
void(* do_ffree)(void *file_ctx)
#define LIBCVMFS_VERSION_MAJOR
Definition: libcvmfs.h:19
int libcvmfs_do_fread(void *file_ctx, char *buff, size_t len, size_t *read_len)
int libcvmfs_do_fopen(void *file_ctx, fs_open_type op_mode)
struct fs_traversal_context * libcvmfs_initialize(const char *repo, const char *base, const char *data, const char *config, int num_threads)
void cvmfs_enable_threaded(LibContext *ctx)
Definition: libcvmfs.cc:452
void libcvmfs_do_ffree(void *file_ctx)
#define LIBCVMFS_REVISION
Definition: libcvmfs.h:47
void(* finalize)(struct fs_traversal_context *ctx)
vector< string > SplitString(const string &str, char delim)
Definition: string.cc:306
#define LIBCVMFS_VERSION_MINOR
Definition: libcvmfs.h:20
cvmfs_errors cvmfs_attach_repo_v2(const char *fqrn, SimpleOptionsParser *opts, LibContext **ctx)
Definition: libcvmfs.cc:454
struct fs_traversal_context *(* initialize)(const char *repo, const char *base, const char *data, const char *config, int num_threads)
void(* list_dir)(struct fs_traversal_context *ctx, const char *dir, char ***buf, size_t *len)
char * cvmfs_options_get(cvmfs_option_map *opts, const char *key)
static void cvmfs_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
Definition: cvmfs.cc:1112
bool(* has_file)(struct fs_traversal_context *ctx, const char *identifier)
void cvmfs_nc_attr_free(struct cvmfs_nc_attr *nc_attr)
Definition: libcvmfs.cc:70
cvmfs_option_map * cvmfs_options_init_v2(int taint_environ)
int(* do_fclose)(void *file_ctx)
char * libcvmfs_get_identifier(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat)
int(* get_stat)(struct fs_traversal_context *ctx, const char *path, struct cvmfs_attr *stat, bool get_hash)
int(* do_fwrite)(void *file_ctx, const char *buff, size_t len)
ssize_t cvmfs_pread(LibContext *ctx, int fd, void *buf, size_t size, off_t off)
Definition: libcvmfs.cc:238
int libcvmfs_do_fwrite(void *file_ctx, const char *buff, size_t len)
int(* do_fread)(void *file_ctx, char *buff, size_t len, size_t *read_len)
int cvmfs_close(LibContext *ctx, int fd)
Definition: libcvmfs.cc:249
void * libcvmfs_get_handle(struct fs_traversal_context *ctx, const char *identifier)
char *(* get_identifier)(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat)
struct cvmfs_attr * cvmfs_attr_init()
Definition: libcvmfs.cc:39
void cvmfs_set_log_fn(void(*log_fn)(const char *msg))
Definition: libcvmfs.cc:507
void cvmfs_adopt_options(cvmfs_context *ctx, SimpleOptionsParser *opts)
Definition: libcvmfs.cc:472
void libcvmfs_list_dir(struct fs_traversal_context *ctx, const char *dir, char ***buf, size_t *len)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:545