From: Michael Tremer Date: Sun, 26 Jan 2025 16:51:38 +0000 (+0000) Subject: job: Send a crash report in case the job crashes X-Git-Tag: 0.9.30~366 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=74af40e83ab3fb84e47226bb31971305bda3efb0;p=pakfire.git job: Send a crash report in case the job crashes This currently does not seem to be able to send the log because it never ends up in our buffer. Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/job.c b/src/pakfire/job.c index 18ce8c76..457d0f73 100644 --- a/src/pakfire/job.c +++ b/src/pakfire/job.c @@ -247,12 +247,103 @@ static void pakfire_job_free(struct pakfire_job* job) { free(job); } +static int pakfire_job_xfer_create(struct pakfire_xfer** xfer, + struct pakfire_job* job, const char* url, ...) __attribute__((format(printf, 3, 4))); + +static int pakfire_job_xfer_create(struct pakfire_xfer** xfer, + struct pakfire_job* job, const char* url, ...) { + struct pakfire_xfer* x = NULL; + va_list args; + int r; + + va_start(args, url); + + // Create a new xfer + r = pakfire_xfer_create(&x, job->ctx, url, args); + if (r < 0) + goto ERROR; + + // Set the base URL + r = pakfire_xfer_set_baseurl(x, pakfire_daemon_url(job->daemon)); + if (r < 0) + goto ERROR; + + // Success + *xfer = pakfire_xfer_ref(x); + +ERROR: + if (x) + pakfire_xfer_unref(x); + va_end(args); + + return r; +} + +static int pakfire_job_crashed(struct pakfire_job* job, const siginfo_t* si) { + struct pakfire_xfer* xfer = NULL; + char job_id[UUID_STR_LEN]; + int r; + + struct pakfire_job_log { + char* data; + size_t length; + } log = {}; + + // Format the job ID as string + uuid_unparse(job->job_id, job_id); + + DEBUG(job->ctx, "Sending crash report...\n"); + + // Dump the log + r = pakfire_log_buffer_dump(job->log.buffer, &log.data, &log.length); + if (r < 0) + goto ERROR; + + // Create a new transfer + r = pakfire_job_xfer_create(&xfer, job, "/api/v1/jobs/%s/crashed", job_id); + if (r < 0) + goto ERROR; + + // Enable authentication + r = pakfire_xfer_auth(xfer); + if (r) + goto ERROR; + + // Add the exit code + r = pakfire_xfer_add_param(xfer, "signo", "%d", si->si_status); + if (r < 0) + goto ERROR; + + // If we have a log, let's send the log, too + // XXX THIS IS NOT QUITE IDEAL BECAUSE THE LOG COULD CONTAIN NULL-CHARACTERS + // WE SHOULD IMPLEMENT THIS WITH CURL'S MIME CALLBACK FUNCTIONS + if (log.data) { + r = pakfire_xfer_add_param(xfer, "log", "%.*s", (int)log.length, log.data); + if (r < 0) + goto ERROR; + } + + // Send the request + r = pakfire_xfer_run_api_request(xfer, NULL); + if (r < 0) + goto ERROR; + +ERROR: + if (xfer) + pakfire_xfer_unref(xfer); + if (log.data) + free(log.data); + + return r; +} + /* This method is triggered by SIGCHLD whenever the job exits */ int pakfire_job_exited(sd_event_source* s, const siginfo_t* si, void* data) { struct pakfire_job* job = data; char job_id[UUID_STR_LEN]; + int r; // Format the job ID as string uuid_unparse(job->job_id, job_id); @@ -274,6 +365,13 @@ int pakfire_job_exited(sd_event_source* s, const siginfo_t* si, void* data) { // Update state job->state = PAKFIRE_JOB_STATE_KILLED; + // Send some information about this + r = pakfire_job_crashed(job, si); + if (r < 0) { + ERROR(job->ctx, "Could not send crash report: %s\n", strerror(-r)); + return r; + } + break; } @@ -594,38 +692,6 @@ static int pakfire_job_closed(struct pakfire_xfer* xfer, int code, void* data) { return 0; } -static int pakfire_job_xfer_create(struct pakfire_xfer** xfer, - struct pakfire_job* job, const char* url, ...) __attribute__((format(printf, 3, 4))); - -static int pakfire_job_xfer_create(struct pakfire_xfer** xfer, - struct pakfire_job* job, const char* url, ...) { - struct pakfire_xfer* x = NULL; - va_list args; - int r; - - va_start(args, url); - - // Create a new xfer - r = pakfire_xfer_create(&x, job->ctx, url, args); - if (r < 0) - goto ERROR; - - // Set the base URL - r = pakfire_xfer_set_baseurl(x, pakfire_daemon_url(job->daemon)); - if (r < 0) - goto ERROR; - - // Success - *xfer = pakfire_xfer_ref(x); - -ERROR: - if (x) - pakfire_xfer_unref(x); - va_end(args); - - return r; -} - static int pakfire_job_connected(struct pakfire_xfer* xfer, void* data) { struct pakfire_job* job = data;