dietpi-services vs systemd vs init

I’m trying to understand where dietpi-services starts and ends versus systemd and/or init.

In particular, I want to tweak the runtime parameters of the mpd daemon.

It looks like there is a systemd service file for mpd here:
/lib/systemd/system/mpd.service

However, when I do “dietpi-services enable mpd”, that service file is not copied or symlink’ed anywhere in the /etc/systemd tree.

With most Linux distros I’ve worked with, it’s considered bad practice to edit the service file in /lib/systemd, but rather make a copy to place in /etc/systemd, and edit the latter.

So what I ended up doing is:

dietpi-services disable mpd
dietpi-services unmask mpd
systemctl enable mpd
rm /etc/systemd/system/multi-user.target.wants/mpd.service
cp /etc/systemd/system/multi-user.target.wants/mpd.service /etc/systemd/system/multi-user.target.wants/mpd.service

And then edit /etc/systemd/system/multi-user.target.wants/mpd.service as I want.

Is this the right way to go about this? Or should I just edit /lib/systemd/system/mpd.service directly, and let dietpi-services manage the mpd service?

Thanks!

Firstly, I don’t know how the “dietpi-services” functionality works so cannot answer that part.

However, my general understanding of systemd is that the files in /etc/ should never be edited - they are system generated so edits are likely to be overwritten by an enable/disable. Editing the files in /lib/ should be avoided as an update to a package will cause your changes to be lost.

My preferred way is to create drop-in files - https://wiki.archlinux.org/index.php/systemd#Editing_provided_units probably gives the best explanation of this.

Also note from the man page

“In addition to /etc/systemd/system, the drop-in “.d/” directories for system services can be placed in /usr/lib/systemd/system or /run/systemd/system directories. Drop-in files in /etc take precedence over those in /run which in turn take precedence over those in /usr/lib. Drop-in files under any of these directories take precedence over unit files wherever located. Multiple drop-in files with different names are applied in lexicographic order, regardless of which of the directories they reside in.”

HTH

Thank you, that is indeed helpful.

I may be overlooking something, but my drop-in doesn’t seem to be honored on reboot. Specifically, the stock mpd.service file has this:

ExecStart=/usr/local/bin/mpd --no-daemon /etc/mpd.conf

And in my drop-in override, I have this:

ExecStart=
ExecStart=/usr/bin/taskset -c 2,3 /usr/local/bin/mpd --no-daemon /etc/mpd.conf

After reboot, mpd is running, but not affinitized cores 2 and 3 as I intend:

root@dietpi-music:~# ps ax | grep mpd | grep -v grep
  441 ?        Ssl    0:01 /usr/local/bin/mpd --no-daemon /etc/mpd.conf

root@dietpi-music:~# taskset -cp 441
pid 441's current affinity list: 0-3

But then I did “systemctl daemon-reload” followed by “systemctl restart mpd.service”, and now I have the affinity I want:

root@dietpi-music:~# systemctl daemon-reload
root@dietpi-music:~# systemctl  restart mpd.service

root@dietpi-music:~# ps ax | grep mpd | grep -v grep
 1618 ?        S<sl   0:01 /usr/local/bin/mpd --no-daemon /etc/mpd.conf

root@dietpi-music:~# taskset -cp 1618
pid 1618's current affinity list: 2,3

Also, is dietpi-services documented anywhere? I still would like to know if it’s more correct to work within the dietpi-services framework, or if I can do what I’ve done and work with systemd in a more “general Linux” fashion.

Thanks again!

Many config files are in the /etc directory… (actually I think all of em are there)
http://www.aboutlinux.info/2007/03/what-does-etc-stands-for-in-linuxunix.html

You can edit the configs for most services there…once changed the service that was started on the previous config needs to be restarted with the new config…thus a service restart is needed.

Also it is a VERY smart thing to do is to copy the original config file to a config.old before modifying the config…this way if something is borked…you can go back to the old config with minimal trouble.

# cp /etc/whateverfile.conf /etc/whateverfile.conf.old (or just /etc/whateverfile.old

Be careful when changing thing as super user

MattG
Instead of touching mpd.service, I suggest you use dietpi-process_tool to set it’s affinity. If I’m not mistaken, currently it would anyway override your set ones with every dietpi-services (re)start with default 0-3 :wink:.

In general dietpi-services is just a frontend for systemctl that we use to start/stop/restart all known/added services on boot, before and after software installs, updates and such, in an order that respects cross-access, e.g. webserver accessing PHP-FPM, or PHP accessing database via module and such.
So you can configure any services as you would do on any other systemd driven OS.

dietpi-process_tool runs after every dietpi-services (re)start to apply nice, affinity, scheduler policy and such. So this is the easiest way have these values adjusted. Now that I am thinking about, it should be less intrusive and only apply values for processes where user did actually choose to do :thinking:.

MichaIng - thank you! I removed the systemd mpd drop-in I mentioned above, and instead used dietpi-process_tool as you suggested. After reboot, everything had the affinity and scheduling params I wanted. That also explains why the affinity/scheduling I specified in my drop-in appeared to not be honored (as it was overridden by dietpi-process_tool).

However, at the risk of being pedantic, I would suggest that your statement, so you can configure any services as you would do on any other systemd driven OS, is a bit misleading, at least in the case of CPU affinity and/or scheduling. On any other systemd-driven OS, if I want to change process affinity and/or the scheduler, I would do it with drop-ins, as described above. Furthemore, on non-DietPi systemd OSes, I’m not aware of any extra process(es) that forces affinity/scheduling.

MattG
Jep you are right. As said, we will change the behaviour of process tool to only apply changes that were actually chosen by user via process_tool GUI.

This thing that is not well understood is that when a system file is enabled, systemd creates the required symlinks (if the actual file is not in /etc). In this way is creates wants and timer ‘files’. All installed packages should work in this way.

If you do a ‘systemctl disable’ systemd will delete the relevant file in the /etc/ directory (as that is the only way to stop it starting) whether that ‘file’ is an actual file or a symlink.

Thus, if you put the file directly in the /etc and then run a disable, the file is deleted (in fact if you create the symlink directly to /etc it will delete the actual symlinked file on disable - you need to symlink the service file to one of the other locations and then use enable).

Always better to put services files in one of the other locations that systemd scans on an enable command.

As a note - that link is quite old and systemd behaviour has changed over time (even between jessie and stretch).

MichaIng Is this tool and how you manipulate systemd documented anywhere? I ask as I have had real issues with getting Monit to start correctly and I suspect now, it is because of how DietPi interacts with systemd and appears to force certain behaviours. I had just installed Monit and created a service file for it. Ended up requiring a timer file to delay it starting.

I’m not a fan of interfering with system processes so you must have good reason for doing so. Is this simply a hang over from init days?

I note

systemd is pretty good at doing this - is it really necessary?

Could you expand on the rationale please?

baz123
We do not touch system services, just the user installed additional software services, webserver, multimedia daemons and such. We simply “disable” it, which means that systemd does not autostart them on boot and e.g. when upgraded via APT. But this only affects services (names) from a certain list, so your custom service should no be affected. You can find here which services we handle manually: DietPi/dietpi/dietpi-services at dev · Fourdee/DietPi · GitHub

Ended up requiring a timer file to delay it starting.

What you mean by “delay” it starting? Systemd starts it as fast as all units/targets listed in After= and Requires= are up. But After= only affects on services actually handled by systemd, so e.g. if you want something to start after mariadb.service, this will not work on DietPi, that is true. You could use the custom include/exclude list to include you service into dietpi-services handling or exclude one: /DietPi/dietpi/.dietpi-services_include_exclude, e.g. add + myservice or - mariadb.

Systemd does handling itself as good as it can, since it does not know when the user want to do some maintenance tasks, where running services might cause issues or even end up with corrupted data/database and such. And e.g. if you have Nextcloud running, and so prevent database corruption you stop mariadb, then webserver/PHP access, the cron job and such will throw ugly error messages, spam your log and such. So it is good to have alle related services stopped in a reasonable order. This is something systemd cant do. Also systemd does only know the dependencies, listed in the systemd unit, but e.g. webservers do not depend on PHP, only if you use them in certain ways, having an actual PHP page. PHP does not depend on e.g. a memory cache server, databases and such, but if your PHP pages or a certain PHP module and config setting require them, systemd does not know it. And you cannot add simply all possible services to the systemd unit list where service might or might not rely/depend on, based on the active/inactive modules and how you use it. So systemd does only respect the hard dependencies, while DietPi handles more possible and expected dependencies, based on usual install/usage.

Hi MichaIng yes I see all that (and by system I am meaning anything controlled by systemd services), but it can only ever be a partial solution and it may actually cause more problems than it solves, especially if it is opaque to the user (as it was to me and I’ve used DietPi for years and think it is great).

For instance, I self install EmonCMS (the full system not your package) and as well as a LAMP stack, it also needs Redis. For various reasons it does not use Redis from APT but PECL. This means Redis is installed outside of dietpi-services scope and there is no way DietPi can possibly know the dependency order. Equally EmonCMS uses Mosquitto which again you cannot know the dependency or the start order. Actually, EmonCMS is pretty robust and it sorts itself out quite happily.

So whilst I do agree with what you do to some extent, and for certain packages it may be vital, I think this should be more transparent so users are aware of what is actually happening and, where the user so desires, the services are left to systemd to manage as per the defined service files.

We simply “disable” it, which means that systemd does not autostart them on boot

Does this mean you actually use

systemctl disable service

If so that can have unexpected consequences (as I outlined elsewhere). Do you then run a

systemctl enable service

then a

systemctl start service

Looking at the code it seems you do.

I think the real concern here is how this is communicated to users. I was unaware of this process (and that probably explains some issues I had in the past) and also unaware of the ability to exclude services from DietPi control (.dietpi-services_include_exclude).

Might I suggest that, when a package that includes a service is installed, you ask the user if they wish the service to be controlled by DietPi? Alternatively an overall check after install? As a minimum, is it possible to exclude services from some sort of config tool (other than just CLI or editing a file)?

On installing and running Monit as a service,

What you mean by “delay” it starting?

In this particular case, if left to systemd to start the service file, the web interface for Monit never started properly. I tried all manner of wants, requires, after etc all to no avail. The only solution was to introduce a timer file that systemd starts so the service is delayed for 30s before being started - then it was all OK.

This has been a really useful insight as to how this all works ‘under the hood’. Thanks.

My final observation is that this does expose what I have always felt is the greatest weakness of DietPi, the documentation. So much of this useful info is buried in this forum. However, please keep up the great work you do.

FYI, another side-effect of wrapping dietpi-services around systemd: again, if you want cpu affinity/priority adjustments, you can no longer do "systemctl restart ", you need to instead use "dietpi-services restart ". This is because dietpi-services “owns” the cpu affinity/priority config.

Case in point, I changed my mpd config and restarted, first with systemd, and my affinity settings weren’t honored. I should have known better, after my participation in this thread. But it’s another use-case where dietpi-services has taken over some systemd functionality.

Now even dietpi-services does not seem to honor cpu affinity/scheduling preferences.

I’m switching between two different DACs right now, so I’m restarting MPD a fair amount.

Example, I first stop mpd via “dietpi-services stop mpd”. I verify no mpd process is running. Then I do “dietpi-services start mpd”. It starts, but is not running with the priority or affinity I have specified:

root@dietpi-music:~# ps ax | grep mpd | grep -v grep
<no output, shows mpd is not running>

root@dietpi-music:~# dietpi-services start mpd
[  OK  ] DietPi-Services | Root access verified.

 DietPi-Services
─────────────────────────────────────────────────────
 Mode: start

[  OK  ] DietPi-Services | start mpd
root@dietpi-music:~# ps ax | grep mpd | grep -v grep
18991 ?        Ssl    0:01 /usr/local/bin/mpd --no-daemon /etc/mpd.conf
root@dietpi-music:~# taskset -cp 18991
pid 18991's current affinity list: 0,1

# can see above it is now running, but pinned to cores 0,1, but should be 2,3 (see below).

root@dietpi-music:~# top -b -n 1
top - 18:31:54 up 5 days,  8:41,  2 users,  load average: 0.22, 0.12, 0.03
Tasks:  84 total,   1 running,  44 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.4 us,  0.1 sy,  0.0 ni, 99.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1000208 total,   323324 free,    37628 used,   639256 buff/cache
KiB Swap:  1097724 total,  1097724 free,        0 used.   850260 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
19008 root      20   0    8124   3116   2728 R  11.8  0.3   0:00.05 top
<snip>
18991 root      20   0  136680  22772  16840 S   0.0  2.3   0:01.08 mpd

# shoes priority/nice level is the default, which is not what is specified:

root@dietpi-music:~# cat /DietPi/dietpi/.dietpi-process_tool
<snip>
aname_save[4]='bin/mpd'
anice_save[4]=-15
aaffinity_save[4]='2,3'
aschedule_policy_save[4]='SCHED_FIFO'
aschedule_priority_save[4]='80'

After reboot, the affinity and priority is as I expect.

Is this is a bug in dietpi-services and/or dietpi-process_tooll?

MattG
Sorry for late reply:

  • I get your points and indeed I also thought in the past, that having services enabled even under dietpi-services control might be beneficial. It would be possible to use systemd unit drop-ins to add mentioned After=/Before= entries (for non-strong requirements) and e.g. as well have them started after dietpi-postboot.service, which currently does the “dietpi-service start” after boot process has finished otherwise. But the latter is actually not even required, if all wanted dependencies/order directives are added.
  • About nice/affinity/scheduler: Jep, dietpi-process_tool is meant to allow changing/setting these. dietpi-process_tool is invoked by “dietpi-services start”, but currently not, when (re)starting a single process. This is actually something we should add.
    To workaround: Just use “dietpi-services start” and you will see process tool applying nice/affinity/scheduler afterwards. Already running processes are usually ignored by systemd, so it should not hurt or interrupt that these are touched as well, at least I never faced this.