// dbus
sd_bus* bus;
+ int inhibitfd;
// Kerberos Authentication
struct {
return r;
}
+/*
+ * Prevents that the system can be shut down when there are jobs running...
+ */
+static int pakfire_daemon_inhibit_shutdown(struct pakfire_daemon* daemon) {
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_message* reply = NULL;
+ int r;
+
+ // Don't do this again if we are already holding the lock
+ if (daemon->inhibitfd >= 0)
+ return 0;
+
+ // Call the Inhibit method
+ r = sd_bus_call_method(
+ daemon->bus,
+
+ // Destination, Path & Interface
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+
+ // Method
+ "Inhibit",
+
+ // Error
+ &error,
+
+ // Reply
+ &reply,
+
+ // Arguments
+ "ssss",
+ "shutdown:sleep:idle",
+ "pakfire-daemon",
+ "Prevent shutdown while build jobs are running",
+ "block"
+ );
+ if (r < 0) {
+ ERROR(daemon->ctx, "Failed to inhibit shutdown: %s\n", error.message);
+ goto ERROR;
+ }
+
+ // Read the file descriptor from the reply
+ r = sd_bus_message_read(reply, "h", &daemon->inhibitfd);
+ if (r < 0) {
+ ERROR(daemon->ctx, "Failed to parse response message: %s\n", strerror(-r));
+ goto ERROR;
+ }
+
+ DEBUG(daemon->ctx, "Successfully inhibited shutdown\n");
+
+ERROR:
+ sd_bus_error_free(&error);
+ if (reply)
+ sd_bus_message_unref(reply);
+
+ return r;
+}
+
+static int pakfire_daemon_release_inhibit_shutdown(struct pakfire_daemon* daemon) {
+ // If we don't hold the lock, we cannot release it
+ if (daemon->inhibitfd >= 0) {
+ close(daemon->inhibitfd);
+ daemon->inhibitfd = -EBADF;
+
+ DEBUG(daemon->ctx, "Released shutdown inhibition\n");
+ }
+
+ return 0;
+}
+
/*
Called when a new job has been received
*/
struct json_object* data = NULL;
int r;
+ // Inhibit shutdown
+ r = pakfire_daemon_inhibit_shutdown(daemon);
+ if (r < 0)
+ goto ERROR;
+
// Fetch the data from the message
if (!json_object_object_get_ex(m, "data", &data)) {
ERROR(daemon->ctx, "Job does not have any data\n");
-
- return -EINVAL;
+ r = -EINVAL;
+ goto ERROR;
}
// Create a new job
}
static void pakfire_daemon_free(struct pakfire_daemon* daemon) {
+ // Release shutdown inhibition
+ pakfire_daemon_release_inhibit_shutdown(daemon);
+
if (daemon->krb5.principal)
krb5_free_principal(daemon->krb5.ctx, daemon->krb5.principal);
if (daemon->krb5.ccache)
// Initialize the reference counter
d->nrefs = 1;
+ // Initialize file descriptors
+ d->inhibitfd = -EBADF;
+
// Read configuration
r = pakfire_daemon_configure(d);
if (r < 0)
Called after a job has exited
*/
int pakfire_daemon_job_finished(struct pakfire_daemon* daemon, struct pakfire_job* job) {
+ int r;
+
DEBUG(daemon->ctx, "Removing job %p\n", job);
for (unsigned int i = 0; i < MAX_JOBS; i++) {
// Now we have one less job running
daemon->running_jobs--;
+ // Release the shutdown inhibition if there are no more jobs running
+ if (!daemon->running_jobs) {
+ r = pakfire_daemon_release_inhibit_shutdown(daemon);
+ if (r < 0)
+ return r;
+ }
+
return 0;
}