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  const 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  const 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  const 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  const ssize_t read =
117  cvmfs_pread(handle->ctx, handle->fd, buff, len, handle->off);
118  if (read == -1) {
119  return -1;
120  }
121  *read_len = read;
122  handle->off += *read_len;
123  return 0;
124 }
125 
126 
127 int libcvmfs_do_fwrite(void *file_ctx, const char *buff, size_t len) {
128  return -1;
129 }
130 
131 
132 void libcvmfs_do_ffree(void *file_ctx) {
133  struct libcvmfs_file_handle
134  *handle = reinterpret_cast<libcvmfs_file_handle *>(file_ctx);
135  if (handle->fd > 0) {
136  libcvmfs_do_fclose(file_ctx);
137  }
138  free(handle->path);
139  free(handle);
140 }
141 
142 
144  const char *base,
145  const char *data,
146  const char *config,
147  int num_threads) {
148  if (!repo) {
149  LogCvmfs(kLogCvmfs, kLogStderr, "Repository name must be specified");
150  return NULL;
151  }
152  int retval = 0;
153 
154  struct fs_traversal_context *result = new struct fs_traversal_context;
155  result->version = 1;
156  char *major = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
157  snprintf(major, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_VERSION_MAJOR);
158  char *minor = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
159  snprintf(minor, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_VERSION_MINOR);
160  char *rev = reinterpret_cast<char *>(smalloc(MAX_INTEGER_DIGITS));
161  snprintf(rev, MAX_INTEGER_DIGITS, "%d", LIBCVMFS_REVISION);
162  const size_t len = 3 + strlen(major) + strlen(minor) + strlen(rev);
163  char *lib_version = reinterpret_cast<char *>(smalloc(len));
164  snprintf(lib_version, len, "%s.%s:%s", major, minor, rev);
165 
166  result->lib_version = strdup(lib_version);
167 
168  free(major);
169  free(minor);
170  free(rev);
171  free(lib_version);
172 
173  result->size = sizeof(*result);
174  result->repo = strdup(repo);
175  result->base = NULL;
176  result->data = NULL;
177  result->config = NULL;
178 
179  // Make cvmfs options part of the environment
180  cvmfs_option_map *options_mgr = cvmfs_options_init_v2(1);
181  if (config) {
182  result->config = strdup(config);
183  } else {
184  const size_t len = 8 + strlen(result->repo);
185  char *def_config = reinterpret_cast<char *>(smalloc(len * sizeof(char)));
186  snprintf(def_config, len, "%s.config", result->repo);
187  result->config = strdup(def_config);
188  free(def_config);
189  }
190  std::vector<std::string> config_files = SplitString(result->config, ':');
191  for (unsigned i = 0; i < config_files.size(); ++i) {
192  retval = cvmfs_options_parse(options_mgr, config_files[i].c_str());
193  if (retval) {
194  LogCvmfs(kLogCvmfs, kLogStderr, "CVMFS Options failed to parse from : %s",
195  config_files[i].c_str());
196  return NULL;
197  }
198  }
199 
200  // Override repository name even if specified
201  cvmfs_options_set(options_mgr, "CVMFS_REPOSITORY_NAME", repo);
202 
203  // Override Mount dir if not specified in configuration
204  if (base && !cvmfs_options_get(options_mgr, "CVMFS_MOUNT_DIR")) {
205  cvmfs_options_set(options_mgr, "CVMFS_MOUNT_DIR", base);
206  }
207 
208  // Override Cache base if not specified in configuration
209  if (data
210  && (!cvmfs_options_get(options_mgr, "CVMFS_CACHE_BASE")
211  && !cvmfs_options_get(options_mgr, "CVMFS_CACHE_DIR"))) {
212  cvmfs_options_set(options_mgr, "CVMFS_CACHE_BASE", data);
213  result->data = strdup(data);
214  }
215 
216  retval = cvmfs_init_v2(options_mgr);
217  if (retval) {
218  LogCvmfs(kLogCvmfs, kLogStderr, "CVMFS Initialization failed : %s", repo);
219  return NULL;
220  }
221 
223 
225  retval = cvmfs_attach_repo_v2(repo, options_mgr, &ctx);
226  if (retval) {
227  LogCvmfs(kLogCvmfs, kLogStderr, "CVMFS Attach to %s failed", repo);
228  return NULL;
229  }
231  result->ctx = ctx;
232  cvmfs_adopt_options(ctx, options_mgr);
233  return result;
234 }
235 
236 
238  cvmfs_context *context = reinterpret_cast<cvmfs_context *>(ctx->ctx);
239  cvmfs_detach_repo(context);
240  cvmfs_fini();
241  free(ctx->repo);
242  free(ctx->base);
243  free(ctx->data);
244  free(ctx->config);
245  free(ctx->lib_version);
246  delete ctx;
247 }
248 
249 
251  struct fs_traversal *result = new struct fs_traversal;
253  result->finalize = libcvmfs_finalize;
254  result->list_dir = libcvmfs_list_dir;
255  result->get_stat = libcvmfs_get_stat;
256  result->has_file = libcvmfs_has_file;
259 
260  result->do_fopen = libcvmfs_do_fopen;
261  result->do_fclose = libcvmfs_do_fclose;
262  result->do_fread = libcvmfs_do_fread;
263  result->do_fwrite = libcvmfs_do_fwrite;
264  result->do_ffree = libcvmfs_do_ffree;
265 
266  return result;
267 }
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:1118
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