-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
dentiny
committed
Nov 14, 2020
1 parent
2381555
commit 4c94d38
Showing
19 changed files
with
5,338 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
all: server tweakfs | ||
|
||
clean: | ||
# make -f Makefile.fuse_rpc clean | ||
rm *.o | ||
rm bbfs.log | ||
rm -f fuse_rpc_client | ||
rm -f fuse_rpc_server | ||
rm -f tweakfs | ||
rm -rf mountdir | ||
rm -rf rootdir | ||
|
||
create: | ||
mkdir mountdir | ||
mkdir rootdir | ||
touch rootdir/secret.txt | ||
touch rootdir/secret_file.txt | ||
touch rootdir/bogus.txt | ||
echo "hello world" > rootdir/bogus.txt | ||
echo "secret" > rootdir/secret.txt | ||
echo "secret_file" > rootdir/secret_file.txt | ||
mkdir rootdir/testdir | ||
|
||
header: fuse_rpc.x | ||
# rpcgen -M -a -C fuse_rpc.x | ||
rpcgen -M fuse_rpc.x | ||
|
||
server: fuse_rpc.h fuse_rpc_svc.c fuse_rpc_server.c fuse_rpc_xdr.c fuse_rpc_clnt.c | ||
gcc -g3 -pthread fuse_rpc_svc.c fuse_rpc_server.c fuse_rpc_xdr.c fuse_rpc_clnt.c -o fuse_rpc_server | ||
|
||
tweakfs: tweakfs.c log.c fuse_rpc_clnt.o fuse_rpc_xdr.o | ||
gcc -g3 -pthread $^ `pkg-config fuse --cflags --libs` -o $@ | ||
|
||
mount: | ||
./tweakfs -d -s rootdir/ mountdir/ localhost | ||
# ./tweakfs rootdir/ mountdir/ localhost | ||
|
||
debug: | ||
# valgrind ./tweakfs -d -s rootdir/ mountdir localhost | ||
valgrind ./tweakfs -d -s rootdir/ mountdir 67.159.88.71 10.148.54.200 | ||
|
||
unmount: | ||
fusermount -u mountdir | ||
|
||
rpc: | ||
# rpcgen -a -C fuse_rpc.x | ||
make -f Makefile.fuse_rpc | ||
|
||
run_server: | ||
sudo ./fuse_rpc_server | ||
# sudo ./fuse_rpc_server 2>/dev/null | ||
|
||
new: | ||
make unmount | ||
make clean | ||
make | ||
make create |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
|
||
# This is a template Makefile generated by rpcgen | ||
|
||
# Parameters | ||
|
||
CLIENT = fuse_rpc_client | ||
SERVER = fuse_rpc_server | ||
|
||
SOURCES_CLNT.c = | ||
SOURCES_CLNT.h = | ||
SOURCES_SVC.c = | ||
SOURCES_SVC.h = | ||
SOURCES.x = fuse_rpc.x | ||
|
||
TARGETS_SVC.c = fuse_rpc_svc.c fuse_rpc_server.c fuse_rpc_xdr.c | ||
TARGETS_CLNT.c = fuse_rpc_clnt.c fuse_rpc_client.c fuse_rpc_xdr.c | ||
TARGETS = fuse_rpc.h fuse_rpc_xdr.c fuse_rpc_clnt.c fuse_rpc_svc.c fuse_rpc_client.c fuse_rpc_server.c | ||
|
||
OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o) | ||
OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o) | ||
# Compiler flags | ||
|
||
CPPFLAGS += -D_REENTRANT | ||
CFLAGS += -g | ||
LDLIBS += -lnsl -lpthread | ||
RPCGENFLAGS = | ||
|
||
# Targets | ||
|
||
all : $(CLIENT) $(SERVER) | ||
|
||
$(TARGETS) : $(SOURCES.x) | ||
rpcgen $(RPCGENFLAGS) $(SOURCES.x) | ||
|
||
$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c) | ||
|
||
$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c) | ||
|
||
$(CLIENT) : $(OBJECTS_CLNT) | ||
$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS) | ||
|
||
$(SERVER) : $(OBJECTS_SVC) | ||
$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS) | ||
|
||
clean: | ||
$(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,89 @@ | ||
# Distributed-File-System | ||
Distributed File Sytem | ||
### Distributed File system | ||
This project is distributed file system based on [FUSE](https://github.com/libfuse/libfuse). Currently the cluster contains only two servers, one primary and one secondary, but it could be extended to more. | ||
|
||
#### How to run the program | ||
Before compiling the project, make sure the environment is set-up. | ||
``` | ||
sudo apt update | ||
sudo apt dist-upgrade | ||
sudo apt install build-essential pkg-config libfuse-dev | ||
``` | ||
This repo has provided Makefile, but several places needs to be updated. | ||
`make header` compiles and updates the RPC header and stab files. | ||
`make all` compiles client-side and server-side executable file `tweakfs` and `fuse_rpc_server` respectively. | ||
`make create` generates the rootdir and mountdir automatically, which is the pre-requisite for the program. | ||
`make debug` needs a little update: the last two arguments are IP addresses for primary and secondary server. | ||
`make unmount` unmount the mountdir off rootdir. | ||
`make clean` cleans all generated object files and rootdir, mountdir. | ||
Additionally, on server-side, I did a hard code of secondary server IP address, ``connect_server``which needs to be corrected. | ||
System configuration file `/etc/hosts` should also appended the target server IP. Example: | ||
``` | ||
127.0.0.1 localhost | ||
127.0.1.1 ubuntu | ||
# For RPC. | ||
67.159.88.71 [email protected] | ||
10.148.54.200 [email protected] | ||
# The following lines are desirable for IPv6 capable hosts | ||
::1 localhost ip6-localhost ip6-loopback | ||
ff02::1 ip6-allnodes | ||
ff02::2 ip6-allrouters | ||
``` | ||
|
||
#### Implementation details | ||
1. On client side, every file system operation will be transmitted to server side via RPC. In this project, I select [Sun RPC](https://docs.oracle.com/cd/E19683-01/816-1435/6m7rrfn9k/index.html). Client side always tries to connect primary server first, then secondary server if fails. | ||
2. `.x` file is the communication protocal for RPC. | ||
Naming pattern: | ||
- client-to-server message structs are named as function_arg, server-to-client message structs are named as function_ret. | ||
- Every server-to-client response includes a data member ret, it returns 0 if RPC succeeds, otherwise it'd be assigned -errno. | ||
- For r/w requests, a len member is included, which indicates the actual bytes completes. | ||
- Every *_arg has a data member called ip, which is used to differentiate seperate path for distinct clients. To create path at server side, it's represented as a unsigned integer. | ||
3. Server handles every RPC requests from client side. | ||
For primary server, several updating operation needs to be completed on secondary server for replication and availability, say, `write`, `mkdir`, `rmdir`, etc. It first transmit these requests to secondary server, and handle the request whatever the second one succeeds or fails. Other read-only requests will only be handled on primary server. | ||
4. Primary server goes through the "handle flow" of `opendir` - `readdir` - `releasedir`, `open` - `read` - `release`, so it could use the fd acquired from previous operations, while the secondary server have to rely on full path. | ||
5. All operations are executed in the order of: | ||
|
||
(1) transmit request to primary server, if possible | ||
|
||
(2) check rwx validility, if needed | ||
|
||
(3) lock the file or directory, if needed | ||
|
||
(4) execute the operation | ||
|
||
(5) unlock the locked resource | ||
|
||
(6) set return value, and send back response back to client via RPC | ||
|
||
6. Server stores all files under the root directory `/DFS`, and create it at the very beginning it doesn't exist. All files are considered visible by all user mounted, but other operations, like updating, removing, reading needs further authentication. | ||
|
||
7. About access authentication: | ||
|
||
(1) file open is checked by read and write bit | ||
|
||
(2) directory listing is checked by read bit, open is checked by execute bit | ||
|
||
(3) file creation, rename and deletion need the rwx bits of parent directory, related operations include operation: unlink, mkdir, rmdir, mknod, rename, symlink, link | ||
|
||
(4) chown needs root, chmod needs owner, utime needs owner | ||
|
||
8. Locking mechanism: | ||
|
||
(1) add shared lock for file read and directory read | ||
|
||
(2) add exclusive lock for file write | ||
|
||
(3) add exclusive lock for directory mutation, eg: rename, unlink, etc | ||
|
||
9. About server recovery, we have provided a python script which does cold restoration. Eg, you could simply `sudo python rsync.py [email protected]:/9962309 /` | ||
|
||
#### Special handling | ||
1. `chown` needs root identity, users calling it will get a "permission deny" error message. | ||
2. `/DFS` is a special root directory in Ddistributed File System. Anyone can create file or directory inside of it, but only owner of the file can delete or rename. | ||
|
||
#### Known bugs | ||
1. We have handled the cases where primary server or secondary one cannot be reached. But if the client goes down, fd won't be released, thus system resource is leaked. | ||
2. `symlink` and `link` operations are not yet thread-safe. | ||
3. `fd .` should show the file system attribute, but my program cannot. | ||
4. server failover test doesn't pass; currently it can only handle the case when server program is killed, and machine is still alive; it doesn't go well when secondary server is rebooted. |
Oops, something went wrong.