Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dbus_systemd to handle systemctl calls #220

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions resources/lib/dbus_systemd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2020-present Team LibreELEC

import dbus_utils

BUS_NAME = 'org.freedesktop.systemd1'
PATH_SYSTEMD = '/org/freedesktop/systemd1'
INTERFACE_SYSTEMD_MANAGER = 'org.freedesktop.systemd1.Manager'

def restart_unit(name, mode='replace'):
return dbus_utils.call_method(BUS_NAME, PATH_SYSTEMD, INTERFACE_SYSTEMD_MANAGER, 'RestartUnit', name, mode)

def reboot():
return dbus_utils.call_method(BUS_NAME, PATH_SYSTEMD, INTERFACE_SYSTEMD_MANAGER, 'Reboot')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a hard reboot. From https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html:

Reboot(), PowerOff(), Halt(), or KExec() may be used to ask for immediate reboot, powering down, halt or kexec based reboot of the system. Note that this does not shut down any services and immediately transitions into the reboot process. These functions are normally only called as the last step of shutdown and should not be called directly. To shut down the machine, it is generally a better idea to invoke Reboot() or PowerOff() on the systemd-logind manager object; see org.freedesktop.login1(5) for more information.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that also, but I also saw this.
https://www.freedesktop.org/software/systemd/man/systemctl.html

reboot
Shut down and reboot the system. This is mostly equivalent to systemctl start reboot.target --job-
mode=replace-irreversibly --no-block, but also prints a wall message to all users. This command is asynchronous; it will return after the reboot operation is enqueued, without waiting for it to complete.

So I'm not 100% sure which we should be using. I can use the logind method if we prefer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From practice the systemd method start with:

Mar 12 23:03:56.682161 le10mars systemd[1]: Shutting down.
Mar 12 23:03:56.761798 le10mars systemd-shutdown[1]: Syncing filesystems and block devices.
Mar 12 23:03:56.761978 le10mars systemd-shutdown[1]: Sending SIGTERM to remaining processes...

what is the final step of a gracefully shutdown.

Logind can only behave better ;-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, it seems like the systemd direct call is too harsh. They can both be tested by the following. I'll likely change it to the logind method though.

busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager Reboot
busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager Reboot b false

7 changes: 4 additions & 3 deletions resources/lib/modules/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import oeWindows
from xml.dom import minidom
import subprocess
import dbus_systemd

xbmcDialog = xbmcgui.Dialog()

Expand Down Expand Up @@ -394,15 +395,15 @@ def reset_xbmc(self, listItem=None):
open(self.XBMC_RESET_FILE, 'a').close()
oe.winOeMain.close()
oe.xbmcm.waitForAbort(1)
subprocess.call(['/usr/bin/systemctl', '--no-block', 'reboot'], close_fds=True)
dbus_systemd.reboot()

@log.log_function()
def reset_oe(self, listItem=None):
if self.ask_sure_reset('Hard') == 1:
open(self.LIBREELEC_RESET_FILE, 'a').close()
oe.winOeMain.close()
oe.xbmcm.waitForAbort(1)
subprocess.call(['/usr/bin/systemctl', '--no-block', 'reboot'], close_fds=True)
dbus_systemd.reboot()

@log.log_function()
def ask_sure_reset(self, part):
Expand Down Expand Up @@ -493,7 +494,7 @@ def do_restore(self, listItem=None):
if oe.reboot_counter(10, oe._(32371)) == 1:
oe.winOeMain.close()
oe.xbmcm.waitForAbort(1)
subprocess.call(['/usr/bin/systemctl', '--no-block', 'reboot'], close_fds=True)
dbus_systemd.reboot()
else:
log.log('User Abort!')
oe.execute(f'rm -rf {self.RESTORE_DIR}')
Expand Down
4 changes: 2 additions & 2 deletions resources/lib/modules/updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import datetime
import tempfile
from functools import cmp_to_key

import dbus_systemd
class updates(modules.Module):

ENABLED = False
Expand Down Expand Up @@ -502,7 +502,7 @@ def do_autoupdate(self, listItem=None, silent=False):
if silent == False:
oe.winOeMain.close()
oe.xbmcm.waitForAbort(1)
subprocess.call(['/usr/bin/systemctl', '--no-block', 'reboot'], close_fds=True)
dbus_systemd.reboot()
else:
delattr(self, 'update_in_progress')

Expand Down
3 changes: 2 additions & 1 deletion resources/lib/oe.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import defaults
import shutil
import hashlib, binascii
import dbus_systemd

from xml.dom import minidom
import imp
Expand Down Expand Up @@ -422,7 +423,7 @@ def set_service(service, options, state):
if not __oe__.is_service:
if service in defaults._services:
for svc in defaults._services[service]:
execute(f'systemctl restart {svc}')
dbus_systemd.restart_unit(svc)
dbg_log('oe::set_service', 'exit_function', LOGDEBUG)
except Exception as e:
dbg_log('oe::set_service', f'ERROR: ({repr(e)})')
Expand Down