registry_init.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "daemon/common.h"
  3. #include "registry_internals.h"
  4. void registry_db_stats(void) {
  5. size_t persons = 0;
  6. size_t persons_urls = 0;
  7. size_t max_urls_per_person = 0;
  8. REGISTRY_PERSON *p;
  9. dfe_start_read(registry.persons, p) {
  10. persons++;
  11. size_t urls = 0;
  12. for(REGISTRY_PERSON_URL *pu = p->person_urls ; pu ;pu = pu->next)
  13. urls++;
  14. if(urls > max_urls_per_person)
  15. max_urls_per_person = urls;
  16. persons_urls += urls;
  17. }
  18. dfe_done(p);
  19. size_t machines = 0;
  20. size_t machines_urls = 0;
  21. size_t max_urls_per_machine = 0;
  22. REGISTRY_MACHINE *m;
  23. dfe_start_read(registry.machines, m) {
  24. machines++;
  25. size_t urls = 0;
  26. for(REGISTRY_MACHINE_URL *mu = m->machine_urls ; mu ;mu = mu->next)
  27. urls++;
  28. if(urls > max_urls_per_machine)
  29. max_urls_per_machine = urls;
  30. machines_urls += urls;
  31. }
  32. dfe_done(m);
  33. netdata_log_info("REGISTRY: persons %zu, person_urls %zu, max_urls_per_person %zu, "
  34. "machines %zu, machine_urls %zu, max_urls_per_machine %zu",
  35. persons, persons_urls, max_urls_per_person,
  36. machines, machines_urls, max_urls_per_machine);
  37. }
  38. void registry_generate_curl_urls(void) {
  39. FILE *fp = fopen("/tmp/registry.curl", "w+");
  40. if (unlikely(!fp))
  41. return;
  42. REGISTRY_PERSON *p;
  43. dfe_start_read(registry.persons, p) {
  44. for(REGISTRY_PERSON_URL *pu = p->person_urls ; pu ;pu = pu->next) {
  45. fprintf(fp, "do_curl '%s' '%s' '%s'\n", p->guid, pu->machine->guid, string2str(pu->url));
  46. }
  47. }
  48. dfe_done(p);
  49. fclose(fp);
  50. }
  51. int registry_init(void) {
  52. char filename[FILENAME_MAX + 1];
  53. // registry enabled?
  54. if(web_server_mode != WEB_SERVER_MODE_NONE) {
  55. registry.enabled = config_get_boolean(CONFIG_SECTION_REGISTRY, "enabled", 0);
  56. }
  57. else {
  58. netdata_log_info("Registry is disabled - use the central netdata");
  59. config_set_boolean(CONFIG_SECTION_REGISTRY, "enabled", 0);
  60. registry.enabled = 0;
  61. }
  62. // path names
  63. snprintfz(filename, FILENAME_MAX, "%s/registry", netdata_configured_varlib_dir);
  64. registry.pathname = config_get(CONFIG_SECTION_DIRECTORIES, "registry", filename);
  65. if(mkdir(registry.pathname, 0770) == -1 && errno != EEXIST)
  66. fatal("Cannot create directory '%s'.", registry.pathname);
  67. // filenames
  68. snprintfz(filename, FILENAME_MAX, "%s/netdata.public.unique.id", registry.pathname);
  69. registry.machine_guid_filename = config_get(CONFIG_SECTION_REGISTRY, "netdata unique id file", filename);
  70. snprintfz(filename, FILENAME_MAX, "%s/registry.db", registry.pathname);
  71. registry.db_filename = config_get(CONFIG_SECTION_REGISTRY, "registry db file", filename);
  72. snprintfz(filename, FILENAME_MAX, "%s/registry-log.db", registry.pathname);
  73. registry.log_filename = config_get(CONFIG_SECTION_REGISTRY, "registry log file", filename);
  74. // configuration options
  75. registry.save_registry_every_entries = (unsigned long long)config_get_number(CONFIG_SECTION_REGISTRY, "registry save db every new entries", 1000000);
  76. registry.persons_expiration = config_get_number(CONFIG_SECTION_REGISTRY, "registry expire idle persons days", 365) * 86400;
  77. registry.registry_domain = config_get(CONFIG_SECTION_REGISTRY, "registry domain", "");
  78. registry.registry_to_announce = config_get(CONFIG_SECTION_REGISTRY, "registry to announce", "https://registry.my-netdata.io");
  79. registry.hostname = config_get(CONFIG_SECTION_REGISTRY, "registry hostname", netdata_configured_hostname);
  80. registry.verify_cookies_redirects = config_get_boolean(CONFIG_SECTION_REGISTRY, "verify browser cookies support", 1);
  81. registry.enable_cookies_samesite_secure = config_get_boolean(CONFIG_SECTION_REGISTRY, "enable cookies SameSite and Secure", 1);
  82. registry_update_cloud_base_url();
  83. setenv("NETDATA_REGISTRY_HOSTNAME", registry.hostname, 1);
  84. setenv("NETDATA_REGISTRY_URL", registry.registry_to_announce, 1);
  85. registry.max_url_length = (size_t)config_get_number(CONFIG_SECTION_REGISTRY, "max URL length", 1024);
  86. if(registry.max_url_length < 10) {
  87. registry.max_url_length = 10;
  88. config_set_number(CONFIG_SECTION_REGISTRY, "max URL length", (long long)registry.max_url_length);
  89. }
  90. registry.max_name_length = (size_t)config_get_number(CONFIG_SECTION_REGISTRY, "max URL name length", 50);
  91. if(registry.max_name_length < 10) {
  92. registry.max_name_length = 10;
  93. config_set_number(CONFIG_SECTION_REGISTRY, "max URL name length", (long long)registry.max_name_length);
  94. }
  95. bool use_mmap = config_get_boolean(CONFIG_SECTION_REGISTRY, "use mmap", false);
  96. // initialize entries counters
  97. registry.persons_count = 0;
  98. registry.machines_count = 0;
  99. registry.usages_count = 0;
  100. registry.persons_urls_count = 0;
  101. registry.machines_urls_count = 0;
  102. // initialize locks
  103. netdata_mutex_init(&registry.lock);
  104. // load the registry database
  105. if(registry.enabled) {
  106. // create dictionaries
  107. registry.persons = dictionary_create(REGISTRY_DICTIONARY_OPTIONS);
  108. registry.machines = dictionary_create(REGISTRY_DICTIONARY_OPTIONS);
  109. // initialize the allocators
  110. size_t min_page_size = 4 * 1024;
  111. size_t max_page_size = 1024 * 1024;
  112. if(use_mmap) {
  113. min_page_size = 100 * 1024 * 1024;
  114. max_page_size = 512 * 1024 * 1024;
  115. }
  116. registry.persons_aral = aral_create("registry_persons", sizeof(REGISTRY_PERSON),
  117. min_page_size / sizeof(REGISTRY_PERSON), max_page_size,
  118. &registry.aral_stats,
  119. "registry_persons",
  120. &netdata_configured_cache_dir,
  121. use_mmap, true);
  122. registry.machines_aral = aral_create("registry_machines", sizeof(REGISTRY_MACHINE),
  123. min_page_size / sizeof(REGISTRY_MACHINE), max_page_size,
  124. &registry.aral_stats,
  125. "registry_machines",
  126. &netdata_configured_cache_dir,
  127. use_mmap, true);
  128. registry.person_urls_aral = aral_create("registry_person_urls", sizeof(REGISTRY_PERSON_URL),
  129. min_page_size / sizeof(REGISTRY_PERSON_URL), max_page_size,
  130. &registry.aral_stats,
  131. "registry_person_urls",
  132. &netdata_configured_cache_dir,
  133. use_mmap, true);
  134. registry.machine_urls_aral = aral_create("registry_machine_urls", sizeof(REGISTRY_MACHINE_URL),
  135. min_page_size / sizeof(REGISTRY_MACHINE_URL), max_page_size,
  136. &registry.aral_stats,
  137. "registry_machine_urls",
  138. &netdata_configured_cache_dir,
  139. use_mmap, true);
  140. // disable cancelability to avoid enable/disable per item in the dictionary locks
  141. netdata_thread_disable_cancelability();
  142. registry_log_open();
  143. registry_db_load();
  144. registry_log_load();
  145. if(unlikely(registry_db_should_be_saved()))
  146. registry_db_save();
  147. // registry_db_stats();
  148. // registry_generate_curl_urls();
  149. // exit(0);
  150. netdata_thread_enable_cancelability();
  151. }
  152. return 0;
  153. }
  154. static int machine_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *data __maybe_unused) {
  155. REGISTRY_MACHINE *m = (REGISTRY_MACHINE *)entry;
  156. int count = 0;
  157. while(m->machine_urls) {
  158. registry_machine_url_unlink_from_machine_and_free(m, m->machine_urls);
  159. count++;
  160. }
  161. aral_freez(registry.machines_aral, m);
  162. return count + 1;
  163. }
  164. static int registry_person_del_callback(const DICTIONARY_ITEM *item __maybe_unused, void *entry, void *d __maybe_unused) {
  165. REGISTRY_PERSON *p = (REGISTRY_PERSON *)entry;
  166. netdata_log_debug(D_REGISTRY, "Registry: registry_person_del('%s'): deleting person", p->guid);
  167. while(p->person_urls)
  168. registry_person_unlink_from_url(p, (REGISTRY_PERSON_URL *)p->person_urls);
  169. //debug(D_REGISTRY, "Registry: deleting person '%s' from persons registry", p->guid);
  170. //dictionary_del(registry.persons, p->guid);
  171. netdata_log_debug(D_REGISTRY, "Registry: freeing person '%s'", p->guid);
  172. aral_freez(registry.persons_aral, p);
  173. return 1;
  174. }
  175. void registry_free(void) {
  176. if(!registry.enabled) return;
  177. registry.enabled = false;
  178. netdata_log_debug(D_REGISTRY, "Registry: destroying persons dictionary");
  179. dictionary_walkthrough_read(registry.persons, registry_person_del_callback, NULL);
  180. dictionary_destroy(registry.persons);
  181. registry.persons = NULL;
  182. netdata_log_debug(D_REGISTRY, "Registry: destroying machines dictionary");
  183. dictionary_walkthrough_read(registry.machines, machine_delete_callback, NULL);
  184. dictionary_destroy(registry.machines);
  185. registry.machines = NULL;
  186. aral_destroy(registry.persons_aral);
  187. aral_destroy(registry.machines_aral);
  188. aral_destroy(registry.person_urls_aral);
  189. aral_destroy(registry.machine_urls_aral);
  190. registry.persons_aral = NULL;
  191. registry.machines_aral = NULL;
  192. registry.person_urls_aral = NULL;
  193. registry.machine_urls_aral = NULL;
  194. }