Skip to content

Commit

Permalink
Merge pull request #17 from SUSE/fix-job-waiting
Browse files Browse the repository at this point in the history
Fix job waiting
  • Loading branch information
liangxin1300 authored Feb 6, 2024
2 parents bef84c5 + 0ae27f8 commit c6f5238
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ sapwmp_capture_CFLAGS = \
$(LIBSYSTEMD_CGLAGS)
sapwmp_capture_LDADD = \
$(LIBSYSTEMD_LIBS)
sapwmp_capture_SOURCES = src/main.c src/config.c src/log.c
sapwmp_capture_SOURCES = src/main.c src/config.c src/log.c src/dbus-job.c
117 changes: 117 additions & 0 deletions src/dbus-job.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "dbus-job.h"
#include "log.h"

/*
* The code waiting for org.freedesktop.systemd1.Manager.JobRemoved signal is
* based on systemd's src/shared/bus-wait-for-jobs.c
*/

struct waited_job {
const char *job;
char *result;
};

static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
assert(m);

log_info("D-Bus connection terminated while waiting for jobs.");
sd_bus_close(sd_bus_message_get_bus(m));

return 0;
}

static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
struct waited_job *wj = userdata;
const char *path, *result;
int r;

assert(m);

r = sd_bus_message_read(m, "uoss", /* id = */ NULL, &path, /* unit = */ NULL, &result);
if (r < 0) {
log_error("DBus signal parsing error: %s", strerror(r));
return 0;
}

if (strcmp(path, wj->job))
return 0;

wj->result = strdup(result);
/* best effort upon ENOMEM */
if (!wj->result)
wj->result = "";

return 0;
}

int bus_setup_wait(sd_bus *bus, struct waited_job *wj) {
int r;

/* When we are a bus client we match by sender. Direct connections OTOH have no initialized sender
* field, and hence we ignore the sender then */
r = sd_bus_add_match(
bus,
NULL, /* slot removed eventually with sd_bus */
"type='signal',"
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"member='JobRemoved',"
"path='/org/freedesktop/systemd1'",
match_job_removed, wj);
if (r < 0)
return r;

r = sd_bus_add_match(
bus,
NULL, /* slot removed eventually with sd_bus */
"type='signal',"
"sender='org.freedesktop.DBus.Local',"
"interface='org.freedesktop.DBus.Local',"
"member='Disconnected'",
match_disconnected, wj);
if (r < 0)
return r;

return 0;
}

static int bus_process_wait(sd_bus *bus, struct waited_job *wj) {
int r;

for (;;) {
r = sd_bus_process(bus, NULL);
if (r < 0)
return r;
if (r > 0 && wj->result) {
if (wj->result[0] == '\0')
return -ENOMEM;
return 0;
}

r = sd_bus_wait(bus, UINT64_MAX);
if (r < 0)
return r;
}
}

int wait_for_job(sd_bus *bus, const char *job) {
struct waited_job wj = { .job = job };
int r;

r = bus_setup_wait(bus, &wj);
if (r < 0)
return r;

r = bus_process_wait(bus, &wj);
if (r < 0)
return r;
log_debug("Job %s finished, result=%s", job, wj.result);
free(wj.result);
return r;
}

4 changes: 4 additions & 0 deletions src/dbus-job.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <systemd/sd-bus.h>

int wait_for_job(sd_bus *bus, const char *job);

6 changes: 5 additions & 1 deletion src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
#define MAX_FORMAT 128

static int use_syslog;
static int *verbose_p;

void log_init(void) {
void log_init(int *v_p) {
if (!isatty(STDERR_FILENO)) {
use_syslog = 1;
}
verbose_p = v_p;
}

static inline void vprintlog(int level /*unused*/, const char *fmt, va_list ap) {
Expand All @@ -23,6 +25,8 @@ static inline void vprintlog(int level /*unused*/, const char *fmt, va_list ap)

void write_log(int level, const char *fmt, ...) {
va_list ap;
if (level >= LOG_DEBUG && !*verbose_p)
return;

va_start(ap, fmt);
if (use_syslog)
Expand Down
2 changes: 1 addition & 1 deletion src/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define log_info(...) write_log(LOG_INFO, __VA_ARGS__)
#define log_debug(...) write_log(LOG_DEBUG, __VA_ARGS__)

void log_init(void);
void log_init(int *v_p);
void write_log(int level, const char *fmt, ...);

void exit_error(int status, int e, const char *fmt, ...) __attribute__ ((noreturn));
22 changes: 16 additions & 6 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "config.h"
#include "log.h"
#include "dbus-job.h"

#define MAX_PIDS 16
#define CONF_FILE "/etc/sapwmp.conf"
Expand Down Expand Up @@ -76,8 +77,9 @@ int already_in_slice(pid_t pid, const char *target_slice) {
int migrate(sd_bus *bus, const char *target_unit, const char *target_slice,
struct unit_config *properties,
size_t n_pids, pid_t *pids) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error bus_error = SD_BUS_ERROR_NULL;
const char *job;
int r;

r = sd_bus_message_new_method_call(
Expand Down Expand Up @@ -166,11 +168,20 @@ int migrate(sd_bus *bus, const char *target_unit, const char *target_slice,
if (r < 0)
return r;

r = sd_bus_call(bus, m, 0, &bus_error, NULL);
r = sd_bus_call(bus, m, 0, &bus_error, &reply);
if (r < 0) {
log_info("DBus call error: %s", strerror(sd_bus_error_get_errno(&bus_error)));
return r;
}
r = sd_bus_message_read(reply, "o", &job);
if (r < 0) {
log_info("DBus read error: %s", strerror(sd_bus_error_get_errno(&bus_error)));
return r;
}
r = wait_for_job(bus, job);
if (r < 0) {
log_info("Start job failed: %s", strerror(sd_bus_error_get_errno(&bus_error)));
}
/* ignore reply, i.e. don't wait for the job to finish */
return r;
}

Expand Down Expand Up @@ -235,8 +246,7 @@ int collect_pids(pid_t **rpids, int force) {
goto err;
}

if (verbose)
log_debug("%10i: %s", pid, comm);
log_debug("%10i: %s", pid, comm);

for (char **p = config.parent_commands.list; *p; p++) {
if(!strcmp(comm, *p)) {
Expand Down Expand Up @@ -303,7 +313,7 @@ int main(int argc, char *argv[]) {
int n_pids;
int r;

log_init();
log_init(&verbose);

while ((opt = getopt(argc, argv, "ahvf")) != -1) {
switch (opt) {
Expand Down

0 comments on commit c6f5238

Please sign in to comment.