libnfs
libnfs copied to clipboard
Segment fault when nfs_opendir.
I got a segment fault occasionally when call nfs_opendir function. I'm using the 2.0.0 release version.
This is the gdb output:
(gdb) bt #0 0x00007ffff7db0b74 in nfs_opendir_cb () from /usr/lib/libnfs.so.11 #1 0x00007ffff7dbb006 in rpc_timeout_scan () from /usr/lib/libnfs.so.11 #2 0x00007ffff7dbb329 in rpc_service () from /usr/lib/libnfs.so.11 #3 0x00007ffff7da7106 in nfs_service () from /usr/lib/libnfs.so.11 #4 0x00007ffff7db5313 in wait_for_nfs_reply () from /usr/lib/libnfs.so.11 #5 0x00007ffff7db6506 in nfs_opendir () from /usr/lib/libnfs.so.11 #6 0x0000000000403478 in nfpi_nfs_scandir (ctx=0x50b010, path=0x408a8a "/test_scan", namelist=0x7fffffffdf48) at mod_nfs.c:251 #7 0x0000000000402958 in nfpi_scandir (ctx=0x50b010, path=0x408a8a "/test_scan", namelist=0x7fffffffdf48) at libnfpi.c:94 #8 0x0000000000402573 in test_scan (url=0x7fffffffe36e "nfs://172.24.137.25/home/share") at test.c:130 #9 0x00000000004025e4 in main (argc=2, argv=0x7fffffffe118) at test.c:140 (gdb) info r rax 0x0 0 rbx 0x7ffff7ffdc20 140737354128416 rcx 0x5137e0 5322720 rdx 0x0 0 rsi 0x3 3 rdi 0x50e100 5300480 rbp 0x7fffffffdd30 0x7fffffffdd30 rsp 0x7fffffffdc50 0x7fffffffdc50 r8 0x7ffff7db0996 140737351715222 r9 0x40000 262144 r10 0x0 0 r11 0x7ffff7178540 140737338901824 r12 0x0 0 r13 0x7fffffffe110 140737488347408 r14 0x0 0 r15 0x0 0 rip 0x7ffff7db0b74 0x7ffff7db0b74 <nfs_opendir_cb+478> eflags 0x10202 [ IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb)
Seams like command_data is NULL and status is RPC_STATUS_TIMEOUT cause a 0 address access at the line "if (res->status != NFS3_OK) {" .
static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { READDIRPLUS3res *res = command_data; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfsdir *nfsdir = data->continue_data; struct entryplus3 *entry; uint64_t cookie = 0;
assert(rpc->magic == RPC_CONTEXT_MAGIC);
if (status == RPC_STATUS_ERROR ||
(status == RPC_STATUS_SUCCESS && res->status == NFS3ERR_NOTSUPP)) {
READDIR3args args;
args.dir = data->fh;
args.cookie = cookie;
memset(&args.cookieverf, 0, sizeof(cookieverf3));
args.count = 8192;
if (rpc_nfs3_readdir_async(nfs->rpc, nfs_opendir2_cb, &args, data) != 0) {
rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path);
data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
nfs_free_nfsdir(nfsdir);
data->continue_data = NULL;
free_nfs_cb_data(data);
return;
}
return;
}
if (status == RPC_STATUS_CANCEL) {
data->cb(-EINTR, nfs, "Command was cancelled", data->private_data);
nfs_free_nfsdir(nfsdir);
data->continue_data = NULL;
free_nfs_cb_data(data);
return;
}
if (res->status != NFS3_OK) {
rpc_set_error(nfs->rpc, "NFS: READDIRPLUS of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status));
data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data);
nfs_free_nfsdir(nfsdir);
data->continue_data = NULL;
free_nfs_cb_data(data);
return;
}
...
The latest code has fixed this issue.
void nfs_opendir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct client *client = private_data; struct nfsdir *nfsdir = data; struct nfsdirent *nfsdirent;
if (status < 0) {
printf("opendir failed with \"%s\"\n", (char *)data);
exit(10);
}
printf("opendir successful\n");
while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) {
printf("Inode:%d Name:%s\n", (int)nfsdirent->inode, nfsdirent->name);
}
nfs_closedir(nfs, nfsdir);
mount_context = rpc_init_context();
if (mount_getexports_async(mount_context, client->server, mount_export_cb, client) != 0) {
printf("Failed to start MOUNT/EXPORT\n");
exit(10);
}
}