API: RCF RPC

Overview

// typedefs

typedef struct rcf_rpc_server rcf_rpc_server;
typedef struct vfork_thread_data vfork_thread_data;
typedef struct rcf_rpc_server_hook rcf_rpc_server_hook;

// structs

struct rcf_rpc_server;
struct rcf_rpc_server_hook;
struct vfork_thread_data;

// global functions

te_errno rcf_rpc_server_get(const char* ta, const char* name, const char* father, int flags, rcf_rpc_server** p_handle);
static te_errno rcf_rpc_server_create(const char* ta, const char* name, rcf_rpc_server** p_handle);
static te_errno rcf_rpc_server_thread_create(rcf_rpc_server* rpcs, const char* name, rcf_rpc_server** p_new);
static te_errno rcf_rpc_server_fork(rcf_rpc_server* rpcs, const char* name, rcf_rpc_server** p_new);
static te_errno rcf_rpc_server_fork_exec(rcf_rpc_server* rpcs, const char* name, rcf_rpc_server** p_new);
te_errno rcf_rpc_server_create_process(rcf_rpc_server* rpcs, const char* name, int flags, rcf_rpc_server** p_new);
te_errno rcf_rpc_server_vfork(rcf_rpc_server* rpcs, const char* name, uint32_t time_to_wait, pid_t* pid, uint32_t* elapsed_time);
te_errno rcf_rpc_server_vfork_in_thread(vfork_thread_data* data, pthread_t* thread_id, rcf_rpc_server** p_new);
te_errno rcf_rpc_server_exec(rcf_rpc_server* rpcs);
te_errno rcf_rpc_setlibname(rcf_rpc_server* rpcs, const char* libname);
static te_errno rcf_rpc_server_restart(rcf_rpc_server* rpcs);
te_errno rcf_rpc_servers_restart_all(void);
te_errno rcf_rpc_server_destroy(rcf_rpc_server* rpcs);
static te_errno rcf_rpc_server_dead(rcf_rpc_server* rpcs);
static te_errno rcf_rpc_server_finished(rcf_rpc_server* rpcs);
void rcf_rpc_call(rcf_rpc_server* rpcs, const char* proc, void* in_arg, void* out_arg);
te_errno rcf_rpc_server_is_op_done(rcf_rpc_server* rpcs, te_bool* done);
te_bool rcf_rpc_server_is_alive(rcf_rpc_server* rpcs);
static void rcf_rpc_free_result(void* out_arg, xdrproc_t out_proc);
static const char* rpcop2str(rcf_rpc_op op);
te_bool rcf_rpc_server_has_children(rcf_rpc_server* rpcs);
void rcf_rpc_namespace_free_cache(rcf_rpc_server* rpcs);
te_errno rcf_rpc_namespace_id2str(rcf_rpc_server* rpcs, rpc_ptr_id_namespace id, char** str);
typedef SLIST_HEAD(rcf_rpc_server_hook);
te_errno rcf_rpc_server_hook_register(void(*)(rcf_rpc_server*rpcs) hook_to_register);

// macros

#define RCF_RPC_DEFAULT_TIMEOUT
#define RCF_RPC_UNSPEC_TIMEOUT
#define RPC_AWAITING_ERROR(_rpcs)
#define RPC_AWAIT_ERROR(_rpcs)
#define RPC_AWAIT_IUT_ERROR(_rpcs)
#define RPC_DONT_AWAIT_ERROR(_rpcs)
#define RPC_DONT_AWAIT_IUT_ERROR(_rpcs)
#define RPC_ERRNO(_rpcs)
#define RPC_ERROR_ARGS(_rpcs)
#define RPC_ERROR_FMT
#define RPC_ERROR_MSG(_rpcs)
#define RPC_IS_CALL_OK(_rpcs)
#define RPC_NAME(rpcs_)
#define TEST_GET_RPCS(_ta, _name, _rpcs)
#define TEST_GET_RPCS_SAFE(_ta, _name, _rpcs)

Detailed Documentation

Typedefs

typedef struct rcf_rpc_server rcf_rpc_server

RPC server context

typedef struct vfork_thread_data vfork_thread_data

Input/output parameters for rcf_rpc_server_vfork() called in a thread.

Global Functions

te_errno rcf_rpc_server_get(const char* ta, const char* name, const char* father, int flags, rcf_rpc_server** p_handle)

Obtain server handle. RPC server is created/restarted, if necessary.

Parameters:

ta

Test Agent name

name

name of the new server (should not start from fork_, forkexec_ or thread_) or existing server

father

father name or NULL (should be NULL if RCF_RPC_SERVER_GET_REUSE or RCF_RPC_SERVER_GET_EXISTING flag is set).

flags

RCF_RPC_SERVER_GET_* flags

p_handle

location for new RPC server handle or NULL

Returns:

Status code

static te_errno rcf_rpc_server_create(const char* ta, const char* name, rcf_rpc_server** p_handle)

Create RPC server.

Parameters:

ta

Test Agent name

name

name of the new server

p_handle

location for new RPC server handle

Returns:

Status code

static te_errno rcf_rpc_server_thread_create(rcf_rpc_server* rpcs, const char* name, rcf_rpc_server** p_new)

Create thread in the process with RPC server.

Parameters:

rpcs

existing RPC server handle

name

name of the new server

p_new

location for new RPC server handle

Returns:

Status code

static te_errno rcf_rpc_server_fork(rcf_rpc_server* rpcs, const char* name, rcf_rpc_server** p_new)

Fork RPC server.

Parameters:

rpcs

existing RPC server handle

name

name of the new server

p_new

location for new RPC server handle

Returns:

Status code

static te_errno rcf_rpc_server_fork_exec(rcf_rpc_server* rpcs, const char* name, rcf_rpc_server** p_new)

Fork-and-exec RPC server.

Parameters:

rpcs

existing RPC server handle

name

name of the new server

p_new

location for new RPC server handle

Returns:

Status code

te_errno rcf_rpc_server_create_process(rcf_rpc_server* rpcs, const char* name, int flags, rcf_rpc_server** p_new)

Fork RPC server with non-default conditions.

Parameters:

rpcs

existing RPC server handle

name

name of the new server

flags

RCF_RPC_SERVER_GET_* flags to use on process creation

p_new

location for new RPC server handle

Returns:

Status code

te_errno rcf_rpc_server_vfork(rcf_rpc_server* rpcs, const char* name, uint32_t time_to_wait, pid_t* pid, uint32_t* elapsed_time)

Call vfork() in RPC server.

Parameters:

rpcs

Existing RPC server handle

name

Name of the new server

time_to_wait

How much time to wait after vfork() call

pid

If not NULL, will be set to result of vfork() call

elapsed_time

Time elapsed until vfork() returned

Returns:

Status code

te_errno rcf_rpc_server_vfork_in_thread(vfork_thread_data* data, pthread_t* thread_id, rcf_rpc_server** p_new)

Call rcf_rpc_server_vfork() in a new thread.

Parameters:

data

Data to be passed to the thread

thread_id

Where to save an ID of the created thread

p_new

Where to save an ID of the created RPC server

Returns:

Status code

te_errno rcf_rpc_server_exec(rcf_rpc_server* rpcs)

Perform execve() on the RPC server. Filename of the running process if used as the first argument.

Parameters:

rpcs

RPC server handle

Returns:

Status code

te_errno rcf_rpc_setlibname(rcf_rpc_server* rpcs, const char* libname)

Set dynamic library name to be used for additional name resolution.

Parameters:

rpcs

existing RPC server handle

libname

name of the dynamic library or NULL

Returns:

Status code

static te_errno rcf_rpc_server_restart(rcf_rpc_server* rpcs)

Restart RPC server.

Parameters:

rpcs

RPC server handle

Returns:

Status code

te_errno rcf_rpc_servers_restart_all(void)

Restart all RPC servers.

This function has a lot of limitations. It does not work when fork child and thread RPC servers exist. It does not preserve name of the dynamic library to be used for functions name to pointer resolution.

Returns:

Status code.

te_errno rcf_rpc_server_destroy(rcf_rpc_server* rpcs)

Destroy RPC server. The caller should assume the RPC server non-existent even if the function returned non-zero.

Parameters:

rpcs

RPC server handle

Returns:

status code

static te_errno rcf_rpc_server_dead(rcf_rpc_server* rpcs)

Mark RPC server as dead to force its killing by rcf_rpc_server_destroy().

Parameters:

rpcs

RPC server handle

Returns:

Status code

static te_errno rcf_rpc_server_finished(rcf_rpc_server* rpcs)

Mark RPC server as finished (i.e. it was terminated and waitpid() or pthread_join() was already called - so only associated data structures remained to be freed on TA).

Parameters:

rpcs

RPC server handle

Returns:

Status code

void rcf_rpc_call(rcf_rpc_server* rpcs, const char* proc, void* in_arg, void* out_arg)

Call SUN RPC on the TA via RCF. The function is also used for checking of status of non-blocking RPC call and waiting for the finish of the non-blocking RPC call.

The Status code is returned in rpcs _errno. If rpcs is NULL the function does nothing.

Parameters:

rpcs

RPC server

proc

RPC to be called

in_arg

input argument

out_arg

output argument

te_errno rcf_rpc_server_is_op_done(rcf_rpc_server* rpcs, te_bool* done)

Check whether a function called using non-blocking RPC has been done.

Parameters:

rpcs

existing RPC server handle

done

location for the result

Returns:

Status code

te_bool rcf_rpc_server_is_alive(rcf_rpc_server* rpcs)

Check whether RPC server is alive.

Parameters:

rpcs

existing RPC server handle

Returns:

TRUE or FALSE

static void rcf_rpc_free_result(void* out_arg, xdrproc_t out_proc)

Free memory allocated by rcf_rpc_call

static const char* rpcop2str(rcf_rpc_op op)

Convert RCF RPC operation to string.

Parameters:

op

RCF RPC operation

Returns:

null-terminated string

te_bool rcf_rpc_server_has_children(rcf_rpc_server* rpcs)

Check is the RPC server has thread children.

Parameters:

rpcs

RPC server

Returns:

TRUE if RPC server has children

void rcf_rpc_namespace_free_cache(rcf_rpc_server* rpcs)

Free namespace cache

Parameters:

rpcs

RPC server

te_errno rcf_rpc_namespace_id2str(rcf_rpc_server* rpcs, rpc_ptr_id_namespace id, char** str)

Convert namespace id to its name.

Parameters:

rpcs

RPC server

id

namespace id

str

namespace as string

Returns:

Status code

te_errno rcf_rpc_server_hook_register(void(*)(rcf_rpc_server*rpcs) hook_to_register)

Add new hook to rcf_rpc_server_hook_list, that will be executed after rcf_rpc_server is created.

Parameters:

hook_to_register

Function to execute

Returns:

Status code

Macros

#define RCF_RPC_DEFAULT_TIMEOUT

Default RPC timeout in milliseconds

#define RCF_RPC_UNSPEC_TIMEOUT

Unspecified RPC timeout in milliseconds

#define RPC_AWAITING_ERROR(_rpcs)

Are we awaiting an error?

#define RPC_AWAIT_ERROR(_rpcs)

Do not jump from the TAPI RPC library call in the case of any error

#define RPC_AWAIT_IUT_ERROR(_rpcs)

Do not jump from the TAPI RPC library call in the case of IUT error

#define RPC_DONT_AWAIT_ERROR(_rpcs)

Roll back RPC_AWAIT_ERROR effect

#define RPC_DONT_AWAIT_IUT_ERROR(_rpcs)

Roll back RPC_AWAIT_IUT_ERROR effect

#define RPC_ERRNO(_rpcs)

Return RPC server context errno

#define RPC_ERROR_ARGS(_rpcs)

Arguments for RPC_ERROR_FMT.

Parameters:

_rpcs

Pointer to rcf_rpc_server structure.

#define RPC_ERROR_FMT

Format string for logging RPC server error (both number and message)

#define RPC_ERROR_MSG(_rpcs)

Get RPC error message.

Parameters:

_rpcs

Pointer to rcf_rpc_server structure.

#define RPC_IS_CALL_OK(_rpcs)

Check, if RPC is called successfully

#define RPC_NAME(rpcs_)

Extract name of the PCO by RCP server handle

Parameters:

rpcs_

  • RPC server handle

Returns:

Name of the PCO

#define TEST_GET_RPCS(_ta, _name, _rpcs)

Get RPC server handle, restart it if necessary.

Parameters:

_ta

name of Test Agent

_name

name of RCF RPC server

_rpcs

variable for RPC server handle

#define TEST_GET_RPCS_SAFE(_ta, _name, _rpcs)

Get RPC server handle, restart it if necessary. Don’t fail.

Parameters:

_ta

name of Test Agent

_name

name of RCF RPC server

_rpcs

variable for RPC server handle