Skip to content

leo-project/nfs_rpc_server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nfs_rpc_server

An Erlang/OTP library implementing Sun RPC (ONC RPC) protocol as defined in RFC 1057 and RFC 1831.

Overview

nfs_rpc_server provides a complete implementation of the Sun RPC protocol for Erlang applications, including:

  • RPC Server: TCP-based RPC server using Ranch for connection management
  • RPC Client: Full-featured client with timeout handling, retry logic, and statistics
  • XDR Encoding/Decoding: Auto-generated XDR codec from .x specification files
  • Port Mapper Integration: Client interface for rpcbind/portmap daemon (port 111)

This library is designed to be used as a foundation for building NFS servers and other RPC-based services in Erlang.

Requirements

  • Erlang/OTP 24 or later (tested up to OTP 28)
  • rebar3

Dependencies

  • ranch 2.2.0 - Socket acceptor pool
  • erpcgen v0.3.0 - XDR code generator

Build

# Get dependencies and compile
rebar3 compile

# Generate XDR code from .x files and build
make all

# Run tests
rebar3 eunit

# Run cross-reference analysis
rebar3 xref

# Run dialyzer
rebar3 dialyzer

Architecture

Modules

Module Description
nfs_rpc_app Application module, manages RPC server lifecycle
nfs_rpc_server_sup Supervisor for the RPC server
nfs_rpc_proto Ranch protocol handler for incoming RPC requests
nfs_rpc_client gen_server-based RPC client implementation
nfs_rpc_xdr XDR encoder/decoder for RPC messages (generated)
pmap Port mapper client interface
pmap_xdr XDR encoder/decoder for port mapper (generated)

XDR Specification Files

  • src/nfs_rpc.x - RPC message format (RFC 1831)
  • src/pmap.x - Port mapper protocol (RFC 1057)

Usage

Starting the RPC Server

%% Configure the server in sys.config or programmatically
application:set_env(nfs_rpc_server, args, [
    {nfs_rpc_app_arg,
        my_server_ref,      % Unique reference
        128,                % Number of acceptors
        [{port, 2049}],     % Transport options
        100003,             % RPC program number (NFS)
        nfs,                % Program name for callbacks
        [],                 % Version list (auto-generated)
        3,                  % Lowest version
        3,                  % Highest version
        true,               % Register with portmapper
        my_nfs_impl,        % Callback module
        [],                 % Init arguments
        []                  % Initial state
    }
]),

%% Start the application
application:ensure_all_started(nfs_rpc_server).

Implementing RPC Callbacks

Your callback module should implement functions named {program_name}_{version}:

-module(my_nfs_impl).
-export([init/1, nfs_3/5]).

init(Args) ->
    {ok, #state{}}.

%% Called for each RPC procedure call
%% nfs_3(Proc, Msg, Offset, Client, State) -> {success, Reply, NewState}
%%                                          | {noreply, NewState}
%%                                          | {garbage_args, NewState}
%%                                          | {error, NewState}
nfs_3(Proc, Msg, Offset, Client, State) ->
    %% Decode arguments from Msg at Offset
    %% Process the request
    %% Return XDR-encoded reply
    {success, <<Reply/binary>>, State}.

Using the RPC Client

%% Connect to an RPC server (using portmapper)
{ok, Clnt} = nfs_rpc_client:open("server.example.com", 100003, 3, tcp),

%% Or connect directly to a known port
{ok, Clnt} = nfs_rpc_client:open("server.example.com", 100003, 3, tcp, 2049),

%% Make an RPC call
Params = encode_my_params(...),
case nfs_rpc_client:call(Clnt, ProcNum, Params) of
    {ok, Reply} ->
        decode_my_reply(Reply);
    {error, Reason} ->
        handle_error(Reason)
end,

%% Close the client
nfs_rpc_client:close(Clnt).

Client Configuration

%% Set authentication
nfs_rpc_client:set_auth(Clnt, auth_null),
nfs_rpc_client:set_auth(Clnt, {auth_sys, Stamp, Hostname, Uid, Gid, Gids}),

%% Configure timeouts (in seconds)
nfs_rpc_client:set_timeout(Clnt, 30),
nfs_rpc_client:set_retry_timeout(Clnt, 5),

%% Configure queue limits
nfs_rpc_client:set_queue_limit(Clnt, 200),

%% Get statistics
{ok, Stats} = nfs_rpc_client:get_stats(Clnt).

Port Mapper Operations

%% Connect to local portmapper
{ok, PClnt} = pmap:open({127, 0, 0, 1}),

%% Look up a service port
{ok, Port} = pmap:getport(PClnt, Program, Version, tcp),

%% Register a service
{ok, true} = pmap:set(PClnt, Program, Version, tcp, Port),

%% Unregister a service
{ok, true} = pmap:unset(PClnt, Program, Version, tcp, Port),

%% List all registered services
{ok, Mappings} = pmap:dump(PClnt),

pmap:close(PClnt).

Protocol Support

  • RPC Version: 2 (RFC 1831)
  • Transport: TCP (primary), UDP (client only)
  • Authentication: AUTH_NONE, AUTH_SYS
  • Port Mapper: Version 2 (RFC 1057)

License

Apache License, Version 2.0

Copyright

  • Copyright (c) 2012-2018 Rakuten, Inc.
  • Copyright (c) 2019-2025 Lions Data, Ltd.

About

NFS RPC Server for LeoFS NFS Protocol

Resources

License

Stars

Watchers

Forks

Packages

No packages published