]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Add a reloadable option for sorcery type objects
authorKevin Harwell <kharwell@digium.com>
Fri, 30 Aug 2013 19:55:56 +0000 (19:55 +0000)
committerKevin Harwell <kharwell@digium.com>
Fri, 30 Aug 2013 19:55:56 +0000 (19:55 +0000)
Some configuration objects currently won't place nice if reloaded.
Specifically, in this case the pjsip transport objects.  Now when
registering an object in sorcery one may specify that the object is
allowed to be reloaded or not.  If the object is set to not reload
then upon reloading of the configuration the objects of that type
will not be reloaded.  The initially loaded objects of that type
however will remain.

While the transport objects will not longer be reloaded it is still
possible for a user to configure an endpoint to an invalid transport.
A couple of log messages were added to help diagnose this problem if
it occurs.

(closes issue ASTERISK-22382)
Reported by: Rusty Newton
(closes issue ASTERISK-22384)
Reported by: Rusty Newton
Review: https://reviewboard.asterisk.org/r/2807/
........

Merged revisions 398139 from http://svn.asterisk.org/svn/asterisk/branches/12

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@398140 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/sorcery.h
main/sorcery.c
res/res_pjsip.c
res/res_pjsip/config_transport.c
res/res_pjsip_outbound_registration.c

index 84a537937d4d916d4e6b08a4a4b3d087190e0ab3..dad0c439c1caebc42ab4f22441e0c3b77fe6b5ee 100644 (file)
@@ -356,7 +356,7 @@ int __ast_sorcery_apply_default(struct ast_sorcery *sorcery, const char *type, c
  * \retval 0 success
  * \retval -1 failure
  */
-int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply);
+int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply);
 
 /*!
  * \brief Register an object type
@@ -371,7 +371,22 @@ int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type,
  * \retval -1 failure
  */
 #define ast_sorcery_object_register(sorcery, type, alloc, transform, apply) \
-       __ast_sorcery_object_register((sorcery), (type), 0, (alloc), (transform), (apply))
+       __ast_sorcery_object_register((sorcery), (type), 0, 1, (alloc), (transform), (apply))
+
+/*!
+ * \brief Register an object type that is not reloadable
+ *
+ * \param sorcery Pointer to a sorcery structure
+ * \param type Type of object
+ * \param alloc Required object allocation callback
+ * \param transform Optional transformation callback
+ * \param apply Optional object set apply callback
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+#define ast_sorcery_object_register_no_reload(sorcery, type, alloc, transform, apply) \
+       __ast_sorcery_object_register((sorcery), (type), 0, 0, (alloc), (transform), (apply))
 
 /*!
  * \brief Register an internal, hidden object type
@@ -386,7 +401,7 @@ int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type,
  * \retval -1 failure
  */
 #define ast_sorcery_internal_object_register(sorcery, type, alloc, transform, apply) \
-       __ast_sorcery_object_register((sorcery), (type), 1, (alloc), (transform), (apply))
+       __ast_sorcery_object_register((sorcery), (type), 1, 1, (alloc), (transform), (apply))
 
 /*!
  * \brief Set the copy handler for an object type
index 1bd55d4533e457c6fd0ff79716aa290b6e870576..3f2346dfeeed1c2de0472b2fb0a138d8ce8df912 100644 (file)
@@ -110,6 +110,9 @@ struct ast_sorcery_object_type {
 
        /*! \brief Serializer for observers */
        struct ast_taskprocessor *serializer;
+
+       /*! \brief Specifies if object type is reloadable or not */
+       unsigned int reloadable:1;
 };
 
 /*! \brief Structure for registered object type observer */
@@ -575,7 +578,7 @@ static int sorcery_extended_fields_handler(const void *obj, struct ast_variable
        return 0;
 }
 
-int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply)
+int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type, unsigned int hidden, unsigned int reloadable, aco_type_item_alloc alloc, sorcery_transform_handler transform, sorcery_apply_handler apply)
 {
        RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
 
@@ -589,6 +592,7 @@ int __ast_sorcery_object_register(struct ast_sorcery *sorcery, const char *type,
        object_type->type.item_alloc = alloc;
        object_type->type.hidden = hidden;
 
+       object_type->reloadable = reloadable;
        object_type->transform = transform;
        object_type->apply = apply;
        object_type->file->types[0] = &object_type->type;
@@ -695,12 +699,26 @@ int __ast_sorcery_object_field_register(struct ast_sorcery *sorcery, const char
        return 0;
 }
 
+/*! \brief Retrieves whether or not the type is reloadable */
+static int sorcery_reloadable(const struct ast_sorcery *sorcery, const char *type)
+{
+       RAII_VAR(struct ast_sorcery_object_type *, object_type,
+                ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
+       return object_type && object_type->reloadable;
+}
+
 static int sorcery_wizard_load(void *obj, void *arg, int flags)
 {
        struct ast_sorcery_object_wizard *wizard = obj;
        struct sorcery_load_details *details = arg;
        void (*load)(void *data, const struct ast_sorcery *sorcery, const char *type);
 
+       if (details->reload && !sorcery_reloadable(details->sorcery, details->type)) {
+               ast_log(LOG_NOTICE, "Type '%s' is not reloadable, "
+                       "maintaining previous values\n", details->type);
+               return 0;
+       }
+
        load = !details->reload ? wizard->wizard->load : wizard->wizard->reload;
 
        if (load) {
index e7c83d9d160a96694ba164e095187970c3ff5c34..d9d841472491ee570d74b17fc6ec887a68b1f648 100644 (file)
@@ -1290,6 +1290,8 @@ static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpo
        transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name);
 
        if (!transport || !transport->state) {
+               ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s' for endpoint '%s'\n",
+                       transport_name, ast_sorcery_object_get_id(endpoint));
                return -1;
        }
 
index 82a995cb6a51b1e546f74a07081521e06376bef0..cf0b5e878799aeeae0171c76298cfa318245a699 100644 (file)
@@ -309,7 +309,7 @@ int ast_sip_initialize_sorcery_transport(struct ast_sorcery *sorcery)
 {
        ast_sorcery_apply_default(sorcery, "transport", "config", "pjsip.conf,criteria=type=transport");
 
-       if (ast_sorcery_object_register(sorcery, "transport", transport_alloc, NULL, transport_apply)) {
+       if (ast_sorcery_object_register_no_reload(sorcery, "transport", transport_alloc, NULL, transport_apply)) {
                return -1;
        }
 
index 67e0ead3370cf0f098d1d1bcba3871200ca6c6d5..166b557773f3a93dbcb71aa5e18987417f618d6f 100644 (file)
@@ -602,6 +602,8 @@ static int sip_outbound_registration_regc_alloc(void *data)
                RAII_VAR(struct ast_sip_transport *, transport, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", registration->transport), ao2_cleanup);
 
                if (!transport || !transport->state) {
+                       ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s' "
+                               " for outbound registration", registration->transport);
                        return -1;
                }