Skip to content

yufeiwu0106/remote-file-system

Repository files navigation

Remote File System (RFS)

A multi-threaded remote file system based on TCP sockets with file versioning support.

Features

  • WRITE: Upload files to the server
  • GET: Download files from the server (with version support)
  • RM: Delete remote files
  • LS: View file version history
  • Multi-threading: Support multiple concurrent client connections
  • Version Control: Automatically save file history versions
  • Concurrency Control: Use mutex locks to protect shared resources

Project Structure

.
├── protocol.h          # Protocol definitions and shared structures
├── utils.c             # Utility function implementations
├── rfserver.c          # Server main program
├── rfs.c               # Client program
├── Makefile            # Build configuration
└── test.sh             # Automated test script

Compilation

make                    # Build all
make server             # Build server only
make client             # Build client only
make clean              # Clean build files

Usage

Start the Server

./rfserver

The server listens on port 7768 with storage root directory at ./storage.

Client Commands

WRITE - Upload File

./rfs WRITE local/file.txt remote/path/file.txt

GET - Download File

./rfs GET remote/file.txt local/downloaded.txt
./rfs GET remote/file.txt:v2 local/version2.txt    # Specific version

RM - Delete File

./rfs RM remote/file.txt

LS - View Version Information

./rfs LS remote/file.txt

STOP - Stop Server

./rfs STOP

Version Control

File Organization

storage/
├── file.txt                    # Current version
└── .versions/
    ├── file.txt.v1             # Version 1
    ├── file.txt.v2             # Version 2
    └── file.txt.meta           # Metadata

Version Strategy

  1. First write creates version 1
  2. Subsequent writes save current file as old version, write new content
  3. Metadata records version numbers, timestamps, and counts

Concurrency Control

Threading Model

  • Main thread: Listen and accept client connections
  • Worker threads: Handle each client in separate thread

Mutex Protection

pthread_mutex_t file_mutex;  // Protects file operations

Protected operations: file writing, version assignment, metadata updates, file deletion.

Testing

Automated Tests

chmod +x test.sh
./test.sh

Manual Testing

make setup
./rfserver &
echo "Hello" > test.txt
./rfs WRITE test.txt remote/test.txt
./rfs GET remote/test.txt downloaded.txt
./rfs LS remote/test.txt
./rfs STOP

Cross-Machine Testing

Server (Machine A)

# Edit protocol.h: set SERVER_IP to Machine A's IP
./rfserver

Client (Machine B)

# Edit protocol.h: set SERVER_IP to Machine A's IP
make client
./rfs WRITE local.txt remote.txt

Error Codes

  • STATUS_FILE_NOT_FOUND (-2): File does not exist
  • STATUS_OUT_OF_STORAGE (-3): Insufficient disk space
  • STATUS_INVALID_PATH (-4): Invalid path (contains ".." or absolute path)
  • STATUS_ERROR (-1): Other errors

Configuration

Edit protocol.h:

#define SERVER_PORT 7768
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 8192
#define MAX_VERSIONS 100

Protocol Design

typedef struct {
    char command[16];        // Command: WRITE, GET, RM, LS
    char arg1[512];          // First argument
    char arg2[512];          // Second argument
    long file_size;          // File size in bytes
    int version;             // Version (0=latest, >0=specific)
} CommandMessage;

typedef struct {
    int status;              // Status code
    long data_size;          // Data size
    char message[256];       // Message
} ResponseMessage;

Implementation Details

Thread Safety

pthread_mutex_lock(&file_mutex);
// Critical section: file operations
pthread_mutex_unlock(&file_mutex);

File Transfer

// Client sends
while ((bytes = fread(buffer, 1, BUFFER_SIZE, fp)) > 0) {
    send(socket_desc, buffer, bytes, 0);
}

// Server receives
while (remaining > 0) {
    bytes = recv(client_sock, buffer, to_read, 0);
    fwrite(buffer, 1, bytes, fp);
    remaining -= bytes;
}

Assignment Requirements

Question Requirement Status
Q1 WRITE command Implemented
Q2 GET command Implemented
Q3 RM command Implemented
Q4 Multi-threading Implemented
Q5 File versioning Implemented
Q6 (Bonus) LS command Implemented
Q7 (Bonus) GET version Implemented

Troubleshooting

Server won't start

netstat -tulpn | grep 7768
killall rfserver

Connection refused

sudo ufw allow 7768/tcp
ps aux | grep rfserver

Permission errors

chmod 755 storage

Author

Course: 93.202 Inter-Process Communication with TCP Sockets in C

About

A versioning remote file system using TCP sockets in C

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published