[Previous] [Contents] [Next]

resmgr_attach()

Attach a path to the pathname space

Synopsis:

#include <sys/dispatch.h>

int resmgr_attach
       ( dispatch_t * dpp,
         resmgr_attr_t * attr,
         const char * path, 
         enum _file_type file_type,
         unsigned flags, 
         const resmgr_connect_funcs_t * connect_funcs,
         const resmgr_io_funcs_t * io_funcs,
         RESMGR_HANDLE_T * handle );

Library:

libc

Description:

The resmgr_attach() function puts the path into the general pathname space and binds requests on this path to the dispatch handle dpp.

attr

Attributes such as the maximum message size, number of parts (number of IOVs in context), and flags can be specified in the attr structure. The resmgr_attr_t structure looks like this:

typedef struct _resmgr_attr {
   unsigned      flags;
   unsigned      nparts_max;
   unsigned      msg_max_size;
   int           (*other_func)
                 ( resmgr_context_t *, void *msg );
} resmgr_attr_t;

where:

nparts_max
Specifies the number of components that are allocated to the IOV array. If you specify 0, the resource manager library bumps the value to the minimum usable by the library itself.
msg_max_size
Specifies the minimum amount of room to be reserved for receiving a message that's allocated in resmgr_context_alloc(). If the value is too low, or you specify it as 0, resmgr_attach() picks a value that is usable.
other_func
A pointer to a function that's called if the resource manager receives an I/O message that it didn't successfully handle. This function is attached only if the RESMGR_FLAG_ATTACH_OTHERFUNC flag (defined in <sys/dispatch.h>) is set.

file_type

The possible values for file_type (defined in <sys/ftype.h>) are:

_FTYPE_ANY
Pathname can be anything.
_FTYPE_LINK
Reserved for the Process Manager.
_FTYPE_MOUNT
Receive mount requests on the path (path must be NULL).
_FTYPE_MQUEUE
Reserved for a mqueue manager.
_FTYPE_PIPE
Reserved for a pipe manager.
_FTYPE_SEM
Reserved for a semaphore manager.
_FTYPE_SHMEM
Reserved for a shared memory object.
_FTYPE_SOCKET
Reserved for a socket manager.
_FTYPE_SYMLINK
Reserved for the Process Manager.

Most of the above file_types are used for special services which have their own open function associated with them. For example, the mqueue manager specifies file_type as _FTYPE_QUEUE and mq_open() requests a pathname match of the same type.

Specify _FTYPE_ANY for normal filesystems and simple devices, such as serial ports, that don't have their own special open type. Also, if you're able to handle the type of service or a redirection node to a manager that does. Most resource managers are this type.

Your resource manager won't receive messages from an open of an inappropriate type. The following table shows the different open function types and the types of pathnames they'll match.

Function: file_type: Matches pathname of type:
mq_open() _FTYPE_MQUEUE _FTYPE_ANY
_FTYPE_MQUEUE
open() _FTYPE_ANY all types
pipe() _FTYPE_PIPE _FTYPE_ANY or
_FTYPE_PIPE
sem_open() _FTYPE_SEM _FTYPE_ANY or
_FTYPE_SEM
shm_open() _FTYPE_SHMEM _FTYPE_ANY or
_FTYPE_SHMEM
socket() _FTYPE_SOCKET _FTYPE_ANY or _FTYPE_SOCKET

The generic open() can be used to open a pathname of any type.

flags

The flags argument specifies additional information to control the pathname resolution. The flags (defined in <sys/resmgr.h>) contain at least the following bitwise flags:

_RESMGR_FLAG_AFTER
Force path to be resolved after others with the same pathname at the same mountpoint.
_RESMGR_FLAG_BEFORE
Force path to be resolved before others with the same pathname at the same mountpoint.
_RESMGR_FLAG_OPAQUE
Don't resolve to mountpoints on a path shorter than this (i.e. find the longest match against all pathnames attached).
_RESMGR_FLAG_DIR
Treat the pathname as a directory and allow the resolving of longer pathnames. The _IO_CONNECT message contains the pathname passed to the client open() with the matching prefix stripped off. Without this flag the pathname is treated as a simple file requiring an exact match.
Attached path Opened path _RESMGR_FLAG_DIR set _RESMGR_FLAG_DIR clear
/a/b /a/b match "" match ""
/a/b /a/b/c match c no match
/a/b /a/b/c/d match c/d no match
/a/b /a/bc no match no match

You can't attach a directory pathname which contains, as a subset, an existing file pathname. Likewise, you can't attach a file pathname which is a subset of an existing directory pathname.

Existing path New path New path allowed?
dir /a/b dir /a yes
dir /a/b dir /a/b/c yes
file /a/b dir /a yes
file /a/b dir /a/b/c no, dir beneath a file
dir /a/b file /a no, dir beneath a file
dir /a/b file /a/b/c yes
file /a/b file /a yes
file /a/b file /a/b/c yes
_RESMGR_FLAG_FTYPEONLY
Only handle requests for the specific filetype indicated. Pathname must be NULL.
_RESMGR_FLAG_SELF
Allow requests to resolve back to this server (potential for deadlock).

connect_funcs

The connect_funcs argument points to functions that operate on a filename.

io_funcs

The io_funcs argument points to functions that operate on a file descriptor.

If you want to use the POSIX functions, we've provided you with the POSIX layer: To fill your connect and I/O functions tables with the default handler functions supplied by the POSIX layer library, use the function iofunc_func_init(). You can then override the defaults placed in the structures with your own handlers later.

For further details about connect and IO messages, see the "Writing a Resource Manager" chapter in the Programmer's Guide.

handle

In the most general case, the last argument, handle is an arbitrary structure that you wish to have associated with the pathname you're attaching. Practically, however, we recommend that it contain the POSIX layer's well defined attributes structure, iofunc_attr_t, as this lets you use the POSIX layer default library. You can certainly extend the data that's contained in the attributes structure to contain any device-specific data that you may require. This is commonly done, and is described in the "Advanced Topics" section of the Writing a Resource Manager chapter in the Programmer's Guide.

In order to use the POSIX layer default library, the attributes structure must be bound into the OCB, and you must use the POSIX layer's iofunc_ocb_t OCB. This is described in the documentation for resmgr_open_bind(), as well as in the above reference.

Returns:

A unique link ID associated with this attach, or -1 on failure (errno is set).

The returned ID is needed to detach the pathname at a later time using resmgr_detach(). The ID is also passed back in the resmgr_handler() function in ctp->id.

Errors:

ENOMEM
There isn't enough free memory to complete the operation.
ENOTDIR
A component of the pathname wasn't a directory entry.

Examples:

Here's an example of a simple single-threaded resource manager:

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>

static resmgr_connect_funcs_t    connect_funcs;
static resmgr_io_funcs_t         io_funcs;
static iofunc_attr_t             attr;

int main(int argc, char **argv)
{
    dispatch_t           *dpp;
    resmgr_attr_t        resmgr_attr;
    resmgr_context_t     *ctp;
    int                  id;

    /* initialize dispatch interface */
    if ( (dpp = dispatch_create()) == NULL ) {
       fprintf( stderr, "%s: Unable to allocate \
                dispatch handle.\n", argv[0] );
       return EXIT_FAILURE;
    }

    /* initialize resource manager attributes */
    memset( &resmgr_attr, 0, sizeof resmgr_attr );
    resmgr_attr.nparts_max = 1;
    resmgr_attr.msg_max_size = 2048;

    /* initialize functions for handling messages */
    iofunc_func_init( _RESMGR_CONNECT_NFUNCS, &connect_funcs,
                      _RESMGR_IO_NFUNCS, &io_funcs );

    /* initialize attribute structure */
    iofunc_attr_init( &attr, S_IFNAM | 0666, 0, 0 );

    /* attach our device name (passing in the POSIX defaults 
       from the iofunc_func_init and iofunc_attr_init functions) 
     */
    if ( (id = resmgr_attach
          ( dpp, &resmgr_attr, "/dev/mynull", _FTYPE_ANY, 0,
          &connect_funcs, &io_funcs, &attr)) == -1 ) {
        fprintf( stderr, "%s: Unable to attach name.\n", \
                 argv[0] );
        return EXIT_FAILURE;
    }

    /* allocate a context structure */
    ctp = resmgr_context_alloc( dpp );

    /* start the resource manager message loop */
    while (1) {
        if ( (ctp = resmgr_block( ctp )) == NULL ) {
           fprintf(stderr, "block error\n");
           return EXIT_FAILURE;
        }
        resmgr_handler(ctp);
    }
}

For more examples using the dispatch interface, see dispatch_create(), message_attach(), and thread_pool_create(). For more information on writing a resource manager, see the "Writing a Resource Manager" chapter in the Programmer's Guide.

Classification:

QNX 6

Safety:
Cancellation point Yes
Interrupt handler No
Signal handler No
Thread Yes

Caveats:

If your application calls this function, it must run as root.

See also:

dispatch_create(), iofunc_attr_init(), iofunc_func_init(), resmgr_block(), resmgr_context_alloc(), resmgr_context_free(), resmgr_detach(), resmgr_handler()


[Previous] [Contents] [Next]