Search code examples
linuxqnxresourcemanager

qnx get resmgr_context_t of old resource manager


I trying to create my own process manager for qnx 6.6 over /proc/{pid}/as.

But I need to change only one operation (io_open), all other operations should continue work with old file (/proc/{pid}/as).

Can I just get pointer to resmgr_context_t (from path or fd, before resmgr_attach) and for all other operations just call default function?

This is stupied example of what I want:

resmgr_context_t* old_context;
int my_lseek(resmgr_context_t *ctp, io_lseek_t *msg, RESMGR_OCB_T *ocb){
   return iofunc_lseek_default(old_context, msg, ocb);
}

Solution

  • You need to make a regular resource manager that only registers a function for io_open, all other resource manager operations will filter down to the lower resource managers in the stack.

    Return ENOENT from the io_open callback if you want the message to move down the resmgr stack to other registered io_open callbacks, otherwise return EOK.

    Error checking was omitted for brevity.

    #include <errno.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <time.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 io_open (resmgr_context_t *ctp, io_open_t  *msg, RESMGR_HANDLE_T *handle, void *extra);
    
    int main(int argc, char **argv)
    {
        resmgr_attr_t        resmgr_attr;
        dispatch_t           *dpp;
        dispatch_context_t   *ctp;
        int                  id;
    
        // initialize dispatch interface
        dpp = dispatch_create();
    
        // 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);
        connect_funcs.open = io_open;
    
        // initialize attribute structure used by the device 
        iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
    
        // attach to /proc/{pid}/as path, replace '1' with correct pid 
        resmgr_attach(dpp, &resmgr_attr,"/proc/1/as", 
            _FTYPE_ANY, _RESMGR_FLAG_BEFORE|_RESMGR_FLAG_DIR,
            &connect_funcs, &io_funcs, &attr);
    
        ctp = dispatch_context_alloc(dpp);
    
        /* start the resource manager message loop */
        while(1) {
            if((ctp = dispatch_block(ctp)) == NULL) {
                perror("dispatch_block");
                return EXIT_FAILURE;
            }
            dispatch_handler(ctp);
        }
    }
    
    int io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
    {
        time_t tod;  
        tod = time(NULL); 
        printf ("%10d %-32s is being opened\n", tod, msg->connect.path);
    
        return(ENOENT);
    }