Compare commits
	
		
			46 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d0097cc10f | ||
|   | eecf868e3c | ||
|   | a5cd486a7f | ||
|   | 6e6b4ac5fa | ||
|   | 558ff4d5fb | ||
|   | 490f855aef | ||
|   | d1491e201d | ||
|   | 3231af9375 | ||
|   | a5758e7aef | ||
|   | 61a9393ce1 | ||
|   | 161d22cb07 | ||
|   | 3a96ca1c96 | ||
|   | 934530914b | ||
|   | b717625cd2 | ||
|   | b475396134 | ||
|   | e7b1d898ca | ||
|   | 5cd09a6f44 | ||
|   | f3c70bf5b5 | ||
|   | f5acc66db7 | ||
|   | fdce4769f2 | ||
|   | 35b1996704 | ||
|   | 3c8e7ed255 | ||
|   | acaed1f910 | ||
|   | 91109e31d8 | ||
|   | 2b6eeea01d | ||
|   | a15de23e57 | ||
|   | efa9ba485d | ||
| d4ddd72701 | |||
|   | 1e9af2cd42 | ||
|   | 3c05db74f6 | ||
|   | edc54b0377 | ||
|   | 8e53a3fa8a | ||
|   | 7f3b413111 | ||
|   | 1ccba05658 | ||
|   | c46adf1434 | ||
|   | 1cac8b080c | ||
|   | b58194ef63 | ||
|   | b28c0d6f66 | ||
|   | 3cf19b0f30 | ||
|   | 0eb47b9af3 | ||
|   | 4ab60ff109 | ||
|   | db4a578273 | ||
|   | b1c3422f45 | ||
|   | 3fafd7a76e | ||
|   | cd5722aca5 | ||
|   | dcb4a4d261 | 
							
								
								
									
										518
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										518
									
								
								ChangeLog
									
									
									
									
									
								
							| @@ -1,4 +1,318 @@ | ||||
| commit 2a203b9b6e91e4ed140750eb9223012035870864 | ||||
| commit eecf868e3c4a763b08cd4b3803f4839e8e710413 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: clarify a log message | ||||
|  | ||||
| commit a5cd486a7fbb5acf8e8f3085500fd86c23dd8641 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Update ChangeLog | ||||
|  | ||||
| commit 6e6b4ac5fa935eb8052d293f2b8378e0395572e1 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: log the command line we run to spawn the child process | ||||
|  | ||||
| commit 558ff4d5fb90b751ebc2852ea907873af2c236fa | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: log with the service name instead of "supervise-daemon" | ||||
|  | ||||
| commit 490f855aef581a720c6c0be0d8407fe6d279f9f5 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     implement "unsupervised" status | ||||
|      | ||||
|     The unsupervised status is to be used when a supervisor of a supervised | ||||
|     service dies but leaves the service daemon itself running. | ||||
|  | ||||
| commit d1491e201d3ad364e25a55b29ff8035775a6acac | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: remove child_pid from saved options during shutdown | ||||
|      | ||||
|     This allows us to detect when the supervisor dies unexpectedly because | ||||
|     in that case child_pid will still exist. | ||||
|  | ||||
| commit 3231af937590b1c00af1a459009472a371aeb04a | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     rc_service_value_set: remove the option if NULL is the value | ||||
|      | ||||
|     This allows the equivalent of "unsetting" a value for a service. | ||||
|  | ||||
| commit a5758e7aeffbeb9766ba3055a3fc347f0ccd3d35 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon.sh: fix status function with no namespaces | ||||
|  | ||||
| commit 61a9393ce12fda412bdca4002ac71e7df82384df | ||||
| Author: Patrick McLean <chutzpah@gentoo.org> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     cgroups_cleanup: clean up shutdown signaling | ||||
|      | ||||
|     - do not sleep for the full 90 seconds if processes are dead | ||||
|     - re-arrange the order of signals we attempt to send to the processes | ||||
|  | ||||
| commit 161d22cb074ecef7003e19682d72a8ee61c14490 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     version 0.34.3 | ||||
|  | ||||
| commit 3a96ca1c966c3cc44a2e0e51b383ab47d078bcc1 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Update ChangeLog | ||||
|  | ||||
| commit 934530914bd507476b428d3f6572bbb1c5bbfd16 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     add "unsupervised" status and return code 64 to supervise-daemon status function | ||||
|      | ||||
|     This is to be used if the service is being supervised and the | ||||
|     supervisor is somehow killed. | ||||
|      | ||||
|     Currently, this is very linux specific, but I will expand to other | ||||
|     platforms, patches are welcome. | ||||
|  | ||||
| commit b717625cd27950c3f00b5345bc1cee9700e79498 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     version 0.34.2 | ||||
|  | ||||
| commit b47539613431521e5e99bc388e6a9d8eb0e48801 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Update ChangeLog | ||||
|  | ||||
| commit e7b1d898ca7896d6443ba1e5167eb6bcf3f92929 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: fix build issue for >=glibc-2.26 | ||||
|      | ||||
|     X-Gentoo-Bug: 635334 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=635334 | ||||
|  | ||||
| commit 5cd09a6f44aa7d16ab7de1453e37d01448426031 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     version 0.34.1 | ||||
|  | ||||
| commit f3c70bf5b5aa18e8dc94d4949f05568e0741c5cb | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Update ChangeLog | ||||
|  | ||||
| commit f5acc66db7d1a0bfad6a40eefc0240b80f52df94 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     rc_find_pids: ignore pids that are not in our pid namespace | ||||
|      | ||||
|     X-Gentoo-Bug: 634634 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=634634 | ||||
|  | ||||
| commit fdce4769f2e0f4175163ffa181c7b3b2192f7b22 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: multiple fixes | ||||
|      | ||||
|     - Harden against dying by handling all signals that would terminate the | ||||
|     program and adding --reexec support | ||||
|     - factor the supervisor into its own function | ||||
|     - fix test for whether we are already running | ||||
|  | ||||
| commit 35b1996704f6635bb29ea3604410e133209e6432 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: elevate some log messages to warnings | ||||
|      | ||||
|     Prior to this change, we were logging unexpected terminations of daemons | ||||
|     we were supervising at the info level. This change moves the logs to | ||||
|     warnings. | ||||
|  | ||||
| commit 3c8e7ed255edb8df0d548d6ce514544d5422cbf0 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     version 0.34 | ||||
|  | ||||
| commit acaed1f910a2a00fdd5b6aeab752c552075a7292 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Update ChangeLog | ||||
|  | ||||
| commit 91109e31d81ecd48f5690ad6f63103fca545dec7 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     update news | ||||
|  | ||||
| commit 2b6eeea01d1c64d58929788f4bfa0758393885bf | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     man: remove service(8) man page | ||||
|  | ||||
| commit a15de23e5713d840d871c526b46050983dc6ea1e | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     typo fix | ||||
|  | ||||
| commit efa9ba485d9328f780f3e60dc18339c75974c6c6 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init.d/sysfs.in: fix reference to RC_LIBEXECDIR | ||||
|      | ||||
|     The sysfs init script referred to @LIBEXECDIR@ before this change, but | ||||
|     it is better to refer to RC_LIBEXECDIR so that we get rid of a sed | ||||
|     substitution. | ||||
|  | ||||
| commit d4ddd72701ff5533a1ba07b1da60806859c63d88 | ||||
| Author: Chris Cromer <chris@cromer.cl> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     add option to make agetty startup quiet | ||||
|      | ||||
|     This fixes #150 | ||||
|  | ||||
| commit 1e9af2cd421423404ffe1491bd35af76c2885f1f | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     fix compiler warning | ||||
|  | ||||
| commit 3c05db74f6e733890e9035c183a774db3d512512 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     remove service binary | ||||
|      | ||||
|     The service binary was just a synonym for rc-service, so use rc-service | ||||
|     instead of service. If you want a "service" binary, it should be | ||||
|     something that can determine which service manager you are running and | ||||
|     run the appropriate service manager commands. | ||||
|  | ||||
| commit edc54b03770d5f58d1a4969d06c28660003dfb04 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     version 0.33 | ||||
|  | ||||
| commit 8e53a3fa8a33fb714064ddbe38bff2213fcf6837 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Update ChangeLog | ||||
|  | ||||
| commit 7f3b41311119e3a96a15b0fb473b44f422e903e9 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     use printf consistently in cgroups handling | ||||
|      | ||||
|     This makes the cgroups handling consistent between cgroups v1 and v2. | ||||
|     Also, it fixes #167. | ||||
|  | ||||
| commit 1ccba056584ee1a8e09fb1d5eebd988b47912c06 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     sh/rc-functions.sh: add need_if_exists convenience function | ||||
|  | ||||
| commit c46adf14343df3a74aef7e4ae5be175ae5fa7a01 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     man/openrc-run.8: Clarify the explanation of the need dependency | ||||
|  | ||||
| commit 1cac8b080c16f9aab19c7a3ae1ca155c20dfa14d | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     ignore sigchld when shutting down the supervised process | ||||
|      | ||||
|     We need to do this to skip the zombie state for the child process since | ||||
|     we are not easily able to wait() for it. | ||||
|  | ||||
| commit b58194ef63ec8c0a7e0ea3c291da9c19aa83cb1a | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     typo fix | ||||
|  | ||||
| commit b28c0d6f66e42b1e6d2a39c286a18c8d92881790 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     typo fix | ||||
|  | ||||
| commit 3cf19b0f30a90157d23d09ded304439f1eb42d4a | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     supervise-daemon: code cleanup | ||||
|      | ||||
|     Clean up the process for killing an active supervisor when stopping. | ||||
|  | ||||
| commit 0eb47b9af340dd07209a3920944ed085fe7bd359 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     initialize the stop schedule | ||||
|  | ||||
| commit 4ab60ff10935122277bbaed437f82a765279cd19 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     rc-schedules.c: pass the correct pid to rc_find_pids | ||||
|      | ||||
|     This is for #163. | ||||
|  | ||||
| commit db4a578273dbfa15b8b96686391bcc9ecc04b646 | ||||
| Author: Jason Zaman <jason@perfinion.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     selinux: fix const qualifier warning | ||||
|      | ||||
|     rc-selinux.c: In function ‘selinux_setup’: | ||||
|     rc-selinux.c:361:9: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers] | ||||
|       curr_t = context_type_get(curr_con); | ||||
|              ^ | ||||
|  | ||||
| commit b1c3422f453921e838d419640fe39144dbf8d13d | ||||
| Author: Jason Zaman <jason@perfinion.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     selinux: use openrc contexts path to get contexts | ||||
|      | ||||
|     The minimum requirement for libselinux is now >=2.6 | ||||
|     The refpolicy and the gentoo policy contain the | ||||
|     contexts since version 2.20170204-r4 | ||||
|  | ||||
| commit 3fafd7a76e6adf15ec72a7ba5f44583eff8fab7a | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
| @@ -9,7 +323,7 @@ Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|      | ||||
|     This fixes #164. | ||||
|  | ||||
| commit a769ea1b92f47254edf11458d2c8b79d3819e0e6 | ||||
| commit cd5722aca50f0eaddde7ce04ee00da53c313ba7d | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
| @@ -17,11 +331,11 @@ Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|      | ||||
|     This is related to #164. | ||||
|  | ||||
| commit 6f564b59cc15e688b2fa0758fa9797632e0751d7 | ||||
| commit dcb4a4d2613a1fdf85651b32e5b7a87528f487bc | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     version 0.31.1 | ||||
|     version 0.32 | ||||
|  | ||||
| commit e312e569970c74cf52e255da67034391b68dafac | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| @@ -1256,199 +1570,3 @@ Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     src/rc/rc: do not try to start services if fork fails | ||||
|  | ||||
| commit 003657c973ea338a19f2b7294190af9d76cf5cea | ||||
| Author: Robin H. Johnson <robbat2@gentoo.org> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init.d/loopback: drop scope on loopback | ||||
|      | ||||
|     Busybox does not support the 'scope' argument on 'ip address add' or 'ip | ||||
|     route add', this is documented in BUSYBOX.md, but is no longer actually | ||||
|     needed, as the kernel does get it right without manual specification, | ||||
|     and the ifconfig variant already relies on the kernel to get it right. | ||||
|     This is part of #103. | ||||
|      | ||||
|     X-Gentoo-Bug: 487208 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=487208 | ||||
|  | ||||
| commit 4fd144c0a6526963c70f18cb34a65354c2f0a48c | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     src/rc/rc-misc.c: report error if call to flock() fails | ||||
|      | ||||
|     X-Gentoo-Bug: 597390 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=597390 | ||||
|  | ||||
| commit c44c904a61418189c989e978b0237e5b161263ef | ||||
| Author: Joe Maloney <jpm820@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init.d.misc/wpa_supplicant: find wireless interface for FreeBSD | ||||
|      | ||||
|     This fixes #101. | ||||
|  | ||||
| commit 78146b0e14cb57dda8a3aed3d4f8d6b1db7a3c7e | ||||
| Author: Sven Wegener <swegener@gentoo.org> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     do_service: Initialize idx to 0 | ||||
|      | ||||
|     If index is not explicitly specified for service_started_daemon, it will | ||||
|     look for daemons by random index. | ||||
|      | ||||
|     This fixes #100. | ||||
|  | ||||
| commit deaae7ab5c499191426cec81f6e803c972f0cca3 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init.d/sysfs: load efivarfs module when booting in efi mode:1 | ||||
|      | ||||
|     The presence of /sys/firmware/efi is used to indicate that the system | ||||
|     was booted in efi mode. | ||||
|  | ||||
| commit 3d2c2f0b871944492036d04b0c220ccba1fa2dd5 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init.d/sysfs: fix efivarfs module test | ||||
|  | ||||
| commit 6a0c033a64ce18056625cd37a94b9810dc5784e3 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init.d/sysfs: fix efivarfs handling | ||||
|      | ||||
|     Separate loading the module, if it isn't built in or loaded, from | ||||
|     mounting the file system. | ||||
|      | ||||
|     This also makes sure the warning about configuring the module in | ||||
|     /etc/conf.d/modules or building it in is displayed only if it is loaded | ||||
|     successfully. | ||||
|      | ||||
|     X-Gentoo-Bug: 595836 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=595836 | ||||
|  | ||||
| commit 6710316a18c33601e780282e72c60f09b5175280 | ||||
| Author: Doug Freed <dwfreed@mtu.edu> | ||||
| Commit: Doug Freed <dwfreed@mtu.edu> | ||||
|  | ||||
|     openrc-run: fix double free | ||||
|  | ||||
| commit 61882821e0d6110a2ca2f67fad7c362983a85cf0 | ||||
| Author: Doug Freed <dwfreed@mtu.edu> | ||||
| Commit: Doug Freed <dwfreed@mtu.edu> | ||||
|  | ||||
|     init.d: Clean up some bad ewarn output | ||||
|  | ||||
| commit 969546bcf0203379db286be21c7f709d27cc73b0 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     typo fix | ||||
|      | ||||
|     X-Gentoo-Bug: 595306 | ||||
|     X-Gentoo-Bug: https://bugs.gentoo.org/show_bug.cgi?id=595306 | ||||
|  | ||||
| commit d0ae7ffc2534fa65c2e8927931f5107ce4505ca6 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     version 0.23 | ||||
|  | ||||
| commit b71bcc242202752bc74fce3a5c629f172b04fca5 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     update ChangeLog | ||||
|  | ||||
| commit 24010dcb483cf7284cd8a5db111ae63f0d4e1038 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     dist: convert to tar.gz | ||||
|      | ||||
|     This allows the "make dist" target to be used as well as the github | ||||
|     archive generation. | ||||
|  | ||||
| commit 0a76627345a173fc00be9864f3f3f5c3b15319cd | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     init.d/swap: remove the case for linux | ||||
|      | ||||
|     I am removing the separate case for Linux, because we are droppping the | ||||
|     "-e" switch. | ||||
|  | ||||
| commit bbf98befb86337a36ef5af7f273e503a6de4b9bd | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     sh/init.sh.Linux.in: update test for live /proc to use md5sum | ||||
|      | ||||
|     This allows us to avoid the warnings from bash-4.4 about null bytes in | ||||
|     command substitutions. | ||||
|      | ||||
|     If you have separate /usr, are not using an initramfs, and have a file | ||||
|     called /proc/self/environ on your root file system, this will break. | ||||
|     X-Gentoo-Bug: 594534 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=594534 | ||||
|  | ||||
| commit 316903fbf0da6edc067a98327c8c6cb2b3cdcf93 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     man/openrc-run.8: typo fix | ||||
|  | ||||
| commit 66a9788435e51e658e4ae9d3ce0d0e54ea53e4f9 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     man/openrc-run.8: Add note about eval usage | ||||
|      | ||||
|     This fixes #77. | ||||
|  | ||||
| commit bf73363f220ff086d2559e7c2015801f80862749 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Add --use-blacklist to modprobe calls in modules and modules-load | ||||
|      | ||||
|     This means that we will honor the modprobe black lists. | ||||
|      | ||||
|     X-Gentoo-Bug: 594012 | ||||
|     X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=594012 | ||||
|  | ||||
| commit d6c30ab12a3b335ac57cd1f0ac00231bb34fc0c4 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Revert "Remove eval calls from supervisor start functions" | ||||
|      | ||||
|     This reverts commit 0d1f1010c299a95332f224c3be9e8dfdd85eec54. | ||||
|     We need the eval in case someone uses something like: | ||||
|     command_args="this \"is a\" test" | ||||
|      | ||||
|     This is related to #77. | ||||
|  | ||||
| commit 0d1f1010c299a95332f224c3be9e8dfdd85eec54 | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Remove eval calls from supervisor start functions | ||||
|      | ||||
|     This fixes #77. | ||||
|  | ||||
| commit 83bb827edf5b9be04a326d1970d6f55db239281f | ||||
| Author: William Hubbs <w.d.hubbs@gmail.com> | ||||
| Commit: William Hubbs <w.d.hubbs@gmail.com> | ||||
|  | ||||
|     Revert "Disable parallel startup in interactive mode" | ||||
|      | ||||
|     This reverts commit 8b4fc05ff2645b2ecb0f153492f72dd8b39ba431. | ||||
|     The original commit did not explain why this feature was disabled, and I | ||||
|     now have a request to enable it. | ||||
|      | ||||
|     This fixes #24. | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| NAME=		openrc | ||||
| VERSION=	0.31.1 | ||||
| VERSION=	0.34.3 | ||||
| PKG=		${NAME}-${VERSION} | ||||
|   | ||||
							
								
								
									
										9
									
								
								NEWS.md
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								NEWS.md
									
									
									
									
									
								
							| @@ -3,6 +3,15 @@ | ||||
| This file will contain a list of notable changes for each release. Note | ||||
| the information in this file is in reverse order. | ||||
|  | ||||
| ## OpenRC 0.33 | ||||
|  | ||||
| This version removes the "service" binary which was just a copy of | ||||
| "rc-service" provided for compatibility. | ||||
|  | ||||
| If you still need the "service" binary, as opposed to "rc-service", it is | ||||
| recommended that you use something like Debian's init-system-helpers. | ||||
| Otherwise, just use "rc-service" in place of "service". | ||||
|  | ||||
| ## OpenRC 0.31 | ||||
|  | ||||
| This version adds support for Control Groups version 2, which is | ||||
|   | ||||
| @@ -1,3 +1,6 @@ | ||||
| # make agetty quiet | ||||
| #quiet="yes" | ||||
|  | ||||
| # Set the baud rate of the terminal line | ||||
| #baud="" | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								guide.md
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								guide.md
									
									
									
									
									
								
							| @@ -53,9 +53,6 @@ Calling `openrc` without any arguments will try to reset all services so | ||||
| that the current runlevel is satisfied; if you manually started apache it will be  | ||||
| stopped, and if squid died but is in the current runlevel it'll be restarted. | ||||
|  | ||||
| There is a `service` helper that emulates the syntax seen on e.g. older Redhat | ||||
| and Ubuntu (`service nginx start` etc.) | ||||
|  | ||||
| # Runlevels | ||||
|  | ||||
| OpenRC has a concept of runlevels, similar to what sysvinit historically  | ||||
|   | ||||
| @@ -16,6 +16,7 @@ term_type="${term_type:-linux}" | ||||
| command=/sbin/agetty | ||||
| command_args_foreground="${agetty_options} ${port} ${baud} ${term_type}" | ||||
| pidfile="/run/${RC_SVCNAME}.pid" | ||||
| export EINFO_QUIET="${quiet:-yes}" | ||||
|  | ||||
| depend() { | ||||
| 	after local | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| S#!@BINDIR@/openrc-run | ||||
| #!@SBINDIR@/openrc-run | ||||
| # Copyright (c) 2009-2015 The OpenRC Authors. | ||||
| # See the Authors file at the top-level directory of this distribution and | ||||
| # https://github.com/OpenRC/openrc/blob/master/AUTHORS | ||||
|   | ||||
| @@ -118,7 +118,7 @@ cgroup1_base() | ||||
| 	fi | ||||
|  | ||||
| 	if ! mountinfo -q /sys/fs/cgroup/openrc; then | ||||
| 		local agent="@LIBEXECDIR@/sh/cgroup-release-agent.sh" | ||||
| 		local agent="${RC_LIBEXECDIR}/sh/cgroup-release-agent.sh" | ||||
| 		mkdir /sys/fs/cgroup/openrc | ||||
| 		mount -n -t cgroup \ | ||||
| 			-o none,${sysfs_opts},name=openrc,release_agent="$agent" \ | ||||
|   | ||||
| @@ -6,7 +6,7 @@ MAN3=		einfo.3 \ | ||||
| 		rc_config.3 rc_deptree.3 rc_find_pids.3 rc_plugin_hook.3 \ | ||||
| 		rc_runlevel.3 rc_service.3 rc_stringlist.3 | ||||
| MAN8=		rc-service.8 rc-status.8 rc-update.8 openrc.8 openrc-run.8 \ | ||||
| 		service.8 start-stop-daemon.8 supervise-daemon.8 | ||||
| 		start-stop-daemon.8 supervise-daemon.8 | ||||
|  | ||||
| ifeq (${OS},Linux) | ||||
| MAN8 += rc-sstat.8 openrc-init.8 openrc-shutdown.8 | ||||
|   | ||||
| @@ -217,8 +217,10 @@ that dependency type to the function, or prefix the names with ! to | ||||
| remove them from the dependencies. | ||||
| .Bl -tag -width "RC_DEFAULTLEVEL" | ||||
| .It Ic need | ||||
| The service will refuse to start until needed services have started and it | ||||
| will refuse to stop until any services that need it have stopped. | ||||
| The service will attempt to start any services it needs regardless of | ||||
| whether they have been added to the runlevel. It will refuse to start | ||||
| until all services it needs have started, and it will refuse to stop until all | ||||
| services that need it have stopped. | ||||
| .It Ic use | ||||
| The service will attempt to start any services it uses that have been added | ||||
| to the runlevel. | ||||
|   | ||||
| @@ -1 +0,0 @@ | ||||
| .so rc-service.8 | ||||
| @@ -165,7 +165,7 @@ cgroup2_remove() | ||||
| 		[ ! -e "${rc_cgroup_path}"/cgroup.events ] && | ||||
| 		return 0 | ||||
| 	grep -qx "$$" "${rc_cgroup_path}/cgroup.procs" && | ||||
| 		echo 0 > "${cgroup_path}/cgroup.procs" | ||||
| 		printf "%d" 0 > "${cgroup_path}/cgroup.procs" | ||||
| 	local key populated vvalue | ||||
| 	while read -r key value; do | ||||
| 		case "${key}" in | ||||
| @@ -188,12 +188,12 @@ cgroup2_set_limits() | ||||
| 	IFS=" | ||||
| " | ||||
| 	[ ! -d "${rc_cgroup_path}" ] && mkdir "${rc_cgroup_path}" | ||||
| 	echo 0 > "${rc_cgroup_path}/cgroup.procs" | ||||
| 	printf "%d" 0 > "${rc_cgroup_path}/cgroup.procs" | ||||
| 	echo "${rc_cgroup_settings}" | while IFS="$OIFS" read -r key value; do | ||||
| 		[ -z "${key}" ] || [ -z "${value}" ] && continue | ||||
| 		[ ! -e "${rc_cgroup_path}/${key}" ] && continue | ||||
| 		veinfo "${RC_SVCNAME}: cgroups: ${key} ${value}" | ||||
| 		echo "${value}" > "${rc_cgroup_path}/${key}" | ||||
| 		printf "%s" "${value}" > "${rc_cgroup_path}/${key}" | ||||
| 	done | ||||
| 	IFS="$OIFS" | ||||
| 	return 0 | ||||
| @@ -203,15 +203,21 @@ cgroup_cleanup() | ||||
| { | ||||
| 	cgroup_running || return 0 | ||||
| 	ebegin "starting cgroups cleanup" | ||||
| 	local pids | ||||
| 	local pids loops=0 | ||||
| 	pids="$(cgroup_get_pids)" | ||||
| 	if [ -n "${pids}" ]; then | ||||
| 		kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null | ||||
| 		kill -s CONT ${pids} 2> /dev/null | ||||
| 		kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null | ||||
| 		yesno "${rc_send_sighup:-no}" && | ||||
| 			kill -s HUP ${pids} 2> /dev/null | ||||
| 		sleep "${rc_timeout_stopsec:-90}" | ||||
| 		yesno "${rc_send_sigkill:-yes}" && | ||||
| 		kill -s "${stopsig:-TERM}" ${pids} 2> /dev/null | ||||
| 		while [ -n "$(cgroup_get_pids)" ] && | ||||
| 			[ "${loops}" -lt "${rc_timeout_stopsec:-90}" ]; do | ||||
| 			loops=$((loops+1)) | ||||
| 			sleep 1 | ||||
| 		done | ||||
| 		pids="$(cgroup_get_pids)" | ||||
| 		[ -n "${pids}" ] && yesno "${rc_send_sigkill:-yes}" && | ||||
| 			kill -s KILL ${pids} 2> /dev/null | ||||
| 	fi | ||||
| 	cgroup2_remove | ||||
|   | ||||
| @@ -119,6 +119,13 @@ get_bootparam_value() | ||||
| 	echo $result | ||||
| } | ||||
|  | ||||
| need_if_exists() | ||||
| { | ||||
| 	for x; do | ||||
| 		rc-service --exists "${x}" && need "${x}" | ||||
| 	done | ||||
| } | ||||
|  | ||||
| # Called from openrc-run.sh or gendepends.sh | ||||
| _get_containers() { | ||||
| 	local c | ||||
|   | ||||
| @@ -56,7 +56,41 @@ supervise_stop() | ||||
| 	eend $? "Failed to stop ${name:-$RC_SVCNAME}" | ||||
| } | ||||
|  | ||||
| _check_supervised() | ||||
| { | ||||
| 	local child_pid start_time | ||||
| 	child_pid="$(service_get_value "child_pid")" | ||||
| 	start_time="$(service_get_value "start_time")" | ||||
| 	if [ -n "${child_pid}" ] && [ -n "${start_time}" ]; then | ||||
| 		return 1 | ||||
| 	fi | ||||
| 	return 0 | ||||
| } | ||||
|  | ||||
| supervise_status() | ||||
| { | ||||
| 	_status | ||||
| 	if service_stopping; then | ||||
| 		ewarn "status: stopping" | ||||
| 		return 4 | ||||
| 	elif service_starting; then | ||||
| 		ewarn "status: starting" | ||||
| 		return 8 | ||||
| 	elif service_inactive; then | ||||
| 		ewarn "status: inactive" | ||||
| 		return 16 | ||||
| 	elif service_started; then | ||||
| 		if service_crashed; then | ||||
| 			if ! _check_supervised; then | ||||
| 				eerror "status: unsupervised" | ||||
| 				return 64 | ||||
| 			fi | ||||
| 			eerror "status: crashed" | ||||
| 			return 32 | ||||
| 		fi | ||||
| 		einfo "status: started" | ||||
| 		return 0 | ||||
| 	else | ||||
| 		einfo "status: stopped" | ||||
| 		return 3 | ||||
| 	fi | ||||
| } | ||||
|   | ||||
| @@ -47,6 +47,7 @@ bool rc_conf_yesno(const char *var); | ||||
| void env_filter(void); | ||||
| void env_config(void); | ||||
| int signal_setup(int sig, void (*handler)(int)); | ||||
| int signal_setup_restart(int sig, void (*handler)(int)); | ||||
| int svc_lock(const char *); | ||||
| int svc_unlock(const char *, int); | ||||
| pid_t exec_service(const char *, const char *); | ||||
|   | ||||
| @@ -80,9 +80,12 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) | ||||
| 	DIR *procdir; | ||||
| 	struct dirent *entry; | ||||
| 	FILE *fp; | ||||
| 	int rc; | ||||
| 	bool container_pid = false; | ||||
| 	bool openvz_host = false; | ||||
| 	char *line = NULL; | ||||
| 	char my_ns[30]; | ||||
| 	char proc_ns[30]; | ||||
| 	size_t len = 0; | ||||
| 	pid_t p; | ||||
| 	char buffer[PATH_MAX]; | ||||
| @@ -131,6 +134,14 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	memset(my_ns, 0, sizeof(my_ns)); | ||||
| 	memset(proc_ns, 0, sizeof(proc_ns)); | ||||
| 	if (exists("/proc/self/ns/pid")) { | ||||
| 		rc = readlink("/proc/self/ns/pid", my_ns, sizeof(my_ns)); | ||||
| 		if (rc <= 0) | ||||
| 			my_ns[0] = '\0'; | ||||
| 	} | ||||
|  | ||||
| 	while ((entry = readdir(procdir)) != NULL) { | ||||
| 		if (sscanf(entry->d_name, "%d", &p) != 1) | ||||
| 			continue; | ||||
| @@ -138,6 +149,14 @@ rc_find_pids(const char *exec, const char *const *argv, uid_t uid, pid_t pid) | ||||
| 			continue; | ||||
| 		if (pid != 0 && pid != p) | ||||
| 			continue; | ||||
| 		snprintf(buffer, sizeof(buffer), "/proc/%d/ns/pid", p); | ||||
| 		if (exists(buffer)) { | ||||
| 			rc = readlink(buffer, proc_ns, sizeof(proc_ns)); | ||||
| 			if (rc <= 0) | ||||
| 				proc_ns[0] = '\0'; | ||||
| 		} | ||||
| 		if (strcmp(my_ns, proc_ns)) | ||||
| 			continue; | ||||
| 		if (uid) { | ||||
| 			snprintf(buffer, sizeof(buffer), "/proc/%d", p); | ||||
| 			if (stat(buffer, &sb) != 0 || sb.st_uid != uid) | ||||
|   | ||||
| @@ -894,12 +894,15 @@ rc_service_value_set(const char *service, const char *option, | ||||
| 		return false; | ||||
|  | ||||
| 	snprintf(p, sizeof(file) - (p - file), "/%s", option); | ||||
| 	if (!(fp = fopen(file, "w"))) | ||||
| 		return false; | ||||
| 	if (value) | ||||
| 	if (value) { | ||||
| 		if (!(fp = fopen(file, "w"))) | ||||
| 			return false; | ||||
| 		fprintf(fp, "%s", value); | ||||
| 	fclose(fp); | ||||
| 	return true; | ||||
| 		fclose(fp); | ||||
| 	} else { | ||||
| 		unlink(file); | ||||
| 	} | ||||
| 		return true; | ||||
| } | ||||
| librc_hidden_def(rc_service_value_set) | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,7 @@ SBINDIR=	${PREFIX}/sbin | ||||
| LINKDIR=	${LIBEXECDIR} | ||||
|  | ||||
| BINPROGS=	rc-status | ||||
| SBINPROGS = openrc openrc-run rc rc-service rc-update runscript service \ | ||||
| SBINPROGS = openrc openrc-run rc rc-service rc-update runscript \ | ||||
| 			start-stop-daemon supervise-daemon | ||||
| RC_BINPROGS=	einfon einfo ewarnn ewarn eerrorn eerror ebegin eend ewend \ | ||||
| 				eindent eoutdent esyslog eval_ecolors ewaitfile \ | ||||
| @@ -150,7 +150,7 @@ rc-depend: rc-depend.o _usage.o rc-misc.o | ||||
| rc-status: rc-status.o _usage.o rc-misc.o | ||||
| 	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD} | ||||
|  | ||||
| rc-service service: rc-service.o _usage.o rc-misc.o | ||||
| rc-service: rc-service.o _usage.o rc-misc.o | ||||
| 	${CC} ${LOCAL_CFLAGS} ${LOCAL_LDFLAGS} ${CFLAGS} ${LDFLAGS} -o $@ $^ ${LDADD} | ||||
|  | ||||
| rc-update: rc-update.o _usage.o rc-misc.o | ||||
|   | ||||
| @@ -217,6 +217,18 @@ signal_setup(int sig, void (*handler)(int)) | ||||
| 	return sigaction(sig, &sa, NULL); | ||||
| } | ||||
|  | ||||
| int | ||||
| signal_setup_restart(int sig, void (*handler)(int)) | ||||
| { | ||||
| 	struct sigaction sa; | ||||
|  | ||||
| 	memset(&sa, 0, sizeof (sa)); | ||||
| 	sigemptyset(&sa.sa_mask); | ||||
| 	sa.sa_handler = handler; | ||||
| 	sa.sa_flags = SA_RESTART; | ||||
| 	return sigaction(sig, &sa, NULL); | ||||
| } | ||||
|  | ||||
| int | ||||
| svc_lock(const char *applet) | ||||
| { | ||||
|   | ||||
| @@ -56,11 +56,6 @@ typedef struct scheduleitem { | ||||
|  | ||||
| static TAILQ_HEAD(, scheduleitem) schedule; | ||||
|  | ||||
| void initialize_schedulelist(void) | ||||
| { | ||||
| 	TAILQ_INIT(&schedule); | ||||
| } | ||||
|  | ||||
| void free_schedulelist(void) | ||||
| { | ||||
| 	SCHEDULEITEM *s1 = TAILQ_FIRST(&schedule); | ||||
| @@ -186,6 +181,7 @@ void parse_schedule(const char *applet, const char *string, int timeout) | ||||
| 	size_t len; | ||||
| 	SCHEDULEITEM *item; | ||||
|  | ||||
| 	TAILQ_INIT(&schedule); | ||||
| 	if (string) | ||||
| 		for (slash = string; *slash; slash++) | ||||
| 			if (*slash == '/') | ||||
| @@ -261,10 +257,10 @@ int do_stop(const char *applet, const char *exec, const char *const *argv, | ||||
| 	bool killed; | ||||
| 	int nkilled = 0; | ||||
|  | ||||
| 	if (pid) | ||||
| 	if (pid > 0) | ||||
| 		pids = rc_find_pids(NULL, NULL, 0, pid); | ||||
| 	else | ||||
| 		pids = rc_find_pids(exec, argv, uid, pid); | ||||
| 		pids = rc_find_pids(exec, argv, uid, 0); | ||||
|  | ||||
| 	if (!pids) | ||||
| 		return 0; | ||||
| @@ -412,11 +408,12 @@ int run_stop_schedule(const char *applet, | ||||
|  | ||||
| 	if (progressed) | ||||
| 		printf("\n"); | ||||
| 	if (! quiet) | ||||
| 	if (! quiet) { | ||||
| 		if (nrunning == 1) | ||||
| 			eerror("%s: %d process refused to stop", applet, nrunning); | ||||
| 		else | ||||
| 			eerror("%s: %d process(es) refused to stop", applet, nrunning); | ||||
| 	} | ||||
|  | ||||
| 	return -nrunning; | ||||
| } | ||||
|   | ||||
| @@ -13,7 +13,6 @@ | ||||
| #ifndef __RC_SCHEDULES_H | ||||
| #define __RC_SCHEDULES_H | ||||
|  | ||||
| void initialize_schedulelist(void); | ||||
| void free_schedulelist(void); | ||||
| int parse_signal(const char *applet, const char *sig); | ||||
| void parse_schedule(const char *applet, const char *string, int timeout); | ||||
|   | ||||
| @@ -39,7 +39,6 @@ | ||||
| #include "rc-selinux.h" | ||||
|  | ||||
| /* the context files for selinux */ | ||||
| #define RUN_INIT_FILE "run_init_type" | ||||
| #define INITRC_FILE "initrc_context" | ||||
|  | ||||
| #ifdef HAVE_AUDIT | ||||
| @@ -299,6 +298,26 @@ static int read_context_file(const char *filename, char **context) | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int read_run_init_context(char **context) | ||||
| { | ||||
| 	int ret = -1; | ||||
| 	RC_STRINGLIST *list; | ||||
| 	char *value = NULL; | ||||
|  | ||||
| 	list = rc_config_list(selinux_openrc_contexts_path()); | ||||
| 	if (list == NULL) | ||||
| 		return ret; | ||||
|  | ||||
| 	value = rc_config_value(list, "run_init"); | ||||
| 	if (value != NULL && strlen(value) > 0) { | ||||
| 		*context = xstrdup(value); | ||||
| 		ret = 0; | ||||
| 	} | ||||
|  | ||||
| 	rc_stringlist_free(list); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| void selinux_setup(char **argv) | ||||
| { | ||||
| 	char *new_context = NULL; | ||||
| @@ -312,7 +331,7 @@ void selinux_setup(char **argv) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (read_context_file(RUN_INIT_FILE, &run_init_t) != 0) { | ||||
| 	if (read_run_init_context(&run_init_t) != 0) { | ||||
| 		/* assume a reasonable default, rather than bailing out */ | ||||
| 		run_init_t = xstrdup("run_init_t"); | ||||
| 		ewarn("Assuming SELinux run_init type is %s", run_init_t); | ||||
| @@ -339,14 +358,13 @@ void selinux_setup(char **argv) | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	curr_t = context_type_get(curr_con); | ||||
| 	curr_t = xstrdup(context_type_get(curr_con)); | ||||
| 	if (!curr_t) { | ||||
| 		context_free(curr_con); | ||||
| 		free(curr_context); | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	curr_t = xstrdup(curr_t); | ||||
| 	/* dont need them anymore so free() now */ | ||||
| 	context_free(curr_con); | ||||
| 	free(curr_context); | ||||
|   | ||||
| @@ -128,6 +128,8 @@ print_service(const char *service) | ||||
| { | ||||
| 	char status[60]; | ||||
| 	char uptime [40]; | ||||
| 	char *child_pid = NULL; | ||||
| 	char *start_time = NULL; | ||||
| 	int cols =  printf(" %s", service); | ||||
| 	const char *c = ecolor(ECOLOR_GOOD); | ||||
| 	RC_SERVICE state = rc_service_state(service); | ||||
| @@ -147,7 +149,14 @@ print_service(const char *service) | ||||
| 		    rc_service_daemons_crashed(service) && | ||||
| 		    errno != EACCES) | ||||
| 		{ | ||||
| 			snprintf(status, sizeof(status), " crashed "); | ||||
| 			child_pid = rc_service_value_get(service, "child_pid"); | ||||
| 			start_time = rc_service_value_get(service, "start_time"); | ||||
| 			if (start_time && child_pid) | ||||
| 				snprintf(status, sizeof(status), " unsupervised "); | ||||
| 			else | ||||
| 				snprintf(status, sizeof(status), " crashed "); | ||||
| 			free(child_pid); | ||||
| 			free(start_time); | ||||
| 		} else { | ||||
| 			get_uptime(service, uptime, 40); | ||||
| 			snprintf(status, sizeof(status), " started %s", uptime); | ||||
|   | ||||
| @@ -67,7 +67,7 @@ static struct pam_conv conv = { NULL, NULL}; | ||||
|  | ||||
| const char *applet = NULL; | ||||
| const char *extraopts = NULL; | ||||
| const char *getoptstring = "D:d:e:g:I:Kk:m:N:p:R:r:Su:1:2:" \ | ||||
| const char *getoptstring = "D:d:e:g:I:Kk:m:N:p:R:r:Su:1:2:3" \ | ||||
| 	getoptstring_COMMON; | ||||
| const struct option longopts[] = { | ||||
| 	{ "respawn-delay",        1, NULL, 'D'}, | ||||
| @@ -87,6 +87,7 @@ const struct option longopts[] = { | ||||
| 	{ "user",         1, NULL, 'u'}, | ||||
| 	{ "stdout",       1, NULL, '1'}, | ||||
| 	{ "stderr",       1, NULL, '2'}, | ||||
| 	{ "reexec",       0, NULL, '3'}, | ||||
| 	longopts_COMMON | ||||
| }; | ||||
| const char * const longopts_help[] = { | ||||
| @@ -107,6 +108,7 @@ const char * const longopts_help[] = { | ||||
| 	"Change the process user", | ||||
| 	"Redirect stdout to file", | ||||
| 	"Redirect stderr to file", | ||||
| 	"reexec (used internally)", | ||||
| 	longopts_help_COMMON | ||||
| }; | ||||
| const char *usagestring = NULL; | ||||
| @@ -127,6 +129,13 @@ static bool exiting = false; | ||||
| #ifdef TIOCNOTTY | ||||
| static int tty_fd = -1; | ||||
| #endif | ||||
| static pid_t child_pid; | ||||
| static int respawn_count = 0; | ||||
| static int respawn_delay = 0; | ||||
| static int respawn_max = 10; | ||||
| static int respawn_period = 5; | ||||
| static char *pidfile = NULL; | ||||
| static char *svcname = NULL; | ||||
|  | ||||
| extern char **environ; | ||||
|  | ||||
| @@ -150,8 +159,71 @@ static void cleanup(void) | ||||
| 	free(changeuser); | ||||
| } | ||||
|  | ||||
| static void child_process(char *exec, char **argv, char *svcname, | ||||
| 		int start_count) | ||||
| static void re_exec(void) | ||||
| { | ||||
| 	syslog(LOG_WARNING, "Re-executing supervise-daemon"); | ||||
| 	execlp("supervise-daemon", "supervise-daemon", "--reexec", (char *) NULL); | ||||
| 	syslog(LOG_ERR, "Unable to execute supervise-daemon: %s", | ||||
| 			strerror(errno)); | ||||
| 	exit(EXIT_FAILURE); | ||||
| } | ||||
|  | ||||
| static void handle_signal(int sig) | ||||
| { | ||||
| 	int serrno = errno; | ||||
|  | ||||
| 	syslog(LOG_WARNING, "caught signal %d", sig); | ||||
|  | ||||
| 	if (sig == SIGTERM) | ||||
| 		exiting = true; | ||||
| 	/* Restore errno */ | ||||
| 	errno = serrno; | ||||
| 	if (! exiting) | ||||
| 		re_exec(); | ||||
| } | ||||
|  | ||||
| static char * expand_home(const char *home, const char *path) | ||||
| { | ||||
| 	char *opath, *ppath, *p, *nh; | ||||
| 	size_t len; | ||||
| 	struct passwd *pw; | ||||
|  | ||||
| 	if (!path || *path != '~') | ||||
| 		return xstrdup(path); | ||||
|  | ||||
| 	opath = ppath = xstrdup(path); | ||||
| 	if (ppath[1] != '/' && ppath[1] != '\0') { | ||||
| 		p = strchr(ppath + 1, '/'); | ||||
| 		if (p) | ||||
| 			*p = '\0'; | ||||
| 		pw = getpwnam(ppath + 1); | ||||
| 		if (pw) { | ||||
| 			home = pw->pw_dir; | ||||
| 			ppath = p; | ||||
| 			if (ppath) | ||||
| 				*ppath = '/'; | ||||
| 		} else | ||||
| 			home = NULL; | ||||
| 	} else | ||||
| 		ppath++; | ||||
|  | ||||
| 	if (!home) { | ||||
| 	free(opath); | ||||
| 		return xstrdup(path); | ||||
| 	} | ||||
| 	if (!ppath) { | ||||
| 		free(opath); | ||||
| 		return xstrdup(home); | ||||
| 	} | ||||
|  | ||||
| 	len = strlen(ppath) + strlen(home) + 1; | ||||
| 	nh = xmalloc(len); | ||||
| 	snprintf(nh, len, "%s%s", home, ppath); | ||||
| 	free(opath); | ||||
| 	return nh; | ||||
| } | ||||
|  | ||||
| static void child_process(char *exec, char **argv) | ||||
| { | ||||
| 	RC_STRINGLIST *env_list; | ||||
| 	RC_STRING *env; | ||||
| @@ -176,11 +248,13 @@ static void child_process(char *exec, char **argv, char *svcname, | ||||
| 	setsid(); | ||||
|  | ||||
| 	if (svcname) { | ||||
| start_time = time(NULL); | ||||
| from_time_t(start_time_string, start_time); | ||||
| 		start_time = time(NULL); | ||||
| 		from_time_t(start_time_string, start_time); | ||||
| 		rc_service_value_set(svcname, "start_time", start_time_string); | ||||
| sprintf(start_count_string, "%i", start_count); | ||||
| 		sprintf(start_count_string, "%i", respawn_count); | ||||
| 		rc_service_value_set(svcname, "start_count", start_count_string); | ||||
| 		sprintf(start_count_string, "%d", getpid()); | ||||
| 		rc_service_value_set(svcname, "child_pid", start_count_string); | ||||
| 	} | ||||
|  | ||||
| 	if (nicelevel) { | ||||
| @@ -323,7 +397,7 @@ sprintf(start_count_string, "%i", start_count); | ||||
|  | ||||
| 	*cmdline = '\0'; | ||||
| 	c = argv; | ||||
| 	while (*c) { | ||||
| 	while (c && *c) { | ||||
| 		strcat(cmdline, *c); | ||||
| 		strcat(cmdline, " "); | ||||
| 		c++; | ||||
| @@ -338,107 +412,156 @@ sprintf(start_count_string, "%i", start_count); | ||||
| 	eerrorx("%s: failed to exec `%s': %s", applet, exec,strerror(errno)); | ||||
| } | ||||
|  | ||||
| static void handle_signal(int sig) | ||||
| static void supervisor(char *exec, char **argv) | ||||
| { | ||||
| 	int serrno = errno; | ||||
| 	char signame[10] = { '\0' }; | ||||
| 	FILE *fp; | ||||
| 	int i; | ||||
| 	int nkilled; | ||||
| 	time_t respawn_now= 0; | ||||
| 	time_t first_spawn= 0; | ||||
|  | ||||
| 	switch (sig) { | ||||
| 	case SIGINT: | ||||
| 		snprintf(signame, sizeof(signame), "SIGINT"); | ||||
| 		break; | ||||
| 	case SIGTERM: | ||||
| 		snprintf(signame, sizeof(signame), "SIGTERM"); | ||||
| 		break; | ||||
| 	case SIGQUIT: | ||||
| 		snprintf(signame, sizeof(signame), "SIGQUIT"); | ||||
| 		break; | ||||
| #ifndef RC_DEBUG | ||||
| 	signal_setup_restart(SIGHUP, handle_signal); | ||||
| 	signal_setup_restart(SIGINT, handle_signal); | ||||
| 	signal_setup_restart(SIGQUIT, handle_signal); | ||||
| 	signal_setup_restart(SIGILL, handle_signal); | ||||
| 	signal_setup_restart(SIGABRT, handle_signal); | ||||
| 	signal_setup_restart(SIGFPE, handle_signal); | ||||
| 	signal_setup_restart(SIGSEGV, handle_signal); | ||||
| 	signal_setup_restart(SIGPIPE, handle_signal); | ||||
| 	signal_setup_restart(SIGALRM, handle_signal); | ||||
| 	signal_setup(SIGTERM, handle_signal); | ||||
| 	signal_setup_restart(SIGUSR1, handle_signal); | ||||
| 	signal_setup_restart(SIGUSR2, handle_signal); | ||||
| 	signal_setup_restart(SIGBUS, handle_signal); | ||||
| 	signal_setup_restart(SIGPOLL, handle_signal); | ||||
| 	signal_setup_restart(SIGPROF, handle_signal); | ||||
| 	signal_setup_restart(SIGSYS, handle_signal); | ||||
| 	signal_setup_restart(SIGTRAP, handle_signal); | ||||
| 	signal_setup_restart(SIGVTALRM, handle_signal); | ||||
| 	signal_setup_restart(SIGXCPU, handle_signal); | ||||
| 	signal_setup_restart(SIGXFSZ, handle_signal); | ||||
| #ifdef SIGEMT | ||||
| 	signal_setup_restart(SIGEMT, handle_signal); | ||||
| #endif | ||||
| 	signal_setup_restart(SIGIO, handle_signal); | ||||
| 	signal_setup_restart(SIGPWR, handle_signal); | ||||
| #ifdef SIGUNUSED | ||||
| 	signal_setup_restart(SIGUNUSED, handle_signal); | ||||
| #endif | ||||
| #ifdef SIGRTMIN | ||||
| 	for (i = SIGRTMIN; i <= SIGRTMAX; i++) | ||||
| 		signal_setup_restart(i, handle_signal); | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| 	fp = fopen(pidfile, "w"); | ||||
| 	if (! fp) | ||||
| 		eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno)); | ||||
| 	fprintf(fp, "%d\n", getpid()); | ||||
| 	fclose(fp); | ||||
|  | ||||
| 	if (svcname) | ||||
| 		rc_service_daemon_set(svcname, exec, (const char * const *) argv, | ||||
| 				pidfile, true); | ||||
|  | ||||
| 	/* remove the controlling tty */ | ||||
| #ifdef TIOCNOTTY | ||||
| 	ioctl(tty_fd, TIOCNOTTY, 0); | ||||
| 	close(tty_fd); | ||||
| #endif | ||||
|  | ||||
| 	/* | ||||
| 	 * Supervisor main loop | ||||
| 	 */ | ||||
| 	i = 0; | ||||
| 	while (!exiting) { | ||||
| 		wait(&i); | ||||
| 		if (exiting) { | ||||
| 			signal_setup(SIGCHLD, SIG_IGN); | ||||
| 			syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid); | ||||
| 			nkilled = run_stop_schedule(applet, exec, NULL, child_pid, 0, | ||||
| 					false, false, true); | ||||
| 			if (nkilled > 0) | ||||
| 				syslog(LOG_INFO, "killed %d processes", nkilled); | ||||
| 		} else { | ||||
| 			sleep(respawn_delay); | ||||
| 			if (respawn_max > 0 && respawn_period > 0) { | ||||
| 				respawn_now = time(NULL); | ||||
| 				if (first_spawn == 0) | ||||
| 					first_spawn = respawn_now; | ||||
| 				if (respawn_now - first_spawn > respawn_period) { | ||||
| 					respawn_count = 0; | ||||
| 					first_spawn = 0; | ||||
| 				} else | ||||
| 					respawn_count++; | ||||
| 				if (respawn_count >= respawn_max) { | ||||
| 					syslog(LOG_WARNING, | ||||
| 							"respawned \"%s\" too many times, exiting", exec); | ||||
| 					exiting = true; | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 			if (WIFEXITED(i)) | ||||
| 				syslog(LOG_WARNING, "%s, pid %d, exited with return code %d", | ||||
| 						exec, child_pid, WEXITSTATUS(i)); | ||||
| 			else if (WIFSIGNALED(i)) | ||||
| 				syslog(LOG_WARNING, "%s, pid %d, terminated by signal %d", | ||||
| 						exec, child_pid, WTERMSIG(i)); | ||||
| 			child_pid = fork(); | ||||
| 			if (child_pid == -1) | ||||
| 				eerrorx("%s: fork: %s", applet, strerror(errno)); | ||||
| 			if (child_pid == 0) | ||||
| 				child_process(exec, argv); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (*signame != 0) { | ||||
| 		syslog(LOG_INFO, "%s: caught signal %s, exiting", applet, signame); | ||||
| 		exiting = true; | ||||
| 	} else | ||||
| 		syslog(LOG_INFO, "%s: caught unknown signal %d", applet, sig); | ||||
|  | ||||
| 	/* Restore errno */ | ||||
| 	errno = serrno; | ||||
| } | ||||
|  | ||||
| static char * expand_home(const char *home, const char *path) | ||||
| { | ||||
| 	char *opath, *ppath, *p, *nh; | ||||
| 	size_t len; | ||||
| 	struct passwd *pw; | ||||
|  | ||||
| 	if (!path || *path != '~') | ||||
| 		return xstrdup(path); | ||||
|  | ||||
| 	opath = ppath = xstrdup(path); | ||||
| 	if (ppath[1] != '/' && ppath[1] != '\0') { | ||||
| 		p = strchr(ppath + 1, '/'); | ||||
| 		if (p) | ||||
| 			*p = '\0'; | ||||
| 		pw = getpwnam(ppath + 1); | ||||
| 		if (pw) { | ||||
| 			home = pw->pw_dir; | ||||
| 			ppath = p; | ||||
| 			if (ppath) | ||||
| 				*ppath = '/'; | ||||
| 		} else | ||||
| 			home = NULL; | ||||
| 	} else | ||||
| 		ppath++; | ||||
|  | ||||
| 	if (!home) { | ||||
| 	free(opath); | ||||
| 		return xstrdup(path); | ||||
| 	if (pidfile && exists(pidfile)) | ||||
| 		unlink(pidfile); | ||||
| 	if (svcname) { | ||||
| 		rc_service_daemon_set(svcname, exec, (const char *const *)argv, | ||||
| 				pidfile, false); | ||||
| 		rc_service_mark(svcname, RC_SERVICE_STOPPED); | ||||
| 		rc_service_value_set(svcname, "child_pid", NULL); | ||||
| 	} | ||||
| 	if (!ppath) { | ||||
| 		free(opath); | ||||
| 		return xstrdup(home); | ||||
| 	} | ||||
|  | ||||
| 	len = strlen(ppath) + strlen(home) + 1; | ||||
| 	nh = xmalloc(len); | ||||
| 	snprintf(nh, len, "%s%s", home, ppath); | ||||
| 	free(opath); | ||||
| 	return nh; | ||||
| 	exit(EXIT_SUCCESS); | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	int opt; | ||||
| 	char **c; | ||||
| 	int x; | ||||
| 	bool start = false; | ||||
| 	bool stop = false; | ||||
| 	bool reexec = false; | ||||
| 	char *exec = NULL; | ||||
| 	char *pidfile = NULL; | ||||
| 	char *retry = NULL; | ||||
| 	int nkilled; | ||||
| 	int sig = SIGTERM; | ||||
| 	char *home = NULL; | ||||
| 	int tid = 0; | ||||
| 	pid_t child_pid, pid; | ||||
| 	char *svcname = getenv("RC_SVCNAME"); | ||||
| 	pid_t pid; | ||||
| 	char *tmp; | ||||
| 	char *p; | ||||
| 	char *token; | ||||
| 	int i; | ||||
| 	int n; | ||||
| 	char exec_file[PATH_MAX]; | ||||
| 	int respawn_count = 0; | ||||
| 	int respawn_delay = 0; | ||||
| 	int respawn_max = 10; | ||||
| 	int respawn_period = 5; | ||||
| 	time_t respawn_now= 0; | ||||
| 	time_t first_spawn= 0; | ||||
| 	char name[PATH_MAX]; | ||||
| 	struct timespec ts; | ||||
| 	struct passwd *pw; | ||||
| 	struct group *gr; | ||||
| 	FILE *fp; | ||||
| 	mode_t numask = 022; | ||||
| 	int child_argc = 0; | ||||
| 	char **child_argv = NULL; | ||||
| 	char *str = NULL; | ||||
| 	char cmdline[PATH_MAX]; | ||||
|  | ||||
| 	applet = basename_c(argv[0]); | ||||
| 	atexit(cleanup); | ||||
| 	svcname = getenv("RC_SVCNAME"); | ||||
| 	openlog(svcname, LOG_PID, LOG_DAEMON); | ||||
|  | ||||
| 	if ((tmp = getenv("SSD_NICELEVEL"))) | ||||
| 		if (sscanf(tmp, "%d", &nicelevel) != 1) | ||||
| @@ -492,8 +615,8 @@ int main(int argc, char **argv) | ||||
|  | ||||
| 		case 'P':  /* --respawn-period time */ | ||||
| 			n = sscanf(optarg, "%d", &respawn_period); | ||||
| 			if (n	!= 1 || respawn_delay < 1) | ||||
| 				eerrorx("Invalid respawn-delay value '%s'", optarg); | ||||
| 			if (n	!= 1 || respawn_period < 1) | ||||
| 				eerrorx("Invalid respawn-period value '%s'", optarg); | ||||
| 			break; | ||||
|  | ||||
| 		case 'S':  /* --start */ | ||||
| @@ -589,86 +712,183 @@ int main(int argc, char **argv) | ||||
| 		case '2':  /* --stderr /path/to/stderr.logfile */ | ||||
| 			redirect_stderr = optarg; | ||||
| 			break; | ||||
| 		case '3':  /* --reexec */ | ||||
| 			reexec = true; | ||||
| 			break; | ||||
|  | ||||
| 		case_RC_COMMON_GETOPT | ||||
| 		} | ||||
|  | ||||
| 	if (!pidfile) | ||||
| 	if (!pidfile && !reexec) | ||||
| 		eerrorx("%s: --pidfile must be specified", applet); | ||||
|  | ||||
| 	*cmdline = '\0'; | ||||
| 	c = argv; | ||||
| 	while (c && *c) { | ||||
| 		strcat(cmdline, *c); | ||||
| 		strcat(cmdline, " "); | ||||
| 		c++; | ||||
| 	} | ||||
| 	endpwent(); | ||||
| 	argc -= optind; | ||||
| 	argv += optind; | ||||
| 	exec = *argv; | ||||
|  | ||||
| 	if (start) { | ||||
| 		if (!exec) | ||||
| 			eerrorx("%s: nothing to start", applet); | ||||
| 		if (respawn_delay * respawn_max > respawn_period) { | ||||
| 			ewarn("%s: Please increase the value of --respawn-period to more " | ||||
| 				"than %d to avoid infinite respawning", applet,  | ||||
| 				respawn_delay * respawn_max); | ||||
| 		} | ||||
| 		if (retry) | ||||
| 			parse_schedule(applet, retry, sig); | ||||
| 		else | ||||
| 			parse_schedule(applet, NULL, sig); | ||||
| 	} | ||||
|  | ||||
| 	/* Expand ~ */ | ||||
| 	if (ch_dir && *ch_dir == '~') | ||||
| 		ch_dir = expand_home(home, ch_dir); | ||||
| 	if (ch_root && *ch_root == '~') | ||||
| 		ch_root = expand_home(home, ch_root); | ||||
| 	if (exec) { | ||||
| 		if (*exec == '~') | ||||
| 			exec = expand_home(home, exec); | ||||
|  | ||||
| 		/* Validate that the binary exists if we are starting */ | ||||
| 		if (*exec == '/' || *exec == '.') { | ||||
| 			/* Full or relative path */ | ||||
| 			if (ch_root) | ||||
| 				snprintf(exec_file, sizeof(exec_file), | ||||
| 				    "%s/%s", ch_root, exec); | ||||
| 			else | ||||
| 				snprintf(exec_file, sizeof(exec_file), | ||||
| 				    "%s", exec); | ||||
| 		} else { | ||||
| 			/* Something in $PATH */ | ||||
| 			p = tmp = xstrdup(getenv("PATH")); | ||||
| 			*exec_file = '\0'; | ||||
| 			while ((token = strsep(&p, ":"))) { | ||||
| 	umask(numask); | ||||
|  | ||||
| 	if (reexec) { | ||||
| 		str = rc_service_value_get(svcname, "argc"); | ||||
| 		sscanf(str, "%d", &child_argc); | ||||
| 		child_argv = xmalloc((child_argc + 1) * sizeof(char *)); | ||||
| 		memset(child_argv, 0, (child_argc + 1) * sizeof(char *)); | ||||
| 		for (x = 0; x < child_argc; x++) { | ||||
| 			sprintf(name, "argv_%d", x); | ||||
| 			str = rc_service_value_get(svcname, name); | ||||
| 			child_argv[x] = str; | ||||
| 		} | ||||
| 		free(str); | ||||
| 		str = rc_service_value_get(svcname, "child_pid"); | ||||
| 		sscanf(str, "%d", &child_pid); | ||||
| 		free(str); | ||||
| 		exec = rc_service_value_get(svcname, "exec"); | ||||
| 		pidfile = rc_service_value_get(svcname, "pidfile"); | ||||
| 		retry = rc_service_value_get(svcname, "retry"); | ||||
| 		if (retry) { | ||||
| 			parse_schedule(applet, retry, sig); | ||||
| 			rc_service_value_set(svcname, "retry", retry); | ||||
| 		} else | ||||
| 			parse_schedule(applet, NULL, sig); | ||||
|  | ||||
| 		str = rc_service_value_get(svcname, "respawn_delay"); | ||||
| 		sscanf(str, "%d", &respawn_delay); | ||||
| 		str = rc_service_value_get(svcname, "respawn_max"); | ||||
| 		sscanf(str, "%d", &respawn_max); | ||||
| 		supervisor(exec, child_argv); | ||||
| 	} else if (start) { | ||||
| 		if (exec) { | ||||
| 			if (*exec == '~') | ||||
| 				exec = expand_home(home, exec); | ||||
|  | ||||
| 			/* Validate that the binary exists if we are starting */ | ||||
| 			if (*exec == '/' || *exec == '.') { | ||||
| 				/* Full or relative path */ | ||||
| 				if (ch_root) | ||||
| 					snprintf(exec_file, sizeof(exec_file), | ||||
| 					    "%s/%s/%s", | ||||
| 					    ch_root, token, exec); | ||||
| 				    	"%s/%s", ch_root, exec); | ||||
| 				else | ||||
| 					snprintf(exec_file, sizeof(exec_file), | ||||
| 					    "%s/%s", token, exec); | ||||
| 				if (exists(exec_file)) | ||||
| 					break; | ||||
| 				    "%s", exec); | ||||
| 			} else { | ||||
| 				/* Something in $PATH */ | ||||
| 				p = tmp = xstrdup(getenv("PATH")); | ||||
| 				*exec_file = '\0'; | ||||
| 				while ((token = strsep(&p, ":"))) { | ||||
| 					if (ch_root) | ||||
| 						snprintf(exec_file, sizeof(exec_file), | ||||
| 					    	"%s/%s/%s", | ||||
| 					    	ch_root, token, exec); | ||||
| 					else | ||||
| 						snprintf(exec_file, sizeof(exec_file), | ||||
| 					    	"%s/%s", token, exec); | ||||
| 					if (exists(exec_file)) | ||||
| 						break; | ||||
| 					*exec_file = '\0'; | ||||
| 				} | ||||
| 				free(tmp); | ||||
| 			} | ||||
| 			free(tmp); | ||||
| 		} | ||||
| 	} | ||||
| 	if (start && !exists(exec_file)) | ||||
| 		eerrorx("%s: %s does not exist", applet, | ||||
| 		    *exec_file ? exec_file : exec); | ||||
| 			if ( !exists(exec_file)) | ||||
| 				eerrorx("%s: %s does not exist", applet, | ||||
| 				    *exec_file ? exec_file : exec); | ||||
| 		} else | ||||
| 			eerrorx("%s: nothing to start", applet); | ||||
|  | ||||
| 	if (stop) { | ||||
| 		pid = get_pid(applet, pidfile); | ||||
| 		if (pid == -1) | ||||
| 			i = pid; | ||||
| 		else | ||||
| 			i = kill(pid, SIGTERM); | ||||
| 		if (i != 0) | ||||
| 			/* We failed to send the signal */ | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		if (pid != -1) | ||||
| 			if (do_stop(applet, exec, (const char * const *)argv, pid, uid, | ||||
| 						0, false, true) > 0) | ||||
| 				eerrorx("%s: %s is already running", applet, exec); | ||||
|  | ||||
| 		/* wait for the supervisor to go down */ | ||||
| 		while (kill(pid, 0) == 0) | ||||
| 			sleep(1); | ||||
| 		if (respawn_delay * respawn_max > respawn_period) | ||||
| 			ewarn("%s: Please increase the value of --respawn-period to more " | ||||
| 				"than %d to avoid infinite respawning", applet,  | ||||
| 				respawn_delay * respawn_max); | ||||
|  | ||||
| 		if (retry) { | ||||
| 			parse_schedule(applet, retry, sig); | ||||
| 			rc_service_value_set(svcname, "retry", retry); | ||||
| 		} else | ||||
| 			parse_schedule(applet, NULL, sig); | ||||
|  | ||||
| 		einfov("Detaching to start `%s'", exec); | ||||
| 		syslog(LOG_INFO, "Supervisor command line: %s", cmdline); | ||||
|  | ||||
| 		/* Remove existing pidfile */ | ||||
| 		if (pidfile) | ||||
| 			unlink(pidfile); | ||||
|  | ||||
| 		/* Make sure we can write a pid file */ | ||||
| 		fp = fopen(pidfile, "w"); | ||||
| 		if (! fp) | ||||
| 			eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno)); | ||||
| 		fclose(fp); | ||||
|  | ||||
| 		rc_service_value_set(svcname, "pidfile", pidfile); | ||||
| 		sprintf(name, "%i", respawn_delay); | ||||
| 		rc_service_value_set(svcname, "respawn_delay", name); | ||||
| 		sprintf(name, "%i", respawn_max); | ||||
| 		rc_service_value_set(svcname, "respawn_max", name); | ||||
| 		sprintf(name, "%i", respawn_period); | ||||
| 		rc_service_value_set(svcname, "respawn_period", name); | ||||
| 		child_pid = fork(); | ||||
| 		if (child_pid == -1) | ||||
| 			eerrorx("%s: fork: %s", applet, strerror(errno)); | ||||
| 		if (child_pid != 0) | ||||
| 			/* first parent process, do nothing. */ | ||||
| 			exit(EXIT_SUCCESS); | ||||
| #ifdef TIOCNOTTY | ||||
| 		tty_fd = open("/dev/tty", O_RDWR); | ||||
| #endif | ||||
| 		devnull_fd = open("/dev/null", O_RDWR); | ||||
| 		child_pid = fork(); | ||||
| 		if (child_pid == -1) | ||||
| 			eerrorx("%s: fork: %s", applet, strerror(errno)); | ||||
| 		else if (child_pid != 0) { | ||||
| 			c = argv; | ||||
| 			x = 0; | ||||
| 			while (c && *c) { | ||||
| 				snprintf(name, sizeof(name), "argv_%-d",x); | ||||
| 				rc_service_value_set(svcname, name, *c); | ||||
| 				x++; | ||||
| 				c++; | ||||
| 			} | ||||
| 			sprintf(name, "%d", x); | ||||
| 				rc_service_value_set(svcname, "argc", name); | ||||
| 			rc_service_value_set(svcname, "exec", exec); | ||||
| 			supervisor(exec, argv); | ||||
| 		} else | ||||
| 			child_process(exec, argv); | ||||
| 	} else if (stop) { | ||||
| 		pid = get_pid(applet, pidfile); | ||||
| 		if (pid != -1) { | ||||
| 			i = kill(pid, SIGTERM); | ||||
| 			if (i != 0) | ||||
| 				/* We failed to send the signal */ | ||||
| 				ewarn("Unable to shut down the supervisor"); | ||||
| 			else { | ||||
| 				/* wait for the supervisor to go down */ | ||||
| 				while (kill(pid, 0) == 0) { | ||||
| 					ts.tv_sec = 0; | ||||
| 					ts.tv_nsec = 1; | ||||
| 					nanosleep(&ts, NULL); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		/* Even if we have not actually killed anything, we should | ||||
| 		 * remove information about it as it may have unexpectedly | ||||
| @@ -684,118 +904,4 @@ int main(int argc, char **argv) | ||||
| 		} | ||||
| 		exit(EXIT_SUCCESS); | ||||
| 	} | ||||
|  | ||||
| 	pid = get_pid(applet, pidfile); | ||||
| 	if (pid != -1) | ||||
| 		if (kill(pid, 0) == 0) | ||||
| 			eerrorx("%s: %s is already running", applet, exec); | ||||
|  | ||||
| 	einfov("Detaching to start `%s'", exec); | ||||
| 	eindentv(); | ||||
|  | ||||
| 	/* Remove existing pidfile */ | ||||
| 	if (pidfile) | ||||
| 		unlink(pidfile); | ||||
|  | ||||
| 	/* | ||||
| 	 * Make sure we can write a pid file | ||||
| 	 */ | ||||
| 	fp = fopen(pidfile, "w"); | ||||
| 	if (! fp) | ||||
| 		eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno)); | ||||
| 	fclose(fp); | ||||
|  | ||||
| 	child_pid = fork(); | ||||
| 	if (child_pid == -1) | ||||
| 		eerrorx("%s: fork: %s", applet, strerror(errno)); | ||||
|  | ||||
| 	/* first parent process, do nothing. */ | ||||
| 	if (child_pid != 0) | ||||
| 		exit(EXIT_SUCCESS); | ||||
|  | ||||
| #ifdef TIOCNOTTY | ||||
| 	tty_fd = open("/dev/tty", O_RDWR); | ||||
| #endif | ||||
| 	devnull_fd = open("/dev/null", O_RDWR); | ||||
| 	child_pid = fork(); | ||||
| 	if (child_pid == -1) | ||||
| 		eerrorx("%s: fork: %s", applet, strerror(errno)); | ||||
|  | ||||
| 	if (child_pid != 0) { | ||||
| 		/* this is the supervisor */ | ||||
| 		umask(numask); | ||||
| 		openlog(applet, LOG_PID, LOG_DAEMON); | ||||
| 		signal_setup(SIGTERM, handle_signal); | ||||
|  | ||||
| 		fp = fopen(pidfile, "w"); | ||||
| 		if (! fp) | ||||
| 			eerrorx("%s: fopen `%s': %s", applet, pidfile, strerror(errno)); | ||||
| 		fprintf(fp, "%d\n", getpid()); | ||||
| 		fclose(fp); | ||||
|  | ||||
| 		if (svcname) | ||||
| 			rc_service_daemon_set(svcname, exec, | ||||
| 									(const char * const *) argv, pidfile, true); | ||||
|  | ||||
| 	/* remove the controlling tty */ | ||||
| #ifdef TIOCNOTTY | ||||
| 		ioctl(tty_fd, TIOCNOTTY, 0); | ||||
| 		close(tty_fd); | ||||
| #endif | ||||
|  | ||||
| 		/* | ||||
| 		 * Supervisor main loop | ||||
| 		 */ | ||||
| 		i = 0; | ||||
| 		while (!exiting) { | ||||
| 			wait(&i); | ||||
| 			if (exiting) { | ||||
| 				syslog(LOG_INFO, "stopping %s, pid %d", exec, child_pid); | ||||
| 				nkilled = run_stop_schedule(applet, exec, NULL, child_pid, | ||||
| 						0, false, false, true); | ||||
| 				if (nkilled > 0) | ||||
| 					syslog(LOG_INFO, "killed %d processes", nkilled); | ||||
| 			} else { | ||||
| 				sleep(respawn_delay); | ||||
| 				if (respawn_max > 0 && respawn_period > 0) { | ||||
| 					respawn_now = time(NULL); | ||||
| 					if (first_spawn == 0) | ||||
| 						first_spawn = respawn_now; | ||||
| 					if (respawn_now - first_spawn > respawn_period) { | ||||
| 						respawn_count = 0; | ||||
| 						first_spawn = 0; | ||||
| 					} else | ||||
| 						respawn_count++; | ||||
| 					if (respawn_count >= respawn_max) { | ||||
| 						syslog(LOG_INFO, "respawned \"%s\" too many times, " | ||||
| 								"exiting", exec); | ||||
| 						exiting = true; | ||||
| 						continue; | ||||
| 					} | ||||
| 				} | ||||
| 				if (WIFEXITED(i)) | ||||
| 					syslog(LOG_INFO, "%s, pid %d, exited with return code %d", | ||||
| 							exec, child_pid, WEXITSTATUS(i)); | ||||
| 				else if (WIFSIGNALED(i)) | ||||
| 					syslog(LOG_INFO, "%s, pid %d, terminated by signal %d", | ||||
| 							exec, child_pid, WTERMSIG(i)); | ||||
| 				child_pid = fork(); | ||||
| 				if (child_pid == -1) | ||||
| 					eerrorx("%s: fork: %s", applet, strerror(errno)); | ||||
| 				if (child_pid == 0) | ||||
| 					child_process(exec, argv, svcname, respawn_count); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (pidfile && exists(pidfile)) | ||||
| 			unlink(pidfile); | ||||
| 		if (svcname) { | ||||
| 			rc_service_daemon_set(svcname, exec, | ||||
| 			    (const char *const *)argv, | ||||
| 			    pidfile, false); | ||||
| 			rc_service_mark(svcname, RC_SERVICE_STOPPED); | ||||
| 		} | ||||
| 		exit(EXIT_SUCCESS); | ||||
| 	} else if (child_pid == 0) | ||||
| 		child_process(exec, argv, svcname, respawn_count); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user