整合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
相关产品推荐
相关产品推荐

