You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

整合FUSE与TCP/IP服务器后无法挂载文件系统求助

问题描述

我用C语言基于FUSE和TCP/IP构建简易分布式文件系统,原本独立的server.c、client.c能正常收发请求,单独测试的filesystem.c也能在Ubuntu虚拟机正常挂载。但将两者整合为fileServer.c后,编译无错误,执行./fileServer -f /home/anon/fuseFileSytem/dfs时文件系统未挂载;尝试sudo mount -t fuse.fileServer ./fileServer /home/sena/finalProject_Sena_Senam/dfs时,出现/bin/sh/: 1: fileServer: not found错误。附上相关代码,请求解决以推进客户端与服务器的远程连接开发。

核心代码片段

#define FUSE_USE_VERSION 30
//  included necessary libraries and headers //

#define NUM_SERVERS 1
#define BASE_PORT 8890
#define MAX_MESSAGE_SIZE 20000

// Server operations
int create_server_socket(int port);
void* server_thread(void* arg);
void* handle_client(void* arg);

// Function prototypes for integrating FUSE filesystem with server
// Call FUSE functions based on client request 
int open_file(const char* filename);
// int close_file(int fd);
int read_file(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi);
int read_directory(const char *path, void *buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi );
int write_tofile(const char *path, const char *buf, size_t size, off_t offset);
int seek_file(int fd, off_t offset, int whence);
int remove_file(const char* filename);
int cache_file(const char* filename);
int get_cache(const char* filename, void* buffer, size_t size);
int flush_cache();

// File system data structures
#define block_size 1024
typedef struct superblock {...} superblock;
typedef struct inode {...} inode;
typedef struct filetype {...} filetype;
filetype * root;
filetype file_array[200];
superblock spblock;

// File system operations
void initialize_superblock();
void tree_to_array(filetype * queue, int * front, int * rear, int * index);
int save_contents();
void initialize_root_directory();
filetype * filetype_from_path(char * path);
int find_free_inode();
int find_free_db();
void add_child(filetype * parent, filetype * child);
static int fsgetattr(const char *path, struct stat *statit);
static int fsmkdir(const char *path, mode_t mode);
int fsreaddir(const char *path, void *buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi );
int fscreate(const char * path, mode_t mode, struct fuse_file_info *fi);
int fsopen(const char *path, struct fuse_file_info *fi);
int fsread(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi);
int fswrite(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi);
static int fsrelease(const char *path, struct fuse_file_info *fi); 

// Error handling
void error(const char* message);

// Implemented file system integration functions
// Implemented FUSE file system functions


static struct fuse_operations fsoperations =
{
    .getattr=fsgetattr,     
    .mkdir=fsmkdir,         
    .readdir=fsreaddir,     
    .open=fsopen,           
    .read=fsread,           
    .create=fscreate,       
    .write=fswrite,         
    .release=fsrelease,     
};


void* server_thread(void* arg) {
    int port = *((int*) arg);
    int socket_desc, client_sock, c;
    struct sockaddr_in server, client;
    
    // Create socket
    socket_desc = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_desc == -1) {
        perror("Could not create socket");
        pthread_exit(NULL);
    }
    
    // Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(port);
    
    // Bind
    if( bind(socket_desc,(struct sockaddr *)&server, sizeof(server)) < 0) {
        perror("bind failed. Error");
        close(socket_desc);
        pthread_exit(NULL);
    }
    
    // Listen
    if (listen(socket_desc, 3) < 0) {
        perror("listen failed");
        close(socket_desc);
        pthread_exit(NULL);
    }
    
    // Accept and handle incoming connections
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);
    
    while (1) {
        // Accept connection from an incoming client
        client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
        if (client_sock < 0) {
            perror("accept failed");
            continue;
        }
        printf("Connection accepted on port %d\n", port);
        
        // Create a new thread to handle client request
        pthread_t client_thread;
        if (pthread_create(&client_thread, NULL, handle_client, (void*)(intptr_t)client_sock) != 0) {
            perror("Failed to create client thread");
            close(client_sock);
            continue;
        }
        
        // Detach the client thread
        pthread_detach(client_thread);
    }
    
    // Close server socket before exiting
    close(socket_desc);
    pthread_exit(NULL);
}


// Function to handle client request
void* handle_client(void* arg) {
    int client_sock = (intptr_t)arg;
    int read_size;
    char client_message[MAX_MESSAGE_SIZE];
    
    // Receive a message from client
    while ((read_size = recv(client_sock , client_message , sizeof(client_message) , 0)) > 0 ) {
        // Parse the received message (assuming format: "OPERATION filename")
        char operation[MAX_MESSAGE_SIZE];
        char filename[MAX_MESSAGE_SIZE];

        if (sscanf(client_message, "%s %s", operation, filename) != 2) {
            // Invalid request format, send error response
            const char *error_message = "Invalid request format";
            if (write(client_sock, error_message, strlen(error_message)) < 0) {
                perror("Error writing to client socket");
            }
            close(client_sock);
            return NULL;
        }

        if (strcmp(operation, "OPEN") == 0) {
            // Handle open file request
            int file_descriptor = open_file(filename);

            if (file_descriptor < 0) {
                // Send error message indicating file not found or other error
                const char *error_message = "File not found or error occurred";
                if (write(client_sock, error_message, strlen(error_message)) < 0) {
                    perror("Error writing to client socket");
                }
            } else {
                // Send success message and file descriptor
                if (write(client_sock, &file_descriptor, sizeof(file_descriptor)) < 0) {
                    perror("Error writing to client socket");
                    close(client_sock);
                    // close_file(file_descriptor); // Close the file before exiting
                    return NULL;
                }
            }
        } else if (strcmp(operation, "READ") == 0) {
            // Handle read file request
            // Read file contents and send them to the client
            char buffer[MAX_MESSAGE_SIZE];
            ssize_t bytes_read;
            while ((bytes_read = read_file(filename, buffer, sizeof(buffer), 0, NULL)) > 0) {
                // Send file contents to client
                if (write(client_sock, buffer, bytes_read) < 0) {
                    perror("Error writing to client socket");
                    close(client_sock);
                    // close_file(file_descriptor); // Close the file before exiting
                    return NULL;
                }
            }
            if (bytes_read < 0) {
                // Error reading file, send error message to client
                const char *error_message = "Error reading file";
                if (write(client_sock, error_message, strlen(error_message)) < 0) {
                    perror("Error writing to client socket");
                }
            }
        } else if (strcmp(operation, "CLOSE") == 0) {
            // Handle close file request
            int file_descriptor;
            if (sscanf(client_message, "%s %d", operation, &file_descriptor) != 2) {
                const char *error_message = "Invalid request format";
                if (write(client_sock, error_message, strlen(error_message)) < 0) {
                    perror("Error writing to client socket");
                }
                close(client_sock);
                return NULL;
            }
        }

        
    }
    
    if(read_size == 0) {
        puts("Client disconnected");
        fflush(stdout);
    } else if(read_size < 0) {
        perror("recv failed");
    }
    
    close(client_sock); // Close the client socket
    
    return NULL;
}


void initialize_filesystem() {
    FILE *fd = fopen("file_structure.bin", "rb");
    if (fd) {
        printf("LOADING\n");
        fread(&file_array, sizeof(filetype)*31, 1, fd);

        int child_startindex = 1;
        file_array[0].parent = NULL;

        for (int i = 0; i < 6; i++) {
            file_array[i].num_children = 0;
            file_array[i].children = NULL;
            for (int j = child_startindex; j < child_startindex + 5; j++) {
                if (file_array[j].valid) {
                    add_child(&file_array[i], &file_array[j]);
                }
            }
            child_startindex += 5;
        }

        root = &file_array[0];

        FILE *fd1 = fopen("super.bin", "rb");
        fread(&spblock, sizeof(superblock), 1, fd1);
    } else {
        initialize_superblock();
        initialize_root_directory();
    }
}

主函数代码

int main(int argc, char *argv[]) {
    // Initialize the file system
    initialize_filesystem();

    // Check if DFS tree initialization failed
    if (root == NULL) {
        fprintf(stderr, "Failed to initialize DFS tree\n");
        return 1;
    }

    // Create and start server threads
    pthread_t server_threads[NUM_SERVERS];
    int ports[NUM_SERVERS];

    for (int i = 0; i < NUM_SERVERS; i++) {
        ports[i] = BASE_PORT + i;
        if (pthread_create(&server_threads[i], NULL, server_thread, (void*)&ports[i]) != 0) {
            perror("Failed to create server thread");
            return 1;
        }
        printf("Server %d started on port %d\n", i+1, ports[i]);
    }

    // Wait for server threads to finish
    for (int i = 0; i < NUM_SERVERS; i++) {
        pthread_join(server_threads[i], NULL);
    }

    // Start the FUSE filesystem after the server threads are created
    struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
    int fuse_ret = fuse_main(args.argc, args.argv, &fsoperations, NULL);
    fuse_opt_free_args(&args);

    if (fuse_ret != 0) {
        fprintf(stderr, "Fuse filesystem exited with error code %d\n", fuse_ret);
        return fuse_ret;
    }

    return 0;
}
解决方案

1. 修复主函数执行顺序(核心问题)

当前代码中pthread_join会阻塞主线程,等待服务器线程结束,但服务器线程是无限循环(while(1)),导致主线程永远无法执行到fuse_main,FUSE文件系统根本没启动。

修改后的主函数:

int main(int argc, char *argv[]) {
    // Initialize the file system
    initialize_filesystem();

    // Check if DFS tree initialization failed
    if (root == NULL) {
        fprintf(stderr, "Failed to initialize DFS tree\n");
        return 1;
    }

    // Create and start server threads
    pthread_t server_threads[NUM_SERVERS];
    int ports[NUM_SERVERS];

    for (int i = 0; i < NUM_SERVERS; i++) {
        ports[i] = BASE_PORT + i;
        if (pthread_create(&server_threads[i], NULL, server_thread, (void*)&ports[i]) != 0) {
            perror("Failed to create server thread");
            return 1;
        }
        printf("Server %d started on port %d\n", i+1, ports[i]);
        // 线程已设置分离,无需等待结束
        pthread_detach(server_threads[i]);
    }

    // 直接启动FUSE文件系统
    struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
    int fuse_ret = fuse_main(args.argc, args.argv, &fsoperations, NULL);
    fuse_opt_free_args(&args);

    if (fuse_ret != 0) {
        fprintf(stderr, "Fuse filesystem exited with error code %d\n", fuse_ret);
        return fuse_ret;
    }

    return 0;
}

2. 修复sudo mount命令错误

使用sudo mount时,fuse.fileServer不是合法的文件系统类型,且sudo环境下当前路径不在PATH中,导致找不到程序。

正确挂载方式:

  • 直接用FUSE自带的挂载命令(推荐):
    sudo ./fileServer -f /home/sena/finalProject_Sena_Senam/dfs
    
  • 或使用绝对路径指定程序:
    sudo mount -t fuse -o allow_other /full/path/to/fileServer /home/sena/finalProject_Sena_Senam/dfs
    

3. 其他注意事项

  • 确保挂载目录为空,且sudo用户拥有读写权限。
  • 编译时必须链接FUSE和pthread库,示例编译命令:
    gcc fileServer.c -o fileServer `pkg-config fuse3 --cflags --libs` -lpthread
    
  • 挂载后可用df -h查看挂载状态,或直接访问挂载目录验证功能。

内容的提问来源于stack exchange,提问作者redhunter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 23:49:51