diff options
47 files changed, 1220 insertions, 670 deletions
diff --git a/ChangeLog b/ChangeLog index 6c5c8a292d1..6e476c375f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,17 @@ +Changes for 3.0.0alpha5 + +New features: + +Bug fixes: +...G...... [ZBX-10045] fixed first proc.cpu.util[] request returning empty value which was treated as network error by server (wiper) +.......PS. [ZBX-1916] improved host availability handling by resetting it for disabled hosts, interfaces without enabled items and hosts monitored by offline proxies (wiper) + +-------------------------------------------------------------------------------- Changes for 3.0.0alpha4 New features: +..F....... [ZBX-9985] fixed template search results (vitalijs) +..F....... [ZBXNEXT-1762] added years, months and half of months periods displaying on graphs X axis (Oleg) A.F....... [ZBXNEXT-1679] implemented value map import/export (Ivo) ..F....... [ZBXNEXT-1679] added checkbox column in value map list view and bulk "Delete" button (Ivo) ..F....... [ZBXNEXT-1679] added "Used in items" column in value map list view and green text "Yes" if value map is used in items or item prototypes (Ivo, Sasha) @@ -17,6 +28,10 @@ A.F....... [ZBXNEXT-1424] implemented value mapping API, added clone button in v ...G...... [ZBXNEXT-2960] reduced the default MaxLinesPerSecond value to 20 (Richlv) Bug fixes: +...G...... [ZBX-2966] fixed handling of possible negative value of vfs.fs.size check (dimir) +..F....... [ZBX-9977] fixed inconsistent display of acknowledge-related elements when acknowledgement is disabled in configuration (Gunars) +..F....... [ZBX-9964] fixed undefined index "inventory_mode" in host prototype edit form (Gunars) +..F....... [ZBXNEXT-1762] fixed time interval calculation and displaying issues in line graphs (Oleg) ..F....... [ZBX-9949] fixed undefined index in proxy edit form (Gunars) ...G...PS. [ZBX-6028] improved log rotation so that zabbix components do not keep writing to the old log file (dimir) .D........ [ZBXNEXT-2637] fixed incorrect double quote character in the default agent configuration files (Richlv) diff --git a/bin/win32/dev/zabbix_sender.dll b/bin/win32/dev/zabbix_sender.dll Binary files differindex bfe94f43c95..398523574ae 100644 --- a/bin/win32/dev/zabbix_sender.dll +++ b/bin/win32/dev/zabbix_sender.dll diff --git a/bin/win32/dev/zabbix_sender.lib b/bin/win32/dev/zabbix_sender.lib Binary files differindex 07c6b386c07..3d6c4a0f737 100644 --- a/bin/win32/dev/zabbix_sender.lib +++ b/bin/win32/dev/zabbix_sender.lib diff --git a/bin/win32/zabbix_agentd.exe b/bin/win32/zabbix_agentd.exe Binary files differindex 9821f3e3c8b..69a92ca6c1c 100755 --- a/bin/win32/zabbix_agentd.exe +++ b/bin/win32/zabbix_agentd.exe diff --git a/bin/win32/zabbix_get.exe b/bin/win32/zabbix_get.exe Binary files differindex e1de4a45506..5356bc711c0 100755 --- a/bin/win32/zabbix_get.exe +++ b/bin/win32/zabbix_get.exe diff --git a/bin/win32/zabbix_sender.exe b/bin/win32/zabbix_sender.exe Binary files differindex 2ca2e144955..2a4fa8a6847 100755 --- a/bin/win32/zabbix_sender.exe +++ b/bin/win32/zabbix_sender.exe diff --git a/bin/win64/dev/zabbix_sender.dll b/bin/win64/dev/zabbix_sender.dll Binary files differindex 6fe2fbb8659..7bca024a9ed 100644 --- a/bin/win64/dev/zabbix_sender.dll +++ b/bin/win64/dev/zabbix_sender.dll diff --git a/bin/win64/dev/zabbix_sender.lib b/bin/win64/dev/zabbix_sender.lib Binary files differindex d35e8bb137b..45483e15a8a 100644 --- a/bin/win64/dev/zabbix_sender.lib +++ b/bin/win64/dev/zabbix_sender.lib diff --git a/bin/win64/zabbix_agentd.exe b/bin/win64/zabbix_agentd.exe Binary files differindex c6997adc3ad..dbcaf883e93 100755 --- a/bin/win64/zabbix_agentd.exe +++ b/bin/win64/zabbix_agentd.exe diff --git a/bin/win64/zabbix_get.exe b/bin/win64/zabbix_get.exe Binary files differindex fef26cff97e..18898606ed0 100755 --- a/bin/win64/zabbix_get.exe +++ b/bin/win64/zabbix_get.exe diff --git a/bin/win64/zabbix_sender.exe b/bin/win64/zabbix_sender.exe Binary files differindex e0939aec226..c521ff3e49f 100755 --- a/bin/win64/zabbix_sender.exe +++ b/bin/win64/zabbix_sender.exe diff --git a/configure.ac b/configure.ac index abb42245047..6d919aca815 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ dnl dnl Process this file with autoconf to produce a configure script. -AC_INIT([Zabbix],[3.0.0alpha4]) +AC_INIT([Zabbix],[3.0.0alpha5]) AC_CONFIG_SRCDIR(src/zabbix_server/server.c) AM_INIT_AUTOMAKE diff --git a/frontends/php/dashconf.php b/frontends/php/dashconf.php index bd0360d0821..8df5e3319c9 100644 --- a/frontends/php/dashconf.php +++ b/frontends/php/dashconf.php @@ -95,7 +95,10 @@ if (hasRequest('update')) { CProfile::update('web.dashconf.triggers.name', getRequest('trigger_name', ''), PROFILE_TYPE_STR); // events - CProfile::update('web.dashconf.events.extAck', getRequest('extAck', 0), PROFILE_TYPE_INT); + $config = select_config(); + if ($config['event_ack_enable']) { + CProfile::update('web.dashconf.events.extAck', getRequest('extAck', 0), PROFILE_TYPE_INT); + } } jSredirect(ZBX_DEFAULT_URL); diff --git a/frontends/php/host_prototypes.php b/frontends/php/host_prototypes.php index bbd4d4435ba..02614fca03c 100644 --- a/frontends/php/host_prototypes.php +++ b/frontends/php/host_prototypes.php @@ -320,6 +320,10 @@ if (isset($_REQUEST['form'])) { if (getRequest('hostid') && !getRequest('form_refresh')) { $data['host_prototype'] = array_merge($data['host_prototype'], $hostPrototype); + if (!array_key_exists('inventory_mode', $data['host_prototype']['inventory'])) { + $data['host_prototype']['inventory']['inventory_mode'] = HOST_INVENTORY_DISABLED; + } + $data['groups'] = API::HostGroup()->get([ 'output' => API_OUTPUT_EXTEND, 'groupids' => zbx_objectValues($data['host_prototype']['groupLinks'], 'groupid'), diff --git a/frontends/php/hosts.php b/frontends/php/hosts.php index 9a4b0d9b289..8602f0149f4 100644 --- a/frontends/php/hosts.php +++ b/frontends/php/hosts.php @@ -909,7 +909,7 @@ elseif (hasRequest('form')) { // Host inventory $data['inventory_mode'] = array_key_exists('inventory_mode', $dbHost['inventory']) ? $dbHost['inventory']['inventory_mode'] - : $config['default_inventory_mode']; + : HOST_INVENTORY_DISABLED; $data['host_inventory'] = $dbHost['inventory']; unset($data['host_inventory']['inventory_mode']); diff --git a/frontends/php/include/classes/graphdraw/CLineGraphDraw.php b/frontends/php/include/classes/graphdraw/CLineGraphDraw.php index 38a2da30753..ef35b7794c4 100644 --- a/frontends/php/include/classes/graphdraw/CLineGraphDraw.php +++ b/frontends/php/include/classes/graphdraw/CLineGraphDraw.php @@ -55,7 +55,7 @@ class CLineGraphDraw extends CGraphDraw { $this->grid = []; // vertical & horizontal grids params $this->gridLinesCount = []; // How many grids to draw $this->gridStep = []; // grid step - $this->gridPixels = 25; // optimal grid size + $this->gridPixels = 30; // optimal grid size $this->gridPixelsVert = 40; } @@ -95,8 +95,7 @@ class CLineGraphDraw extends CGraphDraw { $this->m_showTriggers = ($value == 1) ? 1 : 0; } - public function addItem($itemid, $axis = GRAPH_YAXIS_SIDE_DEFAULT, $calc_fnc = CALC_FNC_AVG, $color = null, - $drawtype = null) { + public function addItem($itemid, $axis = GRAPH_YAXIS_SIDE_DEFAULT, $calc_fnc = CALC_FNC_AVG, $color = null, $drawtype = null, $type = null) { if ($this->type == GRAPH_TYPE_STACKED) { $drawtype = GRAPH_ITEM_DRAWTYPE_FILLED_REGION; } @@ -128,7 +127,7 @@ class CLineGraphDraw extends CGraphDraw { $this->items[$this->num]['drawtype'] = is_null($drawtype) ? GRAPH_ITEM_DRAWTYPE_LINE : $drawtype; $this->items[$this->num]['axisside'] = is_null($axis) ? GRAPH_YAXIS_SIDE_DEFAULT : $axis; $this->items[$this->num]['calc_fnc'] = is_null($calc_fnc) ? CALC_FNC_AVG : $calc_fnc; - $this->items[$this->num]['calc_type'] = GRAPH_ITEM_SIMPLE; + $this->items[$this->num]['calc_type'] = is_null($type) ? GRAPH_ITEM_SIMPLE : $type; if ($this->items[$this->num]['axisside'] == GRAPH_YAXIS_SIDE_LEFT) { $this->yaxisleft = 1; @@ -220,7 +219,7 @@ class CLineGraphDraw extends CGraphDraw { $this->axis_valuetype[$this->items[$i]['axisside']] = ITEM_VALUE_TYPE_FLOAT; } - $calc_type = $this->items[$i]['calc_type']; + $type = $this->items[$i]['calc_type']; $from_time = $this->from_time; $to_time = $this->to_time; $calc_field = 'round('.$x.'*'.zbx_sql_mod(zbx_dbcast_2bigint('clock').'+'.$z, $p).'/('.$p.'),0)'; // required for 'group by' support of Oracle @@ -288,7 +287,12 @@ class CLineGraphDraw extends CGraphDraw { if (!isset($this->data[$this->items[$i]['itemid']])) { $this->data[$this->items[$i]['itemid']] = []; } - $curr_data = &$this->data[$this->items[$i]['itemid']][$calc_type]; + + if (!isset($this->data[$this->items[$i]['itemid']][$type])) { + $this->data[$this->items[$i]['itemid']][$type] = []; + } + + $curr_data = &$this->data[$this->items[$i]['itemid']][$type]; $curr_data['count'] = null; $curr_data['min'] = null; @@ -1056,120 +1060,6 @@ class CLineGraphDraw extends CGraphDraw { } } - private function calcTimeInterval() { - $this->grid['horizontal'] = ['sub' => [], 'main' => []]; - - // align to the closest human time interval - $raw_time_interval = ($this->gridPixels*$this->period)/$this->sizeX; - $intervals = [ - ['main' => 30, 'sub' => 1], // 1 second - ['main' => 60, 'sub' => 5], // 5 seconds - ['main' => 300, 'sub' => 10], // 10 seconds - ['main' => 900, 'sub' => 30], // 30 seconds - ['main' => 3600, 'sub' => 60], // 1 minute - ['main' => 3600, 'sub' => 120], // 2 minutes - ['main' => 3600, 'sub' => 300], // 5 minutes - ['main' => 3600, 'sub' => 900], // 15 minutes - ['main' => 3600, 'sub' => 1800], // 30 minutes - ['main' => 86400, 'sub' => 3600], // 1 hour - ['main' => 86400, 'sub' => 10800], // 3 hours - ['main' => 86400, 'sub' => 21600], // 6 hours - ['main' => 86400, 'sub' => 43200], // 12 hours - ['main' => 604800, 'sub' => 86400], // 1 day - ['main' => 1209600, 'sub' => 604800], // 1 week - ['main' => 2419200, 'sub' => 1209600], // 2 weeks - ['main' => 4838400, 'sub' => 2419200], // 4 weeks - ['main' => 9676800, 'sub' => 4838400], // 8 weeks - ['main' => 19353600, 'sub' => 9676800] // 16 weeks - ]; - - $dist = 19353600; //def week; - $sub_interval = 0; - $main_interval = 0; - - foreach ($intervals as $int) { - $t = abs($int['sub'] - $raw_time_interval); - - if ($t < $dist) { - $dist = $t; - $sub_interval = $int['sub']; - $main_interval = $int['main']; - } - } - - // sub - $intervalX = ($sub_interval * $this->sizeX) / $this->period; - - if ($sub_interval > SEC_PER_DAY) { - $offset = (7 - date('w', $this->from_time)) * SEC_PER_DAY; - $offset += $this->diffTZ; - - $next = $this->from_time + $offset; - - $offset = mktime(0, 0, 0, date('m', $next), date('d', $next), date('Y', $next)) - $this->from_time; - $offsetX = $offset * ($this->sizeX / $this->period); - } - else { - $offset = $sub_interval - (($this->from_time + date('Z', $this->from_time)) % $sub_interval); - $offsetX = ($offset * $this->sizeX) / $this->period; - } - - $vline_count = floor(($this->period-$offset) / $sub_interval); - - $start_i = 0; - if ($offsetX < 12) { - $start_i++; - } - - while (($this->sizeX - ($offsetX + ($vline_count*$intervalX))) < 12) { - $vline_count--; - } - - $sub = &$this->grid['horizontal']['sub']; - $sub['interval'] = $sub_interval; - $sub['linecount'] = $vline_count; - $sub['intervalx'] = $intervalX; - $sub['offset'] = $offset; - $sub['offsetx'] = $offsetX; - $sub['start'] = $start_i; - - // main - $intervalX = ($main_interval * $this->sizeX) / $this->period; - - if ($main_interval > SEC_PER_DAY) { - $offset = (7 - date('w', $this->from_time)) * SEC_PER_DAY; - $offset += $this->diffTZ; - $next = $this->from_time + $offset; - - $offset = mktime(0, 0, 0, date('m', $next), date('d', $next), date('Y', $next)) - $this->from_time; - $offsetX = $offset * ($this->sizeX / $this->period); - } - else { - $offset = $main_interval - (($this->from_time + (date('Z', $this->from_time))) % $main_interval); - $offset += $this->diffTZ; - $offsetX = $offset * ($this->sizeX / $this->period); - } - - $vline_count = floor(($this->period-$offset) / $main_interval); - - $start_i = 0; - if ($offsetX < 12) { - $start_i++; - } - - while (($this->sizeX - ($offsetX + ($vline_count*$intervalX))) < 12) { - $vline_count--; - } - - $main = &$this->grid['horizontal']['main']; - $main['interval'] = $main_interval; - $main['linecount'] = $vline_count; - $main['intervalx'] = $intervalX; - $main['offset'] = $offset; - $main['offsetx'] = $offsetX; - $main['start'] = $start_i; - } - /********************************************************************************************************/ // DRAW ELEMENTS /********************************************************************************************************/ @@ -1316,172 +1206,461 @@ class CLineGraphDraw extends CGraphDraw { } private function drawTimeGrid() { - $this->calcTimeInterval(); - $this->drawSubTimeGrid(); - } - - private function drawSubTimeGrid() { - $main_interval = $this->grid['horizontal']['main']['interval']; - $main_intervalX = $this->grid['horizontal']['main']['intervalx']; - $main_offset = $this->grid['horizontal']['main']['offset']; - - $sub = &$this->grid['horizontal']['sub']; - $interval = $sub['interval']; - $vline_count = $sub['linecount']; - $intervalX = $sub['intervalx']; - - $offset = $sub['offset']; - $offsetX = $sub['offsetx']; - $start_i = $sub['start']; - - if ($interval == $main_interval) { - return; - } - - $test_dims = imageTextSize(7, 90, 'WWW'); - for ($i = $start_i; $i <= $vline_count; $i++) { - $new_time = $this->from_time + $i * $interval + $offset; - $new_pos = $i * $intervalX + $offsetX; - - // dayLightSave - if ($interval > SEC_PER_HOUR) { - $tz = date('Z', $this->from_time) - date('Z', $new_time); - $new_time += $tz; - } + $time_format = (date('Y', $this->stime) != date('Y', $this->to_time)) + ? DATE_FORMAT + : DATE_TIME_FORMAT_SHORT; - // main interval checks - if ($interval < SEC_PER_HOUR && date('i', $new_time) == 0) { - $this->drawMainPeriod($new_time, $new_pos); - continue; - } - - if ($interval >= SEC_PER_HOUR && $interval < SEC_PER_DAY && date('H', $new_time) == '00') { - $this->drawMainPeriod($new_time, $new_pos); - continue; - } + // Draw start date (and time) label. + $this->drawStartEndTimePeriod($this->stime, $time_format, 0); - if ($interval == SEC_PER_DAY && date('N', $new_time) == 7) { - $this->drawMainPeriod($new_time, $new_pos); - continue; - } + $this->calculateTimeInterval(); + $this->drawDateTimeIntervals(); - if ($interval > SEC_PER_DAY && ($i * $interval % $main_interval + $offset) == $main_offset) { - $this->drawMainPeriod($new_time, $new_pos); - continue; - } - - dashedLine( - $this->im, - $this->shiftXleft + $new_pos, - $this->shiftY, - $this->shiftXleft + $new_pos, - $this->sizeY + $this->shiftY, - $this->getColor($this->graphtheme['gridcolor'], 0) - ); - - if ($main_intervalX < floor(($main_interval / $interval) * $intervalX)) { - continue; - } - elseif ($main_intervalX < (ceil($main_interval / $interval + 1) * $test_dims['width'])) { - continue; - } - - if ($interval == SEC_PER_DAY) { - $date_format = _('D'); - } - elseif ($interval > SEC_PER_DAY) { - $date_format = _('d.m'); - } - elseif ($interval < SEC_PER_MIN) { - $date_format = _('H:i:s'); - } - elseif ($interval < SEC_PER_DAY) { - $date_format = _('H:i'); - } - - $str = zbx_date2str($date_format, $new_time); - $dims = imageTextSize(7, 90, $str); - - imageText( - $this->im, - 7, - 90, - $this->shiftXleft + $new_pos+round($dims['width'] / 2), - $this->sizeY + $this->shiftY + $dims['height'] + 6, - $this->getColor($this->graphtheme['textcolor'], 0), - $str - ); - } + // Draw end date (and time) label. + $this->drawStartEndTimePeriod($this->to_time, $time_format, $this->sizeX); + } - // first && last - // start - $str = zbx_date2str(_('d.m H:i'), $this->stime); - $dims = imageTextSize(8, 90, $str); + /** + * Draw start or end date (and time) label. + * + * @param int $value Unix time. + * @param sring $format Date time format. + * @param int $position Position on X axis. + */ + private function drawStartEndTimePeriod($value, $format, $position) { + $point = zbx_date2str(_($format), $value); + $element = imageTextSize(8, 90, $point); imageText( $this->im, 8, 90, - $this->shiftXleft + round($dims['width'] / 2), - $this->sizeY + $this->shiftY + $dims['height'] + 6, + $this->shiftXleft + $position + round($element['width'] / 2), + $this->sizeY + $this->shiftY + $element['height'] + 6, $this->getColor($this->graphtheme['highlightcolor'], 0), - $str + $point ); + } - // end - $endtime = $this->to_time; - - $str = zbx_date2str(_('d.m H:i'), $endtime); + /** + * Draw main period label in red color with 8px font size under X axis and a 2px dashed gray vertical line + * according to that label. + * + * @param int $value Unix time. + * @param sring $format Date time format. + * @param int $position Position on X axis. + */ + private function drawMainPeriod($value, $format, $position) { + $str = zbx_date2str($format, $value); $dims = imageTextSize(8, 90, $str); + imageText( $this->im, 8, 90, - $this->sizeX + $this->shiftXleft + round($dims['width'] / 2), + $this->shiftXleft + $position + round($dims['width'] / 2), $this->sizeY + $this->shiftY + $dims['height'] + 6, $this->getColor($this->graphtheme['highlightcolor'], 0), $str ); - } - private function drawMainPeriod($new_time, $new_pos) { - if (date('H',$new_time) == 0) { - if (date('Hi', $new_time) == 0) { - $date_format = _('d.m'); - } - else { - $date_format = _('d.m H:i'); - } - - $color = $this->graphtheme['highlightcolor']; - } - else { - $date_format = _('H:i'); - $color = $this->graphtheme['highlightcolor']; - } + dashedLine( + $this->im, + $this->shiftXleft + $position, + $this->shiftY, + $this->shiftXleft + $position, + $this->sizeY + $this->shiftY, + $this->getColor($this->graphtheme['maingridcolor'], 0) + ); + } - $str = zbx_date2str($date_format, $new_time); - $dims = imageTextSize(8, 90, $str); + /** + * Draw main period label in black color with 7px font size under X axis and a 1px dashed gray vertical line + * according to that label. + * + * @param int $value Unix time. + * @param sring $format Date time format. + * @param int $position Position on X axis. + */ + private function drawSubPeriod($value, $format, $position) { + $point = zbx_date2str($format, $value); + $element = imageTextSize(7, 90, $point); imageText( $this->im, - 8, + 7, 90, - $this->shiftXleft + $new_pos + round($dims['width'] / 2), - $this->sizeY + $this->shiftY + $dims['height'] + 6, - $this->getColor($color, 0), - $str + $this->shiftXleft + $position + round($element['width'] / 2), + $this->sizeY + $this->shiftY + $element['height'] + 6, + $this->getColor($this->graphtheme['textcolor'], 0), + $point ); dashedLine( $this->im, - $this->shiftXleft + $new_pos, + $this->shiftXleft + $position, $this->shiftY, - $this->shiftXleft + $new_pos, + $this->shiftXleft + $position, $this->sizeY + $this->shiftY, - $this->getColor($this->graphtheme['maingridcolor'], 0) + $this->getColor($this->graphtheme['gridcolor'], 0) ); } + /** + * Calculates the optimal size of time interval. + */ + private function calculateTimeInterval() { + $time_interval = ($this->gridPixels * $this->period) / $this->sizeX; + $intervals = [ + ['main' => SEC_PER_MIN / 2, 'sub' => SEC_PER_MIN / 60], // 30 seconds and 1 second + ['main' => SEC_PER_MIN, 'sub' => SEC_PER_MIN / 12], // 60 seconds and 5 seconds + ['main' => SEC_PER_MIN * 5, 'sub' => SEC_PER_MIN / 6], // 5 minuts and 10 seconds + ['main' => SEC_PER_MIN * 15, 'sub' => SEC_PER_MIN / 2], // 15 minuts and 30 seconds + ['main' => SEC_PER_HOUR, 'sub' => SEC_PER_MIN], // 1 hour and 1 minute + ['main' => SEC_PER_HOUR, 'sub' => SEC_PER_MIN * 2], // 1 hour and 2 minutes + ['main' => SEC_PER_HOUR, 'sub' => SEC_PER_MIN * 5], // 1 hour and 5 minutes + ['main' => SEC_PER_HOUR, 'sub' => SEC_PER_MIN * 15], // 1 hour and 15 minutes + ['main' => SEC_PER_HOUR, 'sub' => SEC_PER_MIN * 30], // 1 hour and 30 minutes + ['main' => SEC_PER_DAY, 'sub' => SEC_PER_HOUR], // 1 day and 1 hours + ['main' => SEC_PER_DAY, 'sub' => SEC_PER_HOUR * 3], // 1 day and 3 hours + ['main' => SEC_PER_DAY, 'sub' => SEC_PER_HOUR * 6], // 1 day and 6 hours + ['main' => SEC_PER_DAY, 'sub' => SEC_PER_HOUR * 12], // 1 day and 12 hours + ['main' => SEC_PER_WEEK, 'sub' => SEC_PER_DAY], // 1 week and 1 day + ['main' => SEC_PER_WEEK * 2, 'sub' => SEC_PER_WEEK], // 2 weeks and 1 week + ['main' => SEC_PER_MONTH, 'sub' => SEC_PER_DAY * 15], // 30 days and 15 days + ['main' => SEC_PER_MONTH * 6, 'sub' => SEC_PER_MONTH], // half year and 30 days + ['main' => SEC_PER_YEAR, 'sub' => SEC_PER_MONTH], // 1 year and 30 days + ['main' => SEC_PER_YEAR, 'sub' => SEC_PER_MONTH * 3], // 1 year and 90 days + ['main' => SEC_PER_YEAR, 'sub' => SEC_PER_MONTH * 4], // 1 year and 120 days + ['main' => SEC_PER_YEAR, 'sub' => SEC_PER_MONTH * 6], // 1 year and 180 days + ['main' => SEC_PER_YEAR * 5, 'sub' => SEC_PER_YEAR], // 5 years and 1 year + ['main' => SEC_PER_YEAR * 10, 'sub' => SEC_PER_YEAR * 2], // 10 years and 2 years + ['main' => SEC_PER_YEAR * 15, 'sub' => SEC_PER_YEAR * 3], // 15 years and 3 years + ['main' => SEC_PER_YEAR * 20, 'sub' => SEC_PER_YEAR * 5], // 20 years and 5 years + ['main' => SEC_PER_YEAR * 30, 'sub' => SEC_PER_YEAR * 10], // 30 years and 10 years + ['main' => SEC_PER_YEAR * 40, 'sub' => SEC_PER_YEAR * 20], // 40 years and 20 years + ['main' => SEC_PER_YEAR * 60, 'sub' => SEC_PER_YEAR * 30], // 60 years and 30 years + ['main' => SEC_PER_YEAR * 80, 'sub' => SEC_PER_YEAR * 40] // 80 years and 40 years + ]; + + // Default inteval values. + $distance = SEC_PER_YEAR * 5; + $main_interval = 0; + $sub_interval = 0; + + foreach ($intervals as $interval) { + $time = abs($interval['sub'] - $time_interval); + + if ($time < $distance) { + $distance = $time; + $sub_interval = $interval['sub']; + $main_interval = $interval['main']; + } + } + + // Calculate sub interval. + $interval_x = ($sub_interval * $this->sizeX) / $this->period; + + if ($sub_interval > SEC_PER_DAY) { + $offset = (7 - date('w', $this->from_time)) * SEC_PER_DAY; + $offset += $this->diffTZ; + + $next = $this->from_time + $offset; + + $offset = mktime(0, 0, 0, date('m', $next), date('d', $next), date('Y', $next)) - $this->from_time; + } + else { + $offset = $sub_interval - (($this->from_time + date('Z', $this->from_time)) % $sub_interval); + } + + $sub = &$this->grid['horizontal']['sub']; + $sub['interval'] = $sub_interval; + $sub['interval_x'] = $interval_x; + $sub['offset'] = $offset; + + // Calculate main interval. + $interval_x = ($main_interval * $this->sizeX) / $this->period; + + if ($main_interval > SEC_PER_DAY) { + $offset = (7 - date('w', $this->from_time)) * SEC_PER_DAY; + $offset += $this->diffTZ; + $next = $this->from_time + $offset; + + $offset = mktime(0, 0, 0, date('m', $next), date('d', $next), date('Y', $next)) - $this->from_time; + } + else { + $offset = $main_interval - (($this->from_time + (date('Z', $this->from_time))) % $main_interval); + $offset += $this->diffTZ; + } + + $main = &$this->grid['horizontal']['main']; + $main['interval'] = $main_interval; + $main['interval_x'] = $interval_x; + $main['offset'] = $offset; + } + + /** + * Draw date and time intervals under the X axis. + */ + private function drawDateTimeIntervals() { + $sub_interval = $this->grid['horizontal']['sub']['interval']; + $sub_interval_x = $this->grid['horizontal']['sub']['interval_x']; + $sub_offset = $this->grid['horizontal']['sub']['offset']; + $main_interval = $this->grid['horizontal']['main']['interval']; + $main_interval_x = $this->grid['horizontal']['main']['interval_x']; + $main_offset = $this->grid['horizontal']['main']['offset']; + + // Infinite loop checks. + if ($sub_interval == $main_interval + || ($main_interval_x < floor(($main_interval / $sub_interval) * $sub_interval_x))) { + return; + } + + // Sub interval title size. + $element_size = imageTextSize(7, 90, 'WWW'); + + // Main interval title size. + $end_element_size = imageTextSize(8, 90, 'WWW'); + + $position = 0; + $i = 0; + + // Calculate the next date and time, postion and determines label type (main or sub) for label placement. + while ($this->stime + $i * $sub_interval + $sub_offset < $this->to_time) { + // Next step calculation by interval. + + $previous_time = isset($new_time) ? $new_time : $this->stime; + + // Every 40 years. + if ($sub_interval == SEC_PER_YEAR * 40) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 40); + } + // Every 30 years. + elseif ($sub_interval == SEC_PER_YEAR * 30) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 30); + } + // Every 20 years. + elseif ($sub_interval == SEC_PER_YEAR * 20) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 20); + } + // Every 10 years. + elseif ($sub_interval == SEC_PER_YEAR * 10) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 10); + } + // Every 5 years. + elseif ($sub_interval == SEC_PER_YEAR * 5) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 5); + } + // Every 3 years. + elseif ($sub_interval == SEC_PER_YEAR * 3) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 3); + } + // Every 2 years. + elseif ($sub_interval == SEC_PER_YEAR * 2) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 2); + } + // Every year. + elseif ($sub_interval == SEC_PER_YEAR) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 1); + } + // Every 6 months. + elseif ($sub_interval == SEC_PER_MONTH * 6) { + // First step calculation. + if ($i == 0) { + // If month > July, then chanage it to 1st of January of the next year. + if (date('m', $this->stime) > 7) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 1); + } + // Otherwise set 1st of July of the same year as the next step. + else { + $new_time = mktime(0, 0, 0, 7, 1, date('Y', $previous_time)); + } + } + // Other steps calculation. + else { + // If month = January, then change it to 1st July of the same year. + if (date('m', $previous_time) == 1) { + $new_time = mktime(0, 0, 0, 7, 1, date('Y', $previous_time)); + } + // Otherwise set 1st of January of the next year as the next step. + else { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 1); + } + } + } + // Every 4 months. + elseif ($sub_interval == SEC_PER_MONTH * 4) { + // First step calculation. + if ($i == 0) { + // If month > September, then chanage it to 1st of January of the next year. + if (date('m', $this->stime) > 9) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 1); + } + // If month > May, then change it to 1st of September of the same year. + elseif (date('m', $this->stime) > 5) { + $new_time = mktime(0, 0, 0, 9, 1, date('Y', $previous_time)); + } + // Otherwise set 1st of May of the same year as next step. + else { + $new_time = mktime(0, 0, 0, 5, 1, date('Y', $previous_time)); + } + } + // Other steps calculation. + else { + // If month = September, then change it to 1st of January of the next year. + if (date('m', $previous_time) == 9) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 1); + } + // If month = May, then change it to 1st of September of the same year. + elseif (date('m', $previous_time) == 5) { + $new_time = mktime(0, 0, 0, 9, 1, date('Y', $previous_time)); + } + // Otherwise set 1st of May of the same year as next step. + else { + $new_time = mktime(0, 0, 0, 5, 1, date('Y', $previous_time)); + } + } + } + // Every 3 months. + elseif ($sub_interval == SEC_PER_MONTH * 3) { + // First step calculation. + if ($i == 0) { + // If month > October, then change it to 1st of January of the next year. + if (date('m', $this->stime) > 10) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 1); + } + // If month > July, then change it to 1st of October of the same year. + elseif (date('m', $this->stime) > 7) { + $new_time = mktime(0, 0, 0, 10, 1, date('Y', $previous_time)); + } + // If month > April, then change it to 1st of July of the same year. + elseif (date('m', $this->stime) > 4) { + $new_time = mktime(0, 0, 0, 7, 1, date('Y', $previous_time)); + } + // Otherwise set 1st of April of the same year as next step. + else { + $new_time = mktime(0, 0, 0, 4, 1, date('Y', $previous_time)); + } + } + // Other steps calculation. + else { + // If month = October, then change it to 1st of January of the next year. + if (date('m', $previous_time) == 10) { + $new_time = mktime(0, 0, 0, 1, 1, date('Y', $previous_time) + 1); + } + // If month = July, then change it to 1st of October of the same year. + elseif (date('m', $previous_time) == 7) { + $new_time = mktime(0, 0, 0, 10, 1, date('Y', $previous_time)); + } + // If month = April, then change it to 1st of July of the same year. + elseif (date('m', $previous_time) == 4) { + $new_time = mktime(0, 0, 0, 7, 1, date('Y', $previous_time)); + } + // Otherwise set 1st of April of the same year as next step. + else { + $new_time = mktime(0, 0, 0, 4, 1, date('Y', $previous_time)); + } + } + } + // Every month. + elseif ($sub_interval == SEC_PER_MONTH) { + $new_time = mktime(0, 0, 0, date('m', $previous_time) + 1, 1, date('Y', $previous_time)); + } + // Every 15 days (about half of a month). + elseif ($sub_interval == SEC_PER_DAY * 15) { + // First step calculation. + if ($i == 0) { + // If day > 16, then change it to the 1st day of the next month. + if (date('d', $this->stime) > 16) { + $new_time = mktime(0, 0, 0, date('m', $previous_time) + 1, 1, date('Y', $previous_time)); + } + // Otherwise set 16th day of the same month. + else { + $new_time = mktime(0, 0, 0, date('m', $previous_time), 16, date('Y', $previous_time)); + } + } + // Other steps calculation. + else { + // If 1st day of the month, then change it to 16th day of the same month. + if (date('d', $previous_time) == 1) { + $new_time = mktime(0, 0, 0, date('m', $previous_time), 16, date('Y', $previous_time)); + } + // Otherwise set 1st day of the next month. + else { + $new_time = mktime(0, 0, 0, date('m', $previous_time) + 1, 1, date('Y', $previous_time)); + } + } + } + // Less than 15 days. + else { + $new_time = $this->from_time + $i * $sub_interval + $sub_offset; + } + + // Draw until year 2038. + if ($new_time < $this->stime && $i != 0) { + break; + } + + $timeInterval = $new_time - $previous_time; + + $timeIntervalX = ($timeInterval * $this->sizeX) / $this->period; + + $position += $timeIntervalX; + + // Start drawing after year 1970. + if ($new_time < 0) { + $i++; + continue; + } + + // First element overlaping checks. + if (($i == 0 && $position < $element_size['width']) || $new_time >= $this->to_time) { + $i++; + continue; + } + + // Last element overlaping check. + if ($position > $this->sizeX - $end_element_size['width'] / 2 - 2) { + break; + } + + $i++; + + // What time format to display. + if (date('d', $new_time) == 1 && date('m', $new_time) == 1 && date('H', $new_time) == 0 + && date('i', $new_time) == 0) { + $format = _x('Y', DATE_FORMAT_CONTEXT); + } + elseif (date('d', $new_time) == 1 && date('H', $new_time) == 0 && date('i', $new_time) == 0 + && ($sub_interval == SEC_PER_MONTH || $sub_interval == SEC_PER_MONTH * 3 + || $sub_interval == SEC_PER_MONTH * 4 || $sub_interval == SEC_PER_MONTH * 6)) { + $format = _('M'); + } + elseif ((date('H', $new_time) == 0 && date('i', $new_time) == 0) || $sub_interval > SEC_PER_HOUR * 12) { + $format = _('m-d'); + } + elseif (date('s', $new_time) == 0 && $sub_interval >= 60) { + $format = TIME_FORMAT; + } + else { + $format = _('H:i:s'); + } + + // Check if main or sub interval and then draw it. + if ((!($new_time % $main_interval) && $main_interval < SEC_PER_DAY) + || ($sub_interval < SEC_PER_MIN && date('s', $new_time) == 0) + || ($main_interval == SEC_PER_DAY && date('H', $new_time) == 0 && date('i', $new_time) == 0) + || ($main_interval == SEC_PER_WEEK && date('N', $new_time) == 7) + || ($main_interval == SEC_PER_MONTH && date('d', $new_time) == 1) + || ($main_interval == SEC_PER_WEEK * 2 && date('m', $new_time) != date('m', $previous_time)) + || $format == _x('Y', DATE_FORMAT_CONTEXT)) { + $this->drawMainPeriod($new_time, $format, $position); + continue; + } + + $this->drawSubPeriod($new_time, $format, $position); + } + } + private function drawSides() { if (isset($this->axis_valuetype[GRAPH_YAXIS_SIDE_RIGHT]) && ($this->yaxisright != 0 || $this->skipRightScale != 1)) { diff --git a/frontends/php/include/defines.inc.php b/frontends/php/include/defines.inc.php index 07d960813c6..d45ded9fc74 100644 --- a/frontends/php/include/defines.inc.php +++ b/frontends/php/include/defines.inc.php @@ -19,7 +19,7 @@ **/ -define('ZABBIX_VERSION', '3.0.0alpha4'); +define('ZABBIX_VERSION', '3.0.0alpha5'); define('ZABBIX_API_VERSION', '3.0.0'); define('ZABBIX_EXPORT_VERSION', '3.0'); define('ZABBIX_DB_VERSION', 2050071); @@ -930,12 +930,12 @@ define('ZBX_API_ERROR_NO_METHOD', 300); define('API_OUTPUT_EXTEND', 'extend'); define('API_OUTPUT_COUNT', 'count'); -define('SEC_PER_MIN', 60); -define('SEC_PER_HOUR', 3600); -define('SEC_PER_DAY', 86400); -define('SEC_PER_WEEK', 604800); // 7 * SEC_PER_DAY -define('SEC_PER_MONTH', 2592000); // 30 * SEC_PER_DAY -define('SEC_PER_YEAR', 31536000); // 365 * SEC_PER_DAY +define('SEC_PER_MIN', 60); +define('SEC_PER_HOUR', 3600); +define('SEC_PER_DAY', 86400); +define('SEC_PER_WEEK', 604800); +define('SEC_PER_MONTH', 2592000); +define('SEC_PER_YEAR', 31536000); define('ZBX_JAN_2038', 2145916800); diff --git a/frontends/php/include/items.inc.php b/frontends/php/include/items.inc.php index 5214408d556..268173ac1e2 100644 --- a/frontends/php/include/items.inc.php +++ b/frontends/php/include/items.inc.php @@ -753,10 +753,15 @@ function getItemDataOverviewCells($tableRow, $ithosts, $hostName) { if ($item['tr_value'] == TRIGGER_VALUE_TRUE) { $css = getSeverityStyle($item['severity']); - $ack = get_last_event_by_triggerid($item['triggerid']); - $ack = ($ack['acknowledged'] == 1) - ? [SPACE, (new CSpan())->addClass(ZBX_STYLE_ICON_ACKN)] - : null; + + // Display event acknowledgement. + $config = select_config(); + if ($config['event_ack_enable']) { + $ack = get_last_event_by_triggerid($item['triggerid']); + $ack = ($ack['acknowledged'] == 1) + ? [SPACE, (new CSpan())->addClass(ZBX_STYLE_ICON_ACKN)] + : null; + } } if ($item['value'] !== null) { diff --git a/frontends/php/include/translateDefines.inc.php b/frontends/php/include/translateDefines.inc.php index c3d263e70c3..a24f070dba3 100644 --- a/frontends/php/include/translateDefines.inc.php +++ b/frontends/php/include/translateDefines.inc.php @@ -29,6 +29,7 @@ define('UNRESOLVED_MACRO_STRING', '*'._('UNKNOWN').'*'); */ define('DATE_TIME_FORMAT_SECONDS', _('Y-m-d H:i:s')); define('DATE_TIME_FORMAT', _('Y-m-d H:i')); +define('DATE_TIME_FORMAT_SHORT', _('m-d H:i')); define('DATE_FORMAT', _('Y-m-d')); define('TIME_FORMAT_SECONDS', _('H:i:s')); define('TIME_FORMAT', _('H:i')); diff --git a/frontends/php/include/views/configuration.sysmap.edit.php b/frontends/php/include/views/configuration.sysmap.edit.php index f9267e054a7..72e10a547c4 100644 --- a/frontends/php/include/views/configuration.sysmap.edit.php +++ b/frontends/php/include/views/configuration.sysmap.edit.php @@ -24,16 +24,16 @@ require_once dirname(__FILE__).'/js/configuration.sysmap.edit.js.php'; $widget = (new CWidget())->setTitle(_('Network maps')); // create sysmap form -$sysmapForm = (new CForm()) +$form = (new CForm()) ->setName('map.edit.php') ->addVar('form', getRequest('form', 1)); if (isset($this->data['sysmap']['sysmapid'])) { - $sysmapForm->addVar('sysmapid', $this->data['sysmap']['sysmapid']); + $form->addVar('sysmapid', $this->data['sysmap']['sysmapid']); } // create sysmap form list -$sysmapList = (new CFormList()) +$form_list = (new CFormList()) ->addRow(_('Name'), (new CTextBox('name', $this->data['sysmap']['name'])) ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH) @@ -54,7 +54,7 @@ $imageComboBox = (new CComboBox('backgroundid', $this->data['sysmap']['backgroun foreach ($this->data['images'] as $image) { $imageComboBox->addItem($image['imageid'], $image['name']); } -$sysmapList->addRow(_('Background image'), $imageComboBox); +$form_list->addRow(_('Background image'), $imageComboBox); // append iconmapping to form list $iconMappingComboBox = (new CComboBox('iconmapid', $this->data['sysmap']['iconmapid'])) @@ -64,24 +64,24 @@ foreach ($this->data['iconMaps'] as $iconMap) { } $iconMappingsLink = (new CLink(_('show icon mappings'), 'adm.iconmapping.php')) ->setAttribute('target', '_blank'); -$sysmapList->addRow(_('Automatic icon mapping'), [$iconMappingComboBox, SPACE, $iconMappingsLink]); +$form_list->addRow(_('Automatic icon mapping'), [$iconMappingComboBox, SPACE, $iconMappingsLink]); // append multiple checkboxes to form list -$sysmapList->addRow(_('Icon highlight'), +$form_list->addRow(_('Icon highlight'), (new CCheckBox('highlight'))->setChecked($this->data['sysmap']['highlight'] == 1) ); -$sysmapList->addRow(_('Mark elements on trigger status change'), +$form_list->addRow(_('Mark elements on trigger status change'), (new CCheckBox('markelements'))->setChecked($this->data['sysmap']['markelements'] == 1) ); -$sysmapList->addRow(_('Expand single problem'), +$form_list->addRow(_('Expand single problem'), (new CCheckBox('expandproblem'))->setChecked($this->data['sysmap']['expandproblem'] == 1) ); -$sysmapList->addRow(_('Advanced labels'), +$form_list->addRow(_('Advanced labels'), (new CCheckBox('label_format'))->setChecked($this->data['sysmap']['label_format'] == 1) ); // append hostgroup to form list -$sysmapList->addRow(_('Host group label type'), [ +$form_list->addRow(_('Host group label type'), [ new CComboBox('label_type_hostgroup', $this->data['sysmap']['label_type_hostgroup'], null, $this->data['labelTypesLimited']), BR(), (new CTextArea('label_string_hostgroup', $this->data['sysmap']['label_string_hostgroup'])) @@ -89,7 +89,7 @@ $sysmapList->addRow(_('Host group label type'), [ ]); // append host to form list -$sysmapList->addRow(_('Host label type'), [ +$form_list->addRow(_('Host label type'), [ new CComboBox('label_type_host', $this->data['sysmap']['label_type_host'], null, $this->data['labelTypes']), BR(), (new CTextArea('label_string_host', $this->data['sysmap']['label_string_host'])) @@ -97,7 +97,7 @@ $sysmapList->addRow(_('Host label type'), [ ]); // append trigger to form list -$sysmapList->addRow(_('Trigger label type'), [ +$form_list->addRow(_('Trigger label type'), [ new CComboBox('label_type_trigger', $this->data['sysmap']['label_type_trigger'], null, $this->data['labelTypesLimited']), BR(), (new CTextArea('label_string_trigger', $this->data['sysmap']['label_string_trigger'])) @@ -105,7 +105,7 @@ $sysmapList->addRow(_('Trigger label type'), [ ]); // append map to form list -$sysmapList->addRow(_('Map label type'), [ +$form_list->addRow(_('Map label type'), [ new CComboBox('label_type_map', $this->data['sysmap']['label_type_map'], null, $this->data['labelTypesLimited']), BR(), (new CTextArea('label_string_map', $this->data['sysmap']['label_string_map'])) @@ -113,7 +113,7 @@ $sysmapList->addRow(_('Map label type'), [ ]); // append image to form list -$sysmapList->addRow(_('Image label type'), [ +$form_list->addRow(_('Image label type'), [ new CComboBox('label_type_image', $this->data['sysmap']['label_type_image'], null, $this->data['labelTypesImage']), BR(), (new CTextArea('label_string_image', $this->data['sysmap']['label_string_image'])) @@ -122,10 +122,10 @@ $sysmapList->addRow(_('Image label type'), [ // append icon label to form list unset($this->data['labelTypes'][MAP_LABEL_TYPE_CUSTOM]); -$sysmapList->addRow(_('Icon label type'), new CComboBox('label_type', $this->data['sysmap']['label_type'], null, $this->data['labelTypes'])); +$form_list->addRow(_('Icon label type'), new CComboBox('label_type', $this->data['sysmap']['label_type'], null, $this->data['labelTypes'])); // append icon label location to form list -$sysmapList->addRow(_('Icon label location'), new CComboBox('label_location', $data['sysmap']['label_location'], null, +$form_list->addRow(_('Icon label location'), new CComboBox('label_location', $data['sysmap']['label_location'], null, [ 0 => _('Bottom'), 1 => _('Left'), @@ -134,19 +134,20 @@ $sysmapList->addRow(_('Icon label location'), new CComboBox('label_location', $d ] )); -// append show unack to form list -$showUnackComboBox = new CComboBox('show_unack', $this->data['sysmap']['show_unack'], null, [ - EXTACK_OPTION_ALL => _('All'), - EXTACK_OPTION_BOTH => _('Separated'), - EXTACK_OPTION_UNACK => _('Unacknowledged only'), -]); -$showUnackComboBox->setEnabled($this->data['config']['event_ack_enable']); -if (!$this->data['config']['event_ack_enable']) { - $showUnackComboBox->setAttribute('title', _('Acknowledging disabled')); +if ($data['config']['event_ack_enable']) { + // append show unack to form list + $show_unack_combobox = new CComboBox('show_unack', $data['sysmap']['show_unack'], null, [ + EXTACK_OPTION_ALL => _('All'), + EXTACK_OPTION_BOTH => _('Separated'), + EXTACK_OPTION_UNACK => _('Unacknowledged only'), + ]); + $form_list->addRow(_('Problem display'), $show_unack_combobox); } -$sysmapList - ->addRow(_('Problem display'), $showUnackComboBox) - ->addRow(_('Minimum trigger severity'), new CSeverity(['name' => 'severity_min', 'value' => (int) $this->data['sysmap']['severity_min']])); + +$form_list->addRow(_('Minimum trigger severity'), new CSeverity([ + 'name' => 'severity_min', + 'value' => (int) $data['sysmap']['severity_min'] +])); // create url table $urlTable = (new CTable()) @@ -203,18 +204,18 @@ $addButtonColumn = (new CCol($addButton))->setColSpan(4); $urlTable->addRow($addButtonColumn); // append url table to form list -$sysmapList->addRow(_('URLs'), +$form_list->addRow(_('URLs'), (new CDiv($urlTable)) ->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR) ->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;') ); // append sysmap to form -$sysmapTab = (new CTabView())->addTab('sysmapTab', _('Map'), $sysmapList); +$tab = (new CTabView())->addTab('sysmapTab', _('Map'), $form_list); // append buttons to form if (hasRequest('sysmapid') && getRequest('sysmapid') > 0) { - $sysmapTab->setFooter(makeFormFooter( + $tab->setFooter(makeFormFooter( new CSubmit('update', _('Update')), [ new CButton('clone', _('Clone')), @@ -224,15 +225,15 @@ if (hasRequest('sysmapid') && getRequest('sysmapid') > 0) { )); } else { - $sysmapTab->setFooter(makeFormFooter( + $tab->setFooter(makeFormFooter( new CSubmit('add', _('Add')), [new CButtonCancel()] )); } -$sysmapForm->addItem($sysmapTab); +$form->addItem($tab); // append form to widget -$widget->addItem($sysmapForm); +$widget->addItem($form); return $widget; diff --git a/frontends/php/include/views/monitoring.dashconf.php b/frontends/php/include/views/monitoring.dashconf.php index e4c5b5bc184..055ab7c868c 100644 --- a/frontends/php/include/views/monitoring.dashconf.php +++ b/frontends/php/include/views/monitoring.dashconf.php @@ -19,33 +19,33 @@ **/ -$dashconfWidget = (new CWidget())->setTitle(_('Dashboard')); +$widget = (new CWidget())->setTitle(_('Dashboard')); // create form -$dashconfForm = (new CForm()) +$form = (new CForm()) ->setName('dashconf') ->setId('dashform') ->addVar('filterEnable', $this->data['isFilterEnable']); // create form list -$dashconfFormList = new CFormList('dashconfFormList'); +$form_list = new CFormList('dashconfFormList'); // append filter status to form list if ($this->data['isFilterEnable']) { $filterStatusSpan = (new CSpan(_('Enabled'))) ->addClass(ZBX_STYLE_LINK_ACTION) ->addClass(ZBX_STYLE_GREEN) - ->onClick("create_var('".$dashconfForm->getName()."', 'filterEnable', 0, true);") + ->onClick("create_var('".$form->getName()."', 'filterEnable', 0, true);") ->setAttribute('tabindex', 0); } else { $filterStatusSpan = (new CSpan(_('Disabled'))) ->addClass(ZBX_STYLE_LINK_ACTION) ->addClass(ZBX_STYLE_RED) - ->onClick("$('dashform').enable(); create_var('".$dashconfForm->getName()."', 'filterEnable', 1, true);") + ->onClick("$('dashform').enable(); create_var('".$form->getName()."', 'filterEnable', 1, true);") ->setAttribute('tabindex', 0); } -$dashconfFormList->addRow(_('Dashboard filter'), $filterStatusSpan); +$form_list->addRow(_('Dashboard filter'), $filterStatusSpan); // append host groups to form list $hostGroupsComboBox = new CComboBox('grpswitch', $this->data['grpswitch'], 'submit()', [ @@ -55,26 +55,26 @@ $hostGroupsComboBox = new CComboBox('grpswitch', $this->data['grpswitch'], 'subm if (!$this->data['isFilterEnable']) { $hostGroupsComboBox->setAttribute('disabled', 'disabled'); } -$dashconfFormList->addRow(_('Host groups'), $hostGroupsComboBox); +$form_list->addRow(_('Host groups'), $hostGroupsComboBox); if ($this->data['grpswitch']) { - $dashconfFormList->addRow(_('Show selected groups'), (new CMultiSelect([ + $form_list->addRow(_('Show selected groups'), (new CMultiSelect([ 'name' => 'groupids[]', 'objectName' => 'hostGroup', 'data' => $this->data['groups'], 'disabled' => !$this->data['isFilterEnable'], 'popup' => [ - 'parameters' => 'srctbl=host_groups&dstfrm='.$dashconfForm->getName().'&dstfld1=groupids_'. + 'parameters' => 'srctbl=host_groups&dstfrm='.$form->getName().'&dstfld1=groupids_'. '&srcfld1=groupid&multiselect=1' ] ]))->setWidth(ZBX_TEXTAREA_FILTER_STANDARD_WIDTH)); - $dashconfFormList->addRow(_('Hide selected groups'), (new CMultiSelect([ + $form_list->addRow(_('Hide selected groups'), (new CMultiSelect([ 'name' => 'hidegroupids[]', 'objectName' => 'hostGroup', 'data' => $this->data['hideGroups'], 'disabled' => !$this->data['isFilterEnable'], 'popup' => [ - 'parameters' => 'srctbl=host_groups&dstfrm='.$dashconfForm->getName().'&dstfld1=hidegroupids_'. + 'parameters' => 'srctbl=host_groups&dstfrm='.$form->getName().'&dstfld1=hidegroupids_'. '&srcfld1=groupid&multiselect=1' ] ]))->setWidth(ZBX_TEXTAREA_FILTER_STANDARD_WIDTH)); @@ -85,7 +85,7 @@ $maintenanceCheckBox = (new CCheckBox('maintenance'))->setChecked($this->data['m if (!$this->data['isFilterEnable']) { $maintenanceCheckBox->setAttribute('disabled', 'disabled'); } -$dashconfFormList->addRow(_('Hosts'), +$form_list->addRow(_('Hosts'), new CLabel([$maintenanceCheckBox, _('Show hosts in maintenance')], 'maintenance') ); @@ -102,36 +102,35 @@ foreach ($this->data['severities'] as $severity) { } array_pop($severities); -$dashconfFormList->addRow(_('Triggers with severity'), $severities); +$form_list->addRow(_('Triggers with severity'), $severities); -$dashconfFormList->addRow(_('Trigger name like'), +$form_list->addRow(_('Trigger name like'), (new CTextBox('trigger_name', $data['trigger_name'])) ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH) ->setEnabled($data['isFilterEnable']) ); -// append problem display to form list -$extAckComboBox = new CComboBox('extAck', $this->data['extAck'], null, [ - EXTACK_OPTION_ALL => _('All'), - EXTACK_OPTION_BOTH => _('Separated'), - EXTACK_OPTION_UNACK => _('Unacknowledged only') -]); -$extAckComboBox->setEnabled($this->data['isFilterEnable'] && $this->data['config']['event_ack_enable']); -if (!$this->data['config']['event_ack_enable']) { - $extAckComboBox->setAttribute('title', _('Event acknowledging disabled')); +if ($data['config']['event_ack_enable']) { + // append problem display to form list + $ext_ack_combobox = new CComboBox('extAck', $data['extAck'], null, [ + EXTACK_OPTION_ALL => _('All'), + EXTACK_OPTION_BOTH => _('Separated'), + EXTACK_OPTION_UNACK => _('Unacknowledged only') + ]); + $ext_ack_combobox->setEnabled($data['isFilterEnable']); + $form_list->addRow(_('Problem display'), $ext_ack_combobox); } -$dashconfFormList->addRow(_('Problem display'), $extAckComboBox); // create tab -$dashconfTab = new CTabView(); -$dashconfTab->addTab('dashconfTab', _('Filter'), $dashconfFormList); +$tab = new CTabView(); +$tab->addTab('dashconfTab', _('Filter'), $form_list); -$dashconfTab->setFooter(makeFormFooter( +$tab->setFooter(makeFormFooter( new CSubmit('update', _('Update')), [new CButtonCancel()] )); -$dashconfForm->addItem($dashconfTab); -$dashconfWidget->addItem($dashconfForm); +$form->addItem($tab); +$widget->addItem($form); -return $dashconfWidget; +return $widget; diff --git a/frontends/php/search.php b/frontends/php/search.php index b73145a5438..e3cfdea5d7f 100644 --- a/frontends/php/search.php +++ b/frontends/php/search.php @@ -421,31 +421,31 @@ if ($admin) { $applications_link = [ new CLink(_('Applications'), 'applications.php?'.$link), - CViewHelper::showNum($host['applications']) + CViewHelper::showNum($template['applications']) ]; $items_link = [ new CLink(_('Items'), 'items.php?filter_set=1&'.$link), - CViewHelper::showNum($host['items']) + CViewHelper::showNum($template['items']) ]; $triggers_link = [ new CLink(_('Triggers'), 'triggers.php?'.$link), - CViewHelper::showNum($host['triggers']) + CViewHelper::showNum($template['triggers']) ]; $graphs_link = [ new CLink(_('Graphs'), 'graphs.php?'.$link), - CViewHelper::showNum($host['graphs']) + CViewHelper::showNum($template['graphs']) ]; $screensLink = [ new CLink(_('Screens'), 'screenconf.php?templateid='.$templateid), - CViewHelper::showNum($host['screens']) + CViewHelper::showNum($template['screens']) ]; $discoveryLink = [ new CLink(_('Discovery'), 'host_discovery.php?'.$link), - CViewHelper::showNum($host['discoveries']) + CViewHelper::showNum($template['discoveries']) ]; $httpTestsLink = [ new CLink(_('Web'), 'httpconf.php?'.$link), - CViewHelper::showNum($host['httpTests']) + CViewHelper::showNum($template['httpTests']) ]; } else { diff --git a/include/cfg.h b/include/cfg.h index 4a51403ac56..90866ece149 100644 --- a/include/cfg.h +++ b/include/cfg.h @@ -36,6 +36,9 @@ #define ZBX_CFG_NOT_STRICT 0 #define ZBX_CFG_STRICT 1 + +#define ZBX_PROXY_HEARTBEAT_FREQUENCY_MAX SEC_PER_HOUR + extern char *CONFIG_FILE; extern char *CONFIG_LOG_FILE; extern int CONFIG_ALLOW_ROOT; diff --git a/include/dbcache.h b/include/dbcache.h index 89c3e43cea7..30ff2ea9b9b 100644 --- a/include/dbcache.h +++ b/include/dbcache.h @@ -454,4 +454,14 @@ void zbx_idset_free(zbx_idset_t *idset); void zbx_config_get(zbx_config_t *cfg, zbx_uint64_t flags); void zbx_config_clean(zbx_config_t *cfg); +/* flags to specify which host interfaces have enabled items */ +#define ZBX_FLAG_INTERFACE_NONE 0x00 +#define ZBX_FLAG_INTERFACE_AGENT 0x01 +#define ZBX_FLAG_INTERFACE_SNMP 0x02 +#define ZBX_FLAG_INTERFACE_IPMI 0x04 +#define ZBX_FLAG_INTERFACE_JMX 0x08 +#define ZBX_FLAG_INTERFACE_UNKNOWN 0x80 + +int DCreset_hosts_availability(zbx_vector_uint64_pair_t *hosts); +void DCupdate_hosts_availability(); #endif diff --git a/include/version.h b/include/version.h index 7b2230268bc..51d7c68c1b0 100644 --- a/include/version.h +++ b/include/version.h @@ -24,12 +24,12 @@ #define ZBX_STR(str) ZBX_STR2(str) #define APPLICATION_NAME "Zabbix Agent" -#define ZABBIX_REVDATE "15 October 2015" +#define ZABBIX_REVDATE "6 November 2015" #define ZABBIX_VERSION_MAJOR 3 #define ZABBIX_VERSION_MINOR 0 #define ZABBIX_VERSION_PATCH 0 #define ZABBIX_VERSION_REVISION {ZABBIX_REVISION} -#define ZABBIX_VERSION_RC "alpha4" +#define ZABBIX_VERSION_RC "alpha5" #define ZABBIX_VERSION ZBX_STR(ZABBIX_VERSION_MAJOR) "." ZBX_STR(ZABBIX_VERSION_MINOR) "." \ ZBX_STR(ZABBIX_VERSION_PATCH) ZABBIX_VERSION_RC #define ZABBIX_REVISION ZBX_STR(ZABBIX_VERSION_REVISION) diff --git a/include/zbxtypes.h b/include/zbxtypes.h index 6c3e9e6bc99..f682f49b4ef 100644 --- a/include/zbxtypes.h +++ b/include/zbxtypes.h @@ -167,4 +167,7 @@ zbx_uint128_t; #define ZBX_SIZE_T_ALIGN8(size) (((size) + 7) & ~(size_t)7) +/* macro to test if a signed value has been assigned to unsigned type (char, short, int, long long) */ +#define ZBX_IS_TOP_BIT_SET(x) (0 != ((__UINT64_C(1) << ((sizeof(x) << 3) - 1)) & (x))) + #endif diff --git a/src/libs/zbxdbcache/dbcache.c b/src/libs/zbxdbcache/dbcache.c index 3f1847b4dd0..fbf617ef906 100644 --- a/src/libs/zbxdbcache/dbcache.c +++ b/src/libs/zbxdbcache/dbcache.c @@ -455,7 +455,7 @@ static void DCflush_trends(ZBX_DC_TREND *trends, int *trends_num, int update_cac } else { - zbx_uint128_t avg; + zbx_uint128_t avg; ZBX_STR2UINT64(value_min.ui64, row[2]); ZBX_STR2UINT64(value_avg.ui64, row[3]); @@ -3144,3 +3144,101 @@ zbx_uint64_t DCget_nextid(const char *table_name, int num) return nextid; } +/****************************************************************************** + * * + * Function: DCupdate_hosts_availability * + * * + * Purpose: performs host availability reset for hosts with availability set * + * on interfaces without enabled items * + * * + ******************************************************************************/ +void DCupdate_hosts_availability() +{ + const char *__function_name = "DCupdate_hosts_availability"; + zbx_vector_uint64_pair_t hosts; + char *sql = NULL; + size_t sql_alloc = 0, sql_offset = 0; + int i; + + zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); + + zbx_vector_uint64_pair_create(&hosts); + + if (SUCCEED != DCreset_hosts_availability(&hosts)) + goto out; + + DBbegin(); + + DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); + + for (i = 0; i < hosts.values_num; i++) + { + char delim = ' '; + zbx_uint64_pair_t *pair = &hosts.values[i]; + + zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update hosts set"); + + if (0 != (pair->second & ZBX_FLAG_INTERFACE_AGENT)) + { + zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%c" + "available=%d," + "errors_from=0," + "disable_until=0," + "error=''", + delim, HOST_AVAILABLE_UNKNOWN); + delim = ','; + } + + if (0 != (pair->second & ZBX_FLAG_INTERFACE_SNMP)) + { + zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%c" + "snmp_available=%d," + "snmp_errors_from=0," + "snmp_disable_until=0," + "snmp_error=''", + delim, HOST_AVAILABLE_UNKNOWN); + delim = ','; + } + + if (0 != (pair->second & ZBX_FLAG_INTERFACE_IPMI)) + { + zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%c" + "ipmi_available=%d," + "ipmi_errors_from=0," + "ipmi_disable_until=0," + "ipmi_error=''", + delim, HOST_AVAILABLE_UNKNOWN); + delim = ','; + } + + if (0 != (pair->second & ZBX_FLAG_INTERFACE_JMX)) + { + zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%c" + "jmx_available=%d," + "jmx_errors_from=0," + "jmx_disable_until=0," + "jmx_error=''", + delim, HOST_AVAILABLE_UNKNOWN); + } + + zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where hostid=" ZBX_FS_UI64 ";\n", + hosts.values[i].first); + + if (SUCCEED != DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset)) + { + DBrollback(); + goto out; + } + } + + DBend_multiple_update(&sql, &sql_alloc, &sql_offset); + + if (16 < sql_offset && ZBX_DB_OK > DBexecute("%s", sql)) + goto out; + + DBcommit(); +out: + zbx_vector_uint64_pair_destroy(&hosts); + + zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); +} diff --git a/src/libs/zbxdbcache/dbconfig.c b/src/libs/zbxdbcache/dbconfig.c index 0825000abe5..55fd1b9b2da 100644 --- a/src/libs/zbxdbcache/dbconfig.c +++ b/src/libs/zbxdbcache/dbconfig.c @@ -30,10 +30,12 @@ #include "dbcache.h" #include "zbxregexp.h" #include "macrocache.h" +#include "cfg.h" #include "comms.h" #include "../zbxcrypto/tls_tcp_active.h" static int sync_in_progress = 0; + #define LOCK_CACHE if (0 == sync_in_progress) zbx_mutex_lock(&config_lock) #define UNLOCK_CACHE if (0 == sync_in_progress) zbx_mutex_unlock(&config_lock) #define START_SYNC LOCK_CACHE; sync_in_progress = 1 @@ -51,6 +53,11 @@ static int sync_in_progress = 0; #define TRIGGER_FUNCTIONAL_TRUE 0 #define TRIGGER_FUNCTIONAL_FALSE 1 +/* shorthand macro for calling in_maintenance_without_data_collection() */ +#define DCin_maintenance_without_data_collection(dc_host, dc_item) \ + in_maintenance_without_data_collection(dc_host->maintenance_status, \ + dc_host->maintenance_type, dc_item->type) + typedef struct { zbx_uint64_t triggerid; @@ -286,6 +293,11 @@ typedef struct unsigned char ipmi_available; unsigned char jmx_available; unsigned char status; + + /* specifies which interfaces are being used (have enabled items) */ + /* (see ZBX_FLAG_INTERFACE_* defines) */ + unsigned char used_interfaces; + /* 'tls_connect' and 'tls_accept' must be respected even if encryption support is not compiled in */ unsigned char tls_connect; unsigned char tls_accept; @@ -297,6 +309,7 @@ typedef struct } ZBX_DC_HOST; + typedef struct { zbx_uint64_t hostid; @@ -317,6 +330,7 @@ typedef struct int proxy_config_nextcheck; int proxy_data_nextcheck; int timediff; + int lastaccess; unsigned char location; } ZBX_DC_PROXY; @@ -1061,16 +1075,15 @@ static void config_hmacro_remove_index(zbx_hashset_t *hmacro_index, ZBX_DC_HMACR } } -#define DEFAULT_REFRESH_UNSUPPORTED 600 -static const char *default_severity_names[] = {"Not classified", "Information", "Warning", "Average", "High", - "Disaster"}; - static int DCsync_config(DB_RESULT result, int *refresh_unsupported_changed) { + static char *default_severity_names[] = {"Not classified", "Information", "Warning", "Average", "High", "Disaster"}; const char *__function_name = "DCsync_config"; DB_ROW row; int i, found = 1; +#define DEFAULT_REFRESH_UNSUPPORTED 600 + zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); *refresh_unsupported_changed = 0; @@ -1182,6 +1195,8 @@ static int DCsync_config(DB_RESULT result, int *refresh_unsupported_changed) zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); +#undef DEFAULT_REFRESH_UNSUPPORTED + return SUCCEED; } @@ -1349,12 +1364,14 @@ static void DCsync_hosts(DB_RESULT result) /* store new information in host structure */ - host->proxy_hostid = proxy_hostid; + /* reset the used interfaces flag */ + host->used_interfaces = ZBX_FLAG_INTERFACE_NONE; + DCstrpool_replace(found, &host->host, row[2]); DCstrpool_replace(found, &host->name, row[23]); #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) - DCstrpool_replace(found, &host->tls_issuer, row[26]); - DCstrpool_replace(found, &host->tls_subject, row[27]); + DCstrpool_replace(found, &host->tls_issuer, row[27]); + DCstrpool_replace(found, &host->tls_subject, row[28]); /* maintain 'config->psks' in configuration cache */ @@ -1424,7 +1441,7 @@ static void DCsync_hosts(DB_RESULT result) /* Detect errors: PSK identity without PSK value or vice versa. This should have been prevented by */ /* validation in frontend or API. Do not update cache in case of error. */ - if ('\0' != *row[28] && '\0' == *row[29]) + if ('\0' != *row[29] && '\0' == *row[30]) { zabbix_log(LOG_LEVEL_WARNING, "empty PSK for PSK identity \"%s\" configured for host \"%s\"" " (hostid %s)", row[28], row[2], row[0]); @@ -1432,9 +1449,9 @@ static void DCsync_hosts(DB_RESULT result) goto done; } - if ('\0' == *row[28]) /* new PSKid empty */ + if ('\0' == *row[29]) /* new PSKid empty */ { - if ('\0' != *row[29]) + if ('\0' != *row[30]) { zabbix_log(LOG_LEVEL_WARNING, "empty PSK identity with non-empty PSK configured for" " host \"%s\" (hostid %s)", row[2], row[0]); @@ -1475,18 +1492,18 @@ static void DCsync_hosts(DB_RESULT result) if (1 == found && NULL != host->tls_dc_psk) /* 'host' record has non-empty PSK */ { - if (0 == strcmp(host->tls_dc_psk->tls_psk_identity, row[28])) /* new PSKid same as */ + if (0 == strcmp(host->tls_dc_psk->tls_psk_identity, row[29])) /* new PSKid same as */ /* old PSKid */ { - if (0 != strcmp(host->tls_dc_psk->tls_psk, row[29])) /* new PSK value */ + if (0 != strcmp(host->tls_dc_psk->tls_psk, row[30])) /* new PSK value */ /* differs from old */ { if (0 == host->tls_dc_psk->changes++) { /* change underlying PSK value and 'config->psks' is updated, too */ - DCstrpool_replace(1, &host->tls_dc_psk->tls_psk, row[29]); + DCstrpool_replace(1, &host->tls_dc_psk->tls_psk, row[30]); zabbix_log(LOG_LEVEL_WARNING, "PSK value changed for identity \"%s\"", - row[28]); + row[29]); } } @@ -1510,18 +1527,18 @@ static void DCsync_hosts(DB_RESULT result) /* new PSK identity already stored? */ - psk_i_local.tls_psk_identity = row[28]; + psk_i_local.tls_psk_identity = row[29]; if (NULL != (psk_i = zbx_hashset_search(&config->psks, &psk_i_local))) { /* new PSKid already in psks hashset */ - if (0 != strcmp(psk_i->tls_psk, row[29])) /* PSKid stored but PSK value is different */ + if (0 != strcmp(psk_i->tls_psk, row[30])) /* PSKid stored but PSK value is different */ { if (0 == psk_i->changes++) { - DCstrpool_replace(1, &psk_i->tls_psk, row[29]); - zabbix_log(LOG_LEVEL_WARNING, "PSK value changed for identity \"%s\"", row[28]); + DCstrpool_replace(1, &psk_i->tls_psk, row[30]); + zabbix_log(LOG_LEVEL_WARNING, "PSK value changed for identity \"%s\"", row[29]); } } @@ -1532,16 +1549,16 @@ static void DCsync_hosts(DB_RESULT result) /* insert new PSKid and value into psks hashset */ - DCstrpool_replace(0, &psk_i_local.tls_psk_identity, row[28]); - DCstrpool_replace(0, &psk_i_local.tls_psk, row[29]); + DCstrpool_replace(0, &psk_i_local.tls_psk_identity, row[29]); + DCstrpool_replace(0, &psk_i_local.tls_psk, row[30]); psk_i_local.refcount = 1; psk_i_local.changes = 1; psk_i_local.conf = NULL; host->tls_dc_psk = zbx_hashset_insert(&config->psks, &psk_i_local, sizeof(ZBX_DC_PSK)); done: #endif - ZBX_STR2UCHAR(host->tls_connect, row[24]); - ZBX_STR2UCHAR(host->tls_accept, row[25]); + ZBX_STR2UCHAR(host->tls_connect, row[25]); + ZBX_STR2UCHAR(host->tls_accept, row[26]); if (0 == found) { @@ -1567,8 +1584,14 @@ done: { if (HOST_STATUS_MONITORED == status && HOST_STATUS_MONITORED != host->status) host->data_expected_from = now; + + /* reset host status if host proxy assignment has been changed */ + if (proxy_hostid != host->proxy_hostid) + host->used_interfaces = ZBX_FLAG_INTERFACE_UNKNOWN; } + host->proxy_hostid = proxy_hostid; + /* update 'hosts_h' and 'hosts_p' indexes using new data, if not done already */ if (1 == update_index_h) @@ -1635,6 +1658,8 @@ done: zbx_binary_heap_remove_direct(&config->pqueue, proxy->hostid); proxy->location = ZBX_LOC_NOWHERE; } + + proxy->lastaccess = atoi(row[24]); } else if (NULL != (proxy = zbx_hashset_search(&config->proxies, &hostid))) { @@ -2505,11 +2530,34 @@ static void DCsync_items(DB_RESULT result, int refresh_unsupported_changed) item->nextcheck += proxy_timediff + (NULL != proxy); } } + + /* update host's used_interfaces flag */ + if (ZBX_FLAG_INTERFACE_UNKNOWN != host->used_interfaces) + { + switch (type) + { + case ITEM_TYPE_ZABBIX: + host->used_interfaces |= ZBX_FLAG_INTERFACE_AGENT; + break; + case ITEM_TYPE_SNMPv1: + case ITEM_TYPE_SNMPv2c: + case ITEM_TYPE_SNMPv3: + host->used_interfaces |= ZBX_FLAG_INTERFACE_SNMP; + break; + case ITEM_TYPE_IPMI: + host->used_interfaces |= ZBX_FLAG_INTERFACE_IPMI; + break; + case ITEM_TYPE_JMX: + host->used_interfaces |= ZBX_FLAG_INTERFACE_JMX; + break; + } + } } else { item->poller_type = ZBX_NO_POLLER; item->nextcheck = 0; + item->unreachable = 0; } item->delay = delay; @@ -3453,7 +3501,7 @@ void DCsync_configuration(void) "errors_from,available,disable_until,snmp_errors_from," "snmp_available,snmp_disable_until,ipmi_errors_from,ipmi_available," "ipmi_disable_until,jmx_errors_from,jmx_available,jmx_disable_until," - "status,name,tls_connect,tls_accept" + "status,name,lastaccess,tls_connect,tls_accept" ",tls_issuer,tls_subject,tls_psk_identity,tls_psk" " from hosts" " where status in (%d,%d,%d,%d)" @@ -3468,7 +3516,7 @@ void DCsync_configuration(void) "errors_from,available,disable_until,snmp_errors_from," "snmp_available,snmp_disable_until,ipmi_errors_from,ipmi_available," "ipmi_disable_until,jmx_errors_from,jmx_available,jmx_disable_until," - "status,name,tls_connect,tls_accept" + "status,name,lastaccess,tls_connect,tls_accept" " from hosts" " where status in (%d,%d,%d,%d)" " and flags<>%d", @@ -3806,20 +3854,6 @@ out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); } -/****************************************************************************** - * * - * Function: init_configuration_cache * - * * - * Purpose: Allocate shared memory for configuration cache * - * * - * Author: Alexander Vladishev, Aleksandrs Saveljevs * - * * - * Comments: helper functions __config_mem_XXX_func(), __config_XXX_hash, * - * and __config_XXX_compare are only used inside this function * - * for initializing hashset, vector, and heap data structures * - * * - ******************************************************************************/ - static zbx_hash_t __config_item_hk_hash(const void *data) { const ZBX_DC_ITEM_HK *item_hk = (const ZBX_DC_ITEM_HK *)data; @@ -4096,6 +4130,19 @@ static int __config_psk_compare(const void *d1, const void *d2) } #endif +/****************************************************************************** + * * + * Function: init_configuration_cache * + * * + * Purpose: Allocate shared memory for configuration cache * + * * + * Author: Alexander Vladishev, Aleksandrs Saveljevs * + * * + * Comments: helper functions __config_mem_XXX_func(), __config_XXX_hash, * + * and __config_XXX_compare are only used inside this function * + * for initializing hashset, vector, and heap data structures * + * * + ******************************************************************************/ void init_configuration_cache(void) { const char *__function_name = "init_configuration_cache"; @@ -4225,8 +4272,8 @@ void init_configuration_cache(void) config->config = NULL; -#undef CREATE_HASHSET -#undef CREATE_HASHSET_EXT +#undef CREATE_HASHSET +#undef CREATE_HASHSET_EXT zbx_strpool_create(strpool_size); @@ -4310,9 +4357,6 @@ void DCload_config(void) * FAIL otherwise * * * ******************************************************************************/ -#define DCin_maintenance_without_data_collection(dc_host, dc_item) \ - in_maintenance_without_data_collection(dc_host->maintenance_status, \ - dc_host->maintenance_type, dc_item->type) int in_maintenance_without_data_collection(unsigned char maintenance_status, unsigned char maintenance_type, unsigned char type) { @@ -5577,8 +5621,7 @@ int DCconfig_get_poller_nextcheck(unsigned char poller_type) * Purpose: Get array of items for selected poller * * * * Parameters: poller_type - [IN] poller type (ZBX_POLLER_TYPE_...) * - * items - [OUT] array of items * - * max_items - [IN] elements in items array * + * items - [OUT] array of items * * * * Return value: number of items in items array * * * @@ -5588,6 +5631,10 @@ int DCconfig_get_poller_nextcheck(unsigned char poller_type) * always return the items they have taken using DCrequeue_items() * * or DCpoller_requeue_items(). * * * + * Currently batch polling is supported only for JMX, SNMP and * + * icmpping* simple checks. In other cases only single item is * + * retrieved. * + * * ******************************************************************************/ int DCconfig_get_poller_items(unsigned char poller_type, DC_ITEM *items) { @@ -6103,8 +6150,14 @@ int DChost_activate(zbx_host_availability_t *in, zbx_host_availability_t *out) if (NULL == (dc_host = zbx_hashset_search(&config->hosts, &in->hostid))) goto unlock; - if (HOST_STATUS_MONITORED != dc_host->status) + /* Don't try activating host if: */ + /* - (server, proxy) it's not monitored any more; */ + /* - (server) it's monitored by proxy. */ + if ((0 != (program_type & ZBX_PROGRAM_TYPE_SERVER) && 0 != dc_host->proxy_hostid) || + HOST_STATUS_MONITORED != dc_host->status) + { goto unlock; + } DChost_get_availability(dc_host, in->type, in); @@ -6154,8 +6207,14 @@ int DChost_deactivate(const zbx_timespec_t *ts, zbx_host_availability_t *in, zbx if (NULL == (dc_host = zbx_hashset_search(&config->hosts, &in->hostid))) goto unlock; - if (HOST_STATUS_MONITORED != dc_host->status) + /* Don't try deactivating host if: */ + /* - (server, proxy) it's not monitored any more; */ + /* - (server) it's monitored by proxy. */ + if ((0 != (program_type & ZBX_PROGRAM_TYPE_SERVER) && 0 != dc_host->proxy_hostid) || + HOST_STATUS_MONITORED != dc_host->status) + { goto unlock; + } DChost_get_availability(dc_host, in->type, in); *out = *in; @@ -7715,3 +7774,119 @@ void zbx_config_clean(zbx_config_t *cfg) } } +/****************************************************************************** + * * + * Function: DCreset_hosts_availability * + * * + * Purpose: resets host availability for disabled hosts and hosts without * + * enabled items for the corresponding interface * + * * + * Parameters: hosts - [OUT] a vector of hostid,reset_flags pairs containing * + * host availability reset data (sorted by hostid) * + * * + * Return value: SUCCEED - host availability was reset for at least one host * + * FAIL - no hosts required availability reset * + * * + * Comments: This function resets host availability in configuration cache. * + * The caller must perform corresponding database updates based * + * on returned host availability reset data. On server the function * + * skips hosts handled by proxies. * + * * + ******************************************************************************/ +int DCreset_hosts_availability(zbx_vector_uint64_pair_t *hosts) +{ + const char *__function_name = "DCreset_hosts_availability"; + zbx_uint64_pair_t pair; + ZBX_DC_HOST *host; + zbx_hashset_iter_t iter; + int now; + + zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); + + now = time(NULL); + + LOCK_CACHE; + + zbx_hashset_iter_reset(&config->hosts, &iter); + + while (NULL != (host = (ZBX_DC_HOST *)zbx_hashset_iter_next(&iter))) + { + /* On server skip hosts handled by proxies. They are handled directly */ + /* when receiving hosts' availability data from proxies. */ + /* Unless a host was just (re)assigned to a proxy or the proxy has */ + /* not updated its status during the maximum proxy heartbeat period. */ + /* In this case reset all interfaces to unknown status. */ + if (0 != (program_type & ZBX_PROGRAM_TYPE_SERVER) && 0 != host->proxy_hostid) + { + if (ZBX_FLAG_INTERFACE_UNKNOWN != host->used_interfaces) + { + ZBX_DC_PROXY *proxy; + + if (NULL != (proxy = zbx_hashset_search(&config->proxies, &host->proxy_hostid))) + { + /* SEC_PER_MIN is a tolerance interval, it was chosen arbitrarily */ + if (ZBX_PROXY_HEARTBEAT_FREQUENCY_MAX + SEC_PER_MIN >= now - proxy->lastaccess) + continue; + } + host->used_interfaces = ZBX_FLAG_INTERFACE_UNKNOWN; + } + } + + pair.second = ZBX_FLAG_INTERFACE_NONE; + + if (0 == (host->used_interfaces & ZBX_FLAG_INTERFACE_AGENT) && + HOST_AVAILABLE_UNKNOWN != host->available) + { + pair.second |= ZBX_FLAG_INTERFACE_AGENT; + + host->available = HOST_AVAILABLE_UNKNOWN; + host->errors_from = 0; + host->disable_until = 0; + } + + if (0 == (host->used_interfaces & ZBX_FLAG_INTERFACE_SNMP) && + HOST_AVAILABLE_UNKNOWN != host->snmp_available) + { + pair.second |= ZBX_FLAG_INTERFACE_SNMP; + + host->snmp_available = HOST_AVAILABLE_UNKNOWN; + host->snmp_errors_from = 0; + host->snmp_disable_until = 0; + } + + if (0 == (host->used_interfaces & ZBX_FLAG_INTERFACE_IPMI) && + HOST_AVAILABLE_UNKNOWN != host->ipmi_available) + { + pair.second |= ZBX_FLAG_INTERFACE_IPMI; + + host->ipmi_available = HOST_AVAILABLE_UNKNOWN; + host->ipmi_errors_from = 0; + host->ipmi_disable_until = 0; + } + + if (0 == (host->used_interfaces & ZBX_FLAG_INTERFACE_JMX) && + HOST_AVAILABLE_UNKNOWN != host->jmx_available) + { + pair.second |= ZBX_FLAG_INTERFACE_JMX; + + + host->jmx_available = HOST_AVAILABLE_UNKNOWN; + host->jmx_errors_from = 0; + host->jmx_disable_until = 0; + } + + if (ZBX_FLAG_INTERFACE_NONE != pair.second) + { + pair.first = host->hostid; + zbx_vector_uint64_pair_append_ptr(hosts, &pair); + } + } + + UNLOCK_CACHE; + + zbx_vector_uint64_pair_sort(hosts, ZBX_DEFAULT_UINT64_COMPARE_FUNC); + + zabbix_log(LOG_LEVEL_DEBUG, "End of %s() hosts:%d", __function_name, hosts->values_num); + + return 0 == hosts->values_num ? FAIL : SUCCEED; +} diff --git a/src/libs/zbxdbhigh/itservices.c b/src/libs/zbxdbhigh/itservices.c index baebf895d54..bc15d9ac41b 100644 --- a/src/libs/zbxdbhigh/itservices.c +++ b/src/libs/zbxdbhigh/itservices.c @@ -721,8 +721,9 @@ int DBupdate_itservices(const DB_EVENT *events, size_t events_num) { const char *__function_name = "DBupdate_itservices"; - int i, ret = SUCCEED; + int ret = SUCCEED; zbx_vector_ptr_t updates; + size_t i; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); diff --git a/src/libs/zbxdbhigh/proxy.c b/src/libs/zbxdbhigh/proxy.c index 2eeb6a99901..05694e9f2d7 100644 --- a/src/libs/zbxdbhigh/proxy.c +++ b/src/libs/zbxdbhigh/proxy.c @@ -1371,7 +1371,10 @@ void process_proxyconfig(struct zbx_json_parse *jp_data) (NULL == error ? "database error" : error)); } else + { DCsync_configuration(); + DCupdate_hosts_availability(); + } zbx_free(error); @@ -1709,7 +1712,8 @@ void process_host_availability(struct zbx_json_parse *jp) DBcommit(); - DChost_update_availability(availability, availability_num); + if (NULL != availability) + DChost_update_availability(availability, availability_num); out: zbx_free(availability); zbx_free(tmp); diff --git a/src/libs/zbxnix/dshm.c b/src/libs/zbxnix/dshm.c index 4202c3f3906..951a030b9ed 100644 --- a/src/libs/zbxnix/dshm.c +++ b/src/libs/zbxnix/dshm.c @@ -52,7 +52,8 @@ int zbx_dshm_create(zbx_dshm_t *shm, int proj_id, size_t shm_size, ZBX_MUTEX_NAM key_t shm_key; int ret = FAIL; - zabbix_log(LOG_LEVEL_DEBUG, "In %s(): proj_id:%d size:" ZBX_FS_SIZE_T, __function_name, proj_id, shm_size); + zabbix_log(LOG_LEVEL_DEBUG, "In %s() proj_id:%d size:" ZBX_FS_SIZE_T, __function_name, proj_id, + (zbx_fs_size_t)shm_size); if (FAIL == zbx_mutex_create_force(&shm->lock, mutex)) { @@ -83,7 +84,7 @@ int zbx_dshm_create(zbx_dshm_t *shm, int proj_id, size_t shm_size, ZBX_MUTEX_NAM ret = SUCCEED; out: - zabbix_log(LOG_LEVEL_DEBUG, "End of %s(): %s shmid:%d", __function_name, zbx_result_string(ret), shm->shmid); + zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s shmid:%d", __function_name, zbx_result_string(ret), shm->shmid); return ret; } @@ -108,7 +109,7 @@ int zbx_dshm_destroy(zbx_dshm_t *shm, char **errmsg) const char *__function_name = "zbx_dshm_destroy"; int ret = FAIL; - zabbix_log(LOG_LEVEL_DEBUG, "In %s(): shmid:%d", __function_name, shm->shmid); + zabbix_log(LOG_LEVEL_DEBUG, "In %s() shmid:%d", __function_name, shm->shmid); zbx_mutex_destroy(&shm->lock); @@ -124,7 +125,7 @@ int zbx_dshm_destroy(zbx_dshm_t *shm, char **errmsg) ret = SUCCEED; out: - zabbix_log(LOG_LEVEL_DEBUG, "End of %s(): %s", __function_name, zbx_result_string(ret)); + zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; } @@ -176,7 +177,7 @@ int zbx_dshm_validate_ref(const zbx_dshm_t *shm, zbx_dshm_ref_t *shm_ref, char * const char *__function_name = "zbx_dshm_validate_ref"; int ret = FAIL; - zabbix_log(LOG_LEVEL_TRACE, "In %s(): shmid:%d refid:%d", __function_name, shm->shmid, shm_ref->shmid); + zabbix_log(LOG_LEVEL_TRACE, "In %s() shmid:%d refid:%d", __function_name, shm->shmid, shm_ref->shmid); if (shm->shmid != shm_ref->shmid) { @@ -203,7 +204,7 @@ int zbx_dshm_validate_ref(const zbx_dshm_t *shm, zbx_dshm_ref_t *shm_ref, char * ret = SUCCEED; out: - zabbix_log(LOG_LEVEL_TRACE, "End of %s(): %s", __function_name, zbx_result_string(ret)); + zabbix_log(LOG_LEVEL_TRACE, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; } @@ -236,7 +237,8 @@ int zbx_dshm_realloc(zbx_dshm_t *shm, size_t size, char **errmsg) void *addr, *addr_old = NULL; size_t shm_size; - zabbix_log(LOG_LEVEL_DEBUG, "In %s(): shmid:%d size:" ZBX_FS_SIZE_T, __function_name, shm->shmid, size); + zabbix_log(LOG_LEVEL_DEBUG, "In %s() shmid:%d size:" ZBX_FS_SIZE_T, __function_name, shm->shmid, + (zbx_fs_size_t)size); /* Create the new shared memory segment. The same key is used. */ if (-1 == (shm_key = zbx_ftok(CONFIG_FILE, shm->proj_id))) @@ -295,8 +297,7 @@ int zbx_dshm_realloc(zbx_dshm_t *shm, size_t size, char **errmsg) ret = SUCCEED; out: - zabbix_log(LOG_LEVEL_DEBUG, "End of %s(): shmid:%d %s", __function_name, shm->shmid, zbx_result_string(ret)); + zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s shmid:%d", __function_name, zbx_result_string(ret), shm->shmid); return ret; } - diff --git a/src/libs/zbxsysinfo/aix/diskspace.c b/src/libs/zbxsysinfo/aix/diskspace.c index e9b93242921..06002f61672 100644 --- a/src/libs/zbxsysinfo/aix/diskspace.c +++ b/src/libs/zbxsysinfo/aix/diskspace.c @@ -48,6 +48,11 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f return SYSINFO_RET_FAIL; } + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; @@ -60,8 +65,7 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pfree = 0; } @@ -69,8 +73,7 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pused = 0; } @@ -124,7 +127,6 @@ static int VFS_FS_TOTAL(const char *fs, AGENT_RESULT *result) SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; - } static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) @@ -162,7 +164,6 @@ static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { char *fsname, *mode; - int ret = SYSINFO_RET_FAIL; if (2 < request->nparam) { @@ -179,32 +180,29 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) - ret = VFS_FS_TOTAL(fsname, result); - else if (0 == strcmp(mode, "free")) - ret = VFS_FS_FREE(fsname, result); - else if (0 == strcmp(mode, "pfree")) - ret = VFS_FS_PFREE(fsname, result); - else if (0 == strcmp(mode, "used")) - ret = VFS_FS_USED(fsname, result); - else if (0 == strcmp(mode, "pused")) - ret = VFS_FS_PUSED(fsname, result); - else - { - SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return SYSINFO_RET_FAIL; - } + if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) /* default parameter */ + return VFS_FS_TOTAL(fsname, result); + if (0 == strcmp(mode, "free")) + return VFS_FS_FREE(fsname, result); + if (0 == strcmp(mode, "pfree")) + return VFS_FS_PFREE(fsname, result); + if (0 == strcmp(mode, "used")) + return VFS_FS_USED(fsname, result); + if (0 == strcmp(mode, "pused")) + return VFS_FS_PUSED(fsname, result); - return ret; + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); + + return SYSINFO_RET_FAIL; } static const char *zbx_get_vfs_name_by_type(int type) { extern struct vfs_ent *getvfsbytype(int type); - struct vfs_ent *vfs; - static char **vfs_names = NULL; - static size_t vfs_names_alloc = 0; + struct vfs_ent *vfs; + static char **vfs_names = NULL; + static size_t vfs_names_alloc = 0; if (type + 1 > vfs_names_alloc) { diff --git a/src/libs/zbxsysinfo/freebsd/diskspace.c b/src/libs/zbxsysinfo/freebsd/diskspace.c index 9e871bea88e..66c862dde5c 100644 --- a/src/libs/zbxsysinfo/freebsd/diskspace.c +++ b/src/libs/zbxsysinfo/freebsd/diskspace.c @@ -40,25 +40,32 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f return SYSINFO_RET_FAIL; } - if (total) + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; - if (free) + + if (NULL != free) *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; - if (used) + + if (NULL != used) *used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE; - if (pfree) + + if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pfree = 0; } - if (pused) + + if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pused = 0; } @@ -112,7 +119,6 @@ static int VFS_FS_TOTAL(const char *fs, AGENT_RESULT *result) SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; - } static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) @@ -150,7 +156,6 @@ static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { char *fsname, *mode; - int ret = SYSINFO_RET_FAIL; if (2 < request->nparam) { @@ -167,24 +172,20 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - /* default parameter */ - if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) - ret = VFS_FS_TOTAL(fsname, result); - else if (0 == strcmp(mode, "free")) - ret = VFS_FS_FREE(fsname, result); - else if (0 == strcmp(mode, "pfree")) - ret = VFS_FS_PFREE(fsname, result); - else if (0 == strcmp(mode, "used")) - ret = VFS_FS_USED(fsname, result); - else if (0 == strcmp(mode, "pused")) - ret = VFS_FS_PUSED(fsname, result); - else - { - SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return SYSINFO_RET_FAIL; - } + if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) /* default parameter */ + return VFS_FS_TOTAL(fsname, result); + if (0 == strcmp(mode, "free")) + return VFS_FS_FREE(fsname, result); + if (0 == strcmp(mode, "pfree")) + return VFS_FS_PFREE(fsname, result); + if (0 == strcmp(mode, "used")) + return VFS_FS_USED(fsname, result); + if (0 == strcmp(mode, "pused")) + return VFS_FS_PUSED(fsname, result); + + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return ret; + return SYSINFO_RET_FAIL; } int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) diff --git a/src/libs/zbxsysinfo/hpux/diskspace.c b/src/libs/zbxsysinfo/hpux/diskspace.c index bc762490e81..3629b883773 100644 --- a/src/libs/zbxsysinfo/hpux/diskspace.c +++ b/src/libs/zbxsysinfo/hpux/diskspace.c @@ -40,25 +40,32 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f return SYSINFO_RET_FAIL; } - if (total) + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; - if (free) + + if (NULL != free) *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; - if (used) + + if (NULL != used) *used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE; - if (pfree) + + if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pfree = 0; } - if (pused) + + if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pused = 0; } @@ -112,7 +119,6 @@ static int VFS_FS_TOTAL(const char *fs, AGENT_RESULT *result) SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; - } static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) @@ -150,7 +156,6 @@ static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { char *fsname, *mode; - int ret = SYSINFO_RET_FAIL; if (2 < request->nparam) { @@ -167,23 +172,20 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) - ret = VFS_FS_TOTAL(fsname, result); - else if (0 == strcmp(mode, "free")) - ret = VFS_FS_FREE(fsname, result); - else if (0 == strcmp(mode, "pfree")) - ret = VFS_FS_PFREE(fsname, result); - else if (0 == strcmp(mode, "used")) - ret = VFS_FS_USED(fsname, result); - else if (0 == strcmp(mode, "pused")) - ret = VFS_FS_PUSED(fsname, result); - else - { - SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return SYSINFO_RET_FAIL; - } + if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) /* default parameter */ + return VFS_FS_TOTAL(fsname, result); + if (0 == strcmp(mode, "free")) + return VFS_FS_FREE(fsname, result); + if (0 == strcmp(mode, "pfree")) + return VFS_FS_PFREE(fsname, result); + if (0 == strcmp(mode, "used")) + return VFS_FS_USED(fsname, result); + if (0 == strcmp(mode, "pused")) + return VFS_FS_PUSED(fsname, result); + + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return ret; + return SYSINFO_RET_FAIL; } int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) diff --git a/src/libs/zbxsysinfo/linux/diskspace.c b/src/libs/zbxsysinfo/linux/diskspace.c index 5008d6da97c..5ba40ba254f 100644 --- a/src/libs/zbxsysinfo/linux/diskspace.c +++ b/src/libs/zbxsysinfo/linux/diskspace.c @@ -22,7 +22,7 @@ #include "zbxjson.h" #include "log.h" -static int get_fs_size_stat(const char *fsname, zbx_uint64_t *total, zbx_uint64_t *free, +static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *free, zbx_uint64_t *used, double *pfree, double *pused, char **error) { #ifdef HAVE_SYS_STATVFS_H @@ -34,37 +34,44 @@ static int get_fs_size_stat(const char *fsname, zbx_uint64_t *total, zbx_uint64_ #endif struct ZBX_STATFS s; - if (NULL == fsname || '\0' == *fsname) + if (NULL == fs || '\0' == *fs) { *error = zbx_strdup(NULL, "Filesystem name cannot be empty."); return SYSINFO_RET_FAIL; } - if (0 != ZBX_STATFS(fsname, &s)) + if (0 != ZBX_STATFS(fs, &s)) { *error = zbx_dsprintf(NULL, "Cannot obtain filesystem information: %s", zbx_strerror(errno)); return SYSINFO_RET_FAIL; } - if (total) + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; - if (free) + + if (NULL != free) *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; - if (used) + + if (NULL != used) *used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE; - if (pfree) + + if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pfree = 0; } - if (pused) + + if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pused = 0; } diff --git a/src/libs/zbxsysinfo/linux/proc.c b/src/libs/zbxsysinfo/linux/proc.c index 087db018dd8..20521e9cbfc 100644 --- a/src/libs/zbxsysinfo/linux/proc.c +++ b/src/libs/zbxsysinfo/linux/proc.c @@ -23,6 +23,8 @@ #include "log.h" #include "stats.h" +extern int CONFIG_TIMEOUT; + typedef struct { pid_t pid; @@ -1328,8 +1330,9 @@ int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result) { const char *procname, *username, *cmdline, *tmp; char *errmsg = NULL; - int period, type, ret; + int period, type; double value; + zbx_timespec_t ts_timeout, ts; /* proc.cpu.util[<procname>,<username>,(user|system),<cmdline>,(avg1|avg5|avg15)] */ /* 0 1 2 3 4 */ @@ -1394,7 +1397,10 @@ int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (SUCCEED != (ret = zbx_procstat_get_util(procname, username, cmdline, 0, period, type, &value, &errmsg))) + zbx_timespec(&ts_timeout); + ts_timeout.sec += CONFIG_TIMEOUT; + + while (SUCCEED != zbx_procstat_get_util(procname, username, cmdline, 0, period, type, &value, &errmsg)) { /* zbx_procstat_get_* functions will return FAIL when either a collection */ /* error was registered or if less than 2 data samples were collected. */ @@ -1404,9 +1410,19 @@ int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result) SET_MSG_RESULT(result, errmsg); return SYSINFO_RET_FAIL; } + + zbx_timespec(&ts); + + if (0 > zbx_timespec_compare(&ts_timeout, &ts)) + { + SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while waiting for collector data.")); + return SYSINFO_RET_FAIL; + } + + sleep(1); } - else - SET_DBL_RESULT(result, value); + + SET_DBL_RESULT(result, value); return SYSINFO_RET_OK; } diff --git a/src/libs/zbxsysinfo/netbsd/diskspace.c b/src/libs/zbxsysinfo/netbsd/diskspace.c index 91409340cb2..39c697d5ad7 100644 --- a/src/libs/zbxsysinfo/netbsd/diskspace.c +++ b/src/libs/zbxsysinfo/netbsd/diskspace.c @@ -40,25 +40,32 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f return SYSINFO_RET_FAIL; } - if (total) + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; - if (free) + + if (NULL != free) *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; - if (used) + + if (NULL != used) *used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE; - if (pfree) + + if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pfree = 0; } - if (pused) + + if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pused = 0; } @@ -112,7 +119,6 @@ static int VFS_FS_TOTAL(const char *fs, AGENT_RESULT *result) SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; - } static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) @@ -150,7 +156,6 @@ static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { char *fsname, *mode; - int ret = SYSINFO_RET_FAIL; if (2 < request->nparam) { @@ -167,23 +172,20 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) - ret = VFS_FS_TOTAL(fsname, result); - else if (0 == strcmp(mode, "free")) - ret = VFS_FS_FREE(fsname, result); - else if (0 == strcmp(mode, "used")) - ret = VFS_FS_USED(fsname, result); - else if (0 == strcmp(mode, "pfree")) - ret = VFS_FS_PFREE(fsname, result); - else if (0 == strcmp(mode, "pused")) - ret = VFS_FS_PUSED(fsname, result); - else - { - SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return SYSINFO_RET_FAIL; - } + if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) /* default parameter */ + return VFS_FS_TOTAL(fsname, result); + if (0 == strcmp(mode, "free")) + return VFS_FS_FREE(fsname, result); + if (0 == strcmp(mode, "pfree")) + return VFS_FS_PFREE(fsname, result); + if (0 == strcmp(mode, "used")) + return VFS_FS_USED(fsname, result); + if (0 == strcmp(mode, "pused")) + return VFS_FS_PUSED(fsname, result); + + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return ret; + return SYSINFO_RET_FAIL; } int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) diff --git a/src/libs/zbxsysinfo/openbsd/diskspace.c b/src/libs/zbxsysinfo/openbsd/diskspace.c index 2444cb92b67..66c862dde5c 100644 --- a/src/libs/zbxsysinfo/openbsd/diskspace.c +++ b/src/libs/zbxsysinfo/openbsd/diskspace.c @@ -40,25 +40,32 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f return SYSINFO_RET_FAIL; } - if (total) + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; - if (free) + + if (NULL != free) *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; - if (used) + + if (NULL != used) *used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE; - if (pfree) + + if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pfree = 0; } - if (pused) + + if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pused = 0; } @@ -112,7 +119,6 @@ static int VFS_FS_TOTAL(const char *fs, AGENT_RESULT *result) SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; - } static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) @@ -150,7 +156,6 @@ static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { char *fsname, *mode; - int ret = SYSINFO_RET_FAIL; if (2 < request->nparam) { @@ -167,23 +172,20 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) - ret = VFS_FS_TOTAL(fsname, result); - else if (0 == strcmp(mode, "free")) - ret = VFS_FS_FREE(fsname, result); - else if (0 == strcmp(mode, "used")) - ret = VFS_FS_USED(fsname, result); - else if (0 == strcmp(mode, "pfree")) - ret = VFS_FS_PFREE(fsname, result); - else if (0 == strcmp(mode, "pused")) - ret = VFS_FS_PUSED(fsname, result); - else - { - SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return SYSINFO_RET_FAIL; - } + if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) /* default parameter */ + return VFS_FS_TOTAL(fsname, result); + if (0 == strcmp(mode, "free")) + return VFS_FS_FREE(fsname, result); + if (0 == strcmp(mode, "pfree")) + return VFS_FS_PFREE(fsname, result); + if (0 == strcmp(mode, "used")) + return VFS_FS_USED(fsname, result); + if (0 == strcmp(mode, "pused")) + return VFS_FS_PUSED(fsname, result); + + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return ret; + return SYSINFO_RET_FAIL; } int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) diff --git a/src/libs/zbxsysinfo/osf/diskspace.c b/src/libs/zbxsysinfo/osf/diskspace.c index 3d4160bebf5..b32962b05d6 100644 --- a/src/libs/zbxsysinfo/osf/diskspace.c +++ b/src/libs/zbxsysinfo/osf/diskspace.c @@ -39,25 +39,32 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f return SYSINFO_RET_FAIL; } - if (total) + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; - if (free) + + if (NULL != free) *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; - if (used) + + if (NULL != used) *used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE; - if (pfree) + + if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pfree = 0; } - if (pused) + + if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pused = 0; } @@ -148,7 +155,6 @@ static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { char *fsname, *mode; - int ret = SYSINFO_RET_FAIL; if (2 < request->nparam) { @@ -156,8 +162,8 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - fsname = get_nparam(request, 0); - mode = get_nparam(request, 1); + fsname = get_rparam(request, 0); + mode = get_rparam(request, 1); if (NULL == fsname || '\0' == *fsname) { @@ -165,21 +171,18 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) - ret = VFS_FS_TOTAL(fsname, result); - else if (0 == strcmp(mode, "free")) - ret = VFS_FS_FREE(fsname, result); - else if (0 == strcmp(mode, "used")) - ret = VFS_FS_USED(fsname, result); - else if (0 == strcmp(mode, "pfree")) - ret = VFS_FS_PFREE(fsname, result); - else if (0 == strcmp(mode, "pused")) - ret = VFS_FS_PUSED(fsname, result); - else - { - SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return SYSINFO_RET_FAIL; - } + if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) /* default parameter */ + return VFS_FS_TOTAL(fsname, result); + if (0 == strcmp(mode, "free")) + return VFS_FS_FREE(fsname, result); + if (0 == strcmp(mode, "pfree")) + return VFS_FS_PFREE(fsname, result); + if (0 == strcmp(mode, "used")) + return VFS_FS_USED(fsname, result); + if (0 == strcmp(mode, "pused")) + return VFS_FS_PUSED(fsname, result); + + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return ret; + return SYSINFO_RET_FAIL; } diff --git a/src/libs/zbxsysinfo/osx/diskspace.c b/src/libs/zbxsysinfo/osx/diskspace.c index 1288a0b88a0..66c862dde5c 100644 --- a/src/libs/zbxsysinfo/osx/diskspace.c +++ b/src/libs/zbxsysinfo/osx/diskspace.c @@ -22,10 +22,8 @@ #include "zbxjson.h" #include "log.h" -static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, - zbx_uint64_t *used, double *pused, - zbx_uint64_t *free, double *pfree, - char **error) +static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *free, + zbx_uint64_t *used, double *pfree, double *pused, char **error) { #ifdef HAVE_SYS_STATVFS_H # define ZBX_STATFS statvfs @@ -42,111 +40,115 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, return SYSINFO_RET_FAIL; } + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; + if (NULL != free) + *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; + if (NULL != used) *used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE; - if (NULL != pused) + if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else - *pused = 0; + *pfree = 0; } - if (NULL != free) - *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; - - if (NULL != pfree) + if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else - *pfree = 0; + *pused = 0; } return SYSINFO_RET_OK; } -static int VFS_FS_TOTAL(const char *fs, AGENT_RESULT *result) +static int VFS_FS_USED(const char *fs, AGENT_RESULT *result) { - zbx_uint64_t total; + zbx_uint64_t value; char *error; - if (SYSINFO_RET_OK != get_fs_size_stat(fs, &total, NULL, NULL, NULL, NULL, &error)) + if (SYSINFO_RET_OK != get_fs_size_stat(fs, NULL, NULL, &value, NULL, NULL, &error)) { SET_MSG_RESULT(result, error); return SYSINFO_RET_FAIL; } - SET_UI64_RESULT(result, total); + SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; - } -static int VFS_FS_USED(const char *fs, AGENT_RESULT *result) +static int VFS_FS_FREE(const char *fs, AGENT_RESULT *result) { - zbx_uint64_t used; + zbx_uint64_t value; char *error; - if (SYSINFO_RET_OK != get_fs_size_stat(fs, NULL, &used, NULL, NULL, NULL, &error)) + if (SYSINFO_RET_OK != get_fs_size_stat(fs, NULL, &value, NULL, NULL, NULL, &error)) { SET_MSG_RESULT(result, error); return SYSINFO_RET_FAIL; } - SET_UI64_RESULT(result, used); + SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; } -static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) +static int VFS_FS_TOTAL(const char *fs, AGENT_RESULT *result) { - double pused; - char *error; + zbx_uint64_t value; + char *error; - if (SYSINFO_RET_OK != get_fs_size_stat(fs, NULL, NULL, &pused, NULL, NULL, &error)) + if (SYSINFO_RET_OK != get_fs_size_stat(fs, &value, NULL, NULL, NULL, NULL, &error)) { SET_MSG_RESULT(result, error); return SYSINFO_RET_FAIL; } - SET_DBL_RESULT(result, pused); + SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; } -static int VFS_FS_FREE(const char *fs, AGENT_RESULT *result) +static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) { - zbx_uint64_t free; - char *error; + double value; + char *error; - if (SYSINFO_RET_OK != get_fs_size_stat(fs, NULL, NULL, NULL, &free, NULL, &error)) + if (SYSINFO_RET_OK != get_fs_size_stat(fs, NULL, NULL, NULL, &value, NULL, &error)) { SET_MSG_RESULT(result, error); return SYSINFO_RET_FAIL; } - SET_UI64_RESULT(result, free); + SET_DBL_RESULT(result, value); return SYSINFO_RET_OK; } -static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) +static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) { - double pfree; + double value; char *error; - if (SYSINFO_RET_OK != get_fs_size_stat(fs, NULL, NULL, NULL, NULL, &pfree, &error)) + if (SYSINFO_RET_OK != get_fs_size_stat(fs, NULL, NULL, NULL, NULL, &value, &error)) { SET_MSG_RESULT(result, error); return SYSINFO_RET_FAIL; } - SET_DBL_RESULT(result, pfree); + SET_DBL_RESULT(result, value); return SYSINFO_RET_OK; } @@ -154,7 +156,6 @@ static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { char *fsname, *mode; - int ret; if (2 < request->nparam) { @@ -171,23 +172,20 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) - ret = VFS_FS_TOTAL(fsname, result); - else if (0 == strcmp(mode, "used")) - ret = VFS_FS_USED(fsname, result); - else if (0 == strcmp(mode, "pused")) - ret = VFS_FS_PUSED(fsname, result); - else if (0 == strcmp(mode, "free")) - ret = VFS_FS_FREE(fsname, result); - else if (0 == strcmp(mode, "pfree")) - ret = VFS_FS_PFREE(fsname, result); - else - { - SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return SYSINFO_RET_FAIL; - } + if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) /* default parameter */ + return VFS_FS_TOTAL(fsname, result); + if (0 == strcmp(mode, "free")) + return VFS_FS_FREE(fsname, result); + if (0 == strcmp(mode, "pfree")) + return VFS_FS_PFREE(fsname, result); + if (0 == strcmp(mode, "used")) + return VFS_FS_USED(fsname, result); + if (0 == strcmp(mode, "pused")) + return VFS_FS_PUSED(fsname, result); + + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return ret; + return SYSINFO_RET_FAIL; } int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) diff --git a/src/libs/zbxsysinfo/solaris/diskspace.c b/src/libs/zbxsysinfo/solaris/diskspace.c index e46e2e213b8..4d60238e536 100644 --- a/src/libs/zbxsysinfo/solaris/diskspace.c +++ b/src/libs/zbxsysinfo/solaris/diskspace.c @@ -44,25 +44,32 @@ static int get_fs_size_stat(const char *fs, zbx_uint64_t *total, zbx_uint64_t *f return SYSINFO_RET_FAIL; } - if (total) + /* Available space could be negative (top bit set) if we hit disk space */ + /* reserved for non-privileged users. Treat it as 0. */ + if (0 != ZBX_IS_TOP_BIT_SET(s.f_bavail)) + s.f_bavail = 0; + + if (NULL != total) *total = (zbx_uint64_t)s.f_blocks * s.ZBX_BSIZE; - if (free) + + if (NULL != free) *free = (zbx_uint64_t)s.f_bavail * s.ZBX_BSIZE; - if (used) + + if (NULL != used) *used = (zbx_uint64_t)(s.f_blocks - s.f_bfree) * s.ZBX_BSIZE; - if (pfree) + + if (NULL != pfree) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pfree = (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pfree = (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pfree = 0; } - if (pused) + + if (NULL != pused) { if (0 != s.f_blocks - s.f_bfree + s.f_bavail) - *pused = 100.0 - (double)(100.0 * s.f_bavail) / - (s.f_blocks - s.f_bfree + s.f_bavail); + *pused = 100.0 - (double)(100.0 * s.f_bavail) / (s.f_blocks - s.f_bfree + s.f_bavail); else *pused = 0; } @@ -116,7 +123,6 @@ static int VFS_FS_TOTAL(const char *fs, AGENT_RESULT *result) SET_UI64_RESULT(result, value); return SYSINFO_RET_OK; - } static int VFS_FS_PFREE(const char *fs, AGENT_RESULT *result) @@ -154,7 +160,6 @@ static int VFS_FS_PUSED(const char *fs, AGENT_RESULT *result) int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) { char *fsname, *mode; - int ret; if (2 < request->nparam) { @@ -171,23 +176,20 @@ int VFS_FS_SIZE(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) - ret = VFS_FS_TOTAL(fsname, result); - else if (0 == strcmp(mode, "free")) - ret = VFS_FS_FREE(fsname, result); - else if (0 == strcmp(mode, "used")) - ret = VFS_FS_USED(fsname, result); - else if (0 == strcmp(mode, "pfree")) - ret = VFS_FS_PFREE(fsname, result); - else if (0 == strcmp(mode, "pused")) - ret = VFS_FS_PUSED(fsname, result); - else - { - SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return SYSINFO_RET_FAIL; - } + if (NULL == mode || '\0' == *mode || 0 == strcmp(mode, "total")) /* default parameter */ + return VFS_FS_TOTAL(fsname, result); + if (0 == strcmp(mode, "free")) + return VFS_FS_FREE(fsname, result); + if (0 == strcmp(mode, "pfree")) + return VFS_FS_PFREE(fsname, result); + if (0 == strcmp(mode, "used")) + return VFS_FS_USED(fsname, result); + if (0 == strcmp(mode, "pused")) + return VFS_FS_PUSED(fsname, result); + + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter.")); - return ret; + return SYSINFO_RET_FAIL; } int VFS_FS_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result) diff --git a/src/libs/zbxsysinfo/solaris/proc.c b/src/libs/zbxsysinfo/solaris/proc.c index b4943e4a26d..d8ce249d682 100644 --- a/src/libs/zbxsysinfo/solaris/proc.c +++ b/src/libs/zbxsysinfo/solaris/proc.c @@ -29,6 +29,8 @@ #include "log.h" #include "stats.h" +extern int CONFIG_TIMEOUT; + typedef struct { pid_t pid; @@ -669,9 +671,10 @@ int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result) { const char *procname, *username, *cmdline, *tmp, *flags; char *errmsg = NULL; - int period, type, ret; + int period, type; double value; zbx_uint64_t zoneflag; + zbx_timespec_t ts_timeout, ts; /* proc.cpu.util[<procname>,<username>,(user|system),<cmdline>,(avg1|avg5|avg15)] */ if (6 < request->nparam) @@ -757,8 +760,10 @@ int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result) return SYSINFO_RET_FAIL; } - if (SUCCEED != (ret = zbx_procstat_get_util(procname, username, cmdline, zoneflag, period, type, &value, - &errmsg))) + zbx_timespec(&ts_timeout); + ts_timeout.sec += CONFIG_TIMEOUT; + + while (SUCCEED != zbx_procstat_get_util(procname, username, cmdline, zoneflag, period, type, &value, &errmsg)) { /* zbx_procstat_get_* functions will return FAIL when either a collection */ /* error was registered or if less than 2 data samples were collected. */ @@ -768,9 +773,19 @@ int PROC_CPU_UTIL(AGENT_REQUEST *request, AGENT_RESULT *result) SET_MSG_RESULT(result, errmsg); return SYSINFO_RET_FAIL; } + + zbx_timespec(&ts); + + if (0 > zbx_timespec_compare(&ts_timeout, &ts)) + { + SET_MSG_RESULT(result, zbx_strdup(NULL, "Timeout while waiting for collector data.")); + return SYSINFO_RET_FAIL; + } + + sleep(1); } - else - SET_DBL_RESULT(result, value); + + SET_DBL_RESULT(result, value); return SYSINFO_RET_OK; } diff --git a/src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java b/src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java index 55bcd7c3cb1..4b11c3e9911 100644 --- a/src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java +++ b/src/zabbix_java/src/com/zabbix/gateway/GeneralInformation.java @@ -22,9 +22,9 @@ package com.zabbix.gateway; class GeneralInformation { public static final String APPLICATION_NAME = "Zabbix Java Gateway"; - public static final String REVISION_DATE = "15 October 2015"; + public static final String REVISION_DATE = "6 November 2015"; public static final String REVISION = "{ZABBIX_REVISION}"; - public static final String VERSION = "3.0.0alpha4"; + public static final String VERSION = "3.0.0alpha5"; public static void printVersion() { diff --git a/src/zabbix_proxy/proxy.c b/src/zabbix_proxy/proxy.c index c0a855c9ebb..40a4d985d3b 100644 --- a/src/zabbix_proxy/proxy.c +++ b/src/zabbix_proxy/proxy.c @@ -569,7 +569,7 @@ static void zbx_load_config(void) {"ProxyOfflineBuffer", &CONFIG_PROXY_OFFLINE_BUFFER, TYPE_INT, PARM_OPT, 1, 720}, {"HeartbeatFrequency", &CONFIG_HEARTBEAT_FREQUENCY, TYPE_INT, - PARM_OPT, 0, SEC_PER_HOUR}, + PARM_OPT, 0, ZBX_PROXY_HEARTBEAT_FREQUENCY_MAX}, {"ConfigFrequency", &CONFIG_PROXYCONFIG_FREQUENCY, TYPE_INT, PARM_OPT, 1, SEC_PER_WEEK}, {"DataSenderFrequency", &CONFIG_PROXYDATA_FREQUENCY, TYPE_INT, diff --git a/src/zabbix_server/dbconfig/dbconfig.c b/src/zabbix_server/dbconfig/dbconfig.c index ab5012cf261..267d348a15f 100644 --- a/src/zabbix_server/dbconfig/dbconfig.c +++ b/src/zabbix_server/dbconfig/dbconfig.c @@ -91,6 +91,7 @@ ZBX_THREAD_ENTRY(dbconfig_thread, args) sec = zbx_time(); DCsync_configuration(); + DCupdate_hosts_availability(); sec = zbx_time() - sec; zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, idle %d sec]", diff --git a/src/zabbix_server/poller/poller.c b/src/zabbix_server/poller/poller.c index eb0cd9a8931..bfe5cc114e4 100644 --- a/src/zabbix_server/poller/poller.c +++ b/src/zabbix_server/poller/poller.c @@ -79,8 +79,8 @@ static void update_triggers_status_to_unknown(zbx_uint64_t hostid, zbx_item_type zbx_snprintf(failed_type_buf, sizeof(failed_type_buf), "%d", ITEM_TYPE_JMX); break; default: - /* we should never end up here */ - assert(0); + zbx_error("unknown item type: %d", type); + THIS_SHOULD_NEVER_HAPPEN; } /************************************************************************* @@ -506,13 +506,14 @@ static int get_value(DC_ITEM *item, AGENT_RESULT *result) * * * Purpose: retrieve values of metrics from monitored hosts * * * - * Parameters: * + * Parameters: poller_type - [IN] poller type (ZBX_POLLER_TYPE_...) * * * * Return value: number of items processed * * * * Author: Alexei Vladishev * * * - * Comments: * + * Comments: processes single item at a time except for Java, SNMP items, * + * see DCconfig_get_poller_items() * * * ******************************************************************************/ static int get_values(unsigned char poller_type, int *nextcheck) @@ -690,7 +691,7 @@ static int get_values(unsigned char poller_type, int *nextcheck) break; default: zbx_error("unknown response code returned: %d", errcodes[i]); - assert(0); + THIS_SHOULD_NEVER_HAPPEN; } if (SUCCEED == errcodes[i]) diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c index 788be2b9f2c..1d87dbf215e 100644 --- a/src/zabbix_server/server.c +++ b/src/zabbix_server/server.c @@ -202,8 +202,8 @@ int CONFIG_SERVER_STARTUP_TIME = 0; /* zabbix server startup time */ int CONFIG_PROXYPOLLER_FORKS = 1; /* parameters for passive proxies */ -/* how often zabbix server sends configuration data to proxy, in seconds */ -int CONFIG_PROXYCONFIG_FREQUENCY = 3600; /* 1h */ +/* how often Zabbix server sends configuration data to proxy, in seconds */ +int CONFIG_PROXYCONFIG_FREQUENCY = SEC_PER_HOUR; int CONFIG_PROXYDATA_FREQUENCY = 1; /* 1s */ char *CONFIG_LOAD_MODULE_PATH = NULL; |