结合 fuse 和 rpc 来列出远程目录
Posted
技术标签:
【中文标题】结合 fuse 和 rpc 来列出远程目录【英文标题】:combine fuse and rpc for remote directory listing 【发布时间】:2013-12-23 15:15:06 【问题描述】:我正在开发一个带有 fuse 的自定义文件系统。我想要做的是从远程服务器读取目录的内容并将它们列出在挂载点中。我的 rpc 程序运行良好。但是当我尝试将它与 rpc 结合时,它出现了一些构建错误。我正在使用 rpcgen 创建我的 rpc 程序,但我不知道应该如何将它们一起构建。
这是我的 cfs_client.c:
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
gcc -Wall cfs.c `pkg-config fuse --cflags --libs` -o cfs
*/
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "cfs.h"
static const char *cfs_str = "Hello World!\n";
static const char *cfs_path = "/cfs";
static int cfs_getattr(const char *path, struct stat *stbuf)
int res = 0;
memset(stbuf, 0, sizeof (struct stat));
if (strcmp(path, "/") == 0)
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
else if (strcmp(path, cfs_path) == 0)
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(cfs_str);
else
res = -ENOENT;
return res;
static int cfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
(void) offset;
(void) fi;
char *host = "localhost";
char *dirname = "/home/hamed/test";
CLIENT *clnt;
readdir_res *result_1;
if (strcmp(path, "/") != 0)
return -ENOENT;
#ifndef DEBUG
clnt = clnt_create(host, CFSPROG, CFSVERS, "udp");
if (clnt == NULL)
clnt_pcreateerror(host);
exit(1);
#endif /* DEBUG */
result_1 = readdir_1(&dirname, clnt);
if (result_1 == (readdir_res *) NULL)
clnt_perror(clnt, "call failed");
namelist nl;
nl = result_1->readdir_res_u.list;
while (nl)
printf("dirname = %s\n", nl->name);
filler(buf, nl->name, NULL, 0);
nl = nl->next;
#ifndef DEBUG
clnt_destroy(clnt);
#endif /* DEBUG */
return 0;
static int cfs_open(const char *path, struct fuse_file_info *fi)
if (strcmp(path, cfs_path) != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
static int cfs_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
size_t len;
(void) fi;
if (strcmp(path, cfs_path) != 0)
return -ENOENT;
len = strlen(cfs_str);
if (offset < len)
if (offset + size > len)
size = len - offset;
memcpy(buf, cfs_str + offset, size);
else
size = 0;
return size;
static struct fuse_operations cfs_oper =
.getattr = cfs_getattr,
.readdir = cfs_readdir,
.open = cfs_open,
.read = cfs_read,
;
int main(int argc, char *argv[])
return fuse_main(argc, argv, &cfs_oper, NULL);
这是我的 cfs_server.c:
/*
* This is sample code generated by rpcgen.
* These are only templates and you can use them
* as a guideline for developing your own functions.
*/
#include "cfs.h"
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <rpc/pmap_clnt.h>
readdir_res * readdir_1_svc(nametype *dirname, struct svc_req *rqstp)
DIR *dp;
struct dirent *directory;
static readdir_res result;
int inode;
namelist nl;
namelist *nlp;
dp = opendir(*dirname);
if (dp != NULL)
nlp = &result.readdir_res_u.list;
while (directory = readdir(dp))
nl = *nlp = (namenode *) malloc(sizeof (namenode));
nl->name = directory->d_name;
nlp = &nl->next;
*nlp = NULL;
result.errnum = 0;
closedir(dp);
return &result;
这是我使用的制作文件:
# This is a template Makefile generated by rpcgen
# Parameters
CLIENT = cfs_client
SERVER = cfs_server
SOURCES_CLNT.c =
SOURCES_CLNT.h =
SOURCES_SVC.c =
SOURCES_SVC.h =
SOURCES.x = cfs.x
TARGETS_SVC.c = cfs_svc.c cfs_server.c cfs_xdr.c
TARGETS_CLNT.c = cfs_clnt.c cfs_client.c cfs_xdr.c
TARGETS = cfs.h cfs_xdr.c cfs_clnt.c cfs_svc.c cfs_client.c cfs_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
CFLAGS += -g -Wall -DRPC_SVC_FG $(shell pkg-config fuse --cflags --libs)
LDLIBS += -lnsl
RPCGENFLAGS = -g
# 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)
编辑: 错误是:
root@debian:/programs/c/rpc/custom file system# make -f Makefile.cfs
rpcgen -g cfs.x
usage: rpcgen infile
rpcgen [-abkCLNTM][-Dname[=value]] [-i size] [-I [-K seconds]] [-Y path] infile
rpcgen [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] [-o outfile] [infile]
rpcgen [-s nettype]* [-o outfile] [infile]
rpcgen [-n netid]* [-o outfile] [infile]
options:
-a generate all files, including samples
-b backward compatibility mode (generates code for SunOS 4.1)
-c generate XDR routines
-C ANSI C mode
-Dname[=value] define a symbol (same as #define)
-h generate header file
-i size size at which to start generating inline code
-I generate code for inetd support in server (for SunOS 4.1)
-K seconds server exits after K seconds of inactivity
-l generate client side stubs
-L server errors will be printed to syslog
-m generate server side stubs
-M generate MT-safe code
-n netid generate server code that supports named netid
-N supports multiple arguments and call-by-value
-o outfile name of the output file
-s nettype generate server code that supports named nettype
-Sc generate sample client code that uses remote procedures
-Ss generate sample server code that defines remote procedures
-Sm generate makefile template
-t generate RPC dispatch table
-T generate code to support RPC dispatch tables
-Y path directory name to find C preprocessor (cpp)
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
make: *** [cfs_clnt.c] Error 1
【问题讨论】:
"...但是当我尝试将它与 rpc 结合使用时,出现了一些构建错误";那是什么构建错误? 我通过添加构建错误来编辑我的问题。 【参考方案1】:我已经通过使用 bash 文件解决了我的问题。这是我的脚本,给那些可能和我有同样问题的人:
cc -g -c -o cfs_clnt.o cfs_clnt.c
cc -g -D_FILE_OFFSET_BITS=64 -c -o cfs_client.o cfs_client.c
cc -g -c -o cfs_xdr.o cfs_xdr.c
cc -g -o cfs_client cfs_clnt.o cfs_client.o cfs_xdr.o -lnsl -Wall `pkg-config fuse --cflags --libs`
cc -g -c -o cfs_svc.o cfs_svc.c
cc -g -c -o cfs_server.o cfs_server.c
cc -g -o cfs_server cfs_svc.o cfs_server.o cfs_xdr.o -lnsl
【讨论】:
以上是关于结合 fuse 和 rpc 来列出远程目录的主要内容,如果未能解决你的问题,请参考以下文章