How to restart a service if its dependent service is restarted
You can use PartOf
.
[Unit]
After=foo.service
Requires=foo.service
PartOf=foo.service
From the systemd.unit
man page:
PartOf=
Configures dependencies similar to Requires=, but limited to stopping and restarting of units. When systemd stops or restarts the units listed here, the action is propagated to this unit. Note that this is a one-way dependency — changes to this unit do not affect the listed units.
Restart a service with dependent services?
Alright, finally implemented this. I've posted it as a separate answer as I had already come to this conclusion in the original update to my question, which was posted prior to the first answer.
Again, the StartService()
, StopService()
and RestartService()
methods follow the conventions outlined in the examples and such already referenced in the question itself (i.e. they wrap Start/Stop behavior to avoid "already started/stopped"-type exceptions) with the addendum that if a Service
is passed in (as is the case below), Refresh()
is called on that service before checking its Status
.
public static void RestartServiceWithDependents(ServiceController service, TimeSpan timeout)
{
int tickCount1 = Environment.TickCount; // record when the task started
// Get a list of all services that depend on this one (including nested
// dependencies)
ServiceController[] dependentServices = service.DependentServices;
// Restart the base service - will stop dependent services first
RestartService(service, timeout);
// Restore dependent services to their previous state - works because no
// Refresh() has taken place on this collection, so while the dependent
// services themselves may have been stopped in the meantime, their
// previous state is preserved in the collection.
foreach (ServiceController dependentService in dependentServices)
{
// record when the previous task "ended"
int tickCount2 = Environment.TickCount;
// update remaining timeout
timeout.Subtract(TimeSpan.FromMilliseconds(tickCount2 - tickCount1));
// update task start time
tickCount1 = tickCount2;
switch (dependentService.Status)
{
case ServiceControllerStatus.Stopped:
case ServiceControllerStatus.StopPending:
// This Stop/StopPending section isn't really necessary in this
// case as it doesn't *do* anything, but it's included for
// completeness & to make the code easier to understand...
break;
case ServiceControllerStatus.Running:
case ServiceControllerStatus.StartPending:
StartService(dependentService, timeout);
break;
case ServiceControllerStatus.Paused:
case ServiceControllerStatus.PausePending:
StartService(dependentService, timeout);
// I don't "wait" here for pause, but you can if you want to...
dependentService.Pause();
break;
}
}
}
How can I configure a systemd service to restart periodically?
Yes, you can make your service to restart it periodically by making your service of Type=notify
.
Add this option in [Service] section of your service file along with Restart=always
and give WatchdogSec=xx
, where xx is the time period in second you want to restart your service. Here your process will be killed by systemd after xx time period and will be restarted by systemd again.
for eg.
[Unit]
.
.
[Service]
Type=notify
.
.
WatchdogSec=10
Restart=always
.
.
[Install]
WantedBy= ....
Systemd timer for a bound service restarts the service it is bound to
Here are the simplest units that meet your constraints:
test-a.service
[Service]
ExecStart=sleep 3600 # long-running command
test-b.service
[Service]
ExecStart=date # short command
test-b.timer
[Unit]
After=test-a.service
BindsTo=test-a.service # makes test-b.timer stop when test-a.service stops
[Timer]
OnCalendar=* *-*-* *:*:00
[Install]
WantedBy=test-a.service # makes test-b.timer start when test-a.service starts
Don't forget to
systemctl daemon-reload
systemctl disable test-b.timer
systemctl enable test-b.timer
To apply the changes in the[Install]
section.
Explanations:
- what you want is to bind
a.service
withb.timer
, notb.service
b.service
is only a short command, andsystemctl start b.service
will only run the command, not start the associated timer- only
systemctl start b.timer
will start the timer - The
WantedBy
tells systemd to starttest-b.timer
whentest-a.service
starts - The
BindsTo
tellstest-b.timer
to stop when test-a.service stops - The
After
only ensures thattest-b.timer
is not started at the same time thantest-a.service
: it will force systemd to starttest-b.timer
aftertest-a.service
has finished starting.
About the behaviour you observed:
- When you stopped your
a.service
, theb.timer
was still active and it tried startingb.service
to run its short command. Since yourb.service
specifiedBindsTo=a.service
, systemd thought thatb.service
requireda.service
to be started also, and effectively restarteda.service
forb.service
to run correctly.
Automatically restart a service after unattended updates under systemd
Use Restart=always
if you want it to run at all times. When mysql
service update happens, this service does a clean stop
and therefore systemd
doesn't restart it. You have Restart=on-failure
set, which only restarts if the stop has a return code other than 0
.
Restart = always
RestartSec = 10
RestartSec
Configures the time to sleep before restarting a service (as configured with Restart=). Takes a unit-less value in seconds, or a time span value such as "5min 20s". Defaults to 100ms.
Related Topics
Linux Command Line Howto Accept Pairing for Bluetooth Device Without Pin
Walking Page Tables of a Process in Linux
How to Capture All of My Compiler's Output to a File
How to Start Tomcat with Output on Console in Linux
What Do the .Eh_Frame and .Eh_Frame_Hdr Sections Store, Exactly
What Is the Use of _Iomem in Linux While Writing Device Drivers
Can't Change Tomcat 7 Heap Size
How to Post Raw Body Data with Curl
Add Text to File at Certain Line in Linux
How to Create a Callback for "Monitor Plugged" on an Intel Graphics
How to Align the Columns of a Space Separated Table in Bash
Linux Process in Background - "Stopped" in Jobs
No Local Gulp Install Found Even After Installing Npm Install -G Gulp
How to Remove the Win10's Path from Wsl
What Is Partition Checker in Arm Secure Mode