static json_t * hardware_process(void *results) { hardware_results_t *raw_results = results; result_desc_t desc = { .stable = false, .name = "Nop syscall overhead", .ignored = N_IGNORED }; result_t nopnulsyscall_result = process_result(N_RUNS, raw_results->nullSyscall_overhead, desc); /* Execlude ccnt, user-level and loop overheads */ desc.overhead = nopnulsyscall_result.min; result_t result = process_result(N_RUNS, raw_results->nullSyscall_results, desc); result_set_t set = { .name = "Hardware null_syscall thread", .n_results = 1, .n_extra_cols = 0, .results = &result }; json_t *array = json_array(); json_array_append_new(array, result_set_to_json(set)); set.name = "Nop syscall overhead"; set.results = &nopnulsyscall_result; json_array_append_new(array, result_set_to_json(set)); return array; } static benchmark_t hardware_benchmark = { .name = "hardware", .enabled = config_set(CONFIG_APP_HARDWAREBENCH), .results_pages = BYTES_TO_SIZE_BITS_PAGES(sizeof(hardware_results_t), seL4_PageBits), .process = hardware_process, .init = blank_init }; benchmark_t * hardware_benchmark_new(void) { return &hardware_benchmark; }
/* note_set_description */ int note_set_description(Note * note, char const * description) { String * d; if((d = string_new_replace(description, "\\", "\\\\")) == NULL) return -1; if(string_replace(&d, "\n", "\\n") != 0 || config_set(note->config, NULL, "description", d) != 0) { string_delete(d); return -1; } string_delete(note->description); note->description = d; return 0; }
static void test_monsters_attack(CuTest * tc) { faction *f, *f2; region *r; unit *u, *m; create_monsters(&f, &f2, &r, &u, &m); guard(m, GUARD_TAX); config_set("rules.monsters.attack_chance", "1"); plan_monsters(f2); CuAssertPtrNotNull(tc, find_order("ATTACKIERE 1", m)); test_cleanup(); }
static void test_monsters_attack_not(CuTest * tc) { faction *f, *f2; unit *u, *m; create_monsters(&f, &f2, &u, &m); setguard(m, true); setguard(u, true); config_set("rules.monsters.attack_chance", "0"); plan_monsters(f2); CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); test_cleanup(); }
static void test_dragon_moves(CuTest * tc) { faction *f, *f2; region *r; unit *u, *m; create_monsters(&f, &f2, &r, &u, &m); rsetpeasants(r, 0); rsetmoney(r, 0); rsetmoney(findregion(1, 0), 1000); set_level(m, SK_WEAPONLESS, 10); config_set("rules.monsters.attack_chance", ".0"); plan_monsters(f2); CuAssertPtrNotNull(tc, find_order("NACH O", m)); test_cleanup(); }
/* fetch a value from the config database - caller must free */ const char *config_get(const char *name) { TDB_DATA data; TDB_DATA key; key.dptr = name; key.dsize = strlen(name)+1; data = tdb_fetch(config_db, key); /* this trick allows config variables to show up in 'aconfig' as soon as they are used */ if (!data.dptr && config_set(name, "NOT_CONFIGURED") == 0) { data = tdb_fetch(config_db, key); } return data.dptr; }
static BOOT_CODE bool_t try_boot_sys_node(cpu_id_t cpu_id) { p_region_t boot_mem_reuse_p_reg; if (!map_kernel_window( boot_state.num_ioapic, boot_state.ioapic_paddr, boot_state.num_drhu, boot_state.drhu_list )) { return false; } setCurrentVSpaceRoot(kpptr_to_paddr(X86_GLOBAL_VSPACE_ROOT), 0); /* Sync up the compilers view of the world here to force the PD to actually * be set *right now* instead of delayed */ asm volatile("" ::: "memory"); /* reuse boot code/data memory */ boot_mem_reuse_p_reg.start = PADDR_LOAD; boot_mem_reuse_p_reg.end = (paddr_t)ki_boot_end - KERNEL_BASE_OFFSET; /* initialise the CPU */ if (!init_cpu(config_set(CONFIG_IRQ_IOAPIC) ? 1 : 0)) { return false; } /* initialise NDKS and kernel heap */ if (!init_sys_state( cpu_id, boot_state.mem_p_regs, boot_state.ui_info, boot_mem_reuse_p_reg, /* parameters below not modeled in abstract specification */ boot_state.num_drhu, boot_state.drhu_list, &boot_state.rmrr_list, &boot_state.vbe_info )) { return false; } return true; }
static void sasl_set_remote_success (PROFILE_INSTANCE *pi) { char *cp; struct configobj *appconfig = bp_get_config (pi -> channel -> conn); if (pro_debug) { fprintf (stderr, "sasl_set_remote_success\n"); fflush (stderr); } if (config_test_and_set (appconfig, SASL_REMOTE_CODE, "200") == CONFIG_OK) { config_set (appconfig, SASL_REMOTE_REASON, "login successful"); cp = config_get (appconfig, SASL_REMOTE_MECHANISM); bp_log (pi -> channel -> conn, LOG_PROF, 2, "sasl 200 %s %s", cp, config_get (appconfig, SASL_REMOTE_USERNAME)); } }
// simple standardized setup for commands that only modify config int modifyConfig(uint8_t configLabel, uint8_t paramSize, uint8_t paramMaxValue) { int param; uint8_t result = getNumParamData(¶m, paramSize); if (result == OK) { if (param <= paramMaxValue) { config_set(configLabel, param); return MODIFIED; } } if (result == NOTHING) { // return current setting printf("%d\r\n", config_get(configLabel)); return OK; } return ERR; }
static void test_monsters_learn_exp(CuTest * tc) { faction *f, *f2; unit *u, *m; skill* sk; create_monsters(&f, &f2, &u, &m); config_set("study.produceexp", "30"); u_setrace(u, u_race(m)); produceexp(u, SK_MELEE, u->number); sk = unit_skill(u, SK_MELEE); CuAssertTrue(tc, !sk); produceexp(m, SK_MELEE, u->number); sk = unit_skill(m, SK_MELEE); CuAssertTrue(tc, sk && (sk->level > 0 || (sk->level == 0 && sk->weeks > 0))); test_cleanup(); }
static void test_monsters_attack_ocean(CuTest * tc) { faction *f, *f2; region *r; unit *u, *m; create_monsters(&f, &f2, &u, &m); r = findregion(-1, 0); // ocean u = test_create_unit(u->faction, r); unit_setid(u, 2); m = test_create_unit(m->faction, r); assert(!m->region->land); config_set("rules.monsters.attack_chance", "1"); plan_monsters(f2); CuAssertPtrNotNull(tc, find_order("attack 2", m)); test_cleanup(); }
/******************************************************************************* 函数名称 : cwmp_node_get_PeriodicInformTime 功能描述 : 取得CPE连接ACS的某一个绝对时间 输入参数 : ws_env 运行环境 输出参数 : get_value 返回值 get_type 返回类型 返 回 值 : 执行成功返回ERR_SUCCESS 否则返回失败 -------------------------------------------------------------------------------- 最近一次修改记录 : 修改作者 : 雷宁 修改目的 : 新函数 修改日期 : 2010-03-09 *******************************************************************************/ u32 cwmp_node_get_PeriodicInformTime(WS_ENV* ws_env, s8** get_value, u32 *get_type) { CONFIG * cfg = NULL; const s8 *time_config = NULL; s8 time_str[32] = {0}; time_t PeriodicInformTime; struct tm *time_cur; cfg = config_load(CWMP_CONF_FILE_PATH); if (NULL != cfg) { time_config = config_get(cfg, "time", NULL); if(NULL == time_config) { /* cft在上面load时已经分配空间,下面往配置文件写time时还会给分配空间,但并没有释放, 会存在内存泄漏,所以在这里释放空间并且重新加载配置文件*/ config_free(cfg); cfg = config_load(CWMP_CONF_FILE_PATH); time(&PeriodicInformTime); time_cur = gmtime(&PeriodicInformTime); if( NULL != time_cur) { snprintf(time_str,32,"%04d-%02d-%02d %02d:%02d:%02d", (1900+time_cur->tm_year),(1+time_cur->tm_mon),time_cur->tm_mday,time_cur->tm_hour,time_cur->tm_min,time_cur->tm_sec); time_str[strlen(time_str)]='\0'; } cfg = config_set(cfg, "time", time_str); config_store(cfg, CWMP_CONF_FILE_PATH); } else { snprintf(time_str,32,"%s",time_config); } } *get_value = ws_strdup(ws_env, time_str); *get_type = CWMP_VALUE_TYPE_STRING; config_free(cfg); return ERROR_SUCCESS; }
/** disable a feature. * features are identified by eone of: * 1. the keyword for their orders, * 2. the name of the skill they use, * 3. a "module.enabled" flag in the settings */ static void disable_feature(const char *str) { char name[32]; int k; skill_t sk; sk = findskill(str); if (sk != NOSKILL) { enable_skill(sk, false); return; } for (k = 0; k != MAXKEYWORDS; ++k) { // FIXME: this loop is slow as balls. if (strcmp(keywords[k], str) == 0) { log_debug("disable keyword %s\n", str); enable_keyword(k, false); return; } } _snprintf(name, sizeof(name), "%s.enabled", str); log_info("disable feature %s\n", name); config_set(name, "0"); }
/* panel_helper_config_set */ static int _panel_helper_config_set(Panel * panel, char const * section, char const * variable, char const * value) { int ret; String * s = NULL; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(\"%s\", \"%s\", \"%s\")\n", __func__, section, variable, value); #endif if(section != NULL) { if((s = string_new_append("applet::", section, NULL)) == NULL) return -1; section = s; } /* FIXME save the configuration (if not in test mode) */ ret = config_set(panel->config, section, variable, value); string_delete(s); return ret; }
static void test_rules(CuTest *tc) { test_setup(); config_set("stealth.faction.other", NULL); CuAssertIntEquals(tc, true, rule_stealth_other()); config_set("stealth.faction.other", "0"); CuAssertIntEquals(tc, false, rule_stealth_other()); config_set("stealth.faction.other", "1"); CuAssertIntEquals(tc, true, rule_stealth_other()); config_set("stealth.faction.anon", NULL); CuAssertIntEquals(tc, true, rule_stealth_anon()); config_set("stealth.faction.anon", "0"); CuAssertIntEquals(tc, false, rule_stealth_anon()); config_set("stealth.faction.anon", "1"); CuAssertIntEquals(tc, true, rule_stealth_anon()); test_teardown(); }
static void sasl_set_local_success (PROFILE_INSTANCE *pi) { int code; char *reason; PRO_LOCALDATA *il = (PRO_LOCALDATA *) pi -> user_ptr1; struct configobj *appconfig = bp_get_config (pi -> channel -> conn); if (pro_debug) { fprintf (stderr, "sasl_set_local_success\n"); fflush (stderr); } if (config_test_and_set (appconfig, SASL_LOCAL_CODE, "200") != CONFIG_OK) { code = atoi (config_get (appconfig, SASL_LOCAL_CODE)); reason = config_get (appconfig, SASL_LOCAL_REASON); } else { code = 200; config_set (appconfig, SASL_LOCAL_REASON, reason = "login successful"); } il -> pl_status = bp_diagnostic_new (pi -> channel -> conn, code, NULL, "%s", reason); }
word_t Arch_setMRs_fault(tcb_t *sender, tcb_t* receiver, word_t *receiveIPCBuffer, word_t faultType) { switch (faultType) { case seL4_Fault_VMFault: { if (config_set(CONFIG_ARM_HYPERVISOR_SUPPORT)) { word_t ipa, va; va = getRestartPC(sender); ipa = (addressTranslateS1CPR(va) & ~MASK(PAGE_BITS)) | (va & MASK(PAGE_BITS)); setMR(receiver, receiveIPCBuffer, seL4_VMFault_IP, ipa); } else { setMR(receiver, receiveIPCBuffer, seL4_VMFault_IP, getRestartPC(sender)); } setMR(receiver, receiveIPCBuffer, seL4_VMFault_Addr, seL4_Fault_VMFault_get_address(sender->tcbFault)); setMR(receiver, receiveIPCBuffer, seL4_VMFault_PrefetchFault, seL4_Fault_VMFault_get_instructionFault(sender->tcbFault)); return setMR(receiver, receiveIPCBuffer, seL4_VMFault_FSR, seL4_Fault_VMFault_get_FSR(sender->tcbFault)); } #ifdef CONFIG_ARM_HYPERVISOR_SUPPORT case seL4_Fault_VGICMaintenance: if (seL4_Fault_VGICMaintenance_get_idxValid(sender->tcbFault)) { return setMR(receiver, receiveIPCBuffer, seL4_VGICMaintenance_IDX, seL4_Fault_VGICMaintenance_get_idx(sender->tcbFault)); } else { return setMR(receiver, receiveIPCBuffer, seL4_VGICMaintenance_IDX, -1); } case seL4_Fault_VCPUFault: return setMR(receiver, receiveIPCBuffer, seL4_VCPUFault_HSR, seL4_Fault_VCPUFault_get_hsr(sender->tcbFault)); #endif default: fail("Invalid fault"); } }
static void test_seaserpent_piracy(CuTest * tc) { faction *f, *f2; region *r; unit *u, *m; race *rc; create_monsters(&f, &f2, &u, &m); r = findregion(-1, 0); // ocean u = test_create_unit(u->faction, r); unit_setid(u, 2); m = test_create_unit(m->faction, r); u_setrace(m, rc = test_create_race("seaserpent")); assert(!m->region->land); fset(m, UFL_MOVED); fset(rc, RCF_ATTACK_MOVED); config_set("rules.monsters.attack_chance", "1"); plan_monsters(f2); CuAssertPtrNotNull(tc, find_order("piracy", m)); CuAssertPtrNotNull(tc, find_order("attack 2", m)); test_cleanup(); }
static BOOT_CODE bool_t try_boot_sys( unsigned long multiboot_magic, multiboot_info_t* mbi ) { /* ==== following code corresponds to the "select" in abstract specification ==== */ acpi_rsdt_t* acpi_rsdt; /* physical address of ACPI root */ paddr_t mods_end_paddr; /* physical address where boot modules end */ paddr_t load_paddr; word_t i; p_region_t ui_p_regs; multiboot_module_t *modules = (multiboot_module_t*)(word_t)mbi->mod_list; if (multiboot_magic != MULTIBOOT_MAGIC) { printf("Boot loader not multiboot compliant\n"); return false; } cmdline_parse((const char *)(word_t)mbi->cmdline, &cmdline_opt); if ((mbi->flags & MULTIBOOT_INFO_MEM_FLAG) == 0) { printf("Boot loader did not provide information about physical memory size\n"); return false; } if (!x86_cpuid_initialize()) { printf("Warning: Your x86 CPU has an unsupported vendor, '%s'.\n" "\tYour setup may not be able to competently run seL4 as " "intended.\n" "\tCurrently supported x86 vendors are AMD and Intel.\n", x86_cpuid_get_identity()->vendor_string); } if (!is_compiled_for_microarchitecture()) { printf("Warning: Your kernel was not compiled for the current microarchitecture.\n"); } #if CONFIG_MAX_NUM_NODES > 1 /* copy boot code for APs to lower memory to run in real mode */ if (!copy_boot_code_aps(mbi->mem_lower)) { return false; } /* Initialize any kernel TLS */ mode_init_tls(0); #endif /* initialize the memory. We track two kinds of memory regions. Physical memory * that we will use for the kernel, and physical memory regions that we must * not give to the user. Memory regions that must not be given to the user * include all the physical memory in the kernel window, but also includes any * important or kernel devices. */ boot_state.mem_p_regs.count = 0; init_allocated_p_regions(); if (mbi->flags & MULTIBOOT_INFO_MMAP_FLAG) { if (!parse_mem_map(mbi->mmap_length, mbi->mmap_addr)) { return false; } } else { /* calculate memory the old way */ p_region_t avail; avail.start = HIGHMEM_PADDR; avail.end = ROUND_DOWN(avail.start + (mbi->mem_upper << 10), PAGE_BITS); if (!add_mem_p_regs(avail)) { return false; } } boot_state.ki_p_reg.start = PADDR_LOAD; boot_state.ki_p_reg.end = kpptr_to_paddr(ki_end); /* copy VESA information from multiboot header */ if ((mbi->flags & MULTIBOOT_INFO_GRAPHICS_FLAG) == 0) { boot_state.vbe_info.vbeMode = -1; printf("Multiboot gave us no video information\n"); } else { boot_state.vbe_info.vbeInfoBlock = *(seL4_VBEInfoBlock_t*)(seL4_Word)mbi->vbe_control_info; boot_state.vbe_info.vbeModeInfoBlock = *(seL4_VBEModeInfoBlock_t*)(seL4_Word)mbi->vbe_mode_info; boot_state.vbe_info.vbeMode = mbi->vbe_mode; printf("Got VBE info in multiboot. Current video mode is %d\n", mbi->vbe_mode); boot_state.vbe_info.vbeInterfaceSeg = mbi->vbe_interface_seg; boot_state.vbe_info.vbeInterfaceOff = mbi->vbe_interface_off; boot_state.vbe_info.vbeInterfaceLen = mbi->vbe_interface_len; } printf("Kernel loaded to: start=0x%lx end=0x%lx size=0x%lx entry=0x%lx\n", boot_state.ki_p_reg.start, boot_state.ki_p_reg.end, boot_state.ki_p_reg.end - boot_state.ki_p_reg.start, (paddr_t)_start ); /* remapping legacy IRQs to their correct vectors */ pic_remap_irqs(IRQ_INT_OFFSET); if (config_set(CONFIG_IRQ_IOAPIC)) { /* Disable the PIC so that it does not generate any interrupts. We need to * do this *before* we initialize the apic */ pic_disable(); } /* get ACPI root table */ acpi_rsdt = acpi_init(); if (!acpi_rsdt) { return false; } /* check if kernel configuration matches platform requirments */ if (!acpi_fadt_scan(acpi_rsdt)) { return false; } if (!config_set(CONFIG_IOMMU) || cmdline_opt.disable_iommu) { boot_state.num_drhu = 0; } else { /* query available IOMMUs from ACPI */ acpi_dmar_scan( acpi_rsdt, boot_state.drhu_list, &boot_state.num_drhu, MAX_NUM_DRHU, &boot_state.rmrr_list ); } /* query available CPUs from ACPI */ boot_state.num_cpus = acpi_madt_scan(acpi_rsdt, boot_state.cpus, &boot_state.num_ioapic, boot_state.ioapic_paddr); if (boot_state.num_cpus == 0) { printf("No CPUs detected\n"); return false; } if (config_set(CONFIG_IRQ_IOAPIC)) { if (boot_state.num_ioapic == 0) { printf("No IOAPICs detected\n"); return false; } } else { if (boot_state.num_ioapic > 0) { printf("Detected %d IOAPICs, but configured to use PIC instead\n", boot_state.num_ioapic); } } if (!(mbi->flags & MULTIBOOT_INFO_MODS_FLAG)) { printf("Boot loader did not provide information about boot modules\n"); return false; } printf("Detected %d boot module(s):\n", mbi->mod_count); if (mbi->mod_count < 1) { printf("Expect at least one boot module (containing a userland image)\n"); return false; } mods_end_paddr = 0; for (i = 0; i < mbi->mod_count; i++) { printf( " module #%ld: start=0x%x end=0x%x size=0x%x name='%s'\n", i, modules[i].start, modules[i].end, modules[i].end - modules[i].start, (char *) (long)modules[i].name ); if ((sword_t)(modules[i].end - modules[i].start) <= 0) { printf("Invalid boot module size! Possible cause: boot module file not found by QEMU\n"); return false; } if (mods_end_paddr < modules[i].end) { mods_end_paddr = modules[i].end; } } mods_end_paddr = ROUND_UP(mods_end_paddr, PAGE_BITS); assert(mods_end_paddr > boot_state.ki_p_reg.end); printf("ELF-loading userland images from boot modules:\n"); load_paddr = mods_end_paddr; load_paddr = load_boot_module(modules, load_paddr); if (!load_paddr) { return false; } /* calculate final location of userland images */ ui_p_regs.start = boot_state.ki_p_reg.end; ui_p_regs.end = ui_p_regs.start + load_paddr - mods_end_paddr; printf( "Moving loaded userland images to final location: from=0x%lx to=0x%lx size=0x%lx\n", mods_end_paddr, ui_p_regs.start, ui_p_regs.end - ui_p_regs.start ); memcpy((void*)ui_p_regs.start, (void*)mods_end_paddr, ui_p_regs.end - ui_p_regs.start); /* adjust p_reg and pv_offset to final load address */ boot_state.ui_info.p_reg.start -= mods_end_paddr - ui_p_regs.start; boot_state.ui_info.p_reg.end -= mods_end_paddr - ui_p_regs.start; boot_state.ui_info.pv_offset -= mods_end_paddr - ui_p_regs.start; /* ==== following code corresponds to abstract specification after "select" ==== */ if (!platAddDevices()) { return false; } /* Total number of cores we intend to boot */ ksNumCPUs = boot_state.num_cpus; printf("Starting node #0 with APIC ID %lu\n", boot_state.cpus[0]); if (!try_boot_sys_node(boot_state.cpus[0])) { return false; } if (config_set(CONFIG_IRQ_IOAPIC)) { ioapic_init(1, boot_state.cpus, boot_state.num_ioapic); } /* initialize BKL before booting up APs */ SMP_COND_STATEMENT(clh_lock_init()); SMP_COND_STATEMENT(start_boot_aps()); /* grab BKL before leaving the kernel */ NODE_LOCK_SYS; printf("Booting all finished, dropped to user space\n"); return true; }
int main(int argc, char* argv[]) { musicd_start_time = time(NULL); config_init(); config_set_hook("log-level", log_level_changed); config_set_hook("log-time-format", log_time_format_changed); config_set("log-level", "debug"); config_set_hook("directory", directory_changed); config_set("config", "~/.musicd.conf"); config_set("directory", "~/.musicd"); config_set("bind", "any"); config_set("port", "6800"); config_set_hook("image-prefix", scan_image_prefix_changed); config_set("image-prefix", "front,cover,jacket"); config_set("server-name", "musicd server"); if (config_load_args(argc, argv)) { musicd_log(LOG_FATAL, "main", "invalid command line arguments"); print_usage(argv[0]); return -1; } if (config_get_value("help")) { print_usage(argv[0]); return 0; } if (config_get_value("version")) { print_version(); return 0; } if (!config_to_bool("no-config") && config_load_file(config_to_path("config"))) { musicd_log(LOG_FATAL, "main", "could not read config file"); return -1; } /* Reload command line arguments - this is because the config file might have * overwritten them, and the command line has the highest priority. */ config_load_args(argc, argv); confirm_directory(); musicd_log(LOG_INFO, "main", "musicd version %s", MUSICD_VERSION_STRING); srand(time(NULL)); av_register_all(); avcodec_register_all(); av_lockmgr_register(&musicd_av_lockmgr); av_log_set_level(AV_LOG_QUIET); if (db_open()) { musicd_log(LOG_FATAL, "library", "can't open database"); return -1; } if (library_open()) { musicd_log(LOG_FATAL, "main", "could not open library"); return -1; } if (cache_open()) { musicd_log(LOG_FATAL, "main", "could not open cache"); return -1; } if (server_start()) { musicd_log(LOG_FATAL, "main", "could not start server"); return -1; } signal(SIGUSR1, start_scan_signal); scan_start(); while (1) { sleep(1); } return 0; }
exception_t decodeTCBConfigure(cap_t cap, unsigned int length, cte_t* slot, extra_caps_t rootCaps, word_t *buffer) { cte_t *bufferSlot, *cRootSlot, *vRootSlot; cap_t bufferCap, cRootCap, vRootCap; deriveCap_ret_t dc_ret; cptr_t faultEP; unsigned int prio; word_t cRootData, vRootData, bufferAddr; if (length < 5 || rootCaps.excaprefs[0] == NULL || rootCaps.excaprefs[1] == NULL || rootCaps.excaprefs[2] == NULL) { userError("TCB Configure: Truncated message."); current_syscall_error.type = seL4_TruncatedMessage; return EXCEPTION_SYSCALL_ERROR; } faultEP = getSyscallArg(0, buffer); prio = getSyscallArg(1, buffer); cRootData = getSyscallArg(2, buffer); vRootData = getSyscallArg(3, buffer); bufferAddr = getSyscallArg(4, buffer); cRootSlot = rootCaps.excaprefs[0]; cRootCap = rootCaps.excaprefs[0]->cap; vRootSlot = rootCaps.excaprefs[1]; vRootCap = rootCaps.excaprefs[1]->cap; bufferSlot = rootCaps.excaprefs[2]; bufferCap = rootCaps.excaprefs[2]->cap; prio = prio & MASK(8); if (prio > ksCurThread->tcbPriority) { userError("TCB Configure: Requested priority %d too high (max %d).", (int)prio, (int)(ksCurThread->tcbPriority)); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } if (bufferAddr == 0) { bufferSlot = NULL; } else { exception_t e; dc_ret = deriveCap(bufferSlot, bufferCap); if (dc_ret.status != EXCEPTION_NONE) { return dc_ret.status; } bufferCap = dc_ret.cap; e = checkValidIPCBuffer(bufferAddr, bufferCap); if (e != EXCEPTION_NONE) { return e; } } if (slotCapLongRunningDelete( TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), tcbCTable)) || slotCapLongRunningDelete( TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), tcbVTable))) { userError("TCB Configure: CSpace or VSpace currently being deleted."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } if (cRootData != 0) { cRootCap = updateCapData(false, cRootData, cRootCap); } dc_ret = deriveCap(cRootSlot, cRootCap); if (dc_ret.status != EXCEPTION_NONE) { return dc_ret.status; } cRootCap = dc_ret.cap; if (cap_get_capType(cRootCap) != cap_cnode_cap && (!config_set(CONFIG_ALLOW_NULL_CSPACE) || cap_get_capType(cRootCap) != cap_null_cap)) { userError("TCB Configure: CSpace cap is invalid."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } if (vRootData != 0) { vRootCap = updateCapData(false, vRootData, vRootCap); } dc_ret = deriveCap(vRootSlot, vRootCap); if (dc_ret.status != EXCEPTION_NONE) { return dc_ret.status; } vRootCap = dc_ret.cap; if (!isValidVTableRoot(vRootCap)) { userError("TCB Configure: VSpace cap is invalid."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } setThreadState(ksCurThread, ThreadState_Restart); return invokeTCB_ThreadControl( TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), slot, faultEP, prio, cRootCap, cRootSlot, vRootCap, vRootSlot, bufferAddr, bufferCap, bufferSlot, thread_control_update_all); }
int main(int argc, char **argv, char **envp) { int pid, c; const char *prj; char buf[4096]; char buf2[4096]; int flag_d = 0; int __optind = 0; int nscr = 0; char *ptr; environ = envp; radare_init(); while ((c = getopt(argc, argv, "l:fs:hb:wLvuVnxi:e:p:d")) != -1) { switch( c ) { case 'd': flag_d = 1; __optind = optind; break; case 'i': config.script[nscr++] = optarg; config.script[nscr] = NULL; break; case 'f': config.block_size = 0; break; case 'n': config.noscript = 1; break; case 'p': config_set("file.project", optarg); break; case 'w': config_set("file.write", "true"); break; case 's': config.seek = (ut64)get_offset(optarg); if (config.seek < 0) config.seek = (ut64)0; config_set("dbg.bep", optarg); break; case 'l': plugin_registry(optarg); break; case 'L': return plugin_list(); case 'b': config.block_size = (size_t)get_offset(optarg); config.block = (unsigned char *)realloc(config.block, config.block_size); config_set_i("cfg.bsize", config.block_size); break; case 'V': printf("radare %s %dbit on %s%dbit "TARGET" %s%s\n", VERSION, sizeof(ut64)*8, (LIL_ENDIAN)?"le":"be", sizeof(void *)*8, (DEBUGGER)? "dbg " :"", (HAVE_GUI)? "gui" :""); return 0; case 'u': config.unksize = 1; break; case 'x': config.mode = MODE_HEXDUMP; break; case 'e': config_eval(optarg); break; case 'h': help_message(0); return 0; case 'v': config_set("cfg.verbose", "false"); break; default: return 1; } } if (optind < argc) config.file = argv[optind++]; if (!flag_d && optind < argc) eprintf("warning: Only the first file has been opened.\n"); /* TODO: we have to recheck this :) */ if (flag_d) { optind--; config.debug = 1; prj = config_get("file.project"); if (__optind==argc) { if (prj == NULL) return help_message(1); snprintf(buf2, 4095, "dbg://%s", project_get_file(prj) ); config.file = strdup(buf2); } else { // XXX : overflowable, must use strcatdup or stgh like that // TODO: support hex pids too pid = atoi(argv[optind]); buf[0]='\0'; /* by process-id */ if (pid > 0) { sprintf(buf2, "pid://%d", pid); config.file = strdup(buf2); } else { #if DEBUGGER /* by program path */ for(c=optind; argv[c]; c++) { char *arg = argv[c]; if (c == optind) arg = (char *)resolve_path(argv[c]); ps.argv[c-optind] = arg; strcat(buf, arg); if (argv[c+1]) strcat(buf, " "); } ps.args = strdup(buf); if (strstr(buf, "://")) strcpy(buf2, buf); else sprintf(buf2, "dbg://%s", buf); config.file = strdup(buf2); ps.filename = strdup(buf2); //ptr = strchr(config.file, ' '); //if (ptr) *ptr = '\0'; //config.file = strdup(buf2); #else eprintf("TODO: Needs debugger\n"); #endif } } config_set("cfg.debug", "true"); } plugin_load(); return radare_go(); }
int search_from_simple_file(char *file) { FILE *fd; char *ptr, buf[4096], cmd[4096]; //int i,ret; ut64 tmp = config.seek; //tokenizer *t; if (strchr(file, '?')) { cons_printf("Usage: /: file [file2] [file3] ...\n" "File format:\n" " puts 89823993982839\n" " scanf 89844483241839\n"); return 0; } fd = fopen(file, "r"); if (fd == NULL) { eprintf("Cannot open file '%s'\n", file); return 0; } config_set("cfg.verbose", "false"); while(!feof(fd) && !config.interrupted) { /* read line */ buf[0]='\0'; fgets(buf, 4095, fd); if (buf[0]=='\0') continue; buf[strlen(buf)-1]='\0'; ptr = strchr(buf, ' '); if (ptr) { ptr[0]='\0'; sprintf(cmd, "hit.%s_%%d%%d", buf); config_set("search.flagname", cmd); sprintf(cmd, ":/x %s", ptr+1); radare_cmd_raw(cmd, 0); //eprintf("(%s)(%s)\n", buf, ptr+1); } } config_set("cfg.verbose", "true"); config_set("search.flagname", "hit%d_%d"); fclose(fd); #if 0 t = binparse_new_from_simple_file(file); if (t == NULL) return 0; t->callback = &radare_tsearch_callback; nhit = 0; radare_controlc(); // TODO: do it generic (as for init) radare_cmd("fs search", 0); for(radare_read(0);!config.interrupted&& config.seek < config.size;radare_read(1)) { for(i=0;i<config.block_size;i++) { ret = update_tlist(t, config.block[i], config.seek+i); if (ret == -1) break; } } radare_controlc_end(); binparser_free(t); #endif radare_seek(tmp, SEEK_SET); radare_read(0); return 1; }
BOOT_CODE bool_t init_sys_state( cpu_id_t cpu_id, mem_p_regs_t mem_p_regs, dev_p_regs_t* dev_p_regs, ui_info_t ui_info, p_region_t boot_mem_reuse_p_reg, /* parameters below not modeled in abstract specification */ uint32_t num_drhu, paddr_t* drhu_list, acpi_rmrr_list_t *rmrr_list ) { cap_t root_cnode_cap; vptr_t bi_frame_vptr; vptr_t ipcbuf_vptr; cap_t it_vspace_cap; cap_t it_ap_cap; cap_t ipcbuf_cap; pptr_t bi_frame_pptr; create_frames_of_region_ret_t create_frames_ret; #ifdef CONFIG_ENABLE_BENCHMARKS vm_attributes_t buffer_attr = {{ 0 }}; word_t paddr; pde_t pde; #endif /* CONFIG_ENABLE_BENCHMARKS */ /* convert from physical addresses to kernel pptrs */ region_t ui_reg = paddr_to_pptr_reg(ui_info.p_reg); region_t boot_mem_reuse_reg = paddr_to_pptr_reg(boot_mem_reuse_p_reg); /* convert from physical addresses to userland vptrs */ v_region_t ui_v_reg; v_region_t it_v_reg; ui_v_reg.start = ui_info.p_reg.start - ui_info.pv_offset; ui_v_reg.end = ui_info.p_reg.end - ui_info.pv_offset; ipcbuf_vptr = ui_v_reg.end; bi_frame_vptr = ipcbuf_vptr + BIT(PAGE_BITS); /* The region of the initial thread is the user image + ipcbuf and boot info */ it_v_reg.start = ui_v_reg.start; it_v_reg.end = bi_frame_vptr + BIT(PAGE_BITS); init_freemem(ui_info.p_reg, mem_p_regs); /* initialise virtual-memory-related data structures (not in abstract spec) */ if (!init_vm_state()) { return false; } #ifdef CONFIG_ENABLE_BENCHMARKS /* allocate and create the log buffer */ buffer_attr.words[0] = IA32_PAT_MT_WRITE_THROUGH; paddr = pptr_to_paddr((void *) alloc_region(pageBitsForSize(X86_LargePage))); /* allocate a large frame for logging */ pde = x86_make_pde_mapping(paddr, buffer_attr); ia32KSGlobalPD[IA32_KSLOG_IDX] = pde; /* flush the tlb */ invalidateTranslationAll(); /* if we crash here, the log isn't working */ #ifdef CONFIG_DEBUG_BUILD #if CONFIG_MAX_NUM_TRACE_POINTS > 0 printf("Testing log\n"); ksLog[0].data = 0xdeadbeef; printf("Wrote to ksLog %x\n", ksLog[0].data); assert(ksLog[0].data == 0xdeadbeef); #endif /* CONFIG_MAX_NUM_TRACE_POINTS */ #endif /* CONFIG_DEBUG_BUILD */ #endif /* CONFIG_ENABLE_BENCHMARKS */ /* create the root cnode */ root_cnode_cap = create_root_cnode(); /* create the IO port cap */ write_slot( SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapIOPort), cap_io_port_cap_new( 0, /* first port */ NUM_IO_PORTS - 1 /* last port */ ) ); /* create the cap for managing thread domains */ create_domain_cap(root_cnode_cap); /* create the IRQ CNode */ if (!create_irq_cnode()) { return false; } /* initialise the IRQ states and provide the IRQ control cap */ init_irqs(root_cnode_cap); /* create the bootinfo frame */ bi_frame_pptr = allocate_bi_frame(0, 1, ipcbuf_vptr); if (!bi_frame_pptr) { return false; } /* Construct an initial address space with enough virtual addresses * to cover the user image + ipc buffer and bootinfo frames */ it_vspace_cap = create_it_address_space(root_cnode_cap, it_v_reg); if (cap_get_capType(it_vspace_cap) == cap_null_cap) { return false; } /* Create and map bootinfo frame cap */ create_bi_frame_cap( root_cnode_cap, it_vspace_cap, bi_frame_pptr, bi_frame_vptr ); /* create the initial thread's IPC buffer */ ipcbuf_cap = create_ipcbuf_frame(root_cnode_cap, it_vspace_cap, ipcbuf_vptr); if (cap_get_capType(ipcbuf_cap) == cap_null_cap) { return false; } /* create all userland image frames */ create_frames_ret = create_frames_of_region( root_cnode_cap, it_vspace_cap, ui_reg, true, ui_info.pv_offset ); if (!create_frames_ret.success) { return false; } ndks_boot.bi_frame->userImageFrames = create_frames_ret.region; /* create the initial thread's ASID pool */ it_ap_cap = create_it_asid_pool(root_cnode_cap); if (cap_get_capType(it_ap_cap) == cap_null_cap) { return false; } write_it_asid_pool(it_ap_cap, it_vspace_cap); /* * Initialise the NULL FPU state. This is different from merely zero'ing it * out (i.e., the NULL FPU state is non-zero), and must be performed before * the first thread is created. */ resetFpu(); saveFpuState(&x86KSnullFpuState); x86KSfpuOwner = NULL; /* create the idle thread */ if (!create_idle_thread()) { return false; } /* create the initial thread */ if (!create_initial_thread( root_cnode_cap, it_vspace_cap, ui_info.v_entry, bi_frame_vptr, ipcbuf_vptr, ipcbuf_cap )) { return false; } if (config_set(CONFIG_IOMMU)) { /* initialise VTD-related data structures and the IOMMUs */ if (!vtd_init(cpu_id, num_drhu, rmrr_list)) { return false; } /* write number of IOMMU PT levels into bootinfo */ ndks_boot.bi_frame->numIOPTLevels = x86KSnumIOPTLevels; /* write IOSpace master cap */ write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapIOSpace), master_iospace_cap()); } else { ndks_boot.bi_frame->numIOPTLevels = -1; } /* convert the remaining free memory into UT objects and provide the caps */ if (!create_untypeds(root_cnode_cap, boot_mem_reuse_reg)) { return false; } /* WARNING: alloc_region() must not be called anymore after here! */ /* create device frames */ if (!create_device_frames(root_cnode_cap, dev_p_regs)) { return false; } /* finalise the bootinfo frame */ bi_finalise(); return true; }
/* * Initialise the FPU for this machine. */ BOOT_CODE bool_t Arch_initFpu(void) { /* Enable FPU / SSE / SSE2 / SSE3 / SSSE3 / SSE4 Extensions. */ write_cr4(read_cr4() | CR4_OSFXSR); /* Enable the FPU in general. */ write_cr0((read_cr0() & ~CR0_EMULATION) | CR0_MONITOR_COPROC | CR0_NUMERIC_ERROR); enableFpu(); /* Initialize the fpu state */ finit(); if (config_set(CONFIG_XSAVE)) { uint64_t xsave_features; uint32_t xsave_instruction; uint64_t desired_features = config_ternary(CONFIG_XSAVE, CONFIG_XSAVE_FEATURE_SET, 1); xsave_state_t *nullFpuState = (xsave_state_t *) &x86KSnullFpuState; /* create NULL state for FPU to be used by XSAVE variants */ memzero(&x86KSnullFpuState, sizeof(x86KSnullFpuState)); /* check for XSAVE support */ if (!(x86_cpuid_ecx(1, 0) & BIT(26))) { printf("XSAVE not supported\n"); return false; } /* enable XSAVE support */ write_cr4(read_cr4() | CR4_OSXSAVE); /* check feature mask */ xsave_features = ((uint64_t)x86_cpuid_edx(0x0d, 0x0) << 32) | x86_cpuid_eax(0x0d, 0x0); if ((xsave_features & desired_features) != desired_features) { printf("Requested feature mask is 0x%llx, but only 0x%llx supported\n", desired_features, (long long)xsave_features); return false; } /* enable feature mask */ write_xcr0(desired_features); /* validate the xsave buffer size and instruction */ if (x86_cpuid_ebx(0x0d, 0x0) > CONFIG_XSAVE_SIZE) { printf("XSAVE buffer set set to %d, but needs to be at least %d\n", CONFIG_XSAVE_SIZE, x86_cpuid_ebx(0x0d, 0x0)); return false; } if (x86_cpuid_ebx(0x0d, 0x0) < CONFIG_XSAVE_SIZE) { printf("XSAVE buffer set set to %d, but only needs to be %d.\n" "Warning: Memory may be wasted with larger than needed TCBs.\n", CONFIG_XSAVE_SIZE, x86_cpuid_ebx(0x0d, 0x0)); } /* check if a specialized XSAVE instruction was requested */ xsave_instruction = x86_cpuid_eax(0x0d, 0x1); if (config_set(CONFIG_XSAVE_XSAVEOPT)) { if (!(xsave_instruction & BIT(0))) { printf("XSAVEOPT requested, but not supported\n"); return false; } } else if (config_set(CONFIG_XSAVE_XSAVEC)) { if (!(xsave_instruction & BIT(1))) { printf("XSAVEC requested, but not supported\n"); return false; } } else if (config_set(CONFIG_XSAVE_XSAVES)) { if (!(xsave_instruction & BIT(3))) { printf("XSAVES requested, but not supported\n"); return false; } /* AVX state from extended region should be in compacted format */ nullFpuState->header.xcomp_bv = XCOMP_BV_COMPACTED_FORMAT; /* initialize the XSS MSR */ x86_wrmsr(IA32_XSS_MSR, desired_features); } /* copy i387 FPU initial state from FPU */ saveFpuState(&x86KSnullFpuState); nullFpuState->i387.mxcsr = MXCSR_INIT_VALUE; } else { /* Store the null fpu state */ saveFpuState(&x86KSnullFpuState); } /* Set the FPU to lazy switch mode */ disableFpu(); return true; }
int main(int argc, char **argv) { int i; int config_loaded = 0; int dont_fork = 0; size_t wanted_stacksize = 0, stacksize = 0; pthread_attr_t attr; // global initialization get_HZ(); // set the name for logging program_name = "netdata"; // parse command line. // parse depercated options // TODO: Remove this block with the next major release. { i = 1; while(i < argc) { if(strcmp(argv[i], "-pidfile") == 0 && (i+1) < argc) { strncpyz(pidfile, argv[i+1], FILENAME_MAX); fprintf(stderr, "%s: deprecated option -- %s -- please use -P instead.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-nodaemon") == 0 || strcmp(argv[i], "-nd") == 0) { dont_fork = 1; fprintf(stderr, "%s: deprecated option -- %s -- please use -D instead.\n ", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-ch") == 0 && (i+1) < argc) { config_set("global", "host access prefix", argv[i+1]); fprintf(stderr, "%s: deprecated option -- %s -- please use -s instead.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) { config_set("global", "history", argv[i+1]); fprintf(stderr, "%s: deprecated option -- %s -- This option will be removed with V2.*.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else i++; } } // parse options { int num_opts = sizeof(options) / sizeof(struct option_def); char optstring[(num_opts * 2) + 1]; int string_i = 0; for( i = 0; i < num_opts; i++ ) { optstring[string_i] = options[i].val; string_i++; if(options[i].arg_name) { optstring[string_i] = ':'; string_i++; } } int opt; while( (opt = getopt(argc, argv, optstring)) != -1 ) { switch(opt) { case 'c': if(load_config(optarg, 1) != 1) { error("Cannot load configuration file %s.", optarg); exit(1); } else { debug(D_OPTIONS, "Configuration loaded from %s.", optarg); config_loaded = 1; } break; case 'D': dont_fork = 1; break; case 'h': help(0); break; case 'i': config_set("global", "bind to", optarg); break; case 'P': strncpy(pidfile, optarg, FILENAME_MAX); pidfile[FILENAME_MAX] = '\0'; break; case 'p': config_set("global", "default port", optarg); break; case 's': config_set("global", "host access prefix", optarg); break; case 't': config_set("global", "update every", optarg); break; case 'u': config_set("global", "run as user", optarg); break; case 'v': // TODO: Outsource version to makefile which can compute version from git. printf("netdata 1.2.1_master\n"); return 0; break; case 'W': { char* stacksize = "stacksize="; char* debug_flags_string = "debug_flags="; if(strcmp(optarg, "unittest") == 0) { rrd_update_every = 1; if(run_all_mockup_tests()) exit(1); if(unit_test_storage()) exit(1); fprintf(stderr, "\n\nALL TESTS PASSED\n\n"); exit(0); } else if(strncmp(optarg, stacksize, strlen(stacksize)) == 0) { optarg += strlen(stacksize); config_set("global", "pthread stack size", optarg); } else if(strncmp(optarg, debug_flags_string, strlen(debug_flags_string)) == 0) { optarg += strlen(debug_flags_string); config_set("global", "debug flags", optarg); debug_flags = strtoull(optarg, NULL, 0); } } break; default: /* ? */ help(1); break; } } } if(!config_loaded) load_config(NULL, 0); // prepare configuration environment variables for the plugins setenv("NETDATA_CONFIG_DIR" , config_get("global", "config directory" , CONFIG_DIR) , 1); setenv("NETDATA_PLUGINS_DIR", config_get("global", "plugins directory" , PLUGINS_DIR), 1); setenv("NETDATA_WEB_DIR" , config_get("global", "web files directory", WEB_DIR) , 1); setenv("NETDATA_CACHE_DIR" , config_get("global", "cache directory" , CACHE_DIR) , 1); setenv("NETDATA_LIB_DIR" , config_get("global", "lib directory" , VARLIB_DIR) , 1); setenv("NETDATA_LOG_DIR" , config_get("global", "log directory" , LOG_DIR) , 1); setenv("NETDATA_HOST_PREFIX", config_get("global", "host access prefix" , "") , 1); setenv("HOME" , config_get("global", "home directory" , CACHE_DIR) , 1); // disable buffering for python plugins setenv("PYTHONUNBUFFERED", "1", 1); // avoid flood calls to stat(/etc/localtime) // http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux setenv("TZ", ":/etc/localtime", 0); { char path[1024 + 1], *p = getenv("PATH"); if(!p) p = "/bin:/usr/bin"; snprintfz(path, 1024, "%s:%s", p, "/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin"); setenv("PATH", config_get("plugins", "PATH environment variable", path), 1); } // cd to /tmp to avoid any plugins writing files at random places if(chdir("/tmp")) error("netdata: ERROR: Cannot cd to /tmp"); char *input_log_file = NULL; char *output_log_file = NULL; char *error_log_file = NULL; char *access_log_file = NULL; char *user = NULL; { char *flags = config_get("global", "debug flags", "0x00000000"); setenv("NETDATA_DEBUG_FLAGS", flags, 1); debug_flags = strtoull(flags, NULL, 0); debug(D_OPTIONS, "Debug flags set to '0x%8llx'.", debug_flags); if(debug_flags != 0) { struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; if(setrlimit(RLIMIT_CORE, &rl) != 0) info("Cannot request unlimited core dumps for debugging... Proceeding anyway..."); prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); } // -------------------------------------------------------------------- #ifdef MADV_MERGEABLE enable_ksm = config_get_boolean("global", "memory deduplication (ksm)", enable_ksm); #else #warning "Kernel memory deduplication (KSM) is not available" #endif // -------------------------------------------------------------------- global_host_prefix = config_get("global", "host access prefix", ""); setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1); // -------------------------------------------------------------------- output_log_file = config_get("global", "debug log", LOG_DIR "/debug.log"); if(strcmp(output_log_file, "syslog") == 0) { output_log_syslog = 1; output_log_file = NULL; } else if(strcmp(output_log_file, "none") == 0) { output_log_syslog = 0; output_log_file = NULL; } else output_log_syslog = 0; // -------------------------------------------------------------------- error_log_file = config_get("global", "error log", LOG_DIR "/error.log"); if(strcmp(error_log_file, "syslog") == 0) { error_log_syslog = 1; error_log_file = NULL; } else if(strcmp(error_log_file, "none") == 0) { error_log_syslog = 0; error_log_file = NULL; // optimization - do not even generate debug log entries } else error_log_syslog = 0; error_log_throttle_period = config_get_number("global", "errors flood protection period", error_log_throttle_period); setenv("NETDATA_ERRORS_THROTTLE_PERIOD", config_get("global", "errors flood protection period" , ""), 1); error_log_errors_per_period = (unsigned long)config_get_number("global", "errors to trigger flood protection", error_log_errors_per_period); setenv("NETDATA_ERRORS_PER_PERIOD" , config_get("global", "errors to trigger flood protection", ""), 1); // -------------------------------------------------------------------- access_log_file = config_get("global", "access log", LOG_DIR "/access.log"); if(strcmp(access_log_file, "syslog") == 0) { access_log_syslog = 1; access_log_file = NULL; } else if(strcmp(access_log_file, "none") == 0) { access_log_syslog = 0; access_log_file = NULL; } else access_log_syslog = 0; // -------------------------------------------------------------------- rrd_memory_mode = rrd_memory_mode_id(config_get("global", "memory mode", rrd_memory_mode_name(rrd_memory_mode))); // -------------------------------------------------------------------- { char hostnamebuf[HOSTNAME_MAX + 1]; if(gethostname(hostnamebuf, HOSTNAME_MAX) == -1) error("WARNING: Cannot get machine hostname."); hostname = config_get("global", "hostname", hostnamebuf); debug(D_OPTIONS, "hostname set to '%s'", hostname); } // -------------------------------------------------------------------- rrd_default_history_entries = (int) config_get_number("global", "history", RRD_DEFAULT_HISTORY_ENTRIES); if(rrd_default_history_entries < 5 || rrd_default_history_entries > RRD_HISTORY_ENTRIES_MAX) { info("Invalid save lines %d given. Defaulting to %d.", rrd_default_history_entries, RRD_DEFAULT_HISTORY_ENTRIES); rrd_default_history_entries = RRD_DEFAULT_HISTORY_ENTRIES; } else { debug(D_OPTIONS, "save lines set to %d.", rrd_default_history_entries); } // -------------------------------------------------------------------- rrd_update_every = (int) config_get_number("global", "update every", UPDATE_EVERY); if(rrd_update_every < 1 || rrd_update_every > 600) { info("Invalid update timer %d given. Defaulting to %d.", rrd_update_every, UPDATE_EVERY_MAX); rrd_update_every = UPDATE_EVERY; } else debug(D_OPTIONS, "update timer set to %d.", rrd_update_every); // let the plugins know the min update_every { char buf[16]; snprintfz(buf, 15, "%d", rrd_update_every); setenv("NETDATA_UPDATE_EVERY", buf, 1); } // -------------------------------------------------------------------- // block signals while initializing threads. // this causes the threads to block signals. sigset_t sigset; sigfillset(&sigset); if(pthread_sigmask(SIG_BLOCK, &sigset, NULL) == -1) { error("Could not block signals for threads"); } // Catch signals which we want to use to quit savely struct sigaction sa; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGHUP); sigaddset(&sa.sa_mask, SIGINT); sigaddset(&sa.sa_mask, SIGTERM); sa.sa_handler = sig_handler_exit; sa.sa_flags = 0; if(sigaction(SIGHUP, &sa, NULL) == -1) { error("Failed to change signal handler for SIGHUP"); } if(sigaction(SIGINT, &sa, NULL) == -1) { error("Failed to change signal handler for SIGINT"); } if(sigaction(SIGTERM, &sa, NULL) == -1) { error("Failed to change signal handler for SIGTERM"); } // save database on SIGUSR1 sa.sa_handler = sig_handler_save; if(sigaction(SIGUSR1, &sa, NULL) == -1) { error("Failed to change signal handler for SIGUSR1"); } // Ignore SIGPIPE completely. // INFO: If we add signals here we have to unblock them // at popen.c when running a external plugin. sa.sa_handler = SIG_IGN; if(sigaction(SIGPIPE, &sa, NULL) == -1) { error("Failed to change signal handler for SIGPIPE"); } // -------------------------------------------------------------------- i = pthread_attr_init(&attr); if(i != 0) fatal("pthread_attr_init() failed with code %d.", i); i = pthread_attr_getstacksize(&attr, &stacksize); if(i != 0) fatal("pthread_attr_getstacksize() failed with code %d.", i); else debug(D_OPTIONS, "initial pthread stack size is %zu bytes", stacksize); wanted_stacksize = config_get_number("global", "pthread stack size", stacksize); // -------------------------------------------------------------------- for (i = 0; static_threads[i].name != NULL ; i++) { struct netdata_static_thread *st = &static_threads[i]; if(st->config_name) st->enabled = config_get_boolean(st->config_section, st->config_name, st->enabled); if(st->enabled && st->init_routine) st->init_routine(); } // -------------------------------------------------------------------- // get the user we should run // IMPORTANT: this is required before web_files_uid() user = config_get("global", "run as user" , (getuid() == 0)?NETDATA_USER:""); // IMPORTANT: these have to run once, while single threaded web_files_uid(); // IMPORTANT: web_files_uid() before web_files_gid() web_files_gid(); // -------------------------------------------------------------------- create_listen_sockets(); } // never become a problem if(nice(20) == -1) error("Cannot lower my CPU priority."); if(become_daemon(dont_fork, 0, user, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1) fatal("Cannot demonize myself."); #ifdef NETDATA_INTERNAL_CHECKS if(debug_flags != 0) { struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; if(setrlimit(RLIMIT_CORE, &rl) != 0) info("Cannot request unlimited core dumps for debugging... Proceeding anyway..."); prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); } #endif /* NETDATA_INTERNAL_CHECKS */ if(output_log_syslog || error_log_syslog || access_log_syslog) openlog("netdata", LOG_PID, LOG_DAEMON); info("NetData started on pid %d", getpid()); // ------------------------------------------------------------------------ // get default pthread stack size if(stacksize < wanted_stacksize) { i = pthread_attr_setstacksize(&attr, wanted_stacksize); if(i != 0) fatal("pthread_attr_setstacksize() to %zu bytes, failed with code %d.", wanted_stacksize, i); else info("Successfully set pthread stacksize to %zu bytes", wanted_stacksize); } // -------------------------------------------------------------------- // initialize the registry registry_init(); // ------------------------------------------------------------------------ // spawn the threads web_server_threading_selection(); for (i = 0; static_threads[i].name != NULL ; i++) { struct netdata_static_thread *st = &static_threads[i]; if(st->enabled) { st->thread = malloc(sizeof(pthread_t)); if(!st->thread) fatal("Cannot allocate pthread_t memory"); info("Starting thread %s.", st->name); if(pthread_create(st->thread, &attr, st->start_routine, NULL)) error("failed to create new thread for %s.", st->name); else if(pthread_detach(*st->thread)) error("Cannot request detach of newly created %s thread.", st->name); } else info("Not starting thread %s.", st->name); } // ------------------------------------------------------------------------ // block signals while initializing threads. sigset_t sigset; sigfillset(&sigset); if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) { error("Could not unblock signals for threads"); } // Handle flags set in the signal handler. while(1) { pause(); if(netdata_exit) { info("Exit main loop of netdata."); netdata_cleanup_and_exit(0); exit(0); } } }
exception_t decodeSetSpace(cap_t cap, unsigned int length, cte_t* slot, extra_caps_t extraCaps, word_t *buffer) { cptr_t faultEP; word_t cRootData, vRootData; cte_t *cRootSlot, *vRootSlot; cap_t cRootCap, vRootCap; deriveCap_ret_t dc_ret; if (length < 3 || extraCaps.excaprefs[0] == NULL || extraCaps.excaprefs[1] == NULL) { userError("TCB SetSpace: Truncated message."); current_syscall_error.type = seL4_TruncatedMessage; return EXCEPTION_SYSCALL_ERROR; } faultEP = getSyscallArg(0, buffer); cRootData = getSyscallArg(1, buffer); vRootData = getSyscallArg(2, buffer); cRootSlot = extraCaps.excaprefs[0]; cRootCap = extraCaps.excaprefs[0]->cap; vRootSlot = extraCaps.excaprefs[1]; vRootCap = extraCaps.excaprefs[1]->cap; if (slotCapLongRunningDelete( TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), tcbCTable)) || slotCapLongRunningDelete( TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), tcbVTable))) { userError("TCB SetSpace: CSpace or VSpace currently being deleted."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } if (cRootData != 0) { cRootCap = updateCapData(false, cRootData, cRootCap); } dc_ret = deriveCap(cRootSlot, cRootCap); if (dc_ret.status != EXCEPTION_NONE) { return dc_ret.status; } cRootCap = dc_ret.cap; if (cap_get_capType(cRootCap) != cap_cnode_cap && (!config_set(CONFIG_ALLOW_NULL_CSPACE) || cap_get_capType(cRootCap) != cap_null_cap)) { userError("TCB SetSpace: Invalid CNode cap."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } if (vRootData != 0) { vRootCap = updateCapData(false, vRootData, vRootCap); } dc_ret = deriveCap(vRootSlot, vRootCap); if (dc_ret.status != EXCEPTION_NONE) { return dc_ret.status; } vRootCap = dc_ret.cap; if (!isValidVTableRoot(vRootCap)) { userError("TCB SetSpace: Invalid VSpace cap."); current_syscall_error.type = seL4_IllegalOperation; return EXCEPTION_SYSCALL_ERROR; } setThreadState(ksCurThread, ThreadState_Restart); return invokeTCB_ThreadControl( TCB_PTR(cap_thread_cap_get_capTCBPtr(cap)), slot, faultEP, 0, /* used to be prioInvalid, but it doesn't matter */ cRootCap, cRootSlot, vRootCap, vRootSlot, 0, cap_null_cap_new(), NULL, thread_control_update_space); }
static BOOT_CODE bool_t is_compiled_for_microarchitecture(void) { word_t microarch_generation = 0; x86_cpu_identity_t *model_info = x86_cpuid_get_model_info(); if (config_set(CONFIG_ARCH_X86_SKYLAKE) ) { microarch_generation = 7; } else if (config_set(CONFIG_ARCH_X86_BROADWELL) ) { microarch_generation = 6; } else if (config_set(CONFIG_ARCH_X86_HASWELL) ) { microarch_generation = 5; } else if (config_set(CONFIG_ARCH_X86_IVY) ) { microarch_generation = 4; } else if (config_set(CONFIG_ARCH_X86_SANDY) ) { microarch_generation = 3; } else if (config_set(CONFIG_ARCH_X86_WESTMERE) ) { microarch_generation = 2; } else if (config_set(CONFIG_ARCH_X86_NEHALEM) ) { microarch_generation = 1; } switch (model_info->model) { case SKYLAKE_1_MODEL_ID: case SKYLAKE_2_MODEL_ID: if (microarch_generation > 7) { return false; } break; case BROADWELL_1_MODEL_ID: case BROADWELL_2_MODEL_ID: case BROADWELL_3_MODEL_ID: case BROADWELL_4_MODEL_ID: case BROADWELL_5_MODEL_ID: if (microarch_generation > 6) { return false; } break; case HASWELL_1_MODEL_ID: case HASWELL_2_MODEL_ID: case HASWELL_3_MODEL_ID: case HASWELL_4_MODEL_ID: if (microarch_generation > 5) { return false; } break; case IVY_BRIDGE_1_MODEL_ID: case IVY_BRIDGE_2_MODEL_ID: case IVY_BRIDGE_3_MODEL_ID: if (microarch_generation > 4) { return false; } break; case SANDY_BRIDGE_1_MODEL_ID: case SANDY_BRIDGE_2_MODEL_ID: if (microarch_generation > 3) { return false; } break; case WESTMERE_1_MODEL_ID: case WESTMERE_2_MODEL_ID: case WESTMERE_3_MODEL_ID: if (microarch_generation > 2) { return false; } break; case NEHALEM_1_MODEL_ID: case NEHALEM_2_MODEL_ID: case NEHALEM_3_MODEL_ID: if (microarch_generation > 1) { return false; } break; default: if (!config_set(CONFIG_ARCH_X86_GENERIC)) { return false; } } return true; }
int main(int argc, char **argv) { int i; int config_loaded = 0; int dont_fork = 0; size_t default_stacksize; // set the name for logging program_name = "netdata"; // parse depercated options // TODO: Remove this block with the next major release. { i = 1; while(i < argc) { if(strcmp(argv[i], "-pidfile") == 0 && (i+1) < argc) { strncpyz(pidfile, argv[i+1], FILENAME_MAX); fprintf(stderr, "%s: deprecated option -- %s -- please use -P instead.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-nodaemon") == 0 || strcmp(argv[i], "-nd") == 0) { dont_fork = 1; fprintf(stderr, "%s: deprecated option -- %s -- please use -D instead.\n ", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-ch") == 0 && (i+1) < argc) { config_set(CONFIG_SECTION_GLOBAL, "host access prefix", argv[i+1]); fprintf(stderr, "%s: deprecated option -- %s -- please use -s instead.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) { config_set(CONFIG_SECTION_GLOBAL, "history", argv[i+1]); fprintf(stderr, "%s: deprecated option -- %s -- This option will be removed with V2.*.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else i++; } } // parse options { int num_opts = sizeof(option_definitions) / sizeof(struct option_def); char optstring[(num_opts * 2) + 1]; int string_i = 0; for( i = 0; i < num_opts; i++ ) { optstring[string_i] = option_definitions[i].val; string_i++; if(option_definitions[i].arg_name) { optstring[string_i] = ':'; string_i++; } } // terminate optstring optstring[string_i] ='\0'; optstring[(num_opts *2)] ='\0'; int opt; while( (opt = getopt(argc, argv, optstring)) != -1 ) { switch(opt) { case 'c': if(config_load(optarg, 1) != 1) { error("Cannot load configuration file %s.", optarg); return 1; } else { debug(D_OPTIONS, "Configuration loaded from %s.", optarg); config_loaded = 1; } break; case 'D': dont_fork = 1; break; case 'h': return help(0); case 'i': config_set(CONFIG_SECTION_WEB, "bind to", optarg); break; case 'P': strncpy(pidfile, optarg, FILENAME_MAX); pidfile[FILENAME_MAX] = '\0'; break; case 'p': config_set(CONFIG_SECTION_GLOBAL, "default port", optarg); break; case 's': config_set(CONFIG_SECTION_GLOBAL, "host access prefix", optarg); break; case 't': config_set(CONFIG_SECTION_GLOBAL, "update every", optarg); break; case 'u': config_set(CONFIG_SECTION_GLOBAL, "run as user", optarg); break; case 'v': case 'V': printf("%s %s\n", program_name, program_version); return 0; case 'W': { char* stacksize_string = "stacksize="; char* debug_flags_string = "debug_flags="; if(strcmp(optarg, "unittest") == 0) { if(unit_test_buffer()) return 1; if(unit_test_str2ld()) return 1; //default_rrd_update_every = 1; //default_rrd_memory_mode = RRD_MEMORY_MODE_RAM; //if(!config_loaded) config_load(NULL, 0); get_netdata_configured_variables(); default_rrd_update_every = 1; default_rrd_memory_mode = RRD_MEMORY_MODE_RAM; default_health_enabled = 0; rrd_init("unittest"); default_rrdpush_enabled = 0; if(run_all_mockup_tests()) return 1; if(unit_test_storage()) return 1; fprintf(stderr, "\n\nALL TESTS PASSED\n\n"); return 0; } else if(strcmp(optarg, "simple-pattern") == 0) { if(optind + 2 > argc) { fprintf(stderr, "%s", "\nUSAGE: -W simple-pattern 'pattern' 'string'\n\n" " Checks if 'pattern' matches the given 'string'.\n" " - 'pattern' can be one or more space separated words.\n" " - each 'word' can contain one or more asterisks.\n" " - words starting with '!' give negative matches.\n" " - words are processed left to right\n" "\n" "Examples:\n" "\n" " > match all veth interfaces, except veth0:\n" "\n" " -W simple-pattern '!veth0 veth*' 'veth12'\n" "\n" "\n" " > match all *.ext files directly in /path/:\n" " (this will not match *.ext files in a subdir of /path/)\n" "\n" " -W simple-pattern '!/path/*/*.ext /path/*.ext' '/path/test.ext'\n" "\n" ); return 1; } const char *heystack = argv[optind]; const char *needle = argv[optind + 1]; size_t len = strlen(needle) + 1; char wildcarded[len]; SIMPLE_PATTERN *p = simple_pattern_create(heystack, NULL, SIMPLE_PATTERN_EXACT); int ret = simple_pattern_matches_extract(p, needle, wildcarded, len); simple_pattern_free(p); if(ret) { fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s', wildcarded '%s'\n", heystack, needle, wildcarded); return 0; } else { fprintf(stdout, "RESULT: NOT MATCHED - pattern '%s' does not match '%s', wildcarded '%s'\n", heystack, needle, wildcarded); return 1; } } else if(strncmp(optarg, stacksize_string, strlen(stacksize_string)) == 0) { optarg += strlen(stacksize_string); config_set(CONFIG_SECTION_GLOBAL, "pthread stack size", optarg); } else if(strncmp(optarg, debug_flags_string, strlen(debug_flags_string)) == 0) { optarg += strlen(debug_flags_string); config_set(CONFIG_SECTION_GLOBAL, "debug flags", optarg); debug_flags = strtoull(optarg, NULL, 0); } else if(strcmp(optarg, "set") == 0) { if(optind + 3 > argc) { fprintf(stderr, "%s", "\nUSAGE: -W set 'section' 'key' 'value'\n\n" " Overwrites settings of netdata.conf.\n" "\n" " These options interact with: -c netdata.conf\n" " If -c netdata.conf is given on the command line,\n" " before -W set... the user may overwrite command\n" " line parameters at netdata.conf\n" " If -c netdata.conf is given after (or missing)\n" " -W set... the user cannot overwrite the command line\n" " parameters." "\n" ); return 1; } const char *section = argv[optind]; const char *key = argv[optind + 1]; const char *value = argv[optind + 2]; optind += 3; // set this one as the default // only if it is not already set in the config file // so the caller can use -c netdata.conf before or // after this parameter to prevent or allow overwriting // variables at netdata.conf config_set_default(section, key, value); // fprintf(stderr, "SET section '%s', key '%s', value '%s'\n", section, key, value); } else if(strcmp(optarg, "get") == 0) { if(optind + 3 > argc) { fprintf(stderr, "%s", "\nUSAGE: -W get 'section' 'key' 'value'\n\n" " Prints settings of netdata.conf.\n" "\n" " These options interact with: -c netdata.conf\n" " -c netdata.conf has to be given before -W get.\n" "\n" ); return 1; } if(!config_loaded) { fprintf(stderr, "warning: no configuration file has been loaded. Use -c CONFIG_FILE, before -W get. Using default config.\n"); config_load(NULL, 0); } backwards_compatible_config(); get_netdata_configured_variables(); const char *section = argv[optind]; const char *key = argv[optind + 1]; const char *def = argv[optind + 2]; const char *value = config_get(section, key, def); printf("%s\n", value); return 0; } else { fprintf(stderr, "Unknown -W parameter '%s'\n", optarg); return help(1); } } break; default: /* ? */ fprintf(stderr, "Unknown parameter '%c'\n", opt); return help(1); } } } #ifdef _SC_OPEN_MAX // close all open file descriptors, except the standard ones // the caller may have left open files (lxc-attach has this issue) { int fd; for(fd = (int) (sysconf(_SC_OPEN_MAX) - 1); fd > 2; fd--) if(fd_is_valid(fd)) close(fd); } #endif if(!config_loaded) config_load(NULL, 0); // ------------------------------------------------------------------------ // initialize netdata { char *pmax = config_get(CONFIG_SECTION_GLOBAL, "glibc malloc arena max for plugins", "1"); if(pmax && *pmax) setenv("MALLOC_ARENA_MAX", pmax, 1); #if defined(HAVE_C_MALLOPT) i = (int)config_get_number(CONFIG_SECTION_GLOBAL, "glibc malloc arena max for netdata", 1); if(i > 0) mallopt(M_ARENA_MAX, 1); #endif // prepare configuration environment variables for the plugins get_netdata_configured_variables(); set_global_environment(); // work while we are cd into config_dir // to allow the plugins refer to their config // files using relative filenames if(chdir(netdata_configured_config_dir) == -1) fatal("Cannot cd to '%s'", netdata_configured_config_dir); } char *user = NULL; { // -------------------------------------------------------------------- // get the debugging flags from the configuration file char *flags = config_get(CONFIG_SECTION_GLOBAL, "debug flags", "0x0000000000000000"); setenv("NETDATA_DEBUG_FLAGS", flags, 1); debug_flags = strtoull(flags, NULL, 0); debug(D_OPTIONS, "Debug flags set to '0x%" PRIX64 "'.", debug_flags); if(debug_flags != 0) { struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; if(setrlimit(RLIMIT_CORE, &rl) != 0) error("Cannot request unlimited core dumps for debugging... Proceeding anyway..."); #ifdef HAVE_SYS_PRCTL_H prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); #endif } // -------------------------------------------------------------------- // get log filenames and settings log_init(); error_log_limit_unlimited(); // -------------------------------------------------------------------- // load stream.conf { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s/stream.conf", netdata_configured_config_dir); appconfig_load(&stream_config, filename, 0); } // -------------------------------------------------------------------- // setup process signals // block signals while initializing threads. // this causes the threads to block signals. signals_block(); // setup the signals we want to use signals_init(); // setup threads configs default_stacksize = netdata_threads_init(); // -------------------------------------------------------------------- // check which threads are enabled and initialize them for (i = 0; static_threads[i].name != NULL ; i++) { struct netdata_static_thread *st = &static_threads[i]; if(st->config_name) st->enabled = config_get_boolean(st->config_section, st->config_name, st->enabled); if(st->enabled && st->init_routine) st->init_routine(); } // -------------------------------------------------------------------- // get the user we should run // IMPORTANT: this is required before web_files_uid() if(getuid() == 0) { user = config_get(CONFIG_SECTION_GLOBAL, "run as user", NETDATA_USER); } else { struct passwd *passwd = getpwuid(getuid()); user = config_get(CONFIG_SECTION_GLOBAL, "run as user", (passwd && passwd->pw_name)?passwd->pw_name:""); } // -------------------------------------------------------------------- // create the listening sockets web_client_api_v1_init(); web_server_threading_selection(); if(web_server_mode != WEB_SERVER_MODE_NONE) api_listen_sockets_setup(); } // initialize the log files open_all_log_files(); #ifdef NETDATA_INTERNAL_CHECKS if(debug_flags != 0) { struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; if(setrlimit(RLIMIT_CORE, &rl) != 0) error("Cannot request unlimited core dumps for debugging... Proceeding anyway..."); #ifdef HAVE_SYS_PRCTL_H prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); #endif } #endif /* NETDATA_INTERNAL_CHECKS */ // get the max file limit if(getrlimit(RLIMIT_NOFILE, &rlimit_nofile) != 0) error("getrlimit(RLIMIT_NOFILE) failed"); else info("resources control: allowed file descriptors: soft = %zu, max = %zu", rlimit_nofile.rlim_cur, rlimit_nofile.rlim_max); // fork, switch user, create pid file, set process priority if(become_daemon(dont_fork, user) == -1) fatal("Cannot daemonize myself."); info("netdata started on pid %d.", getpid()); // IMPORTANT: these have to run once, while single threaded // but after we have switched user web_files_uid(); web_files_gid(); netdata_threads_init_after_fork((size_t)config_get_number(CONFIG_SECTION_GLOBAL, "pthread stack size", (long)default_stacksize)); // ------------------------------------------------------------------------ // initialize rrd, registry, health, rrdpush, etc. rrd_init(netdata_configured_hostname); // ------------------------------------------------------------------------ // enable log flood protection error_log_limit_reset(); // ------------------------------------------------------------------------ // spawn the threads web_server_config_options(); for (i = 0; static_threads[i].name != NULL ; i++) { struct netdata_static_thread *st = &static_threads[i]; if(st->enabled) { st->thread = mallocz(sizeof(netdata_thread_t)); debug(D_SYSTEM, "Starting thread %s.", st->name); netdata_thread_create(st->thread, st->name, NETDATA_THREAD_OPTION_DEFAULT, st->start_routine, st); } else debug(D_SYSTEM, "Not starting thread %s.", st->name); } info("netdata initialization completed. Enjoy real-time performance monitoring!"); // ------------------------------------------------------------------------ // unblock signals signals_unblock(); // ------------------------------------------------------------------------ // Handle signals signals_handle(); // should never reach this point // but we need it for rpmlint #2752 return 1; }
static void config_set_internal ( const char *name, int subopt, const char *value ) { if (config_set(name, subopt, value)) FATAL("Internal built-in configuration error: config_set_internal(\"%s\",%d,\"%s\")", name, subopt, value); }