Loading ifs/include/preload/preload.hpp +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ margo_instance_id ld_margo_id(); hg_addr_t daemon_addr(); void init_passthrough_if_needed(); void init_preload(void) __attribute__((constructor)); Loading ifs/src/preload/CMakeLists.txt +1 −1 Original line number Diff line number Diff line Loading @@ -15,4 +15,4 @@ set(SOURCE_FILES_PRELOAD preload.cpp open_file_map.cpp ../../include/preload/pre add_library(iointer SHARED ${SOURCE_FILES_PRELOAD}) target_link_libraries(iointer dl ${BMI_LIBRARIES} ${MERCURY_LIBRARIES} ${MERCURY_UTIL_LIBRARIES} ${ABT_LIBRARIES} ${ABT_SNOOZER_LIBRARIES} ${MARGO_LIBRARIES} -lboost_system) No newline at end of file -lpthread -lboost_system) No newline at end of file ifs/src/preload/preload.cpp +143 −87 Original line number Diff line number Diff line Loading @@ -12,6 +12,8 @@ #include <sys/stat.h> #include "../../main.hpp" static pthread_once_t init_lib_thread = PTHREAD_ONCE_INIT; // Mercury Client hg_class_t* mercury_hg_class_; hg_context_t* mercury_hg_context_; Loading @@ -25,7 +27,7 @@ static hg_id_t ipc_stat_id; static hg_id_t ipc_unlink_id; // misc bool is_lib_initialized = false; static std::atomic<bool> is_env_initialized(false); // external variables FILE* debug_fd; Loading @@ -36,9 +38,11 @@ void* libc; void* libc_open; //void* libc_open64; //unused void* libc_fopen; void* libc_fopen; // XXX Does not work with streaming pointers. If used will block forever void* libc_fopen64; // XXX Does not work with streaming pointers. If used will block forever //void* libc_creat; //unused //void* libc_creat64; //unused void* libc_unlink; void* libc_close; Loading Loading @@ -75,8 +79,9 @@ void* libc_dup2; static OpenFileMap file_map{}; int ld_open(const char* path, int flags, ...) { DAEMON_DEBUG(debug_fd, "ld_open called with path %s\n", path); int open(const char* path, int flags, ...) { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "open called with path %s\n", path); mode_t mode; if (flags & O_CREAT) { va_list vl; Loading @@ -84,9 +89,8 @@ int ld_open(const char* path, int flags, ...) { mode = va_arg(vl, int); va_end(vl); } if (is_fs_path(path)) { if (is_env_initialized && is_fs_path(path)) { auto fd = file_map.add(path, (flags & O_APPEND) != 0); // TODO call daemon and return if successful return the above fd. if unsuccessful delete fd remove file from map #ifndef MARGOIPC #else Loading @@ -103,8 +107,9 @@ int ld_open(const char* path, int flags, ...) { return (reinterpret_cast<decltype(&open)>(libc_open))(path, flags, mode); } int ld_open64(__const char* path, int flags, ...) { DAEMON_DEBUG(debug_fd, "ld_open64 called with path %s\n", path); int open64(__const char* path, int flags, ...) { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "open64 called with path %s\n", path); mode_t mode; if (flags & O_CREAT) { va_list ap; Loading @@ -112,22 +117,42 @@ int ld_open64(__const char* path, int flags, ...) { mode = va_arg(ap, mode_t); va_end(ap); } return ld_open(path, flags | O_LARGEFILE, mode); return open(path, flags | O_LARGEFILE, mode); } FILE* ld_fopen(const char* path, const char* mode) { // DAEMON_DEBUG(debug_fd, "ld_fopen called with path %s with mode %d\n", path, mode); return (reinterpret_cast<decltype(&fopen)>(libc_fopen))(path, mode); } //// TODO This function somehow always blocks forever if one puts anything between the paththru... //FILE* fopen(const char* path, const char* mode) { //// init_passthrough_if_needed(); //// DAEMON_DEBUG(debug_fd, "fopen called with path %s\n", path); // return (reinterpret_cast<decltype(&fopen)>(libc_fopen))(path, mode); //} //// TODO This function somehow always blocks forever if one puts anything between the paththru... //FILE* fopen64(const char* path, const char* mode) { //// init_passthrough_if_needed(); //// DAEMON_DEBUG(debug_fd, "fopen64 called with path %s\n", path); // return (reinterpret_cast<decltype(&fopen)>(libc_fopen))(path, mode); //} #undef creat int creat(const char* path, mode_t mode) { DAEMON_DEBUG(debug_fd, "ld_creat called with path %s with mode %d\n", path, mode); return ld_open(path, O_CREAT | O_WRONLY | O_TRUNC, mode); init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "creat called with path %s with mode %d\n", path, mode); return open(path, O_CREAT | O_WRONLY | O_TRUNC, mode); } #undef creat64 int creat64(const char* path, mode_t mode) { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "creat64 called with path %s with mode %d\n", path, mode); return open(path, O_CREAT | O_WRONLY | O_TRUNC | O_LARGEFILE, mode); } int unlink(const char* path) __THROW { // DAEMON_DEBUG(debug_fd, "ld_unlink called with path %s\n", path); if (is_fs_path(path)) { init_passthrough_if_needed(); // DAEMON_DEBUG(debug_fd, "unlink called with path %s\n", path); if (is_env_initialized && is_fs_path(path)) { #ifndef MARGOIPC #else return ipc_send_unlink(path, ipc_unlink_id); Loading @@ -136,8 +161,9 @@ int unlink(const char* path) __THROW { return (reinterpret_cast<decltype(&unlink)>(libc_unlink))(path); } int ld_close(int fd) { if (file_map.exist(fd)) { int close(int fd) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // Currently no call to the daemon is required file_map.remove(fd); return 0; Loading @@ -145,14 +171,15 @@ int ld_close(int fd) { return (reinterpret_cast<decltype(&close)>(libc_close))(fd); } int ld___close(int fd) { return ld_close(fd); int __close(int fd) { return close(fd); } int ld_stat(const char* path, struct stat* buf) __THROW { int stat(const char* path, struct stat* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "stat called with path %s\n", path); if (is_fs_path(path)) { if (is_env_initialized && is_fs_path(path)) { // TODO call daemon and return #ifndef MARGOIPC Loading @@ -164,9 +191,10 @@ int ld_stat(const char* path, struct stat* buf) __THROW { return (reinterpret_cast<decltype(&stat)>(libc_stat))(path, buf); } int ld_fstat(int fd, struct stat* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld_fstat called with fd %d\n", fd); if (file_map.exist(fd)) { int fstat(int fd, struct stat* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "fstat called with fd %d\n", fd); if (is_env_initialized && file_map.exist(fd)) { auto path = file_map.get(fd)->path(); // TODO use this to send to the daemon (call directly) // TODO call daemon and return #ifndef MARGOIPC Loading @@ -179,9 +207,10 @@ int ld_fstat(int fd, struct stat* buf) __THROW { return (reinterpret_cast<decltype(&fstat)>(libc_fstat))(fd, buf); } int ld___xstat(int ver, const char* path, struct stat* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld___xstat called with path %s\n", path); if (is_fs_path(path)) { int __xstat(int ver, const char* path, struct stat* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "__xstat called with path %s\n", path); if (is_env_initialized && is_fs_path(path)) { // TODO call stat #ifndef MARGOIPC Loading @@ -192,18 +221,20 @@ int ld___xstat(int ver, const char* path, struct stat* buf) __THROW { return (reinterpret_cast<decltype(&__xstat)>(libc___xstat))(ver, path, buf); } int ld___xstat64(int ver, const char* path, struct stat64* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld___xstat64 called with path %s\n", path); // if (is_fs_path(path)) { // // Not implemented // return -1; // } int __xstat64(int ver, const char* path, struct stat64* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "__xstat64 called with path %s\n", path); if (is_env_initialized && is_fs_path(path)) { // Not implemented return -1; } return (reinterpret_cast<decltype(&__xstat64)>(libc___xstat64))(ver, path, buf); } int ld___fxstat(int ver, int fd, struct stat* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld___fxstat called with fd %d\n", fd); if (file_map.exist(fd)) { int __fxstat(int ver, int fd, struct stat* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "__fxstat called with fd %d\n", fd); if (is_env_initialized && file_map.exist(fd)) { // TODO call fstat auto path = file_map.get(fd)->path(); #ifndef MARGOIPC Loading @@ -215,9 +246,10 @@ int ld___fxstat(int ver, int fd, struct stat* buf) __THROW { return (reinterpret_cast<decltype(&__fxstat)>(libc___fxstat))(ver, fd, buf); } int ld___fxstat64(int ver, int fd, struct stat64* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld___fxstat64 called with fd %d\n", fd); if (file_map.exist(fd)) { int __fxstat64(int ver, int fd, struct stat64* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "__fxstat64 called with fd %d\n", fd); if (is_env_initialized && file_map.exist(fd)) { // TODO call fstat64 // auto path = file_map.get(fd)->path(); #ifndef MARGOIPC Loading @@ -229,24 +261,27 @@ int ld___fxstat64(int ver, int fd, struct stat64* buf) __THROW { return (reinterpret_cast<decltype(&__fxstat64)>(libc___fxstat64))(ver, fd, buf); } extern int ld___lxstat(int ver, const char* path, struct stat* buf) __THROW { if (is_fs_path(path)) { extern int __lxstat(int ver, const char* path, struct stat* buf) __THROW { init_passthrough_if_needed(); if (is_env_initialized && is_fs_path(path)) { // Not implemented return -1; } return (reinterpret_cast<decltype(&__lxstat)>(libc___lxstat))(ver, path, buf); } extern int ld___lxstat64(int ver, const char* path, struct stat64* buf) __THROW { if (is_fs_path(path)) { extern int __lxstat64(int ver, const char* path, struct stat64* buf) __THROW { init_passthrough_if_needed(); if (is_env_initialized && is_fs_path(path)) { // Not implemented return -1; } return (reinterpret_cast<decltype(&__lxstat64)>(libc___lxstat64))(ver, path, buf); } int ld_access(const char* path, int mode) __THROW { if (is_fs_path(path)) { int access(const char* path, int mode) __THROW { init_passthrough_if_needed(); if (is_env_initialized && is_fs_path(path)) { #ifndef MARGOIPC #else Loading @@ -256,12 +291,13 @@ int ld_access(const char* path, int mode) __THROW { return (reinterpret_cast<decltype(&access)>(libc_access))(path, mode); } int ld_puts(const char* str) { int puts(const char* str) { return (reinterpret_cast<decltype(&puts)>(libc_puts))(str); } ssize_t ld_write(int fd, const void* buf, size_t count) { if (file_map.exist(fd)) { ssize_t write(int fd, const void* buf, size_t count) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto adafs_fd = file_map.get(fd); // auto path = adafs_fd->path(); // TODO use this to send to the daemon (call directly) // auto append_flag = adafs_fd->append_flag(); Loading @@ -276,8 +312,9 @@ ssize_t ld_write(int fd, const void* buf, size_t count) { return (reinterpret_cast<decltype(&write)>(libc_write))(fd, buf, count); } ssize_t ld_pwrite(int fd, const void* buf, size_t count, off_t offset) { if (file_map.exist(fd)) { ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto adafs_fd = file_map.get(fd); // auto path = adafs_fd->path(); // TODO use this to send to the daemon (call directly) // auto append_flag = adafs_fd->append_flag(); Loading @@ -292,8 +329,9 @@ ssize_t ld_pwrite(int fd, const void* buf, size_t count, off_t offset) { return (reinterpret_cast<decltype(&pwrite)>(libc_pwrite))(fd, buf, count, offset); } ssize_t ld_read(int fd, void* buf, size_t count) { if (file_map.exist(fd)) { ssize_t read(int fd, void* buf, size_t count) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto path = file_map.get(fd)->path(); // TODO use this to send to the daemon (call directly) // TODO call daemon and return size read #ifndef MARGOIPC Loading @@ -306,8 +344,9 @@ ssize_t ld_read(int fd, void* buf, size_t count) { return (reinterpret_cast<decltype(&read)>(libc_read))(fd, buf, count); } ssize_t ld_pread(int fd, void* buf, size_t count, off_t offset) { if (file_map.exist(fd)) { ssize_t pread(int fd, void* buf, size_t count, off_t offset) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto path = file_map.get(fd)->path(); // TODO use this to send to the daemon (call directly) // TODO call daemon and return size written #ifndef MARGOIPC Loading @@ -320,8 +359,9 @@ ssize_t ld_pread(int fd, void* buf, size_t count, off_t offset) { return (reinterpret_cast<decltype(&pread)>(libc_pread))(fd, buf, count, offset); } ssize_t ld_pread64(int fd, void* buf, size_t nbyte, __off64_t offset) { if (file_map.exist(fd)) { ssize_t pread64(int fd, void* buf, size_t nbyte, __off64_t offset) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto path = file_map.get(fd)->path(); // TODO use this to send to the daemon (call directly) // TODO call daemon and return size written #ifndef MARGOIPC Loading @@ -334,32 +374,38 @@ ssize_t ld_pread64(int fd, void* buf, size_t nbyte, __off64_t offset) { return (reinterpret_cast<decltype(&pread64)>(libc_pread64))(fd, buf, nbyte, offset); } off_t ld_lseek(int fd, off_t offset, int whence) __THROW { off_t lseek(int fd, off_t offset, int whence) __THROW { init_passthrough_if_needed(); return (reinterpret_cast<decltype(&lseek)>(libc_lseek))(fd, offset, whence); } off_t ld_lseek64(int fd, off_t offset, int whence) __THROW { return ld_lseek(fd, offset, whence); off_t lseek64(int fd, off_t offset, int whence) __THROW { init_passthrough_if_needed(); return lseek(fd, offset, whence); } int ld_truncate(const char* path, off_t length) __THROW { int truncate(const char* path, off_t length) __THROW { init_passthrough_if_needed(); return (reinterpret_cast<decltype(&truncate)>(libc_truncate))(path, length); } int ld_ftruncate(int fd, off_t length) __THROW { int ftruncate(int fd, off_t length) __THROW { init_passthrough_if_needed(); return (reinterpret_cast<decltype(&ftruncate)>(libc_ftruncate))(fd, length); } int ld_dup(int oldfd) __THROW { if (file_map.exist(oldfd)) { int dup(int oldfd) __THROW { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(oldfd)) { // Not implemented return -1; } return (reinterpret_cast<decltype(&dup)>(libc_dup))(oldfd); } int ld_dup2(int oldfd, int newfd) __THROW { if (file_map.exist(oldfd) || file_map.exist(newfd)) { int dup2(int oldfd, int newfd) __THROW { init_passthrough_if_needed(); if (is_env_initialized && (file_map.exist(oldfd) || file_map.exist(newfd))) { // Not implemented return -1; } Loading Loading @@ -474,16 +520,27 @@ hg_addr_t daemon_addr() { } /** * Called initially when preload library is used with the LD_PRELOAD environment variable * This function is only called in the preload constructor */ void init_preload(void) { void init_environment() { #ifdef MARGOIPC // init margo client for IPC auto err = init_ld_argobots(); assert(err); err = init_ipc_client(); assert(err); err = ipc_send_get_fs_config(ipc_config_id); // get fs configurations the daemon was started with. assert(err); #endif is_env_initialized = true; DAEMON_DEBUG0(debug_fd, "Environment initialized.\n"); } // just a security measure if (is_lib_initialized) return; void init_passthrough_() { libc = dlopen("libc.so.6", RTLD_LAZY); libc_open = dlsym(libc, "open"); libc_fopen = dlsym(libc, "fopen"); // libc_fopen = dlsym(libc, "fopen"); // libc_fopen64 = dlsym(libc, "fopen64"); libc_unlink = dlsym(libc, "unlink"); Loading Loading @@ -517,21 +574,21 @@ void init_preload(void) { libc_dup = dlsym(libc, "dup"); libc_dup2 = dlsym(libc, "dup2"); // XXX Continue here. stat is not intercepted because it is not part of libc? investigate. debug_fd = fopen(LOG_DAEMON_PATH, "a+"); fs_config = make_shared<struct FsConfig>(); DAEMON_DEBUG0(debug_fd, "Preload initialized.\n"); is_lib_initialized = true; #ifdef MARGOIPC // init margo client for IPC auto err = init_ld_argobots(); assert(err); err = init_ipc_client(); assert(err); err = ipc_send_get_fs_config(ipc_config_id); // get fs configurations the daemon was started with. assert(err); #endif DAEMON_DEBUG0(debug_fd, "Passthrough initialized.\n"); } void init_passthrough_if_needed() { pthread_once(&init_lib_thread, init_passthrough_); } /** * Called initially when preload library is used with the LD_PRELOAD environment variable */ void init_preload(void) { init_passthrough_if_needed(); init_environment(); printf("[INFO] preload init successful.\n"); } Loading @@ -555,6 +612,5 @@ void destroy_preload(void) { HG_Finalize(mercury_hg_class_); DAEMON_DEBUG0(debug_fd, "Preload library shut down.\n"); #endif fclose(debug_fd); } No newline at end of file Loading
ifs/include/preload/preload.hpp +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ margo_instance_id ld_margo_id(); hg_addr_t daemon_addr(); void init_passthrough_if_needed(); void init_preload(void) __attribute__((constructor)); Loading
ifs/src/preload/CMakeLists.txt +1 −1 Original line number Diff line number Diff line Loading @@ -15,4 +15,4 @@ set(SOURCE_FILES_PRELOAD preload.cpp open_file_map.cpp ../../include/preload/pre add_library(iointer SHARED ${SOURCE_FILES_PRELOAD}) target_link_libraries(iointer dl ${BMI_LIBRARIES} ${MERCURY_LIBRARIES} ${MERCURY_UTIL_LIBRARIES} ${ABT_LIBRARIES} ${ABT_SNOOZER_LIBRARIES} ${MARGO_LIBRARIES} -lboost_system) No newline at end of file -lpthread -lboost_system) No newline at end of file
ifs/src/preload/preload.cpp +143 −87 Original line number Diff line number Diff line Loading @@ -12,6 +12,8 @@ #include <sys/stat.h> #include "../../main.hpp" static pthread_once_t init_lib_thread = PTHREAD_ONCE_INIT; // Mercury Client hg_class_t* mercury_hg_class_; hg_context_t* mercury_hg_context_; Loading @@ -25,7 +27,7 @@ static hg_id_t ipc_stat_id; static hg_id_t ipc_unlink_id; // misc bool is_lib_initialized = false; static std::atomic<bool> is_env_initialized(false); // external variables FILE* debug_fd; Loading @@ -36,9 +38,11 @@ void* libc; void* libc_open; //void* libc_open64; //unused void* libc_fopen; void* libc_fopen; // XXX Does not work with streaming pointers. If used will block forever void* libc_fopen64; // XXX Does not work with streaming pointers. If used will block forever //void* libc_creat; //unused //void* libc_creat64; //unused void* libc_unlink; void* libc_close; Loading Loading @@ -75,8 +79,9 @@ void* libc_dup2; static OpenFileMap file_map{}; int ld_open(const char* path, int flags, ...) { DAEMON_DEBUG(debug_fd, "ld_open called with path %s\n", path); int open(const char* path, int flags, ...) { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "open called with path %s\n", path); mode_t mode; if (flags & O_CREAT) { va_list vl; Loading @@ -84,9 +89,8 @@ int ld_open(const char* path, int flags, ...) { mode = va_arg(vl, int); va_end(vl); } if (is_fs_path(path)) { if (is_env_initialized && is_fs_path(path)) { auto fd = file_map.add(path, (flags & O_APPEND) != 0); // TODO call daemon and return if successful return the above fd. if unsuccessful delete fd remove file from map #ifndef MARGOIPC #else Loading @@ -103,8 +107,9 @@ int ld_open(const char* path, int flags, ...) { return (reinterpret_cast<decltype(&open)>(libc_open))(path, flags, mode); } int ld_open64(__const char* path, int flags, ...) { DAEMON_DEBUG(debug_fd, "ld_open64 called with path %s\n", path); int open64(__const char* path, int flags, ...) { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "open64 called with path %s\n", path); mode_t mode; if (flags & O_CREAT) { va_list ap; Loading @@ -112,22 +117,42 @@ int ld_open64(__const char* path, int flags, ...) { mode = va_arg(ap, mode_t); va_end(ap); } return ld_open(path, flags | O_LARGEFILE, mode); return open(path, flags | O_LARGEFILE, mode); } FILE* ld_fopen(const char* path, const char* mode) { // DAEMON_DEBUG(debug_fd, "ld_fopen called with path %s with mode %d\n", path, mode); return (reinterpret_cast<decltype(&fopen)>(libc_fopen))(path, mode); } //// TODO This function somehow always blocks forever if one puts anything between the paththru... //FILE* fopen(const char* path, const char* mode) { //// init_passthrough_if_needed(); //// DAEMON_DEBUG(debug_fd, "fopen called with path %s\n", path); // return (reinterpret_cast<decltype(&fopen)>(libc_fopen))(path, mode); //} //// TODO This function somehow always blocks forever if one puts anything between the paththru... //FILE* fopen64(const char* path, const char* mode) { //// init_passthrough_if_needed(); //// DAEMON_DEBUG(debug_fd, "fopen64 called with path %s\n", path); // return (reinterpret_cast<decltype(&fopen)>(libc_fopen))(path, mode); //} #undef creat int creat(const char* path, mode_t mode) { DAEMON_DEBUG(debug_fd, "ld_creat called with path %s with mode %d\n", path, mode); return ld_open(path, O_CREAT | O_WRONLY | O_TRUNC, mode); init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "creat called with path %s with mode %d\n", path, mode); return open(path, O_CREAT | O_WRONLY | O_TRUNC, mode); } #undef creat64 int creat64(const char* path, mode_t mode) { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "creat64 called with path %s with mode %d\n", path, mode); return open(path, O_CREAT | O_WRONLY | O_TRUNC | O_LARGEFILE, mode); } int unlink(const char* path) __THROW { // DAEMON_DEBUG(debug_fd, "ld_unlink called with path %s\n", path); if (is_fs_path(path)) { init_passthrough_if_needed(); // DAEMON_DEBUG(debug_fd, "unlink called with path %s\n", path); if (is_env_initialized && is_fs_path(path)) { #ifndef MARGOIPC #else return ipc_send_unlink(path, ipc_unlink_id); Loading @@ -136,8 +161,9 @@ int unlink(const char* path) __THROW { return (reinterpret_cast<decltype(&unlink)>(libc_unlink))(path); } int ld_close(int fd) { if (file_map.exist(fd)) { int close(int fd) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // Currently no call to the daemon is required file_map.remove(fd); return 0; Loading @@ -145,14 +171,15 @@ int ld_close(int fd) { return (reinterpret_cast<decltype(&close)>(libc_close))(fd); } int ld___close(int fd) { return ld_close(fd); int __close(int fd) { return close(fd); } int ld_stat(const char* path, struct stat* buf) __THROW { int stat(const char* path, struct stat* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "stat called with path %s\n", path); if (is_fs_path(path)) { if (is_env_initialized && is_fs_path(path)) { // TODO call daemon and return #ifndef MARGOIPC Loading @@ -164,9 +191,10 @@ int ld_stat(const char* path, struct stat* buf) __THROW { return (reinterpret_cast<decltype(&stat)>(libc_stat))(path, buf); } int ld_fstat(int fd, struct stat* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld_fstat called with fd %d\n", fd); if (file_map.exist(fd)) { int fstat(int fd, struct stat* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "fstat called with fd %d\n", fd); if (is_env_initialized && file_map.exist(fd)) { auto path = file_map.get(fd)->path(); // TODO use this to send to the daemon (call directly) // TODO call daemon and return #ifndef MARGOIPC Loading @@ -179,9 +207,10 @@ int ld_fstat(int fd, struct stat* buf) __THROW { return (reinterpret_cast<decltype(&fstat)>(libc_fstat))(fd, buf); } int ld___xstat(int ver, const char* path, struct stat* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld___xstat called with path %s\n", path); if (is_fs_path(path)) { int __xstat(int ver, const char* path, struct stat* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "__xstat called with path %s\n", path); if (is_env_initialized && is_fs_path(path)) { // TODO call stat #ifndef MARGOIPC Loading @@ -192,18 +221,20 @@ int ld___xstat(int ver, const char* path, struct stat* buf) __THROW { return (reinterpret_cast<decltype(&__xstat)>(libc___xstat))(ver, path, buf); } int ld___xstat64(int ver, const char* path, struct stat64* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld___xstat64 called with path %s\n", path); // if (is_fs_path(path)) { // // Not implemented // return -1; // } int __xstat64(int ver, const char* path, struct stat64* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "__xstat64 called with path %s\n", path); if (is_env_initialized && is_fs_path(path)) { // Not implemented return -1; } return (reinterpret_cast<decltype(&__xstat64)>(libc___xstat64))(ver, path, buf); } int ld___fxstat(int ver, int fd, struct stat* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld___fxstat called with fd %d\n", fd); if (file_map.exist(fd)) { int __fxstat(int ver, int fd, struct stat* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "__fxstat called with fd %d\n", fd); if (is_env_initialized && file_map.exist(fd)) { // TODO call fstat auto path = file_map.get(fd)->path(); #ifndef MARGOIPC Loading @@ -215,9 +246,10 @@ int ld___fxstat(int ver, int fd, struct stat* buf) __THROW { return (reinterpret_cast<decltype(&__fxstat)>(libc___fxstat))(ver, fd, buf); } int ld___fxstat64(int ver, int fd, struct stat64* buf) __THROW { DAEMON_DEBUG(debug_fd, "ld___fxstat64 called with fd %d\n", fd); if (file_map.exist(fd)) { int __fxstat64(int ver, int fd, struct stat64* buf) __THROW { init_passthrough_if_needed(); DAEMON_DEBUG(debug_fd, "__fxstat64 called with fd %d\n", fd); if (is_env_initialized && file_map.exist(fd)) { // TODO call fstat64 // auto path = file_map.get(fd)->path(); #ifndef MARGOIPC Loading @@ -229,24 +261,27 @@ int ld___fxstat64(int ver, int fd, struct stat64* buf) __THROW { return (reinterpret_cast<decltype(&__fxstat64)>(libc___fxstat64))(ver, fd, buf); } extern int ld___lxstat(int ver, const char* path, struct stat* buf) __THROW { if (is_fs_path(path)) { extern int __lxstat(int ver, const char* path, struct stat* buf) __THROW { init_passthrough_if_needed(); if (is_env_initialized && is_fs_path(path)) { // Not implemented return -1; } return (reinterpret_cast<decltype(&__lxstat)>(libc___lxstat))(ver, path, buf); } extern int ld___lxstat64(int ver, const char* path, struct stat64* buf) __THROW { if (is_fs_path(path)) { extern int __lxstat64(int ver, const char* path, struct stat64* buf) __THROW { init_passthrough_if_needed(); if (is_env_initialized && is_fs_path(path)) { // Not implemented return -1; } return (reinterpret_cast<decltype(&__lxstat64)>(libc___lxstat64))(ver, path, buf); } int ld_access(const char* path, int mode) __THROW { if (is_fs_path(path)) { int access(const char* path, int mode) __THROW { init_passthrough_if_needed(); if (is_env_initialized && is_fs_path(path)) { #ifndef MARGOIPC #else Loading @@ -256,12 +291,13 @@ int ld_access(const char* path, int mode) __THROW { return (reinterpret_cast<decltype(&access)>(libc_access))(path, mode); } int ld_puts(const char* str) { int puts(const char* str) { return (reinterpret_cast<decltype(&puts)>(libc_puts))(str); } ssize_t ld_write(int fd, const void* buf, size_t count) { if (file_map.exist(fd)) { ssize_t write(int fd, const void* buf, size_t count) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto adafs_fd = file_map.get(fd); // auto path = adafs_fd->path(); // TODO use this to send to the daemon (call directly) // auto append_flag = adafs_fd->append_flag(); Loading @@ -276,8 +312,9 @@ ssize_t ld_write(int fd, const void* buf, size_t count) { return (reinterpret_cast<decltype(&write)>(libc_write))(fd, buf, count); } ssize_t ld_pwrite(int fd, const void* buf, size_t count, off_t offset) { if (file_map.exist(fd)) { ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto adafs_fd = file_map.get(fd); // auto path = adafs_fd->path(); // TODO use this to send to the daemon (call directly) // auto append_flag = adafs_fd->append_flag(); Loading @@ -292,8 +329,9 @@ ssize_t ld_pwrite(int fd, const void* buf, size_t count, off_t offset) { return (reinterpret_cast<decltype(&pwrite)>(libc_pwrite))(fd, buf, count, offset); } ssize_t ld_read(int fd, void* buf, size_t count) { if (file_map.exist(fd)) { ssize_t read(int fd, void* buf, size_t count) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto path = file_map.get(fd)->path(); // TODO use this to send to the daemon (call directly) // TODO call daemon and return size read #ifndef MARGOIPC Loading @@ -306,8 +344,9 @@ ssize_t ld_read(int fd, void* buf, size_t count) { return (reinterpret_cast<decltype(&read)>(libc_read))(fd, buf, count); } ssize_t ld_pread(int fd, void* buf, size_t count, off_t offset) { if (file_map.exist(fd)) { ssize_t pread(int fd, void* buf, size_t count, off_t offset) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto path = file_map.get(fd)->path(); // TODO use this to send to the daemon (call directly) // TODO call daemon and return size written #ifndef MARGOIPC Loading @@ -320,8 +359,9 @@ ssize_t ld_pread(int fd, void* buf, size_t count, off_t offset) { return (reinterpret_cast<decltype(&pread)>(libc_pread))(fd, buf, count, offset); } ssize_t ld_pread64(int fd, void* buf, size_t nbyte, __off64_t offset) { if (file_map.exist(fd)) { ssize_t pread64(int fd, void* buf, size_t nbyte, __off64_t offset) { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(fd)) { // auto path = file_map.get(fd)->path(); // TODO use this to send to the daemon (call directly) // TODO call daemon and return size written #ifndef MARGOIPC Loading @@ -334,32 +374,38 @@ ssize_t ld_pread64(int fd, void* buf, size_t nbyte, __off64_t offset) { return (reinterpret_cast<decltype(&pread64)>(libc_pread64))(fd, buf, nbyte, offset); } off_t ld_lseek(int fd, off_t offset, int whence) __THROW { off_t lseek(int fd, off_t offset, int whence) __THROW { init_passthrough_if_needed(); return (reinterpret_cast<decltype(&lseek)>(libc_lseek))(fd, offset, whence); } off_t ld_lseek64(int fd, off_t offset, int whence) __THROW { return ld_lseek(fd, offset, whence); off_t lseek64(int fd, off_t offset, int whence) __THROW { init_passthrough_if_needed(); return lseek(fd, offset, whence); } int ld_truncate(const char* path, off_t length) __THROW { int truncate(const char* path, off_t length) __THROW { init_passthrough_if_needed(); return (reinterpret_cast<decltype(&truncate)>(libc_truncate))(path, length); } int ld_ftruncate(int fd, off_t length) __THROW { int ftruncate(int fd, off_t length) __THROW { init_passthrough_if_needed(); return (reinterpret_cast<decltype(&ftruncate)>(libc_ftruncate))(fd, length); } int ld_dup(int oldfd) __THROW { if (file_map.exist(oldfd)) { int dup(int oldfd) __THROW { init_passthrough_if_needed(); if (is_env_initialized && file_map.exist(oldfd)) { // Not implemented return -1; } return (reinterpret_cast<decltype(&dup)>(libc_dup))(oldfd); } int ld_dup2(int oldfd, int newfd) __THROW { if (file_map.exist(oldfd) || file_map.exist(newfd)) { int dup2(int oldfd, int newfd) __THROW { init_passthrough_if_needed(); if (is_env_initialized && (file_map.exist(oldfd) || file_map.exist(newfd))) { // Not implemented return -1; } Loading Loading @@ -474,16 +520,27 @@ hg_addr_t daemon_addr() { } /** * Called initially when preload library is used with the LD_PRELOAD environment variable * This function is only called in the preload constructor */ void init_preload(void) { void init_environment() { #ifdef MARGOIPC // init margo client for IPC auto err = init_ld_argobots(); assert(err); err = init_ipc_client(); assert(err); err = ipc_send_get_fs_config(ipc_config_id); // get fs configurations the daemon was started with. assert(err); #endif is_env_initialized = true; DAEMON_DEBUG0(debug_fd, "Environment initialized.\n"); } // just a security measure if (is_lib_initialized) return; void init_passthrough_() { libc = dlopen("libc.so.6", RTLD_LAZY); libc_open = dlsym(libc, "open"); libc_fopen = dlsym(libc, "fopen"); // libc_fopen = dlsym(libc, "fopen"); // libc_fopen64 = dlsym(libc, "fopen64"); libc_unlink = dlsym(libc, "unlink"); Loading Loading @@ -517,21 +574,21 @@ void init_preload(void) { libc_dup = dlsym(libc, "dup"); libc_dup2 = dlsym(libc, "dup2"); // XXX Continue here. stat is not intercepted because it is not part of libc? investigate. debug_fd = fopen(LOG_DAEMON_PATH, "a+"); fs_config = make_shared<struct FsConfig>(); DAEMON_DEBUG0(debug_fd, "Preload initialized.\n"); is_lib_initialized = true; #ifdef MARGOIPC // init margo client for IPC auto err = init_ld_argobots(); assert(err); err = init_ipc_client(); assert(err); err = ipc_send_get_fs_config(ipc_config_id); // get fs configurations the daemon was started with. assert(err); #endif DAEMON_DEBUG0(debug_fd, "Passthrough initialized.\n"); } void init_passthrough_if_needed() { pthread_once(&init_lib_thread, init_passthrough_); } /** * Called initially when preload library is used with the LD_PRELOAD environment variable */ void init_preload(void) { init_passthrough_if_needed(); init_environment(); printf("[INFO] preload init successful.\n"); } Loading @@ -555,6 +612,5 @@ void destroy_preload(void) { HG_Finalize(mercury_hg_class_); DAEMON_DEBUG0(debug_fd, "Preload library shut down.\n"); #endif fclose(debug_fd); } No newline at end of file