apcupsd and systemd - killpower issues

Hi All!

I’m trying to make things working with apcupsd under OpenSuse 12.2.

Here is my configuration:
I need a system power down and an UPS power down after the onbattery script is called
My UPS powers directly the PC and it is connected to it by USB. Apcupsd is configured, up and running
Once the UPS is on battery, apcupsd calls the onbattery script.
In onbattery script, I take care of creating /etc/apcupsd/powerfail file
In the /etc/init.d/halt script there is the $HALT_POWERDOWN_INSERT line that should call /etc/init.d/apcupsd try-powerdown, as it is configured in /etc/sysconfig editor after apcupsd is installed
I edited this file to have /etc/init.d/powerdown instead to make sure that, even if power returns, the UPS is shut down anyway.

Now, after being a little bit puzzled about the reason why the init script was not called, I noticed that the init sistem passed from sysv to systemd, end everything is changed.

Do you know a way to make it working using systemd or I have to switch back to sysv scripts?
I don’t like to use legacy apps to workaround issues, but, as obvious, with sysv everything works fine.

At least, anyway, systemd makes unusable part of /etc/sysconfig scripts and apcupsd configuration gets broken, thus, IMMO it may be considered definitively (partially) a bug…

Advices are welcome.

If you run this command, what do you get?

> systemctl status apcupsd.service

Here is the output that I see.

apcupsd.service - LSB: Start the apcupsd daemon
          Loaded: loaded (/etc/init.d/apcupsd)
          Active: active (running) since Thu, 11 Oct 2012 20:33:42 -0500; 18h ago
         Process: 900 ExecStart=/etc/init.d/apcupsd start (code=exited, status=0/SUCCESS)
          CGroup: name=systemd:/system/apcupsd.service
                  └ 931 /usr/sbin/apcupsd

Thank You,

Thanks for your reply.

To answer your question, the output is more or less the same you got. The service is up and running.

Here is also the output from the following command:


> apcaccess


APC      : 001,044,1073
DATE     : 2012-10-15 09:32:13 +0200  
HOSTNAME : my-hostname
VERSION  : 3.14.8 (16 January 2010) suse
UPSNAME  : my-hostname
CABLE    : USB Cable
MODEL    : Back-UPS CS 650 
UPSMODE  : Stand Alone
STARTTIME: 2012-10-15 09:31:21 +0200  
STATUS   : ONLINE 
LINEV    : 228.0 Volts
LOADPCT  :  18.0 Percent Load Capacity
BCHARGE  : 100.0 Percent
TIMELEFT :  26.2 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME  : 0 Seconds
OUTPUTV  : 230.0 Volts
SENSE    : Medium
DWAKE    : 000 Seconds
DSHUTD   : 000 Seconds
LOTRANS  : 180.0 Volts
HITRANS  : 266.0 Volts
RETPCT   : 000.0 Percent
ITEMP    : 29.2 C Internal
ALARMDEL : Always
BATTV    : 13.6 Volts
LINEFREQ : 50.0 Hz
LASTXFER : No transfers since turnon
NUMXFERS : 0
TONBATT  : 0 seconds
CUMONBATT: 0 seconds
XOFFBATT : N/A
SELFTEST : OK
STESTI   : None
STATFLAG : 0x07000008 Status Flag
SERIALNO : 4B1217P15930  
BATTDATE : 2012-04-25
NOMOUTV  : 230 Volts
NOMINV   : 230 Volts
NOMBATTV :  12.0 Volts
NOMPOWER : 400 Watts
FIRMWARE : 817.v9.I USB FW:v9
APCMODEL : Back-UPS CS 650 
END APC  : 2012-10-15 09:32:14 +0200  

I add here also some comments about things I considered trivial, but it’s better to explain.

  1. apcupsd is up and running. The onbattery script I’m using to trigger shutdown is working.
  2. My issue is not just shutting down the system, but also shut down the UPS using killpower command. After the system is shut down, the UPS shall turn off itself.
  3. The –killpower
    option makes sure that the system is in power fail condition before settings UPS to shut down within some time. I always make sure that the /etc/apcupsd/powerfail file is in place before system shutdown. This file is used to tell the system that mains power is gone. 1. The command works fine in sysv. If you take a look at halt scripts in /etc/init.d directory, here is a brief description of what happens:
  • The halt script has a section called $HALT_POWERDOWN_INSERT that is configured in /etc/sysconfig directory. The default setting once apcupsd is installed is /etc/init.d/apcupsd try-powerdown
    . I changed it, to make things a little bit easier, to /etc/init.d/apcupsd powerdown - The script /etc/init.d/apcupsd powerdown
    calls /sbin/apcupsd-lite --killpower, that makes sure that the powerfail file exists and issues killpower command to UPS - Since no halt script is called using systemd, this instruction (that is problematic since it is to be run in the very last sections of the halt sequence but it still needs read access to the filesystem, but is works in the actual configuration) gets never called, and the ups lasts in ON state until it is discharged.

So I am not sure that the halt script is being run under systemd. If I look at YaST / System / System Services I see no halt is listed there. This is where I look to see if the init.d script is picked up by systemd straight on. If I look at /lib/systemd/system/halt.service it says it will run the command “/bin/systemctl --force halt” should this come up and so I am thinking you would have to modify this service file to do something different with halt, but I guess I am not for sure as I have not tried to determine just what systemd does with halt. In a similar fashion, I had found that the after.local file was not being run any more and I have a blog on the subject here:

systemd and using the after.local script in openSUSE 12.1/12.2 - Blogs - openSUSE Forums

And I found that after installing dkms, it did not run from the init.d folder either and this is what I did with it:

DKMS, systemd & Virtual Box - How to get Dynamic Kernel Module Support to work in openSUSE 12.1/12.2 - Blogs - openSUSE Forums

Its possible you must do something as well to get the action you desire on system halt. If you do make a change that works, be sure to come share the solution with us.

Thank You,

If you do not want to learn systemd, the simplest way is to add your command(s) to /etc/init.d/halt.local. This is executed after everything is stopped but before system is physically shut down. It means that you still have read access to root filesystem, but all other filesystems are not mounted anymore.

I can explain how to write native systemd unit to do the same if you are interested. This would be better as it could be packaged in apcd and installed automatically.

Somewehere I read that /etc/init.d directory is ignored under systemd. Maybe this is not the case, but I’m almost sure that /etc/init.d/halt script is not called under systemd. Perhaps this could be the expected behavoir.
I’ll try to add commands to /etc/init.d/halt.local file (that actually is empty), and try to see if the these gets called.
Sending commands to USB UPS is tricky when it is done at the end of the boot process, USB peripherals may or may not work, and the same is for system files read access.

I’ll try to play also with systemd and its configuration files. It takes time, since I have to work out the behavoir of systemd. And time is always less than needed…

If you can give me advices on how to run $HALT_POWERDOWN_INSERT in system shutdown process, maybe this will be fixed also in future system distributions, and I’ll appreciate it.
Sorry I have to bother you with such questions, but new system features always need time to be learned, and sometimes it hard to find the starting point without being addressed (or without reading full manuals). Even more difficul is configuring them by attempts.

As a short introduction. Systemd works with concept of “units” and “dependencies”. “Units” have some properties which may include command(s) to execute and represent objects or actions. Units normally have states (started, stopped, etc). 'Dependencies" represent relations between unit (states) - like “starting this unit requires other unit to be started”, “this unit has to be started before other unit” etc. There are many unit types that differ in properties associated with them. Most commonly encountered are “service” - which is roughly equivalent to well known SysV initscript - and “target” which represents collection of unit states. So starting e.g. target “multiuser.target” will automatically start all units that are required by this target (also transitively) in order defined by their dependencies.

When system shuts down, systemd (actually systemctl) “starts” one of predefined targets (halt.target, etc) which triggers stopping of running units. Two milestones are “shutdown.target” and “final.target”. All running units are usually made to Conflict with “shutdown.target” and halt.target implicitly triggers “start” of shutdown.target. So all running units (services) are being stopped. final.target is special, it allows you to order actions after shutdown.target but before system is physically turned off.

So your systemd unit may look like this

[Unit]
Description=APC UPS killpower
ConditionPathExists=/path/to/apcupsd/flag/file
DefaultDependencies=no
After=shutdown.target
Before=final.target

[Service]
Type=oneshot
ExecStart=/path/to/killpower/command --with --arguments
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes

[Install]
WantedBy=shutdown.target

This assumes that APC UPS daemon creates some file to signal power failure. This seems to be pretty much self explanatory. After and Before order execution. WantedBy makes it to be automatically added to state transition when shutdown.target is called. Now place it into /etc/systemd/system/killpower.service, execute

systemctl enable killpower.service
systemctl daemon-reload

and it should be fine. You also need something that removes flag file during system startup. Or even better would be to have file created under /run filesystem. I have to check whether it is unmounted or not, but likely not (it is really too important to be just killed).

This probably better should be “After=shutdown.target umount.target” to make sure everything is really unmounted at this point.

systemctl enable killpower.service
systemctl daemon-reload

Second command is redundant normally.

One thing to consider is we continue to install applications, such as dkms or apcupsd who continue to place files in the init.d folder where somethings work and others do not. Only when something does not work properly might someone slog through the bs to figure out why a function does not work under systemd and to kludge together some kind of fix. It is too bad applications are not identified as working or not working with systemd as if we only knew, we might start something in an effort to fix them. It seems that the switch to systemd is completely separated from the reality of our installation application repositories. It is true that standard items included with a normal openSUSE releases seem to be tested properly to work with systemd, but that is about the extent of it. Must we dig up each every maintainer of an application is our repositories and ask if they have tested their program with systemd in mind? While I am not sure of an answer to such a question, time and time again, the use of systemd breaks well worn programs we have come to use over the years.

Thank You,

Well … I agree that HALT_POWERDOWN_INSERT was somehow forgotten when transitioning from /etc/init.d/halt to native systemd shutdown. Care to open bug report?

But to be honest … this is almost the only case I can remember. I do not know how dkms was integrated in openSUSE before, but I had no problems with it in Mandriva back in the past during systemd transition. And “each and every” looks like a bit of generalizing when you speak about two packages so far :slight_smile:

Notice that both are rather unusual. They integrate deep into startup/shutdown sequence and need to be executed at the very precise moments. That makes them special. “Normal” services usually continue to work. Can you give example of standard scripts that break?

So consider I am no systemd expert but, the after.local script no longer works though I serve up a kluge that kind of works. We can see that halt does not work and apcupsd is a very common application that uses it. And, I had to come up with a fix under openSUSE 12.1 to get dkms to work properly as it simple did not work. I continue to use my same fix under 12.2, but I guess I did not try using dkms without the fix under openSUSE 12.2. All of these examples are important applications and I can’t say for sure what else does not work. I know that we could not get xen to work under 12.1 if systemd was being used though I guess I also hear it only works with 64 bit these days. And really, its not some sort of rejection to systemd per say, but what systemd is doing and how it replaces what we used to use is just not that simple to understand. Just reading your short introduction is enough to cause many followers to fall of the tracks. One thing is for sure, I do not wish to discourage your attempt to help others. Anyone with a good understanding of just how systemd works is VERY WELCOME here. Trust me on that one, we want your input and we want your help and thank you for providing it.

Thank You,

I started a bug report here: https://bugzilla.novell.com/show_bug.cgi?id=785156

I encourage anyone with input on the subject to please add your comments there.

Thank You,

On 2012-10-15 19:36, jdmcdaniel3 wrote:

> It is true that standard items included with a normal openSUSE
> releases seem to be tested properly to work with systemd, but that is
> about the extent of it. Must we dig up each every maintainer of an
> application is our repositories and ask if they have tested their
> program with systemd in mind? While I am not sure of an answer to such a
> question, time and time again, the use of systemd breaks well worn
> programs we have come to use over the years.

If I interpreted correctly what I read, some said that they would not
adapt to systemd, they would not invest time on it.


Cheers / Saludos,

Carlos E. R.
(from 12.1 x86_64 “Asparagus” at Telcontar)

I do not see dkms package in openSUSE repository so it is hard to comment. Is there any standard package for openSUSE? Or documentation “DKMS on openSUSE”? In the former case it is straightforward to add systemd unit to it; in the latter description simply has to be extended for 12.2 case.

dkms comes from the Packman repository. It is primarily used for the recompile of the VirtualBox binary driver after a kernel version change but I also can use for the nVIDIA driver. Here are a couple of blogs I have on using dkms.

DKMS, systemd & Virtual Box - How to get Dynamic Kernel Module Support to work in openSUSE 12.1/12.2 - Blogs - openSUSE Forums

AND

S.A.N.D.I. - SuSE Automated NVIDIA Driver Installer - Version 1.47 - Blogs - openSUSE Forums

And I did get it to work after some research, not sure I would call it easy, at least easy at the time. I also have a blog on getting the after.local file to work:

systemd and using the after.local script in openSUSE 12.1/12.2 - Blogs - openSUSE Forums

And its really during local I guess, but I was unable to come up with a real after local operation under systemd. I understand that a change may exist in the future with systemd that might allow that to happen.

Thank You,

OK, so we have package for 12.2 that does not work under 12.2. Then this package has to be fixed, right? I do not know what is the support model for packman. Do they have some mailing list or ticketing system?

I don’t know the answer to that question, but I will try to find out tonight. Here is their Web Site: PackMan :: home

Thank You,

Sorry for the delay in response.
First, many thanks to arvidjaar for his kind and exhaustive reply. I was intimidated by the information on systemd website, but things are easier than expected.
Here is my code, that worked simply as needed.

Some notes:

  1. The powerdown file is created and removed by apcupsd (or by my application).
  2. Apcupsd with killpower option refuses to issue the command if such file is not available. The condition added here could be useful to suppress some warnings.
  3. Still, $HALT_POWERDOWN_INSERT is not executed. It is not needed now, but I don’t know if systemd can accept system configured variables as commands. It seems it cannot, since I tried without result. If so, this configuration should be removed from Suse and a similar file should be added in apcupsd package (or in an additional package for system shutdown).

in /etc/systemd/system/killpower.service


[Unit] 
Description=APC UPS killpower 
ConditionPathExists=/etc/apcupsd/powerfail 
DefaultDependencies=no 
After=shutdown.target 
Before=final.target  

[Service] 
Type=oneshot 
ExecStart=/sbin/apcupsd-lite --killpower 
TimeoutSec=0 
StandardOutput=tty 
RemainAfterExit=yes  

[Install] 
WantedBy=shutdown.target


Thus, after executing both commands:


systemctl enable killpower.service 
systemctl daemon-reload

On power out apcupsd turn off UPS correctly. This job is done here even better than under SysV.

Another small clarification:
Bug report posted by jdmcdaniel3 (https://bugzilla.novell.com/show_bug.cgi?id=785156) says that system is not shut down by apcupsd and that the expected result is that PC is shut down by apcupsd before battery runs out.
This is not exactly true.
The user can select the point where system is shut down, either on power fail, battery low or other triggers from apcupsd. Perhaps there could be some settings in power management, but it’s easy to call commands into apcupsd scripts.
The issue is that, on the shutdown process, an attempt to kill UPS power is to be done, otherwise UPS will keep beeping until it gets discharged (or until user intervention).

I think this issue can be considered solved, unless you are keeping discussion on other packages that gets broken on change to systemd.

Again, many thanks for your support and your prompt replies.

On 2012-10-18 16:26, gnarlo wrote:
> I
> was intimidated by the information on systemd website,

There is a chapter here on systemd:
openSUSE Reference


Cheers / Saludos,

Carlos E. R.
(from 12.1 x86_64 “Asparagus” at Telcontar)

Now that’s constructive attitude :slight_smile:

https://bugzilla.novell.com/show_bug.cgi?id=785701