Navigation


Changeset 732:4a0b61061a6d in freeDiameter


Ignore:
Timestamp:
Feb 25, 2011, 3:46:40 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Added simple mechanism to declare dependencies between extensions

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • extensions/app_diameap/diameap.c

    r438 r732  
    8484
    8585/* Define the entry point */
    86 EXTENSION_ENTRY("DiamEAP", diameap_main)
     86EXTENSION_ENTRY("DiamEAP", diameap_main, "dict_eap")
    8787;
  • extensions/app_sip/app_sip.c

    r639 r732  
    250250}
    251251
    252 EXTENSION_ENTRY("app_sip", as_entry);
     252EXTENSION_ENTRY("app_sip", as_entry, "dict_sip");
  • extensions/dict_eap/dict_eap.c

    r662 r732  
    528528}
    529529
    530 EXTENSION_ENTRY("dict_eap", deap_entry);
     530EXTENSION_ENTRY("dict_eap", deap_entry, "dict_nasreq");
  • extensions/test_sip/test_sip.c

    r658 r732  
    240240}
    241241
    242 EXTENSION_ENTRY("test_sip", ts_entry);
    243 
     242EXTENSION_ENTRY("test_sip", ts_entry, "dict_sip");
     243
  • include/freeDiameter/extension.h

    r658 r732  
    4242
    4343/* Macro that define the entry point of the extension */
    44 #define EXTENSION_ENTRY(_name, _function)                                               \
     44#define EXTENSION_ENTRY(_name, _function, _depends...)                                  \
     45const char *fd_ext_depends[] = { _name , ## _depends , NULL };                          \
    4546static int extension_loaded = 0;                                                        \
    4647int fd_ext_init(int major, int minor, char * conffile) {                                \
  • libfdcore/extensions.c

    r706 r732  
    4646        char            *conffile;      /* optional configuration file name for the extension */
    4747        void            *handler;       /* object returned by dlopen() */
     48        const char      **depends;      /* names of the other extensions this one depends on (if provided) */
     49        char            *ext_name;      /* points to the extension name, either inside depends, or basename(filename) */
     50        int             free_ext_name;  /* must be freed if it was malloc'd */
    4851        void            (*fini)(void);  /* optional address of the fd_ext_fini callback */
    4952};
     
    8588                fd_log_debug(" - '%s'[%s] is %sloaded\n", ext->filename, ext->conffile?:"no conf", ext->handler ? "" : "not ");
    8689        }
     90}
     91
     92/* Check the dependencies. The object must have been dlopened already. */
     93static int check_dependencies(struct fd_ext_info * ext)
     94{
     95        int i = 1;
     96        TRACE_ENTRY( "%p", ext );
     97       
     98        /* Attempt to resolve the dependency array */
     99        ext->depends = dlsym( ext->handler, "fd_ext_depends" );
     100        if (!ext->depends) {
     101                /* Duplicate the filename */
     102                char * tmp = strdup(ext->filename);
     103                ext->ext_name = strdup(basename(tmp));
     104                free(tmp);
     105                ext->free_ext_name = 1;
     106                TRACE_DEBUG(FULL, "Old extension's [%s] API: missing dependencies (ignored)", ext->ext_name);
     107                return 0;
     108        }
     109       
     110        ext->ext_name = (char *)ext->depends[0];
     111       
     112        TRACE_DEBUG(FULL, "Checking dependencies for '%s'...", ext->ext_name);
     113       
     114        while (ext->depends[i]) {
     115                struct fd_list * li;
     116                for (li = ext_list.next; li != &ext->chain; li = li->next)
     117                {
     118                        struct fd_ext_info * e = (struct fd_ext_info *)li;
     119                        if (!strcasecmp(e->ext_name, ext->depends[i])) {
     120                                /* the dependency was already loaded */
     121                                break;
     122                        }
     123                }
     124               
     125                if (li == &ext->chain) {
     126                        /* the dependency was not found */
     127                        TRACE_DEBUG(NONE, "Error: extension [%s] depends on [%s] which was not loaded first.\nPlease fix your configuration file.",
     128                                ext->ext_name, ext->depends[i]);
     129                        return ESRCH;
     130                }
     131               
     132                i++;
     133        }
     134
     135        /* All dependencies resolved successfully */
     136        return 0;
    87137}
    88138
     
    111161                if (ext->handler == NULL) {
    112162                        /* An error occured */
    113                         TRACE_DEBUG( NONE, "Loading of extension %s failed:\n %s\n", ext->filename, dlerror());
     163                        TRACE_DEBUG( NONE, "Loading of extension %s failed:\n %s", ext->filename, dlerror());
     164                        #ifdef DEBUG
     165                        ext->handler = dlopen(ext->filename, RTLD_LAZY | RTLD_GLOBAL);
     166                        if (ext->handler) {
     167                                if (!check_dependencies(ext)) {
     168                                        TRACE_DEBUG( NONE, "In addition, all declared dependencies are satisfied (Internal Error!)\n");
     169                                }
     170                        }
     171                        #endif /* DEBUG */
    114172                        return EINVAL;
    115173                }
     174               
     175                /* Check if declared dependencies are satisfied. */
     176                CHECK_FCT( check_dependencies(ext) );
    116177               
    117178                /* Resolve the entry point of the extension */
     
    168229                /* Call the exit point of the extension, if it was resolved */
    169230                if (ext->fini != NULL) {
    170                         TRACE_DEBUG (FULL, "Calling [%s]->fd_ext_fini function.", ext->filename);
     231                        TRACE_DEBUG (FULL, "Calling [%s]->fd_ext_fini function.", ext->ext_name ?: ext->filename);
    171232                        (*ext->fini)();
    172233                }
     
    175236                /* Now unload the extension */
    176237                if (ext->handler) {
    177                         TRACE_DEBUG (FULL, "Unloading %s", ext->filename);
     238                        TRACE_DEBUG (FULL, "Unloading %s", ext->ext_name ?: ext->filename);
    178239                        if ( dlclose(ext->handler) != 0 ) {
    179                                 TRACE_DEBUG (INFO, "Unloading [%s] failed : %s\n", ext->filename, dlerror());
     240                                TRACE_DEBUG (INFO, "Unloading [%s] failed : %s\n", ext->ext_name ?: ext->filename, dlerror());
    180241                        }
    181242                }
     
    183244               
    184245                /* Free the object and continue */
     246                if (ext->free_ext_name)
     247                        free(ext->ext_name);
    185248                free(ext->filename);
    186249                free(ext->conffile);
Note: See TracChangeset for help on using the changeset viewer.