diff --git a/.gitignore b/.gitignore index a36d09314612a7bb070506d895a8315b7e985663..866eaf9475f1232553f562779287fc828c5ca8be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ target .vscode Cargo.lock +run_with_sd/systemd-dockerimg/rootfs +run_with_sd/systemd-dockerimg/rpms diff --git a/run_with_sd/patches/0004-add-signal.patch b/run_with_sd/patches/0004-add-signal.patch index 988c32a87bb9b700adb6e9709b487754362439f1..0cd0647cf632e5548fe22f889382a68ffed18818 100644 --- a/run_with_sd/patches/0004-add-signal.patch +++ b/run_with_sd/patches/0004-add-signal.patch @@ -1,14 +1,14 @@ -From 81e1652c378be010b64b6e49b22ccaaebd709ecc Mon Sep 17 00:00:00 2001 +From 12c8379d3b81bf0a63a50dfd1ea243dcb102242e Mon Sep 17 00:00:00 2001 From: rpm-build -Date: Tue, 21 Dec 2021 15:09:31 +0800 +Date: Wed, 29 Dec 2021 09:25:37 +0800 Subject: [PATCH] add signal --- - src/core/manager.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 67 insertions(+) + src/core/manager.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) diff --git a/src/core/manager.c b/src/core/manager.c -index 58345e1..e509e8d 100644 +index 58345e1..d75cbd4 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -524,6 +524,7 @@ static int manager_setup_signals(Manager *m) { @@ -16,82 +16,84 @@ index 58345e1..e509e8d 100644 SIGRTMIN+5, /* systemd: start reboot.target */ SIGRTMIN+6, /* systemd: start kexec.target */ + SIGRTMIN+7, /* systemd: receive init signal */ - + /* ... space for more special targets ... */ - -@@ -2778,6 +2779,72 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t - + +@@ -2778,6 +2779,74 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t + switch (sfsi.ssi_signo - SIGRTMIN) { - -+ case 7: -+ siginfo_t si = { -+ .si_signo = sfsi.ssi_signo, -+ .si_code = sfsi.ssi_code, -+ .si_pid = sfsi.ssi_pid, -+ .si_status = sfsi.ssi_status -+ }; -+ if (IN_SET(si.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED)) { -+ _cleanup_free_ Unit **array_copy = NULL; -+ _cleanup_free_ char *name = NULL; -+ Unit *u1, *u2, **array; + ++ case 7: ++ { ++ siginfo_t si = { ++ .si_signo = sfsi.ssi_signo, ++ .si_code = sfsi.ssi_code, ++ .si_pid = sfsi.ssi_pid, ++ .si_status = sfsi.ssi_status ++ }; ++ if (IN_SET(si.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED)) { ++ _cleanup_free_ Unit **array_copy = NULL; ++ _cleanup_free_ char *name = NULL; ++ Unit *u1, *u2, **array; ++ ++ (void) get_process_comm(si.si_pid, &name); ++ ++ log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)", ++ si.si_pid, strna(name), ++ sigchld_code_to_string(si.si_code), ++ si.si_status, ++ strna(si.si_code == CLD_EXITED ++ ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL) ++ : signal_to_string(si.si_status))); ++ ++ /* Increase the generation counter used for filtering out duplicate unit invocations */ ++ m->sigchldgen++; + -+ (void) get_process_comm(si.si_pid, &name); ++ /* And now figure out the unit this belongs to, it might be multiple... */ ++ u1 = manager_get_unit_by_pid_cgroup(m, si.si_pid); ++ u2 = hashmap_get(m->watch_pids, PID_TO_PTR(si.si_pid)); ++ array = hashmap_get(m->watch_pids, PID_TO_PTR(-si.si_pid)); ++ if (array) { ++ size_t cnt = 0; + -+ log_debug("Child "PID_FMT" (%s) died (code=%s, status=%i/%s)", -+ si.si_pid, strna(name), -+ sigchld_code_to_string(si.si_code), -+ si.si_status, -+ strna(si.si_code == CLD_EXITED -+ ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL) -+ : signal_to_string(si.si_status))); ++ /* Count how many entries the array has */ ++ while (array[cnt]) ++ cnt++; + -+ /* Increase the generation counter used for filtering out duplicate unit invocations */ -+ m->sigchldgen++; ++ /* Make a copy of the array so that we don't trip up on the array changing beneath us */ ++ array_copy = newdup(Unit*, array, cnt+1); ++ if (!array_copy) ++ log_oom(); ++ } + -+ /* And now figure out the unit this belongs to, it might be multiple... */ -+ u1 = manager_get_unit_by_pid_cgroup(m, si.si_pid); -+ u2 = hashmap_get(m->watch_pids, PID_TO_PTR(si.si_pid)); -+ array = hashmap_get(m->watch_pids, PID_TO_PTR(-si.si_pid)); -+ if (array) { -+ size_t cnt = 0; ++ /* Finally, execute them all. Note that u1, u2 and the array might contain duplicates, but ++ * that's fine, manager_invoke_sigchld_event() will ensure we only invoke the handlers once for ++ * each iteration. */ ++ if (u1) { ++ /* We check for oom condition, in case we got SIGCHLD before the oom notification. ++ * We only do this for the cgroup the PID belonged to. */ ++ (void) unit_check_oom(u1); + -+ /* Count how many entries the array has */ -+ while (array[cnt]) -+ cnt++; -+ -+ /* Make a copy of the array so that we don't trip up on the array changing beneath us */ -+ array_copy = newdup(Unit*, array, cnt+1); -+ if (!array_copy) -+ log_oom(); -+ } ++ /* This only logs for now. In the future when the interface for kills/notifications ++ * is more stable we can extend service results table similar to how kernel oom kills ++ * are managed. */ ++ (void) unit_check_oomd_kill(u1); + -+ /* Finally, execute them all. Note that u1, u2 and the array might contain duplicates, but -+ * that's fine, manager_invoke_sigchld_event() will ensure we only invoke the handlers once for -+ * each iteration. */ -+ if (u1) { -+ /* We check for oom condition, in case we got SIGCHLD before the oom notification. -+ * We only do this for the cgroup the PID belonged to. */ -+ (void) unit_check_oom(u1); -+ -+ /* This only logs for now. In the future when the interface for kills/notifications -+ * is more stable we can extend service results table similar to how kernel oom kills -+ * are managed. */ -+ (void) unit_check_oomd_kill(u1); -+ -+ manager_invoke_sigchld_event(m, u1, &si); -+ } -+ if (u2) -+ manager_invoke_sigchld_event(m, u2, &si); -+ if (array_copy) -+ for (size_t i = 0; array_copy[i]; i++) - manager_invoke_sigchld_event(m, array_copy[i], &si); -+ syscall(__NR_rt_sigqueueinfo, 1, sfsi.ssi_signo, &si); -+ } -+ break; ++ manager_invoke_sigchld_event(m, u1, &si); ++ } ++ if (u2) ++ manager_invoke_sigchld_event(m, u2, &si); ++ if (array_copy) ++ for (size_t i = 0; array_copy[i]; i++) ++ manager_invoke_sigchld_event(m, array_copy[i], &si); ++ syscall(__NR_rt_sigqueueinfo, 1, sfsi.ssi_signo, &si); ++ } ++ break; ++ } + case 20: manager_override_show_status(m, SHOW_STATUS_YES, "signal"); break; --- +-- 2.30.0 diff --git a/run_with_sd/patches/README.md b/run_with_sd/patches/README.md new file mode 100644 index 0000000000000000000000000000000000000000..aa3aba725d5011403569ed9f836c3bd78cad1bda --- /dev/null +++ b/run_with_sd/patches/README.md @@ -0,0 +1,5 @@ +1. 下载[systemd-248-13.oe1.src.rpm](https://repo.openeuler.org/openEuler-21.09/source/Packages/systemd-248-13.oe1.src.rpm) +2. 执行`rpm -ivh systemd-248-13.oe1.src.rpm`, 源码安装到`~/rpmbuild` +3. 将patches目录下的内容拷贝覆盖到`~/rpmbuild/SOURCES` +4. 执行`rpmbuild -ba ~/rpmbuild/SOURCES/systemd.spec --nocheck` +5. 生成的rpm在`~/rpmbuild/RPMS/x86_64/`下 \ No newline at end of file diff --git a/run_with_sd/patches/systemd.spec b/run_with_sd/patches/systemd.spec new file mode 100644 index 0000000000000000000000000000000000000000..da8f08704b8ca93a1b87c816de32eec3e864cb66 --- /dev/null +++ b/run_with_sd/patches/systemd.spec @@ -0,0 +1,15 @@ +#这只是其中的一部分 +Name: systemd +Url: https://www.freedesktop.org/wiki/Software/systemd +Version: 248 +Release: 13.test42 +License: MIT and LGPLv2+ and GPLv2+ +Summary: System and Service Manager + +#add these patches in systemd.spec +Patch0101: 0001-fake-pid1-by-env.patch +Patch0102: 0002-detect-virt.patch +Patch0103: 0003-reap-child-by-systemd.patch +Patch0104: 0004-add-signal.patch +Patch0105: 0005-donot-wait-in-shutdown.patch +Patch0106: 0006-reexec-when-crash.patch diff --git a/run_with_sd/systemd-dockerimg/build.sh b/run_with_sd/systemd-dockerimg/build.sh index 8b623f05dcfeab2be5f6daf955150a3a00a3647a..e30a839c316d61cc204ca9ba68bf8c40c5146040 100755 --- a/run_with_sd/systemd-dockerimg/build.sh +++ b/run_with_sd/systemd-dockerimg/build.sh @@ -1,10 +1,11 @@ #!/bin/bash -yum -c openEuler.repo --installroot=$PWD/rootfs install systemd -y -cp -a rpms/systemd*.rpm rootfs/ +yum -c openEuler.repo --repo=everything --installroot=$PWD/rootfs install systemd -y +mkdir -p rootfs/rpms +cp -a rpms/systemd*.rpm rootfs/rpms if [ $? -ne 0 ]; then echo "put your rpms into dir rpms" exit 1 fi -chroot rootfs /bin/bash -c "rpm -Fvh *" -rm -rf rootfs/systemd*.rpm +chroot rootfs /bin/bash -c "rpm -Fvh /rpms/*" +rm -rf rootfs/rpms/systemd*.rpm docker build --no-cache --tag systemd . diff --git a/run_with_sd/systemd-dockerimg/rpms/README.md b/run_with_sd/systemd-dockerimg/rpms/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f6f124a8c26e700e86155f1af6eccdc09a6d0192 --- /dev/null +++ b/run_with_sd/systemd-dockerimg/rpms/README.md @@ -0,0 +1 @@ +生成在`~/rpmbuild/RPMS/x86_64/`下rpms, 拷贝到此目录 \ No newline at end of file