From 41e7689c774bc165840c6973ef5f3df904dc49ec Mon Sep 17 00:00:00 2001 From: Neil Lathwood Date: Wed, 3 May 2017 14:48:23 +0100 Subject: [PATCH] refactor: DB Updates will now file level lock to stop duplicate updates (#6469) * refactor: DB Updates will now file level lock to stop duplicate updates * scrut fixes * renamed function from clear_lock() to release_lock() --- alerts.php | 18 ++----------- discovery.php | 4 ++- doc/General/Updating.md | 26 +++++++++++++++---- html/index.php | 2 +- html/install.php | 2 +- includes/functions.php | 47 ++++++++++++++++++++++++++++++++++ includes/sql-schema/update.php | 7 +++++ sql-schema/107.sql | 1 - sql-schema/118.sql | 1 - sql-schema/171.sql | 1 - 10 files changed, 82 insertions(+), 27 deletions(-) diff --git a/alerts.php b/alerts.php index 36eaf924db..97da4d6e50 100755 --- a/alerts.php +++ b/alerts.php @@ -30,21 +30,7 @@ require __DIR__ . '/includes/init.php'; $options = getopt('d::'); -$lock = false; -if (file_exists($config['install_dir'].'/.alerts.lock')) { - $pids = explode("\n", trim(`ps -e | grep php | awk '{print $1}'`)); - $lpid = trim(file_get_contents($config['install_dir'].'/.alerts.lock')); - if (in_array($lpid, $pids)) { - $lock = true; - } -} - -if ($lock === true) { - exit(1); -} else { - file_put_contents($config['install_dir'].'/.alerts.lock', getmypid()); -} - +set_lock('alerts'); if (isset($options['d'])) { echo "DEBUG!\n"; @@ -74,7 +60,7 @@ if (!defined('TEST') && $config['alert']['disable'] != 'true') { echo 'End : '.date('r')."\r\n"; } -unlink($config['install_dir'].'/.alerts.lock'); +release_lock('alerts'); function ClearStaleAlerts() { diff --git a/discovery.php b/discovery.php index 7fa28c24de..79e56881fc 100755 --- a/discovery.php +++ b/discovery.php @@ -113,7 +113,9 @@ if (!$where) { exit; } -require 'includes/sql-schema/update.php'; +if (get_lock('schema') === false) { + require 'includes/sql-schema/update.php'; +} $discovered_devices = 0; diff --git a/doc/General/Updating.md b/doc/General/Updating.md index fcffdc9b5a..40f80c6f15 100644 --- a/doc/General/Updating.md +++ b/doc/General/Updating.md @@ -9,16 +9,32 @@ then you can do this by running the following command as the **librenms** user: This will update both the core LibreNMS files but also update the database structure if updates are available. +#### Advanced users +If you absolutely must update manually then you can do so by running the following commands: +```bash +cd /opt/librenms +git pull +php includes/sql-schema/update.php +``` + ## Configuring the update channel ## LibreNMS follows the master branch on github for daily updates. -You can change to the monthly releases by setting: + +#### Stable branch +You can change to the stable monthly branch by setting: `$config['update_channel'] = 'release';` +> Choose this branch if you want to have a stable release + +#### Development branch +You can change to the development branch by setting: + +`$config['update_channel'] = 'master';` + +> Choose this branch if you want the latest features at the cost that sometimes bugs are inadvertently introduced. + ## Disabling automatic updates ## -LibreNMS by default performs updates on a daily basis. This can be disabled -by ensuring: +LibreNMS by default performs updates on a daily basis. This can be disabled by setting: `$config['update'] = 0;` - -is no longer commented out. diff --git a/html/index.php b/html/index.php index 83a087645b..9ef45376ab 100644 --- a/html/index.php +++ b/html/index.php @@ -57,7 +57,7 @@ $msg_box = array(); // Check for install.inc.php if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') { // no config.php does so let's redirect to the install - header('Location: install.php'); + header("Location: {$config['base_url']}/install.php"); exit; } diff --git a/html/install.php b/html/install.php index b5f6dfe055..448a59398d 100644 --- a/html/install.php +++ b/html/install.php @@ -22,7 +22,7 @@ if ($stage > 3) { require realpath(__DIR__ . '/..') . '/includes/init.php'; // List of php modules we expect to see -$modules = array('gd','mysqli','snmp','mcrypt'); +$modules = array('gd','mysqli','mcrypt'); $dbhost = @$_POST['dbhost'] ?: 'localhost'; $dbuser = @$_POST['dbuser'] ?: 'librenms'; diff --git a/includes/functions.php b/includes/functions.php index e1072e1584..c1c8ebe107 100644 --- a/includes/functions.php +++ b/includes/functions.php @@ -2327,6 +2327,53 @@ function db_schema_is_current() return $current >= $latest; } +/** + * Get the lock status for a given name + * @param $name + * @return bool + */ +function get_lock($name) +{ + global $config; + $lock_file = $config['install_dir']."/.$name.lock"; + if (file_exists($lock_file)) { + $pids = explode("\n", trim(`ps -e | grep php | awk '{print $1}'`)); + $lpid = trim(file_get_contents($lock_file)); + if (in_array($lpid, $pids)) { + return true; + } + } + return false; +} + +/** + * Set the lock status for a given name + * @param $name + */ +function set_lock($name) +{ + global $config; + $lock_file = $config['install_dir']."/.$name.lock"; + $lock = get_lock($name); + + if ($lock === true) { + echo "$lock_file exists, exiting\n"; + exit(1); + } else { + file_put_contents($lock_file, getmypid()); + } +} + +/** + * Release lock file for a given name + * @param $name + */ +function release_lock($name) +{ + global $config; + unlink($config['install_dir']."/.$name.lock"); +} + /** * @param $device * @return int|null diff --git a/includes/sql-schema/update.php b/includes/sql-schema/update.php index 8c7cdc3be1..66a1143299 100644 --- a/includes/sql-schema/update.php +++ b/includes/sql-schema/update.php @@ -15,6 +15,8 @@ * See COPYING for more details. */ +set_lock('schema'); + if (!isset($debug) && php_sapi_name() == 'cli') { // Not called from within discovery, let's load up the necessary stuff. $init_modules = array(); @@ -24,8 +26,11 @@ if (!isset($debug) && php_sapi_name() == 'cli') { $debug = isset($options['d']); } +d_echo("DB Schema update started....\n"); + if (db_schema_is_current()) { d_echo("DB Schema already up to date.\n"); + release_lock('schema'); return; } @@ -91,3 +96,5 @@ if ($updating) { $_SESSION['build-ok'] = true; } } + +release_lock('schema'); diff --git a/sql-schema/107.sql b/sql-schema/107.sql index 0fb3afc881..6eb6c8015e 100644 --- a/sql-schema/107.sql +++ b/sql-schema/107.sql @@ -1,4 +1,3 @@ -UPDATE dbSchema SET version = 107; CREATE TABLE bill_port_counters_tmp(port_id int NOT NULL PRIMARY KEY, `timestamp` timestamp NOT NULL DEFAULT current_timestamp, in_counter bigint, in_delta bigint NOT NULL DEFAULT 0, out_counter bigint, out_delta bigint NOT NULL DEFAULT 0); INSERT INTO bill_port_counters_tmp(port_id, timestamp, in_counter, out_counter) SELECT q.port_id, q.max_timestamp, max(i.counter), max(o.counter) FROM (SELECT port_id, MAX(`timestamp`) AS max_timestamp FROM port_in_measurements GROUP BY port_id) q INNER JOIN port_in_measurements i ON q.port_id = i.port_id AND q.max_timestamp = i.timestamp INNER JOIN port_out_measurements o ON q.port_id = o.port_id AND q.max_timestamp = o.timestamp GROUP BY q.port_id, q.max_timestamp; RENAME TABLE bill_port_counters_tmp TO bill_port_counters; diff --git a/sql-schema/118.sql b/sql-schema/118.sql index eb755d5e74..9c9674eb11 100644 --- a/sql-schema/118.sql +++ b/sql-schema/118.sql @@ -1,4 +1,3 @@ -UPDATE dbSchema SET version = 118; ALTER TABLE `eventlog` ADD `device_id` INT NOT NULL AFTER `host` ; ALTER TABLE `eventlog` ADD INDEX ( `device_id` ) ; UPDATE eventlog SET device_id=host WHERE device_id=0; diff --git a/sql-schema/171.sql b/sql-schema/171.sql index d0d1dc5965..9a71aff72f 100644 --- a/sql-schema/171.sql +++ b/sql-schema/171.sql @@ -1,4 +1,3 @@ -UPDATE `dbSchema` SET `version` = 171; ALTER TABLE `access_points` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; ALTER TABLE `alert_map` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; ALTER TABLE `alert_rules` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;