Commit graph

2125 commits

Author SHA1 Message Date
Julian Brost
1a386ad55d
Merge pull request #10265 from Icinga/RedisConnection-spinlock
RedisConnection#Connect(): get rid of spin lock
2025-05-14 15:06:58 +02:00
Alexander A. Klimov
060d8b185e Introduce AsioDualEvent 2025-05-14 12:24:28 +02:00
Alvar Penning
7e65a60a5d
Fix PerfdataValue Counter Parsing
Ensure that the counter unit of measurement, "c", is parsed correctly
for performance data values again.

A prior refactoring in 720a88c29a changed
the parsing logic, resulting in an incorrect behavior for counter units.
By passing the raw input into the l_CsUoMs map first, the "c" UoM is
removed. Moving the explicit counter check before passing the raw unit
into the map resolves this issue.

Fixes #9540.
2025-05-12 16:34:05 +02:00
Alexander A. Klimov
331ba1f661 Rename AsioConditionVariable to AsioEvent
The current implementation is rather similar to Python's threading.Event, than to a CV.
2025-04-29 11:39:42 +02:00
Julian Brost
5404143dee Ensure consistent mktime() DST behavior across different implementations
There are inputs to mktime() where the behavior is not specified and there's
also no single obviously correct behavior. In particular, this affects how
auto-detection of whether DST is in effect is done when tm_isdst = -1 is set
and the time specified does not exist at all or exists twice on that day.

If different implementations are used within an Icinga 2 cluster, that can lead
to inconsistent behavior because different nodes may interpret the same
TimePeriod differently.

This commit introduces a wrapper to mktime(), namely Utility::NormalizeTm()
that implements the behavior provided by glibc. The choice for glibc's behavior
is pretty arbitrary, it was simply picked because most systems that are
officially/fully supported use it (with the only exception being Windows), so
this should give the least possible amount of user-visible changes.

As part of this commit, the closely related helper function mktime_const() is
also moved to Utility::TmToTimestamp() and made a wrapper around the newly
introduced NormalizeTm().
2025-04-28 13:38:55 +02:00
Johannes Schmidt
43f78a4b86 Fix SIGABRT not causing a core dump
A second abort() is needed at the end of `SigAbrtHandler()` to trigger the SIG_DFL action (in this case the core dump).

Also since `AttachDebugger()` disables the ability to dump core, so
it gets reenabled after returning from it.
2025-04-23 09:13:04 +02:00
Alexander A. Klimov
c2ddd20ef3 Fix compiler warnings by (copy-)constructing loop variables explicitly
for (const T& needle : haystack) creates the illusion that haystack is a
container of T and we're just borrowing needle. In these cases that's not true.
2025-04-22 13:55:49 +02:00
Julian Brost
d3fae440d4
SpawnCoroutine: move callback into wrapper lambda
f isn't used otherwise in the function, so if possible, it can just be moved into the lambda, avoiding a copy.

Co-authored-by: Alexander Aleksandrovič Klimov <alexander.klimov@icinga.com>
2025-04-15 15:10:12 +02:00
Julian Brost
d1d399f8b3 Avoid multiple #if in a single function call expression
Simply giving two entire call expressions for either Boost version greatly
improves readability in my opinion.
2025-04-14 17:30:19 +02:00
Julian Brost
ccfc72267f Prefer icinga::String::GetData() over icinga::String::CStr()
Creating the string_view from the std::string (as returned by GetData()) uses
the stored length instead of having to detect it by finding '\0'.
2025-04-14 17:30:19 +02:00
Alexander A. Klimov
fb2b2e2d5b Don't use removed boost::asio::spawn() overload if Boost >= v1.87 2025-04-14 17:30:19 +02:00
Alexander A. Klimov
0662f2b719 In a coroutine, re-throw everything ex. std::exception (and inheritors)
not just boost::coroutines::detail::forced_unwind.

This is needed because as of Boost 1.87, boost::asio::spawn() uses Fiber, not Coroutine v1.
https://github.com/boostorg/asio/commit/df973a85ed69f021

This is safe because every actual exception shall inherit from std::exception. Except forced_unwind and its Fiber equivalent, so that `catch(const std::exception&)` doesn't catch them and only them.
2025-04-14 17:30:19 +02:00
Alexander Aleksandrovič Klimov
7bd35d8c6b Don't use boost::asio::ip::tcp::resolver::query
It was removed in Boost 1.87.
2025-04-14 17:30:19 +02:00
Alexander Aleksandrovič Klimov
adde9cc53b
Merge pull request #10222 from Icinga/Registry-cleanup
Clean up Registry class
2025-03-21 11:00:49 +01:00
Richard Mortimer
63926c6e0d
Process: Clean up process table entry even when kill(2) fails with ESRCH (#10375)
* Icinga daemon leaves zombie processes on very busy system

On a very heavily loaded system the process group kill can
be delayed until after the regular TERM signal has caused
the process to exit. In this situation the waitpid call
is valid and reaps the zombie process that would otherwise
be left behind.

* Update AUTHORS file
2025-03-18 11:29:00 +01:00
Alexander A. Klimov
a9e9e14fce Remove unused Registry#Clear() 2025-03-18 11:22:56 +01:00
Alexander A. Klimov
4d7361527c Remove unused Registry#RegisterIfNew() 2025-03-18 11:22:56 +01:00
Alexander A. Klimov
07b274ec45 Remove unused Registry#Unregister() 2025-03-18 11:22:56 +01:00
Julian Brost
e6ad2199fc
Merge pull request #10360 from Icinga/dependency-cycle-detection
Rework dependency cycle detection
2025-03-12 15:58:44 +01:00
Julian Brost
500ad70b8c Implement std::hash<boost::intrusive_ptr<T>> for old Boost versions
Boost only implements it iself starting from version 1.74, but a specialization
of std::hash<> can be added trivially to allow the use of
std::unordered_set<boost::intrusive_ptr<T>> and
std::unordered_map<boost::intrusive_ptr<K>, V>.

Being unable to use such types already came up a few types in the past, often
resulting in the use of raw pointer instead which always involves an additional
"is this safe?"/"could the object go out of scope?" discussion. This commit
simply solves this for the future by simply allowing the use of intrusive_ptr
in unordered containers.
2025-03-12 11:53:30 +01:00
Julian Brost
4b18f62a11 Add ConfigType::BeforeOnAllConfigLoaded signal
Allows to hook into the config loading process just before OnAllConfigLoaded()
is called on a bunch of individual config objects. Allows doing some operations
more efficiently at once for all objects.

Intended use: when adding a number of dependencies, it has to be checked
whether this uses any cycles. This can be done more efficiently if all
dependencies are checked at once. So far, this is with a case-distinction for
initially loaded files in DaemonUtility::LoadConfigFiles() and for dependencies
created by runtime updates in Dependency::OnAllConfigLoaded(). The mechanism
added by this commit allows to unify the handling of both cases (done in a
following commit).
2025-03-12 11:53:30 +01:00
Yonas Habteab
3e9292a349 Value: Add a specialized rvalue reference of Get()
The move `String(Value&&)` constructor tries to partially move `String`
values from a `Value` type. However, since there was no an appropriate
`Value::Get<T>()` implementation that binds to the requested move
operation, the compiler will actually not move the value but copy it
instead as the only available implementation of `Value::Get<T>()`
returns a const reference `const T&`. This commit adds a new overload
that returns a non-const reference and allows to optionally move the string
value of a Value type.
2025-03-07 10:16:31 +01:00
Yonas Habteab
6a888e1494 String: Mark move constructor & assignment op as noexcept
The Icinga DB code performs intensive operations on certain STL containers,
primarily on `std::vector<String>`. Specifically, it inserts 2-3 new elements
at the beginning of a vector containing thousands of elements. Without this commit,
all the existing elements would be unnecessarily copied just to accommodate the new
elements at the front. By making this change, the compiler is able to optimize STL
operations like `push_back`, `emplace_back`, and `insert`, enabling it to prefer the
move constructor over copy operations, provided it is guaranteed that no exceptions
will be thrown.
2025-03-06 13:02:40 +01:00
Alexander A. Klimov
e1a4390b9c Fix compile error on OpenBSD which has no SSL_OP_NO_RENEGOTIATION 2025-01-29 17:42:10 +01:00
Alexander Aleksandrovič Klimov
866db3ba3c
Merge pull request #10137 from Icinga/win-progfiles-icinga2-var
On Windows, don't create C:\Program Files\Icinga2\var during MSI build
2025-01-16 12:02:33 +01:00
Julian Brost
4ffe88e263
Merge pull request #9732 from Icinga/silence-compiler-warnings-in-code-we-don-t-maintain
Silence compiler warnings in code we don't maintain
2025-01-15 16:33:24 +01:00
Alexander A. Klimov
6195a457a7 Silence compiler warnings in code we don't maintain 2025-01-14 11:48:33 +01:00
Lorenz Kästle
e7381193c8
Reject infinite performance data values
Some fault monitoring plugins may return "inf" or "-inf" as
values due to a failure to initialize or other errors.

This patch introduces a check on whether the parse value is infinite
(or negative infinite) and rejects the data point if that is the case.

The reasoning here is: There is no possible way a value of "inf" is ever
a true measuring or even useful. Furthermore, when passed to the
performance data writers, it may be rejected by the backend and lead
to further complications.
2025-01-09 11:46:34 +01:00
Alexander A. Klimov
8f72891228 Document Timeout 2025-01-07 18:20:54 +01:00
Alexander A. Klimov
3ca7ff7bf4 Timeout: explicitly delete #Timeout(const Timeout&), #Timeout(Timeout&&), #operator=(const Timeout&), #operator=(Timeout&&) 2025-01-07 18:20:52 +01:00
Alexander A. Klimov
27e0e236cb Move Timeout instances from heap to stack 2025-01-07 18:20:50 +01:00
Alexander A. Klimov
d77d7506f1 Don't call Timeout#Cancel() where Timeout#~Timeout() is called 2025-01-07 18:20:14 +01:00
Alexander A. Klimov
959b162913 Timeout#~Timeout(), #Cancel(): support boost::asio::io_context running on multiple threads 2025-01-07 18:19:42 +01:00
Alexander A. Klimov
cb51649363 Timeout#Timeout(): drop unnecessary template parameters 2025-01-07 18:19:39 +01:00
Alexander A. Klimov
faaeb4eb2e Timeout: use a plain callback, not an unnecessary coroutine 2025-01-07 18:18:24 +01:00
Alexander A. Klimov
92ab913226 Timeout#Timeout(): don't pass yield_context to callback
It's not used. Also, the callback shall run completely at once. This ensures that it won't (continue to) run once another coroutine on the strand calls Timeout#Cancel().
2025-01-07 18:18:18 +01:00
Julian Brost
cf125dd8d5 Simplify DependencyGraph:RemoveDependency() method 2025-01-07 11:07:46 +01:00
Yonas Habteab
015374e69d DependencyGraph: Allow lookups by parent & child dependencies 2025-01-07 11:07:46 +01:00
Alexander Aleksandrovič Klimov
383773eb2b
Merge pull request #10264 from Icinga/DependencyGraph-ConfigObject
DependencyGraph: use ConfigObject*, not Object*
2024-12-18 13:36:56 +01:00
Alexander A. Klimov
3a09cf72d6 DependencyGraph: use ConfigObject*, not Object*
This saves dynamic_cast<ConfigObject*> + if() on every item of GetChildren().
2024-12-17 18:33:05 +01:00
Julian Brost
452386cdb6
Merge pull request #10005 from Icinga/graceful-tls-disconnect
Add a dedicated method for disconnecting TLS connections
2024-12-12 16:20:14 +01:00
Julian Brost
56d5811283 AsioTlsStream: add GracefulDisconnect() and ForceDisconnect()
Calling `AsioTlsStream::async_shutdown()` performs a TLS shutdown which
exchanges messages (that's why it takes a `yield_context`) and thus has the
potential to block the coroutine. Therefore, it should be protected with a
timeout. As `async_shutdown()` doesn't simply take a timeout, this has to be
implemented using a timer. So far, these timers are scattered throughout the
codebase with some places missing them entirely. This commit adds helper
functions to properly shutdown a TLS connection with a single function call.
2024-12-12 12:10:59 +01:00
Alexander A. Klimov
188ba53b74 DependencyGraph: switch "parent" and "child" terminology
The .ti files call `DependencyGraph::AddDependency(this, service.get())`. Obviously, `service.get()` is the parent and `this` (Downtime, Notification, ...) is the child. The DependencyGraph terminology should reflect this not to confuse its future users.
2024-12-04 10:57:30 +01:00
Yonas Habteab
d68ee3fcf8
Merge pull request #10224 from Icinga/Empty-constant
Make icinga::Empty constant to prevent accidental changes
2024-11-14 10:35:36 +01:00
Julian Brost
5817e7666b
Merge commit from fork
Security: fix TLS certificate validation bypass
2024-11-12 15:01:57 +01:00
Alexander A. Klimov
09160ea9eb Make icinga::Empty constant to prevent accidental changes 2024-11-11 16:31:04 +01:00
Alexander Aleksandrovič Klimov
fb64c4f057
Atomic#Atomic(): remove superfluous atomic write 2024-11-06 11:37:02 +01:00
Alexander Aleksandrovič Klimov
a77259adc1
Atomic<T>#Atomic(T): fix C++ compliance
by not calling `std::atomic<T>::atomic(void)`.

After the latter the instance "does not contain a T object, and its only valid uses are destruction and initialization by std::atomic_init" which we don't call. So the only safe option is `std::atomic<T>::atomic(T)`.

https://en.cppreference.com/w/cpp/atomic/atomic/atomic
2024-11-05 13:15:22 +01:00
Julian Brost
869a7d6f0f Security: fix TLS certificate validation bypass
The previous validation in set_verify_callback() could be bypassed, tricking
Icinga 2 into treating invalid certificates as valid. To fix this, the
validation checks were moved into the IsVerifyOK() function.

This is tracked as CVE-2024-49369, more details will be published at a later time.
2024-10-22 10:36:58 +02:00
Julian Brost
f0e084d530 Log: fix some parts of messages not being discarded early
`m_IsNoOp` was introduced to avoid building up log messages that will later be
discarded, like debug messages if no debug logging is configured. However, it
looks like the template operator<< implemented in the header file was forgotten
when adding this feature, all other places writing into `m_Buffer` already have
an if guard like added by this commit.
2024-09-27 14:23:05 +02:00
Yonas Habteab
467e8b18e7 Type: Simplify sort by load dependencies algorithm 2024-09-20 16:18:12 +02:00
Alexander A. Klimov
b848934d57 Introduce Type::GetConfigTypesSortedByLoadDependencies() 2024-09-20 16:18:12 +02:00
Alexander Aleksandrovič Klimov
79e3cb2a95 Utility::ReleaseHelper(): remove detection of EOL distros
We only support /etc/os-release owners.
2024-09-04 10:26:50 +02:00
Yonas Habteab
a5a83e311a Defer: Allow empty initialization & add SetFunc() method 2024-08-27 14:23:41 +02:00
Alexander A. Klimov
f96e7c67ee On Windows, don't create C:\Program Files\Icinga2\var during MSI build 2024-08-23 12:49:09 +02:00
Julian Brost
39ae2e8ca4 Utility::FormatDateTime(): provide an overload for tm*
This allows the function to be used both with a double timestamp or a pointer
to a tm struct. With this, a similar implementation inside the tests can simply
use our regular function.
2024-08-23 12:48:50 +02:00
Julian Brost
d5b3ffaa6d Utility::FormatDateTime(): handle invalid format strings on Windows
On Windows, the strftime() function family invokes an invalid parameter handler
when the format string is invalid (see the "Remarks" section in their
documentation). std::put_time() shows the same behavior as it uses
_wcsftime_l() internally. The default invalid parameter handler may terminate
the process, which can be a problem given that the format string can be
specified by the user from the Icinga DSL.

Thus, temporarily set a thread-local no-op handler to disable the default one
allowing the program to continue. This then simply results in the function
returning an error which then results in an exception as we ask the stream to
throw one.

See also:
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strftime-wcsftime-strftime-l-wcsftime-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/parameter-validation?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/set-invalid-parameter-handler-set-thread-local-invalid-parameter-handler?view=msvc-170
2024-08-23 12:48:50 +02:00
Julian Brost
0285028689 Utility::FormatDateTime(): handle errors from strftime()
So far, the return value of strftime() was simply ignored and the output buffer
passed to the icinga::String constructor. However, there are error conditions
where strftime() returns 0 to signal an error, like if the buffer was too small
for the output. In that case, there's no guarantee on the buffer contents and
reading it can result in undefined behavior. Unfortunately, returning 0 can
also indicate success and strftime() doesn't set errno, so there's no reliable
way to distinguish both situations. Thus, the implementation now returns the
empty string in both cases.

I attempted to use std::put_time() at first as that allows for better error
handling, however, there were problems with the implementation on Windows (see
inline comment), so I put that plan on hold at left strftime() there for the
time being.
2024-08-23 12:42:54 +02:00
Julian Brost
c2c66908f6 Utility::FormatDateTime(): use localtime_s() on Windows
localtime() is not thread-safe as it returns a pointer to a shared tm struct.
Everywhere except on Windows, localtime_r() is used already which avoids the
problem by using a struct allocated by the caller for the output.

Windows actually has a similar function called localtime_s() which has the same
properties, just with a different name and order of arguments.
2024-08-23 12:42:32 +02:00
Julian Brost
704acdc698 Utility::FormatDateTime(): use boost::numeric_cast<>()
The previous implementation actually had undefined behavior when called with a
double that can't be represented as time_t. With boost::numeric_cast, there's a
convenient cast available that avoids this and throws an exceptions on
overflow.

It's undefined behavior ([0], where the implicit conversion rule comes into
play because the C-style cast uses static_cast [1] which in turn uses the
imlicit conversion as per rule 5 of [2]):

> A prvalue of floating-point type can be converted to a prvalue of any integer
> type. The fractional part is truncated, that is, the fractional part is
> discarded.
>
> * If the truncated value cannot fit into the destination type, the behavior
>   is undefined (even when the destination type is unsigned, modulo arithmetic
>   does not apply).

Note that on Linux amd64, the undefined behavior typically manifests itself in
the result being the minimal value of time_t which then results in localtime_r
failing with EOVERFLOW.

[0]: https://en.cppreference.com/w/cpp/language/implicit_conversion#Floating.E2.80.93integral_conversions
[1]: https://en.cppreference.com/w/cpp/language/explicit_cast
[2]: https://en.cppreference.com/w/cpp/language/static_cast
2024-08-23 12:42:30 +02:00
Alexander Aleksandrovič Klimov
d8f8d64f1a
Merge pull request #10027 from macdems/master
Fix missing values in PerfData normalization
2024-04-25 19:38:21 +02:00
Maciej Dems
2bb5cc62e2 Fix missing values in PerfData normalization 2024-04-25 17:41:12 +02:00
Alexander A. Klimov
e33befabfb Make ProcessResult#ExitStatus and CheckResult#exit_status 64-bit ints
so that they can hold Windows exit codes like 3221225477 (>2147483647).
2024-04-23 17:45:31 +02:00
Alexander Aleksandrovič Klimov
9db1c4aca3
Merge pull request #8011 from Icinga/bugfix/reset-sigpipe-6912
Reset all signal handlers of child processes
2024-02-15 12:22:36 +01:00
Alexander Aleksandrovič Klimov
1a8ce5a90e
Merge pull request #9575 from Icinga/WorkQueue-ParallelFor
WorkQueue#ParallelFor(): allocate lambda once per thread, not once per item
2024-02-14 12:59:50 +01:00
Alexander Aleksandrovič Klimov
48eb563ca0
Merge pull request #9736 from Icinga/stream-read-allow_partial
Stream#Read(): remove de facto unused param allow_partial
2024-02-13 13:04:15 +01:00
Eric Lippmann
c7293de91d IoEngine: Always log coroutine exception diagnostics
While analyzing a possible memory leak, we encountered several coroutine
exception messages, which unfortunately do not provide any information
about what exactly went wrong, as exception diagnostics were previously
only logged at the notice level.
2024-02-08 12:09:06 +01:00
Alexander A. Klimov
d48b369554 Reset all signal handlers of child processes
... not to disturb check plugins.

refs #6912
2024-01-17 12:25:59 +01:00
Alexander Aleksandrovič Klimov
28b2db8446
Merge pull request #9851 from Icinga/Al2Klimov-patch-3
Make ObjectImpl<Logger>#GetSeverity() non-virtual
2023-12-22 12:44:51 +01:00
Alexander Aleksandrovič Klimov
949d983a76
Merge pull request #9895 from Icinga/targeted-api-filter
FilterUtility::GetFilterTargets(): don't run filter for specific object(s) for all objects
2023-12-19 15:18:41 +01:00
Alexander Aleksandrovič Klimov
8b2e28a869
Merge pull request #9891 from Icinga/renew-the-ca-9890
ApiListener#Start(): auto-renew CA on its owner
2023-12-19 14:57:47 +01:00
Alexander A. Klimov
551c3afa60 CertificateToString(): allow raw pointer input 2023-12-18 15:28:11 +01:00
Alexander A. Klimov
7b55df6f11 CreateCertIcingaCA(EVP_PKEY*, X509_NAME*): enable optional CA creation 2023-12-18 15:28:11 +01:00
Alexander A. Klimov
8bcae97ecc Introduce Dictionary#GetRef() 2023-12-13 16:02:50 +01:00
Alexander A. Klimov
74f52c6fcd Introduce IsCaUptodate() by splitting IsCertUptodate() 2023-12-13 12:08:34 +01:00
Julian Brost
871fa67b52
Merge pull request #9885 from Icinga/renegotiation 2023-12-12 17:38:09 +01:00
Alexander A. Klimov
7ce9457a4a Disable TLS renegotiation
The API doesn't need it and a customer's security scanner
is afraid of a potential DoS attack vector.
2023-11-06 18:46:37 +01:00
Theo Buehler
1f06589f7a Remove dead code in GetSignatureAlgorithm()
This code was added in commit 548eb93 and never did anything useful.
Using X509_get_signature_nid() or its expanded version in the pre-1.1
branch is the correct way of retrieving the signature algorithm of a
certificate.

CLA: trivial
2023-10-20 18:55:44 +02:00
Alexander Aleksandrovič Klimov
e5d988a2fe
Merge pull request #7799 from Icinga/bugfix/file-end
Fix file endings
2023-08-25 11:06:19 +02:00
Alexander Aleksandrovič Klimov
993c9b742d
Make ObjectImpl<Logger>#GetSeverity() non-virtual
After all it's not overridden.
2023-08-15 13:03:31 +02:00
Alexander A. Klimov
1308ad62af Stream#Read(): remove de facto unused param allow_partial
The only caller passes true, so no one forbids partial reads (even implicitly).
All usages in the implementation just assert it being true (allowed).
2023-07-13 16:55:48 +02:00
Alexander Aleksandrovič Klimov
1af5109ad3
Merge pull request #9734 from Icinga/remove-unused-stream-peek-
Remove unused Stream#Peek()
2023-07-13 16:52:29 +02:00
Alexander A. Klimov
8f8a6ee2a0 Application::m_LastReloadFailed: if double isn't always lock free, use uint32_t
which will overflow in 2106, not 2038.
This fixes a compile failure on 32-bit Raspbian.
2023-07-10 10:51:02 +02:00
Julian Brost
fe13b96226
Merge pull request #9809 from Icinga/reevaluate-and-update-default-tls-cipher-list-9808
Copy and paste global default TLS cipher set from ssl-config.mozilla.org
2023-07-03 19:13:10 +02:00
Alexander A. Klimov
617dda61fb Re-order global default TLS cipher list to prefer AES256 over AES128 2023-07-03 15:36:11 +02:00
Julian Brost
a2e05f89e8 Enable built-in OpenSSL DH parameters to allow DHE TLS ciphers
Non-ECC DHE ciphers in the `cipher_list` attribute of `ApiListener` (the
default value includes these) had no effect as no DH parameters were available
and therefore the server wouldn't offer these ciphers. OpenSSL provides
built-in DH parameters starting from version 1.1.0, however, these have to be
enables explicitly using the `SSL_CTX_set_dh_auto()` function. This commit does
so and thereby makes it possible to establish a connection to an Icinga 2
server using a DHE cipher.
2023-06-29 12:06:26 +02:00
Alexander A. Klimov
2e053b0e06 Copy and paste global default TLS cipher set from ssl-config.mozilla.org
which got more secure by now, but still overlaps with v2.13.x' set.
2023-06-28 14:49:08 +02:00
Julian Brost
b0899d9ab4
Merge pull request #8429 from Icinga/bugfix/last-reload-attempt-failed-8428
Share "Last reload attempt failed" time across Icinga process tree on *nix
2023-05-30 11:42:21 +02:00
Julian Brost
2470e930eb
Merge pull request #9643 from Icinga/hardware_concurrency
Always use Configuration#Concurrency, not `std:🧵:hardware_concurrency()`
2023-05-23 19:23:14 +02:00
Alexander A. Klimov
3fae41ef22 Restart thread pool after freezing Configuration
The user (-D) or we could have changed Configuration.Concurrency,
so correct the thread pool's thread amount.
2023-05-23 14:41:35 +02:00
Alexander A. Klimov
9376a311ea Fix file endings
git ls-files -z \
	|grep -zEe '^lib/' \
	|grep -zEe '\.[ch]pp$' \
	|xargs -0 perl -p0i -e 's/\n*(?!(?:.|\n))/\n/'
2023-05-17 18:05:13 +02:00
Alexander A. Klimov
32eb1680f7 Configuration.Concurrency: default to 1 until Configuration freeze
not to start many threads before the user could override their amount (-D).
2023-05-11 16:59:47 +02:00
Alexander A. Klimov
8fb5d53118 Track Configuration.Concurrency modifications 2023-05-11 15:41:35 +02:00
Alexander A. Klimov
5c330e9d4f Share "Last reload attempt failed" time across Icinga process tree on *nix
... as only the umbrella process knows that time,
but the icinga check running in the main process also needs to know it.

refs #8428
2023-05-08 14:42:21 +02:00
Julian Brost
af9d67b262
Merge pull request #9726 from Icinga/43624b
Remove -and notify- expired downtimes immediately, not every 60s II
2023-05-02 11:25:03 +02:00
Alexander A. Klimov
ba7102cae3 Explicitly stop started timers and wait for them
before permitting their parent objects' destruction.
For the cases where the handlers have raw pointers to these objects.
2023-04-14 14:52:04 +02:00
Alexander A. Klimov
a66ace7245 Introduce SharedMemory 2023-04-04 13:40:27 +02:00
Alexander A. Klimov
c41e5fd05d Support multiple redundant Timer#Start() calls
so that only the first one changes l_AliveTimers (as in Timer#Stop()).
2023-04-04 10:35:22 +02:00
Alexander A. Klimov
298f3b1973 Timer: actually support non-periodic timers 2023-04-04 10:35:22 +02:00
Alexander A. Klimov
3933502739 Timer#Start(): don't unnecessarily unlock/lock l_TimerMutex
via new Timer#InternalRescheduleUnlocked()
2023-04-04 10:35:22 +02:00
Alexander A. Klimov
13b9cfda41 Timer::TimerThreadProc(): don't unnecessarily unlock and lock l_TimerMutex 2023-04-04 10:35:22 +02:00
Alexander A. Klimov
1badbab002 Timer::TimerThreadProc(): keep a Timer alive while it's running
to prevent the case: Timer callback destroys parent object -> destroys
Timer -> ~Timer() -> Stop(true) -> waits for the Timer callback to finish
-> deadlock.
2023-04-04 10:35:22 +02:00
Alexander A. Klimov
9b00c1c4dd Timer: drop unnecessary base class 2023-04-04 10:35:22 +02:00
Alexander A. Klimov
24681b30f6 Make Timer::Ptr a std::shared_ptr 2023-04-04 10:35:22 +02:00
Alexander A. Klimov
9ee4d08722 Make Timer#Timer() private to enforce Timer::Create() usage 2023-04-04 10:35:22 +02:00
Alexander A. Klimov
21b68455ce Use Timer::Create() instead of new Timer()
git ls-files -z |xargs -0 perl -pi -e 's/\bnew Timer\b/Timer::Create/g'

ex. in Timer::Create() itself.
2023-04-04 10:35:20 +02:00
Alexander A. Klimov
bb1f574b69 Introduce factory method Timer::Create() 2023-04-04 10:35:10 +02:00
Alexander A. Klimov
335688909b Document why Timer::TimerThreadProc() can use Timer members during Timer#~Timer() call 2023-03-29 18:04:19 +02:00
Alexander A. Klimov
78b4dc6509 Remove unused Stream#Peek() 2023-03-24 18:18:13 +01:00
Julian Brost
66b039df9c
Merge pull request #9497 from Icinga/9249
Application::Exit(): don't exit(), but _exit(), even in debug build mode
2023-03-10 16:04:54 +01:00
Alexander Aleksandrovič Klimov
55930c8042
ProcessSpawnImpl(): remove redundant _exit(128);
Now this if doesn’t _exit(128) by itself, but "return" to the outer if which immediately _exit(128)s.
2023-03-02 12:45:15 +01:00
Julian Brost
cf517050bc
Merge pull request #9711 from Icinga/connect-cancel
Connect(): don't try next DNS record if operation is canceled
2023-03-01 15:49:53 +01:00
Alexander A. Klimov
79f1e0666a Connect(): don't try next DNS record if operation is canceled
Instead return immediately to meet the caller's expectations.
2023-02-28 10:57:54 +01:00
Julian Brost
bda8be343b
Merge pull request #9662 from Icinga/Repair#9627
Repair DSL Namespace values being constant broken in #9627
2023-02-20 16:35:36 +01:00
Julian Brost
d9767cff3f
Merge pull request #9675 from Icinga/third-party/nlohmann_json
Update third-party/nlohmann_json to v3.9.1
2023-02-20 15:31:32 +01:00
Julian Brost
3023009804
Merge pull request #9653 from Icinga/9631
Setup all signal handlers with SA_RESTART flag
2023-02-14 17:55:09 +01:00
Alexander A. Klimov
34d0b942b9 Update third-party/nlohmann_json to v3.9.1
the latest version w/o Apache 2.0 licensed code which conflicts with GPL 2.
2023-02-14 16:19:44 +01:00
Julian Brost
e074e892ce
Merge pull request #9658 from Icinga/unfreeze
Dictionary#*(): remove bool overrideFrozen if unused
2023-02-10 19:42:00 +01:00
Alexander A. Klimov
f3f2c943c7 ScriptGlobal::Set(): don't explicitly give Namespace#Set() its default values 2023-02-10 15:55:10 +01:00
Alexander A. Klimov
e61b380808 Call Namespace#Set(), not #SetFieldByName()
Namespace#SetFieldByName() calls #Set() anyway.
2023-02-10 15:53:30 +01:00
Alexander A. Klimov
683095a165 Make globals.Internal values non-const by default
That namespace is internal anyway.

Previous commit, icinga2 console:
Error: Constants must not be removed.

This commit fixes it.
2023-02-10 15:47:25 +01:00
Alexander A. Klimov
02df94a46a Repair DSL Namespace values being constant broken in #9627
master before #9627 (a0286e9c6):

<1> => namespace n { x = 42; x = 42 }
                             ^^^^^^
Constant must not be modified.
<2> =>

HEAD of #9627 (24b57f0d3):

<1> => namespace n { x = 42; x = 42 }
null
<2> =>
2023-02-10 15:43:01 +01:00
Julian Brost
0dd35bb960
Merge pull request #9657 from Icinga/shared_mutex-Dictionary
Use a shared_mutex for read `Dictionary` operations
2023-02-10 15:15:52 +01:00
Alexander A. Klimov
e9846f1827 ScriptGlobal::Set(): remove unused bool overrideFrozen 2023-02-10 11:33:46 +01:00
Alexander A. Klimov
cd78da13d3 Dictionary#Clear(): remove unused bool overrideFrozen 2023-02-10 11:33:46 +01:00
Alexander A. Klimov
270c6392d4 Dictionary#Remove(): remove unused bool overrideFrozen 2023-02-10 11:33:46 +01:00
Alexander A. Klimov
ca547d0292 Use a shared_mutex for read Dictionary operations
This allows multiple parallel read operations resulting
in a overall speedup on systems with many cores.
2023-02-10 11:31:51 +01:00
Alexander A. Klimov
a9341eb4a0 Setup all signal handlers with SA_RESTART flag
so interrupted syscalls get auto-restarted and callers
don't get or have to handle the EINTR error.
2023-02-03 14:46:45 +01:00
Julian Brost
c51037725a
Merge pull request #9466 from Icinga/flush-temp-files
Deduplicate and stabilize fragile filesystem transactions
2023-02-02 16:29:11 +01:00
Julian Brost
fd1aa73d25 Fix config sync after freezing namespaces
This was accidentally broken by #9627 because during config sync, a config
validation happens that uses `--define System.ZonesStageVarDir=...` which fails
on the now frozen namespace.

This commit changes this to use `Internal.ZonesStageVarDir` instead. After all,
this is used for internal functionality, users should not directly interact
with this flag.

Additionally, it no longer freezes the `Internal` namespace which actually
allows using `Internal.ZonesStageVarDir` in the first place. This also fixes
`--define Internal.Debug*` which was also broken by said PR. Freezing of the
`Internal` namespace is not necessary for performance reasons as it's not
searched implicitly (for example when accessing `globals.x`) and should users
actually interact with it, they should know by that name that they are on their
own.
2023-02-01 12:29:47 +01:00
Alexander A. Klimov
c953ba1206 Remove redundant ThreadPool#m_Threads 2023-01-27 16:34:11 +01:00
Alexander A. Klimov
288ad68649 ThreadPool#ThreadPool(): remove unused parameter 2023-01-27 16:32:29 +01:00
Alexander A. Klimov
d22fdf2a7a Introduce AtomicFile#GetTempFilename() 2023-01-27 12:03:59 +01:00
Alexander A. Klimov
0367c9e099 Remove unused Utility::CreateTempFile() 2023-01-27 12:03:59 +01:00
Alexander A. Klimov
b92fe23469 Deduplicate and stabilize fragile filesystem transactions
by using AtomicFile so they ensure all or nothing of a file gets replaced.
2023-01-27 12:03:56 +01:00
Alexander A. Klimov
a3e205b990 Introduce AtomicFile::Write() 2023-01-27 11:36:09 +01:00
Julian Brost
2d860a0f5e
Merge pull request #8118 from Icinga/feature/speed-object-registry-8112
Speed up config object lookup
2023-01-26 19:03:40 +01:00
Alexander Aleksandrovič Klimov
421ac1735c
Merge pull request #9608 from Icinga/move-types-namespace
Move Types namespace into type.cpp and simplify Type::GetByName()
2023-01-26 18:32:41 +01:00
Alexander A. Klimov
b2fc49569c Make ConfigType#m_Mutex a std::shared_timed_mutex
refs #8112
2023-01-26 15:04:02 +01:00
Alexander A. Klimov
21759f015d ConfigType: store config objects in a hash map
refs #8112
2023-01-26 15:03:54 +01:00
Julian Brost
3dab46623b Move Types namespace into type.cpp and simplify Type::GetByName()
This commit moves the initialization of the globals.Types namespace to type.cpp
in order to keep a pointer to the Namespace object in Type::m_Namespace and
simplify Type::GetByName() using it.

The dynamic type check is moved into an assertion after freezing the namespace.
2023-01-26 14:26:41 +01:00
Yonas Habteab
7b91b200f5 Use simplified if conditions where applicable 2023-01-26 09:06:20 +01:00
Yonas Habteab
38313434d2 Avoid calling GetDeferredInitializers() repeatedly 2023-01-26 09:05:19 +01:00
Julian Brost
24b57f0d3a Namespace: don't acquire shared locks on frozen namespaces
This makes freezing a namespace an irrevocable operation but in return allows
omitting further lock operations. This results in a performance improvement as
reading an atomic bool is faster than acquiring and releasing a shared lock.

ObjectLocks on namespaces remain untouched as these mostly affect write
operations which there should be none of after freezing (if there are some,
they will throw exceptions anyways).
2023-01-19 17:56:44 +01:00
Julian Brost
cc0e2ec181 Use a shared_mutex for read Namespace operations
This allows multiple parallel read operations resulting in a overall speedup on
systems with many cores.
2023-01-19 17:55:29 +01:00
Julian Brost
1c066fc02e Simplify NamespaceValue class hierarchy to one struct without member functions
This commit removes EmbeddedNamespaceValue and ConstEmbeddedNamespaceValue and
reduces NamespaceValue down to a simple struct without inheritance or member
functions. The code from these clases is inlined into the Namespace class. The
class hierarchy determining whether a value is const is moved to an attribute
of NamespaceValue.

This is done in preparation for changes to the locking in the Namespace class.
Currently, it relies on a recursive mutex. In the future, a shared mutex
(read/write lock) should be used instead, which cannot allow recursive locking
(without failing or risk deadlocking on lock upgrades). With this change, all
operations requiring a lock for one operation are within one function, no
recursive locking is not needed any more.
2023-01-19 17:55:11 +01:00
Julian Brost
0503ca1379 Initialize namespaces without using overrideFrozen
This commit adds a new initialization priority `FreezeNamespaces` that is run
last and moves all calls to `Namespace::Freeze()` there. This allows all other
initialization functions to still update namespaces without the use of the
`overrideFrozen` flag.

It also moves the initialization of `System.Platform*` and `System.Build*` to
an initialize function so that these can also be set without setting
`overrideFrozen`.

This is preparation for a following commit that will make the frozen flag in
namespaces finial, no longer allowing it to be overriden (freezing the
namespace will disable locking, so performing further updates would be unsafe).
2023-01-19 09:53:36 +01:00
Julian Brost
6229f4d9bf InitializePriority: don't explicitly specify values
Now that all values are in one place, there is no reason for this numbering
with gaps anymore. If you need to insert a new value in between, you can just
do so in the enum.

This reverses the sort order of the enum, thereby requiring a change to the
sort order of the std::priority_queue containing the elements.
2023-01-18 15:57:32 +01:00
Julian Brost
99bb687350 INITIALIZE_ONCE_WITH_PRIORITY: use enum for priority values
Change the type of the priority values from int to a new enum. By replacing the
magic int values throughout the code base with named values, there is now a
single place where all priority values are defined and you get an overview over
the initialization order.
2023-01-18 15:57:27 +01:00
Julian Brost
61285adcae InitializeOnceHelper: use std::function instead of C function pointer
InitializeOnceHelper calls Loader::AddDeferredInitializer which takes a
std::function, so it's eventually converted to that anyways. This commit just
does this a bit earlier, and by saving the step of the intermediate C function
pointer, this would now also work for capturing lambdas (which there are none
of at the moment).
2023-01-18 15:52:42 +01:00