Skip to content

Pickle #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: pickle
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
cd90850
Merge pull request #1 from sbu-fsl/yifei-ioctl
excelle08 May 5, 2021
99512da
pickle test script/small code change
Jul 23, 2021
fd93300
racer support/pickle&load initial implementation
peiliou Jul 26, 2021
36bc483
comment out state_pool until further solutions
peiliou Jul 28, 2021
52c5207
modernize some cpp code for easier viewability
peiliou Jul 31, 2021
153cff9
changed test script to pause before cleanup for debugging purposes
peiliou Jul 31, 2021
8b925cf
fix pickle memleak/update test script
peiliou Aug 2, 2021
8b5ac1c
make test script fully automatic
peiliou Aug 11, 2021
46f9240
complete implementation&fix of verifs2 pickle/unpickle(with checkpoin…
peiliou Aug 23, 2021
9ac1408
rename link count functions
peiliou Aug 30, 2021
678b915
Merge branch 'master' of github.com:sbu-fsl/fuse-cpp-ramfs
excelle08 Nov 16, 2021
f2f9405
Revise the logic of readdir to make sure each dirent has a unique coo…
excelle08 Nov 27, 2021
daf4714
We don't need PDF docs on server
excelle08 Dec 21, 2021
cb61eea
Create and install the mount helper when building the project, so tha…
excelle08 Dec 21, 2021
8ab0635
Update doc
excelle08 Dec 21, 2021
235ada8
Remove unnecessary ckpt_restore_test.sh
Yifei-Liu Jan 16, 2022
6c49876
Fix a tiny issue in create mount script
Yifei-Liu Feb 5, 2022
ef58c0e
Update README
Yifei-Liu Feb 21, 2022
6ee7d07
script to build and mount verifs2
Yifei-Liu Feb 27, 2022
8e1494e
merge from master branch
peiliou May 3, 2022
40d32da
fix all verifs2 init/exit valgrind issues
peiliou May 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ Quick Run
=========
::

mkdir build
cd build
cmake ../src
make
make install


sudo make install
sudo mkdir /mnt/test-verifs2
sudo mount -t fuse.fuse-cpp-ramfs verifs2 /mnt/test-verifs2

Requirements
============
fuse-cpp-ramfs builds with CMake version 3.0 or greater.
Expand Down
27 changes: 27 additions & 0 deletions build_verifs2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

fsname="verifs2"
BUILD_DIR="build"
MOUNT_POINT="/mnt/test-$fsname"

if [ -d ./$BUILD_DIR ]; then
rm -r ./$BUILD_DIR
fi

mkdir -p ./$BUILD_DIR

cd ./$BUILD_DIR
cmake ../src
make
sudo make install

if [ "$(mount | grep $MOUNT_POINT)" ]; then
sudo umount -f $MOUNT_POINT;
fi

if [ -d $MOUNT_POINT ]; then
sudo rm -rf $MOUNT_POINT;
fi

sudo mkdir $MOUNT_POINT
sudo mount -t fuse.fuse-cpp-ramfs $fsname $MOUNT_POINT
20 changes: 0 additions & 20 deletions ckpt_restore_test.sh

This file was deleted.

10 changes: 1 addition & 9 deletions doc/english/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ add_custom_command(OUTPUT fuse-cpp-ramfs.ps
add_custom_target(postscript ALL
DEPENDS fuse-cpp-ramfs.ps)

# Set GROFF_NO_SGR because the following txt rule running ul is incompatible with the
# Set GROFF_NO_SGR because the following txt rule running ul is incompatible with the
# default.
add_custom_command(OUTPUT fuse-cpp-ramfs.1
COMMAND export GROFF_NO_SGR=1 && groff -e -T ascii -man ${CMAKE_CURRENT_SOURCE_DIR}/fuse-cpp-ramfs.man > fuse-cpp-ramfs.1
Expand All @@ -21,14 +21,6 @@ add_custom_command(OUTPUT fuse-cpp-ramfs.txt
add_custom_target(txt ALL
DEPENDS fuse-cpp-ramfs.txt)

add_custom_command(OUTPUT fuse-cpp-ramfs.pdf
COMMAND ps2pdf fuse-cpp-ramfs.ps > fuse-cpp-ramfs.pdf
DEPENDS fuse-cpp-ramfs.ps
COMMENT "Creating pdf file")
add_custom_target(pdf ALL
DEPENDS fuse-cpp-ramfs.pdf)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/fuse-cpp-ramfs.ps" DESTINATION "${DOCDIR}")
install(FILES fuse-cpp-ramfs.man DESTINATION "${MANDIR}/man1" RENAME fuse-cpp-ramfs.1)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/fuse-cpp-ramfs.txt" DESTINATION "${DOCDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/fuse-cpp-ramfs.pdf" DESTINATION "${DOCDIR}")
9 changes: 9 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,13 @@ target_link_libraries(ckpt pthread)
target_link_libraries(restore pthread)
target_link_libraries(pkl mcfs)
target_link_libraries(load mcfs)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/mount.fuse.fuse-cpp-ramfs
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/create-mount-helper.sh
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_target(
mount-helper ALL
DEPENDS fuse-cpp-ramfs ${CMAKE_BINARY_DIR}/mount.fuse.fuse-cpp-ramfs)
install(TARGETS fuse-cpp-ramfs DESTINATION bin)
install(PROGRAMS ${CMAKE_BINARY_DIR}/mount.fuse.fuse-cpp-ramfs DESTINATION /sbin)

2 changes: 1 addition & 1 deletion src/ckpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "fuse_cpp_ramfs.hpp"
#include "testops.h"

std::string MOUNTPOINT = VERIFS2_MOUNTPOINT;
//std::string MOUNTPOINT = VERIFS2_MOUNTPOINT;

int main(int argc, char **argv)
{
Expand Down
63 changes: 34 additions & 29 deletions src/cr_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,46 @@ bool isExistInDeleted(fuse_ino_t curr_ino, std::queue<fuse_ino_t> DeletedInodes)
void print_ino_queue(std::queue<fuse_ino_t> DeletedInodes);
#endif

std::unordered_map<uint64_t, verifs2_state > state_pool;
std::unordered_map<uint64_t, verifs2_state> state_pool;

int insert_state(uint64_t key,
const std::tuple<std::vector<Inode *>, std::queue<fuse_ino_t>,
struct statvfs> &fs_states_vec) {
auto it = state_pool.find(key);
if (it != state_pool.end()) {
return -EEXIST;
}
state_pool.insert({key, fs_states_vec});

int insert_state(uint64_t key,
std::tuple<std::vector <Inode *>, std::queue<fuse_ino_t>,
struct statvfs> fs_states_vec)
{
auto it = state_pool.find(key);
if (it != state_pool.end()) {
return -EEXIST;
}
state_pool.insert({key, fs_states_vec});
return 0;
}

return 0;
verifs2_state find_state(uint64_t key) {
auto it = state_pool.find(key);
if (it == state_pool.end()) {
std::queue<fuse_ino_t> empty_queue;
struct statvfs empty_statvfs = {};
return verifs2_state{std::vector<Inode *>(), empty_queue, empty_statvfs};
} else {
return it->second;
}
}

verifs2_state find_state(uint64_t key)
{
auto it = state_pool.find(key);
if (it == state_pool.end()) {
std::queue<fuse_ino_t> empty_queue;
struct statvfs empty_statvfs = {};
return verifs2_state{std::vector <Inode *>(), empty_queue, empty_statvfs};
} else {
return it->second;
}
int remove_state(uint64_t key) {
auto it = state_pool.find(key);
if (it == state_pool.end()) {
return -ENOENT;
}
state_pool.erase(it);
return 0;
}

int remove_state(uint64_t key)
{
auto it = state_pool.find(key);
if (it == state_pool.end()) {
return -ENOENT;
}
state_pool.erase(it);
return 0;
std::unordered_map<uint64_t, verifs2_state> get_state_pool() {
return state_pool;
}

void clear_states() {
state_pool.clear();
}

#ifdef DUMP_TESTING
Expand Down
10 changes: 8 additions & 2 deletions src/cr_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
#include "special_inode.hpp"
#include "symlink.hpp"

typedef std::tuple<std::vector <Inode *>, std::queue<fuse_ino_t>, struct statvfs> verifs2_state;
typedef std::tuple<std::vector<Inode *>, std::queue<fuse_ino_t>, struct statvfs> verifs2_state;

int insert_state(uint64_t key, const verifs2_state &fs_states_vec);

int insert_state(uint64_t key, verifs2_state fs_states_vec);
verifs2_state find_state(uint64_t key);

int remove_state(uint64_t key);

std::unordered_map<uint64_t, verifs2_state> get_state_pool();

void clear_states();

#ifdef DUMP_TESTING
void dump_File(File* file);
void dump_Directory(Directory* dir);
Expand Down
43 changes: 43 additions & 0 deletions src/create-mount-helper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash

DEST_DIR=$(pwd)
DEST_NAME=mount.fuse.fuse-cpp-ramfs
DEST=$DEST_DIR/$DEST_NAME
FUSE_RAMFS_BINDIR=$(pwd)

echo '#!/bin/bash' > $DEST
echo '' >> $DEST
echo 'if [ "$#" -lt 2 ]; then' >> $DEST
echo ' echo "Usage: $0 <mount-name> <mount-dir> [-o options]";' >> $DEST
echo ' exit 1;' >> $DEST
echo 'fi' >> $DEST
echo '' >> $DEST
echo "FUSE_RAMFS_BINDIR=$FUSE_RAMFS_BINDIR" >> $DEST
echo 'MNT_NAME=$1' >> $DEST
echo 'MNT_DIR=$2' >> $DEST
echo 'OPTS=' >> $DEST
echo 'FUSE_CPP_RAMFS_PROG=$FUSE_RAMFS_BINDIR/fuse-cpp-ramfs' >> $DEST
echo 'FUSE_CPP_RAMFS_MOUNT=$FUSE_RAMFS_BINDIR/mnts' >> $DEST
echo '' >> $DEST
echo '# If there is options string?' >> $DEST
echo 'if [ "$#" -gt 2 ] && [ "$3" == "-o" ]; then' >> $DEST
echo ' OPTS=$4;' >> $DEST
echo 'fi' >> $DEST
echo '' >> $DEST
echo 'mkdir -p $FUSE_CPP_RAMFS_MOUNT' >> $DEST
echo 'ln -fs $FUSE_CPP_RAMFS_PROG $FUSE_CPP_RAMFS_MOUNT/$MNT_NAME' >> $DEST
echo '' >> $DEST
echo 'if [ -n "$OPTS" ]; then' >> $DEST
echo ' nohup $FUSE_CPP_RAMFS_MOUNT/$MNT_NAME -o $OPTS $MNT_DIR 2>&1 > $FUSE_CPP_RAMFS_MOUNT/$MNT_NAME.out &' >> $DEST
echo 'else' >> $DEST
echo ' nohup $FUSE_CPP_RAMFS_MOUNT/$MNT_NAME $MNT_DIR 2>&1 > $FUSE_CPP_RAMFS_MOUNT/$MNT_NAME.out &' >> $DEST
echo 'fi' >> $DEST
echo '' >> $DEST
echo 'if [ -z "$(pgrep $MNT_NAME)" ]; then' >> $DEST
echo ' echo "Mount failed.";' >> $DEST
echo ' exit 1;' >> $DEST
echo 'fi' >> $DEST
echo '' >> $DEST
echo 'exit 0;' >> $DEST

chmod +x $DEST
58 changes: 36 additions & 22 deletions src/directory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,16 @@ int Directory::ReadAndReply(fuse_req_t req, size_t size, off_t off) {
return fuse_reply_err(req, EISDIR);
}

/* The cookie uses 32 bits, with the higher 16 bit the key to the readdir
* context, and the lower 16 bit representing the index of the directory entry.
*/
Directory::ReadDirCtx* Directory::PrepareReaddir(off_t cookie) {
off_t key = 0;
if (cookie != 0) {
/* NOTE: Will throw std::out_of_range if no entry is found */
Directory::ReadDirCtx* ctx = readdirStates.at(cookie);

/* If we have reached the end of the iterator, we should destroy this context
* to release memory */
if (ctx->it == ctx->children.end()) {
Directory::readdirStates.erase(cookie);
delete ctx;
throw(std::out_of_range("Not found"));
}
key = (cookie & 0xffff0000) >> 16;
Directory::ReadDirCtx* ctx = readdirStates.at(key);

return ctx;
}
/* Make a copy of children */
Expand All @@ -166,23 +164,38 @@ Directory::ReadDirCtx* Directory::PrepareReaddir(off_t cookie) {
lk.unlock();

/* Add it to the table */
cookie = rand();
key = rand() & 0xffff;
/* Make sure there is no duplicate */
while (readdirStates.find(cookie) != readdirStates.end()) {
cookie = rand();
while (readdirStates.find(key) != readdirStates.end()) {
key = rand() & 0xffff;
}
cookie = 0;
cookie = key << 16;
ReadDirCtx *newctx = new ReadDirCtx(cookie, copiedChildren);
readdirStates.insert({cookie, newctx});
readdirStates.insert({key, newctx});
return newctx;
}

void Directory::RecycleStates() {
// find context objects whose iterators have reached the end, and free them
for (auto ctxiter = readdirStates.begin(); ctxiter != readdirStates.end();) {
Directory::ReadDirCtx *ctx = ctxiter->second;
if (ctx->it == ctx->children.end()) {
delete ctx;
ctxiter = readdirStates.erase(ctxiter);
} else {
++ctxiter;
}
}
}

bool Directory::IsEmpty() {
std::shared_lock<std::shared_mutex> lk(childrenRwSem);
for (auto it = m_children.begin(); it != m_children.end(); ++it) {
if (it->first == "." || it->first == "..") {
for (auto & it : m_children) {
if (it.first == "." || it.first == "..") {
continue;
}
Inode *entry = FuseRamFs::GetInode(it->second);
Inode *entry = FuseRamFs::GetInode(it.second);
/* Not empty if it has at least one undeleted inode */
if (entry && !entry->HasNoLinks()) {
return false;
Expand All @@ -196,13 +209,13 @@ size_t Directory::GetPickledSize() {
// the number of children
res += sizeof(size_t);
// iterate children
for (auto it = m_children.begin(); it != m_children.end(); ++it) {
for (auto & it : m_children) {
// inode number
res += sizeof(fuse_ino_t);
// name length field
res += sizeof(size_t);
// size of file name
res += it->first.size();
res += it.first.size();
}
return res;
}
Expand All @@ -221,17 +234,17 @@ size_t Directory::Pickle(void* &buf) {
memcpy(ptr, &nchildren, sizeof(nchildren));
ptr += sizeof(nchildren);
// iterate children and store
for (auto it = m_children.begin(); it != m_children.end(); ++it) {
for (auto & it : m_children) {
// store inode number
fuse_ino_t ino = it->second;
fuse_ino_t ino = it.second;
memcpy(ptr, &ino, sizeof(ino));
ptr += sizeof(ino);
// store the length of the file name
size_t namelen = it->first.size();
size_t namelen = it.first.size();
memcpy(ptr, &namelen, sizeof(namelen));
ptr += sizeof(namelen);
// store the name string
memcpy(ptr, it->first.c_str(), namelen);
memcpy(ptr, it.first.c_str(), namelen);
ptr += namelen;
}
return ptr - (char *)buf;
Expand All @@ -244,6 +257,7 @@ size_t Directory::Load(const void* &buf) {
size_t nchildren;
memcpy(&nchildren, ptr, sizeof(nchildren));
ptr += sizeof(nchildren);
m_children.clear();
// iterate the list and load the children
for (size_t i = 0; i < nchildren; ++i) {
// load inode number
Expand Down
1 change: 1 addition & 0 deletions src/directory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Directory : public Inode {

static std::unordered_map<off_t, Directory::ReadDirCtx *> readdirStates;
ReadDirCtx* PrepareReaddir(off_t cookie);
void RecycleStates();
friend class FuseRamFs;
public:
~Directory() {}
Expand Down
Loading