loader.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2006, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. * Kevin P. Fleming <kpfleming@digium.com>
  8. * Luigi Rizzo <rizzo@icir.org>
  9. *
  10. * See http://www.asterisk.org for more information about
  11. * the Asterisk project. Please do not directly contact
  12. * any of the maintainers of this project for assistance;
  13. * the project provides a web site, mailing lists and IRC
  14. * channels for your use.
  15. *
  16. * This program is free software, distributed under the terms of
  17. * the GNU General Public License Version 2. See the LICENSE file
  18. * at the top of the source tree.
  19. */
  20. /*! \file
  21. *
  22. * \brief Module Loader
  23. * \author Mark Spencer <markster@digium.com>
  24. * \author Kevin P. Fleming <kpfleming@digium.com>
  25. * \author Luigi Rizzo <rizzo@icir.org>
  26. * - See ModMngMnt
  27. */
  28. /*** MODULEINFO
  29. <support_level>core</support_level>
  30. ***/
  31. #include "asterisk.h"
  32. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  33. #include "asterisk/_private.h"
  34. #include "asterisk/paths.h" /* use ast_config_AST_MODULE_DIR */
  35. #include <dirent.h>
  36. #include "asterisk/dlinkedlists.h"
  37. #include "asterisk/module.h"
  38. #include "asterisk/config.h"
  39. #include "asterisk/channel.h"
  40. #include "asterisk/term.h"
  41. #include "asterisk/acl.h"
  42. #include "asterisk/manager.h"
  43. #include "asterisk/cdr.h"
  44. #include "asterisk/enum.h"
  45. #include "asterisk/http.h"
  46. #include "asterisk/lock.h"
  47. #include "asterisk/features_config.h"
  48. #include "asterisk/dsp.h"
  49. #include "asterisk/udptl.h"
  50. #include "asterisk/vector.h"
  51. #include "asterisk/app.h"
  52. #include "asterisk/test.h"
  53. #include "asterisk/cli.h"
  54. #include <dlfcn.h>
  55. #include "asterisk/md5.h"
  56. #include "asterisk/utils.h"
  57. /*** DOCUMENTATION
  58. <managerEvent language="en_US" name="Reload">
  59. <managerEventInstance class="EVENT_FLAG_SYSTEM">
  60. <synopsis>Raised when a module has been reloaded in Asterisk.</synopsis>
  61. <syntax>
  62. <parameter name="Module">
  63. <para>The name of the module that was reloaded, or
  64. <literal>All</literal> if all modules were reloaded</para>
  65. </parameter>
  66. <parameter name="Status">
  67. <para>The numeric status code denoting the success or failure
  68. of the reload request.</para>
  69. <enumlist>
  70. <enum name="0"><para>Success</para></enum>
  71. <enum name="1"><para>Request queued</para></enum>
  72. <enum name="2"><para>Module not found</para></enum>
  73. <enum name="3"><para>Error</para></enum>
  74. <enum name="4"><para>Reload already in progress</para></enum>
  75. <enum name="5"><para>Module uninitialized</para></enum>
  76. <enum name="6"><para>Reload not supported</para></enum>
  77. </enumlist>
  78. </parameter>
  79. </syntax>
  80. </managerEventInstance>
  81. </managerEvent>
  82. ***/
  83. #ifndef RTLD_NOW
  84. #define RTLD_NOW 0
  85. #endif
  86. #ifndef RTLD_LOCAL
  87. #define RTLD_LOCAL 0
  88. #endif
  89. struct ast_module_user {
  90. struct ast_channel *chan;
  91. AST_LIST_ENTRY(ast_module_user) entry;
  92. };
  93. AST_DLLIST_HEAD(module_user_list, ast_module_user);
  94. static const unsigned char expected_key[] =
  95. { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
  96. 0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
  97. static char buildopt_sum[33] = AST_BUILDOPT_SUM;
  98. AST_VECTOR(module_vector, struct ast_module *);
  99. /*!
  100. * \brief Internal flag to indicate all modules have been initially loaded.
  101. */
  102. static int modules_loaded;
  103. struct ast_module {
  104. const struct ast_module_info *info;
  105. #ifdef REF_DEBUG
  106. /*! Used to get module references into refs log */
  107. void *ref_debug;
  108. #endif
  109. /*! The shared lib. */
  110. void *lib;
  111. /*! Number of 'users' and other references currently holding the module. */
  112. int usecount;
  113. /*! List of users holding the module. */
  114. struct module_user_list users;
  115. struct {
  116. /*! The module running and ready to accept requests. */
  117. unsigned int running:1;
  118. /*! The module has declined to start. */
  119. unsigned int declined:1;
  120. /*! This module is being held open until it's time to shutdown. */
  121. unsigned int keepuntilshutdown:1;
  122. } flags;
  123. AST_DLLIST_ENTRY(ast_module) entry;
  124. char resource[0];
  125. };
  126. static AST_DLLIST_HEAD_STATIC(module_list, ast_module);
  127. static int module_vector_strcasecmp(struct ast_module *a, struct ast_module *b)
  128. {
  129. return strcasecmp(a->resource, b->resource);
  130. }
  131. static int module_vector_cmp(struct ast_module *a, struct ast_module *b)
  132. {
  133. /* if load_pri is not set, default is 128. Lower is better */
  134. int a_pri = ast_test_flag(a->info, AST_MODFLAG_LOAD_ORDER)
  135. ? a->info->load_pri : AST_MODPRI_DEFAULT;
  136. int b_pri = ast_test_flag(b->info, AST_MODFLAG_LOAD_ORDER)
  137. ? b->info->load_pri : AST_MODPRI_DEFAULT;
  138. /*
  139. * Returns comparison values for a vector sorted by priority.
  140. * <0 a_pri < b_pri
  141. * =0 a_pri == b_pri
  142. * >0 a_pri > b_pri
  143. */
  144. return a_pri - b_pri;
  145. }
  146. const char *ast_module_name(const struct ast_module *mod)
  147. {
  148. if (!mod || !mod->info) {
  149. return NULL;
  150. }
  151. return mod->info->name;
  152. }
  153. struct loadupdate {
  154. int (*updater)(void);
  155. AST_LIST_ENTRY(loadupdate) entry;
  156. };
  157. static AST_DLLIST_HEAD_STATIC(updaters, loadupdate);
  158. AST_MUTEX_DEFINE_STATIC(reloadlock);
  159. struct reload_queue_item {
  160. AST_LIST_ENTRY(reload_queue_item) entry;
  161. char module[0];
  162. };
  163. static int do_full_reload = 0;
  164. static AST_DLLIST_HEAD_STATIC(reload_queue, reload_queue_item);
  165. /*!
  166. * \internal
  167. *
  168. * This variable is set by load_dynamic_module so ast_module_register
  169. * can know what pointer is being registered.
  170. *
  171. * This is protected by the module_list lock.
  172. */
  173. static struct ast_module * volatile resource_being_loaded;
  174. /*!
  175. * \internal
  176. * \brief Used by AST_MODULE_INFO to register with the module loader.
  177. *
  178. * This function is automatically called when each module is opened.
  179. * It must never be used from outside AST_MODULE_INFO.
  180. */
  181. void ast_module_register(const struct ast_module_info *info)
  182. {
  183. struct ast_module *mod;
  184. /*
  185. * This lock protects resource_being_loaded as well as the module
  186. * list. Normally we already have a lock on module_list when we
  187. * begin the load but locking again from here prevents corruption
  188. * if an asterisk module is dlopen'ed from outside the module loader.
  189. */
  190. AST_DLLIST_LOCK(&module_list);
  191. mod = resource_being_loaded;
  192. if (!mod) {
  193. AST_DLLIST_UNLOCK(&module_list);
  194. return;
  195. }
  196. ast_debug(5, "Registering module %s\n", info->name);
  197. /* This tells load_dynamic_module that we're registered. */
  198. resource_being_loaded = NULL;
  199. mod->info = info;
  200. #ifdef REF_DEBUG
  201. mod->ref_debug = ao2_t_alloc_options(0, NULL, AO2_ALLOC_OPT_LOCK_NOLOCK, info->name);
  202. #endif
  203. AST_LIST_HEAD_INIT(&mod->users);
  204. AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
  205. AST_DLLIST_UNLOCK(&module_list);
  206. /* give the module a copy of its own handle, for later use in registrations and the like */
  207. *((struct ast_module **) &(info->self)) = mod;
  208. }
  209. static void module_destroy(struct ast_module *mod)
  210. {
  211. AST_LIST_HEAD_DESTROY(&mod->users);
  212. #ifdef REF_DEBUG
  213. ao2_cleanup(mod->ref_debug);
  214. #endif
  215. ast_free(mod);
  216. }
  217. void ast_module_unregister(const struct ast_module_info *info)
  218. {
  219. struct ast_module *mod = NULL;
  220. /* it is assumed that the users list in the module structure
  221. will already be empty, or we cannot have gotten to this
  222. point
  223. */
  224. AST_DLLIST_LOCK(&module_list);
  225. AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
  226. if (mod->info == info) {
  227. AST_DLLIST_REMOVE_CURRENT(entry);
  228. break;
  229. }
  230. }
  231. AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
  232. AST_DLLIST_UNLOCK(&module_list);
  233. if (mod) {
  234. ast_debug(5, "Unregistering module %s\n", info->name);
  235. module_destroy(mod);
  236. }
  237. }
  238. struct ast_module_user *__ast_module_user_add(struct ast_module *mod, struct ast_channel *chan)
  239. {
  240. struct ast_module_user *u;
  241. u = ast_calloc(1, sizeof(*u));
  242. if (!u) {
  243. return NULL;
  244. }
  245. u->chan = chan;
  246. AST_LIST_LOCK(&mod->users);
  247. AST_LIST_INSERT_HEAD(&mod->users, u, entry);
  248. AST_LIST_UNLOCK(&mod->users);
  249. #ifdef REF_DEBUG
  250. ao2_ref(mod->ref_debug, +1);
  251. #endif
  252. ast_atomic_fetchadd_int(&mod->usecount, +1);
  253. ast_update_use_count();
  254. return u;
  255. }
  256. void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
  257. {
  258. if (!u) {
  259. return;
  260. }
  261. AST_LIST_LOCK(&mod->users);
  262. u = AST_LIST_REMOVE(&mod->users, u, entry);
  263. AST_LIST_UNLOCK(&mod->users);
  264. if (!u) {
  265. /*
  266. * Was not in the list. Either a bad pointer or
  267. * __ast_module_user_hangup_all() has been called.
  268. */
  269. return;
  270. }
  271. #ifdef REF_DEBUG
  272. ao2_ref(mod->ref_debug, -1);
  273. #endif
  274. ast_atomic_fetchadd_int(&mod->usecount, -1);
  275. ast_free(u);
  276. ast_update_use_count();
  277. }
  278. void __ast_module_user_hangup_all(struct ast_module *mod)
  279. {
  280. struct ast_module_user *u;
  281. AST_LIST_LOCK(&mod->users);
  282. while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
  283. if (u->chan) {
  284. ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
  285. }
  286. #ifdef REF_DEBUG
  287. ao2_ref(mod->ref_debug, -1);
  288. #endif
  289. ast_atomic_fetchadd_int(&mod->usecount, -1);
  290. ast_free(u);
  291. }
  292. AST_LIST_UNLOCK(&mod->users);
  293. ast_update_use_count();
  294. }
  295. /*! \note
  296. * In addition to modules, the reload command handles some extra keywords
  297. * which are listed here together with the corresponding handlers.
  298. * This table is also used by the command completion code.
  299. */
  300. static struct reload_classes {
  301. const char *name;
  302. int (*reload_fn)(void);
  303. } reload_classes[] = { /* list in alpha order, longest match first for cli completion */
  304. { "acl", ast_named_acl_reload },
  305. { "cdr", ast_cdr_engine_reload },
  306. { "cel", ast_cel_engine_reload },
  307. { "dnsmgr", dnsmgr_reload },
  308. { "dsp", ast_dsp_reload},
  309. { "extconfig", read_config_maps },
  310. { "enum", ast_enum_reload },
  311. { "features", ast_features_config_reload },
  312. { "http", ast_http_reload },
  313. { "indications", ast_indications_reload },
  314. { "logger", logger_reload },
  315. { "manager", reload_manager },
  316. { "plc", ast_plc_reload },
  317. { "udptl", ast_udptl_reload },
  318. { NULL, NULL }
  319. };
  320. static int printdigest(const unsigned char *d)
  321. {
  322. int x, pos;
  323. char buf[256]; /* large enough so we don't have to worry */
  324. for (pos = 0, x = 0; x < 16; x++)
  325. pos += sprintf(buf + pos, " %02hhx", *d++);
  326. ast_debug(1, "Unexpected signature:%s\n", buf);
  327. return 0;
  328. }
  329. static int key_matches(const unsigned char *key1, const unsigned char *key2)
  330. {
  331. int x;
  332. for (x = 0; x < 16; x++) {
  333. if (key1[x] != key2[x])
  334. return 0;
  335. }
  336. return 1;
  337. }
  338. static int verify_key(const unsigned char *key)
  339. {
  340. struct MD5Context c;
  341. unsigned char digest[16];
  342. MD5Init(&c);
  343. MD5Update(&c, key, strlen((char *)key));
  344. MD5Final(digest, &c);
  345. if (key_matches(expected_key, digest))
  346. return 0;
  347. printdigest(digest);
  348. return -1;
  349. }
  350. static size_t resource_name_baselen(const char *name)
  351. {
  352. size_t len = strlen(name);
  353. if (len > 3 && !strcasecmp(name + len - 3, ".so")) {
  354. return len - 3;
  355. }
  356. return len;
  357. }
  358. static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
  359. {
  360. if (baselen1 != resource_name_baselen(name2)) {
  361. return -1;
  362. }
  363. return strncasecmp(name1, name2, baselen1);
  364. }
  365. static struct ast_module *find_resource(const char *resource, int do_lock)
  366. {
  367. struct ast_module *cur;
  368. size_t resource_baselen = resource_name_baselen(resource);
  369. if (do_lock) {
  370. AST_DLLIST_LOCK(&module_list);
  371. }
  372. AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
  373. if (!resource_name_match(resource, resource_baselen, cur->resource)) {
  374. break;
  375. }
  376. }
  377. if (do_lock) {
  378. AST_DLLIST_UNLOCK(&module_list);
  379. }
  380. return cur;
  381. }
  382. /*!
  383. * \brief dlclose(), with failure logging.
  384. */
  385. static void logged_dlclose(const char *name, void *lib)
  386. {
  387. char *error;
  388. if (!lib) {
  389. return;
  390. }
  391. /* Clear any existing error */
  392. dlerror();
  393. if (dlclose(lib)) {
  394. error = dlerror();
  395. ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
  396. S_OR(name, "unknown"), S_OR(error, "Unknown error"));
  397. }
  398. }
  399. #if defined(HAVE_RTLD_NOLOAD)
  400. /*!
  401. * \brief Check to see if the given resource is loaded.
  402. *
  403. * \param resource_name Name of the resource, including .so suffix.
  404. * \return False (0) if module is not loaded.
  405. * \return True (non-zero) if module is loaded.
  406. */
  407. static int is_module_loaded(const char *resource_name)
  408. {
  409. char fn[PATH_MAX] = "";
  410. void *lib;
  411. snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR,
  412. resource_name);
  413. lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
  414. if (lib) {
  415. logged_dlclose(resource_name, lib);
  416. return 1;
  417. }
  418. return 0;
  419. }
  420. #endif
  421. static void unload_dynamic_module(struct ast_module *mod)
  422. {
  423. #if defined(HAVE_RTLD_NOLOAD)
  424. char *name = ast_strdupa(ast_module_name(mod));
  425. #endif
  426. void *lib = mod->lib;
  427. /* WARNING: the structure pointed to by mod is going to
  428. disappear when this operation succeeds, so we can't
  429. dereference it */
  430. logged_dlclose(ast_module_name(mod), lib);
  431. /* There are several situations where the module might still be resident
  432. * in memory.
  433. *
  434. * If somehow there was another dlopen() on the same module (unlikely,
  435. * since that all is supposed to happen in loader.c).
  436. *
  437. * Avoid the temptation of repeating the dlclose(). The other code that
  438. * dlopened the module still has its module reference, and should close
  439. * it itself. In other situations, dlclose() will happily return success
  440. * for as many times as you wish to call it.
  441. */
  442. #if defined(HAVE_RTLD_NOLOAD)
  443. if (is_module_loaded(name)) {
  444. ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
  445. }
  446. #endif
  447. }
  448. #define MODULE_LOCAL_ONLY (void *)-1
  449. /*!
  450. * \internal
  451. * \brief Attempt to dlopen a module.
  452. *
  453. * \param resource_in The module name to load.
  454. * \param so_ext ".so" or blank if ".so" is already part of resource_in.
  455. * \param filename Passed directly to dlopen.
  456. * \param flags Passed directly to dlopen.
  457. * \param suppress_logging Do not log any error from dlopen.
  458. *
  459. * \return Pointer to opened module, NULL on error.
  460. *
  461. * \warning module_list must be locked before calling this function.
  462. */
  463. static struct ast_module *load_dlopen(const char *resource_in, const char *so_ext,
  464. const char *filename, int flags, unsigned int suppress_logging)
  465. {
  466. struct ast_module *mod;
  467. ast_assert(!resource_being_loaded);
  468. mod = ast_calloc(1, sizeof(*mod) + strlen(resource_in) + strlen(so_ext) + 1);
  469. if (!mod) {
  470. return NULL;
  471. }
  472. sprintf(mod->resource, "%s%s", resource_in, so_ext); /* safe */
  473. resource_being_loaded = mod;
  474. mod->lib = dlopen(filename, flags);
  475. if (resource_being_loaded) {
  476. resource_being_loaded = NULL;
  477. if (mod->lib) {
  478. ast_log(LOG_ERROR, "Module '%s' did not register itself during load\n", resource_in);
  479. logged_dlclose(resource_in, mod->lib);
  480. } else if (!suppress_logging) {
  481. ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
  482. }
  483. ast_free(mod);
  484. return NULL;
  485. }
  486. return mod;
  487. }
  488. static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, unsigned int suppress_logging)
  489. {
  490. char fn[PATH_MAX];
  491. struct ast_module *mod;
  492. size_t resource_in_len = strlen(resource_in);
  493. int exports_globals;
  494. const char *so_ext = "";
  495. if (resource_in_len < 4 || strcasecmp(resource_in + resource_in_len - 3, ".so")) {
  496. so_ext = ".so";
  497. }
  498. snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, so_ext);
  499. /* Try loading in quiet mode first with flags to export global symbols.
  500. * If the module does not want to export globals we will close and reopen. */
  501. mod = load_dlopen(resource_in, so_ext, fn,
  502. global_symbols_only ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL,
  503. suppress_logging);
  504. if (!mod) {
  505. return NULL;
  506. }
  507. exports_globals = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
  508. if ((global_symbols_only && exports_globals) || (!global_symbols_only && !exports_globals)) {
  509. /* The first dlopen had the correct flags. */
  510. return mod;
  511. }
  512. /* Close the module so we can reopen with correct flags. */
  513. logged_dlclose(resource_in, mod->lib);
  514. if (global_symbols_only) {
  515. return MODULE_LOCAL_ONLY;
  516. }
  517. return load_dlopen(resource_in, so_ext, fn,
  518. exports_globals ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL,
  519. 0);
  520. }
  521. int modules_shutdown(void)
  522. {
  523. struct ast_module *mod;
  524. int somethingchanged;
  525. int res;
  526. AST_DLLIST_LOCK(&module_list);
  527. /*!\note Some resources, like timers, are started up dynamically, and thus
  528. * may be still in use, even if all channels are dead. We must therefore
  529. * check the usecount before asking modules to unload. */
  530. do {
  531. /* Reset flag before traversing the list */
  532. somethingchanged = 0;
  533. AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
  534. if (mod->usecount) {
  535. ast_debug(1, "Passing on %s: its use count is %d\n",
  536. mod->resource, mod->usecount);
  537. continue;
  538. }
  539. AST_DLLIST_REMOVE_CURRENT(entry);
  540. if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
  541. ast_verb(1, "Unloading %s\n", mod->resource);
  542. mod->info->unload();
  543. }
  544. module_destroy(mod);
  545. somethingchanged = 1;
  546. }
  547. AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
  548. if (!somethingchanged) {
  549. AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
  550. if (mod->flags.keepuntilshutdown) {
  551. ast_module_unref(mod);
  552. mod->flags.keepuntilshutdown = 0;
  553. somethingchanged = 1;
  554. }
  555. }
  556. }
  557. } while (somethingchanged);
  558. res = AST_DLLIST_EMPTY(&module_list);
  559. AST_DLLIST_UNLOCK(&module_list);
  560. return !res;
  561. }
  562. int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
  563. {
  564. struct ast_module *mod;
  565. int res = -1;
  566. int error = 0;
  567. AST_DLLIST_LOCK(&module_list);
  568. if (!(mod = find_resource(resource_name, 0))) {
  569. AST_DLLIST_UNLOCK(&module_list);
  570. ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
  571. return -1;
  572. }
  573. if (!mod->flags.running || mod->flags.declined) {
  574. ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
  575. error = 1;
  576. }
  577. if (!error && (mod->usecount > 0)) {
  578. if (force)
  579. ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n",
  580. resource_name, mod->usecount);
  581. else {
  582. ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
  583. mod->usecount);
  584. error = 1;
  585. }
  586. }
  587. if (!error) {
  588. /* Request any channels attached to the module to hangup. */
  589. __ast_module_user_hangup_all(mod);
  590. ast_verb(1, "Unloading %s\n", mod->resource);
  591. res = mod->info->unload();
  592. if (res) {
  593. ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
  594. if (force <= AST_FORCE_FIRM) {
  595. error = 1;
  596. } else {
  597. ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
  598. }
  599. }
  600. if (!error) {
  601. /*
  602. * Request hangup on any channels that managed to get attached
  603. * while we called the module unload function.
  604. */
  605. __ast_module_user_hangup_all(mod);
  606. sched_yield();
  607. }
  608. }
  609. if (!error)
  610. mod->flags.running = mod->flags.declined = 0;
  611. AST_DLLIST_UNLOCK(&module_list);
  612. if (!error) {
  613. unload_dynamic_module(mod);
  614. ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
  615. ast_update_use_count();
  616. }
  617. return res;
  618. }
  619. static int module_matches_helper_type(struct ast_module *mod, enum ast_module_helper_type type)
  620. {
  621. switch (type) {
  622. case AST_MODULE_HELPER_UNLOAD:
  623. return !mod->usecount && mod->flags.running && !mod->flags.declined;
  624. case AST_MODULE_HELPER_RELOAD:
  625. return mod->flags.running && mod->info->reload;
  626. case AST_MODULE_HELPER_RUNNING:
  627. return mod->flags.running;
  628. case AST_MODULE_HELPER_LOADED:
  629. /* if we have a 'struct ast_module' then we're loaded. */
  630. return 1;
  631. default:
  632. /* This function is not called for AST_MODULE_HELPER_LOAD. */
  633. /* Unknown ast_module_helper_type. Assume it doesn't match. */
  634. ast_assert(0);
  635. return 0;
  636. }
  637. }
  638. struct module_load_word {
  639. const char *word;
  640. size_t len;
  641. size_t moddir_len;
  642. };
  643. static int module_load_helper_on_file(const char *dir_name, const char *filename, void *obj)
  644. {
  645. struct module_load_word *word = obj;
  646. struct ast_module *mod;
  647. char *filename_merged = NULL;
  648. /* dir_name will never be shorter than word->moddir_len. */
  649. dir_name += word->moddir_len;
  650. if (!ast_strlen_zero(dir_name)) {
  651. ast_assert(dir_name[0] == '/');
  652. dir_name += 1;
  653. if (ast_asprintf(&filename_merged, "%s/%s", dir_name, filename) < 0) {
  654. /* If we can't allocate the string just give up! */
  655. return -1;
  656. }
  657. filename = filename_merged;
  658. }
  659. if (!strncasecmp(filename, word->word, word->len)) {
  660. /* Don't list files that are already loaded! */
  661. mod = find_resource(filename, 0);
  662. if (!mod || !mod->flags.running) {
  663. ast_cli_completion_add(ast_strdup(filename));
  664. }
  665. }
  666. ast_free(filename_merged);
  667. return 0;
  668. }
  669. static void module_load_helper(const char *word)
  670. {
  671. struct module_load_word word_l = {
  672. .word = word,
  673. .len = strlen(word),
  674. .moddir_len = strlen(ast_config_AST_MODULE_DIR),
  675. };
  676. AST_DLLIST_LOCK(&module_list);
  677. ast_file_read_dirs(ast_config_AST_MODULE_DIR, module_load_helper_on_file, &word_l, -1);
  678. AST_DLLIST_UNLOCK(&module_list);
  679. }
  680. char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int _type)
  681. {
  682. enum ast_module_helper_type type = _type;
  683. struct ast_module *mod;
  684. int which = 0;
  685. int wordlen = strlen(word);
  686. char *ret = NULL;
  687. if (pos != rpos) {
  688. return NULL;
  689. }
  690. if (type == AST_MODULE_HELPER_LOAD) {
  691. module_load_helper(word);
  692. return NULL;
  693. }
  694. if (type == AST_MODULE_HELPER_RELOAD) {
  695. int idx;
  696. for (idx = 0; reload_classes[idx].name; idx++) {
  697. if (!strncasecmp(word, reload_classes[idx].name, wordlen) && ++which > state) {
  698. return ast_strdup(reload_classes[idx].name);
  699. }
  700. }
  701. }
  702. AST_DLLIST_LOCK(&module_list);
  703. AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
  704. if (!module_matches_helper_type(mod, type)) {
  705. continue;
  706. }
  707. if (!strncasecmp(word, mod->resource, wordlen) && ++which > state) {
  708. ret = ast_strdup(mod->resource);
  709. break;
  710. }
  711. }
  712. AST_DLLIST_UNLOCK(&module_list);
  713. return ret;
  714. }
  715. void ast_process_pending_reloads(void)
  716. {
  717. struct reload_queue_item *item;
  718. modules_loaded = 1;
  719. AST_LIST_LOCK(&reload_queue);
  720. if (do_full_reload) {
  721. do_full_reload = 0;
  722. AST_LIST_UNLOCK(&reload_queue);
  723. ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
  724. ast_module_reload(NULL);
  725. return;
  726. }
  727. while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
  728. ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
  729. ast_module_reload(item->module);
  730. ast_free(item);
  731. }
  732. AST_LIST_UNLOCK(&reload_queue);
  733. }
  734. static void queue_reload_request(const char *module)
  735. {
  736. struct reload_queue_item *item;
  737. AST_LIST_LOCK(&reload_queue);
  738. if (do_full_reload) {
  739. AST_LIST_UNLOCK(&reload_queue);
  740. return;
  741. }
  742. if (ast_strlen_zero(module)) {
  743. /* A full reload request (when module is NULL) wipes out any previous
  744. reload requests and causes the queue to ignore future ones */
  745. while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
  746. ast_free(item);
  747. }
  748. do_full_reload = 1;
  749. } else {
  750. /* No reason to add the same module twice */
  751. AST_LIST_TRAVERSE(&reload_queue, item, entry) {
  752. if (!strcasecmp(item->module, module)) {
  753. AST_LIST_UNLOCK(&reload_queue);
  754. return;
  755. }
  756. }
  757. item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
  758. if (!item) {
  759. ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
  760. AST_LIST_UNLOCK(&reload_queue);
  761. return;
  762. }
  763. strcpy(item->module, module);
  764. AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
  765. }
  766. AST_LIST_UNLOCK(&reload_queue);
  767. }
  768. /*!
  769. * \since 12
  770. * \internal
  771. * \brief Publish a \ref stasis message regarding the reload result
  772. */
  773. static void publish_reload_message(const char *name, enum ast_module_reload_result result)
  774. {
  775. RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
  776. RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
  777. RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
  778. RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
  779. char res_buffer[8];
  780. if (!ast_manager_get_generic_type()) {
  781. return;
  782. }
  783. snprintf(res_buffer, sizeof(res_buffer), "%u", result);
  784. event_object = ast_json_pack("{s: s, s: s}",
  785. "Module", S_OR(name, "All"),
  786. "Status", res_buffer);
  787. json_object = ast_json_pack("{s: s, s: i, s: o}",
  788. "type", "Reload",
  789. "class_type", EVENT_FLAG_SYSTEM,
  790. "event", ast_json_ref(event_object));
  791. if (!json_object) {
  792. return;
  793. }
  794. payload = ast_json_payload_create(json_object);
  795. if (!payload) {
  796. return;
  797. }
  798. message = stasis_message_create(ast_manager_get_generic_type(), payload);
  799. if (!message) {
  800. return;
  801. }
  802. stasis_publish(ast_manager_get_topic(), message);
  803. }
  804. enum ast_module_reload_result ast_module_reload(const char *name)
  805. {
  806. struct ast_module *cur;
  807. enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
  808. int i;
  809. size_t name_baselen = name ? resource_name_baselen(name) : 0;
  810. /* If we aren't fully booted, we just pretend we reloaded but we queue this
  811. up to run once we are booted up. */
  812. if (!modules_loaded) {
  813. queue_reload_request(name);
  814. res = AST_MODULE_RELOAD_QUEUED;
  815. goto module_reload_exit;
  816. }
  817. if (ast_mutex_trylock(&reloadlock)) {
  818. ast_verb(3, "The previous reload command didn't finish yet\n");
  819. res = AST_MODULE_RELOAD_IN_PROGRESS;
  820. goto module_reload_exit;
  821. }
  822. ast_sd_notify("RELOAD=1");
  823. ast_lastreloadtime = ast_tvnow();
  824. if (ast_opt_lock_confdir) {
  825. int try;
  826. int lockres;
  827. for (try = 1, lockres = AST_LOCK_TIMEOUT; try < 6 && (lockres == AST_LOCK_TIMEOUT); try++) {
  828. lockres = ast_lock_path(ast_config_AST_CONFIG_DIR);
  829. if (lockres == AST_LOCK_TIMEOUT) {
  830. ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
  831. }
  832. }
  833. if (lockres != AST_LOCK_SUCCESS) {
  834. ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
  835. res = AST_MODULE_RELOAD_ERROR;
  836. goto module_reload_done;
  837. }
  838. }
  839. /* Call "predefined" reload here first */
  840. for (i = 0; reload_classes[i].name; i++) {
  841. if (!name || !strcasecmp(name, reload_classes[i].name)) {
  842. if (reload_classes[i].reload_fn() == AST_MODULE_LOAD_SUCCESS) {
  843. res = AST_MODULE_RELOAD_SUCCESS;
  844. } else if (res == AST_MODULE_RELOAD_NOT_FOUND) {
  845. res = AST_MODULE_RELOAD_ERROR;
  846. }
  847. }
  848. }
  849. if (name && res == AST_MODULE_RELOAD_SUCCESS) {
  850. if (ast_opt_lock_confdir) {
  851. ast_unlock_path(ast_config_AST_CONFIG_DIR);
  852. }
  853. goto module_reload_done;
  854. }
  855. AST_DLLIST_LOCK(&module_list);
  856. AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
  857. const struct ast_module_info *info = cur->info;
  858. if (name && resource_name_match(name, name_baselen, cur->resource)) {
  859. continue;
  860. }
  861. if (!cur->flags.running || cur->flags.declined) {
  862. if (res == AST_MODULE_RELOAD_NOT_FOUND) {
  863. res = AST_MODULE_RELOAD_UNINITIALIZED;
  864. }
  865. if (!name) {
  866. continue;
  867. }
  868. break;
  869. }
  870. if (!info->reload) { /* cannot be reloaded */
  871. if (res == AST_MODULE_RELOAD_NOT_FOUND) {
  872. res = AST_MODULE_RELOAD_NOT_IMPLEMENTED;
  873. }
  874. if (!name) {
  875. continue;
  876. }
  877. break;
  878. }
  879. ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
  880. if (info->reload() == AST_MODULE_LOAD_SUCCESS) {
  881. res = AST_MODULE_RELOAD_SUCCESS;
  882. } else if (res == AST_MODULE_RELOAD_NOT_FOUND) {
  883. res = AST_MODULE_RELOAD_ERROR;
  884. }
  885. if (name) {
  886. break;
  887. }
  888. }
  889. AST_DLLIST_UNLOCK(&module_list);
  890. if (ast_opt_lock_confdir) {
  891. ast_unlock_path(ast_config_AST_CONFIG_DIR);
  892. }
  893. module_reload_done:
  894. ast_mutex_unlock(&reloadlock);
  895. ast_sd_notify("READY=1");
  896. module_reload_exit:
  897. publish_reload_message(name, res);
  898. return res;
  899. }
  900. static unsigned int inspect_module(const struct ast_module *mod)
  901. {
  902. if (!mod->info->description) {
  903. ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
  904. return 1;
  905. }
  906. if (!mod->info->key) {
  907. ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
  908. return 1;
  909. }
  910. if (verify_key((unsigned char *) mod->info->key)) {
  911. ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
  912. return 1;
  913. }
  914. if (!ast_strlen_zero(mod->info->buildopt_sum) &&
  915. strcmp(buildopt_sum, mod->info->buildopt_sum)) {
  916. ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
  917. ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
  918. return 1;
  919. }
  920. return 0;
  921. }
  922. static enum ast_module_load_result start_resource(struct ast_module *mod)
  923. {
  924. char tmp[256];
  925. enum ast_module_load_result res;
  926. if (mod->flags.running) {
  927. return AST_MODULE_LOAD_SUCCESS;
  928. }
  929. if (!mod->info->load) {
  930. return AST_MODULE_LOAD_FAILURE;
  931. }
  932. if (!ast_fully_booted) {
  933. ast_verb(1, "Loading %s.\n", mod->resource);
  934. }
  935. res = mod->info->load();
  936. switch (res) {
  937. case AST_MODULE_LOAD_SUCCESS:
  938. if (!ast_fully_booted) {
  939. ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
  940. } else {
  941. ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
  942. }
  943. mod->flags.running = 1;
  944. ast_update_use_count();
  945. break;
  946. case AST_MODULE_LOAD_DECLINE:
  947. mod->flags.declined = 1;
  948. break;
  949. case AST_MODULE_LOAD_FAILURE:
  950. case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
  951. case AST_MODULE_LOAD_PRIORITY:
  952. break;
  953. }
  954. /* Make sure the newly started module is at the end of the list */
  955. AST_DLLIST_LOCK(&module_list);
  956. AST_DLLIST_REMOVE(&module_list, mod, entry);
  957. AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
  958. AST_DLLIST_UNLOCK(&module_list);
  959. return res;
  960. }
  961. /*! loads a resource based upon resource_name. If global_symbols_only is set
  962. * only modules with global symbols will be loaded.
  963. *
  964. * If the module_vector is provided (not NULL) the module is found and added to the
  965. * vector without running the module's load() function. By doing this, modules
  966. * can be initialized later in order by priority and dependencies.
  967. *
  968. * If the module_vector is not provided, the module's load function will be executed
  969. * immediately */
  970. static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct module_vector *resource_heap, int required)
  971. {
  972. struct ast_module *mod;
  973. enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
  974. if ((mod = find_resource(resource_name, 0))) {
  975. if (mod->flags.running) {
  976. ast_log(LOG_WARNING, "Module '%s' already loaded and running.\n", resource_name);
  977. return AST_MODULE_LOAD_DECLINE;
  978. }
  979. if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
  980. return AST_MODULE_LOAD_SKIP;
  981. } else {
  982. mod = load_dynamic_module(resource_name, global_symbols_only, suppress_logging);
  983. if (mod == MODULE_LOCAL_ONLY) {
  984. return AST_MODULE_LOAD_SKIP;
  985. }
  986. if (!mod) {
  987. if (!global_symbols_only) {
  988. ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
  989. }
  990. return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
  991. }
  992. }
  993. if (inspect_module(mod)) {
  994. goto prestart_error;
  995. }
  996. mod->flags.declined = 0;
  997. if (resource_heap) {
  998. if (AST_VECTOR_ADD_SORTED(resource_heap, mod, module_vector_cmp)) {
  999. goto prestart_error;
  1000. }
  1001. res = AST_MODULE_LOAD_PRIORITY;
  1002. } else {
  1003. res = start_resource(mod);
  1004. }
  1005. return res;
  1006. prestart_error:
  1007. ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
  1008. unload_dynamic_module(mod);
  1009. return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
  1010. }
  1011. int ast_load_resource(const char *resource_name)
  1012. {
  1013. int res;
  1014. AST_DLLIST_LOCK(&module_list);
  1015. res = load_resource(resource_name, 0, 0, NULL, 0);
  1016. if (!res) {
  1017. ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
  1018. }
  1019. AST_DLLIST_UNLOCK(&module_list);
  1020. return res;
  1021. }
  1022. struct load_order_entry {
  1023. char *resource;
  1024. int required;
  1025. AST_LIST_ENTRY(load_order_entry) entry;
  1026. };
  1027. AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
  1028. static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
  1029. {
  1030. struct load_order_entry *order;
  1031. size_t resource_baselen = resource_name_baselen(resource);
  1032. AST_LIST_TRAVERSE(load_order, order, entry) {
  1033. if (!resource_name_match(resource, resource_baselen, order->resource)) {
  1034. /* Make sure we have the proper setting for the required field
  1035. (we might have both load= and required= lines in modules.conf) */
  1036. order->required |= required;
  1037. return NULL;
  1038. }
  1039. }
  1040. if (!(order = ast_calloc(1, sizeof(*order))))
  1041. return NULL;
  1042. order->resource = ast_strdup(resource);
  1043. if (!order->resource) {
  1044. ast_free(order);
  1045. return NULL;
  1046. }
  1047. order->required = required;
  1048. AST_LIST_INSERT_TAIL(load_order, order, entry);
  1049. return order;
  1050. }
  1051. AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry);
  1052. /*! loads modules in order by load_pri, updates mod_count
  1053. \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
  1054. */
  1055. static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
  1056. {
  1057. struct module_vector resource_heap;
  1058. struct load_order_entry *order;
  1059. struct load_retries load_retries;
  1060. int count = 0;
  1061. int res = 0;
  1062. int i = 0;
  1063. #define LOAD_RETRIES 4
  1064. AST_LIST_HEAD_INIT_NOLOCK(&load_retries);
  1065. if (AST_VECTOR_INIT(&resource_heap, 500)) {
  1066. ast_log(LOG_ERROR, "Failed to initialize module loader.\n");
  1067. return -1;
  1068. }
  1069. /* first, add find and add modules to heap */
  1070. AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
  1071. enum ast_module_load_result lres;
  1072. /* Suppress log messages unless this is the last pass */
  1073. lres = load_resource(order->resource, global_symbols, 1, &resource_heap, order->required);
  1074. ast_debug(3, "PASS 0: %-46s %d %d\n", order->resource, lres, global_symbols);
  1075. switch (lres) {
  1076. case AST_MODULE_LOAD_SUCCESS:
  1077. /* We're supplying a heap so SUCCESS isn't possible but we still have to test for it. */
  1078. break;
  1079. case AST_MODULE_LOAD_FAILURE:
  1080. case AST_MODULE_LOAD_DECLINE:
  1081. /*
  1082. * DECLINE or FAILURE means there was an issue with dlopen or module_register
  1083. * which might be retryable. LOAD_FAILURE only happens for required modules
  1084. * but we're still going to retry. We need to remove the entry from the
  1085. * load_order list and add it to the load_retries list.
  1086. */
  1087. AST_LIST_REMOVE_CURRENT(entry);
  1088. AST_LIST_INSERT_TAIL(&load_retries, order, entry);
  1089. break;
  1090. case AST_MODULE_LOAD_SKIP:
  1091. /*
  1092. * SKIP means that dlopen worked but global_symbols was set and this module doesn't qualify.
  1093. * Leave it in load_order for the next call of load_resource_list.
  1094. */
  1095. break;
  1096. case AST_MODULE_LOAD_PRIORITY:
  1097. /* load_resource worked and the module was added to the priority vector */
  1098. AST_LIST_REMOVE_CURRENT(entry);
  1099. ast_free(order->resource);
  1100. ast_free(order);
  1101. break;
  1102. }
  1103. }
  1104. AST_LIST_TRAVERSE_SAFE_END;
  1105. /* Retry the failures until the list is empty or we reach LOAD_RETRIES */
  1106. for (i = 0; !AST_LIST_EMPTY(&load_retries) && i < LOAD_RETRIES; i++) {
  1107. AST_LIST_TRAVERSE_SAFE_BEGIN(&load_retries, order, entry) {
  1108. enum ast_module_load_result lres;
  1109. /* Suppress log messages unless this is the last pass */
  1110. lres = load_resource(order->resource, global_symbols, (i < LOAD_RETRIES - 1), &resource_heap, order->required);
  1111. ast_debug(3, "PASS %d %-46s %d %d\n", i + 1, order->resource, lres, global_symbols);
  1112. switch (lres) {
  1113. /* These are all retryable. */
  1114. case AST_MODULE_LOAD_SUCCESS:
  1115. case AST_MODULE_LOAD_DECLINE:
  1116. break;
  1117. case AST_MODULE_LOAD_FAILURE:
  1118. /* LOAD_FAILURE only happens for required modules */
  1119. if (i == LOAD_RETRIES - 1) {
  1120. /* This was the last chance to load a required module*/
  1121. ast_log(LOG_ERROR, "*** Failed to load module %s - Required\n", order->resource);
  1122. fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);
  1123. res = -2;
  1124. goto done;
  1125. }
  1126. break;;
  1127. case AST_MODULE_LOAD_SKIP:
  1128. /*
  1129. * SKIP means that dlopen worked but global_symbols was set and this module
  1130. * doesn't qualify. Put it back in load_order for the next call of
  1131. * load_resource_list.
  1132. */
  1133. AST_LIST_REMOVE_CURRENT(entry);
  1134. AST_LIST_INSERT_TAIL(load_order, order, entry);
  1135. break;
  1136. case AST_MODULE_LOAD_PRIORITY:
  1137. /* load_resource worked and the module was added to the priority heap */
  1138. AST_LIST_REMOVE_CURRENT(entry);
  1139. ast_free(order->resource);
  1140. ast_free(order);
  1141. break;
  1142. }
  1143. }
  1144. AST_LIST_TRAVERSE_SAFE_END;
  1145. }
  1146. /* second remove modules from heap sorted by priority */
  1147. for (i = 0; i < AST_VECTOR_SIZE(&resource_heap); i++) {
  1148. struct ast_module *mod = AST_VECTOR_GET(&resource_heap, i);
  1149. enum ast_module_load_result lres;
  1150. lres = start_resource(mod);
  1151. ast_debug(3, "START: %-46s %d %d\n", mod->resource, lres, global_symbols);
  1152. switch (lres) {
  1153. case AST_MODULE_LOAD_SUCCESS:
  1154. count++;
  1155. case AST_MODULE_LOAD_DECLINE:
  1156. break;
  1157. case AST_MODULE_LOAD_FAILURE:
  1158. ast_log(LOG_ERROR, "*** Failed to load module %s\n", mod->resource);
  1159. res = -1;
  1160. goto done;
  1161. case AST_MODULE_LOAD_SKIP:
  1162. case AST_MODULE_LOAD_PRIORITY:
  1163. break;
  1164. }
  1165. }
  1166. done:
  1167. while ((order = AST_LIST_REMOVE_HEAD(&load_retries, entry))) {
  1168. ast_free(order->resource);
  1169. ast_free(order);
  1170. }
  1171. if (mod_count) {
  1172. *mod_count += count;
  1173. }
  1174. AST_VECTOR_FREE(&resource_heap);
  1175. return res;
  1176. }
  1177. int load_modules(unsigned int preload_only)
  1178. {
  1179. struct ast_config *cfg;
  1180. struct load_order_entry *order;
  1181. struct ast_variable *v;
  1182. unsigned int load_count;
  1183. struct load_order load_order;
  1184. int res = 0;
  1185. struct ast_flags config_flags = { 0 };
  1186. int modulecount = 0;
  1187. struct dirent *dirent;
  1188. DIR *dir;
  1189. ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
  1190. AST_LIST_HEAD_INIT_NOLOCK(&load_order);
  1191. AST_DLLIST_LOCK(&module_list);
  1192. cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
  1193. if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
  1194. ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
  1195. goto done;
  1196. }
  1197. /* first, find all the modules we have been explicitly requested to load */
  1198. for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
  1199. if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
  1200. add_to_load_order(v->value, &load_order, 0);
  1201. }
  1202. if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
  1203. /* Add the module to the list and make sure it's required */
  1204. add_to_load_order(v->value, &load_order, 1);
  1205. ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
  1206. }
  1207. }
  1208. /* check if 'autoload' is on */
  1209. if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
  1210. /* if we are allowed to load dynamic modules, scan the directory for
  1211. for all available modules and add them as well */
  1212. if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
  1213. while ((dirent = readdir(dir))) {
  1214. int ld = strlen(dirent->d_name);
  1215. /* Must end in .so to load it. */
  1216. if (ld < 4)
  1217. continue;
  1218. if (strcasecmp(dirent->d_name + ld - 3, ".so"))
  1219. continue;
  1220. /* if there is already a module by this name in the module_list,
  1221. skip this file */
  1222. if (find_resource(dirent->d_name, 0))
  1223. continue;
  1224. add_to_load_order(dirent->d_name, &load_order, 0);
  1225. }
  1226. closedir(dir);
  1227. } else {
  1228. if (!ast_opt_quiet)
  1229. ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
  1230. ast_config_AST_MODULE_DIR);
  1231. }
  1232. }
  1233. /* now scan the config for any modules we are prohibited from loading and
  1234. remove them from the load order */
  1235. for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
  1236. size_t baselen;
  1237. if (strcasecmp(v->name, "noload")) {
  1238. continue;
  1239. }
  1240. baselen = resource_name_baselen(v->value);
  1241. AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
  1242. if (!resource_name_match(v->value, baselen, order->resource)) {
  1243. AST_LIST_REMOVE_CURRENT(entry);
  1244. ast_free(order->resource);
  1245. ast_free(order);
  1246. }
  1247. }
  1248. AST_LIST_TRAVERSE_SAFE_END;
  1249. }
  1250. /* we are done with the config now, all the information we need is in the
  1251. load_order list */
  1252. ast_config_destroy(cfg);
  1253. load_count = 0;
  1254. AST_LIST_TRAVERSE(&load_order, order, entry)
  1255. load_count++;
  1256. if (load_count)
  1257. ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
  1258. /* first, load only modules that provide global symbols */
  1259. if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
  1260. goto done;
  1261. }
  1262. /* now load everything else */
  1263. if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
  1264. goto done;
  1265. }
  1266. done:
  1267. while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
  1268. ast_free(order->resource);
  1269. ast_free(order);
  1270. }
  1271. AST_DLLIST_UNLOCK(&module_list);
  1272. return res;
  1273. }
  1274. void ast_update_use_count(void)
  1275. {
  1276. /* Notify any module monitors that the use count for a
  1277. resource has changed */
  1278. struct loadupdate *m;
  1279. AST_LIST_LOCK(&updaters);
  1280. AST_LIST_TRAVERSE(&updaters, m, entry)
  1281. m->updater();
  1282. AST_LIST_UNLOCK(&updaters);
  1283. }
  1284. /*!
  1285. * \internal
  1286. * \brief Build an alpha sorted list of modules.
  1287. *
  1288. * \param alpha_module_list Pointer to uninitialized module_vector.
  1289. *
  1290. * This function always initializes alpha_module_list.
  1291. *
  1292. * \pre module_list must be locked.
  1293. */
  1294. static int alpha_module_list_create(struct module_vector *alpha_module_list)
  1295. {
  1296. struct ast_module *cur;
  1297. if (AST_VECTOR_INIT(alpha_module_list, 32)) {
  1298. return -1;
  1299. }
  1300. AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
  1301. if (AST_VECTOR_ADD_SORTED(alpha_module_list, cur, module_vector_strcasecmp)) {
  1302. return -1;
  1303. }
  1304. }
  1305. return 0;
  1306. }
  1307. int ast_update_module_list(int (*modentry)(const char *module, const char *description,
  1308. int usecnt, const char *status, const char *like,
  1309. enum ast_module_support_level support_level),
  1310. const char *like)
  1311. {
  1312. int total_mod_loaded = 0;
  1313. struct module_vector alpha_module_list;
  1314. AST_DLLIST_LOCK(&module_list);
  1315. if (!alpha_module_list_create(&alpha_module_list)) {
  1316. int idx;
  1317. for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
  1318. struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
  1319. total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
  1320. cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
  1321. }
  1322. }
  1323. AST_DLLIST_UNLOCK(&module_list);
  1324. AST_VECTOR_FREE(&alpha_module_list);
  1325. return total_mod_loaded;
  1326. }
  1327. int ast_update_module_list_data(int (*modentry)(const char *module, const char *description,
  1328. int usecnt, const char *status, const char *like,
  1329. enum ast_module_support_level support_level,
  1330. void *data),
  1331. const char *like, void *data)
  1332. {
  1333. int total_mod_loaded = 0;
  1334. struct module_vector alpha_module_list;
  1335. AST_DLLIST_LOCK(&module_list);
  1336. if (!alpha_module_list_create(&alpha_module_list)) {
  1337. int idx;
  1338. for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
  1339. struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
  1340. total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
  1341. cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
  1342. }
  1343. }
  1344. AST_DLLIST_UNLOCK(&module_list);
  1345. AST_VECTOR_FREE(&alpha_module_list);
  1346. return total_mod_loaded;
  1347. }
  1348. int ast_update_module_list_condition(int (*modentry)(const char *module, const char *description,
  1349. int usecnt, const char *status,
  1350. const char *like,
  1351. enum ast_module_support_level support_level,
  1352. void *data, const char *condition),
  1353. const char *like, void *data, const char *condition)
  1354. {
  1355. int conditions_met = 0;
  1356. struct module_vector alpha_module_list;
  1357. AST_DLLIST_LOCK(&module_list);
  1358. if (!alpha_module_list_create(&alpha_module_list)) {
  1359. int idx;
  1360. for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
  1361. struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
  1362. conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
  1363. cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
  1364. condition);
  1365. }
  1366. }
  1367. AST_DLLIST_UNLOCK(&module_list);
  1368. AST_VECTOR_FREE(&alpha_module_list);
  1369. return conditions_met;
  1370. }
  1371. /*! \brief Check if module exists */
  1372. int ast_module_check(const char *name)
  1373. {
  1374. struct ast_module *cur;
  1375. if (ast_strlen_zero(name))
  1376. return 0; /* FALSE */
  1377. cur = find_resource(name, 1);
  1378. return (cur != NULL);
  1379. }
  1380. int ast_loader_register(int (*v)(void))
  1381. {
  1382. struct loadupdate *tmp;
  1383. if (!(tmp = ast_malloc(sizeof(*tmp))))
  1384. return -1;
  1385. tmp->updater = v;
  1386. AST_LIST_LOCK(&updaters);
  1387. AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
  1388. AST_LIST_UNLOCK(&updaters);
  1389. return 0;
  1390. }
  1391. int ast_loader_unregister(int (*v)(void))
  1392. {
  1393. struct loadupdate *cur;
  1394. AST_LIST_LOCK(&updaters);
  1395. AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
  1396. if (cur->updater == v) {
  1397. AST_LIST_REMOVE_CURRENT(entry);
  1398. break;
  1399. }
  1400. }
  1401. AST_LIST_TRAVERSE_SAFE_END;
  1402. AST_LIST_UNLOCK(&updaters);
  1403. return cur ? 0 : -1;
  1404. }
  1405. struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
  1406. {
  1407. if (!mod) {
  1408. return NULL;
  1409. }
  1410. #ifdef REF_DEBUG
  1411. __ao2_ref_debug(mod->ref_debug, +1, "", file, line, func);
  1412. #endif
  1413. ast_atomic_fetchadd_int(&mod->usecount, +1);
  1414. ast_update_use_count();
  1415. return mod;
  1416. }
  1417. void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
  1418. {
  1419. if (!mod || mod->flags.keepuntilshutdown) {
  1420. return;
  1421. }
  1422. __ast_module_ref(mod, file, line, func);
  1423. mod->flags.keepuntilshutdown = 1;
  1424. }
  1425. void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
  1426. {
  1427. if (!mod) {
  1428. return;
  1429. }
  1430. #ifdef REF_DEBUG
  1431. __ao2_ref_debug(mod->ref_debug, -1, "", file, line, func);
  1432. #endif
  1433. ast_atomic_fetchadd_int(&mod->usecount, -1);
  1434. ast_update_use_count();
  1435. }
  1436. const char *support_level_map [] = {
  1437. [AST_MODULE_SUPPORT_UNKNOWN] = "unknown",
  1438. [AST_MODULE_SUPPORT_CORE] = "core",
  1439. [AST_MODULE_SUPPORT_EXTENDED] = "extended",
  1440. [AST_MODULE_SUPPORT_DEPRECATED] = "deprecated",
  1441. };
  1442. const char *ast_module_support_level_to_string(enum ast_module_support_level support_level)
  1443. {
  1444. return support_level_map[support_level];
  1445. }
  1446. /* The following exists for ABI compatibility */
  1447. #undef ast_module_ref
  1448. #undef ast_module_unref
  1449. struct ast_module *ast_module_ref(struct ast_module *mod);
  1450. void ast_module_unref(struct ast_module *mod);
  1451. struct ast_module *ast_module_ref(struct ast_module *mod)
  1452. {
  1453. return __ast_module_ref(mod, __FILE__, __LINE__, __PRETTY_FUNCTION__);
  1454. }
  1455. void ast_module_unref(struct ast_module *mod)
  1456. {
  1457. __ast_module_unref(mod, __FILE__, __LINE__, __PRETTY_FUNCTION__);
  1458. }