CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
interface.cc
Go to the documentation of this file.
1 
4 #include "interface.h"
5 
6 #include <dirent.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <stdio.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <utime.h>
13 
14 #include <cstring>
15 #include <map>
16 #include <string>
17 #include <vector>
18 
19 #include "crypto/hash.h"
20 #include "garbage_collector.h"
21 #include "helpers.h"
22 #include "libcvmfs.h"
24 #include "shrinkwrap/util.h"
25 #include "util/logging.h"
26 #include "util/posix.h"
27 #include "util/smalloc.h"
28 #include "util/string.h"
29 #include "xattr.h"
30 
32  std::string path;
33  FILE *fd;
34  struct utimbuf mtimes;
36 };
37 
38 /*
39  * BASIC FS OPERATIONS
40  */
41 void posix_list_dir(struct fs_traversal_context *ctx, const char *dir,
42  char ***buf, size_t *len);
43 
44 int posix_get_stat(struct fs_traversal_context *ctx, const char *path,
45  struct cvmfs_attr *stat_result, bool get_hash);
46 
47 int posix_set_meta(struct fs_traversal_context *ctx, const char *path,
48  const struct cvmfs_attr *stat_info);
49 
51  const struct cvmfs_attr *stat);
52 
53 bool posix_has_file(struct fs_traversal_context *ctx, const char *ident);
54 
55 int posix_do_unlink(struct fs_traversal_context *ctx, const char *path);
56 
57 int posix_do_rmdir(struct fs_traversal_context *ctx, const char *path);
58 
59 int posix_do_link(struct fs_traversal_context *ctx, const char *path,
60  const char *identifier);
61 
62 int posix_do_mkdir(struct fs_traversal_context *ctx, const char *path,
63  const struct cvmfs_attr *stat_info);
64 
65 int posix_do_symlink(struct fs_traversal_context *ctx, const char *src,
66  const char *dest, const struct cvmfs_attr *stat_info);
67 
69  const struct cvmfs_attr *stat_info);
70 
72  const struct cvmfs_attr *stat_info);
73 
74 /*
75  * FILE OPERATIONS
76  */
77 
79  const char *identifier);
80 
81 int posix_do_fopen(void *file_ctx, fs_open_type op_mode);
82 
83 int posix_do_fclose(void *file_ctx);
84 
85 int posix_do_fread(void *file_ctx, char *buff, size_t len, size_t *read_len);
86 
87 int posix_do_fwrite(void *file_ctx, const char *buff, size_t len);
88 
89 void posix_do_ffree(void *file_ctx);
90 
91 /*
92  * GARBAGE COLLECTION
93  */
94 
96 
97 
98 /*
99  * ARCHIVE PROVENANCE INFORMATION
100  */
101 bool posix_archive_config(std::string config_name, std::string prov_name);
102 
104  const char *info_file);
105 
107  struct fs_traversal_context *dest);
108 
109 /*
110  * INITIALIZATION
111  */
112 
113 struct fs_traversal_context *posix_initialize(const char *repo,
114  const char *base,
115  const char *data,
116  const char *config,
117  int num_threads);
118 
120 
122  struct fs_traversal *result = new struct fs_traversal;
123  result->initialize = posix_initialize;
124  result->finalize = posix_finalize;
126  result->list_dir = posix_list_dir;
127  result->get_stat = posix_get_stat;
129  result->set_meta = posix_set_meta;
130  result->has_file = posix_has_file;
132  result->do_link = posix_do_link;
133  result->do_unlink = posix_do_unlink;
134  result->do_mkdir = posix_do_mkdir;
135  result->do_rmdir = posix_do_rmdir;
136  result->touch = posix_touch;
137  result->get_handle = posix_get_handle;
138  result->do_symlink = posix_do_symlink;
140 
141  result->do_fopen = posix_do_fopen;
142  result->do_fclose = posix_do_fclose;
143  result->do_fread = posix_do_fread;
144  result->do_fwrite = posix_do_fwrite;
145  result->do_ffree = posix_do_ffree;
146 
147  return result;
148 }
149 
150 // Utility function
151 int posix_cleanup_path(struct fs_traversal_context *ctx, const char *path) {
152  std::string complete_path = BuildPath(ctx, path);
153  std::string dirname = GetParentPath(complete_path);
154  if (!DirectoryExists(dirname)) {
155  // Directory doesn't exist
156  errno = ENOENT;
157  return -1;
158  }
159  if (FileExists(complete_path) || SymlinkExists(complete_path)) {
160  // Unlink file if existing
161  int res = posix_do_unlink(ctx, path);
162  if (res != 0)
163  return -1;
164  }
165  if (DirectoryExists(complete_path)) {
166  struct dirent *de;
167  DIR *dr = opendir(complete_path.c_str());
168  while ((de = readdir(dr)) != NULL) {
169  if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) {
170  std::string cur_path = std::string(path) + "/" + de->d_name;
171  if (posix_cleanup_path(ctx, cur_path.c_str()) != 0) {
172  return -1;
173  }
174  }
175  }
176  int res = closedir(dr);
177  res |= posix_do_rmdir(ctx, path);
178  if (res != 0)
179  return -1;
180  }
181  return 0;
182 }
183 
189  const char *dir,
190  char ***buf,
191  size_t *len) {
192  struct dirent *de;
193  *len = 0;
194  size_t buflen = 5;
195  *buf = reinterpret_cast<char **>(smalloc(sizeof(char *) * buflen));
196 
197  DIR *dr = opendir(BuildPath(ctx, dir).c_str());
198 
199  // NULL terminate the list;
200  AppendStringToList(NULL, buf, len, &buflen);
201 
202  if (dr == NULL) {
203  return;
204  }
205 
206  while ((de = readdir(dr)) != NULL) {
207  if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0
208  && strcmp(de->d_name, WARNING_FILE_NAME) != 0) {
209  AppendStringToList(de->d_name, buf, len, &buflen);
210  }
211  }
212 
213  closedir(dr);
214  return;
215 }
216 
218  const char *path,
219  struct cvmfs_attr *stat_result,
220  bool get_hash) {
221  std::string complete_path = BuildPath(ctx, path);
222  struct stat buf;
223  int res = lstat(complete_path.c_str(), &buf);
224  if (res == -1) {
225  return -1;
226  }
227  stat_result->st_dev = buf.st_dev;
228  stat_result->st_ino = buf.st_ino;
229  stat_result->st_mode = buf.st_mode;
230  stat_result->st_nlink = buf.st_nlink;
231  stat_result->st_uid = buf.st_uid;
232  stat_result->st_gid = buf.st_gid;
233  stat_result->st_rdev = buf.st_rdev;
234  stat_result->st_size = buf.st_size;
235  stat_result->mtime = buf.st_mtime;
236 
237  if (get_hash && S_ISREG(buf.st_mode)) {
238  // We cannot reliably figure out the hash
239  // because we don't know the hash algorithm
240  return -1;
241  } else {
242  // We usually do not calculate the checksum for posix files since it's a
243  // destination file system.
244  stat_result->cvm_checksum = NULL;
245  }
246 
247  if (S_ISLNK(buf.st_mode)) {
248  char slnk[PATH_MAX + 1];
249  const ssize_t length = readlink(complete_path.c_str(), slnk, PATH_MAX);
250  if (length < 0) {
251  return -1;
252  }
253  slnk[length] = '\0';
254  stat_result->cvm_symlink = strdup(slnk);
255  } else {
256  stat_result->cvm_symlink = NULL;
257  }
258  std::string parent_path = GetParentPath(path);
259  std::string file_name = GetFileName(path);
260  stat_result->cvm_parent = strdup(parent_path.c_str());
261  stat_result->cvm_name = strdup(file_name.c_str());
262 
263  stat_result->cvm_xattrs = XattrList::CreateFromFile(complete_path);
264  if (stat_result->cvm_xattrs == NULL)
265  return -1;
266 
267  return 0;
268 }
269 
270 int posix_set_meta(struct fs_traversal_context *ctx, const char *path,
271  const struct cvmfs_attr *stat_info) {
272  std::string complete_path = BuildPath(ctx, path);
273  return PosixSetMeta(complete_path.c_str(), stat_info,
274  !S_ISLNK(stat_info->st_mode));
275 }
276 
278  const struct cvmfs_attr *stat) {
279  shash::Any content_hash = shash::MkFromHexPtr(
280  shash::HexPtr(stat->cvm_checksum));
281  shash::Any meta_hash = HashMeta(stat);
282  std::string path = ("/"
283  + content_hash.MakePathExplicit(kDirLevels,
284  kDigitsPerDirLevel, '.')
285  + meta_hash.ToString());
286  char *res = strdup(path.c_str());
287  return res;
288 }
289 
290 bool posix_has_file(struct fs_traversal_context *ctx, const char *ident) {
291  return FileExists(BuildHiddenPath(ctx, ident));
292 }
293 
294 int posix_do_unlink(struct fs_traversal_context *ctx, const char *path) {
295  std::string complete_path = BuildPath(ctx, path);
296  std::string parent_path = GetParentPath(complete_path);
297  const char *complete_path_char = complete_path.c_str();
298  struct stat buf;
299  int res2 = lstat(complete_path_char, &buf);
300  if (res2 == -1 && errno == ENOENT)
301  return -1;
302  assert(res2 == 0);
303  struct utimbuf mtimes;
304  if (!BackupMtimes(parent_path, &mtimes))
305  return -1;
306  // Unlinking
307  int res1 = unlink(complete_path_char);
308  res1 |= utime(parent_path.c_str(), &mtimes);
309  if (res1 == -1)
310  return -1;
311  // GC Flagging
312  if (S_ISREG(buf.st_mode) && buf.st_nlink == 2) {
314  *pos_ctx = reinterpret_cast<struct fs_traversal_posix_context *>(
315  ctx->ctx);
316  pos_ctx->gc_flagged[buf.st_ino] = true;
317  }
318  return 0;
319 }
320 
321 int posix_do_rmdir(struct fs_traversal_context *ctx, const char *path) {
322  std::string complete_path = BuildPath(ctx, path);
323  std::string parent_path = GetParentPath(complete_path);
324  struct utimbuf mtimes;
325  if (!BackupMtimes(parent_path, &mtimes))
326  return -1;
327  int res = rmdir(complete_path.c_str());
328  res |= utime(parent_path.c_str(), &mtimes);
329  if (res != 0)
330  return -1;
331  return 0;
332 }
333 
335  const char *path,
336  const char *identifier) {
337  std::string complete_path = BuildPath(ctx, path);
338  std::string parent_path = GetParentPath(complete_path);
339  std::string hidden_datapath = BuildHiddenPath(ctx, identifier);
340  const char *hidden_datapath_char = hidden_datapath.c_str();
341  if (!FileExists(hidden_datapath)) {
342  // Hash file doesn't exist
343  errno = ENOENT;
344  return -1;
345  }
346  struct utimbuf mtimes_parent;
347  if (!BackupMtimes(parent_path, &mtimes_parent))
348  return -1;
349 
350  struct utimbuf mtimes_link;
351  if (!BackupMtimes(hidden_datapath, &mtimes_link))
352  return -1;
353 
354  if (posix_cleanup_path(ctx, path) != 0) {
355  return -1;
356  }
357  // GC Unflagging
358  struct stat buf;
359  int res2 = lstat(hidden_datapath_char, &buf);
360  assert(res2 == 0);
361  int res1 = link(hidden_datapath_char, complete_path.c_str());
362  res1 |= utime(parent_path.c_str(), &mtimes_parent);
363  res1 |= utime(hidden_datapath.c_str(), &mtimes_link);
364  if (res1 != 0) {
366  "Failed to create link : %s->%s : %d : %s\n", hidden_datapath_char,
367  complete_path.c_str(), errno, strerror(errno));
368  return -1;
369  }
370  if (S_ISREG(buf.st_mode) && buf.st_nlink == 2) {
372  *pos_ctx = reinterpret_cast<struct fs_traversal_posix_context *>(
373  ctx->ctx);
374  if (pos_ctx->gc_flagged.count(buf.st_ino) > 0) {
375  pos_ctx->gc_flagged[buf.st_ino] = false;
376  }
377  }
378  return 0;
379 }
380 
382  const char *path,
383  const struct cvmfs_attr *stat_info) {
384  std::string complete_path = BuildPath(ctx, path);
385  std::string parent_path = GetParentPath(complete_path);
386  std::string dirname = GetParentPath(complete_path);
387  struct utimbuf mtimes;
388  if (!BackupMtimes(parent_path, &mtimes))
389  return -1;
390  if (posix_cleanup_path(ctx, path) != 0) {
391  return -1;
392  }
393  int res = mkdir(complete_path.c_str(), stat_info->st_mode);
394  res |= utime(parent_path.c_str(), &mtimes);
395  if (res != 0)
396  return -1;
397  return PosixSetMeta(complete_path.c_str(), stat_info);
398 }
399 
401  const char *src,
402  const char *dest,
403  const struct cvmfs_attr *stat_info) {
404  std::string complete_src_path = BuildPath(ctx, src);
405  std::string parent_path = GetParentPath(complete_src_path);
406  std::string complete_dest_path = dest;
407  struct utimbuf mtimes;
408  if (!BackupMtimes(parent_path, &mtimes))
409  return -1;
410  if (posix_cleanup_path(ctx, src) != 0) {
411  return -1;
412  }
413  int res = symlink(complete_dest_path.c_str(), complete_src_path.c_str());
414  res |= utime(parent_path.c_str(), &mtimes);
415  if (res != 0)
416  return -1;
417  return PosixSetMeta(complete_src_path.c_str(), stat_info, false);
418 }
419 
421  const struct cvmfs_attr *stat_info) {
422  // NOTE(steuber): creat is only atomic on non-NFS paths!
423  char *identifier = posix_get_identifier(ctx, stat_info);
424  if (posix_has_file(ctx, identifier)) {
425  free(identifier);
426  errno = EEXIST;
427  return -1;
428  }
429  std::string hidden_datapath = BuildHiddenPath(ctx, identifier);
430  free(identifier);
431  int res1 = creat(hidden_datapath.c_str(), stat_info->st_mode);
432  if (res1 < 0)
433  return -1;
434  int res2 = close(res1);
435  if (res2 < 0)
436  return -1;
437  int res3 = PosixSetMeta(hidden_datapath.c_str(), stat_info);
438  if (res3 < 0)
439  return -1;
440  return 0;
441 }
442 
444  const struct cvmfs_attr *stat_info) {
445  errno = 0;
446  std::string complete_path = BuildPath(
447  ctx,
448  (std::string(stat_info->cvm_parent) + "/" + stat_info->cvm_name).c_str());
449  struct stat display_path_stat;
450  int res1 = lstat(complete_path.c_str(), &display_path_stat);
451  if (res1 == -1) {
452  // If visible path doesn't exist => error
453  return false;
454  }
455  char *identifier = posix_get_identifier(ctx, stat_info);
456  if (!posix_has_file(ctx, identifier)) {
457  free(identifier);
458  return false;
459  }
460  std::string hidden_datapath = BuildHiddenPath(ctx, identifier);
461  free(identifier);
462  struct stat hidden_path_stat;
463  int res2 = stat(hidden_datapath.c_str(), &hidden_path_stat);
464  if (res2 == -1) {
465  // If hidden path doesn't exist although apparently existing => error
466  return false;
467  }
468  return display_path_stat.st_ino == hidden_path_stat.st_ino;
469 }
470 
472  const char *identifier) {
473  struct posix_file_handle *file_ctx = new struct posix_file_handle;
474  file_ctx->path = BuildHiddenPath(ctx, identifier);
475 
476  return file_ctx;
477 }
478 
480  struct stat info;
481  int retval = stat(handle->path.c_str(), &info);
482  if (retval != 0)
483  return false;
484  handle->original_mode = info.st_mode;
485  retval = chmod(handle->path.c_str(), info.st_mode | S_IWUSR | S_IWUSR);
486  return retval == 0;
487 }
488 
489 int posix_do_fopen(void *file_ctx, fs_open_type op_mode) {
490  struct posix_file_handle *handle = reinterpret_cast<posix_file_handle *>(
491  file_ctx);
492  const char *mode = "r";
493  if (op_mode == fs_open_write) {
494  mode = "w";
495  } else if (op_mode == fs_open_append) {
496  mode = "a";
497  }
498  if (!BackupMtimes(handle->path, &(handle->mtimes)))
499  return -1;
500  handle->original_mode = 0;
501 
502  FILE *fd = fopen(handle->path.c_str(), mode);
503  if (fd == NULL) {
504  if (errno == EACCES) {
505  EnableWriteAccess(handle);
506  fd = fopen(handle->path.c_str(), mode);
507  if (fd == NULL)
508  return -1;
509  } else {
510  return -1;
511  }
512  }
513  handle->fd = fd;
514  return 0;
515 }
516 
517 int posix_do_fclose(void *file_ctx) {
518  struct posix_file_handle *handle = reinterpret_cast<posix_file_handle *>(
519  file_ctx);
520  int res = 0;
521  if (handle->original_mode != 0) {
522  res = fchmod(fileno(handle->fd), handle->original_mode);
523  }
524  res |= fclose(handle->fd);
525  handle->fd = NULL;
526  if (res != 0) {
527  // Opportunistic approach to reset time stamp
528  utime(handle->path.c_str(), &(handle->mtimes));
529  return -1;
530  }
531  res = utime(handle->path.c_str(), &(handle->mtimes));
532  if (res != 0)
533  return -1;
534  return 0;
535 }
536 
537 int posix_do_fread(void *file_ctx, char *buff, size_t len, size_t *read_len) {
538  struct posix_file_handle *handle = reinterpret_cast<posix_file_handle *>(
539  file_ctx);
540  *read_len = fread(buff, sizeof(char), len, handle->fd);
541  if (*read_len < len && ferror(handle->fd) != 0) {
542  clearerr(handle->fd);
543  return -1;
544  }
545  return 0;
546 }
547 
548 int posix_do_fwrite(void *file_ctx, const char *buff, size_t len) {
549  struct posix_file_handle *handle = reinterpret_cast<posix_file_handle *>(
550  file_ctx);
551  size_t written_len = fwrite(buff, sizeof(char), len, handle->fd);
552  if (written_len != len) {
553  clearerr(handle->fd);
554  return -1;
555  }
556  return 0;
557 }
558 
559 void posix_do_ffree(void *file_ctx) {
560  struct posix_file_handle *handle = reinterpret_cast<posix_file_handle *>(
561  file_ctx);
562  if (handle->fd != NULL) {
563  posix_do_fclose(file_ctx);
564  }
565  delete handle;
566 }
567 
569  return RunGarbageCollection(ctx);
570 }
571 
572 bool posix_archive_config(std::string config_name, std::string prov_name) {
573  FILE *prov = fopen(prov_name.c_str(), "w");
574  if (prov == NULL) {
576  "Archive config: failed to open : %s : %d : %s\n",
577  prov_name.c_str(), errno, strerror(errno));
578  return false;
579  }
580 
581  std::vector<std::string> config_files = SplitString(config_name, ':');
582  for (unsigned i = 0; i < config_files.size(); ++i) {
583  FILE *config = fopen(config_files[i].c_str(), "r");
584  if (config == NULL) {
586  "Archive config: failed to open : %s : %d : %s\n",
587  config_name.c_str(), errno, strerror(errno));
588  fclose(prov);
589  return false;
590  }
591 
592  while (1) {
593  char buffer[COPY_BUFFER_SIZE];
594 
595  size_t nbytes = 0;
596  nbytes = fread(&buffer, sizeof(char), sizeof(buffer), config);
597  if (nbytes < sizeof(buffer) && ferror(config) != 0) {
598  LogCvmfs(kLogCvmfs, kLogStderr, "Archive config: read failed : %d %s\n",
599  errno, strerror(errno));
600  fclose(config);
601  fclose(prov);
602  return false;
603  }
604 
605  size_t written_len = fwrite(buffer, sizeof(char), nbytes, prov);
606  if (written_len != nbytes) {
608  "Archive config: write failed : %d %s\n", errno,
609  strerror(errno));
610  fclose(config);
611  fclose(prov);
612  return false;
613  }
614 
615  if (nbytes < COPY_BUFFER_SIZE)
616  break;
617  }
618  }
619 
620  return true;
621 }
622 
624  const char *info_file) {
625  FILE *f = fopen(info_file, "w");
626  if (f != NULL) {
627  fwrite("repo : ", sizeof(char), 7, f);
628  fwrite(ctx->repo, sizeof(char), strlen(ctx->repo), f);
629  fwrite("\nversion : ", sizeof(char), 11, f);
630  fwrite(ctx->lib_version, sizeof(char), strlen(ctx->lib_version), f);
631  fwrite("\nbase : ", sizeof(char), 8, f);
632  if (ctx->base)
633  fwrite(ctx->base, sizeof(char), strlen(ctx->base), f);
634  fwrite("\ncache : ", sizeof(char), 9, f);
635  if (ctx->data)
636  fwrite(ctx->data, sizeof(char), strlen(ctx->data), f);
637  fwrite("\nconfig : ", sizeof(char), 10, f);
638  if (ctx->config)
639  fwrite(ctx->config, sizeof(char), strlen(ctx->config), f);
640  fclose(f);
641  }
642 }
643 
645  struct fs_traversal_context *dest) {
646  std::string prov_dir;
647  prov_dir.append(dest->base);
648  prov_dir.append(".provenance/");
649  prov_dir.append(dest->repo);
650  prov_dir.append("/");
651 
652  if (!DirectoryExists(prov_dir.c_str())) {
653  if (!MkdirDeep(prov_dir.c_str(), 0755, true)) {
655  "Failed to create repository directory '%s'", prov_dir.c_str());
656  }
657  }
658 
659  std::string src_info = prov_dir;
660  src_info.append("src.info");
661  posix_write_provenance_info(src, src_info.c_str());
662 
663  if (src->config) {
664  std::string src_config = prov_dir + "src.config";
665  if (!posix_archive_config(src->config, src_config)) {
666  LogCvmfs(kLogCvmfs, kLogStderr, "Failed to archive source config '%s'",
667  src->config);
668  }
669  }
670 
671  std::string dest_info = prov_dir;
672  dest_info.append("dest.info");
673  posix_write_provenance_info(dest, dest_info.c_str());
674 
675  if (dest->config) {
676  std::string dest_config = prov_dir + "dest.config";
677  if (!posix_archive_config(dest->config, dest_config)) {
679  "Failed to archive destination config '%s'", dest->config);
680  }
681  }
682 }
683 
685  const char *base,
686  const char *data,
687  const char *config,
688  int num_threads) {
689  fs_traversal_context *result = new struct fs_traversal_context;
690  result->version = 1;
691  result->lib_version = strdup("1.0");
693  *posix_ctx = new struct fs_traversal_posix_context;
694  posix_ctx->num_threads = num_threads;
695  result->ctx = posix_ctx;
696 
697  // Retrieve base directory for traversal
698  if (!base) {
699  result->base = strdup("/tmp/cvmfs/");
700  } else {
701  if (base[strlen(base) - 1] != '/') {
702  size_t len = 2 + strlen(base);
703  char *base_dir = reinterpret_cast<char *>(smalloc(len * sizeof(char)));
704  snprintf(base_dir, len, "%s/", base);
705  result->base = strdup(base_dir);
706  free(base_dir);
707  } else {
708  result->base = strdup(base);
709  }
710  }
711 
712  // Retrieve repository (inside base directory) for traversal
713  if (!repo) {
714  LogCvmfs(kLogCvmfs, kLogStderr, "Repository name must be specified");
715  return NULL;
716  }
717  result->repo = strdup(repo);
718 
719  // Retrieve data directory (for hidden dedup directory)
720  if (!data) {
721  size_t len = 6 + strlen(result->base);
722  char *def_data = reinterpret_cast<char *>(smalloc(len * sizeof(char)));
723  snprintf(def_data, len, "%s.data", result->base);
724  result->data = strdup(def_data);
725  free(def_data);
726  } else {
727  result->data = strdup(data);
728  }
729 
730  if (config && strlen(config) > 0) {
732  "Configuration file is not supported in POSIX interface '%s'",
733  config);
734  return NULL;
735  }
736  result->config = NULL;
737 
738  // Build directory if not there yet
739  std::string req_dirs = BuildPath(result, "");
740  if (!DirectoryExists(req_dirs.c_str())) {
741  if (!MkdirDeep(req_dirs.c_str(), 0755, true)) {
743  "Failed to create repository directory '%s'", req_dirs.c_str());
744  return NULL;
745  }
746  }
747 
748  // Initializes Data Directory, Garbage Collection and Warning file
749  InitialFsOperations(result);
750  return result;
751 }
752 
755  free(ctx->repo);
756  free(ctx->base);
757  free(ctx->data);
758  free(ctx->config);
759  free(ctx->lib_version);
761  *posix_ctx = reinterpret_cast<struct fs_traversal_posix_context *>(
762  ctx->ctx);
763  delete posix_ctx;
764  delete ctx;
765 }
nlink_t st_nlink
Definition: libcvmfs.h:159
std::map< ino_t, bool > gc_flagged
Definition: helpers.h:26
char * cvm_symlink
Definition: libcvmfs.h:172
struct cvmcache_context * ctx
char * cvm_name
Definition: libcvmfs.h:174
int(* do_fopen)(void *file_ctx, fs_open_type op_mode)
NameString GetFileName(const PathString &path)
Definition: shortstring.cc:28
int posix_garbage_collector(struct fs_traversal_context *ctx)
Definition: interface.cc:568
int posix_do_fopen(void *file_ctx, fs_open_type op_mode)
Definition: interface.cc:489
int posix_get_stat(struct fs_traversal_context *ctx, const char *path, struct cvmfs_attr *stat_result, bool get_hash)
Definition: interface.cc:217
std::string ToString(const bool with_suffix=false) const
Definition: hash.h:241
int(* set_meta)(struct fs_traversal_context *ctx, const char *path, const struct cvmfs_attr *stat)
bool(* is_hash_consistent)(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat)
void InitialFsOperations(struct fs_traversal_context *ctx)
Definition: helpers.cc:39
void posix_finalize(struct fs_traversal_context *ctx)
Definition: interface.cc:753
void posix_do_ffree(void *file_ctx)
Definition: interface.cc:559
bool posix_has_file(struct fs_traversal_context *ctx, const char *ident)
Definition: interface.cc:290
dev_t st_dev
Definition: libcvmfs.h:156
struct fs_traversal * posix_get_interface()
Definition: interface.cc:121
int posix_do_rmdir(struct fs_traversal_context *ctx, const char *path)
Definition: interface.cc:321
int posix_cleanup_path(struct fs_traversal_context *ctx, const char *path)
Definition: interface.cc:151
int posix_do_fread(void *file_ctx, char *buff, size_t len, size_t *read_len)
Definition: interface.cc:537
int PosixSetMeta(const char *path, const struct cvmfs_attr *stat_info, bool set_permissions)
Definition: helpers.cc:78
void FinalizeFsOperations(struct fs_traversal_context *ctx)
Definition: helpers.cc:45
int posix_do_fwrite(void *file_ctx, const char *buff, size_t len)
Definition: interface.cc:548
assert((mem||(size==0))&&"Out Of Memory")
int posix_set_meta(struct fs_traversal_context *ctx, const char *path, const struct cvmfs_attr *stat_info)
Definition: interface.cc:270
char * cvm_parent
Definition: libcvmfs.h:173
int(* do_unlink)(struct fs_traversal_context *ctx, const char *path)
int(* garbage_collector)(struct fs_traversal_context *ctx)
int(* do_rmdir)(struct fs_traversal_context *ctx, const char *path)
void *(* get_handle)(struct fs_traversal_context *ctx, const char *identifier)
#define WARNING_FILE_NAME
Definition: helpers.h:15
bool posix_archive_config(std::string config_name, std::string prov_name)
Definition: interface.cc:572
char * cvm_checksum
Definition: libcvmfs.h:171
bool SymlinkExists(const std::string &path)
Definition: posix.cc:833
void(* do_ffree)(void *file_ctx)
int posix_do_unlink(struct fs_traversal_context *ctx, const char *path)
Definition: interface.cc:294
bool FileExists(const std::string &path)
Definition: posix.cc:803
int posix_do_mkdir(struct fs_traversal_context *ctx, const char *path, const struct cvmfs_attr *stat_info)
Definition: interface.cc:381
int(* touch)(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat)
void posix_list_dir(struct fs_traversal_context *ctx, const char *dir, char ***buf, size_t *len)
Definition: interface.cc:188
void * cvm_xattrs
Definition: libcvmfs.h:175
bool EnableWriteAccess(posix_file_handle *handle)
Definition: interface.cc:479
int(* do_symlink)(struct fs_traversal_context *ctx, const char *src, const char *dest, const struct cvmfs_attr *stat_info)
void(* finalize)(struct fs_traversal_context *ctx)
vector< string > SplitString(const string &str, char delim)
Definition: string.cc:306
int(* do_link)(struct fs_traversal_context *ctx, const char *path, const char *identifier)
int RunGarbageCollection(struct fs_traversal_context *ctx)
const unsigned kDigitsPerDirLevel
Definition: helpers.h:22
struct fs_traversal_context *(* initialize)(const char *repo, const char *base, const char *data, const char *config, int num_threads)
time_t mtime
Definition: libcvmfs.h:164
gid_t st_gid
Definition: libcvmfs.h:161
void(* list_dir)(struct fs_traversal_context *ctx, const char *dir, char ***buf, size_t *len)
void(* archive_provenance)(struct fs_traversal_context *src, struct fs_traversal_context *dest)
std::string BuildPath(struct fs_traversal_context *ctx, const char *dir)
Definition: helpers.cc:61
off_t st_size
Definition: libcvmfs.h:163
bool MkdirDeep(const std::string &path, const mode_t mode, bool verify_writable)
Definition: posix.cc:855
bool(* has_file)(struct fs_traversal_context *ctx, const char *identifier)
const unsigned kDirLevels
Definition: helpers.h:21
std::string path
Definition: interface.cc:32
#define COPY_BUFFER_SIZE
int posix_touch(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat_info)
Definition: interface.cc:420
bool BackupMtimes(std::string path, struct utimbuf *mtimes)
Definition: helpers.cc:116
shash::Any HashMeta(const struct cvmfs_attr *stat_info)
Definition: util.cc:16
void posix_write_provenance_info(struct fs_traversal_context *ctx, const char *info_file)
Definition: interface.cc:623
bool DirectoryExists(const std::string &path)
Definition: posix.cc:824
int posix_do_fclose(void *file_ctx)
Definition: interface.cc:517
std::string BuildHiddenPath(struct fs_traversal_context *ctx, const char *ident)
Definition: helpers.cc:71
int(* do_fclose)(void *file_ctx)
int posix_do_link(struct fs_traversal_context *ctx, const char *path, const char *identifier)
Definition: interface.cc:334
int(* get_stat)(struct fs_traversal_context *ctx, const char *path, struct cvmfs_attr *stat, bool get_hash)
std::string MakePathExplicit(const unsigned dir_levels, const unsigned digits_per_level, const Suffix hash_suffix=kSuffixNone) const
Definition: hash.h:339
int(* do_fwrite)(void *file_ctx, const char *buff, size_t len)
ino_t st_ino
Definition: libcvmfs.h:157
PathString GetParentPath(const PathString &path)
Definition: shortstring.cc:14
void * posix_get_handle(struct fs_traversal_context *ctx, const char *identifier)
Definition: interface.cc:471
int(* do_fread)(void *file_ctx, char *buff, size_t len, size_t *read_len)
Any MkFromHexPtr(const HexPtr hex, const char suffix)
Definition: hash.cc:82
static XattrList * CreateFromFile(const std::string &path)
Definition: xattr.cc:32
uid_t st_uid
Definition: libcvmfs.h:160
bool posix_is_hash_consistent(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat_info)
Definition: interface.cc:443
int(* do_mkdir)(struct fs_traversal_context *ctx, const char *path, const struct cvmfs_attr *stat)
dev_t st_rdev
Definition: libcvmfs.h:162
char *(* get_identifier)(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat)
char * posix_get_identifier(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat)
Definition: interface.cc:277
int posix_do_symlink(struct fs_traversal_context *ctx, const char *src, const char *dest, const struct cvmfs_attr *stat_info)
Definition: interface.cc:400
struct utimbuf mtimes
Definition: interface.cc:34
struct fs_traversal_context * posix_initialize(const char *repo, const char *base, const char *data, const char *config, int num_threads)
Definition: interface.cc:684
void AppendStringToList(char const *str, char ***buf, size_t *listlen, size_t *buflen)
Definition: util.cc:61
void posix_archive_provenance(struct fs_traversal_context *src, struct fs_traversal_context *dest)
Definition: interface.cc:644
mode_t st_mode
Definition: libcvmfs.h:158
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:545