tbrehm
2008-12-11 9eff6c2532469bacabc935e14e264b284454833c
Fixed several bugs in data replication.
8 files modified
86 ■■■■■ changed files
install/sql/ispconfig3.sql 3 ●●●● patch | view | raw | blame | history
install/update.php 2 ●●●●● patch | view | raw | blame | history
interface/lib/app.inc.php 8 ●●●●● patch | view | raw | blame | history
server/lib/app.inc.php 22 ●●●● patch | view | raw | blame | history
server/lib/classes/modules.inc.php 32 ●●●●● patch | view | raw | blame | history
server/lib/classes/plugins.inc.php 9 ●●●●● patch | view | raw | blame | history
server/lib/classes/services.inc.php 3 ●●●● patch | view | raw | blame | history
server/server.php 7 ●●●● patch | view | raw | blame | history
install/sql/ispconfig3.sql
@@ -598,7 +598,7 @@
  `db_server` tinyint(4) NOT NULL default '0',
  `vserver_server` tinyint(4) NOT NULL default '0',
  `config` text NOT NULL,
  `updated` tinyint(4) NOT NULL default '0',
  `updated` bigint(20) unsigned NOT NULL default '0',
  `active` tinyint(4) NOT NULL default '1',
  PRIMARY KEY  (`server_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 ;
@@ -1004,6 +1004,7 @@
CREATE TABLE `sys_log` (
  `syslog_id` int(10) unsigned NOT NULL auto_increment,
  `server_id` int(10) unsigned NOT NULL default '0',
  `datalog_id` bigint(20) unsigned NOT NULL default '0',
  `loglevel` tinyint(4) NOT NULL default '0',
  `tstamp` int(10) unsigned NOT NULL,
  `message` text,
install/update.php
@@ -134,6 +134,7 @@
//* Update $conf array with values from the server.ini that shall be preserved
$tmp = $inst->db->queryOneRecord("SELECT * FROM ".$conf["mysql"]["database"].".server WHERE server_id = ".$conf['server_id']);
$ini_array = ini_to_array(stripslashes($tmp['config']));
$conf['services']['mail'] = ($tmp['mail_server'] == 1)?true:false;
$conf['services']['web'] = ($tmp['web_server'] == 1)?true:false;
@@ -141,6 +142,7 @@
$conf['services']['file'] = ($tmp['file_server'] == 1)?true:false;
$conf['services']['db'] = ($tmp['db_server'] == 1)?true:false;
$conf['services']['vserver'] = ($tmp['vserver_server'] == 1)?true:false;
$conf['postfix']['vmail_mailbox_base'] = $ini_array['mail']['homedir_path'];
//** Delete the old database
if( !$inst->db->query('DROP DATABASE IF EXISTS '.$conf['mysql']['database']) ) {
interface/lib/app.inc.php
@@ -145,9 +145,11 @@
            //* loading global and module Wordbook
            // TODO: this need to be made clearer somehow - pedro
            @include_once(ISPC_ROOT_PATH.'/lib/lang/'.$_SESSION['s']['language'].'.lng');
            $lng_file = ISPC_ROOT_PATH.'/web/'.$_SESSION['s']['module']['name'].'/lib/lang/'.$_SESSION['s']['language'].'.lng';
            if(!file_exists($lng_file)) $lng_file = ISPC_ROOT_PATH.'/web/'.$_SESSION['s']['module']['name'].'/lib/lang/en.lng';
            include_once($lng_file);
            if(isset($_SESSION['s']['module']['name']) && isset($_SESSION['s']['language'])) {
                $lng_file = ISPC_ROOT_PATH.'/web/'.$_SESSION['s']['module']['name'].'/lib/lang/'.$_SESSION['s']['language'].'.lng';
                if(!file_exists($lng_file)) $lng_file = ISPC_ROOT_PATH.'/web/'.$_SESSION['s']['module']['name'].'/lib/lang/en.lng';
                @include_once($lng_file);
            }
            $this->_wb = $wb;
            $this->_language_inc = 1;
        }        
server/lib/app.inc.php
@@ -125,15 +125,27 @@
                            }
                            echo date("d.m.Y-H:i")." - ".$priority_txt." - ". $msg."\n";
                            fclose($fp);
                            // Log to database
                            if(isset($this->db)) {
                            if(isset($this->dbmaster)) {
                                $server_id = $conf['server_id'];
                                $loglevel = $priority;
                                $tstamp = time();
                                $message = $this->db->quote($msg);
                                $sql = "INSERT INTO sys_log (server_id,loglevel,tstamp,message) VALUES ('$server_id','$loglevel','$tstamp','$message')";
                                $this->db->query($sql);
                                $message = $this->dbmaster->quote($msg);
                                $datalog_id = (isset($this->modules->current_datalog_id) && $this->modules->current_datalog_id > 0)?$this->modules->current_datalog_id:0;
                                if($datalog_id > 0) {
                                    $tmp_rec = $this->dbmaster->queryOneRecord("SELECT count(syslog_id) as number FROM sys_log WHERE datalog_id = $datalog_id AND loglevel = ".LOGLEVEL_ERROR);
                                    //* Do not insert duplicate errors into the web log.
                                    if($tmp_rec['number'] == 0) {
                                        $sql = "INSERT INTO sys_log (server_id,datalog_id,loglevel,tstamp,message) VALUES ('$server_id',$datalog_id,'$loglevel','$tstamp','$message')";
                                        $this->dbmaster->query($sql);
                                    }
                                } else {
                                    $sql = "INSERT INTO sys_log (server_id,datalog_id,loglevel,tstamp,message) VALUES ('$server_id',0,'$loglevel','$tstamp','$message')";
                                    $this->dbmaster->query($sql);
                                }
                            }
                        //} else {
server/lib/classes/modules.inc.php
@@ -31,6 +31,8 @@
class modules {
    
    var $notification_hooks = array();
    var $current_datalog_id = 0;
    var $debug = false;
    
    /*
     This function is called to load the modules from the mods-enabled or the mods-core folder
@@ -48,7 +50,7 @@
                    if($file != '.' && $file != '..' && substr($file,-8,8) == '.inc.php') {
                        $module_name = substr($file,0,-8);
                        include_once($modules_dir.$file);
                        $app->log("Loading Module: $module_name",LOGLEVEL_DEBUG);
                        if($this->debug) $app->log("Loading Module: $module_name",LOGLEVEL_DEBUG);
                        $app->loaded_modules[$module_name] = new $module_name;
                        $app->loaded_modules[$module_name]->onLoad();
                    }
@@ -68,7 +70,7 @@
    function registerTableHook($table_name,$module_name,$function_name) {
        global $app;
        $this->notification_hooks[$table_name][] = array('module' => $module_name, 'function' => $function_name);
        $app->log("Registered TableHook '$table_name' in module '$module_name' for processing function '$function_name'",LOGLEVEL_DEBUG);
        if($this->debug) $app->log("Registered TableHook '$table_name' in module '$module_name' for processing function '$function_name'",LOGLEVEL_DEBUG);
    }
    
    /*
@@ -83,12 +85,14 @@
        // TODO: process only new entries.
        //* If its a multiserver setup
        if($app->db->dbHost != $app->dbmaster->dbHost) {
            $sql = "SELECT * FROM sys_datalog WHERE server_id = ".$conf["server_id"]." ORDER BY datalog_id";
            $sql = "SELECT * FROM sys_datalog WHERE datalog_id > ".$conf['last_datalog_id']." AND (server_id = ".$conf["server_id"]." OR server_id = 0) ORDER BY datalog_id";
            $records = $app->dbmaster->queryAllRecords($sql);
            foreach($records as $d) {
                
                $data = unserialize(stripslashes($d["data"]));
                $replication_error = false;
                $this->current_datalog_id = $d["datalog_id"];
                
                if($d["action"] == 'i') {
                    $idx = explode(":",$d["dbidx"]);
@@ -144,25 +148,25 @@
                    $this->raiseTableHook($d["dbtable"],$d["action"],$data);
                    //$app->dbmaster->query("DELETE FROM sys_datalog WHERE datalog_id = ".$d["datalog_id"]);
                    //$app->log("Deleting sys_datalog ID ".$d["datalog_id"],LOGLEVEL_DEBUG);
                    $app->db->query("UPDATE sys_datalog SET status = 'ok' WHERE datalog_id = ".$d["datalog_id"]);
                    $app->log("Changing datalog status to -ok- for sys_datalog ID ".$rec["datalog_id"],LOGLEVEL_DEBUG);
                    $app->dbmaster->query("UPDATE server SET updated = ".$d["datalog_id"]." WHERE server_id = ".$conf["server_id"]);
                    $app->log("Processed datalog_id ".$d["datalog_id"],LOGLEVEL_DEBUG);
                } else {
                    $app->log("Error in Repliction, changes were not processed.",LOGLEVEL_ERROR);
                    $app->db->query("UPDATE sys_datalog SET status = 'error' WHERE datalog_id = ".$d["datalog_id"]);
                }
            }
            
        //* if we have a single server setup
        } else {
            $sql = "SELECT * FROM sys_datalog WHERE server_id = ".$conf["server_id"]." ORDER BY datalog_id";
            $sql = "SELECT * FROM sys_datalog WHERE datalog_id > ".$conf['last_datalog_id']." AND (server_id = ".$conf["server_id"]." OR server_id = 0) ORDER BY datalog_id";
            $records = $app->db->queryAllRecords($sql);
            foreach($records as $rec) {
                $data = unserialize(stripslashes($rec["data"]));
                $this->raiseTableHook($rec["dbtable"],$rec["action"],$data);
            foreach($records as $d) {
                $data = unserialize(stripslashes($d["data"]));
                $this->current_datalog_id = $d["datalog_id"];
                $this->raiseTableHook($d["dbtable"],$d["action"],$data);
                //$app->db->query("DELETE FROM sys_datalog WHERE datalog_id = ".$rec["datalog_id"]);
                //$app->log("Deleting sys_datalog ID ".$rec["datalog_id"],LOGLEVEL_DEBUG);
                $app->db->query("UPDATE sys_datalog SET status = 'ok' WHERE datalog_id = ".$rec["datalog_id"]);
                $app->log("Changing datalog status to -ok- for sys_datalog ID ".$rec["datalog_id"],LOGLEVEL_DEBUG);
                $app->db->query("UPDATE server SET updated = ".$d["datalog_id"]." WHERE server_id = ".$conf["server_id"]);
                $app->log("Processed datalog_id ".$d["datalog_id"],LOGLEVEL_DEBUG);
            }
        }
        
@@ -177,14 +181,14 @@
        
        // Get the hooks for this table
        $hooks = $this->notification_hooks[$table_name];
        $app->log("Raised TableHook for table: '$table_name'",LOGLEVEL_DEBUG);
        if($this->debug) $app->log("Raised TableHook for table: '$table_name'",LOGLEVEL_DEBUG);
        
        if(is_array($hooks)) {
            foreach($hooks as $hook) {
                $module_name = $hook["module"];
                $function_name = $hook["function"];
                // Claa the processing function of the module
                $app->log("Call function '$function_name' in module '$module_name' raised by TableHook '$table_name'.",LOGLEVEL_DEBUG);
                if($this->debug) $app->log("Call function '$function_name' in module '$module_name' raised by TableHook '$table_name'.",LOGLEVEL_DEBUG);
                call_user_method($function_name,$app->loaded_modules[$module_name],$table_name,$action,$data);
                unset($module_name);
                unset($function_name);
server/lib/classes/plugins.inc.php
@@ -32,6 +32,7 @@
    
    var $available_events = array();
    var $subscribed_events = array();
    var $debug = false;
    
    /*
     This function is called to load the plugins from the plugins-enabled or the plugins-core folder
@@ -61,7 +62,7 @@
                //** load the plugins
                foreach($tmp_plugins as $plugin_name => $file) {
                    include_once($plugins_dir.$file);
                    $app->log("Loading Plugin: $plugin_name",LOGLEVEL_DEBUG);
                    if($this->debug) $app->log("Loading Plugin: $plugin_name",LOGLEVEL_DEBUG);
                    $app->loaded_plugins[$plugin_name] = new $plugin_name;
                    $app->loaded_plugins[$plugin_name]->onLoad();
                }
@@ -82,7 +83,7 @@
        global $app;
        foreach($events as $event_name) {
            $this->available_events[$event_name] = $module_name;
            $app->log("Announced event: $event_name",LOGLEVEL_DEBUG);
            if($this->debug) $app->log("Announced event: $event_name",LOGLEVEL_DEBUG);
        }
    }
    
@@ -97,7 +98,7 @@
            $app->log("Unable to register the function '$function_name' in the plugin '$plugin_name' for event '$event_name'",LOGLEVEL_DEBUG);
        } else {
            $this->subscribed_events[$event_name][] = array('plugin' => $plugin_name, 'function' => $function_name);
            $app->log("Registered the function '$function_name' in the plugin '$plugin_name' for event '$event_name'.",LOGLEVEL_DEBUG);
            if($this->debug)  $app->log("Registered the function '$function_name' in the plugin '$plugin_name' for event '$event_name'.",LOGLEVEL_DEBUG);
        }
    }
    
@@ -107,7 +108,7 @@
        
        // Get the subscriptions for this event
        $events = $this->subscribed_events[$event_name];
        $app->log("Raised event: '$event_name'",LOGLEVEL_DEBUG);
        if($this->debug) $app->log("Raised event: '$event_name'",LOGLEVEL_DEBUG);
        
        if(is_array($events)) {
            foreach($events as $event) {
server/lib/classes/services.inc.php
@@ -32,6 +32,7 @@
    var $registered_services = array();
    var $delayed_restarts = array();
    var $debug = false;
    
    // This function adds a request for restarting 
    // a service at the end of the configuration run.
@@ -64,7 +65,7 @@
    function registerService($service_name,$module_name, $function_name) {
        global $app;
        $this->registered_services[$service_name] = array('module' => $module_name, 'function' => $function_name);
        $app->log("Registered Service '$service_name' in module '$module_name' for processing function '$function_name'",LOGLEVEL_DEBUG);
        if($this->debug) $app->log("Registered Service '$service_name' in module '$module_name' for processing function '$function_name'",LOGLEVEL_DEBUG);
    }
    
    // This function is called at the end of the server script to restart services.
server/server.php
@@ -66,8 +66,13 @@
$app->log("Set Lock: ".$conf["temppath"].$conf["fs_div"].".ispconfig_lock", LOGLEVEL_DEBUG);
*/
// get the dalaog_id of the last performed record
$tmp_rec = $app->dbmaster->queryOneRecord("SELECT updated FROM server WHERE server_id = ".$conf["server_id"]);
$conf['last_datalog_id'] = (int)$tmp_rec['updated'];
unset($tmp_rec);
// Check if there is anything to update
$tmp_rec = $app->dbmaster->queryOneRecord("SELECT count(server_id) as number from sys_datalog WHERE server_id = ".$conf["server_id"]." AND status = 'pending'");
$tmp_rec = $app->dbmaster->queryOneRecord("SELECT count(server_id) as number from sys_datalog WHERE datalog_id > ".$conf['last_datalog_id']." AND (server_id = ".$conf["server_id"]." OR server_id = 0)");
$tmp_num_records = $tmp_rec["number"];
unset($tmp_rec);