Я использую скрипт для создания инкрементных резервных копий раздела btrfs с одного диска на другой.
Сценарий запускается cron.weekly в случайное время дня.
Если я закрою систему во время работы скрипта, у меня возникают проблемы с удалением старых резервных копий и новым не созданным.
Есть ли способ настроить систему на ожидание завершения скрипта? [ ! d3]
Я использую Ubuntu 16.04 с systemd.
В BackInTime я использую несколько разных методов DBus для работы со всеми основными DE. Единственный недостаток - это не будет работать для root, потому что root не имеет dbus.SessionBus.
#!/usr/bin/env python3
import sys
import dbus
from time import sleep
INHIBIT_LOGGING_OUT = 1
INHIBIT_USER_SWITCHING = 2
INHIBIT_SUSPENDING = 4
INHIBIT_IDLE = 8
INHIBIT_DBUS = (
{'service': 'org.gnome.SessionManager',
'objectPath': '/org/gnome/SessionManager',
'methodSet': 'Inhibit',
'methodUnSet': 'Uninhibit',
'interface': 'org.gnome.SessionManager',
'arguments': (0, 1, 2, 3)
},
{'service': 'org.mate.SessionManager',
'objectPath': '/org/mate/SessionManager',
'methodSet': 'Inhibit',
'methodUnSet': 'Uninhibit',
'interface': 'org.mate.SessionManager',
'arguments': (0, 1, 2, 3)
},
{'service': 'org.freedesktop.PowerManagement',
'objectPath': '/org/freedesktop/PowerManagement/Inhibit',
'methodSet': 'Inhibit',
'methodUnSet': 'UnInhibit',
'interface': 'org.freedesktop.PowerManagement.Inhibit',
'arguments': (0, 2)
})
def inhibitSuspend(app_id = sys.argv[0],
toplevel_xid = None,
reason = 'take snapshot',
flags = INHIBIT_SUSPENDING | INHIBIT_IDLE):
"""
Prevent machine to go to suspend or hibernate.
Returns the inhibit cookie which is used to end the inhibitor.
"""
if not app_id:
app_id = 'backintime'
if not toplevel_xid:
toplevel_xid = 0
for dbus_props in INHIBIT_DBUS:
try:
bus = dbus.SessionBus()
interface = bus.get_object(dbus_props['service'], dbus_props['objectPath'])
proxy = interface.get_dbus_method(dbus_props['methodSet'], dbus_props['interface'])
cookie = proxy(*[(app_id, dbus.UInt32(toplevel_xid), reason, dbus.UInt32(flags))[i] for i in dbus_props['arguments']])
print('Inhibit Suspend started. Reason: %s' % reason)
return (cookie, bus, dbus_props)
except dbus.exceptions.DBusException:
pass
print('Inhibit Suspend failed.')
def unInhibitSuspend(cookie, bus, dbus_props):
"""
Release inhibit.
"""
assert isinstance(cookie, int), 'cookie is not int type: %s' % cookie
assert isinstance(bus, dbus.bus.BusConnection), 'bus is not dbus.bus.BusConnection type: %s' % bus
assert isinstance(dbus_props, dict), 'dbus_props is not dict type: %s' % dbus_props
try:
interface = bus.get_object(dbus_props['service'], dbus_props['objectPath'])
proxy = interface.get_dbus_method(dbus_props['methodUnSet'], dbus_props['interface'])
proxy(cookie)
print('Release inhibit Suspend')
return None
except dbus.exceptions.DBusException:
print('Release inhibit Suspend failed.')
return (cookie, bus, dbus_props)
if __name__ == '__main__':
cookie, bus, dbus_props = inhibitSuspend()
print('do something here')
sleep(10)
unInhibitSuspend(cookie, bus, dbus_props)
Для Ubuntu 16.04+ с использованием systemd (по умолчанию).
systemd-inhibit --why="Wait for this script to finish" bash script.sh
===
Тест:
$ systemctl poweroff
Operation inhibited by "bash script.sh" (PID 23912 "systemd-inhibit", user rinzwind),
reason is "Wait for this script to finish".
Please retry operation after closing inhibitors and logging out other users.
===
Имеется 7 замков:
sleep блокирует системную приостановку и спящий режим, запрошенные (непривилегированными) пользователями shutdown, блокирует выключение системы высокого уровня и перезагрузка, запрошенную (непривилегированными) пользователями idle, запрещает, чтобы система перешла в режим ожидания, возможно что приводит к приостановке или отключению системы в зависимости от конфигурации. handle-power-key подавляет низкоуровневую (то есть логин-внутреннюю) обработку аппаратного ключа питания системы, позволяя (возможно, непривилегированный) внешний код обрабатывать событие. handle-suspend-key блокирует низкоуровневую обработку ключа приостановки аппаратного обеспечения. handle-hibernate-key блокирует низкоуровневую обработку системного спящего режима. handle-lid-switch подавляет низкоуровневую обработку переключателя аппаратной крышки systemd.Вероятно, вы также хотите предотвратить suspend, idle и hibernate.
fd = Inhibit("shutdown:idle", "Package Manager", "Upgrade in progress...", "block");
/* ...
do your work
... */
close(fd);
Аналогично этому вы можете запрограммировать свою версию и добавить «выключение», в конце этого скрипта (или добавить способ определения выключения должен быть следующим действием).
В BackInTime я использую несколько разных методов DBus для работы со всеми основными DE. Единственный недостаток - это не будет работать для root, потому что root не имеет dbus.SessionBus.
#!/usr/bin/env python3
import sys
import dbus
from time import sleep
INHIBIT_LOGGING_OUT = 1
INHIBIT_USER_SWITCHING = 2
INHIBIT_SUSPENDING = 4
INHIBIT_IDLE = 8
INHIBIT_DBUS = (
{'service': 'org.gnome.SessionManager',
'objectPath': '/org/gnome/SessionManager',
'methodSet': 'Inhibit',
'methodUnSet': 'Uninhibit',
'interface': 'org.gnome.SessionManager',
'arguments': (0, 1, 2, 3)
},
{'service': 'org.mate.SessionManager',
'objectPath': '/org/mate/SessionManager',
'methodSet': 'Inhibit',
'methodUnSet': 'Uninhibit',
'interface': 'org.mate.SessionManager',
'arguments': (0, 1, 2, 3)
},
{'service': 'org.freedesktop.PowerManagement',
'objectPath': '/org/freedesktop/PowerManagement/Inhibit',
'methodSet': 'Inhibit',
'methodUnSet': 'UnInhibit',
'interface': 'org.freedesktop.PowerManagement.Inhibit',
'arguments': (0, 2)
})
def inhibitSuspend(app_id = sys.argv[0],
toplevel_xid = None,
reason = 'take snapshot',
flags = INHIBIT_SUSPENDING | INHIBIT_IDLE):
"""
Prevent machine to go to suspend or hibernate.
Returns the inhibit cookie which is used to end the inhibitor.
"""
if not app_id:
app_id = 'backintime'
if not toplevel_xid:
toplevel_xid = 0
for dbus_props in INHIBIT_DBUS:
try:
bus = dbus.SessionBus()
interface = bus.get_object(dbus_props['service'], dbus_props['objectPath'])
proxy = interface.get_dbus_method(dbus_props['methodSet'], dbus_props['interface'])
cookie = proxy(*[(app_id, dbus.UInt32(toplevel_xid), reason, dbus.UInt32(flags))[i] for i in dbus_props['arguments']])
print('Inhibit Suspend started. Reason: %s' % reason)
return (cookie, bus, dbus_props)
except dbus.exceptions.DBusException:
pass
print('Inhibit Suspend failed.')
def unInhibitSuspend(cookie, bus, dbus_props):
"""
Release inhibit.
"""
assert isinstance(cookie, int), 'cookie is not int type: %s' % cookie
assert isinstance(bus, dbus.bus.BusConnection), 'bus is not dbus.bus.BusConnection type: %s' % bus
assert isinstance(dbus_props, dict), 'dbus_props is not dict type: %s' % dbus_props
try:
interface = bus.get_object(dbus_props['service'], dbus_props['objectPath'])
proxy = interface.get_dbus_method(dbus_props['methodUnSet'], dbus_props['interface'])
proxy(cookie)
print('Release inhibit Suspend')
return None
except dbus.exceptions.DBusException:
print('Release inhibit Suspend failed.')
return (cookie, bus, dbus_props)
if __name__ == '__main__':
cookie, bus, dbus_props = inhibitSuspend()
print('do something here')
sleep(10)
unInhibitSuspend(cookie, bus, dbus_props)
Для Ubuntu 16.04+ с использованием systemd (по умолчанию).
systemd-inhibit --why="Wait for this script to finish" bash script.sh
===
Тест:
$ systemctl poweroff
Operation inhibited by "bash script.sh" (PID 23912 "systemd-inhibit", user rinzwind),
reason is "Wait for this script to finish".
Please retry operation after closing inhibitors and logging out other users.
===
Имеется 7 замков:
sleep блокирует системную приостановку и спящий режим, запрошенные (непривилегированными) пользователями shutdown, блокирует выключение системы высокого уровня и перезагрузка, запрошенную (непривилегированными) пользователями idle, запрещает, чтобы система перешла в режим ожидания, возможно что приводит к приостановке или отключению системы в зависимости от конфигурации. handle-power-key подавляет низкоуровневую (то есть логин-внутреннюю) обработку аппаратного ключа питания системы, позволяя (возможно, непривилегированный) внешний код обрабатывать событие. handle-suspend-key блокирует низкоуровневую обработку ключа приостановки аппаратного обеспечения. handle-hibernate-key блокирует низкоуровневую обработку системного спящего режима. handle-lid-switch подавляет низкоуровневую обработку переключателя аппаратной крышки systemd.Вероятно, вы также хотите предотвратить suspend, idle и hibernate.
fd = Inhibit("shutdown:idle", "Package Manager", "Upgrade in progress...", "block");
/* ...
do your work
... */
close(fd);
Аналогично этому вы можете запрограммировать свою версию и добавить «выключение», в конце этого скрипта (или добавить способ определения выключения должен быть следующим действием).