mirror of
https://github.com/usatiuk/backup.git
synced 2025-10-26 09:27:48 +01:00
omg it's very hacky but mounting kinda works
This commit is contained in:
@@ -1,15 +1,15 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
add_compile_options(-Ofast)
|
#add_compile_options(-Ofast)
|
||||||
add_link_options(-Ofast)
|
#add_link_options(-Ofast)
|
||||||
|
|
||||||
# add_compile_options(-Ofast -flto)
|
# add_compile_options(-Ofast -flto)
|
||||||
# add_link_options(-Ofast -flto)
|
# add_link_options(-Ofast -flto)
|
||||||
|
|
||||||
#add_compile_options(-Wall -O0 -Wextra -pedantic -Wshadow -Wformat=2 -Wfloat-equal -D_GLIBCXX_DEBUG -Wconversion -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g -rdynamic)
|
add_compile_options(-Wall -O0 -Wextra -pedantic -Wshadow -Wformat=2 -Wfloat-equal -D_GLIBCXX_DEBUG -Wconversion -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g -rdynamic)
|
||||||
#add_compile_options(-fsanitize=address -fsanitize=undefined -fno-sanitize-recover)
|
add_compile_options(-fsanitize=address -fsanitize=undefined -fno-sanitize-recover)
|
||||||
#add_link_options(-fsanitize=address -fsanitize=undefined -fno-sanitize-recover)
|
add_link_options(-fsanitize=address -fsanitize=undefined -fno-sanitize-recover)
|
||||||
#add_link_options(-rdynamic)
|
add_link_options(-rdynamic)
|
||||||
|
|
||||||
project(backup)
|
project(backup)
|
||||||
|
|
||||||
|
|||||||
2
Doxyfile
2
Doxyfile
@@ -2421,7 +2421,7 @@ HIDE_UNDOC_RELATIONS = YES
|
|||||||
# set to NO
|
# set to NO
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
|
|
||||||
HAVE_DOT = NO
|
HAVE_DOT = YES
|
||||||
|
|
||||||
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
|
||||||
# to run in parallel. When set to 0 doxygen will base this on the number of
|
# to run in parallel. When set to 0 doxygen will base this on the number of
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ add_subdirectory(crypto)
|
|||||||
add_subdirectory(filters)
|
add_subdirectory(filters)
|
||||||
add_subdirectory(repo)
|
add_subdirectory(repo)
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
|
add_subdirectory(fuse)
|
||||||
|
|
||||||
add_executable(backup main.cpp)
|
add_executable(backup main.cpp)
|
||||||
target_link_libraries(backup PRIVATE change_detectors chunkers commands crypto filters repo utils)
|
target_link_libraries(backup PRIVATE change_detectors chunkers commands crypto filters repo utils)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
add_library(commands srcs/Command.cpp srcs/CommandDiff.cpp srcs/CommandList.cpp srcs/CommandListFiles.cpp srcs/CommandRestore.cpp srcs/CommandRun.cpp srcs/CommandsCommon.cpp srcs/Diff.cpp)
|
add_library(commands srcs/Command.cpp srcs/CommandDiff.cpp srcs/CommandList.cpp srcs/CommandListFiles.cpp srcs/CommandRestore.cpp srcs/CommandRun.cpp srcs/CommandsCommon.cpp srcs/Diff.cpp srcs/CommandMount.cpp)
|
||||||
|
|
||||||
target_include_directories(commands PUBLIC includes)
|
target_include_directories(commands PUBLIC includes)
|
||||||
|
|
||||||
target_link_libraries(commands crypto repo chunkers utils change_detectors)
|
target_link_libraries(commands crypto repo chunkers utils change_detectors fuse)
|
||||||
|
|||||||
17
src/commands/includes/CommandMount.h
Normal file
17
src/commands/includes/CommandMount.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 07.06.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BACKUP_COMMANDMOUNT_H
|
||||||
|
#define BACKUP_COMMANDMOUNT_H
|
||||||
|
|
||||||
|
#include "Command.h"
|
||||||
|
|
||||||
|
class CommandMount : public Command {
|
||||||
|
public:
|
||||||
|
CommandMount();
|
||||||
|
void run(Context ctx) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif//BACKUP_COMMANDMOUNT_H
|
||||||
14
src/commands/srcs/CommandMount.cpp
Normal file
14
src/commands/srcs/CommandMount.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 07.06.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../includes/CommandMount.h"
|
||||||
|
#include "RepoFS.h"
|
||||||
|
|
||||||
|
CommandMount::CommandMount() : Command("mount") {
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandMount::run(Context ctx) {
|
||||||
|
RepoFS rfs(ctx.repo, ctx.repo->getObjects(Object::ObjectType::Archive).begin()->second, "./hi");
|
||||||
|
rfs.workerFn();
|
||||||
|
}
|
||||||
11
src/fuse/CMakeLists.txt
Normal file
11
src/fuse/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
|
pkg_check_modules(FUSE REQUIRED IMPORTED_TARGET fuse)
|
||||||
|
|
||||||
|
add_library(fuse srcs/RepoFS.cpp)
|
||||||
|
|
||||||
|
target_include_directories(fuse PUBLIC includes)
|
||||||
|
|
||||||
|
target_link_libraries(fuse utils repo PkgConfig::FUSE)
|
||||||
43
src/fuse/includes/RepoFS.h
Normal file
43
src/fuse/includes/RepoFS.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 07.06.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BACKUP_REPOFS_H
|
||||||
|
#define BACKUP_REPOFS_H
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "Repository.h"
|
||||||
|
#include "objects/Archive.h"
|
||||||
|
#include "objects/File.h"
|
||||||
|
|
||||||
|
struct DirEntry {
|
||||||
|
std::unordered_map<std::string, DirEntry> children;
|
||||||
|
std::optional<File> file;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RepoFS {
|
||||||
|
public:
|
||||||
|
RepoFS(Repository *repo, Object::idType archiveId, std::string path);
|
||||||
|
|
||||||
|
RepoFS &operator=(RepoFS rhs) = delete;
|
||||||
|
RepoFS(const RepoFS &orig) = delete;
|
||||||
|
|
||||||
|
~RepoFS();
|
||||||
|
|
||||||
|
void workerFn();
|
||||||
|
static inline DirEntry root;
|
||||||
|
static inline Repository *repo;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic<bool> stop = false;///< Stop flag
|
||||||
|
|
||||||
|
Archive archive;
|
||||||
|
std::string path;
|
||||||
|
|
||||||
|
|
||||||
|
// std::thread thread;///< Worker thread
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif//BACKUP_REPOFS_H
|
||||||
153
src/fuse/srcs/RepoFS.cpp
Normal file
153
src/fuse/srcs/RepoFS.cpp
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 07.06.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../includes/RepoFS.h"
|
||||||
|
|
||||||
|
#define FUSE_USE_VERSION 26
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <fuse.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "Serialize.h"
|
||||||
|
#include "objects/Chunk.h"
|
||||||
|
|
||||||
|
RepoFS::RepoFS(Repository *repon, Object::idType archiveId, std::string path) : archive(Serialize::deserialize<Archive>(repon->getObject(archiveId))), path(std::move(path)) {
|
||||||
|
RepoFS::repo = repon;
|
||||||
|
for (auto const &f: archive.files) {
|
||||||
|
auto file = Serialize::deserialize<File>(repo->getObject(f));
|
||||||
|
auto path = std::filesystem::u8path(file.name);
|
||||||
|
DirEntry *entry = &root;
|
||||||
|
for (auto const &subp: path) {
|
||||||
|
entry = &entry->children[subp];
|
||||||
|
}
|
||||||
|
entry->file.emplace(file);
|
||||||
|
}
|
||||||
|
// thread = std::thread(&RepoFS::workerFn, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
RepoFS::~RepoFS() {
|
||||||
|
// stop = true;
|
||||||
|
// thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *hello_str = "Hello World!\n";
|
||||||
|
static const char *hello_path = "/hello";
|
||||||
|
|
||||||
|
DirEntry *getf(std::string path) {
|
||||||
|
auto p = std::filesystem::relative(std::filesystem::u8path(path), "/");
|
||||||
|
DirEntry *entry = &RepoFS::root;
|
||||||
|
if (p != ".")
|
||||||
|
for (auto const &subp: p) {
|
||||||
|
entry = &entry->children.at(subp);
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfsGetattr(const char *path, struct stat *stbuf) {
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
memset(stbuf, 0, sizeof(struct stat));
|
||||||
|
if (strcmp(path, "/") == 0) {
|
||||||
|
stbuf->st_mode = S_IFDIR | 0755;
|
||||||
|
stbuf->st_nlink = 2;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
DirEntry *e;
|
||||||
|
try {
|
||||||
|
e = getf(path);
|
||||||
|
if (e->file->fileType == File::Type::Directory) {
|
||||||
|
stbuf->st_mode = S_IFDIR | 0755;
|
||||||
|
stbuf->st_nlink = 1;
|
||||||
|
} else if (e->file->fileType == File::Type::Normal) {
|
||||||
|
stbuf->st_mode = S_IFREG | 0444;
|
||||||
|
stbuf->st_nlink = 1;
|
||||||
|
stbuf->st_size = e->file->bytes;
|
||||||
|
}
|
||||||
|
} catch (...) { return -ENOENT; }
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfsReaddir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||||
|
off_t offset, struct fuse_file_info *fi) {
|
||||||
|
(void) offset;
|
||||||
|
(void) fi;
|
||||||
|
|
||||||
|
DirEntry *entry = &RepoFS::root;
|
||||||
|
if (std::string(path) != "/")
|
||||||
|
try {
|
||||||
|
entry = getf(path);
|
||||||
|
} catch (...) { return -ENOENT; }
|
||||||
|
|
||||||
|
filler(buf, ".", NULL, 0);
|
||||||
|
filler(buf, "..", NULL, 0);
|
||||||
|
|
||||||
|
for (auto const &e: entry->children) {
|
||||||
|
auto pstr = std::filesystem::u8path(e.second.file->name).filename().u8string();
|
||||||
|
std::cout << pstr << std::endl;
|
||||||
|
filler(buf, pstr.c_str(), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfsOpen(const char *path, struct fuse_file_info *fi) {
|
||||||
|
DirEntry *entry = &RepoFS::root;
|
||||||
|
if (std::string(path) != "/")
|
||||||
|
try {
|
||||||
|
entry = getf(path);
|
||||||
|
} catch (...) { return -ENOENT; }
|
||||||
|
|
||||||
|
if ((fi->flags & 3) != O_RDONLY)
|
||||||
|
return -EACCES;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfsRead(const char *path, char *buf, size_t size, off_t offset,
|
||||||
|
struct fuse_file_info *fi) {
|
||||||
|
size_t len;
|
||||||
|
(void) fi;
|
||||||
|
DirEntry *entry = &RepoFS::root;
|
||||||
|
if (std::string(path) != "/")
|
||||||
|
try {
|
||||||
|
entry = getf(path);
|
||||||
|
} catch (...) { return -ENOENT; }
|
||||||
|
|
||||||
|
std::vector<char> data;
|
||||||
|
|
||||||
|
for (auto const &id: entry->file->chunks) {
|
||||||
|
auto ch = Serialize::deserialize<Chunk>(RepoFS::repo->getObject(id));
|
||||||
|
data.insert(data.end(), ch.data.begin(), ch.data.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
len = data.size();
|
||||||
|
if (offset < len) {
|
||||||
|
if (offset + size > len)
|
||||||
|
size = len - offset;
|
||||||
|
memcpy(buf, data.data() + offset, size);
|
||||||
|
} else
|
||||||
|
size = 0;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct fuse_operations rfsOps = {
|
||||||
|
.getattr = rfsGetattr,
|
||||||
|
.readdir = rfsReaddir,
|
||||||
|
.open = rfsOpen,
|
||||||
|
.read = rfsRead,
|
||||||
|
};
|
||||||
|
|
||||||
|
void RepoFS::workerFn() {
|
||||||
|
int argc = 3;
|
||||||
|
char *argv[] = {"", "-d", const_cast<char *>(path.c_str())};
|
||||||
|
std::cout << static_cast<int>(fuse_main(argc, argv, &rfsOps, nullptr));
|
||||||
|
// while (!stop) {
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "CommandMount.h"
|
||||||
#include "commands/includes/Command.h"
|
#include "commands/includes/Command.h"
|
||||||
#include "commands/includes/CommandDiff.h"
|
#include "commands/includes/CommandDiff.h"
|
||||||
#include "commands/includes/CommandList.h"
|
#include "commands/includes/CommandList.h"
|
||||||
@@ -113,6 +114,7 @@ int main(int argc, char *argv[]) {
|
|||||||
commands.emplace(CommandRun().name, std::make_unique<CommandRun>());
|
commands.emplace(CommandRun().name, std::make_unique<CommandRun>());
|
||||||
commands.emplace(CommandListFiles().name, std::make_unique<CommandListFiles>());
|
commands.emplace(CommandListFiles().name, std::make_unique<CommandListFiles>());
|
||||||
commands.emplace(CommandList().name, std::make_unique<CommandList>());
|
commands.emplace(CommandList().name, std::make_unique<CommandList>());
|
||||||
|
commands.emplace(CommandMount().name, std::make_unique<CommandMount>());
|
||||||
|
|
||||||
if (commands.count(opt) == 0) {
|
if (commands.count(opt) == 0) {
|
||||||
std::cerr << "Unknown argument" << std::endl;
|
std::cerr << "Unknown argument" << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user