function SwapWatchdog()
{
    $sock = new sockets();
    $unix = new unix();
    $MonitConfig = unserialize(base64_decode($sock->GET_INFO("SquidWatchdogMonitConfig")));
    $MonitConfig = watchdog_config_default($MonitConfig);
    $ps = $unix->find_program("ps");
    if ($GLOBALS["VERBOSE"]) {
        echo "\n******** SWAP *******\n";
    }
    if ($MonitConfig["SWAP_MONITOR"] == 0) {
        return;
    }
    include_once dirname(__FILE__) . "/ressources/class.main_cf.inc";
    $sys = new systeminfos();
    $pourc = round($sys->swap_used / $sys->swap_total * 100);
    $freeMemory = $unix->TOTAL_MEMORY_MB_FREE();
    $SwapMemoryused = $sys->swap_used;
    ToSyslog("SwapWatchdog(): {$sys->swap_used}MB used Current {$pourc}% Free Memory: {$freeMemory}MB, min:{$MonitConfig["SWAP_MIN"]}% MAX:{$MonitConfig["SWAP_MAX"]}%");
    if ($pourc < $MonitConfig["SWAP_MIN"]) {
        return;
    }
    if (!isset($MonitConfig["SWAP_MIN"])) {
        $MonitConfig["SWAP_MIN"] = 5;
    }
    if (!isset($MonitConfig["SWAP_MAX"])) {
        $MonitConfig["SWAP_MAX"] = 55;
    }
    $ps_text[] = "There is not enough memory to clean the swap";
    $ps_text[] = "Current configuration was: Free Swap memory over than {$MonitConfig["SWAP_MAX"]}%";
    $ps_text[] = "Your current Swap file using: {$SwapMemoryused}M - {$pourc}% - {$sys->swap_used}/{$sys->swap_total}";
    $ps_text[] = "Memory free on your system:{$freeMemory}M";
    $ps_text[] = "You will find here a snapshot of current tasks";
    $ps_text[] = ps_mem_report();
    $ps_mail = @implode("\n", $ps_text);
    if ($pourc > $MonitConfig["SWAP_MAX"]) {
        if ($SwapMemoryused < $freeMemory) {
            squid_admin_mysql(0, "[ALERT] REBOOT server!!! Swap exceed rule {$pourc}% max: {$MonitConfig["SWAP_MAX"]}%", $ps_mail, __FILE__, __LINE__);
            FailOverDown("Swap exceed rule - reboot - {$pourc}% max:{$MonitConfig["SWAP_MAX"]}%\n{$ps_mail}");
            shell_exec($unix->find_program("shutdown") . " -rF now");
            die;
        }
        squid_admin_mysql(1, "Cleaning SWAP current: {$pourc}% max:{$MonitConfig["SWAP_MAX"]}%", "clean the swap ({$SwapMemoryused}M/{$freeMemory}M)\n{$ps_mail}", __FILE__, __LINE__);
        SwapWatchdog_FreeSync();
        die;
    }
    squid_admin_mysql(1, "Cleaning SWAP current:{$pourc}% min:{$MonitConfig["SWAP_MIN"]}%", "clean the swap ({$SwapMemoryused}M/{$freeMemory}M)\n{$ps_mail}", __FILE__, __LINE__);
    SwapWatchdog_FreeSync();
}
function FreeMem($aspid = false, $SwapOffOn = array())
{
    $unix = new unix();
    if (!$aspid) {
        $pidfile = "/etc/artica-postfix/pids/" . basename(__FILE__) . "." . __FUNCTION__ . ".pid";
        $pid = @file_get_contents($pidfile);
        if ($unix->process_exists($pid, basename(__FILE__))) {
            if ($GLOBALS["VERBOSE"]) {
                echo "Already executed pid {$pid}\n";
            }
            return;
        }
    }
    if (count($SwapOffOn) == 0) {
        $sock = new sockets();
        $SwapOffOn = unserialize(base64_decode($sock->GET_INFO("SwapOffOn")));
        if (!is_numeric($SwapOffOn["AutoMemWatchdog"])) {
            $SwapOffOn["AutoMemWatchdog"] = 1;
        }
        if (!is_numeric($SwapOffOn["AutoMemPerc"])) {
            $SwapOffOn["AutoMemPerc"] = 90;
        }
        if (!is_numeric($SwapOffOn["AutoMemInterval"])) {
            $SwapOffOn["AutoMemInterval"] = 180;
        }
    }
    $text[] = "Configuration was:";
    $text[] = "--------------------------------------";
    $text[] = "Free memory when Swap exceed {$SwapOffOn["AutoMemPerc"]}%";
    $text[] = "Watchdog scanning interval: each {$SwapOffOn["AutoMemInterval"]}mn";
    if (isset($SwapOffOn["CURRENT"])) {
        $text[] = $SwapOffOn["CURRENT"];
    }
    $text[] = ps_mem_report();
    $TOTAL_MEMORY_MB_FREE = $unix->TOTAL_MEMORY_MB_FREE();
    $text[] = "{$TOTAL_MEMORY_MB_FREE}MB before operation";
    $sync = $unix->find_program("sync");
    $sysctl = $unix->find_program("sysctl");
    $squid = $unix->LOCATE_SQUID_BIN();
    shell_exec($sync);
    shell_exec("{$sysctl} -w vm.drop_caches=3");
    shell_exec($sync);
    shell_exec("/etc/init.d/apache2 restart");
    if (is_file("/etc/init.d/ssh")) {
        shell_exec("/etc/init.d/ssh restart");
    }
    if ($unix->is_socket("/var/run/mysqld/mysqld.sock")) {
        $q = new mysql();
        $q->EXECUTE_SQL("RESET QUERY CACHE;");
    }
    if ($unix->is_socket("/var/run/mysqld/squid-db.sock")) {
        $q = new mysql_squid_builder();
        $q->EXECUTE_SQL("RESET QUERY CACHE;");
    }
    $TOTAL_MEMORY_MB_FREE2 = $unix->TOTAL_MEMORY_MB_FREE();
    $text[] = "{$TOTAL_MEMORY_MB_FREE2}MB After operation";
    $TOTAL_MEMORY_MB = $TOTAL_MEMORY_MB_FREE2 - $TOTAL_MEMORY_MB_FREE;
    $text[] = "{$TOTAL_MEMORY_MB}MB restored";
    $FINAL_TEXT = @implode("\n", $text);
    system_admin_events("Free memory operation has been executed - {$TOTAL_MEMORY_MB}MB restored\n{$FINAL_TEXT}", __FUNCTION__, __FILE__, __LINE__);
    if (is_file($squid)) {
        squid_admin_mysql(1, "Swap exceed rule: Free memory operation has been executed - {$TOTAL_MEMORY_MB}MB restored", $FINAL_TEXT, __FILE__, __LINE__);
    }
}
Exemple #3
0
function SwapWatchdog()
{
    $reboot = false;
    $DisableSWAPP = $GLOBALS["CLASS_SOCKETS"]->GET_INFO("DisableSWAPP");
    if (!is_numeric($DisableSWAPP)) {
        $DisableSWAPP = 0;
    }
    if ($DisableSWAPP == 1) {
        return;
    }
    @mkdir("/etc/artica-postfix/cron.1", 0755, true);
    $filecache = "/etc/artica-postfix/cron.1/SwapOffOn.time";
    $filecache20 = "/etc/artica-postfix/cron.1/SwapOffOn20.time";
    $filecache50 = "/etc/artica-postfix/cron.1/SwapOffOn50.time";
    $filecache100 = "/etc/artica-postfix/cron.1/SwapOffOn50.time";
    $ps = $GLOBALS["CLASS_UNIX"]->find_program("ps");
    $SwapOffOn = unserialize(base64_decode($GLOBALS["CLASS_SOCKETS"]->GET_INFO("SwapOffOn")));
    if (!is_numeric($SwapOffOn["SwapEnabled"])) {
        $SwapOffOn["SwapEnabled"] = 1;
    }
    if (!is_numeric($SwapOffOn["SwapMaxPourc"])) {
        $SwapOffOn["SwapMaxPourc"] = 20;
    }
    if (!is_numeric($SwapOffOn["SwapMaxMB"])) {
        $SwapOffOn["SwapMaxMB"] = 0;
    }
    if (!is_numeric($SwapOffOn["SwapTimeOut"])) {
        $SwapOffOn["SwapTimeOut"] = 60;
    }
    include_once dirname(__FILE__) . "/ressources/class.main_cf.inc";
    $sys = new systeminfos();
    if ($sys->swap_used == 0) {
        return;
    }
    if ($sys->swap_total == 0) {
        return;
    }
    if ($sys->swap_used == $sys->swap_total) {
        return;
    }
    events("{$sys->swap_used}/{$sys->swap_total} ", __FUNCTION__, __LINE__);
    $pourc = round($sys->swap_used / $sys->swap_total * 100);
    $notif = $notif . "{$sys->swap_used}/{$sys->swap_total}\n";
    events("{$sys->swap_used}MB used ({$pourc}%)", __FUNCTION__, __LINE__);
    if ($pourc > 20) {
        if ($pourc < 50) {
            $filetime = $GLOBALS["CLASS_UNIX"]->file_time_min($filecache20);
            if ($filetime > 30) {
                @unlink($filecache20);
                @file_put_contents($filecache20, time());
                squid_admin_mysql(1, "[INFO]: System swap exceed {$pourc}%", "You will find here a snapshot of current tasks\n" . ps_mem_report());
            }
        }
    }
    if ($pourc > 50) {
        if ($pourc < 70) {
            $filetime = $GLOBALS["CLASS_UNIX"]->file_time_min($filecache50);
            if ($filetime > 15) {
                @unlink($filecache50);
                @file_put_contents($filecache50, time());
                squid_admin_mysql(1, "[WARNING]: System swap exceed {$pourc}%", "You will find here a snapshot of current tasks\n" . ps_mem_report());
            }
        }
    }
    if ($pourc > 70) {
        $filetime = $GLOBALS["CLASS_UNIX"]->file_time_min($filecache100);
        if ($filetime > 10) {
            @unlink($filecache100);
            @file_put_contents($filecache100, time());
            squid_admin_mysql(0, "[ALERT!!]: System swap exceed {$pourc}%", "You will find here a snapshot of current tasks\n" . ps_mem_report());
        }
    }
    if ($SwapOffOn["SwapEnabled"] == 0) {
        return;
    }
    $filetime = $GLOBALS["CLASS_UNIX"]->file_time_min($filecache);
    if ($filetime < $SwapOffOn["SwapTimeOut"]) {
        events("{$filetime}Mn need to wait {$SwapOffOn["SwapTimeOut"]}mn", __FUNCTION__, __LINE__);
        return;
    }
    if ($SwapOffOn["SwapMaxMB"] > 0) {
        if ($sys->swap_used > $SwapOffOn["SwapMaxMB"]) {
            $execeed_text = $SwapOffOn["SwapMaxMB"] . "MB";
            $reboot = true;
        }
    }
    if ($SwapOffOn["SwapMaxMB"] == 0) {
        if ($pourc > 3) {
            if ($pourc > $SwapOffOn["SwapMaxPourc"]) {
                $execeed_text = $SwapOffOn["SwapMaxPourc"] . "%";
                $reboot = true;
            }
        }
    }
    @unlink($filecache);
    @file_put_contents($filecache, time());
    if (!$reboot) {
        return;
    }
    $swapoff = $GLOBALS["CLASS_UNIX"]->find_program("swapoff");
    $swapon = $GLOBALS["CLASS_UNIX"]->find_program("swapon");
    if (!is_file($swapoff)) {
        events("swapoff no such file", __FUNCTION__, __LINE__);
        shell_exec2("sync; echo \"3\" > /proc/sys/vm/drop_caches >/dev/null 2>&1");
        return;
    }
    if (!is_file($swapon)) {
        events("swapon no such file", __FUNCTION__, __LINE__);
        shell_exec2("sync; echo \"3\" > /proc/sys/vm/drop_caches >/dev/null 2>&1");
        return;
    }
    $time = time();
    if (function_exists("WriteToSyslogMail")) {
        WriteToSyslogMail("SwapWatchdog:: Starting to purge the swap file because it execeed rules", basename(__FILE__));
    }
    $cmd = "{$swapoff} -a 2>&1";
    $results = array();
    $results[] = $cmd;
    events("running {$cmd}", __FUNCTION__, __LINE__);
    exec($cmd, $results);
    $cmd = "{$swapon} -a 2>&1";
    $results[] = $cmd;
    events("running {$cmd}", __FUNCTION__, __LINE__);
    exec($cmd, $results);
    $text = @implode("\n", $results);
    $time_duration = distanceOfTimeInWords($time, time());
    shell_exec2("sync; echo \"3\" > /proc/sys/vm/drop_caches >/dev/null 2>&1");
    events("results: {$time_duration}\n {$text}", __FUNCTION__, __LINE__);
    $notif = $notif . "\nMemory swap purge {$execeed_text} ({$time_duration})\n{$text}";
    squid_admin_mysql(1, "Memory swap purge {$execeed_text}", "(Execution time: {$time_duration})", __FILE__, __LINE__);
    $GLOBALS["CLASS_UNIX"]->send_email_events("Memory swap purge {$execeed_text} (task time execuction: {$time_duration})", $text, "system");
    $sqdbin = $GLOBALS["CLASS_UNIX"]->find_program("squid");
    if (!is_file($sqdbin)) {
        $sqdbin = $GLOBALS["CLASS_UNIX"]->find_program("squid3");
    }
    if (is_file($sqdbin)) {
        $php5 = $GLOBALS["CLASS_UNIX"]->LOCATE_PHP5_BIN();
        $nohup = $GLOBALS["CLASS_UNIX"]->find_program("nohup");
        if (function_exists("debug_backtrace")) {
            $trace = debug_backtrace();
            if (isset($trace[1])) {
                $sourcefunction = $trace[1]["function"];
                $sourceline = $trace[1]["line"];
                $executed = "Executed by {$sourcefunction}() line {$sourceline}\nusing argv:{$GLOBALS["ARGVS"]}\n";
            }
        }
        squid_admin_mysql(1, "Asking to reload proxy service after purging the Swap file", "{$executed}\n{$notif}", __FILE__, __LINE__);
        if (function_exists("WriteToSyslogMail")) {
            WriteToSyslogMail("SwapWatchdog:: reloading Squid after purging the Swap file", basename(__FILE__));
        }
        shell_exec2("{$nohup} {$php5} /usr/share/artica-postfix/exec.squid.php --reload-squid --bywatchdog >/dev/null 2>&1 &");
    }
}