11 #include <sys/types.h>
42 char ***buf,
size_t *len);
45 struct cvmfs_attr *stat_result,
bool get_hash);
60 const char *identifier);
66 const char *dest,
const struct cvmfs_attr *stat_info);
79 const char *identifier);
85 int posix_do_fread(
void *file_ctx,
char *buff,
size_t len,
size_t *read_len);
104 const char *info_file);
152 std::string complete_path =
BuildPath(ctx, path);
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;
176 int res = closedir(dr);
195 *buf =
reinterpret_cast<char **
>(smalloc(
sizeof(
char *) * buflen));
197 DIR *dr = opendir(
BuildPath(ctx, dir).c_str());
206 while ((de = readdir(dr)) != NULL) {
207 if (strcmp(de->d_name,
".") != 0 && strcmp(de->d_name,
"..") != 0
221 std::string complete_path =
BuildPath(ctx, path);
223 int res = lstat(complete_path.c_str(), &buf);
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;
237 if (get_hash && S_ISREG(buf.st_mode)) {
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);
260 stat_result->
cvm_parent = strdup(parent_path.c_str());
261 stat_result->
cvm_name = strdup(file_name.c_str());
272 std::string complete_path =
BuildPath(ctx, path);
282 std::string path = (
"/"
286 char *res = strdup(path.c_str());
295 std::string complete_path =
BuildPath(ctx, path);
297 const char *complete_path_char = complete_path.c_str();
299 int res2 = lstat(complete_path_char, &buf);
300 if (res2 == -1 && errno == ENOENT)
303 struct utimbuf mtimes;
307 int res1 = unlink(complete_path_char);
308 res1 |= utime(parent_path.c_str(), &mtimes);
312 if (S_ISREG(buf.st_mode) && buf.st_nlink == 2) {
322 std::string complete_path =
BuildPath(ctx, path);
324 struct utimbuf mtimes;
327 int res = rmdir(complete_path.c_str());
328 res |= utime(parent_path.c_str(), &mtimes);
336 const char *identifier) {
337 std::string complete_path =
BuildPath(ctx, path);
340 const char *hidden_datapath_char = hidden_datapath.c_str();
346 struct utimbuf mtimes_parent;
350 struct utimbuf mtimes_link;
359 int res2 = lstat(hidden_datapath_char, &buf);
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);
366 "Failed to create link : %s->%s : %d : %s\n", hidden_datapath_char,
367 complete_path.c_str(), errno, strerror(errno));
370 if (S_ISREG(buf.st_mode) && buf.st_nlink == 2) {
374 if (pos_ctx->
gc_flagged.count(buf.st_ino) > 0) {
384 std::string complete_path =
BuildPath(ctx, path);
387 struct utimbuf mtimes;
393 int res = mkdir(complete_path.c_str(), stat_info->
st_mode);
394 res |= utime(parent_path.c_str(), &mtimes);
404 std::string complete_src_path =
BuildPath(ctx, src);
406 std::string complete_dest_path = dest;
407 struct utimbuf mtimes;
413 int res = symlink(complete_dest_path.c_str(), complete_src_path.c_str());
414 res |= utime(parent_path.c_str(), &mtimes);
417 return PosixSetMeta(complete_src_path.c_str(), stat_info,
false);
431 int res1 = creat(hidden_datapath.c_str(), stat_info->
st_mode);
434 int res2 = close(res1);
437 int res3 =
PosixSetMeta(hidden_datapath.c_str(), stat_info);
449 struct stat display_path_stat;
450 int res1 = lstat(complete_path.c_str(), &display_path_stat);
462 struct stat hidden_path_stat;
463 int res2 = stat(hidden_datapath.c_str(), &hidden_path_stat);
468 return display_path_stat.st_ino == hidden_path_stat.st_ino;
472 const char *identifier) {
481 int retval = stat(handle->
path.c_str(), &info);
485 retval = chmod(handle->
path.c_str(), info.st_mode | S_IWUSR | S_IWUSR);
492 const char *mode =
"r";
502 FILE *
fd = fopen(handle->
path.c_str(), mode);
504 if (errno == EACCES) {
506 fd = fopen(handle->
path.c_str(), mode);
524 res |= fclose(handle->
fd);
528 utime(handle->
path.c_str(), &(handle->
mtimes));
531 res = utime(handle->
path.c_str(), &(handle->
mtimes));
540 *read_len = fread(buff,
sizeof(
char), len, handle->
fd);
541 if (*read_len < len && ferror(handle->
fd) != 0) {
542 clearerr(handle->
fd);
551 size_t written_len = fwrite(buff,
sizeof(
char), len, handle->
fd);
552 if (written_len != len) {
553 clearerr(handle->
fd);
562 if (handle->
fd != NULL) {
573 FILE *prov = fopen(prov_name.c_str(),
"w");
576 "Archive config: failed to open : %s : %d : %s\n",
577 prov_name.c_str(), errno, strerror(errno));
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));
596 nbytes = fread(&buffer,
sizeof(
char),
sizeof(buffer), config);
597 if (nbytes <
sizeof(buffer) && ferror(config) != 0) {
599 errno, strerror(errno));
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,
624 const char *info_file) {
625 FILE *f = fopen(info_file,
"w");
627 fwrite(
"repo : ",
sizeof(
char), 7, f);
628 fwrite(ctx->
repo,
sizeof(
char), strlen(ctx->
repo), f);
629 fwrite(
"\nversion : ",
sizeof(
char), 11, f);
631 fwrite(
"\nbase : ",
sizeof(
char), 8, f);
633 fwrite(ctx->
base,
sizeof(
char), strlen(ctx->
base), f);
634 fwrite(
"\ncache : ",
sizeof(
char), 9, f);
636 fwrite(ctx->
data,
sizeof(
char), strlen(ctx->
data), f);
637 fwrite(
"\nconfig : ",
sizeof(
char), 10, f);
639 fwrite(ctx->
config,
sizeof(
char), strlen(ctx->
config), f);
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(
"/");
653 if (!
MkdirDeep(prov_dir.c_str(), 0755,
true)) {
655 "Failed to create repository directory '%s'", prov_dir.c_str());
659 std::string src_info = prov_dir;
660 src_info.append(
"src.info");
664 std::string src_config = prov_dir +
"src.config";
671 std::string dest_info = prov_dir;
672 dest_info.append(
"dest.info");
676 std::string dest_config = prov_dir +
"dest.config";
679 "Failed to archive destination config '%s'", dest->
config);
695 result->
ctx = posix_ctx;
699 result->
base = strdup(
"/tmp/cvmfs/");
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);
708 result->
base = strdup(base);
717 result->
repo = strdup(repo);
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);
727 result->
data = strdup(data);
730 if (config && strlen(config) > 0) {
732 "Configuration file is not supported in POSIX interface '%s'",
739 std::string req_dirs =
BuildPath(result,
"");
741 if (!
MkdirDeep(req_dirs.c_str(), 0755,
true)) {
743 "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,...)