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
Maintainer: StarlingX Developers <starlingx-discuss@lists.starlingx.io>
Build-Depends: debhelper-compat (= 13),
libjson-c-dev
libjson-c-dev,
libdaemon-dev
Standards-Version: 4.5.1
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
[Service]
Type=oneshot
Type=forking
ExecStart=/usr/local/sbin/luks-fs-mgr start
PIDFile=/var/run/luks-fs-mgr.pid
User=root
Group=root
KillMode=process
SendSIGKILL=no
[Install]
WantedBy=multi-user.target

View File

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

View File

@ -14,6 +14,7 @@
#include <json-c/json.h>
#include <syslog.h>
#include <unistd.h>
#include <libdaemon/daemon.h>
#include <iostream>
#include <string>
#include <cstdlib>
@ -21,6 +22,8 @@
#include <type_traits>
#include "PassphraseGenerator.h"
#define SLEEP_DURATION 60
using namespace std;
// 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 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;
CreatedLuksConfig createdLuksConfig;
string passphrase;
@ -723,10 +758,10 @@ int main() {
PassphraseMechanism selectedMechanism = passPhraseType();
auto passphraseGenerator =
PassphraseGeneratorFactory::createPassphraseGenerator(selectedMechanism);
bool ret = passphraseGenerator->generatePassphrase(passphrase);
bool passStatus = passphraseGenerator->generatePassphrase(passphrase);
// Validating if passphrase is empty
if (passphrase.empty() || ret == false) {
if (passphrase.empty() || passStatus == false) {
log("Passphrase generation failed or"
" returned an empty passphrase.", LOG_ERR);
rc = 1;
@ -786,6 +821,7 @@ int main() {
int createdsize = 0;
defaultsize = checkVaultSize(luksConfig.vaultSize);
createdsize = checkVaultSize(createdLuksConfig.vaultSize);
string volName = string(createdLuksConfig.volName);
if (defaultsize > createdsize) {
log("Resizing the vault file.", LOG_INFO);
if (resizeVault(createdLuksConfig.vaultFile,
@ -834,7 +870,7 @@ int main() {
// or device is block device
// 1: failure; incorrect invocation, permissions or system error
// 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) {
// Mount path directory is not mount point,
// proceed to mount it
@ -863,8 +899,9 @@ int main() {
log("Encrypted vault is mounted.", LOG_INFO);
}
}
rc = 0;
goto cleanup;
monitorLUKSVolume(volName);
rc = 0;
goto cleanup;
} else {
// Execute the below code when service start during first boot
// 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
string modifiedVaultFile = luksConfig.vaultFile;
string mountPath = luksConfig.mountPath;
string volName = luksConfig.volName;
// Check if directory path is provided in vaultFile
size_t lastSlashPos = modifiedVaultFile.rfind('/');
if (lastSlashPos == string::npos) {
@ -1027,6 +1065,7 @@ int main() {
rc = 1;
goto cleanup;
}
monitorLUKSVolume(volName);
rc = 0;
goto cleanup;
}