Table of Contents

Name

linx - LINX inter-process communication protocol

Synopsis

#include <linx.h>
#include <linx_socket.h>
#include <linx_ioctl.h>
#include <linx_types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

Description

LINX is a location transparent inter-process communication protocol. It is based on the message passing technology used in the Enea OSE family of real time operating systems.

LINX consists of a set of kernel modules and provides a standard socket based interface using its own protocol family, PF_LINX. There is also a LINX library that provides a more advanced messaging API. Applications normally access LINX through this library, but sometimes direct access via the socket interface may be necessary.

Linx Concepts

An application that wants to communicate using LINX must first create a LINX endpoint. One thread may own multiple LINX endpoints simultaneously. A LINX endpoint is created with a non-unique name (a string). A handle which is used to refer to the endpoint in subsequent calls is returned to the application.

LINX endpoints communicate by sending and receiving LINX signals. The properties of LINX signals are described below.

Each LINX endpoint has a binary identifier called a spid which is unique within the node. A sending endpoint must know the spid of the destination endpoint to be able to communicate. The spid of a peer LINX endpoint is normally obtained by hunting for its name. When an endpoint with a matching name is found or created, LINX sends a hunt signal back to the hunting endpoint that appears to have been sent from the found endpoint. The spid can thus be obtained by looking at the sender of this signal.

A LINX endpoint can supervise, or attach to, the spid of a peer endpoint in order to be notified by a LINX signal when it is terminated or becomes unreachable.

The communication path between two LINX nodes is called a LINX link. A LINX link is created with a name string, and the same link may have different names on the opposite nodes, i.e. the link between nodes A and B may be called "LinkToB" on A, and "LinkToA" on B.

When hunting for an endpoint on a remote node, the name of the endpoint is prepended with the path of link names needed to reach the node, e.g. "LinkToB/LinkToC/EndpointName". LINX will create a virtual endpoint that acts as a local representation of the remote endpoint. LINX signals sent to the spid of a virtual endpoint are automatically routed to the proper destination on the remote node.

When a LINX endpoint is closed, its owned LINX signals are freed.

It is not allowed to use a LINX endpoint from two contexts at the same time. When a Linux process has multiple threads, it is not allowed to access a LINX endpoint from other contexts than the one that opened it. When fork(2) is called, the child process inherits copies of the parents socket related resources, including LINX endpoints. In this case, either the parent or the child shall close its LINX endpoints. A LINX endpoint is not removed until it has been closed by all of its owners.

LINX Application Interfaces

LINX provides both a standard socket interface and a more advanced LINX API which is available through the LINX library, to be linked with the application. The LINX API is the recommended way for applications to access LINX, since it simplifies for the programmer by abstracting the direct socket interactions. It implements a set of functions specified in linx.h(3) .

The LINX socket interface is the underlying socket implementation provided by the LINX kernel module and is used by the LINX library. It is described in detail below.

It is possible for applications to use a combination of the LINX API and the LINX socket interface. In this case, the LINX API function linx_get_descriptor(3) can be used to obtain the socket descriptor of a LINX endpoint. This descriptor can be used together with other file descriptors in generic poll(2) or select(2) calls. Note that it is NOT allowed to call close(2) on a LINX socket descriptor obtained by a linx_get_descriptor(3) call.

LINX Signals

A LINX signal consists of a mandatory leading 4-byte signal number, optionally followed by data. Thus, the size of a LINX signal buffer must be at least 4 bytes. LINX signal numbers are of type LINX_SIGSELECT. Signal numbers are mainly defined by the applications, but a few values are not allowed. Zero (0) is illegal and must not be used and 250-255 are reserved by LINX.

LINX provides endian conversion of the signal number if needed when a signal is sent to a remote node. The signal data is not converted.

LINX Socket Interface

The LINX socket interface allows application programmers to access LINX using standard socket calls. It should be noted that only a subset of the socket calls are implemented and that additional features have been made available through ioctl calls. These deviations and features are described below.

struct sockaddr_linx
When using the socket interface directly, a LINX endpoint is represented by a sockaddr_linx structure:


struct sockaddr_linx
{
        sa_family_t family;
        LINX_SPID   spid;
};

family shall be AF_LINX and spid is the spid of the LINX endpoint. The sockaddr_linx structure is type-casted into a generic sockaddr structure when passed to the socket interface function calls.


The following calls are provided by the LINX socket interface:

socket()
A LINX socket is created by calling the socket(2) function as:

linx_sd = socket(PF_LINX, SOCK_DGRAM, 0);

When a LINX socket is created, its name is unspecified. To assign a name to the socket, use the LINX_IOCTL_HUNTNAME ioctl request.

On success, the return value is a descriptor referencing the socket. On error, -1 is returned and errno is set to one of the following values:

EPROTONOTSUPPORTED
The protocol type is not supported. Only PF_LINX is accepted.

ESOCKTNOSUPPORT
The socket type is not supported. Only SOCK_DGRAM is accepted.

ENOMEM
Insufficient memory is available. Alternatively, the maximum number of spids has been reached. This value is configurable as a parameter to the LINX kernel module, see LINX Users Guide for more information.

sendto()
The sendto(2) function is called as:

len = sendto(linx_sd, payload, size, 0, (struct sockaddr*) &sockaddr_linx, sizeof(struct sockaddr_linx));

The payload shall be a LINX signal buffer and size shall be its length in bytes. Note that it is mandatory for a LINX signal to have a leading 4 byte signal number. The spid field of the sockaddr_linx structure shall be the spid of the destination endpoint.

On success, the number of bytes sent is returned. On error, -1 is returned and errno is set to one of the following values:

EBADF
An invalid descriptor was specified.

ECONNRESET
The destination endpoint has been killed.

EINVAL
Invalid argument passed.

ENOMEM
Insufficient memory is available.

EOPNOTSUPP
The sending LINX socket has not been assigned a name.

EPIPE
This error is reported at an attempt to send to the spid of a LINX endpoint that is being closed as the call occurs.

sendmsg()
The sendmsg(2) function is called as:

len = sendmsg(linx_sd, *msg, 0);

msg is a msghdr structure as defined in sendmsg(2) . The msg_iov field of the msghdr structure shall point to an iovec structure containing the LINX signal buffer to transmit and the msg_iovlen field shall be set to 1. Note that it is mandatory for a LINX signal to have a leading 4 byte signal number. The msg_name field shall be a pointer to a sockaddr_linx structure containing the spid of the destination endpoint and the msg_namelen field shall be set to the size of the sockaddr_linx structure. The ancillary fields and the flags field of the msghdr structure shall not be used and be set to zero.

On success, the number of bytes sent is returned. On error, -1 is returned and errno is set to one of the following values:

EBADF
An invalid descriptor was specified.

ECONNRESET
The destination endpoint has been killed. Note that this case is accepted and the signal is silently discarded by LINX.

EINVAL
Invalid argument passed.

ENOMEM
Insufficient memory is available.

EOPNOTSUPP
The sending socket has not been assigned a name.

EPIPE
This error is reported at an attempt to send to the spid of a LINX endpoint that is being closed as the call occurs.

recvfrom()
The recvfrom(2) function is called as:

len = recvfrom(linx_sd, payload, size, 0, (struct sockaddr*) &sockaddr_linx, sizeof(struct sockaddr_linx));

It is used to receive any LINX signal from any LINX endpoint. It can not be used when signal number filtering and/or sender filtering is needed, see recvmsg(2) . The first signal in the sockets receive queue is returned in the supplied payload buffer. If no signal is currently available at the socket, the call blocks until a signal is received. The sender of the signal is returned in the sockaddr_linx structure. Note that the size of the payload buffer must be at least 4 bytes, since it is mandatory for a LINX signal to have a 4 byte leading signal number.

On success, the number of bytes received is returned. If the received signal is larger than the supplied payload buffer, zero is returned and the signal buffer size is written as a 32-bit value in the first 4 bytes of the payload buffer. On error, -1 is returned and errno is set to one of the following values:

EBADF
An invalid descriptor was specified.

EFAULT
Invalid payload buffer pointer provided.

EINVAL
Invalid argument passed.

ENOMEM
Insufficient memory is available.

EOPNOTSUPP
The receiving socket has not been assigned a name.

recvmsg()
The recvmsg(2) function is called as:

len = recvmsg(sd, msg, 0);

msg is a pointer to a msghdr structure as defined in recvmsg(2) . A LINX signal buffer shall be supplied in an iovec structure pointed to from the msg_iov field and the msg_iovlen field shall be set to 1. Note that the size of the supplied buffer must be at least 4 bytes, since it is mandatory for a LINX signal to have a 4 byte leading signal number.

The recvmsg(2) call supports signal number filtering and sender filtering. This allows the user to specify which signal numbers shall be received and/or from which sender. The signal filter is described by a linx_receive_filter_param structure:


struct linx_receive_filter_param
{
        LINX_SPID             from;
        LINX_OSBUFSIZE        sigselect_size;
        const LINX_SIGSELECT *sigselect;
};

The from field specifies that only signals from a specific spid should be received and sigselect is an array of LINX_SIGSELECT numbers to be received. The first position in the array contains the number of entries in the list that follows. If the first position is set to a negative count, all LINX signals except those listed will be received. The size of the array is sigselect_size.

The filtering uses ancillary fields in the msghdr structure and is described by the following example code:


struct msghdr msg;
char cmsg[CMSG_SPACE(sizeof(struct linx_receive_filter_param))];
struct linx_receive_filter_param * rfp;
struct iovec iov;
const LINX_SIGSELECT sig_sel[] = { 1, EXAMPLE_SIG };
rfp = ((struct linx_receive_filter_param *)
        (CMSG_DATA(((struct cmsghdr *)cmsg))));
rfp->sigselect_size = sizeof(sig_sel);
rfp->from = from_spid;
rfp->sigselect = sig_sel;
msg.msg_name = (void*)&linx_addr;
msg.msg_namelen = sizeof(struct sockaddr_linx);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_flags = 0;
msg.msg_control = cmsg;
msg.msg_controllen =
        CMSG_SPACE(sizeof(struct linx_receive_filter_param));
((struct cmsghdr *)cmsg)->cmsg_len = msg.msg_controllen;
((struct cmsghdr *)cmsg)->cmsg_level = 0;
((struct cmsghdr *)cmsg)->cmsg_type = 0;
iov.iov_base = *signal;
iov.iov_len = sigsize;
read_size = recvmsg(linx->socket, &msg, 0);

On success, the number of bytes received is returned. If the received signal is larger than the supplied payload buffer, zero is returned and the signal buffer size is written as a 32-bit value in the first 4 bytes of the payload buffer. On error, -1 is returned and errno is set to one of the following values:

EBADF
An invalid descriptor was specified.

EFAULT
An invalid msghdr structure was provided.

EINVAL
Invalid argument passed.

ENOMEM
Insufficient memory is available.

EOPNOTSUPP
The sending socket has not been assigned a name.

poll()
LINX socket descriptors can be used in the poll(2) call.

The call returns a bitmask that indicates the state of the LINX socket receive queues. The following possible bits can be set at return from this function: POLLERR if the LINX socket is in an error state, POLLHUP if the LINX socket has been shutdown/released, POLLIN and POLLRDNORM if the LINX socket has data to read in receive queue.

select()
LINX socket descriptors can be used together with other file descriptors in the select(2) call.

ioctl()
IOCTL requests are sent to a LINX socket using the ioctl(2) call. See below for all IOCTL request codes supported by LINX sockets.

close()
A LINX socket created by a socket(2) call can be closed with close(2) . Note that this function shall NOT be used on any LINX socket descriptor created with linx_open(3) or obtained by the LINX API function linx_get_descriptor(3) .

On success, 0 is returned, otherwise -1 is returned and errno can be one of the following errors:

EBADF
An invalid descriptor was specified.

Only the calls described above are supported by a LINX socket. The following are NOT supported on LINX sockets and shall not be used: bind(2) , connect(2) , socketpair(2) , accept(2) , getname(2) , listen(2) , shutdown(2) , setsockopt(2) , getsockopt(2) , mmap(2) and sendpage(2) .

IOCTL Request Codes

The following IOCTL request codes can be accessed using ioctl(2) on LINX sockets:

LINX_IOCTL_SEND

Sends a signal from a LINX socket sd. The correct syntax is:


struct linx_sndrcv_param *sndrcv;

error = ioctl(sd, LINX_IOCTL_SEND, sndrcv);

sndrcv is a linx_sndrcv_param structure:


struct linx_sndrcv_param
{
    __u32 from;
    __u32 to;
    __u32 size;
    __u32 sig_attr;
    __u32 sigselect_size;
    __u64 sigselect;
    __u32 tmo;
    __u64 buffer;
};

from is the spid of the sender, the sender does not need to be the current socket, the signal is sent from the current socket but the receiver will see the from as the sending spid, the default case is that from is the spid of the current LINX socket. to is the spid of the receiver, size is the size of the signal to be sent and sig_attr are the attributes of the signal. The sigselect_size and sigselect are not used by LINX_IOCTL_SEND and notused is for padding the struct since it needs to be 64-bit aligned but should be zeroed for future use. buffer is the pointer to the buffer to be sent, it is passed as a 64 bit unsigned value to be both 32-bit and 64-bit compatible.

On success, the number of bytes sent is returned.

LINX_IOCTL_RECEIVE

Receives a signal on a LINX socket sd. The call will block until a signal is received. The correct syntax is:


struct linx_sndrcv_param *sndrcv;

error = ioctl(sd, LINX_IOCTL_RECEIVE, sndrcv);

sndrcv is a linx_sndrcv_param structure:


struct linx_sndrcv_param
{
    __u32 from;
    __u32 to;
    __u32 size;
    __u32 sig_attr;
    __u32 sigselect_size;
    __u64 sigselect;
    __u32 tmo;
    __u64 buffer;
};

The from field should be set to LINX_ILLEGAL_SPID if signals from anyone should be received or if only signals from a specific spid should be received then from should be set to that spid. If LINX_ILLEGAL_SPID was set the from will contain the spid of the sender after the return of the call. The to field is not used when receiving a signal. The size field is the size of the provided buffer. When the call returns the sig_attr field is set to the attribute the signal carriers. The sigselect field is an array of LINX_SIGSELECT numbers to be received. The first position in the array contains the number of entries in the list that follows. If the first position is set to a negative count, all LINX signals except those listed will be received. The size of the array is sigselect_size. When the tmo field is used the call waits maximum tmo milliseconds before returning even if no signal has been received, if a blocking receive is requested the tmo field should be ~0 (0xFFFFFFFF), this will block forever. If no signal is received the. buffer pointer will be set to NULL (the provided buffer is always consumed). The buffer field is a pointer to the buffer provided by the user.

On success, the number of bytes received is returned. If the received signal is larger than the supplied payload buffer, zero is returned and the signal buffer size is written as a 32-bit value in the first 4 bytes of the payload buffer.

LINX_IOCTL_REQUEST_TMO

Request a timeout, a signal is sent to the requesting LINX endpoint when a timeout has expired. The correct syntax is:


struct linx_tmo_param *tmo_param;

error = ioctl(sd, LINX_IOCTL_REQUEST_TMO, tmo_param);

tmo_param is a linx_tmo_param structure:


struct linx_tmo_param
{
    LINX_OSTIME tmo;
    LINX_OSBUFSIZE sigsize;
    union LINX_SIGNAL *sig;
    LINX_OSTMOREF tmoref;
};

tmo is the timeout in milliseconds and the actual timeout time is rounded upward to the nest larger tick, the call guarantees at least the number of milliseconds requested, sig is a pointer to the signal that will be returned when the timeout expires, if sig is LINX_NIL then the default timeout signal with signal number LINX_OS_TMO_SIG is received instead, sigsize is the size of the provided signal, if no signal is provided the value must be set to zero.

On success, an timemout reference is returned in tmoref. This reference can be used in LINX_IOCTL_CANCEL_TMO and LINX_IOCTL_MODIFY_TMO.

LINX_IOCTL_CANCEL_TMO

Cancel a pending timeout, the correct syntax is:


struct linx_tmo_param *tmo_param;

error = ioctl(sd, LINX_IOCTL_CANCEL_TMO, tmo_param);

tmo_param is a linx_tmo_param structure:


struct linx_tmo_param
{
    LINX_OSTIME tmo;
    LINX_OSBUFSIZE sigsize;
    union LINX_SIGNAL *sig;
    LINX_OSTMOREF tmoref;
};

tmo, sigsize and sig are ignored, tmoref is used to identify which timeout is to be canceled, it is guaranteed that the timeout signal cannot be received after cancellation.

LINX_IOCTL_MODIFY_TMO

Modifies a pending timeout, the correct syntax is:


struct linx_tmo_param *tmo_param;

error = ioctl(sd, LINX_IOCTL_MODIFY_TMO, tmo_param);

tmo_param is a linx_tmo_param structure:


struct linx_tmo_param
{
    LINX_OSTIME tmo;
    LINX_OSBUFSIZE sigsize;
    union LINX_SIGNAL *sig;
    LINX_OSTMOREF tmoref;
};

sigsize and sig are ignored, tmoref is used to identify which timeout is to be modified, tmo is the new timeout value.

LINX_IOCTL_REQUEST_NEW_LINK

Request a signal when a new link is available, the correct syntax is:


struct linx_new_link_param *new_link_param;

error = ioctl(sd, LINX_IOCTL_REQUEST_NEW_LINK, new_link_param);

new_link_param is a linx_new_link_param structure:


struct linx_new_link_param
{
    uint32_t token;
    uint32_t new_link_ref;
};

token is passed to and from the LINX kernel module keeping track of which links the caller already have been notified about, the token value is ignored the first time a LINX endpint requests a new link signal. The token received in the new link signal should then be used in the next new link signal request. new_link_ref is used to cancel a pending new link signal request.

The syntax of the new link signal received when a new link is available is:


struct linx_new_link {
    LINX_SIGSELECT signo;
    LINX_NLTOKEN token;
    int name;
    int attr;
    char buf[1];
};

signo is LINX_OS_NEW_LINK_SIG, token is the token value to be used in the next request for a new link signal, name is the offset into buf where the name of the new link is stored, the name is null terminated, attr is the offset into buf where the attributes, if any, of the link are stored, the attribute string is null terminted, buf is a character buffer containg the name and the attributes, if any, of the link.

LINX_IOCTL_CANCEL_NEW_LINK

Cancels a pending new link signal request, the correct syntax is:


struct linx_new_link_param *new_link_param;

error = ioctl(sd, LINX_IOCTL_CANCEL_NEW_LINK, new_link_param);

new_link_param is a linx_new_link_param structure:


struct linx_new_link_param
{
    uint32_t token;
    uint32_t new_link_ref;
};

token is ignored, new_link_ref is used to identify which pending new link signal request is to be cancelled, after the cancellation it is guarnateed that no more new link signals can be received.

LINX_IOCTL_HUNTNAME

Sets the name of a LINX socket sd and returns its binary LINX endpoint identifier, the spid. The correct syntax is:


struct linx_huntname *huntname;

error = ioctl(sd, LINX_IOCTL_HUNTNAME, huntname);

huntname is a linx_huntname structure:


struct linx_huntname
{
        LINX_SPID spid;
        size_t    namelen; 
        char     *name;    
};

namelen is the size in bytes of the string name that contains the name to assign to the socket. On success, spid is set to the spid assigned to the LINX socket.

LINX_IOCTL_HUNT

Hunts for a LINX endpoint (that has been assigned a name) to obtain its spid. The correct syntax is:


struct linx_hunt_param *hunt_param;

error = ioctl(sd, LINX_IOCTL_HUNT, hunt_param);

hunt_param is a linx_hunt_param structure:


struct linx_hunt_param
{
        LINX_OSBUFSIZE     sigsize;
        union LINX_SIGNAL *sig;     
        LINX_SPID          from;    
        size_t             namelen; 
        char              *name;                                    
};

The sig parameter optionally holds a signal of size sigsize to be received when the other LINX socket is available. If no signal (NULL) is provided, the LINX default hunt signal of type LINX_OS_HUNT_SIG will be used. The from parameter shall be set to the owner of the hunt. In the normal case, this is the spid of the LINX socket performing the hunt call. If the spid associated with a different LINX socket is provided, the hunt can be cancelled by closing that socket. The hunt signal is always sent to the LINX socket performing the hunt call. The namelen is the size of the string name that contains the name of the LINX endpoint to be hunted for.

LINX_IOCTL_ATTACH

Attaches to a LINX endpoint in order to supervise it, i.e. to get an attach signal if it becomes unavailable. The correct syntax is:


struct linx_attach_param *attach_param;

error = ioctl(sd, LINX_IOCTL_ATTACH, attach_param);


attach_param is a linx_attach_param structure:


struct linx_attach_param
{
        LINX_SPID          spid;   
        LINX_OSBUFSIZE     sigsize;                                
        union LINX_SIGNAL *sig;    
        LINX_OSATTREF      attref; 
};

The spid field is the spid of the LINX endpoint to supervise. The sig parameter optionally holds a LINX signal of size sigsize to be received when the supervised LINX endpoint becomes unavailable. If no signal (NULL) is provided, the LINX default attach signal of type LINX_OS_ATTACH_SIG will be used.

On success, an attach reference is returned in attref. This reference can be used in LINX_IOCTL_DETACH later.

LINX_IOCTL_DETACH

Detaches from a supervised LINX endpoint, i.e. stops supervising it. The correct syntax is:


struct linx_detach_param *detach_param;

error = ioctl(sd, LINX_IOCTL_DETACH, detach_param);

The detach_param parameter is a struct linx_detach_param with the following fields:


struct linx_detach_param
{
        LINX_OSATTREF  attref;
}

The attref field is an attach reference returned from a LINX_IOCTL_ATTACH call.

LINX_IOCTL_SET_RECEIVE_FILTER

Sets up a receive filter prior to a select(2) call. The correct syntax is:


struct linx_receive_filter_param *rfp;

error = ioctl(sd, LINX_IOCTL_SET_RECEIVE_FILTER, rfp);

rfp is a linx_receive_filter_param structure:


struct linx_receive_filter_param
{
        LINX_SPID             from;          
        LINX_OSBUFSIZE        sigselect_size;
        const LINX_SIGSELECT *sigselect;     
};

The from parameter specifies that only signals from a specific spid should be received and sigselect is an array of LINX_SIGSELECT numbers to be received. The first position in the array contains the number of entries in the list that follows. If the first position is set to a negative count, all LINX signals except those listed will be received. The size of the array is sigselect_size.

LINX_IOCTL_REGISTER_LINK_SUPERVISOR

Registers this socket as a supervisor of LINX links. The correct syntax is:


error = ioctl(sd, LINX_IOCTL_REGISTER_LINK_SUPERVISOR, 0);

When a link is established to another node, a notification signal will be sent to all LINX sockets that have registered as link supervisor. This signal has the format:


struct linx_new_link
{
        LINX_SIGSELECT signo;
        int            name;
        int            attr;
        char           buf[1];
};

The signo is LINX_OS_LINK_SIG. The name of the link begins name bytes into buf and its attributes starts attr bytes into buf. Both the name and attributes are null terminated strings assigned to a link with the linxcfg(1) command.

To be notified when a link becomes unavailable, first do a LINX_IOCTL_HUNT on the link name. This returns a spid representing the link. Then the link can be supervised using LINX_IOCTL_ATTACH to that spid.

LINX_IOCTL_UNREGISTER_LINK_SUPERVISOR

Unregister this socket as a supervisor of LINX links. The correct syntax is:


error = ioctl(sd, LINX_IOCTL_UNREGISTER_LINK_SUPERVISOR, 0);

LINX_IOCTL_VERSION

Returns the version of the LINX kernel module. The correct syntax is:


unsigned int version;

error = ioctl(sd, LINX_IOCTL_VERSION, &version);

On success, the version parameter contains the version of the LINX kernel module. The LINX version number is a 32-bit number composed of an 8-bit major version, an 16-bit minor version, and a 8-bit seq (patch) number.

LINX_IOCTL_INFO

Retrieves information from the LINX kernel module. The correct syntax is:


struct linx_info info;

error = ioctl(sd, LINX_IOCTL_INFO, &info);

The info parameter is a struct linx_info with the following fields:


struct linx_info
{
        int    type;
        void  *type_spec;
};

The type field indicates the requested type of information and type_spec is a pointer to a struct that will contain input and return parameters.

Note that information retrieved with LINX_IOCTL_INFO may have become inaccurate when used in a subsequent call. The application must be prepared to handle errors related to this.

The different kinds of information that can be retrieved from the LINX kernel module are:

LINX_INFO_SUMMARY


Provides a summary of the most important information from the LINX kernel module.


struct linx_info info;

struct linx_info_summary info_summary;

info.type = LINX_INFO_SUMMARY;

info.type_spec = &info_summary;

The linx_info_summary structure is defined as:


struct linx_info_summary
{
       int no_of_local_sockets;
       int no_of_remote_sockets;
       int no_of_link_sockets;
       int no_of_pend_attach;
       int no_of_pend_hunt;
       int no_of_queued_signals;
};

The no_of_local_sockets field is the number of LINX sockets open locally, no_of_remote_sockets is the number of internal sockets open that have been created by the LINX kernel module to represent remote LINX endpoints. The no_of_link_sockets field is the number of open sockets representing LINX links to other nodes. The no_of_pend_attach field is the number of pending attaches, no_of_pend_hunt is the number of pending hunts and no_of_queued_signals is the number of queued signals.

LINX_INFO_SOCKETS


Returns the number of open LINX sockets and their LINX endpoint identifiers (spids).


struct linx_info info;

struct linx_info_sockets info_sockets;

info.type = LINX_INFO_SOCKETS;

info.type_spec = &info_sockets;

The linx_info_sockets structure is defined as:


struct linx_info_sockets
{
        LINX_OSBOOLEAN local;
        LINX_OSBOOLEAN remote;
        LINX_OSBOOLEAN link;
        int            buffer_size;
        int            no_of_sockets;
        LINX_SPID     *buffer;
};

If local is true, local sockets are included in the output, if remote is true, remote sockets are included and if link is true, sockets representing LINX links are included. The number of LINX sockets matching the search is returned in no_of_sockets and the array of spids is returned in the provided buffer. of size buffer_size bytes. If the provided buffer is too small, not all sockets will be included.

LINX_INFO_TYPE


Returns the type of a LINX endpoint.


struct linx_info info;

struct linx_info_type info_type;

info.type = LINX_INFO_TYPE;

info.type_spec = &info_type;

The linx_info_type structure is defined as:


struct linx_info_type
{
        LINX_SPID  spid;
        int        type;
};

The spid field is the identifier of the LINX endpoint for which the type is requested. The type is returned in type. A LINX endpoint can be of types: LINX_TYPE_UNKNOWN, LINX_TYPE_LOCAL, LINX_TYPE_REMOTE, LINX_TYPE_LINK, LINX_TYPE_ILLEGAL or LINX_TYPE_ZOMBIE.

LINX_INFO_STATE


Returns the state of a LINX endpoint.


struct linx_info info;

struct linx_info_state info_state;

info.type = LINX_INFO_STATE;

info.type_spec = &info_state;

The linx_info_state structure is defined as:


struct linx_info_state
{
        LINX_SPID  spid;
        int        state;
};

The spid field is the identifier of the LINX endpoint for which the state is requested. The state is returned in state. A LINX socket can be in states: LINX_STATE_UNKNOWN, LINX_STATE_RUNNING, LINX_STATE_RECV or LINX_STATE_POLL.

LINX_INFO_FILTERS


Returns information about the receive filters set up by a LINX endpoint.


struct linx_info info;

struct linx_info_filters info_filters;

info.type = LINX_INFO_FILTERS;

info.type_spec = &info_filters;

The linx_info_filters structure is defined as:


struct linx_info_filters
{
        LINX_SPID       spid;           
        LINX_SPID       from_filter;
        int             buffer_size;
        int             no_of_sigselect;
        LINX_SIGSELECT *buffer;         
};

The spid field is the identifier of the LINX endpoint for which the receive filter is requested. If the endpoint has setup a receive filter only accepting signals from a specific LINX endpoint, the spid of that endpoint is returned in from_filter. The number of LINX_SIGSELECT signal numbers in the receive filter is returned in no_of_sigselect and an array of these signal numbers are returned in the provided buffer. The buffer_size is the size in bytes of the buffer. If the buffer is too small, not all signal numbers in the filter are included.

LINX_INFO_RECV_QUEUE


Returns the receive queue of a LINX endpoint.


struct linx_info info;

struct linx_info_recv_queue info_recv_queue;

info.type = LINX_INFO_RECV_QUEUE;

info.type_spec = &info_recv_queue;

The linx_info_recv_queue structure is defined as:


struct linx_info_recv_queue
{
        LINX_SPID                spid;           
        int                      buffer_size;    
        int                      no_of_signals;  
        struct linx_info_signal *buffer;
};

The spid field is the identifier of the LINX endpoint for which the receive queue is requested. The number of signals in the queue is returned in no_of_signals. An array with queue information is returned in the provided buffer. The buffer_size is the size in bytes of the buffer. If the buffer is too small, not all signals are included. The linx_info_signal structure is defined as:


struct linx_info_signal
{
        LINX_SIGSELECT signo;
        int            size; 
        LINX_SPID      from; 
};

The signo field holds the signal number, size is the size in bytes of the signal and from is the spid of the sending LINX endpoint.

LINX_INFO_PEND_ATTACH


Returns information about pending attaches from or to a LINX endpoint.


struct linx_info info;

struct linx_info_pend_attach info_pend_attach;

info.type = LINX_INFO_PEND_ATTACH;

info.type_spec = &info_pend_attach;

The linx_info_pend_attach structure is defined as:


struct linx_info_pend_attach
{
        LINX_SPID                spid;      
        int                      from_or_to;
        int                      buffer_size;
        int                      no_of_attaches;
        struct linx_info_attach *buffer;        
};

The spid field is the identifier of the LINX endpoint for which attach informations is requested. If from_or_to is set to LINX_ATTACH_FROM, information about attaches from the spid is returned. If it is set to LINX_ATTACH_TO, information about attaches to the spid is returned. The number of attaches to/from the spid is returned in no_of_attaches, Information about the attaches are returned in the provided buffer. The buffer_size is the size in bytes of the buffer. If the buffer is too small, not all attaches are included. The linx_info_attach structure is defined as:


struct linx_info_attach
{
        LINX_SPID               spid;  
        LINX_OSATTREF           attref;
        struct linx_info_signal attach_signal;
};

The spid is the identifier of the LINX endpoint that has attached or has been attached to (depending on what from_or_to is set to). The attref field is the attach reference and attach_signal is the attach signal.

LINX_INFO_PEND_HUNT


Returns information about pending hunts issued from any LINX endpoint.

struct linx_info info;

struct linx_info_pend_hunt info_pend_hunt;

info.type = LINX_INFO_PEND_HUNT;

info.type_spec = &info_pend_hunt;

The linx_info_pend_hunt structure is defined as:


struct linx_info_pend_hunt
{
        LINX_SPID              spid;          
        int                    buffer_size;   
        int                    strings_offset;
        int                    no_of_hunts;     
        struct linx_info_hunt *buffer;          
};

The spid field is the identifier of the LINX endpoint for which hunt information is requested. The number of pending hunts is returned in no_of_hunts and information about each pending hunt is returned in the provided buffer. The buffer_size is the size in bytes of the buffer. If the buffer is too small, not all hunts are included. The strings_offset is the offset into the buffer where the name strings are stored. Each linx_info_hunt structure is defined as:


struct linx_info_hunt
{
        struct linx_info_signal hunt_signal;
        LINX_SPID               owner;      
        char                   *hunt_name;  
};

The owner field is the owner of the pending hunt and hunt_name is a string containing the name hunted for. The hunt_signal is the hunt signal. The linx_info_signal structure is described under LINX_INFO_RECV_QUEUE.

LINX_INFO_PEND_TMO


Returns information about pending timeouts issued from any LINX endpoint.

struct linx_info info;

struct linx_info_pend_tmo info_pend_tmo;

info.type = LINX_INFO_PEND_TMO;

info.type_spec = &info_pend_tmo;

The linx_info_pend_tmo structure is defined as:


struct linx_info_pend_tmo
{
        LINX_SPID             spid;
        int                   buffer_size;
        int                   no_of_timeouts;
        struct linx_info_tmo  *buffer;
};

The spid field is the identifier of the LINX endpoint for which hunt information is requested. The number of pending timeouts is returned in no_of_timeouts and information about each pending timeout is returned in the provided buffer. The buffer_size is the size in bytes of the buffer. If the buffer is too small, not all timeouts are included. Each linx_info_tmo structure is defined as:


struct linx_info_tmo
{
        LINX_OSTIME             tmo;
        LINX_OSTMOREF           tmoref;
        struct linx_info_signal tmo_signal;
};

The tmo field is the remaining time and tmoref is the timeout reference. The tmo_signal holds the timeout signal information.

LINX_INFO_SIGNAL_PAYLOAD


Returns the payload of a signal owned by a LINX endpoint.

struct linx_info info;

struct linx_info_signal_payload info_signal_payload;

info.type = LINX_INFO_SIGNAL_PAYLOAD;

info.type_spec = &info_signal_payload;

The linx_info_signal_payload structure is defined as:


struct linx_info_signal_payload
{
        LINX_SPID               spid;       
        int                     buffer_size;
        struct linx_info_signal signal;       
        int                     payload_size; 
        char                   *buffer;       
};

The spid field is the identifier of the LINX endpoint owning the signal and signal is a linx_info_signal structure returned from a previous LINX_INFO call. The signal buffer will be returned in the provided buffer. The buffer_size is the size in bytes of the buffer. If the provided buffer is too small, only the beginning of the signal buffer is returned. The payload_size shows the size in bytes of the returned signal payload. If the provided buffer is larger than the signal payload, payload_size will be less then buffer_size. If no signal payload matching the signal the payload_size will be set to zero.

LINX_INFO_NAME


Returns the name of a LINX endpoint.


struct linx_info info;

struct linx_info_name info_name;

info.type = LINX_INFO_NAME;

info.type_spec = &info_name;

The linx_info_name structure is defined as:


struct linx_info_name
{
        LINX_SPID spid;   
        int       namelen;
        char     *name;   
};

The spid field is the identifier of the LINX endpoint for which the name is requested. The namelen field is the length of the provided name buffer in which the name is be returned. If the LINX socket endpoint has not been assigned a name yet zero is returned and name is set to the empty string.

LINX_INFO_OWNER


Returns the process (PID) that owns a LINX endpoint.


struct linx_info info;

struct linx_info_owner info_owner;

info.type = LINX_INFO_OWNER;

info.type_spec = &info_owner;

The linx_info_owner structure is defined as:


struct linx_info_owner
{
        LINX_SPID spid; 
        pid_t     owner;
};

The spid field is the identifier of the LINX endpoint for which the information is requested. On success, the PID of the owning process is returned in owner.

LINX_INFO_STAT


Returns statistics for a LINX endpoint. This requires that the LINX kernel module has been compiled with the "SOCK_STAT=yes" setting.

struct linx_info info;

struct linx_info_stat info_stat;

info.type = LINX_INFO_STAT;

info.type_spec = &info_stat;

The linx_info_stat structure is defined as:


struct linx_info_stat
{
        LINX_SPID spid;
        uint64_t no_sent_local_signals;
        uint64_t no_recv_local_signals;
        uint64_t no_sent_local_bytes;
        uint64_t no_recv_local_bytes;
        uint64_t no_sent_remote_signals;
        uint64_t no_recv_remote_signals;
        uint64_t no_sent_remote_bytes;
        uint64_t no_recv_remote_bytes;
        uint64_t no_sent_signals;
        uint64_t no_recv_signals;
        uint64_t no_sent_bytes;
        uint64_t no_recv_bytes;
        uint64_t no_queued_bytes;
        uint64_t no_queued_signals;
};

The spid is the identifier of the LINX endpoint for which statistics is required. If the LINX kernel module has not been compiled with "SOCK_STAT=yes", ioctl returns -1 and errno is set to ENOSYS.

Known Bugs

None.

See Also

Generic LINX for Linux man-page:
linx(7) (this document)

LINX API man-pages:
linx.h(3) , linx_types.h(3) ,
linx_alloc(3) , linx_attach(3) , linx_cancel_tmo(3) , linx_close(3) ,
linx_detach(3) , linx_free_buf(3) , linx_free_name(3) , linx_free_stat(3) ,
linx_get_descriptor(3) , linx_get_name(3) , linx_get_spid(3) ,
linx_get_stat(3) , linx_hunt(3) , linx_hunt_from(3) , linx_modify_tmo(3) ,
linx_open(3) , linx_receive(3) , linx_receive_from(3) ,
linx_receive_w_tmo(3) , linx_request_tmo(3) , linx_send(3) , linx_send_w_opt(3) ,
linx_send_w_s(3) , linx_sender(3) , linx_set_sigsize(3) , linx_sigattr(3) , linx_sigsize(3)

Related LINX applications
linxcfg(1) , linxdisc(8) , linxdisc.conf(5) , linxstat(1) , mkethcon(1) , mklink(1) , mktcpcon(1) , rmethcon(1) , rmlink(1) , rmtcpcon(1)

Related generic Linux man-pages:
socket(2) , close(2) , sendto(2) , sendmsg(2) , recvfrom(2) , recvmsg(2) , poll(2) , select(2) , ioctl(2)

Author

Enea LINX team

Copyright

Copyright (c) 2006-2007, Enea Software AB All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Enea Software AB nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Table of Contents