11 #include <sys/types.h>
42 char ***buf,
size_t *len);
45 const char *path,
struct cvmfs_attr *stat_result,
bool get_hash);
48 const char *path,
const struct cvmfs_attr *stat_info);
63 const char *path,
const char *identifier);
69 const char *dest,
const struct cvmfs_attr *stat_info);
82 const char *identifier);
88 int posix_do_fread(
void *file_ctx,
char *buff,
size_t len,
size_t *read_len);
105 std::string config_name,
106 std::string prov_name
111 const char *info_file
163 std::string complete_path =
BuildPath(ctx, path);
173 if (res != 0)
return -1;
177 DIR *dr = opendir(complete_path.c_str());
178 while ((de = readdir(dr)) != NULL) {
179 if (strcmp(de->d_name,
".") != 0
180 && strcmp(de->d_name,
"..") != 0) {
181 std::string cur_path = std::string(path) +
"/" + de->d_name;
187 int res = closedir(dr);
189 if (res != 0)
return -1;
205 *buf =
reinterpret_cast<char **
>(smalloc(
sizeof(
char *) * buflen));
207 DIR *dr = opendir(
BuildPath(ctx, dir).c_str());
216 while ((de = readdir(dr)) != NULL) {
217 if (strcmp(de->d_name,
".") != 0
218 && strcmp(de->d_name,
"..") != 0
233 std::string complete_path =
BuildPath(ctx, path);
235 int res = lstat(complete_path.c_str(), &buf);
239 stat_result->
st_dev = buf.st_dev;
240 stat_result->
st_ino = buf.st_ino;
241 stat_result->
st_mode = buf.st_mode;
242 stat_result->
st_nlink = buf.st_nlink;
243 stat_result->
st_uid = buf.st_uid;
244 stat_result->
st_gid = buf.st_gid;
245 stat_result->
st_rdev = buf.st_rdev;
246 stat_result->
st_size = buf.st_size;
247 stat_result->
mtime = buf.st_mtime;
249 if (get_hash && S_ISREG(buf.st_mode)) {
259 if (S_ISLNK(buf.st_mode)) {
260 char slnk[PATH_MAX+1];
261 const ssize_t length =
262 readlink(complete_path.c_str(), slnk, PATH_MAX);
273 stat_result->
cvm_parent = strdup(parent_path.c_str());
274 stat_result->
cvm_name = strdup(file_name.c_str());
277 if (stat_result->
cvm_xattrs == NULL)
return -1;
283 const char *path,
const struct cvmfs_attr *stat_info) {
284 std::string complete_path =
BuildPath(ctx, path);
294 std::string path = (
"/"
297 char *res = strdup(path.c_str());
308 std::string complete_path =
BuildPath(ctx, path);
310 const char *complete_path_char = complete_path.c_str();
312 int res2 = lstat(complete_path_char, &buf);
313 if (res2 == -1 && errno == ENOENT)
return -1;
315 struct utimbuf mtimes;
318 int res1 = unlink(complete_path_char);
319 res1 |= utime(parent_path.c_str(), &mtimes);
320 if (res1 == -1)
return -1;
322 if (S_ISREG(buf.st_mode) && buf.st_nlink == 2) {
332 std::string complete_path =
BuildPath(ctx, path);
334 struct utimbuf mtimes;
336 int res = rmdir(complete_path.c_str());
337 res |= utime(parent_path.c_str(), &mtimes);
338 if (res != 0)
return -1;
344 const char *identifier) {
345 std::string complete_path =
BuildPath(ctx, path);
348 const char *hidden_datapath_char = hidden_datapath.c_str();
354 struct utimbuf mtimes_parent;
355 if (!
BackupMtimes(parent_path, &mtimes_parent))
return -1;
357 struct utimbuf mtimes_link;
358 if (!
BackupMtimes(hidden_datapath, &mtimes_link))
return -1;
365 int res2 = lstat(hidden_datapath_char, &buf);
367 int res1 = link(hidden_datapath_char, complete_path.c_str());
368 res1 |= utime(parent_path.c_str(), &mtimes_parent);
369 res1 |= utime(hidden_datapath.c_str(), &mtimes_link);
372 "Failed to create link : %s->%s : %d : %s\n",
373 hidden_datapath_char, complete_path.c_str(), errno, strerror(errno));
376 if (S_ISREG(buf.st_mode) && buf.st_nlink == 2) {
379 if (pos_ctx->
gc_flagged.count(buf.st_ino) > 0) {
389 std::string complete_path =
BuildPath(ctx, path);
392 struct utimbuf mtimes;
397 int res = mkdir(complete_path.c_str(), stat_info->
st_mode);
398 res |= utime(parent_path.c_str(), &mtimes);
399 if (res != 0)
return -1;
407 std::string complete_src_path =
BuildPath(ctx, src);
409 std::string complete_dest_path = dest;
410 struct utimbuf mtimes;
415 int res = symlink(complete_dest_path.c_str(), complete_src_path.c_str());
416 res |= utime(parent_path.c_str(), &mtimes);
417 if (res != 0)
return -1;
418 return PosixSetMeta(complete_src_path.c_str(), stat_info,
false);
432 int res1 = creat(hidden_datapath.c_str(), stat_info->
st_mode);
433 if (res1 < 0)
return -1;
434 int res2 = close(res1);
435 if (res2 < 0)
return -1;
436 int res3 =
PosixSetMeta(hidden_datapath.c_str(), stat_info);
437 if (res3 < 0)
return -1;
444 std::string complete_path =
BuildPath(ctx,
446 struct stat display_path_stat;
447 int res1 = lstat(complete_path.c_str(), &display_path_stat);
459 struct stat hidden_path_stat;
460 int res2 = stat(hidden_datapath.c_str(), &hidden_path_stat);
465 return display_path_stat.st_ino == hidden_path_stat.st_ino;
469 const char *identifier) {
478 int retval = stat(handle->
path.c_str(), &info);
479 if (retval != 0)
return false;
481 retval = chmod(handle->
path.c_str(), info.st_mode | S_IWUSR | S_IWUSR);
488 const char *mode =
"r";
497 FILE *
fd = fopen(handle->
path.c_str(), mode);
499 if (errno == EACCES) {
501 fd = fopen(handle->
path.c_str(), mode);
519 res |= fclose(handle->
fd);
523 utime(handle->
path.c_str(), &(handle->
mtimes));
526 res = utime(handle->
path.c_str(), &(handle->
mtimes));
527 if (res != 0)
return -1;
534 *read_len = fread(buff,
sizeof(
char), len, handle->
fd);
535 if (*read_len < len && ferror(handle->
fd) != 0) {
536 clearerr(handle->
fd);
545 size_t written_len = fwrite(buff,
sizeof(
char), len, handle->
fd);
546 if (written_len != len) {
547 clearerr(handle->
fd);
556 if (handle->
fd != NULL) {
567 std::string config_name,
568 std::string prov_name
570 FILE *prov = fopen(prov_name.c_str(),
"w");
573 "Archive config: failed to open : %s : %d : %s\n",
574 prov_name.c_str(), errno, strerror(errno));
578 std::vector<std::string> config_files =
SplitString(config_name,
':');
579 for (
unsigned i = 0; i < config_files.size(); ++i) {
580 FILE *config = fopen(config_files[i].c_str(),
"r");
581 if (config == NULL) {
583 "Archive config: failed to open : %s : %d : %s\n",
584 config_name.c_str(), errno, strerror(errno));
593 nbytes = fread(&buffer,
sizeof(
char),
sizeof(buffer), config);
594 if (nbytes <
sizeof(buffer) && ferror(config) != 0) {
596 "Archive config: read failed : %d %s\n", errno, strerror(errno));
602 size_t written_len = fwrite(buffer,
sizeof(
char), nbytes, prov);
603 if (written_len != nbytes) {
605 "Archive config: write failed : %d %s\n",
606 errno, strerror(errno));
622 const char *info_file
624 FILE *f = fopen(info_file,
"w");
626 fwrite(
"repo : ",
sizeof(
char), 7, f);
627 fwrite(ctx->
repo,
sizeof(
char), strlen(ctx->
repo), f);
628 fwrite(
"\nversion : ",
sizeof(
char), 11, f);
630 fwrite(
"\nbase : ",
sizeof(
char), 8, f);
632 fwrite(ctx->
base,
sizeof(
char), strlen(ctx->
base), f);
633 fwrite(
"\ncache : ",
sizeof(
char), 9, f);
635 fwrite(ctx->
data,
sizeof(
char), strlen(ctx->
data), f);
636 fwrite(
"\nconfig : ",
sizeof(
char), 10, f);
638 fwrite(ctx->
config,
sizeof(
char), strlen(ctx->
config), f);
647 std::string prov_dir;
648 prov_dir.append(dest->
base);
649 prov_dir.append(
".provenance/");
650 prov_dir.append(dest->
repo);
651 prov_dir.append(
"/");
654 if (!
MkdirDeep(prov_dir.c_str(), 0755,
true)) {
656 "Failed to create repository directory '%s'", prov_dir.c_str());
660 std::string src_info = prov_dir;
661 src_info.append(
"src.info");
665 std::string src_config = prov_dir +
"src.config";
668 "Failed to archive source config '%s'", src->
config);
672 std::string dest_info = prov_dir;
673 dest_info.append(
"dest.info");
677 std::string dest_config = prov_dir +
"dest.config";
680 "Failed to archive destination config '%s'", dest->
config);
697 result->
ctx = posix_ctx;
701 result->
base = strdup(
"/tmp/cvmfs/");
703 if (base[strlen(base)-1] !=
'/') {
704 size_t len = 2 + strlen(base);
705 char *base_dir =
reinterpret_cast<char *
>(smalloc(len*
sizeof(
char)));
706 snprintf(base_dir, len,
"%s/", base);
707 result->
base = strdup(base_dir);
710 result->
base = strdup(base);
717 "Repository name must be specified");
720 result->
repo = strdup(repo);
724 size_t len = 6 + strlen(result->
base);
725 char *def_data =
reinterpret_cast<char *
>(smalloc(len*
sizeof(
char)));
726 snprintf(def_data, len,
"%s.data", result->
base);
727 result->
data = strdup(def_data);
730 result->
data = strdup(data);
733 if (config && strlen(config) > 0) {
735 "Configuration file is not supported in POSIX interface '%s'", config);
741 std::string req_dirs =
BuildPath(result,
"");
743 if (!
MkdirDeep(req_dirs.c_str(), 0755,
true)) {
745 "Failed to create repository directory '%s'", req_dirs.c_str());
std::map< ino_t, bool > gc_flagged
struct cvmcache_context * ctx
int(* do_fopen)(void *file_ctx, fs_open_type op_mode)
NameString GetFileName(const PathString &path)
int posix_garbage_collector(struct fs_traversal_context *ctx)
int posix_do_fopen(void *file_ctx, fs_open_type op_mode)
int posix_get_stat(struct fs_traversal_context *ctx, const char *path, struct cvmfs_attr *stat_result, bool get_hash)
std::string ToString(const bool with_suffix=false) const
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)
void posix_finalize(struct fs_traversal_context *ctx)
void posix_do_ffree(void *file_ctx)
bool posix_has_file(struct fs_traversal_context *ctx, const char *ident)
struct fs_traversal * posix_get_interface()
int posix_do_rmdir(struct fs_traversal_context *ctx, const char *path)
int posix_cleanup_path(struct fs_traversal_context *ctx, const char *path)
int posix_do_fread(void *file_ctx, char *buff, size_t len, size_t *read_len)
int PosixSetMeta(const char *path, const struct cvmfs_attr *stat_info, bool set_permissions)
void FinalizeFsOperations(struct fs_traversal_context *ctx)
int posix_do_fwrite(void *file_ctx, const char *buff, size_t len)
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)
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
bool posix_archive_config(std::string config_name, std::string prov_name)
bool SymlinkExists(const std::string &path)
void(* do_ffree)(void *file_ctx)
int posix_do_unlink(struct fs_traversal_context *ctx, const char *path)
bool FileExists(const std::string &path)
int posix_do_mkdir(struct fs_traversal_context *ctx, const char *path, const struct cvmfs_attr *stat_info)
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)
bool EnableWriteAccess(posix_file_handle *handle)
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)
int(* do_link)(struct fs_traversal_context *ctx, const char *path, const char *identifier)
int RunGarbageCollection(struct fs_traversal_context *ctx)
const unsigned kDigitsPerDirLevel
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)
void(* archive_provenance)(struct fs_traversal_context *src, struct fs_traversal_context *dest)
std::string BuildPath(struct fs_traversal_context *ctx, const char *dir)
bool MkdirDeep(const std::string &path, const mode_t mode, bool verify_writable)
bool(* has_file)(struct fs_traversal_context *ctx, const char *identifier)
const unsigned kDirLevels
int posix_touch(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat_info)
bool BackupMtimes(std::string path, struct utimbuf *mtimes)
shash::Any HashMeta(const struct cvmfs_attr *stat_info)
void posix_write_provenance_info(struct fs_traversal_context *ctx, const char *info_file)
bool DirectoryExists(const std::string &path)
int posix_do_fclose(void *file_ctx)
std::string BuildHiddenPath(struct fs_traversal_context *ctx, const char *ident)
int(* do_fclose)(void *file_ctx)
int posix_do_link(struct fs_traversal_context *ctx, const char *path, const char *identifier)
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
int(* do_fwrite)(void *file_ctx, const char *buff, size_t len)
PathString GetParentPath(const PathString &path)
void * posix_get_handle(struct fs_traversal_context *ctx, const char *identifier)
int(* do_fread)(void *file_ctx, char *buff, size_t len, size_t *read_len)
Any MkFromHexPtr(const HexPtr hex, const char suffix)
static XattrList * CreateFromFile(const std::string &path)
bool posix_is_hash_consistent(struct fs_traversal_context *ctx, const struct cvmfs_attr *stat_info)
int(* do_mkdir)(struct fs_traversal_context *ctx, const char *path, const struct cvmfs_attr *stat)
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)
int posix_do_symlink(struct fs_traversal_context *ctx, const char *src, const char *dest, const struct cvmfs_attr *stat_info)
struct fs_traversal_context * posix_initialize(const char *repo, const char *base, const char *data, const char *config, int num_threads)
void AppendStringToList(char const *str, char ***buf, size_t *listlen, size_t *buflen)
void posix_archive_provenance(struct fs_traversal_context *src, struct fs_traversal_context *dest)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)