return 0;
}
+int pidref_get_ppid_as_pidref(const PidRef *pidref, PidRef *ret) {
+ pid_t ppid;
+ int r;
+
+ assert(ret);
+
+ r = pidref_get_ppid(pidref, &ppid);
+ if (r < 0)
+ return r;
+
+ for (unsigned attempt = 0; attempt < 16; attempt++) {
+ _cleanup_(pidref_done) PidRef parent = PIDREF_NULL;
+
+ r = pidref_set_pid(&parent, ppid);
+ if (r < 0)
+ return r;
+
+ /* If we have a pidfd of the original PID, let's verify that the process we acquired really
+ * is the parent still */
+ if (pidref->fd >= 0) {
+ r = pidref_get_ppid(pidref, &ppid);
+ if (r < 0)
+ return r;
+
+ /* Did the PPID change since we queried it? if so we might have pinned the wrong
+ * process, if its PID got reused by now. Let's try again */
+ if (parent.pid != ppid)
+ continue;
+ }
+
+ *ret = TAKE_PIDREF(parent);
+ return 0;
+ }
+
+ /* Give up after 16 tries */
+ return -ENOTRECOVERABLE;
+}
+
int pid_get_start_time(pid_t pid, usec_t *ret) {
_cleanup_free_ char *line = NULL;
const char *p;
int get_process_environ(pid_t pid, char **ret);
int pid_get_ppid(pid_t pid, pid_t *ret);
int pidref_get_ppid(const PidRef *pidref, pid_t *ret);
+int pidref_get_ppid_as_pidref(const PidRef *pidref, PidRef *ret);
int pid_get_start_time(pid_t pid, usec_t *ret);
int pidref_get_start_time(const PidRef *pid, usec_t *ret);
int get_process_umask(pid_t pid, mode_t *ret);
pid = ppid;
}
+
+ /* the same via pidref */
+ _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
+ ASSERT_OK(pidref_set_self(&pidref));
+ for (;;) {
+ _cleanup_free_ char *c1 = NULL, *c2 = NULL;
+ _cleanup_(pidref_done) PidRef parent = PIDREF_NULL;
+ r = pidref_get_ppid_as_pidref(&pidref, &parent);
+ if (r == -EADDRNOTAVAIL) {
+ log_info("No further parent PID");
+ break;
+ }
+
+ ASSERT_OK(r);
+
+ ASSERT_OK(pidref_get_cmdline(&pidref, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c1));
+ ASSERT_OK(pidref_get_cmdline(&parent, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c2));
+
+ log_info("Parent of " PID_FMT " (%s) is " PID_FMT " (%s).", pidref.pid, c1, parent.pid, c2);
+
+ pidref_done(&pidref);
+ pidref = TAKE_PIDREF(parent);
+ }
}
TEST(set_oom_score_adjust) {