I'm trying to execute a .sh
script from within a .Net Core service daemon and getting weird behavior. The purpose of the script is to create an encrypted container, format it, set some settings, then mount it.
I'm using .Net Core version 3.1.4 on Raspbian on a Raspberry Pi 4.
The problem: I have the below script which creates the container, formats it, sets the settings, then attempts to mount it. It all seems to work fine but the last command, mount call, never actually works. The mount point is not valid.
The kicker: After the script is run via the service, if I open a terminal and issue the mount command there manully, it mounts correctly. I can then goto that mount point and it shows ~10GB of space available meaning it's using the container.
Note: Make sure the script is chmod +x
when testing. Also you'll need cryptsetup installed to work.
Thoughts:
I'm not sure if some environment or PATH variables are missing for the shell script to properly function. Since this is a service, I can edit the Unit
to include this information, if I knew what it was.
In previous attempts at issuing bash commands, I've had to set the DISPLAY
variable like below for it to work correctly (because of needing to work with the desktop). For this issue that doesn't seem to matter but if I need to set the script as executable, then this command is uses as an example
string chmodArgs = string.Format("DISPLAY=:0.0; export DISPLAY && chmod +x {0}", scriptPath);
chmodArgs = string.Format("-c \"{0}\"", chmodArgs);
I'd like to see if someone can take the below and test on their end to confirm and possibly help come up with a solution. Thanks!
#!/bin/bash
# variables
# s0f4e7n4r4h8x4j4
# /usr/sbin/content1
# content1
# /mnt/content1
# 10240
# change the size of M to what the size of container should be
echo "Allocating 10240MB..."
fallocate -l 10240M /usr/sbin/content1
sleep 1
# using echo with -n passes in the password required for cryptsetup command. The dash at the end tells cryptsetup to read in from console
echo "Formatting..."
echo -n s0f4e7n4r4h8x4j4 | cryptsetup luksFormat /usr/sbin/content1 -
sleep 1
echo "Opening..."
echo -n s0f4e7n4r4h8x4j4 | cryptsetup luksOpen /usr/sbin/content1 content1 -
sleep 1
# create without journaling
echo "Creating filesystem..."
mkfs.ext4 -O ^has_journal /dev/mapper/content1
sleep 1
# enable writeback mode
echo "Tuning..."
tune2fs -o journal_data_writeback /dev/mapper/content1
sleep 1
if [ ! -d "/mnt/content1" ]; then
echo "Creating directory..."
mkdir -p /mnt/content1
sleep 1
fi
# mount with no access time to stop unnecessary writes to disk for just access
echo "Mounting..."
mount /dev/mapper/content1 /mnt/content1 -o noatime
sleep 1
This is how I'm executing the script in .Net
var proc = new System.Diagnostics.Process {
StartInfo =
{
FileName = pathToScript,
WorkingDirectory = workingDir,
Arguments = args,
UseShellExecute = false
}
};
if (proc.Start())
{
while (!proc.HasExited)
{
System.Threading.Thread.Sleep(33);
}
}
The Unit
file use for service daemon
[Unit]
Description=Service name
[Service]
ExecStart=/bin/bash -c 'PATH=/sbin/dotnet:$PATH exec dotnet myservice.dll'
WorkingDirectory=/sbin/myservice/
User=root
Group=root
Restart=on-failure
SyslogIdentifier=my-service
PrivateTmp=true
[Install]
WantedBy=multi-user.target