CernVM-FS  2.9.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 
5 #include <stdio.h>
6 #include <stdlib.h>
7 
8 #include <cstring>
9 #include <string>
10 #include <vector>
11 
12 #include "fs_traversal_interface.h"
13 #include "fs_traversal_libcvmfs.h"
14 #include "libcvmfs.h"
15 #include "logging.h"
16 #include "smalloc.h"
17 #include "util/string.h"
18 
19 #define MAX_INTEGER_DIGITS 20
20 
21 
22 void libcvmfs_sw_log(const char *msg) {
23  printf("(libcvmfs) %s\n", msg);
24 }
25 
26 
28  const char *dir,
29  char ***buf,
30  size_t *len)
31 {
32  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
33  size_t buf_len = 0;
34  struct cvmfs_nc_attr *nc_attr = cvmfs_nc_attr_init();
35  cvmfs_stat_nc(context, dir, nc_attr);
36  cvmfs_nc_attr_free(nc_attr);
37  cvmfs_listdir_contents(context, dir, buf, len, &buf_len);
38  return;
39 }
40 
41 
43  const char *path,
44  struct cvmfs_attr *stat_result,
45  bool get_hash)
46 {
47  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
48  return cvmfs_stat_attr(context, path, stat_result);
49 }
50 
51 
53  struct fs_traversal_context *ctx,
54  const struct cvmfs_attr *stat)
55 {
56  int length = 2 + strlen(stat->cvm_parent) + strlen(stat->cvm_name);
57  char* res = reinterpret_cast<char *>(smalloc(length));
58  snprintf(res, length, "%s/%s", stat->cvm_parent, stat->cvm_name);
59  return res;
60 }
61 
62 
63 bool libcvmfs_has_file(struct fs_traversal_context *ctx, const char *ident) {
64  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
65  struct cvmfs_attr *attr = cvmfs_attr_init();
66  int retval = cvmfs_stat_attr(context, ident, attr);
67  cvmfs_attr_free(attr);
68  return retval;
69 }
70 
71 
73  char *path;
74  int fd;
75  off_t off;
77 };
78 
79 
81  struct fs_traversal_context *ctx,
82  const char *identifier)
83 {
84  struct libcvmfs_file_handle *file_ctx =
85  reinterpret_cast<libcvmfs_file_handle *>(calloc(1, sizeof(*file_ctx)));
86  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
87  file_ctx->ctx = context;
88  file_ctx->path = strdup(identifier);
89 
90  return file_ctx;
91 }
92 
93 
94 int libcvmfs_do_fopen(void *file_ctx, fs_open_type op_mode) {
95  struct libcvmfs_file_handle *handle =
96  reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
97  handle->fd = cvmfs_open(handle->ctx, handle->path);
98  if (handle->fd == -1) {
99  return -1;
100  }
101  return 0;
102 }
103 
104 
105 int libcvmfs_do_fclose(void *file_ctx) {
106  struct libcvmfs_file_handle *handle =
107  reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
108  int res = cvmfs_close(handle->ctx, handle->fd);
109  if (res != 0) return -1;
110  handle->fd = -1;
111  return 0;
112 }
113 
114 
116  void *file_ctx,
117  char *buff,
118  size_t len,
119  size_t *read_len
120 ) {
121  struct libcvmfs_file_handle *handle =
122  reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
123  ssize_t read = cvmfs_pread(handle->ctx, handle->fd, buff, len, handle->off);
124  if (read == -1) {
125  return -1;
126  }
127  *read_len = read;
128  handle->off += *read_len;
129  return 0;
130 }
131 
132 
133 int libcvmfs_do_fwrite(void *file_ctx, const char *buff, size_t len) {
134  return -1;
135 }
136 
137 
138 void libcvmfs_do_ffree(void *file_ctx) {
139  struct libcvmfs_file_handle *handle =
140  reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
141  if (handle->fd > 0) {
142  libcvmfs_do_fclose(file_ctx);
143  }
144  free(handle->path);
145  free(handle);
146 }
147 
148 
150  const char *repo,
151  const char *base,
152  const char *data,
153  const char *config,
154  int num_threads)
155 {
156  if (!repo) {
158  "Repository name must be specified");
159  return NULL;
160  }
161  int retval = 0;
162 
163  struct fs_traversal_context *result = new struct fs_traversal_context;
164  result->version = 1;
165  char* major = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
166  snprintf(major, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_VERSION_MAJOR);
167  char* minor = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
168  snprintf(minor, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_VERSION_MINOR);
169  char* rev = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
170  snprintf(rev, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_REVISION);
171  size_t len = 3 + strlen(major) + strlen(minor) + strlen(rev);
172  char* lib_version = reinterpret_cast<char *>(smalloc(len));
173  snprintf(lib_version, len, "%s.%s:%s", major, minor, rev);
174 
175  result->lib_version = strdup(lib_version);
176 
177  free(major);
178  free(minor);
179  free(rev);
180  free(lib_version);
181 
182  result->size = sizeof(*result);
183  result->repo = strdup(repo);
184  result->base = NULL;
185  result->data = NULL;
186  result->config = NULL;
187 
188  // Make cvmfs options part of the environment
189  cvmfs_option_map *options_mgr = cvmfs_options_init_v2(1);
190  if (config) {
191  result->config = strdup(config);
192  } else {
193  size_t len = 8 + strlen(result->repo);
194  char *def_config = reinterpret_cast<char *>(smalloc(len*sizeof(char)));
195  snprintf(def_config, len, "%s.config", result->repo);
196  result->config = strdup(def_config);
197  free(def_config);
198  }
199  std::vector<std::string> config_files = SplitString(result->config, ':');
200  for (unsigned i = 0; i < config_files.size(); ++i) {
201  retval = cvmfs_options_parse(options_mgr, config_files[i].c_str());
202  if (retval) {
204  "CVMFS Options failed to parse from : %s", config_files[i].c_str());
205  return NULL;
206  }
207  }
208 
209  // Override repository name even if specified
210  cvmfs_options_set(options_mgr, "CVMFS_REPOSITORY_NAME", repo);
211 
212  // Override Mount dir if not specified in configuration
213  if (base && !cvmfs_options_get(options_mgr, "CVMFS_MOUNT_DIR")) {
214  cvmfs_options_set(options_mgr, "CVMFS_MOUNT_DIR", base);
215  }
216 
217  // Override Cache base if not specified in configuration
218  if (data && (!cvmfs_options_get(options_mgr, "CVMFS_CACHE_BASE") &&
219  !cvmfs_options_get(options_mgr, "CVMFS_CACHE_DIR"))) {
220  cvmfs_options_set(options_mgr, "CVMFS_CACHE_BASE", data);
221  result->data = strdup(data);
222  }
223 
224  retval = cvmfs_init_v2(options_mgr);
225  if (retval) {
227  "CVMFS Initilization failed : %s", repo);
228  return NULL;
229  }
230 
232 
234  retval = cvmfs_attach_repo_v2(repo, options_mgr, &ctx);
235  if (retval) {
237  "CVMFS Attach to %s failed", repo);
238  return NULL;
239  }
241  result->ctx = ctx;
242  cvmfs_adopt_options(ctx, options_mgr);
243  return result;
244 }
245 
246 
248  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
249  cvmfs_detach_repo(context);
250  cvmfs_fini();
251  free(ctx->repo);
252  free(ctx->base);
253  free(ctx->data);
254  free(ctx->config);
255  free(ctx->lib_version);
256  delete ctx;
257 }
258 
259 
261  struct fs_traversal *result = new struct fs_traversal;
263  result->finalize = libcvmfs_finalize;
264  result->list_dir = libcvmfs_list_dir;
265  result->get_stat = libcvmfs_get_stat;
266  result->has_file = libcvmfs_has_file;
269 
270  result->do_fopen = libcvmfs_do_fopen;
271  result->do_fclose = libcvmfs_do_fclose;
272  result->do_fread = libcvmfs_do_fread;
273  result->do_fwrite = libcvmfs_do_fwrite;
274  result->do_ffree = libcvmfs_do_ffree;
275 
276  return result;
277 }
int cvmfs_options_parse(cvmfs_option_map *opts, const char *path)
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
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:514
char * cvm_name
Definition: libcvmfs.h:172
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:376
bool libcvmfs_has_file(struct fs_traversal_context *ctx, const char *ident)
#define MAX_INTEGER_DIGITS
void cvmfs_fini()
Definition: libcvmfs.cc:531
vector< string > SplitString(const string &str, const char delim, const unsigned max_chunks)
Definition: string.cc:288
void cvmfs_attr_free(struct cvmfs_attr *attr)
Definition: libcvmfs.cc:53
struct cvmfs_nc_attr * cvmfs_nc_attr_init()
Definition: libcvmfs.cc:66
cvmfs_errors cvmfs_init_v2(SimpleOptionsParser *opts)
Definition: libcvmfs.cc:519
int cvmfs_stat_attr(LibContext *ctx, const char *path, struct cvmfs_attr *attr)
Definition: libcvmfs.cc:331
struct fs_traversal * libcvmfs_get_interface()
int cvmfs_stat_nc(LibContext *ctx, const char *path, struct cvmfs_nc_attr *nc_attr)
Definition: libcvmfs.cc:424
char * cvm_parent
Definition: libcvmfs.h:171
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:483
void libcvmfs_do_ffree(void *file_ctx)
#define LIBCVMFS_REVISION
Definition: libcvmfs.h:45
void(* finalize)(struct fs_traversal_context *ctx)
#define LIBCVMFS_VERSION_MINOR
Definition: libcvmfs.h:20
cvmfs_errors cvmfs_attach_repo_v2(const char *fqrn, SimpleOptionsParser *opts, LibContext **ctx)
Definition: libcvmfs.cc:489
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:863
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:73
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:245
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:261
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:550
void cvmfs_adopt_options(cvmfs_context *ctx, SimpleOptionsParser *opts)
Definition: libcvmfs.cc:509
void libcvmfs_list_dir(struct fs_traversal_context *ctx, const char *dir, char ***buf, size_t *len)