]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-aux-scope.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
13 #include "bus-error.h"
14 #include "bus-message.h"
15 #include "bus-wait-for-jobs.h"
16 #include "daemon-util.h"
19 #include "missing_syscall.h"
20 #include "process-util.h"
23 static int on_sigusr1(sd_event_source
*s
, const struct signalfd_siginfo
*ssi
, void *userdata
) {
24 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*message
= NULL
, *reply
= NULL
;
25 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
26 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
27 _cleanup_(sd_bus_unrefp
) sd_bus
*bus
= NULL
;
28 PidRef
*pids
= (PidRef
*) userdata
;
34 r
= sd_bus_open_system(&bus
);
36 return log_error_errno(r
, "Failed to acquire bus: %m");
38 r
= sd_bus_message_new_method_call(bus
, &message
,
39 "org.freedesktop.systemd1",
40 "/org/freedesktop/systemd1",
41 "org.freedesktop.systemd1.Manager",
42 "StartAuxiliaryScope");
44 return log_error_errno(r
, "Failed to create bus message: %m");
46 r
= sd_bus_message_append_basic(message
, 's', "test-aux-scope.scope");
48 return log_error_errno(r
, "Failed to attach scope name: %m");
50 r
= sd_bus_message_open_container(message
, 'a', "h");
52 return log_error_errno(r
, "Failed to create array of FDs: %m");
54 for (size_t i
= 0; i
< 10; i
++) {
55 r
= sd_bus_message_append_basic(message
, 'h', &pids
[i
].fd
);
57 return log_error_errno(r
, "Failed to append PIDFD to message: %m");
60 r
= sd_bus_message_close_container(message
);
62 return log_error_errno(r
, "Failed to close container: %m");
64 r
= sd_bus_message_append(message
, "ta(sv)", UINT64_C(0), 1, "Description", "s", "Test auxiliary scope");
66 return log_error_errno(r
, "Failed to append unit properties: %m");
68 r
= sd_bus_call(bus
, message
, 0, &error
, &reply
);
70 return log_error_errno(r
, "Failed to start auxiliary scope: %s", bus_error_message(&error
, r
));
72 r
= sd_bus_message_read(reply
, "o", &job
);
74 return log_error_errno(r
, "Failed to read reply: %m");
76 r
= bus_wait_for_jobs_new(bus
, &w
);
78 return log_error_errno(r
, "Could not watch jobs: %m");
80 r
= bus_wait_for_jobs_one(w
, job
, false, NULL
);
87 static void destroy_pidrefs(PidRef
*pids
, size_t npids
) {
88 assert(pids
|| npids
== 0);
90 for (size_t i
= 0; i
< npids
; i
++)
91 pidref_done(&pids
[i
]);
96 int main(int argc
, char *argv
[]) {
97 _cleanup_(sd_event_unrefp
) sd_event
*event
= NULL
;
102 CLEANUP_ARRAY(pids
, npids
, destroy_pidrefs
);
104 test_setup_logging(LOG_INFO
);
106 fd
= pidfd_open(getpid_cached(), 0);
107 if (fd
< 0 && (ERRNO_IS_NOT_SUPPORTED(errno
) || ERRNO_IS_PRIVILEGE(errno
)))
108 return log_tests_skipped("pidfds are not available");
110 log_error_errno(errno
, "pidfd_open() failed: %m");
115 r
= sd_event_new(&event
);
117 log_error_errno(r
, "Failed to allocate event loop: %m");
122 pids
= new0(PidRef
, npids
);
125 r
= sd_event_add_signal(event
, NULL
, SIGUSR1
|SD_EVENT_SIGNAL_PROCMASK
, on_sigusr1
, pids
);
127 log_error_errno(r
, "Failed to setup SIGUSR1 signal handling: %m");
131 for (size_t i
= 0; i
< npids
; i
++) {
132 PidRef pidref
= PIDREF_NULL
;
135 r
= safe_fork("(worker)", FORK_RESET_SIGNALS
|FORK_DEATHSIG_SIGTERM
|FORK_CLOSE_ALL_FDS
, &pid
);
137 log_error_errno(r
, "Failed to fork(): %m");
147 r
= pidref_set_pid(&pidref
, pid
);
149 log_error_errno(r
, "Failed to initialize PID ref: %m");
153 assert_se(pidref
.pid
== pid
);
154 assert_se(pidref
.fd
!= -EBADF
);
156 pids
[i
] = TAKE_PIDREF(pidref
);
159 r
= sd_notify(false, NOTIFY_READY
);
161 return log_error_errno(r
, "Failed to send readiness notification: %m");
163 r
= sd_event_loop(event
);
165 return log_error_errno(r
, "Failed to run event loop: %m");