<p>Joshua Colp <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/15561">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Kevin Harwell: Looks good to me, approved
George Joseph: Looks good to me, but someone else must approve
Joshua Colp: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">sorcery: Add support for more intelligent reloading.<br><br>Some sorcery objects actually contain dynamic content<br>that can change despite the underlying configuration<br>itself not changing. A good example of this is the<br>res_pjsip_endpoint_identifier_ip module which allows<br>specifying hostnames. While the configuration may not<br>change between reloads the DNS information of the<br>hostnames can.<br><br>This change adds the ability for a sorcery object to be<br>marked as having dynamic contents which is then taken<br>into account when reloading by the sorcery file based<br>config module. If there is an object with dynamic content<br>then a reload will be forced while if there are none<br>then the existing behavior of not reloading occurs.<br><br>ASTERISK-29321<br><br>Change-Id: I9342dc55be46cc00204533c266a68d972760a0b1<br>---<br>M include/asterisk/sorcery.h<br>M main/sorcery.c<br>M res/res_pjsip_endpoint_identifier_ip.c<br>M res/res_sorcery_config.c<br>4 files changed, 53 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h</span><br><span>index a0ec653..c3e2864 100644</span><br><span>--- a/include/asterisk/sorcery.h</span><br><span>+++ b/include/asterisk/sorcery.h</span><br><span>@@ -1559,6 +1559,28 @@</span><br><span> int ast_sorcery_object_set_extended(const void *object, const char *name, const char *value);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Get whether an object contains dynamic contents or not</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param object Pointer to a sorcery object</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 19</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 18.3.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.17.0</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+unsigned int ast_sorcery_object_has_dynamic_contents(const void *object);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Set the dynamic contents flag on a sorcery object</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param object Pointer to a sorcery object</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 19</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 18.3.0</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 16.17.0</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sorcery_object_set_has_dynamic_contents(const void *object);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span> * \brief ao2 object comparator based on sorcery id.</span><br><span> */</span><br><span> int ast_sorcery_object_id_compare(void *obj, void *arg, int flags);</span><br><span>diff --git a/main/sorcery.c b/main/sorcery.c</span><br><span>index 0ada81e..ad10aee 100644</span><br><span>--- a/main/sorcery.c</span><br><span>+++ b/main/sorcery.c</span><br><span>@@ -139,6 +139,9 @@</span><br><span> </span><br><span> /*! \brief Time that the object was created */</span><br><span> struct timeval created;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Whether this object has dynamic contents or not */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int has_dynamic_contents:1;</span><br><span> };</span><br><span> </span><br><span> /*! \brief Structure for registered object type */</span><br><span>@@ -2366,6 +2369,20 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+unsigned int ast_sorcery_object_has_dynamic_contents(const void *object)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ast_sorcery_object_details *details = object;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return details->object->has_dynamic_contents;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void ast_sorcery_object_set_has_dynamic_contents(const void *object)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct ast_sorcery_object_details *details = object;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ details->object->has_dynamic_contents = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)</span><br><span> {</span><br><span> RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);</span><br><span>diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c</span><br><span>index a2aa934..d8de261 100644</span><br><span>--- a/res/res_pjsip_endpoint_identifier_ip.c</span><br><span>+++ b/res/res_pjsip_endpoint_identifier_ip.c</span><br><span>@@ -515,6 +515,9 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Hosts can produce dynamic content, so mark the identify as such */</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sorcery_object_set_has_dynamic_contents(obj);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Resolve the match addresses now */</span><br><span> i = ao2_iterator_init(identify->hosts, 0);</span><br><span> while ((current_string = ao2_iterator_next(&i))) {</span><br><span>diff --git a/res/res_sorcery_config.c b/res/res_sorcery_config.c</span><br><span>index 67679a2..dfe7a35 100644</span><br><span>--- a/res/res_sorcery_config.c</span><br><span>+++ b/res/res_sorcery_config.c</span><br><span>@@ -65,6 +65,9 @@</span><br><span> /*! \brief Configuration is invalid in some way, force reload */</span><br><span> unsigned int configuration_invalid:1;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Configuration contains at least one object with dynamic contents */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int has_dynamic_contents:1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief Filename of the configuration file */</span><br><span> char filename[];</span><br><span> };</span><br><span>@@ -313,12 +316,13 @@</span><br><span> static void sorcery_config_internal_load(void *data, const struct ast_sorcery *sorcery, const char *type, unsigned int reload)</span><br><span> {</span><br><span> struct sorcery_config *config = data;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_flags flags = { reload && !config->configuration_invalid ? CONFIG_FLAG_FILEUNCHANGED : 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_flags flags = { reload && !config->configuration_invalid && !config->has_dynamic_contents ? CONFIG_FLAG_FILEUNCHANGED : 0 };</span><br><span> struct ast_config *cfg = ast_config_load2(config->filename, config->uuid, flags);</span><br><span> struct ast_category *category = NULL;</span><br><span> RAII_VAR(struct ao2_container *, objects, NULL, ao2_cleanup);</span><br><span> const char *id = NULL;</span><br><span> unsigned int buckets = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int has_dynamic_contents = 0;</span><br><span> </span><br><span> if (!cfg) {</span><br><span> ast_log(LOG_ERROR, "Unable to load config file '%s'\n", config->filename);</span><br><span>@@ -430,9 +434,15 @@</span><br><span> ast_log(LOG_NOTICE, "Retaining existing configuration for object of type '%s' with id '%s'\n", type, id);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* We store the dynamic contents state until the end in case this reload or load</span><br><span style="color: hsl(120, 100%, 40%);">+ * gets rolled back.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ has_dynamic_contents |= ast_sorcery_object_has_dynamic_contents(obj);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> ao2_link(objects, obj);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ config->has_dynamic_contents = has_dynamic_contents;</span><br><span> ao2_global_obj_replace_unref(config->objects, objects);</span><br><span> ast_config_destroy(cfg);</span><br><span> }</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/15561">change 15561</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/15561"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: I9342dc55be46cc00204533c266a68d972760a0b1 </div>
<div style="display:none"> Gerrit-Change-Number: 15561 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>