|
|
2ff057 |
#include "system.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <dbus/dbus.h>
|
|
|
2ff057 |
#include <sys/types.h>
|
|
|
2ff057 |
#include <sys/stat.h>
|
|
|
2ff057 |
#include <unistd.h>
|
|
|
2ff057 |
#include <rpm/rpmlog.h>
|
|
|
2ff057 |
#include <rpm/rpmts.h>
|
|
|
2ff057 |
#include "lib/rpmplugin.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
static int lock_fd = -1;
|
|
|
2ff057 |
|
|
|
2ff057 |
static int inhibit(void)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
DBusError err;
|
|
|
2ff057 |
DBusConnection *bus = NULL;
|
|
|
2ff057 |
DBusMessage *msg = NULL;
|
|
|
2ff057 |
DBusMessage *reply = NULL;
|
|
|
2ff057 |
int fd = -1;
|
|
|
2ff057 |
|
|
|
2ff057 |
dbus_error_init(&err;;
|
|
|
2ff057 |
bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err;;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (bus) {
|
|
|
2ff057 |
msg = dbus_message_new_method_call("org.freedesktop.login1",
|
|
|
2ff057 |
"/org/freedesktop/login1",
|
|
|
2ff057 |
"org.freedesktop.login1.Manager",
|
|
|
2ff057 |
"Inhibit");
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (msg) {
|
|
|
2ff057 |
const char *what = "idle:sleep:shutdown";
|
|
|
2ff057 |
const char *mode = "block";
|
|
|
2ff057 |
const char *who = "RPM";
|
|
|
2ff057 |
const char *reason = "Transaction running";
|
|
|
2ff057 |
|
|
|
2ff057 |
dbus_message_append_args(msg,
|
|
|
2ff057 |
DBUS_TYPE_STRING, &what,
|
|
|
2ff057 |
DBUS_TYPE_STRING, &who,
|
|
|
2ff057 |
DBUS_TYPE_STRING, &reason,
|
|
|
2ff057 |
DBUS_TYPE_STRING, &mode,
|
|
|
2ff057 |
DBUS_TYPE_INVALID);
|
|
|
2ff057 |
|
|
|
2ff057 |
reply = dbus_connection_send_with_reply_and_block(bus, msg, -1, &err;;
|
|
|
2ff057 |
dbus_message_unref(msg);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (reply) {
|
|
|
2ff057 |
dbus_message_get_args(reply, &err,
|
|
|
2ff057 |
DBUS_TYPE_UNIX_FD, &fd,
|
|
|
2ff057 |
DBUS_TYPE_INVALID);
|
|
|
2ff057 |
dbus_message_unref(reply);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (dbus_error_is_set(&err)) {
|
|
Packit Service |
0cfc1f |
if (!dbus_error_has_name(&err, DBUS_ERROR_NO_SERVER) &&
|
|
Packit Service |
0cfc1f |
!dbus_error_has_name(&err, DBUS_ERROR_FILE_NOT_FOUND))
|
|
Packit Service |
0cfc1f |
{
|
|
Packit Service |
0cfc1f |
rpmlog(RPMLOG_WARNING,
|
|
|
2ff057 |
"Unable to get systemd shutdown inhibition lock: %s\n",
|
|
|
2ff057 |
err.message);
|
|
Packit Service |
0cfc1f |
}
|
|
|
2ff057 |
dbus_error_free(&err;;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (bus) {
|
|
|
2ff057 |
dbus_connection_close(bus);
|
|
|
2ff057 |
dbus_connection_unref(bus);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return fd;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC systemd_inhibit_init(rpmPlugin plugin, rpmts ts)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
struct stat st;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (lstat("/run/systemd/system/", &st) == 0) {
|
|
|
2ff057 |
if (S_ISDIR(st.st_mode)) {
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return RPMRC_NOTFOUND;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC systemd_inhibit_tsm_pre(rpmPlugin plugin, rpmts ts)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
|
|
|
2ff057 |
lock_fd = inhibit();
|
|
|
2ff057 |
|
|
|
2ff057 |
if (lock_fd >= 0) {
|
|
|
2ff057 |
rpmlog(RPMLOG_DEBUG, "System shutdown blocked (fd %d)\n", lock_fd);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC systemd_inhibit_tsm_post(rpmPlugin plugin, rpmts ts, int res)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (lock_fd >= 0) {
|
|
|
2ff057 |
close(lock_fd);
|
|
|
2ff057 |
lock_fd = -1;
|
|
|
2ff057 |
rpmlog(RPMLOG_DEBUG, "System shutdown unblocked\n");
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
struct rpmPluginHooks_s systemd_inhibit_hooks = {
|
|
|
2ff057 |
.init = systemd_inhibit_init,
|
|
|
2ff057 |
.tsm_pre = systemd_inhibit_tsm_pre,
|
|
|
2ff057 |
.tsm_post = systemd_inhibit_tsm_post,
|
|
|
2ff057 |
};
|