Enabling Luks service manager as daemon service

Added functionality to run luks-fs-mgr as daemon
service. Included library libdaemon which provides functions and
utilities to daemonize a program.
The daemon function is called to daemonize the program.
The daemon function is provided by libdaemon, and it sets up the
necessary environment for a daemon process. It is called with two
arguments, both set to 0. The first argument is the nochdir
parameter, which tells the function not to change the current
working directory to the root directory ("/").
The second argument is the noclose parameter, which tells the
function not to close standard input, output, and error streams.

Depends on: https://review.opendev.org/c/starlingx/integ/+/898695

Test Plan:
PASSED: build-pkgs -c -p luks-fs-mgr
PASSED: build-image
PASSED: AIO-SX bootstrap
PASSED: binary available at /usr/local/sbin/
PASSED: systemd unit file available at /lib/systemd/system
PASSED: luks_config.json avaiable at /etc/luks-fs-mgr.d/
PASSED: sudo systemctl start luks-fs-mgr
        luks-fs-mgr.service - Create and mount encrypted vault using
                                                                LUKS
        Loaded: loaded (/lib/systemd/system/luks-fs-mgr.service;
                                enabled; vendor preset: enabled)
        Active: active (running) since Fri 2023-10-13 05:58:04 UTC;
                                                       1h 34min ago
        Main PID: 1770 (luks-fs-mgr)
        Tasks: 1 (limit: 28602)
        Memory: 2.1M
        CPU: 3.422s
        CGroup: /system.slice/luks-fs-mgr.service
                └─1770 /usr/local/sbin/luks-fs-mgr start
PASSED: sudo systemctl stop luks-fs-mgr

Story: 2010872
Task: 48944

Change-Id: I975409d749fed8f27b291db80fa10223de60b05c
Signed-off-by: Rahul Roshan Kachchap <rahulroshan.kachchap@windriver.com>
This commit is contained in:
Rahul Roshan Kachchap 2023-10-13 01:15:01 -04:00
parent d52a1eedd3
commit aa8a787dfd
4 changed files with 52 additions and 9 deletions

View File

@ -3,7 +3,8 @@ Section: admin
Priority: optional Priority: optional
Maintainer: StarlingX Developers <starlingx-discuss@lists.starlingx.io> Maintainer: StarlingX Developers <starlingx-discuss@lists.starlingx.io>
Build-Depends: debhelper-compat (= 13), Build-Depends: debhelper-compat (= 13),
libjson-c-dev libjson-c-dev,
libdaemon-dev
Standards-Version: 4.5.1 Standards-Version: 4.5.1
Homepage: https://www.starlingx.io Homepage: https://www.starlingx.io

View File

@ -3,9 +3,12 @@ Description=Create and mount encrypted vault using LUKS
After=local-fs.target network-online.target After=local-fs.target network-online.target
[Service] [Service]
Type=oneshot Type=forking
ExecStart=/usr/local/sbin/luks-fs-mgr start ExecStart=/usr/local/sbin/luks-fs-mgr start
PIDFile=/var/run/luks-fs-mgr.pid User=root
Group=root
KillMode=process
SendSIGKILL=no
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -7,7 +7,7 @@
SHELL = /bin/bash SHELL = /bin/bash
CFLAGS = -Wall -Wextra -g -Werror -std=c++11 CFLAGS = -Wall -Wextra -g -Werror -std=c++11
LIBS = -lstdc++ -ljson-c LIBS = -lstdc++ -ljson-c -ldaemon
INCLUDES = -I. INCLUDES = -I.
CC=g++ CC=g++

View File

@ -14,6 +14,7 @@
#include <json-c/json.h> #include <json-c/json.h>
#include <syslog.h> #include <syslog.h>
#include <unistd.h> #include <unistd.h>
#include <libdaemon/daemon.h>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <cstdlib> #include <cstdlib>
@ -21,6 +22,8 @@
#include <type_traits> #include <type_traits>
#include "PassphraseGenerator.h" #include "PassphraseGenerator.h"
#define SLEEP_DURATION 60
using namespace std; using namespace std;
// Global constants // Global constants
@ -707,8 +710,40 @@ bool resizeVault(const char* vaultFile,
} }
} }
/* ***********************************************************************
*
* Name : monitorLUKSVolume
*
* Description: This function monitors the LUKS volume status and runs
* in loop until there's any issue with the LUKS volume.
*
* ************************************************************************/
void monitorLUKSVolume(const string& volumeName) {
while (1) {
string statusCommand = "cryptsetup status " + volumeName +
" 2>/dev/null";
int status = system(statusCommand.c_str());
if (status != 0) {
string errorMessage = "LUKS volume is not in use. "
"Error code: " + to_string(status);
log(errorMessage, LOG_ERR);
break;
}
sleep(SLEEP_DURATION);
}
}
int main() { int main() {
int rc = 0; int rc = 0;
int ret = daemon(0, 0);
if (ret != 0) {
string errorMessage = "Failed to run luks-fs-mgr as daemon service. "
"Error code: " + to_string(ret);
log(errorMessage, LOG_ERR);
return 1;
}
LuksConfig luksConfig; LuksConfig luksConfig;
CreatedLuksConfig createdLuksConfig; CreatedLuksConfig createdLuksConfig;
string passphrase; string passphrase;
@ -723,10 +758,10 @@ int main() {
PassphraseMechanism selectedMechanism = passPhraseType(); PassphraseMechanism selectedMechanism = passPhraseType();
auto passphraseGenerator = auto passphraseGenerator =
PassphraseGeneratorFactory::createPassphraseGenerator(selectedMechanism); PassphraseGeneratorFactory::createPassphraseGenerator(selectedMechanism);
bool ret = passphraseGenerator->generatePassphrase(passphrase); bool passStatus = passphraseGenerator->generatePassphrase(passphrase);
// Validating if passphrase is empty // Validating if passphrase is empty
if (passphrase.empty() || ret == false) { if (passphrase.empty() || passStatus == false) {
log("Passphrase generation failed or" log("Passphrase generation failed or"
" returned an empty passphrase.", LOG_ERR); " returned an empty passphrase.", LOG_ERR);
rc = 1; rc = 1;
@ -786,6 +821,7 @@ int main() {
int createdsize = 0; int createdsize = 0;
defaultsize = checkVaultSize(luksConfig.vaultSize); defaultsize = checkVaultSize(luksConfig.vaultSize);
createdsize = checkVaultSize(createdLuksConfig.vaultSize); createdsize = checkVaultSize(createdLuksConfig.vaultSize);
string volName = string(createdLuksConfig.volName);
if (defaultsize > createdsize) { if (defaultsize > createdsize) {
log("Resizing the vault file.", LOG_INFO); log("Resizing the vault file.", LOG_INFO);
if (resizeVault(createdLuksConfig.vaultFile, if (resizeVault(createdLuksConfig.vaultFile,
@ -834,7 +870,7 @@ int main() {
// or device is block device // or device is block device
// 1: failure; incorrect invocation, permissions or system error // 1: failure; incorrect invocation, permissions or system error
// 32: failure; the directory is not a mountpoint, // 32: failure; the directory is not a mountpoint,
// or device is not a block device on // or device is not a block device
if (mountpoint_status != 0) { if (mountpoint_status != 0) {
// Mount path directory is not mount point, // Mount path directory is not mount point,
// proceed to mount it // proceed to mount it
@ -863,8 +899,9 @@ int main() {
log("Encrypted vault is mounted.", LOG_INFO); log("Encrypted vault is mounted.", LOG_INFO);
} }
} }
rc = 0; monitorLUKSVolume(volName);
goto cleanup; rc = 0;
goto cleanup;
} else { } else {
// Execute the below code when service start during first boot // Execute the below code when service start during first boot
// Create default directory for the service to create FS and mount // Create default directory for the service to create FS and mount
@ -882,6 +919,7 @@ int main() {
// Create a new string to hold the created values // Create a new string to hold the created values
string modifiedVaultFile = luksConfig.vaultFile; string modifiedVaultFile = luksConfig.vaultFile;
string mountPath = luksConfig.mountPath; string mountPath = luksConfig.mountPath;
string volName = luksConfig.volName;
// Check if directory path is provided in vaultFile // Check if directory path is provided in vaultFile
size_t lastSlashPos = modifiedVaultFile.rfind('/'); size_t lastSlashPos = modifiedVaultFile.rfind('/');
if (lastSlashPos == string::npos) { if (lastSlashPos == string::npos) {
@ -1027,6 +1065,7 @@ int main() {
rc = 1; rc = 1;
goto cleanup; goto cleanup;
} }
monitorLUKSVolume(volName);
rc = 0; rc = 0;
goto cleanup; goto cleanup;
} }