The secpol_resmgr_attach() and resmgr_attach() functions and their parameters

QNX SDP8.0Getting Started with the QNX OSDeveloperUser

As you saw in the /dev/null example above, the first thing you'll want to do is register your chosen mountpoint with the process manager. This is done via secpol_resmgr_attach() or resmgr_attach().

The secpol_resmgr_attach() function has the following prototype:
int secpol_resmgr_attach (secpol_file_t *handle,
                          void *dpp,
                          resmgr_attr_t *resmgr_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,
                          iofunc_attr_t *iofunc_attr,
                          bool *perms_set);

The prototype for resmgr_attach() functions is the same, except it does not have the secpol_file_t handle or perms_set parameters.

Let's examine these arguments, in order, and see what they're used for.

handle

Handle to the security policy file. Usually NULL, which specifies that the default security policy file is used (either the system default or one set using secpol_open()).

dpp
The dispatch handle. This lets the dispatch interface manage the message receive for your resource manager.
resmgr_attr
Controls the resource manager characteristics, as discussed above.
path
The mountpoint that you're registering. If you're registering a discrete mountpoint (such as would be the case, for example, with /dev/null, or /dev/ser1), then this mountpoint must be matched exactly by the client, with no further pathname components past the mountpoint. If you're registering a directory mountpoint (such as would be the case, for example, with a network filesystem mounted as /nfs), then the match must be exact as well, with the added feature that pathnames past the mountpoint are allowed; they get passed to the connect functions stripped of the mountpoint. For example, the pathname /nfs/etc/passwd would match the network filesystem resource manager, and it would get etc/passwd as the rest of the pathname.
file_type
The class of resource manager. See below.
flags
Additional flags to control the behavior of your resource manager. These flags are defined below.
connect_funcs and io_funcs
These are simply the list of connect functions and I/O functions that you wish to bind to the mountpoint.
iofunc_attr
This is an extendable data structure (aka attributes structure) that identifies the resource being mounted. For example, for a serial port, you'd extend the standard POSIX-layer attributes structure by adding information about the base address of the serial port, the baud rate, etc.
perms_set

If non-NULL, set to true if permissions were altered; otherwise, set to false.

The flags member can contain any of the following flags (or the constant 0 if none are specified):

_RESMGR_FLAG_BEFORE or _RESMGR_FLAG_AFTER
These flags indicate that your resource manager wishes to be placed before or after (respectively) other resource managers with the same mountpoint. These two flags would be useful with unioned (overlaid) filesystems. We'll discuss the interactions of these flags shortly.
_RESMGR_FLAG_DIR
This flag indicates that your resource manager is taking over the specified mountpoint and below—it's effectively a filesystem style of resource manager, as opposed to a discretely manifested (device) resource manager.
_RESMGR_FLAG_OPAQUE
If set, prevents resolving to any other manager below your mountpoint except for the path manager. This effectively eliminates unioning on a path.
_RESMGR_FLAG_FTYPEONLY
This ensures that only requests that have the same _FTYPE_* as the file_type passed to resmgr_attach() are matched.
_RESMGR_FLAG_FTYPEALL
This flag is used when a resource manager wants to catch all client requests, even those with a different _FTYPE_* specification than the one passed to resmgr_attach() in the file_type argument. This can only be used in conjunction with a registration file type of _FTYPE_ALL.
_RESMGR_FLAG_SELF
Allow this resource manager to talk to itself. This really is a Don't try this at home, kids kind of flag, because allowing a resource manager to talk to itself can break the send-hierarchy and lead to deadlock (as was discussed in the Message Passing chapter).

You can call secpol_resmgr_attach() or resmgr_attach() multiple times to mount different mountpoints. You can also call them from within the connect or I/O functions—this is kind of a neat feature that allows you to create devices on the fly.

Note:
When it calls secpol_resmgr_attach() or resmgr_attach(), your resource manager needs the PROCMGR_AID_PATHSPACE ability, to add a name to the pathname space.

For more information, go to the entry procmgr_ability() in the QNX OS C Library Reference.

When you've decided on the mountpoint, and want to create it, you'll need to tell the process manager if this resource manager can handle requests from just anyone, or if it's limited to handling requests only from clients who identify their connect messages with special tags. For example, consider the POSIX message queue (mqueue) driver. It's not going to allow (and certainly wouldn't know what to do with) regular open() messages from any old client. It will allow messages only from clients that use the POSIX mq_open(), mq_receive(), and so on, function calls.

To prevent the process manager from even allowing regular requests to arrive at the mqueue resource manager, mqueue specified _FTYPE_MQUEUE as the file_type parameter. This means that when a client requests a name resolution from the process manager, the process manager won't even bother considering the resource manager during the search unless the client has specified that it wants to talk to a resource manager that has identified itself as _FTYPE_MQUEUE.

Unless you're doing something very special, you'll use a file_type of _FTYPE_ANY, which means that your resource manager is prepared to handle requests from anyone. For the full list of _FTYPE_* manifest constants, take a look in <sys/ftype.h>.

With respect to the before and after flags, things get a little bit more interesting. You can specify only one of these flags or the constant 0.

Let's see how this works. Suppose a number of resource managers have started, in the order given in the table. We also see the flags they passed for the flags member. Observe the positions they're given:

Resmgr Flag Order
1 _RESMGR_FLAG_BEFORE 1
2 _RESMGR_FLAG_AFTER 1, 2
3 0 1, 3, 2
4 _RESMGR_FLAG_BEFORE 1, 4, 3, 2
5 _RESMGR_FLAG_AFTER 1, 4, 3, 5, 2
6 0 1, 4, 6, 3, 5, 2

As you can see, the first resource manager to actually specify a flag always ends up in that position. (From the table, resource manager number 1 was the first to specify the before flag; no matter who registers, resource manager 1 is always first in the list. Likewise, resource manager 2 was the first to specify the after flag; again, no matter who else registers, it's always last.) If no flag is specified, it effectively acts as a middle flag. When resource manager 3 started with a flag of zero, it got put into the middle. As with the before and after flags, there's a preferential ordering given to all the middle resource managers, whereby newer ones are placed in front of other, existing middle ones.

However, in reality, there are very few cases where you'd actually mount more than one, and even fewer cases where you'd mount more than two resource managers at the same mountpoint. Here's a design tip: expose the ability to set the flags at the command line of the resource manager so that the end-user of your resource manager is able to specify, for example, -b to use the before flag, and -a to use the after flag, with no command-line option specified to indicate that a zero should be passed as the flag.

Keep in mind that this discussion applies only to resource managers mounted with the same mountpoint. Mounting /nfs with a before flag and /disk2 with an after flag will have no effect on each other; only if you were to then mount another /nfs or /disk2 would these flags (and rules) come into play.

Finally, the secpol_resmgr_attach() and resmgr_attach() functions return a small integer handle on success or -1 on failure. This handle can then be used to detach the pathname from the process manager's internal pathname tables.

Page updated: