Skip to content

Commit 4ed6b8a

Browse files
authored
Merge pull request #71 from hug-dev/reloading
Add SIGHUP signal handling to reload configuration
2 parents f8c60c0 + 7952c09 commit 4ed6b8a

File tree

5 files changed

+67
-55
lines changed

5 files changed

+67
-55
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,16 @@ jobs:
4747
steps:
4848
- uses: actions/checkout@v1
4949
- run: cargo build --verbose
50-
- name: Tests executed before the shutdown
51-
run: |
50+
- run: |
5251
RUST_BACKTRACE=1 RUST_LOG=info cargo run &
5352
SERVER_PID=$!
5453
cargo test --test persistent-before
55-
kill $SERVER_PID
56-
# Create a fake mapping file for the root application, the Mbed Provider and
57-
# a key name of "Test Key". It contains a valid PSA Key ID.
58-
# It is tested in test "should_have_been_deleted".
59-
- name: Create a fake mapping file
60-
run: |
54+
# Create a fake mapping file for the root application, the Mbed Provider and
55+
# a key name of "Test Key". It contains a valid PSA Key ID.
56+
# It is tested in test "should_have_been_deleted".
6157
mkdir -p mappings/cm9vdA==/1 || exit 1
6258
printf '\xe0\x19\xb2\x5c' > mappings/cm9vdA==/1/VGVzdCBLZXk\=
63-
- name: Tests executed after the shutdown
64-
run: |
65-
RUST_BACKTRACE=1 RUST_LOG=info cargo run &
59+
kill -s SIGHUP $SERVER_PID
6660
cargo test --test persistent-after
6761
6862
stress-test:

src/bin/main.rs

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// limitations under the License.
1515
use log::info;
1616
use parsec::utils::{ServiceBuilder, ServiceConfig};
17-
use signal_hook::{flag, SIGTERM};
17+
use signal_hook::{flag, SIGHUP, SIGTERM};
1818
use std::io::Error;
1919
use std::sync::{
2020
atomic::{AtomicBool, Ordering},
@@ -26,39 +26,57 @@ const CONFIG_FILE_PATH: &str = "./config.toml";
2626
const MAIN_LOOP_DEFAULT_SLEEP: u64 = 10;
2727

2828
fn main() -> Result<(), Error> {
29-
let config_file =
29+
// Register a boolean set to true when the SIGTERM signal is received.
30+
let kill_signal = Arc::new(AtomicBool::new(false));
31+
// Register a boolean set to true when the SIGHUP signal is received.
32+
let reload_signal = Arc::new(AtomicBool::new(false));
33+
flag::register(SIGTERM, kill_signal.clone())?;
34+
flag::register(SIGHUP, reload_signal.clone())?;
35+
36+
let mut config_file =
3037
::std::fs::read_to_string(CONFIG_FILE_PATH).expect("Failed to read configuration file");
31-
let config: ServiceConfig =
38+
let mut config: ServiceConfig =
3239
toml::from_str(&config_file).expect("Failed to parse service configuration");
3340

3441
log_setup(&config);
3542

36-
info!("PARSEC started.");
37-
38-
let front_end_handler = ServiceBuilder::build_service(&config);
39-
40-
let listener = ServiceBuilder::start_listener(&config.listener);
43+
info!("Parsec started. Configuring the service...");
4144

4245
// Multiple threads can not just have a reference of the front end handler because they could
4346
// outlive the run function. It is needed to give them all ownership of the front end handler
4447
// through an Arc.
45-
let front_end_handler = Arc::from(front_end_handler);
48+
let mut front_end_handler = Arc::from(ServiceBuilder::build_service(&config));
49+
let mut listener = ServiceBuilder::start_listener(&config.listener);
50+
let mut threadpool = ServiceBuilder::build_threadpool(config.core_settings.thread_pool_size);
4651

47-
// Register a boolean set to true when the SIGTERM signal is received.
48-
let kill_signal = Arc::new(AtomicBool::new(false));
49-
flag::register(SIGTERM, kill_signal.clone())?;
52+
// Notify systemd that the daemon is ready, the start command will block until this point.
53+
let _ = sd_notify::notify(false, &[sd_notify::NotifyState::Ready]);
5054

51-
let threadpool = ServiceBuilder::build_threadpool(config.core_settings.thread_pool_size);
55+
info!("Parsec is ready.");
5256

53-
info!("PARSEC is ready.");
57+
while !kill_signal.load(Ordering::Relaxed) {
58+
if reload_signal.swap(false, Ordering::Relaxed) {
59+
let _ = sd_notify::notify(false, &[sd_notify::NotifyState::Reloading]);
60+
info!("SIGHUP signal received. Reloading the configuration...");
5461

55-
// Notify systemd that the daemon is ready, the start command will block until this point.
56-
let _ = sd_notify::notify(true, &[sd_notify::NotifyState::Ready]);
62+
threadpool.join();
63+
64+
// Explicitely call drop now because otherwise Rust will drop these variables only
65+
// after they have been overwritten, in which case some values/libraries might be
66+
// initialized twice.
67+
drop(front_end_handler);
68+
drop(listener);
69+
drop(threadpool);
70+
71+
config_file = ::std::fs::read_to_string(CONFIG_FILE_PATH)
72+
.expect("Failed to read configuration file");
73+
config = toml::from_str(&config_file).expect("Failed to parse service configuration");
74+
front_end_handler = Arc::from(ServiceBuilder::build_service(&config));
75+
listener = ServiceBuilder::start_listener(&config.listener);
76+
threadpool = ServiceBuilder::build_threadpool(config.core_settings.thread_pool_size);
5777

58-
loop {
59-
if kill_signal.load(Ordering::Relaxed) {
60-
info!("SIGTERM signal received.");
61-
break;
78+
let _ = sd_notify::notify(false, &[sd_notify::NotifyState::Ready]);
79+
info!("Parsec configuration reloaded.");
6280
}
6381

6482
if let Some(stream) = listener.accept() {
@@ -76,8 +94,10 @@ fn main() -> Result<(), Error> {
7694
}
7795
}
7896

79-
info!("Shutting down PARSEC, waiting for all threads to finish.");
97+
let _ = sd_notify::notify(true, &[sd_notify::NotifyState::Stopping]);
98+
info!("SIGTERM signal received. Shutting down Parsec, waiting for all threads to finish...");
8099
threadpool.join();
100+
info!("Parsec is now terminated.");
81101

82102
Ok(())
83103
}

src/providers/mbed_provider/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,14 @@ impl Provide for MbedProvider {
482482
}
483483
}
484484

485+
impl Drop for MbedProvider {
486+
fn drop(&mut self) {
487+
unsafe {
488+
psa_crypto_binding::mbedtls_psa_crypto_free();
489+
}
490+
}
491+
}
492+
485493
#[derive(Default)]
486494
pub struct MbedProviderBuilder {
487495
key_id_store: Option<Arc<RwLock<dyn ManageKeyIDs + Send + Sync>>>,

src/providers/pkcs11_provider/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,14 @@ impl Provide for Pkcs11Provider {
900900
}
901901
}
902902

903+
impl Drop for Pkcs11Provider {
904+
fn drop(&mut self) {
905+
if let Err(e) = self.backend.finalize() {
906+
error!("Error when dropping the PKCS 11 provider: {}", e);
907+
}
908+
}
909+
}
910+
903911
#[derive(Default)]
904912
pub struct Pkcs11ProviderBuilder {
905913
key_id_store: Option<Arc<RwLock<dyn ManageKeyIDs + Send + Sync>>>,

tests/all.sh

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,16 @@ cargo test --doc || exit 1
3939
cargo fmt --all -- --check || exit 1
4040
cargo clippy || exit 1
4141

42-
############################
43-
# Normal Integration tests #
44-
############################
42+
#####################
43+
# Integration tests #
44+
#####################
4545
RUST_BACKTRACE=1 RUST_LOG=info cargo run &
4646
SERVER_PID=$!
4747

4848
cargo test --test normal || exit 1
4949

50-
kill $SERVER_PID
51-
52-
#################################
53-
# Persistence Integration tests #
54-
#################################
55-
RUST_BACKTRACE=1 RUST_LOG=info cargo run &
56-
SERVER_PID=$!
57-
5850
cargo test --test persistent-before || exit 1
5951

60-
kill $SERVER_PID
61-
6252
# Create a fake mapping file for the root application, the Mbed Provider and a
6353
# key name of "Test Key". It contains a valid PSA Key ID.
6454
# It is tested in test "should_have_been_deleted".
@@ -68,19 +58,11 @@ printf '\xe0\x19\xb2\x5c' > mappings/cm9vdA==/1/VGVzdCBLZXk\=
6858
# For PKCS 11 Provider
6959
printf '\xe0\x19\xb2\x5c' > mappings/cm9vdA==/2/VGVzdCBLZXk\=
7060

71-
RUST_BACKTRACE=1 RUST_LOG=info cargo run &
72-
SERVER_PID=$!
61+
# Trigger a configuration reload to load the new mappings.
62+
kill -s SIGHUP $SERVER_PID
7363

7464
cargo test --test persistent-after || exit 1
7565

76-
kill $SERVER_PID
77-
78-
################
79-
# Stress tests #
80-
################
81-
RUST_BACKTRACE=1 RUST_LOG=info cargo run &
82-
SERVER_PID=$!
83-
8466
RUST_LOG=info cargo test --test stress_test || exit 1
8567

8668
kill $SERVER_PID

0 commit comments

Comments
 (0)