Пример #1
0
void	zbx_on_exit(void)
{
	unload_modules();
	zabbix_close_log();

	free_metrics();
	alias_list_free();

	exit(EXIT_SUCCESS);
}
Пример #2
0
void	zbx_on_exit()
{
	unload_modules();
	zabbix_close_log();

	free_metrics();
	alias_list_free();

	exit(SUCCEED);
}
Пример #3
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_free_service_resources                                       *
 *                                                                            *
 * Purpose: free service resources allocated by main thread                   *
 *                                                                            *
 ******************************************************************************/
void	zbx_free_service_resources(void)
{
	if (NULL != threads)
	{
		int		i;
#if !defined(_WINDOWS)
		sigset_t	set;

		/* ignore SIGCHLD signals in order for zbx_sleep() to work */
		sigemptyset(&set);
		sigaddset(&set, SIGCHLD);
		sigprocmask(SIG_BLOCK, &set, NULL);
#else
		/* wait for threads to finish first. although listener threads will never end */
		WaitForMultipleObjectsEx(threads_num, threads, TRUE, 1000, FALSE);
#endif
		for (i = 0; i < threads_num; i++)
		{
			if (threads[i])
				zbx_thread_kill(threads[i]);
		}

		for (i = 0; i < threads_num; i++)
		{
			if (threads[i])
				zbx_thread_wait(threads[i]);

			threads[i] = ZBX_THREAD_HANDLE_NULL;
		}

		zbx_free(threads);
	}

	zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Agent stopped. Zabbix %s (revision %s).",
			ZABBIX_VERSION, ZABBIX_REVISION);

#ifndef _WINDOWS
	unload_modules();
#endif
	zabbix_close_log();

	free_metrics();
	alias_list_free();
	free_collector_data();
#ifdef _WINDOWS
	free_perf_collector();
	zbx_co_uninitialize();
#endif
}
Пример #4
0
void
quit(int exitcode)
{
    printf("Signal %d received\n", exitcode);
    // Stop server thread
    stop_server();
    // Stop CLI server thread
    cli_server_stop();
    // Stop manager thread
    stop_manager();
    // Remove all loaded modules. They should unregister their apps
    unload_modules();
    // if requested to restart
    //if (sig == SIGHUP) execvp(_argv[0], _argv);
    // Exit the program!
    exit(exitcode);
}
Пример #5
0
/**
 * Deinit NuAuth:
 *    - Stop NuAuth: close_nufw_servers(), close_clients(), end_tls(), end_audit() ;
 *    - Free memory ;
 *    - Unload modules: unload_modules() ;
 *    - Destroy pid file ;
 *    - And finally exit.
*
 */
void nuauth_deinit(gboolean soft)
{
	log_message(CRITICAL, DEBUG_AREA_MAIN, "[+] NuAuth deinit");
#if 0
	signal(SIGTERM, SIG_DFL);
	signal(SIGKILL, SIG_DFL);
	signal(SIGHUP, SIG_DFL);
#endif

	stop_threads(soft);

	log_message(INFO, DEBUG_AREA_MAIN, "Unloading modules");
	unload_modules();

#if 0
	end_tls();
#endif

	log_message(INFO, DEBUG_AREA_MAIN, "Ending audit");
	end_audit();

	log_message(INFO, DEBUG_AREA_MAIN, "Freeing memory");
	free_nuauth_params(nuauthconf);
	if (nuauthconf->acl_cache) {
		cache_destroy(nuauthdatas->acl_cache);
	}
	if (nuauthconf->user_cache) {
		cache_destroy(nuauthdatas->user_cache);
	}
	g_free(nuauthdatas->program_fullpath);
	free_threads();
	clear_push_queue();

	g_hash_table_destroy(conn_list);

	g_static_mutex_free(&insert_mutex);

	/* destroy pid file */
	unlink(NUAUTH_PID_FILE);
}
	CError CModuleManager::unload_unused_embedded_modules()
	{
		guid_set module_ids;
		/* first pass - collect ids of all embedded modules */
		for( map_guid_to_interface_definition::const_iterator i = m_module_id_map.begin(); i != m_module_id_map.end(); i++ )
		{
			const IInterfaceDefinition *interface_definition = i->second;

			if( interface_definition->get_module_source() == CInterfaceDefinition::MODULE_EMBEDDED )
			{
				module_ids.insert( interface_definition->get_module_guid() );
			}
		}

		/* second pass - walk node tree pruning any modules still in use */
		remove_in_use_module_ids_from_set( m_server.get_nodes(), module_ids );

		/* third pass - unload modules */
		unload_modules( module_ids );

		return CError::SUCCESS;
	}
Пример #7
0
int	main(int argc, char **argv)
{
	ZBX_TASK_EX	t;
#ifdef _WINDOWS
	int		ret;

	/* Provide, so our process handles errors instead of the system itself. */
	/* Attention!!! */
	/* The system does not display the critical-error-handler message box. */
	/* Instead, the system sends the error to the calling process.*/
	SetErrorMode(SEM_FAILCRITICALERRORS);
#endif
#if defined(PS_OVERWRITE_ARGV) || defined(PS_PSTAT_ARGV)
	argv = setproctitle_save_env(argc, argv);
#endif
	memset(&t, 0, sizeof(t));
	t.task = ZBX_TASK_START;

	progname = get_program_name(argv[0]);

	parse_commandline(argc, argv, &t);

	import_symbols();

	/* this is needed to set default hostname in zbx_load_config() */
	init_metrics();

	switch (t.task)
	{
		case ZBX_TASK_SHOW_USAGE:
			usage();
			exit(EXIT_FAILURE);
			break;
#ifdef _WINDOWS
		case ZBX_TASK_INSTALL_SERVICE:
		case ZBX_TASK_UNINSTALL_SERVICE:
		case ZBX_TASK_START_SERVICE:
		case ZBX_TASK_STOP_SERVICE:
			zbx_load_config(ZBX_CFG_FILE_REQUIRED);
			zbx_free_config();

			if (t.flags & ZBX_TASK_FLAG_MULTIPLE_AGENTS)
			{
				zbx_snprintf(ZABBIX_SERVICE_NAME, sizeof(ZABBIX_SERVICE_NAME), "%s [%s]",
						APPLICATION_NAME, CONFIG_HOSTNAME);
				zbx_snprintf(ZABBIX_EVENT_SOURCE, sizeof(ZABBIX_EVENT_SOURCE), "%s [%s]",
						APPLICATION_NAME, CONFIG_HOSTNAME);
			}

			ret = zbx_exec_service_task(argv[0], &t);
			free_metrics();
			exit(ret);
			break;
#endif
		case ZBX_TASK_TEST_METRIC:
		case ZBX_TASK_PRINT_SUPPORTED:
			zbx_load_config(ZBX_CFG_FILE_OPTIONAL);
#ifdef _WINDOWS
			init_perf_collector(0);
			load_perf_counters(CONFIG_PERF_COUNTERS);
#else
			zbx_set_common_signal_handlers();
#endif
#ifndef _WINDOWS
			if (FAIL == load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 0))
			{
				zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting...");
				exit(EXIT_FAILURE);
			}
#endif
			load_user_parameters(CONFIG_USER_PARAMETERS);
			load_aliases(CONFIG_ALIASES);
			zbx_free_config();
			if (ZBX_TASK_TEST_METRIC == t.task)
				test_parameter(TEST_METRIC);
			else
				test_parameters();
#ifdef _WINDOWS
			free_perf_collector();	/* cpu_collector must be freed before perf_collector is freed */
#endif
#ifndef _WINDOWS
			unload_modules();
#endif
			free_metrics();
			alias_list_free();
			exit(SUCCEED);
			break;
		default:
			zbx_load_config(ZBX_CFG_FILE_REQUIRED);
			break;
	}

	START_MAIN_ZABBIX_ENTRY(CONFIG_ALLOW_ROOT);

	exit(SUCCEED);
}
Пример #8
0
int main(int argc, char *argv[])
{
    int     ret, server_mode;
    void    *host_addr = memalign(1024 * 1024, HOST_SIZE);
    msgType dialog_type;
	sys_ppu_thread_t id; // start server thread

    load_modules();

    init_logging();

	netInitialize();
	netCtlInit();

    // Initialize SPUs
    LOG(lm_main, LOG_DEBUG, ("Initializing SPUs\n"));
    ret = sysSpuInitialize(MAX_PHYSICAL_SPU, MAX_RAW_SPU);
    if (ret != 0)
    {
        LOG(lm_main, LOG_ERROR, ("sysSpuInitialize failed: %d\n", ret));
        goto quit;
    }

    init_screen(host_addr, HOST_SIZE);
    ioPadInit(7);

    ret = initialize_exit_handlers();
    if (ret != 0)
        goto quit;

    show_version();

    if (user_requested_exit())
        goto quit;

	u64 CEX=0x4345580000000000ULL;
	u64 DEX=0x4445580000000000ULL;
	u64 DEH=0x4445480000000000ULL;

	if(lv2peek(0x80000000002E79C8ULL)==DEX) {dex_mode=2; c_firmware=3.41f;}
	else
	if(lv2peek(0x80000000002CFF98ULL)==CEX) {dex_mode=0; c_firmware=3.41f;}
	else
	if(lv2peek(0x80000000002EFE20ULL)==DEX) {dex_mode=2; c_firmware=3.55f;}
	else
	if(lv2peek(0x80000000002D83D0ULL)==CEX) {dex_mode=0; c_firmware=3.55f;}
	else
	if(lv2peek(0x8000000000302D88ULL)==DEX) {dex_mode=2; c_firmware=4.21f;}
	else
	if(lv2peek(0x80000000002E8610ULL)==CEX) {dex_mode=0; c_firmware=4.21f;}
	else
	if(lv2peek(0x80000000002E9F08ULL)==CEX) {dex_mode=0; c_firmware=4.30f;}
	else
	if(lv2peek(0x8000000000304630ULL)==DEX) {dex_mode=2; c_firmware=4.30f;}
	else
	if(lv2peek(0x80000000002E9F18ULL)==CEX) {dex_mode=0; c_firmware=4.31f;}
	else
	if(lv2peek(0x80000000002EA488ULL)==CEX) {dex_mode=0; c_firmware=4.40f;}
	else
	if(lv2peek(0x80000000002EA498ULL)==CEX) {dex_mode=0; c_firmware=4.41f;}
	else
	if(lv2peek(0x8000000000304EF0ULL)==DEX) {dex_mode=2; c_firmware=4.41f;}
	else
	if(lv2peek(0x80000000002EA9B8ULL)==CEX) {dex_mode=0; c_firmware=4.46f;}
	else
	if(lv2peek(0x8000000000305410ULL)==DEX) {dex_mode=2; c_firmware=4.46f;}
	else
	if(lv2peek(0x80000000002E9BE0ULL)==CEX) {dex_mode=0; c_firmware=4.50f;}
	else
	if(lv2peek(0x8000000000309698ULL)==DEX) {dex_mode=2; c_firmware=4.50f;}
	else
	if(lv2peek(0x80000000002E9D70ULL)==CEX) {dex_mode=0; c_firmware=4.53f;}
	else
	if(lv2peek(0x80000000002EC5E0ULL)==CEX) {dex_mode=0; c_firmware=4.55f;}
	else
	if(lv2peek(0x80000000002ED850ULL)==CEX) {dex_mode=0; c_firmware=4.60f;}
	else
	if(lv2peek(0x80000000002ED860ULL)==CEX) {dex_mode=0; c_firmware=4.65f;}
	else
	if(lv2peek(0x800000000030F1A8ULL)==DEX) {dex_mode=2; c_firmware=4.65f;}
	else
	if(lv2peek(0x80000000002ED778ULL)==CEX) {dex_mode=0; c_firmware=4.70f;}
	else
	if(lv2peek(0x800000000030F240ULL)==DEX) {dex_mode=2; c_firmware=4.70f;}
	else
	if(lv2peek(0x80000000002ED818ULL)==CEX) {dex_mode=0; c_firmware=4.75f;}
	else
	if(lv2peek(0x800000000030F2D0ULL)==DEX) {dex_mode=2; c_firmware=4.75f;}
	else
	if(lv2peek(0x80000000002ED808ULL)==CEX) {dex_mode=0; c_firmware=4.80f;}
	else
	if(lv2peek(0x800000000030F3A0ULL)==DEX) {dex_mode=2; c_firmware=4.80f;}
	else
	if(lv2peek(0x800000000030F3B0ULL)==DEX) {dex_mode=2; c_firmware=4.81f;}
	else
	if(lv2peek(0x800000000032EB60ULL)==DEH) {deh_mode=2; c_firmware=4.81f;}
	else	
		c_firmware=0.00f;

	if(c_firmware==3.55f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_355D;
	}
	else
	if(c_firmware==3.55f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_355;
	}
	else
	if(c_firmware==4.21f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_421;
	}
	else
	if(c_firmware==4.30f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_430;
	}
	else
	if(c_firmware==4.30f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_430D;
	}
	else
	if(c_firmware==4.31f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_431;
	}
	else
	if(c_firmware==4.40f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_440;
	}
	else
	if(c_firmware==4.41f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_441;
	}
	else
	if(c_firmware==4.41f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_441D;
	}
	else
	if(c_firmware==4.46f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_446;
	}
	else
	if(c_firmware==4.50f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_450;
	}
	else
	if(c_firmware==4.53f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_453;
	}
	else
	if(c_firmware==4.55f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_455;
	}
	else
	if(c_firmware==4.60f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_460;
	}
	else
	if(c_firmware==4.65f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_465;
	}
	else
	if(c_firmware==4.65f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_465D;
	}
	else
	if(c_firmware==4.70f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_470;
	}
	else
	if(c_firmware==4.70f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_470D;
	}
	else
	if(c_firmware==4.75f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_475;
	}
	else
	if(c_firmware==4.80f && !dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_480;
	}
	else
	if(c_firmware==4.80f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_480D;
	}
	else
	if(c_firmware==4.75f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_475D;
	}
	else
	if(c_firmware==4.81f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_481D;
	}
	else
	if(c_firmware==4.46f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_446D;
	}
	else
	if(c_firmware==4.50f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_450D;
	}
	else
	if(c_firmware==4.21f && dex_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_421D;
	}
	else
	if(c_firmware==3.41f)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_341;
	}
	else
	if(c_firmware==4.81f && deh_mode)
	{
		SYSCALL_TABLE			= SYSCALL_TABLE_481H;
	}	
/*
	if(c_firmware>=4.20f && SYSCALL_TABLE)
	{
		// add and enable lv2 peek/poke + lv1 peek/poke
		lv2poke(0x800000000000171CULL,       0x7C0802A6F8010010ULL);
		lv2poke(0x800000000000171CULL +   8, 0x396000B644000022ULL);
		lv2poke(0x800000000000171CULL +  16, 0x7C832378E8010010ULL);
		lv2poke(0x800000000000171CULL +  24, 0x7C0803A64E800020ULL);
		lv2poke(0x800000000000171CULL +  32, 0x7C0802A6F8010010ULL);
		lv2poke(0x800000000000171CULL +  40, 0x396000B744000022ULL);
		lv2poke(0x800000000000171CULL +  48, 0x38600000E8010010ULL);
		lv2poke(0x800000000000171CULL +  56, 0x7C0803A64E800020ULL);
		lv2poke(0x800000000000171CULL +  64, 0x7C0802A6F8010010ULL);
		lv2poke(0x800000000000171CULL +  72, 0x7D4B537844000022ULL);
		lv2poke(0x800000000000171CULL +  80, 0xE80100107C0803A6ULL);
		lv2poke(0x800000000000171CULL +  88, 0x4E80002080000000ULL);
		lv2poke(0x800000000000171CULL +  96, 0x0000170C80000000ULL);
		lv2poke(0x800000000000171CULL + 104, 0x0000171480000000ULL);
		lv2poke(0x800000000000171CULL + 112, 0x0000171C80000000ULL);
		lv2poke(0x800000000000171CULL + 120, 0x0000173C80000000ULL);
		lv2poke(0x800000000000171CULL + 128, 0x0000175C00000000ULL);
		lv2poke(SYSCALL_PTR( 6), 0x8000000000001778ULL); //sc6
		lv2poke(SYSCALL_PTR( 7), 0x8000000000001780ULL); //sc7
		lv2poke(SYSCALL_PTR( 8), 0x8000000000001788ULL); //sc8
		lv2poke(SYSCALL_PTR( 9), 0x8000000000001790ULL); //sc9
		lv2poke(SYSCALL_PTR(10), 0x8000000000001798ULL); //sc10
	}*/
    // remove patch protection
	if(c_firmware==3.55f)
	    remove_protection();

	if(c_firmware==0.00f)
		ret = -1;
	else
	    ret = patch_lv1_ss_services();
    if (ret < 0)
    {
        dialog_type = (MSG_DIALOG_NORMAL | MSG_DIALOG_BTN_TYPE_OK | MSG_DIALOG_DISABLE_CANCEL_ON);
        msgDialogOpen2(dialog_type, "ERROR: Couldn't patch lv1 services, returning to the XMB.\nMake sure you are running a firmware which allows patching!", dialog_handler, NULL, NULL);

        dialog_action = 0;
        while (!dialog_action && !user_requested_exit())
        {
            sysUtilCheckCallback();
            flip();
        }
        msgDialogAbort();

        goto quit;
    }

    // patch syscall 864 to allow drive re-init
	if(c_firmware==0.0f)
		ret = -1;
	else
	    ret = patch_syscall_864();
    if (ret < 0)
    {
        dialog_type = (MSG_DIALOG_NORMAL | MSG_DIALOG_BTN_TYPE_OK | MSG_DIALOG_DISABLE_CANCEL_ON);
        msgDialogOpen2(dialog_type, "ERROR: Couldn't patch syscall 864, returning to the XMB.\nMake sure you are running a firmware which allows patching!", dialog_handler, NULL, NULL);

        dialog_action = 0;
        while (!dialog_action && !user_requested_exit())
        {
            sysUtilCheckCallback();
            flip();
        }
        msgDialogAbort();

        goto quit;
    }

    // install the necessary modules
    ret = install_modules();
    if (ret < 0)
    {
        dialog_type = (MSG_DIALOG_NORMAL | MSG_DIALOG_BTN_TYPE_OK | MSG_DIALOG_DISABLE_CANCEL_ON);
        msgDialogOpen2(dialog_type, "Installation was aborted, returning to the XMB.", dialog_handler, NULL, NULL);

        dialog_action = 0;
        while (!dialog_action && !user_requested_exit())
        {
            sysUtilCheckCallback();
            flip();
        }
        msgDialogAbort();

        goto quit;
    }

    if (user_requested_exit())
        goto quit;

    // reset & re-authenticate the BD drive
    sys_storage_reset_bd();
    sys_storage_authenticate_bd();

    // eject current disc
    {
        int fd;
        ret = sys_storage_open(BD_DEVICE, &fd);
        if (ret == 0)
        {
            ioctl_eject(fd);
            sys_storage_close(fd);
        }
    }

    ret = sysDiscRegisterDiscChangeCallback(&bd_eject_disc_callback, &bd_insert_disc_callback);

    // poll for an output_device
    poll_output_devices();

    server_mode = user_select_server_mode();

    if (user_requested_exit())
        goto quit;

    if (server_mode)
    {
#ifdef ENABLE_LOGGING
        if (output_device)
        {
            char file_path[100];
            sprintf(file_path, "%s/daemon_log.txt", output_device);
            set_log_file(file_path);
        }
#endif
    	sysThreadCreate(&id, listener_thread, NULL, 1500, 0x400, 0, "listener");

        while (1)
        {
            // server loop
            server_loop();

            // break out of the loop when requested
            if (user_requested_exit())
                break;
        }
    }
    else
    {
        while (1)
        {
            // main loop
            main_loop();

            // break out of the loop when requested
            if (user_requested_exit())
                break;
        }
    }

    ret = sysDiscUnregisterDiscChangeCallback();

 quit:

    unpatch_lv1_ss_services();

    destroy_logging();
	netDeinitialize();
    unload_modules();

    free(host_addr);

    return 0;
}
Пример #9
0
void mod_fini(void) {
	mp_cache_destroy(&mod_cache);

	unload_modules();
}
Пример #10
0
/**
 * exit function if a signal is received in daemon mode.
 *
 * Argument: signal number
 * Return: None
 */
gboolean nuauth_reload(int signum)
{
	struct nuauth_params *newconf = NULL;
	gboolean restart;
	int retval;

	g_message("[+] Reload NuAuth server");
	nuauth_install_signals(FALSE);

	/* Reload the configuration file */
	retval = nuauth_parse_configuration(nuauthconf->configfile);
	if (retval != 0) {
		log_message(CRITICAL, DEBUG_AREA_MAIN,
			    "Cannot reload configuration (file '%s')",
			    nuauthconf->configfile);
		return -1;
	}

	init_nuauthconf(&newconf);
	g_message("nuauth module reloading");

	/* block threads of pool at start */
	block_thread_pools();
	/* we have to wait that all threads are blocked */
	wait_all_thread_pools();
	/* unload modules */
	unload_modules();

	/* Only duplicate configfile info, if configfile has not been set */
	if (! newconf->configfile) {
		newconf->configfile = g_strdup(nuauthconf->configfile);
	}

	/* switch conf before loading modules */
	restart = compare_nuauthparams(nuauthconf, newconf);

	if (restart == FALSE) {
		apply_new_config(newconf);
		/* debug is set via command line thus duplicate */
		newconf->debug_level = nuauthconf->debug_level;
		free_nuauth_params(nuauthconf);
		g_free(nuauthconf);
		nuauthconf = newconf;
	} else {
		free_nuauth_params(newconf);
	}

	/* reload modules with new conf */
	load_modules();
	/* init period */
	nuauthconf->periods = init_periods(nuauthconf);
	/* ask cache to reset */
	if (nuauthconf->acl_cache) {
		cache_reset(nuauthdatas->acl_cache);
	}

	release_thread_pools();
	nuauth_install_signals(TRUE);

	force_refresh_crl_file();

	g_message("[+] NuAuth server reloaded");
	return restart;
}
Пример #11
0
void	zbx_on_exit()
{
	zabbix_log(LOG_LEVEL_DEBUG, "zbx_on_exit() called");

	if (SUCCEED == DBtxn_ongoing())
		DBrollback();

	if (NULL != threads)
	{
		int		i;
		sigset_t	set;

		/* ignore SIGCHLD signals in order for zbx_sleep() to work */
		sigemptyset(&set);
		sigaddset(&set, SIGCHLD);
		sigprocmask(SIG_BLOCK, &set, NULL);

		for (i = 0; i < threads_num; i++)
		{
			if (threads[i])
			{
				kill(threads[i], SIGTERM);
				threads[i] = ZBX_THREAD_HANDLE_NULL;
			}
		}

		zbx_free(threads);
	}

	free_metrics();

	zbx_sleep(2);	/* wait for all child processes to exit */

	DBconnect(ZBX_DB_CONNECT_EXIT);

	free_database_cache();

	DBclose();

	free_configuration_cache();

	/* free history value cache */
	zbx_vc_destroy();

	zbx_destroy_itservices_lock();

	zbx_mutex_destroy(&node_sync_access);

#ifdef HAVE_OPENIPMI
	free_ipmi_handler();
#endif

#ifdef HAVE_SQLITE3
	zbx_remove_sqlite3_mutex();
#endif

	/* free vmware support */
	if (0 != CONFIG_VMWARE_FORKS)
		zbx_vmware_destroy();

	free_selfmon_collector();

	unload_modules();

	zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Server stopped. Zabbix %s (revision %s).",
			ZABBIX_VERSION, ZABBIX_REVISION);

	zabbix_close_log();

#if defined(PS_OVERWRITE_ARGV)
	setproctitle_free_env();
#endif

	exit(SUCCEED);
}