Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e74dff96ba | ||
|
|
9ed4407b20 | ||
|
|
eb913e8bf2 | ||
|
|
17d04779fb | ||
|
|
ab661423ba | ||
|
|
8e77ea68b2 | ||
|
|
b0e672bc9a | ||
|
|
ad76e15949 | ||
|
|
b8735cc893 | ||
|
|
c058b3f9ce | ||
|
|
8f6c61606a | ||
|
|
96f944b816 | ||
|
|
a81530754b | ||
|
|
1518eb9466 | ||
|
|
50b9e46e19 | ||
|
|
c01faef99b | ||
|
|
4867b7268b | ||
|
|
662293e194 | ||
|
|
4ce810cc1f | ||
|
|
184c079c08 | ||
|
|
17c6791c70 | ||
|
|
42f24f5af5 | ||
|
|
cef5049bf0 | ||
|
|
ec251f1ce1 | ||
|
|
98ec30d308 | ||
|
|
e1fe870aaf | ||
|
|
f04fce544d | ||
|
|
7aa9ed5982 | ||
|
|
a1a92a04bd | ||
|
|
804f655d87 | ||
|
|
2c78e7429a | ||
|
|
d77f0127b4 | ||
|
|
4253d0de25 | ||
|
|
d47181a4a7 | ||
|
|
8642007d0e | ||
|
|
96c74ed48b | ||
|
|
03a14bcaa5 | ||
|
|
4bb2c33859 | ||
|
|
ab81272083 | ||
|
|
1fbf03bc1e | ||
|
|
92a2861b1c | ||
|
|
922714780a | ||
|
|
b206c3d655 | ||
|
|
109d8826bd | ||
|
|
60478106eb | ||
|
|
0de9cfb020 | ||
|
|
0b182c063e | ||
|
|
f0914f6d32 | ||
|
|
7090321ff3 | ||
|
|
266f1132a4 | ||
|
|
5f7e8457af | ||
|
|
a215747355 | ||
|
|
dacda5ab5d | ||
|
|
39044adcf8 | ||
|
|
9396cd1d26 | ||
|
|
c9fd4418e7 | ||
|
|
7206f745a2 | ||
|
|
25bcde12d4 | ||
|
|
7459ede806 | ||
|
|
6bf35513c3 | ||
|
|
0b8d39329a | ||
|
|
84098dd8b7 | ||
|
|
c4463ec64f | ||
|
|
6f1808248e | ||
|
|
29029bb78f | ||
|
|
bbe588ac16 | ||
|
|
34bf9a7776 | ||
|
|
bb111f98fc | ||
|
|
c7faf4f9e2 | ||
|
|
18774539c0 | ||
|
|
abaad560f0 | ||
|
|
0ef325d86c | ||
|
|
2c94f4e45f | ||
|
|
da184e7922 | ||
|
|
1e93fc1671 | ||
|
|
8e7d1b7bb5 | ||
|
|
373738f3d1 | ||
|
|
e6d3eb2526 | ||
|
|
d7fd5bc902 | ||
|
|
3f98220d5d | ||
|
|
0ca509a42e | ||
|
|
d17144d16f | ||
|
|
a608c5a5c9 | ||
|
|
9b44b99480 | ||
|
|
ad225156f1 | ||
|
|
eb92a915d3 | ||
|
|
69a4f2c115 | ||
|
|
9ce95fe8c0 | ||
|
|
06889cc014 | ||
|
|
329f11b4da | ||
|
|
ce40e2b9d2 | ||
|
|
d0176612c9 | ||
|
|
21753e26dd | ||
|
|
0dc2513b32 | ||
|
|
d16bfa789b | ||
|
|
0b27778c96 | ||
|
|
3e25297e3c | ||
|
|
6560968c8b | ||
|
|
c9a3c5c885 | ||
|
|
a2d45e8f5e | ||
|
|
f6c69eb108 | ||
|
|
f0032ab6b7 | ||
|
|
53c5d0e55a | ||
|
|
7c8ab7915f | ||
|
|
12f7855a78 | ||
|
|
bcc3360b53 | ||
|
|
d3408d14a8 | ||
|
|
804060444a | ||
|
|
de544a5b36 | ||
|
|
0d48d1df49 | ||
|
|
b46592e818 | ||
|
|
22bc218c84 | ||
|
|
702a606d26 | ||
|
|
a3d9b6e9b1 | ||
|
|
390a0f48c1 | ||
|
|
f4a13687e8 | ||
|
|
43ca51c3b1 | ||
|
|
864b71af14 | ||
|
|
44a928e5e6 | ||
|
|
f513348963 | ||
|
|
820b9a77c1 | ||
|
|
85baafe99c | ||
|
|
e635ea882a | ||
|
|
f908c8d43a | ||
|
|
308f75b209 | ||
|
|
d87d298c85 | ||
|
|
ae7931f68e | ||
|
|
8422d2715c | ||
|
|
2eefaa5db6 | ||
|
|
fb0ad18d3a | ||
|
|
2681444b07 | ||
|
|
dd36116a97 | ||
|
|
e756d6f8ac | ||
|
|
567c695954 | ||
|
|
4877aecc1e | ||
|
|
65644f5956 | ||
|
|
a02760f499 | ||
|
|
7aab3bb421 | ||
|
|
b5beb2b8d4 | ||
|
|
09b4aee5bc | ||
|
|
d9a0c2dce9 | ||
|
|
178301baf2 | ||
|
|
4e18affa9b | ||
|
|
21f40fb95e | ||
|
|
24f0cee49a | ||
|
|
fee38d4359 | ||
|
|
0c85ea844a | ||
|
|
c3839edc40 | ||
|
|
be2a0ec3e7 | ||
|
|
c23952cd9e | ||
|
|
13a8f56b46 | ||
|
|
927acdbd7e | ||
|
|
6f6267f3b3 | ||
|
|
dec89d4054 | ||
|
|
193e114596 | ||
|
|
1be67c434e | ||
|
|
4f8dab75b2 | ||
|
|
37d063fd3b | ||
|
|
97be3da126 | ||
|
|
e7f97f8264 | ||
|
|
6415aeebac | ||
|
|
e69200ea43 | ||
|
|
26d5018224 | ||
|
|
1b7699ca93 | ||
|
|
8eab099f09 | ||
|
|
c7c5426586 | ||
|
|
85484178e0 | ||
|
|
e958189e6a | ||
|
|
eb13309a34 | ||
|
|
4f01856313 | ||
|
|
2aa9e5bad6 | ||
|
|
b897c62a73 | ||
|
|
6c133e85f2 | ||
|
|
d30959e909 | ||
|
|
2badd840fa | ||
|
|
e00476250f | ||
|
|
c3f758de96 | ||
|
|
29761b69ea | ||
|
|
e08d56af71 | ||
|
|
a370ddc3c0 | ||
|
|
8377f0e736 | ||
|
|
f42a1fd356 | ||
|
|
ab82e6f696 | ||
|
|
cd0ddd6bfc | ||
|
|
31b78817dd | ||
|
|
5599aca0a3 | ||
|
|
d77773d8ee | ||
|
|
efadbb0694 | ||
|
|
de4be1557b | ||
|
|
a73e02afac | ||
|
|
a3c5dfd543 | ||
|
|
4c208c18e2 | ||
|
|
0a9ac65609 | ||
|
|
167d75ac4a | ||
|
|
0cd51fb7d3 | ||
|
|
bf2c0542ca | ||
|
|
0bef874cf3 | ||
|
|
eadd01da1f | ||
|
|
80b0750523 | ||
|
|
4525aec118 | ||
|
|
61be1ef880 | ||
|
|
a7428ababa | ||
|
|
b4b7ee1b71 | ||
|
|
ff91d5c836 | ||
|
|
d652211621 | ||
|
|
9f95934df9 | ||
|
|
261d604ea3 | ||
|
|
085fc4c660 | ||
|
|
ce7d4cebab | ||
|
|
d5a47e2d8b | ||
|
|
020eefe732 | ||
|
|
14336bd407 | ||
|
|
bb841383b8 | ||
|
|
e49763d834 | ||
|
|
57545e1ab0 | ||
|
|
7ad802b092 | ||
|
|
e319a606b8 | ||
|
|
7d434b1eaa | ||
|
|
58d48b54b3 | ||
|
|
7d4603e13b | ||
|
|
d0c5d7be5b | ||
|
|
db840bdc19 | ||
|
|
3df3c51dae | ||
|
|
d37d241647 | ||
|
|
b18b21830a | ||
|
|
06daf2e4a5 | ||
|
|
eb13ccc227 | ||
|
|
0861373d14 | ||
|
|
1b9e69414e | ||
|
|
39f4aa3f2c | ||
|
|
dedb56a9d0 | ||
|
|
a27903c745 | ||
|
|
f24f76fc80 | ||
|
|
d95fc5f790 | ||
|
|
10a1257e47 | ||
|
|
a7b8e1b94d | ||
|
|
da83462731 | ||
|
|
1396177706 | ||
|
|
7cf0a293fd | ||
|
|
d0d9b83b66 | ||
|
|
76f8a18816 | ||
|
|
dc497bcd57 | ||
|
|
0da6bbe4a8 | ||
|
|
91f7a75bee | ||
|
|
f217d493b4 | ||
|
|
77404a2ea0 | ||
|
|
d42a1d438b | ||
|
|
1275f05343 | ||
|
|
61a92aa0b6 | ||
|
|
b38ff0cc79 | ||
|
|
168f5bf1d8 | ||
|
|
ffd00f646c | ||
|
|
5e2e273cad | ||
|
|
33f6697cd5 | ||
|
|
6f0ba22a0f | ||
|
|
ecb690c9ec | ||
|
|
0459bb432a | ||
|
|
2760616c73 | ||
|
|
62ab990129 | ||
|
|
0c2836d747 | ||
|
|
8be7a462e0 | ||
|
|
5993b4bb5d | ||
|
|
2957246092 | ||
|
|
a5710125f6 | ||
|
|
ff95ebeb91 | ||
|
|
1921b3f2c5 | ||
|
|
051ef81e53 | ||
|
|
90993c237a | ||
|
|
b0b4f7b2ba | ||
|
|
4d79d84fb8 | ||
|
|
d318aa00c3 | ||
|
|
9684127eb7 | ||
|
|
8d2cfd69fa | ||
|
|
4f252858e4 | ||
|
|
1ccd1d6926 | ||
|
|
b87c51209d | ||
|
|
6b7478ff43 | ||
|
|
6c4c16cbdb | ||
|
|
e539dbfe37 | ||
|
|
90c6bcd365 | ||
|
|
c9c268f218 | ||
|
|
3feff37ba5 | ||
|
|
c67d15e272 | ||
|
|
8984c655f8 | ||
|
|
1a7b26bac3 | ||
|
|
1f47718012 | ||
|
|
fa13cddc28 | ||
|
|
185a72bd14 | ||
|
|
cd32c623cf | ||
|
|
ac4b9c2f93 | ||
|
|
5e9591d0a8 | ||
|
|
e3bcf9bf16 | ||
|
|
84fd3196b0 | ||
|
|
994e51e34f | ||
|
|
0a7814b391 | ||
|
|
73f72b39cf | ||
|
|
02e0aa7383 | ||
|
|
6528628b5c | ||
|
|
1480657982 | ||
|
|
33e378a345 | ||
|
|
b695b46a9d | ||
|
|
0e61ed727f | ||
|
|
e9d60a6c04 | ||
|
|
5e9edf9deb | ||
|
|
8ed2751ae1 | ||
|
|
7fec66dc09 | ||
|
|
75fa868a4b | ||
|
|
7b321de339 | ||
|
|
1691ebb292 | ||
|
|
c371c10455 | ||
|
|
a23e152f6b | ||
|
|
9210f2851e | ||
|
|
617609cbc5 | ||
|
|
b022916758 | ||
|
|
9a357b7aab | ||
|
|
ffd01b0276 | ||
|
|
2c95f091ee | ||
|
|
b75b107d6d | ||
|
|
1f2c1d2109 | ||
|
|
f328d24d01 | ||
|
|
211293a83d | ||
|
|
446f5bc8b8 | ||
|
|
0c6f748f2c | ||
|
|
a677b94ad9 | ||
|
|
6552cda605 | ||
|
|
3add682be3 | ||
|
|
abac31682d | ||
|
|
cfe915e6d5 | ||
|
|
ecf65ce44b | ||
|
|
0d742d6ae8 | ||
|
|
cf201a43df | ||
|
|
9245869e18 | ||
|
|
0f4a487328 | ||
|
|
f1b5b42919 | ||
|
|
f546129baf | ||
|
|
27451ac3f2 | ||
|
|
0a8f3a6250 | ||
|
|
70c4e7d774 | ||
|
|
5265eee25d | ||
|
|
4b06e1a49f | ||
|
|
6b9aa21509 | ||
|
|
990307fbc9 | ||
|
|
9d8a9b7fba | ||
|
|
bbc83eaa64 | ||
|
|
23d034f521 | ||
|
|
9a3148a49d | ||
|
|
8560103a24 | ||
|
|
7a75e34808 | ||
|
|
4d4fc10d57 | ||
|
|
003faae9e9 | ||
|
|
01a01d65c0 | ||
|
|
048302f06a | ||
|
|
74f0fcfccd | ||
|
|
3cfe0a33b8 | ||
|
|
465bc17ca4 | ||
|
|
d4889b435d | ||
|
|
49c0557ced | ||
|
|
6be16f2f6d | ||
|
|
bc8118d515 | ||
|
|
0c0e880f3f | ||
|
|
119e66a7e9 | ||
|
|
46ffa81f5c | ||
|
|
54701422a5 | ||
|
|
9d463e3823 | ||
|
|
56e558c960 | ||
|
|
dfaf351da1 | ||
|
|
a8433fcb7f | ||
|
|
2daa953bee | ||
|
|
3e3e9aadf5 | ||
|
|
dc873c6548 | ||
|
|
29bd7a504e | ||
|
|
a0685219cf | ||
|
|
13b107b7b1 | ||
|
|
409d68d05b | ||
|
|
ab62b5282b | ||
|
|
d02d65feeb | ||
|
|
9a0dea6aef | ||
|
|
7481505b1a | ||
|
|
8251f1a422 | ||
|
|
e269176a79 | ||
|
|
612f5a9385 | ||
|
|
4a2381eb6f | ||
|
|
0cae7d44dd | ||
|
|
340cae4afd | ||
|
|
6a89e60fc8 | ||
|
|
840d612fc2 | ||
|
|
60c676ab2d | ||
|
|
deada0fa89 | ||
|
|
7b501f255b | ||
|
|
052136cb99 | ||
|
|
742b8b72cc | ||
|
|
c37037c015 | ||
|
|
c32b5a749a | ||
|
|
7701718d7b | ||
|
|
eb4eca9607 | ||
|
|
cab94b81e8 | ||
|
|
5913217808 | ||
|
|
b49f55ab3d | ||
|
|
bf4a584e2e | ||
|
|
90a4df8d12 | ||
|
|
146bf55122 | ||
|
|
c1ed373398 | ||
|
|
5998342b3e | ||
|
|
9dc7b8a6b0 | ||
|
|
c221823654 | ||
|
|
248f7d3110 | ||
|
|
fe90ba5781 | ||
|
|
71c87734b7 | ||
|
|
cd060e8af3 | ||
|
|
33a7f123d7 | ||
|
|
d15e28ea6b | ||
|
|
836bfff08b | ||
|
|
59152b557c | ||
|
|
293b0ffa79 | ||
|
|
d5d9cd5645 | ||
|
|
2f281665af | ||
|
|
b00e7394f8 | ||
|
|
d5a5fffa52 | ||
|
|
4d24c34b28 | ||
|
|
355265651e | ||
|
|
41093df2a9 | ||
|
|
0a816d1fa4 | ||
|
|
3bfc0f0fca | ||
|
|
0aa6ee895c | ||
|
|
b1526fb2d6 | ||
|
|
b2624ac160 | ||
|
|
2c340f83ce | ||
|
|
337ee003bb | ||
|
|
791df0c986 | ||
|
|
f29e92be21 | ||
|
|
379a63fce4 | ||
|
|
b1f9a11809 | ||
|
|
2d9c63e48e | ||
|
|
d66455496a | ||
|
|
77cf72cb40 | ||
|
|
6cc587068b | ||
|
|
cc96e8908a | ||
|
|
adb25d52cd | ||
|
|
7d09567ec8 | ||
|
|
9130af1c77 | ||
|
|
cbea83b369 | ||
|
|
42cd8d284b | ||
|
|
72ebc92622 | ||
|
|
06adecaaea | ||
|
|
efc0592961 | ||
|
|
ed88469276 | ||
|
|
cbf96a1de0 | ||
|
|
cc979f27f1 | ||
|
|
fca5ce57ea | ||
|
|
53aa195ad5 | ||
|
|
e60211168e | ||
|
|
dc3ee9e467 | ||
|
|
6918f3b711 | ||
|
|
66020f48ea | ||
|
|
47b0d4cccf | ||
|
|
92c2efa655 | ||
|
|
b69aa8a8bd | ||
|
|
ca90bbfb04 | ||
|
|
0b5c555c7f | ||
|
|
6443995fc9 | ||
|
|
180faf8a40 | ||
|
|
0ebdd32f6b | ||
|
|
60bf858302 | ||
|
|
7c86b40190 | ||
|
|
4f3f140a09 | ||
|
|
10c24b1674 | ||
|
|
2b4f89ecd1 | ||
|
|
c42a6f2869 | ||
|
|
89bb609a7e | ||
|
|
da6298aecd | ||
|
|
576318cc29 | ||
|
|
0d7d331ad4 | ||
|
|
c886ecb5cc | ||
|
|
304a096877 | ||
|
|
064c7682fc | ||
|
|
58239b897b | ||
|
|
5281d82e80 | ||
|
|
5ff28c4dc6 | ||
|
|
f2218836af | ||
|
|
fbb3779d17 | ||
|
|
68f44f7a97 | ||
|
|
50e587f447 | ||
|
|
fb4c560196 | ||
|
|
8b5fa5eeaa | ||
|
|
88ec21e9cc | ||
|
|
84adec4006 | ||
|
|
19b2b2a279 | ||
|
|
e4163b7221 | ||
|
|
eaef302420 | ||
|
|
d5738da307 | ||
|
|
c9f930c7ad | ||
|
|
e2ee372b5d | ||
|
|
7ff7f93364 | ||
|
|
d5a95760ef | ||
|
|
24d1425b74 | ||
|
|
43d9e25ba7 | ||
|
|
f27998ae4f | ||
|
|
c8e0b6b9ef | ||
|
|
f7e8fccb2f | ||
|
|
7bbccb1213 | ||
|
|
d38c333e04 | ||
|
|
095f6b645c | ||
|
|
b4d10cbade | ||
|
|
5d703fd39e | ||
|
|
eaaf8d862e | ||
|
|
2468f11cd8 | ||
|
|
f8a6a119ac | ||
|
|
1889b88aab | ||
|
|
0d70023bfe | ||
|
|
41648a073b | ||
|
|
33cee0ba5f | ||
|
|
2235fb8352 | ||
|
|
eb9e94935e | ||
|
|
fb230f2137 | ||
|
|
6aa48a8b32 | ||
|
|
5b9cebbfd3 | ||
|
|
38791616e0 | ||
|
|
fede3fd2e1 | ||
|
|
a46a33238d | ||
|
|
afe0488bf2 | ||
|
|
ec5e42694d | ||
|
|
2e73563eea | ||
|
|
338521a748 | ||
|
|
6ae1083c99 | ||
|
|
846806747b | ||
|
|
8904ca993e | ||
|
|
efed0db16b | ||
|
|
11946f12d3 | ||
|
|
2ba359ed80 | ||
|
|
fafd524701 | ||
|
|
1ee6c9f46b | ||
|
|
a88eb82a68 | ||
|
|
a436a1c8cb | ||
|
|
7cb91854b0 | ||
|
|
939ae02a6a | ||
|
|
480d29175c | ||
|
|
ea68413512 | ||
|
|
4edfa9859e | ||
|
|
eb6291c943 | ||
|
|
756b7c3fb6 | ||
|
|
263aec292a | ||
|
|
5a946a4ea7 | ||
|
|
c90b4d797b | ||
|
|
6e7a2fb6d5 | ||
|
|
ddedcf77e8 | ||
|
|
924ec2ef80 | ||
|
|
a49f27c191 | ||
|
|
b41b4ce989 | ||
|
|
3d74e93fa2 | ||
|
|
443700a88e | ||
|
|
4701edef4c | ||
|
|
e6da0a22e7 | ||
|
|
7be2bbbc30 | ||
|
|
3e269c632f | ||
|
|
f2507d9fd7 | ||
|
|
e9f403bceb | ||
|
|
c03176c42a | ||
|
|
9707bfb103 | ||
|
|
11430f83c8 | ||
|
|
a22a794f55 | ||
|
|
5556501287 | ||
|
|
ab554568b2 | ||
|
|
b39a4498a3 | ||
|
|
dead2444e2 | ||
|
|
a58002588e | ||
|
|
28e101aaae | ||
|
|
6da8af8136 | ||
|
|
3069e753e1 | ||
|
|
aafd5c1010 | ||
|
|
2f51c8ea0d | ||
|
|
d1130473fc | ||
|
|
b682a5e4fe | ||
|
|
1fc0f36c6c | ||
|
|
5df5b22327 | ||
|
|
4153c7966d | ||
|
|
458d68533f | ||
|
|
63b5db38df | ||
|
|
2135639508 | ||
|
|
9c8cd6c024 | ||
|
|
450f498061 | ||
|
|
5769500afe | ||
|
|
dc61969164 | ||
|
|
6f0d448765 | ||
|
|
0c9b7a67e0 | ||
|
|
5db2fb2c32 | ||
|
|
f4d3ec1a9f | ||
|
|
51befb492c | ||
|
|
7850378e15 | ||
|
|
438d6b4e63 | ||
|
|
712f68f9da | ||
|
|
8a32ec5c92 | ||
|
|
081622a085 | ||
|
|
2526431d8e | ||
|
|
47d8a83668 | ||
|
|
f72f3febf9 | ||
|
|
138546d008 | ||
|
|
cee244d151 | ||
|
|
7af4ad5c24 | ||
|
|
c0d3705ed5 | ||
|
|
5cf2b9a283 | ||
|
|
0e898da6e5 | ||
|
|
d9f13a1e50 | ||
|
|
4fbcd1bbad | ||
|
|
b6c5498f43 | ||
|
|
9a6c68c952 | ||
|
|
e8170e1216 | ||
|
|
059a4c8a86 | ||
|
|
0de9db68a3 | ||
|
|
aeff68b598 | ||
|
|
700c32fd73 | ||
|
|
334d4a708a | ||
|
|
4d472273e1 | ||
|
|
13f1359b3a | ||
|
|
2e5b97c8b2 | ||
|
|
9a962c86c8 | ||
|
|
f954a4cb92 | ||
|
|
feb97bc77c | ||
|
|
e00fda5dc3 | ||
|
|
80191f2fd5 | ||
|
|
42ef3d3cf7 | ||
|
|
1f4acb322a | ||
|
|
c3ba15045b | ||
|
|
8f1d1717f8 | ||
|
|
7703d00e82 | ||
|
|
3bb826b22b | ||
|
|
9ee2be121f | ||
|
|
36c6aa73aa | ||
|
|
13dddb6912 | ||
|
|
bdaf3370d4 | ||
|
|
a24077c4af | ||
|
|
414a49d733 | ||
|
|
be9d54561d | ||
|
|
3ce5a2a965 | ||
|
|
1d03e9aa8b | ||
|
|
5340e47e81 | ||
|
|
98bbf4a1e5 | ||
|
|
d70e2f1ed0 | ||
|
|
ecb5949679 | ||
|
|
e55fd19091 | ||
|
|
19c64e323c | ||
|
|
9354221bdd | ||
|
|
1d7048d3ae | ||
|
|
8251d713e0 | ||
|
|
44d0d87ad3 | ||
|
|
571250a9b9 | ||
|
|
91540fd793 | ||
|
|
2566e00ef0 | ||
|
|
1e5ce38928 | ||
|
|
c679b0a93d | ||
|
|
c4dcf568c8 | ||
|
|
b65773d508 | ||
|
|
e75c1792aa | ||
|
|
0be4838e01 | ||
|
|
b71605c819 | ||
|
|
3bb2eb2a8d | ||
|
|
8ce35771c3 | ||
|
|
67e80ea989 | ||
|
|
f4d8ecfb5b | ||
|
|
2eb3ebb404 | ||
|
|
1e1b3564dd | ||
|
|
7af257cccf | ||
|
|
84ddac65e5 | ||
|
|
62d6b56fd3 | ||
|
|
fa71f97dcf | ||
|
|
ed383eaaa6 | ||
|
|
9cb6a54493 | ||
|
|
f796d59f77 | ||
|
|
97ca450966 | ||
|
|
e0c1c08e68 | ||
|
|
c81b722691 | ||
|
|
11da93b759 | ||
|
|
28a90a793d | ||
|
|
56a89db889 | ||
|
|
a613ee908f | ||
|
|
d3f58b5df0 | ||
|
|
af88b10322 | ||
|
|
966ae9fb0d | ||
|
|
a69cef0a11 | ||
|
|
b396a018c5 | ||
|
|
a4af9ba248 | ||
|
|
6942e38413 | ||
|
|
e03bd093b5 | ||
|
|
d6070a0d10 | ||
|
|
bd4efb59ca | ||
|
|
a90cfd4a75 | ||
|
|
ab5a983bf7 | ||
|
|
f7bacf8b1b | ||
|
|
d363501e21 | ||
|
|
4150fdfe59 | ||
|
|
4d2b97e4cc | ||
|
|
21eda9dd1c | ||
|
|
4f7e726a3e | ||
|
|
74fc16b832 | ||
|
|
7393072120 | ||
|
|
96bb3f5c6c | ||
|
|
c23a867485 | ||
|
|
4f8a5a6531 | ||
|
|
48e1a0b17f | ||
|
|
9c727ed08d | ||
|
|
49cd3a441d | ||
|
|
8b9258aa73 | ||
|
|
82c6e4680f | ||
|
|
a67b2ba9a7 | ||
|
|
a96edf0291 | ||
|
|
c26dded49c | ||
|
|
3bd15a53d6 | ||
|
|
f0a888c0d1 | ||
|
|
b6769356b2 | ||
|
|
5a9cafc2fc | ||
|
|
2e36590bbd | ||
|
|
33e504b928 | ||
|
|
6a4f197cc0 | ||
|
|
4894580e8b | ||
|
|
70997fb4c5 | ||
|
|
e9515971ea | ||
|
|
82dfa002ff | ||
|
|
a664fd7192 | ||
|
|
b62ee0ef6d | ||
|
|
0cfd867816 | ||
|
|
934a4db7d5 | ||
|
|
c9fe9afa61 | ||
|
|
320e91653b | ||
|
|
859d215ca4 | ||
|
|
0a94f3f303 | ||
|
|
e83a26b256 | ||
|
|
2508495b8c | ||
|
|
3ef52d9324 | ||
|
|
05b72281e6 | ||
|
|
a47abfdc16 | ||
|
|
2c9265f8c8 | ||
|
|
56cb6f8613 | ||
|
|
3dd56ed8af | ||
|
|
fddeeb683c | ||
|
|
25835b0edf | ||
|
|
27fcfada66 | ||
|
|
2dd5fb0f77 | ||
|
|
63044a4b81 | ||
|
|
4e74f9783a | ||
|
|
c3c662fe64 | ||
|
|
7c2764790c | ||
|
|
732d500cf5 | ||
|
|
4e1ac726ac | ||
|
|
fba58085c6 | ||
|
|
d1ebb255c6 | ||
|
|
a39ee0b44d | ||
|
|
947d91acd5 | ||
|
|
8c206d52e5 | ||
|
|
0f445dc9f4 | ||
|
|
c71b35e61a | ||
|
|
d20308b7d7 | ||
|
|
e4e54a88d9 | ||
|
|
308b7c5197 | ||
|
|
89772bf6c0 | ||
|
|
077002e647 | ||
|
|
988cdf9878 | ||
|
|
97db2078f5 | ||
|
|
02a110e6c2 | ||
|
|
681ef8de6f | ||
|
|
0147e0e64f | ||
|
|
311c6be9aa | ||
|
|
c22d123ab0 | ||
|
|
96b5991355 | ||
|
|
06bd352863 | ||
|
|
a918f7497a | ||
|
|
8bbae3d414 | ||
|
|
bfd1f36fdd | ||
|
|
6fc702a560 | ||
|
|
40dcc5541b | ||
|
|
5b41c6e327 | ||
|
|
4bd81b4d4c | ||
|
|
c29589c2ca | ||
|
|
73b89430e4 | ||
|
|
2a62fa3d85 | ||
|
|
4542fdb5bb | ||
|
|
525aaf1f66 | ||
|
|
910dac5f3a | ||
|
|
2a5c319084 | ||
|
|
612f4fe288 | ||
|
|
c058c05651 | ||
|
|
0de4578e50 | ||
|
|
b9e94e4695 | ||
|
|
9887003b25 | ||
|
|
f6bfbc86e9 | ||
|
|
4c90b51d80 | ||
|
|
48cfbfe5ed | ||
|
|
f98be8540f | ||
|
|
17c69fef3d | ||
|
|
c586204fc1 | ||
|
|
ff5e3219be | ||
|
|
07c52f1566 | ||
|
|
0e04ffd68f | ||
|
|
8b5435908c | ||
|
|
3a74310aa6 | ||
|
|
180859a429 | ||
|
|
1d92819d92 | ||
|
|
cfa871c548 | ||
|
|
685e0a80a4 | ||
|
|
19847d2997 | ||
|
|
7108b0e789 | ||
|
|
7eac0b0341 | ||
|
|
33ec4e7d19 | ||
|
|
1b78f2b364 | ||
|
|
119363ff75 | ||
|
|
f89b508c01 | ||
|
|
dda8c7c3ac | ||
|
|
e2d9aab70d | ||
|
|
3df154b798 | ||
|
|
3d9cbaf040 | ||
|
|
70c2939596 | ||
|
|
d4ee44e27f | ||
|
|
0498326962 | ||
|
|
c84ababbd4 | ||
|
|
67ea42c87b | ||
|
|
a2ab45cad7 | ||
|
|
f3fcca6150 | ||
|
|
2b65d8f1e9 | ||
|
|
7c2abf69c4 | ||
|
|
457c0a246f | ||
|
|
1a439baf68 | ||
|
|
68ce78b3fe | ||
|
|
72e27e99e5 | ||
|
|
a436382886 | ||
|
|
6bbfc7b1f1 | ||
|
|
006dd12b09 | ||
|
|
d3a0631390 | ||
|
|
9046b6fe2b | ||
|
|
f217794773 | ||
|
|
11e02fabb3 | ||
|
|
8b9bb1c7ce | ||
|
|
2a7abf1db0 | ||
|
|
34b8c5a3ba | ||
|
|
8e056422fc | ||
|
|
94e8b185b4 | ||
|
|
996d3960e1 | ||
|
|
3b19734f63 | ||
|
|
64e7c0cd9e | ||
|
|
4d0c88bd7a | ||
|
|
9e8c601507 | ||
|
|
b26104466a | ||
|
|
bd25bf65ce | ||
|
|
edd3b41adf | ||
|
|
28ca3fcc5c | ||
|
|
3b601d0115 | ||
|
|
1ef9a9f128 | ||
|
|
d612a86c3b | ||
|
|
5d3cd05202 | ||
|
|
726f7ba229 | ||
|
|
61dab8bd75 | ||
|
|
a7e81f45c6 | ||
|
|
be4062f019 | ||
|
|
035f06e137 | ||
|
|
2f91ab5eac | ||
|
|
f6b5b0260b | ||
|
|
bb9bd7e0b0 | ||
|
|
287abd5c7c | ||
|
|
d27f114742 | ||
|
|
505c370898 | ||
|
|
f26009ec3e | ||
|
|
8425bc313b | ||
|
|
f4d3cf2835 | ||
|
|
bd5cf7c9eb | ||
|
|
4709394ae6 | ||
|
|
729002ef82 | ||
|
|
58b075dbf2 | ||
|
|
d679840fa3 | ||
|
|
0e70bdbf6a | ||
|
|
d810ac00bc | ||
|
|
5f74adad06 | ||
|
|
585ac51f45 | ||
|
|
ce36797506 | ||
|
|
a61c2ceb79 | ||
|
|
383339dc4a | ||
|
|
36b46ba134 | ||
|
|
a2d0859bf1 | ||
|
|
d5f542dcca | ||
|
|
fb86042cb3 | ||
|
|
359fb8530e | ||
|
|
5dd1a676ac | ||
|
|
278994781b | ||
|
|
c9f1bff419 | ||
|
|
1f9621cf4b | ||
|
|
9458e4e66b | ||
|
|
ff08038bdc | ||
|
|
ce330e8bf1 | ||
|
|
47d837bf6a | ||
|
|
912a281ee2 | ||
|
|
6e863a7872 | ||
|
|
488e6c2adf | ||
|
|
e177b866a9 | ||
|
|
15dcebd0f1 | ||
|
|
af60d8d3ec | ||
|
|
5a32fdb309 | ||
|
|
19f5cb1d01 | ||
|
|
c5bca5f80a | ||
|
|
d22dea74e3 | ||
|
|
dc547317c9 | ||
|
|
6bf5d98569 | ||
|
|
29dea38f50 | ||
|
|
34567dd244 | ||
|
|
a3584c6ca3 | ||
|
|
165d0633f6 | ||
|
|
9f7ba1ba79 | ||
|
|
03c08d3970 | ||
|
|
37e3be9a0d | ||
|
|
10437887fc | ||
|
|
faf1c6233d | ||
|
|
c36960350c | ||
|
|
51ade57723 | ||
|
|
9d79673cea | ||
|
|
762bf5f031 | ||
|
|
abcb3ceb67 | ||
|
|
0ae5071f94 | ||
|
|
e589c5b269 | ||
|
|
12e341fe73 | ||
|
|
9be3c4cb9a | ||
|
|
433f3ce17e | ||
|
|
2c29ede0da | ||
|
|
7cfbca6d74 | ||
|
|
b30621bb3b | ||
|
|
d6f35903d6 | ||
|
|
a61a8015d7 | ||
|
|
e2f070649d | ||
|
|
f08d375c36 | ||
|
|
1c4bad5b73 | ||
|
|
6c874895dc | ||
|
|
ef1a05425d | ||
|
|
fc3bad2160 | ||
|
|
31ac933d64 | ||
|
|
caa398816d | ||
|
|
0d57a507f3 | ||
|
|
96257cc5c7 | ||
|
|
fbcd7d2384 | ||
|
|
d9dbfa23c7 | ||
|
|
91f077bd08 | ||
|
|
5fb4a6ae8f | ||
|
|
e84333662e | ||
|
|
ddb42fda70 | ||
|
|
621eb21b42 | ||
|
|
6cc44a87c9 | ||
|
|
5f908cae49 | ||
|
|
6de67ed107 | ||
|
|
c129f06195 | ||
|
|
d11dc63bc2 | ||
|
|
d904ec1602 | ||
|
|
2a98b2f055 | ||
|
|
6286ede985 | ||
|
|
4a8ca787d3 | ||
|
|
561c88a868 | ||
|
|
f8dfcdf024 | ||
|
|
f50b5a4ac6 | ||
|
|
59525b80e3 | ||
|
|
0ce028add1 | ||
|
|
75c5c85f07 | ||
|
|
ccb84ced2e | ||
|
|
5ef669fb6c | ||
|
|
96ff9c115c | ||
|
|
83aa6abb1c | ||
|
|
9304024841 | ||
|
|
0de5981948 | ||
|
|
c39106906d | ||
|
|
929a6e7aac | ||
|
|
ceb4d04d23 | ||
|
|
f483a8aeaa | ||
|
|
e3e220ce8e | ||
|
|
fc653e4293 | ||
|
|
94d55cb7dd | ||
|
|
0e84ecf143 | ||
|
|
0e93dfd640 | ||
|
|
4dff8237f1 | ||
|
|
35400f2a8b | ||
|
|
9a76f0862c | ||
|
|
fb8a7caa99 | ||
|
|
f8bed5c7af | ||
|
|
da6fa482e7 | ||
|
|
fdf8e48c99 | ||
|
|
195155a7f5 | ||
|
|
6934ba4dbc | ||
|
|
fdbd25c1b5 | ||
|
|
467f1cca81 | ||
|
|
d6fdf4a806 | ||
|
|
4be9d97e61 | ||
|
|
021d011493 | ||
|
|
e988d38f71 | ||
|
|
8690fc732b |
@@ -9,9 +9,9 @@ For email questions/requests/alerts there is always the risk of memory
|
|||||||
exhaustion on the part of the maintainer(s).
|
exhaustion on the part of the maintainer(s).
|
||||||
|
|
||||||
If you are unsure of what to do, or how to implement an idea or bugfix,
|
If you are unsure of what to do, or how to implement an idea or bugfix,
|
||||||
open an issue with `"[RFC: Unsure if this is a bug ... ?"`, or similar,
|
open an issue with `"[RFC: Unsure if this is a bug ... ?"`, or use the
|
||||||
so we can discuss it. Talking about the code first is the best way to
|
GitHub discussions forum, so we can discuss it. Talking about the code
|
||||||
get started before submitting a pull request.
|
first is the best way to get started before submitting a pull request.
|
||||||
|
|
||||||
Either way, when sending an email, patch, or pull request, start by
|
Either way, when sending an email, patch, or pull request, start by
|
||||||
stating the version the change is made against, what it does, and why.
|
stating the version the change is made against, what it does, and why.
|
||||||
@@ -24,7 +24,8 @@ the maintainer(s) and make it easier for them to include your code.
|
|||||||
Coding Style
|
Coding Style
|
||||||
------------
|
------------
|
||||||
|
|
||||||
> **Tip:** Always submit code that follows the style of surrounding code!
|
> [!TIP]
|
||||||
|
> Always submit code that follows the style of surrounding code!
|
||||||
|
|
||||||
First of all, lines are allowed to be longer than 72 characters these
|
First of all, lines are allowed to be longer than 72 characters these
|
||||||
days. In fact, there exist no enforced maximum, but keeping it around
|
days. In fact, there exist no enforced maximum, but keeping it around
|
||||||
@@ -73,7 +74,6 @@ It is expected of everyone engaging in the project to, in the words of
|
|||||||
Bill & Ted; [be excellent to each other][conduct].
|
Bill & Ted; [be excellent to each other][conduct].
|
||||||
|
|
||||||
|
|
||||||
[github]: https://github.com/troglobit/finit/
|
|
||||||
[KNF]: https://en.wikipedia.org/wiki/Kernel_Normal_Form
|
[KNF]: https://en.wikipedia.org/wiki/Kernel_Normal_Form
|
||||||
[gitbook]: https://git-scm.com/book/ch5-2.html
|
[gitbook]: https://git-scm.com/book/ch5-2.html
|
||||||
[conduct]: CODE-OF-CONDUCT.md
|
[conduct]: CODE-OF-CONDUCT.md
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
finit is a small project, as such we have no possibility to support older versions.
|
finit is a small project, as such we have no possibility to support older versions.
|
||||||
The only supported version is the latest released on GitHub:
|
The only supported version is the latest released on GitHub:
|
||||||
|
|
||||||
<https://github.com/troglobit/finit/releases>
|
<https://github.com/finit-project/finit/releases>
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
|||||||
@@ -8,63 +8,80 @@ on:
|
|||||||
- '**'
|
- '**'
|
||||||
- '!dev'
|
- '!dev'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
types: [opened, synchronize, reopened, labeled]
|
||||||
- '**'
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
# Verify we can build on latest Ubuntu with both gcc and clang
|
# Verify we can build on latest Ubuntu with both gcc and clang
|
||||||
name: ${{ matrix.compiler }}
|
name: ${{ matrix.compiler }}
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-latest
|
||||||
|
# Skip redundant builds for PRs - prefer PR builds over push builds
|
||||||
|
if: github.event_name != 'push' || github.ref == 'refs/heads/master'
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
compiler: [gcc, clang]
|
compiler: [gcc, clang]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
env:
|
env:
|
||||||
MAKEFLAGS: -j3
|
|
||||||
CC: ${{ matrix.compiler }}
|
CC: ${{ matrix.compiler }}
|
||||||
steps:
|
steps:
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -y update
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install pkg-config tree jq libcap-dev
|
||||||
sudo apt-get -y install pkg-config
|
sudo apt-get -y install pkg-config
|
||||||
wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
|
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
|
||||||
wget https://github.com/troglobit/libite/releases/download/v2.5.2/libite-2.5.2.tar.gz
|
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
|
||||||
tar xf libuev-2.3.2.tar.xz
|
tar xf libuev-2.4.1.tar.xz
|
||||||
tar xf libite-2.5.2.tar.gz
|
tar xf libite-2.6.2.tar.gz
|
||||||
(cd libuev-2.3.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
|
||||||
(cd libite-2.5.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Static Finit
|
- name: Static Finit
|
||||||
run: |
|
run: |
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
./configure --prefix= --enable-static
|
./configure --prefix= --enable-static
|
||||||
make V=1
|
make -j9 V=1
|
||||||
- name: Regular Finit
|
- name: Regular Finit
|
||||||
run: |
|
run: |
|
||||||
./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
|
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var \
|
||||||
make clean
|
--enable-x11-common-plugin --enable-testserv-plugin --with-watchdog \
|
||||||
make V=1
|
--with-keventd --with-libsystemd \
|
||||||
- name: Install to ~/tmp and Inspect
|
CFLAGS="-fsanitize=address -ggdb"
|
||||||
|
make -j9 clean
|
||||||
|
make -j9 V=1
|
||||||
|
- name: Install to /tmp
|
||||||
run: |
|
run: |
|
||||||
DESTDIR=/tmp make install-strip
|
DESTDIR=/tmp make install-strip
|
||||||
tree /tmp
|
tree /tmp || true
|
||||||
|
- name: Check dependencies
|
||||||
|
run: |
|
||||||
ldd /tmp/sbin/finit
|
ldd /tmp/sbin/finit
|
||||||
size /tmp/sbin/finit
|
size /tmp/sbin/finit
|
||||||
ldd /tmp/sbin/initctl
|
ldd /tmp/sbin/initctl
|
||||||
size /tmp/sbin/initctl
|
size /tmp/sbin/initctl
|
||||||
ldd /tmp/sbin/reboot
|
ldd /tmp/sbin/reboot
|
||||||
size /tmp/sbin/reboot
|
size /tmp/sbin/reboot
|
||||||
/tmp/sbin/finit -h
|
- name: Verify starting and showing usage text
|
||||||
/tmp/sbin/initctl -h
|
run: |
|
||||||
|
sudo /tmp/sbin/finit -h
|
||||||
|
sudo /tmp/sbin/initctl -h
|
||||||
|
- name: Enable unprivileged userns (unshare)
|
||||||
|
run: |
|
||||||
|
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
|
||||||
- name: Run Unit Tests
|
- name: Run Unit Tests
|
||||||
run: |
|
run: |
|
||||||
ver=$(/tmp/sbin/initctl -V | awk '/Finit.*/ {print $2;}')
|
make -j1 check || (cat test/test-suite.log; false)
|
||||||
dir=finit-$ver/_build/sub
|
|
||||||
make -j1 distcheck || (cat $dir/test/setup-root.log; cat $dir/test/test-suite.log; false)
|
|
||||||
- name: Upload Test Results
|
- name: Upload Test Results
|
||||||
uses: actions/upload-artifact@v2
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: finit-test-${{ matrix.compiler }}
|
name: finit-test-${{ matrix.compiler }}
|
||||||
path: test/*
|
path: test/*.log
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'dev'
|
- 'dev'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PROJECT_NAME: finit
|
PROJECT_NAME: finit
|
||||||
@@ -15,40 +19,60 @@ jobs:
|
|||||||
coverity:
|
coverity:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v2
|
- name: Fetch latest Coverity Scan MD5
|
||||||
id: coverity-toolchain-cache
|
id: var
|
||||||
with:
|
|
||||||
path: cov-analysis-linux64
|
|
||||||
key: ${{ runner.os }}-coverity
|
|
||||||
- name: Download Coverity Scan
|
|
||||||
if: steps.coverity-toolchain-cache.outputs.cache-hit != 'true'
|
|
||||||
env:
|
env:
|
||||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
wget -q https://scan.coverity.com/download/cxx/linux64 \
|
wget -q https://scan.coverity.com/download/cxx/linux64 \
|
||||||
--post-data "token=$TOKEN&project=${COVERITY_PROJ}" \
|
--post-data "token=$TOKEN&project=${COVERITY_PROJ}&md5=1" \
|
||||||
-O cov-analysis-linux64.tar.gz
|
-O coverity-latest.tar.gz.md5
|
||||||
mkdir cov-analysis-linux64
|
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
|
||||||
tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64
|
- uses: actions/cache@v4
|
||||||
|
id: cache
|
||||||
|
with:
|
||||||
|
path: coverity-latest.tar.gz
|
||||||
|
key: ${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-coverity-${{ steps.var.outputs.md5 }}
|
||||||
|
${{ runner.os }}-coverity-
|
||||||
|
${{ runner.os }}-coverity
|
||||||
|
- name: Download Coverity Scan
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||||
|
run: |
|
||||||
|
if [ ! -f coverity-latest.tar.gz ]; then
|
||||||
|
wget -q https://scan.coverity.com/download/cxx/linux64 \
|
||||||
|
--post-data "token=$TOKEN&project=${COVERITY_PROJ}" \
|
||||||
|
-O coverity-latest.tar.gz
|
||||||
|
else
|
||||||
|
echo "Latest Coverity Scan available from cache :-)"
|
||||||
|
md5sum coverity-latest.tar.gz
|
||||||
|
fi
|
||||||
|
mkdir coverity
|
||||||
|
tar xzf coverity-latest.tar.gz --strip 1 -C coverity
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -y update
|
sudo apt-get -y update
|
||||||
sudo apt-get -y install pkg-config
|
sudo apt-get -y install pkg-config libcap-dev
|
||||||
wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
|
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
|
||||||
wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz
|
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
|
||||||
tar xf libuev-2.3.2.tar.xz
|
tar xf libuev-2.4.1.tar.xz
|
||||||
tar xf libite-2.3.1.tar.gz
|
tar xf libite-2.6.2.tar.gz
|
||||||
(cd libuev-2.3.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
|
||||||
(cd libite-2.3.1 && ./configure --prefix=/usr && make && sudo make install-strip)
|
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
- name: Build
|
- name: Configure
|
||||||
run: |
|
run: |
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
|
./configure --prefix= --enable-x11-common-plugin --with-watchdog \
|
||||||
export PATH=`pwd`/cov-analysis-linux64/bin:$PATH
|
--with-keventd --with-libsystemd
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
export PATH=`pwd`/coverity/bin:$PATH
|
||||||
cov-build --dir cov-int make
|
cov-build --dir cov-int make
|
||||||
- name: Submit result to Coverity Scan
|
- name: Submit results to Coverity Scan
|
||||||
env:
|
env:
|
||||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
@@ -61,3 +85,8 @@ jobs:
|
|||||||
--form version=trunk \
|
--form version=trunk \
|
||||||
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
|
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
|
||||||
https://scan.coverity.com/builds?project=${COVERITY_PROJ}
|
https://scan.coverity.com/builds?project=${COVERITY_PROJ}
|
||||||
|
- name: Upload build.log
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: coverity-build.log
|
||||||
|
path: cov-int/build-log.txt
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
name: Dotty the Documenteer
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- 'doc/**'
|
||||||
|
- 'README.md'
|
||||||
|
- 'mkdocs.yml'
|
||||||
|
- '.github/workflows/docs.yml'
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened, labeled]
|
||||||
|
paths:
|
||||||
|
- 'doc/**'
|
||||||
|
- 'README.md'
|
||||||
|
- 'mkdocs.yml'
|
||||||
|
- '.github/workflows/docs.yml'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Needed for git-revision-date-localized plugin
|
||||||
|
|
||||||
|
- name: Setup Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.x'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pipx install mkdocs
|
||||||
|
pipx inject mkdocs mkdocs-material
|
||||||
|
pipx inject mkdocs pymdown-extensions
|
||||||
|
pipx inject mkdocs mkdocs-callouts
|
||||||
|
pipx inject mkdocs mkdocs-glightbox
|
||||||
|
|
||||||
|
- name: Build documentation
|
||||||
|
run: mkdocs build --clean
|
||||||
|
|
||||||
|
- name: Upload site artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: site
|
||||||
|
path: site/
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download site artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: site
|
||||||
|
path: site/
|
||||||
|
|
||||||
|
- name: Checkout pages repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: finit-project/finit-project.github.io
|
||||||
|
path: pages
|
||||||
|
ssh-key: ${{ secrets.DOCS_DEPLOY_KEY }}
|
||||||
|
persist-credentials: true
|
||||||
|
|
||||||
|
- name: Setup SSH for push
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
chmod 700 ~/.ssh
|
||||||
|
ssh-keyscan github.com >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
- name: Sync site to pages repo
|
||||||
|
run: |
|
||||||
|
rsync -a --delete --exclude .git site/ pages/
|
||||||
|
|
||||||
|
- name: Commit and push
|
||||||
|
run: |
|
||||||
|
cd pages/
|
||||||
|
if [ -z "$(git status --porcelain)" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
SRC_REPO="${GITHUB_REPOSITORY}"
|
||||||
|
SRC_REF="${GITHUB_SHA::7}"
|
||||||
|
SRC_URL="https://github.com/${SRC_REPO}/commit/${SRC_REF}"
|
||||||
|
|
||||||
|
git config user.name "GitHub Actions"
|
||||||
|
git config user.email "actions@github.com"
|
||||||
|
git add -A
|
||||||
|
git commit -m "docs: update from ${SRC_REPO}@${SRC_REF}" \
|
||||||
|
-m "For details, see ${SRC_URL}"
|
||||||
|
git push
|
||||||
@@ -5,65 +5,78 @@ on:
|
|||||||
tags:
|
tags:
|
||||||
- '[0-9]+.[0-9]+*'
|
- '[0-9]+.[0-9]+*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
name: Create GitHub release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
outputs:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
release_id: ${{ steps.create_release.outputs.id }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Extract ChangeLog entry ...
|
|
||||||
# Hack to extract latest entry for body_path below
|
|
||||||
run: |
|
|
||||||
awk '/-----*/{if (x == 1) exit; x=1;next}x' ChangeLog.md \
|
|
||||||
|head -n -1 > release.md
|
|
||||||
cat release.md
|
|
||||||
- name: Create release ...
|
|
||||||
id: create_release
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
tag_name: ${{ github.ref }}
|
|
||||||
release_name: Finit v${{ github.ref }}
|
|
||||||
body_path: release.md
|
|
||||||
draft: false
|
|
||||||
prerelease: false
|
|
||||||
tarball:
|
|
||||||
name: Build and upload release tarball
|
name: Build and upload release tarball
|
||||||
needs: release
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Installing dependencies
|
- name: Installing dependencies ...
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -y update
|
sudo apt-get -y update
|
||||||
sudo apt-get -y install pkg-config
|
sudo apt-get -y install pkg-config jq libcap-dev
|
||||||
wget https://github.com/troglobit/libuev/releases/download/v2.3.2/libuev-2.3.2.tar.xz
|
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
|
||||||
wget https://github.com/troglobit/libite/releases/download/v2.3.1/libite-2.3.1.tar.gz
|
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
|
||||||
tar xf libuev-2.3.2.tar.xz
|
tar xf libuev-2.4.1.tar.xz
|
||||||
tar xf libite-2.3.1.tar.gz
|
tar xf libite-2.6.2.tar.gz
|
||||||
(cd libuev-2.3.2 && ./configure --prefix=/usr && make && sudo make install-strip)
|
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
|
||||||
(cd libite-2.3.1 && ./configure --prefix=/usr && make && sudo make install-strip)
|
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
|
||||||
sudo ldconfig
|
sudo ldconfig
|
||||||
- name: Creating Makefiles
|
- name: Setting release variables ...
|
||||||
|
id: build
|
||||||
|
run: |
|
||||||
|
ver=${GITHUB_REF#refs/tags/}
|
||||||
|
echo "ver=${ver}" >> $GITHUB_OUTPUT
|
||||||
|
if echo $ver | grep -qE '^[0-9]+\.[0-9]+(\.[0-9]+)?(-alpha|-beta|-rc)[0-9]*$'; then
|
||||||
|
echo "pre=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "pre=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
if echo $ver | grep -qE '^[0-9.]+\.[0-9.]+(\.[0-9]+)?$'; then
|
||||||
|
echo "latest=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "latest=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
- name: Creating Makefiles ...
|
||||||
run: |
|
run: |
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
./configure --prefix= --enable-x11-common-plugin --with-watchdog --with-keventd
|
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc \
|
||||||
- name: Building release
|
--localstatedir=/var --enable-x11-common-plugin \
|
||||||
|
--enable-testserv-plugin --with-watchdog \
|
||||||
|
--with-keventd --with-libsystemd
|
||||||
|
- name: Enable unprivileged userns (unshare)
|
||||||
run: |
|
run: |
|
||||||
make release
|
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
|
||||||
|
- name: Build release ...
|
||||||
|
run: |
|
||||||
|
# Get version for finding distcheck build directory
|
||||||
|
./configure --version | head -1
|
||||||
|
ver=$(./configure --version | head -1 | awk '{print $NF}')
|
||||||
|
dir=finit-$ver/_build/sub
|
||||||
|
|
||||||
|
make -j1 release || (cat $dir/test/test-suite.log; false)
|
||||||
ls -lF ../
|
ls -lF ../
|
||||||
mkdir -p artifacts/
|
mkdir -p artifacts/
|
||||||
mv ../*.tar.* artifacts/
|
mv ../*.tar.* artifacts/
|
||||||
- name: Uploading release artifacts
|
- name: Upload Test Results
|
||||||
uses: skx/github-action-publish-binaries@release-0.15
|
if: always()
|
||||||
env:
|
uses: actions/upload-artifact@v4
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
with:
|
||||||
releaseId: ${{ needs.release.outputs.release_id }}
|
name: finit-release-test-logs
|
||||||
args: artifacts/*
|
path: finit-*/_build/sub/test/*.log
|
||||||
|
- name: Extract ChangeLog entry ...
|
||||||
|
run: |
|
||||||
|
awk '/-----*/{if (x == 1) exit; x=1;next}x' doc/ChangeLog.md \
|
||||||
|
|head -n -1 > release.md
|
||||||
|
cat release.md
|
||||||
|
- uses: ncipollo/release-action@v1
|
||||||
|
with:
|
||||||
|
name: Finit v${{ github.ref_name }}
|
||||||
|
prerelease: ${{ steps.build.outputs.pre }}
|
||||||
|
makeLatest: ${{ steps.build.outputs.latest }}
|
||||||
|
bodyFile: "release.md"
|
||||||
|
artifacts: "artifacts/*"
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
name: Weekly Distcheck
|
||||||
|
|
||||||
|
# Verify that `make distcheck` works as intended: all tests pass, and
|
||||||
|
# any new files are distributed in the tarballs
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * 0'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
schedule:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
run: ${{ steps.schedule.outputs.run }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Check for any commits since last week
|
||||||
|
id: schedule
|
||||||
|
run: |
|
||||||
|
commits="$(git log --format=%H --since='1 week ago')"
|
||||||
|
if [ -z "$commits" ]; then
|
||||||
|
echo "run=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "run=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
distcheck:
|
||||||
|
needs: schedule
|
||||||
|
if: ${{ needs.schedule.outputs.run == 'true' }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get -y update
|
||||||
|
sudo apt-get -y install pkg-config jq libcap-dev
|
||||||
|
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
|
||||||
|
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
|
||||||
|
tar xf libuev-2.4.1.tar.xz
|
||||||
|
tar xf libite-2.6.2.tar.gz
|
||||||
|
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
|
||||||
|
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
|
||||||
|
sudo ldconfig
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Base run
|
||||||
|
run: |
|
||||||
|
./autogen.sh
|
||||||
|
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var
|
||||||
|
make -j9 V=1
|
||||||
|
- name: Install to /tmp
|
||||||
|
run: |
|
||||||
|
DESTDIR=/tmp make install-strip
|
||||||
|
- name: Enable unprivileged userns (unshare)
|
||||||
|
run: |
|
||||||
|
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
|
||||||
|
- name: Check dist tarball
|
||||||
|
run: |
|
||||||
|
ver=$(/tmp/sbin/initctl -V | awk '/Finit.*/ {print $2;}')
|
||||||
|
dir=finit-$ver/_build/sub
|
||||||
|
make -j1 distcheck || (cat $dir/test/test-suite.log; false)
|
||||||
|
- name: Upload Test Results
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: finit-weekly-test-logs
|
||||||
|
path: finit-*/_build/sub/test/*.log
|
||||||
@@ -14,6 +14,7 @@ GTAGS
|
|||||||
/autom4te.cache
|
/autom4te.cache
|
||||||
/aclocal.m4
|
/aclocal.m4
|
||||||
/ar-lib
|
/ar-lib
|
||||||
|
/backup/
|
||||||
/compile
|
/compile
|
||||||
/config.cache
|
/config.cache
|
||||||
/config.h
|
/config.h
|
||||||
@@ -36,6 +37,9 @@ GTAGS
|
|||||||
/test-driver
|
/test-driver
|
||||||
/test-suite.log
|
/test-suite.log
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
/.gdb_history
|
||||||
|
|
||||||
# TroglOS build system
|
# TroglOS build system
|
||||||
/.config
|
/.config
|
||||||
/.stamp
|
/.stamp
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# GNU Global .conf file, see /etc/gtags/gtags.conf for details.
|
||||||
|
# This configuration is optimized for the Finit project structure.
|
||||||
|
|
||||||
|
default:\
|
||||||
|
:tc=default@/etc/gtags/gtags.conf:\
|
||||||
|
:tc=common:
|
||||||
|
|
||||||
|
common:\
|
||||||
|
:skip=tags,TAGS,ID,y.tab.c,y.tab.h,gtags.files,cscope.files,cscope.out,cscope.po.out,cscope.in.out,\
|
||||||
|
{arch}/,autom4te.cache/,\
|
||||||
|
*.orig,*.rej,*.bak,*~,#*#,*.swp,*.tmp,*_flymake.*,*_flymake,\
|
||||||
|
*.o,*.a,*.so,*.lo,*.la,\
|
||||||
|
*.zip,*.gz,*.bz2,*.xz,*.lzh,*.Z,*.tgz,\
|
||||||
|
*.log,*.trs,test-suite.log,stamp-*,\
|
||||||
|
sysroot/:
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
Copyright (c) 2008-2022 Joachim Wiberg <troglobit@gmail.com>
|
Copyright (c) 2008-2025 Joachim Wiberg <troglobit@gmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
SUBDIRS = man plugins src test
|
SUBDIRS = man plugins src system tmpfiles.d
|
||||||
doc_DATA = README.md LICENSE contrib/finit.conf
|
dist_doc_DATA = README.md LICENSE contrib/finit.conf
|
||||||
EXTRA_DIST = README.md LICENSE ChangeLog.md contrib/finit.conf
|
|
||||||
|
|
||||||
if CONTRIB
|
if CONTRIB
|
||||||
SUBDIRS += contrib
|
SUBDIRS += contrib
|
||||||
@@ -9,6 +8,17 @@ endif
|
|||||||
if DOC
|
if DOC
|
||||||
SUBDIRS += doc
|
SUBDIRS += doc
|
||||||
endif
|
endif
|
||||||
|
if LIBSYSTEMD
|
||||||
|
SUBDIRS += libsystemd
|
||||||
|
endif
|
||||||
|
|
||||||
|
if LIBSYSTEMD
|
||||||
|
SUBDIRS += test
|
||||||
|
# Explicit dependency to ensure libsystemd is built before test
|
||||||
|
test: libsystemd
|
||||||
|
else
|
||||||
|
SUBDIRS += test
|
||||||
|
endif
|
||||||
|
|
||||||
# Compat hook
|
# Compat hook
|
||||||
install-dev:
|
install-dev:
|
||||||
@@ -30,4 +40,7 @@ release: distcheck
|
|||||||
printf "$$file.sha256\t"; cat ../$$file.sha256 | cut -f1 -d' '; \
|
printf "$$file.sha256\t"; cat ../$$file.sha256 | cut -f1 -d' '; \
|
||||||
done
|
done
|
||||||
|
|
||||||
DISTCHECK_CONFIGURE_FLAGS = --with-fstab=/etc/fstab
|
DISTCHECK_CONFIGURE_FLAGS = --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
|
||||||
|
--enable-testserv-plugin --enable-x11-common-plugin \
|
||||||
|
--with-watchdog --with-keventd --with-fstab=/etc/fstab \
|
||||||
|
--with-libsystemd --with-bash-completion-dir=no
|
||||||
|
|||||||
@@ -1,610 +1,50 @@
|
|||||||
[![License Badge][]][License] [![GitHub Status][]][GitHub] [![Coverity Status][]][Coverity Scan]
|
[![License Badge][]][License] [![Release Badge][]][Release] [![GitHub Status][]][GitHub] [![Coverity Status][]][Coverity Scan]
|
||||||
<img align="right" src="img/finit3.png" alt="Finit: Fast Init">
|
<img align="right" src="doc/img/finit3.png" alt="Finit: Fast Init">
|
||||||
|
|
||||||
* [Introduction](#introduction)
|
Finit is a fast, simple alternative to [SysV init](https://en.wikipedia.org/wiki/Init)
|
||||||
* [Features](#features)
|
and [systemd](https://systemd.io), designed for small and embedded Linux systems.
|
||||||
* [Bootstrap](doc/bootstrap.md#bootstrap)
|
It can also run on desktop and server systems, like [finix][].
|
||||||
* [Runlevels](#runlevels)
|
|
||||||
* [Syntax](doc/config.md#syntax)
|
> Reverse engineered from the [EeePC fastinit][]
|
||||||
* [Runparts & /etc/rc.local](#runparts--etcrclocal)
|
> "gaps filled with frog DNA …"
|
||||||
* [Hooks, Callbacks & Plugins](doc/plugins.md#hooks-callbacks--plugins)
|
> — [Claudio Matsuoka][]
|
||||||
* [Rebooting & Halting](#rebooting--halting)
|
|
||||||
* [Commands & Status](#commands--status)
|
For detailed information, explore our extensive documentation
|
||||||
* [Tips & Tricks with the kernel cmdline](doc/cmdline.md)
|
:books: **<http://finit-project.github.io>**
|
||||||
* [Building](doc/build.md#building)
|
|
||||||
* [Running](doc/build.md#running)
|
<div align="center">
|
||||||
* [Recovery](doc/build.md#recovery)
|
<img src="doc/img/alpine-screenshot2.png" alt="Alpine screenshot"><br/>
|
||||||
* [Debugging](doc/build.md#debugging)
|
</div>
|
||||||
* [Requirements](#requirements)
|
|
||||||
* [Origin & References](#origin--references)
|
For working examples, see the :rocket: [contrib/](contrib/) section or these
|
||||||
|
tutorials:
|
||||||
|
|
||||||
Introduction
|
* :hammer_and_wrench: [Buildroot embedded Linux][br2demo],
|
||||||
------------
|
* :package: [Debian GNU/Linux](contrib/debian/),
|
||||||
|
* :mountain: [Alpine Linux](contrib/alpine/), and
|
||||||
Fast init for Linux systems. Reverse engineered from the [EeePC
|
* :milky_way: [Void Linux](contrib/void/)
|
||||||
fastinit][] over ten years ago by [Claudio Matsuoka][] — "gaps filled
|
|
||||||
with frog DNA …"
|
> [!NOTE]
|
||||||
|
> Finit can run on various Linux distributions, but the bundled install
|
||||||

|
> scripts are examples only. They have been tested on amd64 (x86_64) systems
|
||||||
*Figure 1: Screenshot showing Finit booting [Alpine Linux](https://www.alpinelinux.org/).*
|
> with standard configurations.
|
||||||
|
>
|
||||||
Features include:
|
> For embedded systems, see these [Buildroot][]-based examples:
|
||||||
|
> [myLinux][], [Infix][], or [br2-finit-demo][].
|
||||||
* Runlevels, defined per service
|
|
||||||
* One-shot tasks, services (daemons), or [SysV init][4] start/stop scripts
|
[finix]: https://github.com/finix-community/finix
|
||||||
* Runparts and `/etc/rc.local` support
|
[Buildroot]: https://buildroot.org
|
||||||
* Process supervision similar to [systemd][]
|
[Infix]: https://kernelkit.github.io
|
||||||
* Sourcing environment files
|
[myLinux]: https://github.com/troglobit/myLinux/
|
||||||
* Conditions for network/process/custom dependencies
|
[br2demo]: https://troglobit.com/post/2022-12-26-buildroot-demo-of-fastinit-finit/
|
||||||
* Pre/Post script actions
|
|
||||||
* Tooling to enable/disable services
|
|
||||||
* Built-in getty
|
|
||||||
* Built-in watchdog, with support for hand-over to [watchdogd](https://troglobit.com/watchdogd.html)
|
|
||||||
* Built-in support for Debian/BusyBox `/etc/network/interfaces`
|
|
||||||
* Cgroups v2, both configuration and monitoring in `initctl top`
|
|
||||||
* Plugin support for customization
|
|
||||||
* Proper rescue mode with bundled `sulogin` for protected maintenance shell
|
|
||||||
|
|
||||||
Focus is on small and embedded systems, although Finit is fully usable
|
|
||||||
on server and desktop systems as well. For working examples, see the
|
|
||||||
[contrib/](contrib/) section with tutorials for:
|
|
||||||
|
|
||||||
* [Void Linux](contrib/void/),
|
|
||||||
* [Alpine Linux](contrib/alpine/), and
|
|
||||||
* [Debian GNU/Linux](contrib/debian/)
|
|
||||||
|
|
||||||
> **Note:** support for various Linux distributions does not mean Finit
|
|
||||||
> installs easily on all architectures. The bundled install scripts are
|
|
||||||
> examples for standard installations, tested on x86_64 systems. Custom
|
|
||||||
> setups, targeted at embedded systems, can be found in [myLinux][].
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
This example `/etc/finit.conf` can also be split up in multiple `.conf`
|
|
||||||
files in `/etc/finit.d`. Available, but not yet enabled, services can
|
|
||||||
be placed in `/etc/finit.d/available` and enabled by an operator using
|
|
||||||
the [initctl](#commands--status) tool.
|
|
||||||
|
|
||||||
```ApacheConf
|
|
||||||
# Fallback if /etc/hostname is missing
|
|
||||||
host default
|
|
||||||
|
|
||||||
# Runlevel to start after bootstrap, 'S', default: 2
|
|
||||||
runlevel 2
|
|
||||||
|
|
||||||
# Max file size for each log file: 100 kiB, rotate max 4 copies:
|
|
||||||
# log => log.1 => log.2.gz => log.3.gz => log.4.gz
|
|
||||||
log size=100k count=4
|
|
||||||
|
|
||||||
# Services to be monitored and respawned as needed
|
|
||||||
service [S12345] env:-/etc/conf.d/watchdog watchdog $WATCHDOG_OPTS $WATCHDOG_DEV -- System watchdog daemon
|
|
||||||
service [S12345] env:-/etc/conf.d/syslog syslogd -n $SYSLOGD_OPTS -- System log daemon
|
|
||||||
service [S12345] <pid/syslogd> env:-/etc/conf.d/klogd klogd -n $KLOGD_OPTS -- Kernel log daemon
|
|
||||||
service [2345] env:-/etc/conf.d/lldpd lldpd -d $LLDPD_OPTS -- LLDP daemon (IEEE 802.1ab)
|
|
||||||
|
|
||||||
# The BusyBox ntpd does not use syslog when running in the foreground
|
|
||||||
# So we use this trick to redirect stdout/stderr to a log file. The
|
|
||||||
# log file is rotated with the above settings. The condition declares
|
|
||||||
# a dependency on a system default route (gateway) to be set. A single
|
|
||||||
# <!> at the beginning means ntpd does not respect SIGHUP for restart.
|
|
||||||
service [2345] log:/var/log/ntpd.log <!net/route/default> ntpd -n -l -I eth0 -- NTP daemon
|
|
||||||
|
|
||||||
# For multiple instances of the same service, add :ID somewhere between
|
|
||||||
# the service/run/task keyword and the command.
|
|
||||||
service :80 [2345] merecat -n -p 80 /var/www -- Web server
|
|
||||||
service :8080 [2345] merecat -n -p 8080 /var/www -- Old web server
|
|
||||||
|
|
||||||
# Alternative method instead of below runparts, can also use /etc/rc.local
|
|
||||||
#sysv [S] /etc/init.d/keyboard-setup -- Setting up preliminary keymap
|
|
||||||
#sysv [S] /etc/init.d/acpid -- Starting ACPI Daemon
|
|
||||||
#task [S] /etc/init.d/kbd -- Preparing console
|
|
||||||
|
|
||||||
# Run start scripts from this directory
|
|
||||||
# runparts /etc/start.d
|
|
||||||
|
|
||||||
# Virtual consoles run BusyBox getty, keep kernel default speed
|
|
||||||
tty [12345] /sbin/getty -L 0 /dev/tty1 linux nowait noclear
|
|
||||||
tty [2345] /sbin/getty -L 0 /dev/tty2 linux nowait noclear
|
|
||||||
tty [2345] /sbin/getty -L 0 /dev/tty3 linux nowait noclear
|
|
||||||
|
|
||||||
# Use built-in getty for serial port and USB serial
|
|
||||||
#tty [12345] /dev/ttyAMA0 noclear nowait
|
|
||||||
#tty [12345] /dev/ttyUSB0 noclear
|
|
||||||
|
|
||||||
# Just give me a shell, I need to debug this embedded system!
|
|
||||||
#tty [12345] console noclear nologin
|
|
||||||
```
|
|
||||||
|
|
||||||
The `service` stanza, as well as `task`, `run` and others are described
|
|
||||||
in full in [doc/config.md](doc/config.md). Here's a quick overview of
|
|
||||||
some of the most common components needed to start a UNIX daemon:
|
|
||||||
|
|
||||||
```
|
|
||||||
service [LVLS] <COND> log env:[-]/etc/default/daemon daemon ARGS -- Daemon daemon
|
|
||||||
^ ^ ^ ^ ^ ^ ^ ^
|
|
||||||
| | | | | | | `---------- Optional description
|
|
||||||
| | | | | | `------------------ Daemon arguments
|
|
||||||
| | | | | `------------------------- Path to daemon
|
|
||||||
| | | | `---------------------------------------------------- Optional env. file
|
|
||||||
| | | `-------------------------------------------------------- Redirect output to log
|
|
||||||
| | `--------------------------------------------------------------- Optional conditions
|
|
||||||
| `---------------------------------------------------------------------- Optional Runlevels
|
|
||||||
`------------------------------------------------------------------------------ Monitored application
|
|
||||||
```
|
|
||||||
|
|
||||||
Some components are optional: runlevel(s), condition(s) and description,
|
|
||||||
making it easy to create simple start scripts and still possible for more
|
|
||||||
advanced uses as well:
|
|
||||||
|
|
||||||
service /usr/sbin/sshd -D
|
|
||||||
|
|
||||||
Dependencies are handled using [conditions](doc/conditions.md). One of
|
|
||||||
the most common conditions is to wait for basic networking to become
|
|
||||||
available:
|
|
||||||
|
|
||||||
service <net/route/default> nginx -- High performance HTTP server
|
|
||||||
|
|
||||||
Here is another example where we instruct Finit to not start BusyBox
|
|
||||||
`ntpd` until `syslogd` has started properly. Finit waits for `syslogd`
|
|
||||||
to create its PID file, by default `/var/run/syslogd.pid`.
|
|
||||||
|
|
||||||
service [2345] log <!pid/syslogd> ntpd -n -N -p pool.ntp.org
|
|
||||||
service [S12345] syslogd -n -- Syslog daemon
|
|
||||||
|
|
||||||
Notice the `log` keyword, BusyBox `ntpd` uses `stderr` for logging when
|
|
||||||
run in the foreground. With `log` Finit redirects `stdout` + `stderr`
|
|
||||||
to the system log daemon using the command line `logger(1)` tool.
|
|
||||||
|
|
||||||
A service, or task, can have multiple dependencies listed. Here we wait
|
|
||||||
for *both* `syslogd` to have started and basic networking to be up:
|
|
||||||
|
|
||||||
service [2345] log <pid/syslogd,net/route/default> ntpd -n -N -p pool.ntp.org
|
|
||||||
|
|
||||||
If either condition fails, e.g. loss of networking, `ntpd` is stopped
|
|
||||||
and as soon as it comes back up again `ntpd` is restarted automatically.
|
|
||||||
|
|
||||||
**Note:** Make sure daemons *do not* fork and detach themselves from the
|
|
||||||
controlling TTY, usually an `-n` or `-f` flag, or `-D` as in the case
|
|
||||||
of OpenSSH above. If it detaches itself, Finit cannot monitor it and
|
|
||||||
will instead try to restart it.
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
**Process Supervision**
|
|
||||||
|
|
||||||
Start, monitor and restart services should they fail.
|
|
||||||
|
|
||||||
|
|
||||||
**Getty**
|
|
||||||
|
|
||||||
Finit supports external getty but also comes with a limited built-in
|
|
||||||
Getty, useful for really small systems. A getty sets up the TTY and
|
|
||||||
waits for user input before handing over to `/bin/login`, which is
|
|
||||||
responsible for handling the actual authentication.
|
|
||||||
|
|
||||||
```conf
|
|
||||||
tty [12345] /dev/tty1 nowait linux
|
|
||||||
tty [12345] /dev/ttyAMA0 noclear vt100
|
|
||||||
tty [12345] /sbin/getty -L /dev/ttyAMA0 vt100
|
|
||||||
```
|
|
||||||
|
|
||||||
Users of embedded systems may want to enable automatic serial console
|
|
||||||
with the special `@console` device. This works regardless weather the
|
|
||||||
system uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit
|
|
||||||
figures it out by querying sysfs: `/sys/class/tty/console/active`.
|
|
||||||
|
|
||||||
```conf
|
|
||||||
tty [12345] @console linux noclear
|
|
||||||
```
|
|
||||||
|
|
||||||
Notice the optional `noclear`, `nowait`, and `nologin` flags. The
|
|
||||||
latter is for skipping the login process entirely. For more information,
|
|
||||||
see [doc/config.md](doc/config.md#syntax).
|
|
||||||
|
|
||||||
|
|
||||||
**Runlevels**
|
|
||||||
|
|
||||||
Support for SysV init-style [runlevels][5] is available, in the same
|
|
||||||
minimal style as everything else in Finit. The `[2345]` syntax can be
|
|
||||||
applied to service, task, run, and TTY stanzas.
|
|
||||||
|
|
||||||
Reserved runlevels are 0 and 6, halt and reboot, respectively just like
|
|
||||||
SysV init. Runlevel 1 can be configured freely, but is recommended to
|
|
||||||
be kept as the system single-user runlevel since Finit will not start
|
|
||||||
networking here. The configured `runlevel NUM` from `/etc/finit.conf`
|
|
||||||
is what Finit changes to after bootstrap, unless 'single' (or 'S') is
|
|
||||||
given on the kernel cmdline, in which case runlevel 1 is started.
|
|
||||||
|
|
||||||
All services in runlevel S(0) are started first, followed by the desired
|
|
||||||
run-time runlevel. Run tasks in runlevel S can be started in sequence
|
|
||||||
by using `run [S] cmd`. Changing runlevels at runtime is done like any
|
|
||||||
other init, e.g. <kbd>init 4</kbd>, but also using the more advanced
|
|
||||||
`intictl` tool.
|
|
||||||
|
|
||||||
|
|
||||||
**Plugins**
|
|
||||||
|
|
||||||
Plugins can *extend* the functionality of Finit and *hook into* the
|
|
||||||
different stages of the boot process and at runtime. Plugins are
|
|
||||||
written in C and compiled into a dynamic library loaded automatically by
|
|
||||||
finit at boot. A basic set of plugins are bundled in the `plugins/`
|
|
||||||
directory.
|
|
||||||
|
|
||||||
Capabilities:
|
|
||||||
|
|
||||||
- **Hooks**
|
|
||||||
Hook into the boot at predefined points to extend Finit
|
|
||||||
- **I/O**
|
|
||||||
Listen to external events and control Finit behavior/services
|
|
||||||
|
|
||||||
Extensions and functionality not purely related to what an `/sbin/init`
|
|
||||||
needs to start a system are available as a set of plugins that either
|
|
||||||
hook into the boot process or respond to various I/O.
|
|
||||||
|
|
||||||
For more information, see [doc/plugins.md](doc/plugins.md).
|
|
||||||
|
|
||||||
|
|
||||||
**Automatic Reload**
|
|
||||||
|
|
||||||
By default, Finit monitors `/etc/finit.d/` and `/etc/finit.d/enabled/`
|
|
||||||
registering any changes to `.conf` files. To activate a change the user
|
|
||||||
must call `initctl reload`, which reloads all modified files, stops any
|
|
||||||
removed services, starts new ones, and restarts any modified ones. If the
|
|
||||||
command line arguments of a service have changed, the process will be
|
|
||||||
terminated and then started again with the updated arguments. If the arguments
|
|
||||||
have not been modified and the process supports SIGHUP, the process will
|
|
||||||
receive a SIGHUP rather than being terminated and started.
|
|
||||||
|
|
||||||
For some use-cases the extra step of calling `initctl reload` creates an
|
|
||||||
unnecessary overhead, which can be removed at build-time using:
|
|
||||||
|
|
||||||
configure --enable-auto-reload
|
|
||||||
|
|
||||||
|
|
||||||
**Cgroups**
|
|
||||||
|
|
||||||
Finit supports cgroups v2 and comes with the following default groups
|
|
||||||
in which services and user sessions are placed in:
|
|
||||||
|
|
||||||
/sys/fs/cgroup
|
|
||||||
|-- init/ # cpu.weight:100
|
|
||||||
|-- system/ # cpu.weight:9800
|
|
||||||
`-- user/ # cpu.weight:100
|
|
||||||
|
|
||||||
Finit itself and its helper scripts and services are placed in the
|
|
||||||
top-level leaf-node group `init/`, which also is _reserved_.
|
|
||||||
|
|
||||||
All run/task/service/sysv processes are placed in their own sub-group
|
|
||||||
in `system/`. The name of each sub-group is taken from the respective
|
|
||||||
`.conf` file from `/etc/finit.d`.
|
|
||||||
|
|
||||||
All getty/tty processes are placed in their own sub-group in `user/`.
|
|
||||||
The name of each sub-group is taken from the username.
|
|
||||||
|
|
||||||
A fourth group also exists, the `root` group. It is also _reserved_ and
|
|
||||||
primarily intended for RT tasks. If you have RT tasks they need to be
|
|
||||||
declared as such in their service stanza like this:
|
|
||||||
|
|
||||||
service [...] <...> cgroup.root /path/to/foo args -- description
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
cgroup.root
|
|
||||||
service [...] <...> /path/to/foo args -- description
|
|
||||||
service [...] <...> /path/to/bar args -- description
|
|
||||||
|
|
||||||
See [doc/config.md](doc/config.md#cgroups) for more information, e.g.,
|
|
||||||
how to configure per-group limits.
|
|
||||||
|
|
||||||
The `initctl` tool has three commands to help debug and optimize the
|
|
||||||
setup and monitoring of cgroups. See the `ps`, `top`, and `cgroup`
|
|
||||||
commands for details.
|
|
||||||
|
|
||||||
|
|
||||||
Runparts & /etc/rc.local
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
At the end of the boot, when all bootstrap (`S`) tasks and services have
|
|
||||||
started, but not networking, Finit calls its built-in [run-parts(8)][]
|
|
||||||
command on any configured `runparts <DIR>` directory. This happens just
|
|
||||||
before changing to the configured runlevel (default 2). (Networking is
|
|
||||||
enabled just prior to changing from single user mode.)
|
|
||||||
|
|
||||||
```shell
|
|
||||||
runparts /etc/rc.d/
|
|
||||||
```
|
|
||||||
|
|
||||||
Right after the runlevel change when all services have started properly,
|
|
||||||
`/etc/rc.local` is called.
|
|
||||||
|
|
||||||
No configuration stanza in `/etc/finit.conf` is required for `rc.local`.
|
|
||||||
If it exists and is an executable shell script Finit calls it at the very
|
|
||||||
end of the boot, before calling the `HOOK_SYSTEM_UP`. See more on hooks
|
|
||||||
in [doc/plugins.md](doc/plugins.md#hooks), and about the system bootstrap
|
|
||||||
in [doc/bootstrap.md](doc/bootstrap.md).
|
|
||||||
|
|
||||||
|
|
||||||
Runlevels
|
|
||||||
---------
|
|
||||||
|
|
||||||
Basic support for [runlevels][5] is included in Finit from v1.8. By
|
|
||||||
default all services, tasks, run commands and TTYs listed without a set
|
|
||||||
of runlevels get a default set `[234]` assigned. The default runlevel
|
|
||||||
after boot is 2.
|
|
||||||
|
|
||||||
Finit supports runlevels 0-9, and S, with 0 reserved for halt, 6 reboot
|
|
||||||
and S for services to only run at bootstrap. Runlevel 1 is the single
|
|
||||||
user level, where usually no networking is enabled. In Finit this is
|
|
||||||
more of a policy for the user to define. Normally only runlevels 1-6
|
|
||||||
are used, and even more commonly, only the default runlevel is used.
|
|
||||||
|
|
||||||
To specify an allowed set of runlevels for a `service`, `run` command,
|
|
||||||
`task`, or `tty`, add `[NNN]` to your `/etc/finit.conf`, like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
service [S12345] syslogd -n -x -- System log daemon
|
|
||||||
run [S] /etc/init.d/acpid start -- Starting ACPI Daemon
|
|
||||||
task [S] /etc/init.d/kbd start -- Preparing console
|
|
||||||
service [S12345] <pid/syslogd> klogd -n -x -- Kernel log daemon
|
|
||||||
|
|
||||||
tty [12345] /dev/tty1
|
|
||||||
tty [2] /dev/tty2
|
|
||||||
tty [2] /dev/tty3
|
|
||||||
tty [2] /dev/tty4
|
|
||||||
tty [2] /dev/tty5
|
|
||||||
tty [2] /dev/tty6
|
|
||||||
```
|
|
||||||
|
|
||||||
In this example syslogd is first started, in parallel, and then acpid is
|
|
||||||
called using a conventional SysV init script. It is called with the run
|
|
||||||
command, meaning the following task command to start the kbd script is
|
|
||||||
not called until the acpid init script has fully completed. Then the
|
|
||||||
keyboard setup script is called in parallel with klogd as a monitored
|
|
||||||
service.
|
|
||||||
|
|
||||||
Again, tasks and services are started in parallel, while run commands
|
|
||||||
are called in the order listed and subsequent commands are not started
|
|
||||||
until a run command has completed. Also, task and run commands are run
|
|
||||||
in a shell, so pipes and redirects can be used.
|
|
||||||
|
|
||||||
The following examples illustrate this. Bootstrap task and run commands
|
|
||||||
are also removed when they have completed, `initctl show` will not list
|
|
||||||
them.
|
|
||||||
|
|
||||||
```
|
|
||||||
task [S] echo "foo" | cat >/tmp/bar
|
|
||||||
run [S] echo "$HOME" >/tmp/secret
|
|
||||||
```
|
|
||||||
|
|
||||||
Switching between runlevels can be done by calling init with a single
|
|
||||||
argument, e.g. <kbd>init 5</kbd>, or using `initctl runlevel 5`, both
|
|
||||||
switch to runlevel 5. When changing runlevels Finit also automatically
|
|
||||||
reloads all `.conf` files in the `/etc/finit.d/` directory. So if you
|
|
||||||
want to set a new system config, switch to runlevel 1, change all config
|
|
||||||
files in the system, and touch all `.conf` files in `/etc/finit.d`
|
|
||||||
before switching back to the previous runlevel again — that way Finit
|
|
||||||
can both stop old services and start any new ones for you, without
|
|
||||||
rebooting the system.
|
|
||||||
|
|
||||||
|
|
||||||
Rebooting & Halting
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Traditionally, rebooting and halting a UNIX system is done by changing
|
|
||||||
its runlevel. Finit comes with its own tooling providing: `shutdown`,
|
|
||||||
`reboot`, `poweroff`, and `suspend`, but also the `initctl` tool,
|
|
||||||
detailed in the next section.
|
|
||||||
|
|
||||||
For compatibility reasons Finit listens to the same set of signals as
|
|
||||||
BusyBox init. This is not 100% compatible with SysV init, but clearly
|
|
||||||
the more common combination for Finit. For more details, see
|
|
||||||
[doc/signals.md](doc/signals.md).
|
|
||||||
|
|
||||||
|
|
||||||
Commands & Status
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Finit also implements a modern API to query status, and start/stop
|
|
||||||
services, called `initctl`. Unlike `telinit` the `initctl` tool does
|
|
||||||
not return until the given command has fully completed.
|
|
||||||
|
|
||||||
```
|
|
||||||
alpine:~# initctl help
|
|
||||||
Usage: initctl [OPTIONS] [COMMAND]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-b, --batch Batch mode, no screen size probing
|
|
||||||
-c, --create Create missing paths (and files) as needed
|
|
||||||
-f, --force Ignore missing files and arguments, never prompt
|
|
||||||
-1, --once Only one lap in commands like 'top'
|
|
||||||
-p, --plain Use plain table headings, no ctrl chars
|
|
||||||
-q, --quiet Silent, only return status of command
|
|
||||||
-t, --no-heading Skip table headings
|
|
||||||
-v, --verbose Verbose output
|
|
||||||
-h, --help This help text
|
|
||||||
|
|
||||||
Commands:
|
|
||||||
debug Toggle Finit (daemon) debug
|
|
||||||
help This help text
|
|
||||||
version Show Finit version
|
|
||||||
|
|
||||||
ls | list List all .conf in /etc/finit.d
|
|
||||||
create <CONF> Create .conf in /etc/finit.d/available
|
|
||||||
delete <CONF> Delete .conf in /etc/finit.d/available
|
|
||||||
show <CONF> Show .conf in /etc/finit.d/available
|
|
||||||
edit <CONF> Edit .conf in /etc/finit.d/available
|
|
||||||
touch <CONF> Change .conf in /etc/finit.d/available
|
|
||||||
enable <CONF> Enable .conf in /etc/finit.d/available
|
|
||||||
disable <CONF> Disable .conf in /etc/finit.d/enabled
|
|
||||||
reload Reload *.conf in /etc/finit.d (activate changes)
|
|
||||||
|
|
||||||
cond set <COND> Set (assert) user-defined condition +usr/COND
|
|
||||||
cond clear <COND> Clear (deassert) user-defined condition -usr/COND
|
|
||||||
cond status Show condition status, default cond command
|
|
||||||
cond dump Dump all conditions and their status
|
|
||||||
|
|
||||||
log [NAME] Show ten last Finit, or NAME, messages from syslog
|
|
||||||
start <NAME>[:ID] Start service by name, with optional ID
|
|
||||||
stop <NAME>[:ID] Stop/Pause a running service by name
|
|
||||||
reload <NAME>[:ID] Reload service by name (SIGHUP or restart)
|
|
||||||
restart <NAME>[:ID] Restart (stop/start) service by name
|
|
||||||
status <NAME>[:ID] Show service status, by name
|
|
||||||
status Show status of services, default command
|
|
||||||
|
|
||||||
cgroup List cgroup config overview
|
|
||||||
ps List processes based on cgroups
|
|
||||||
top Show top-like listing based on cgroups
|
|
||||||
|
|
||||||
runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot
|
|
||||||
reboot Reboot system
|
|
||||||
halt Halt system
|
|
||||||
poweroff Halt and power off system
|
|
||||||
suspend Suspend system
|
|
||||||
```
|
|
||||||
|
|
||||||
For services *not* supporting `SIGHUP` the `<!>` notation in the .conf
|
|
||||||
file must be used to tell Finit to stop and start it on `reload` and
|
|
||||||
`runlevel` changes. If `<>` holds more [conditions](doc/conditions.md),
|
|
||||||
these will also affect how a service is maintained.
|
|
||||||
|
|
||||||
> **Note:** even though it is possible to start services not belonging in
|
|
||||||
> the current runlevel these services will not be respawned automatically
|
|
||||||
> by Finit if they exit (crash). Hence, if the runlevel is 2, the below
|
|
||||||
> Dropbear SSH service will not be restarted if it is killed or exits.
|
|
||||||
|
|
||||||
The `status` command is the default, it displays a quick overview of all
|
|
||||||
monitored run/task/services. Here we call `initctl -p`, suitable for
|
|
||||||
scripting and documentation:
|
|
||||||
|
|
||||||
```
|
|
||||||
alpine:~# initctl -p
|
|
||||||
PID IDENT STATUS RUNLEVELS DESCRIPTION
|
|
||||||
======================================================================
|
|
||||||
1506 acpid running [--2345----] ACPI daemon
|
|
||||||
1509 crond running [--2345----] Cron daemon
|
|
||||||
1489 dropbear running [--2345----] Dropbear SSH daemon
|
|
||||||
1511 klogd running [S12345----] Kernel log daemon
|
|
||||||
1512 ntpd running [--2345----] NTP daemon
|
|
||||||
1473 syslogd running [S12345----] Syslog daemon
|
|
||||||
|
|
||||||
alpine:~# initctl -pv
|
|
||||||
PID IDENT STATUS RUNLEVELS COMMAND
|
|
||||||
======================================================================
|
|
||||||
1506 acpid running [--2345----] acpid -f
|
|
||||||
1509 crond running [--2345----] crond -f -S $CRON_OPTS
|
|
||||||
1489 dropbear running [--2345----] dropbear -R -F $DROPBEAR_OPTS
|
|
||||||
1511 klogd running [S12345----] klogd -n $KLOGD_OPTS
|
|
||||||
1512 ntpd running [--2345----] ntpd -n $NTPD_OPTS
|
|
||||||
1473 syslogd running [S12345----] syslogd -n
|
|
||||||
```
|
|
||||||
|
|
||||||
The environment variables to each of the services above are read from,
|
|
||||||
in the case of Alpine Linux, `/etc/conf.d/`. Other distributions may
|
|
||||||
have other directories, e.g., Debian use `/etc/default/`.
|
|
||||||
|
|
||||||
The `status` command takes an optional `NAME:ID` argument. Here we
|
|
||||||
check the status of `dropbear`, which only has one instance in this
|
|
||||||
system:
|
|
||||||
|
|
||||||
```
|
|
||||||
alpine:~# initctl -p status dropbear
|
|
||||||
Status : running
|
|
||||||
Identity : dropbear
|
|
||||||
Description : Dropbear SSH daemon
|
|
||||||
Origin : /etc/finit.d/enabled/dropbear.conf
|
|
||||||
Environment : -/etc/conf.d/dropbear
|
|
||||||
Condition(s):
|
|
||||||
Command : dropbear -R -F $DROPBEAR_OPTS
|
|
||||||
PID file : !/run/dropbear.pid
|
|
||||||
PID : 1485
|
|
||||||
User : root
|
|
||||||
Group : root
|
|
||||||
Uptime : 2 hour 46 min 56 sec
|
|
||||||
Runlevels : [--2345----]
|
|
||||||
Memory : 1.2M
|
|
||||||
CGroup : /system/dropbear cpu 0 [100, max] mem [--.--, max]
|
|
||||||
|- 1485 dropbear -R -F
|
|
||||||
|- 2634 dropbear -R -F
|
|
||||||
|- 2635 ash
|
|
||||||
`- 2652 initctl -p status dropbear
|
|
||||||
|
|
||||||
Apr 8 12:19:49 alpine authpriv.info dropbear[1485]: Not backgrounding
|
|
||||||
Apr 8 12:37:45 alpine authpriv.info dropbear[2300]: Child connection from 192.168.121.1:47834
|
|
||||||
Apr 8 12:37:46 alpine authpriv.notice dropbear[2300]: Password auth succeeded for 'root' from 192.168.121.1:47834
|
|
||||||
Apr 8 12:37:46 alpine authpriv.info dropbear[2300]: Exit (root) from <192.168.121.1:47834>: Disconnect received
|
|
||||||
Apr 8 15:02:11 alpine authpriv.info dropbear[2634]: Child connection from 192.168.121.1:48576
|
|
||||||
Apr 8 15:02:12 alpine authpriv.notice dropbear[2634]: Password auth succeeded for 'root' from 192.168.121.1:48576
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
------------
|
|
||||||
|
|
||||||
Finit is capable of running on both desktop/server systems with udev and
|
|
||||||
embedded systems that usually come with BusyBox mdev. Some systems have
|
|
||||||
systemd-udev or eudev today instead of the original udev, Finit probes
|
|
||||||
for all of them at runtime and expects `/dev/` to be a writable file
|
|
||||||
system using `devtmpfs`. It is also possible to run on a statically set
|
|
||||||
up `/dev` if needed. It is however not a good idea to have both udev
|
|
||||||
and mdev installed at the same time, this will lead to unpredictable
|
|
||||||
results.
|
|
||||||
|
|
||||||
At boot Finit calls either `mdev` or `udevd` to populate `/dev`, this is
|
|
||||||
done slightly differently and on systems with udev you might want to add
|
|
||||||
the following one-shot task early in your `/etc/finit.conf`:
|
|
||||||
|
|
||||||
```conf
|
|
||||||
run [S] udevadm settle --timeout=120 -- Waiting for udev
|
|
||||||
```
|
|
||||||
|
|
||||||
Finit has a built-in Getty for TTYs, but requires a working `/bin/login`
|
|
||||||
or `/bin/sh`, if no TTYs are configured in `/etc/finit.conf`.
|
|
||||||
|
|
||||||
For a fully operational system `/var`, `/run` and `/tmp` must be set up
|
|
||||||
properly in `/etc/fstab` -- which is iterated over at boot.
|
|
||||||
|
|
||||||
|
|
||||||
Origin & References
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
This project is based on the [original finit][] by [Claudio Matsuoka][]
|
|
||||||
which was reverse engineered from syscalls of the [EeePC fastinit][] —
|
|
||||||
"gaps filled with frog DNA …"
|
|
||||||
|
|
||||||
Finit is developed and maintained by [Joachim Wiberg][] at [GitHub][6].
|
|
||||||
Please file bug reports, clone it, or send pull requests for bug fixes
|
|
||||||
and proposed extensions.
|
|
||||||
|
|
||||||
|
|
||||||
[1]: https://en.wikipedia.org/wiki/Process_supervision
|
|
||||||
[2]: https://cr.yp.to/daemontools.html
|
|
||||||
[3]: https://smarden.org/runit/
|
|
||||||
[4]: https://en.wikipedia.org/wiki/Init
|
|
||||||
[5]: https://en.wikipedia.org/wiki/Runlevel
|
|
||||||
[6]: https://github.com/troglobit/finit
|
|
||||||
[RFC862]: https://tools.ietf.org/html/rfc862
|
|
||||||
[RFC863]: https://tools.ietf.org/html/rfc863
|
|
||||||
[RFC864]: https://tools.ietf.org/html/rfc864
|
|
||||||
[RFC867]: https://tools.ietf.org/html/rfc867
|
|
||||||
[RFC868]: https://tools.ietf.org/html/rfc868
|
|
||||||
[init]: https://en.wikipedia.org/wiki/Init
|
|
||||||
[upstart]: https://upstart.ubuntu.com/
|
|
||||||
[systemd]: https://www.freedesktop.org/wiki/Software/systemd/
|
|
||||||
[openrc]: https://www.gentoo.org/proj/en/base/openrc/
|
|
||||||
[run-parts(8)]: https://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
|
||||||
[original finit]: http://helllabs.org/finit/
|
|
||||||
[EeePC fastinit]: https://web.archive.org/web/20071208212450/http://wiki.eeeuser.com/boot_process:the_boot_process
|
[EeePC fastinit]: https://web.archive.org/web/20071208212450/http://wiki.eeeuser.com/boot_process:the_boot_process
|
||||||
[Claudio Matsuoka]: https://github.com/cmatsuoka
|
[Claudio Matsuoka]: https://github.com/cmatsuoka
|
||||||
[Joachim Wiberg]: https://troglobit.com
|
|
||||||
[License]: https://en.wikipedia.org/wiki/MIT_License
|
[License]: https://en.wikipedia.org/wiki/MIT_License
|
||||||
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
|
[License Badge]: https://img.shields.io/badge/License-MIT-teal.svg
|
||||||
[GitHub]: https://github.com/troglobit/myLinux/
|
[Release]: https://github.com/finit-project/finit/releases
|
||||||
[GitHub]: https://github.com/troglobit/finit/actions/workflows/build.yml/
|
[Release Badge]: https://img.shields.io/github/v/release/finit-project/finit
|
||||||
[GitHub Status]: https://github.com/troglobit/finit/actions/workflows/build.yml/badge.svg
|
[GitHub]: https://github.com/finit-project/finit/actions/workflows/build.yml/
|
||||||
|
[GitHub Status]: https://github.com/finit-project/finit/actions/workflows/build.yml/badge.svg
|
||||||
[Coverity Scan]: https://scan.coverity.com/projects/3545
|
[Coverity Scan]: https://scan.coverity.com/projects/3545
|
||||||
[Coverity Status]: https://scan.coverity.com/projects/3545/badge.svg
|
[Coverity Status]: https://scan.coverity.com/projects/3545/badge.svg
|
||||||
|
[br2-finit-demo]: https://github.com/finit-project/br2-finit-demo
|
||||||
|
|||||||
@@ -1,21 +1,25 @@
|
|||||||
AC_INIT(Finit, 4.3-rc2, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/projects/finit/)
|
AC_INIT([Finit], [4.17], [https://github.com/finit-project/finit/issues],
|
||||||
|
[finit], [https://http://finit-project.github.io/])
|
||||||
AC_CONFIG_AUX_DIR(aux)
|
AC_CONFIG_AUX_DIR(aux)
|
||||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
|
AM_INIT_AUTOMAKE([1.11 foreign subdir-objects])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR([src/finit.c])
|
AC_CONFIG_SRCDIR([src/finit.c])
|
||||||
AC_CONFIG_HEADER([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([Makefile
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
contrib/alpine/Makefile contrib/alpine/finit.d/Makefile contrib/alpine/finit.d/available/Makefile
|
contrib/alpine/Makefile contrib/alpine/finit.d/Makefile contrib/alpine/finit.d/available/Makefile
|
||||||
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile
|
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile
|
||||||
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
|
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
|
||||||
doc/Makefile
|
doc/Makefile doc/config/Makefile
|
||||||
|
libsystemd/Makefile libsystemd/libsystemd.pc
|
||||||
man/Makefile
|
man/Makefile
|
||||||
plugins/Makefile
|
plugins/Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
|
system/Makefile system/10-hotplug.conf
|
||||||
test/test.env test/Makefile
|
test/test.env test/Makefile
|
||||||
test/tenv/Makefile test/common/Makefile])
|
test/lib/Makefile test/src/Makefile
|
||||||
|
tmpfiles.d/Makefile])
|
||||||
|
|
||||||
# Older versions of autoconf (<2.58) do not have AC_CONFIG_MACRO_DIR()
|
# Older versions of autoconf (<2.58) do not have AC_CONFIG_MACRO_DIR()
|
||||||
#m4_include([m4/plugin.m4])
|
#m4_include([m4/plugin.m4])
|
||||||
@@ -32,7 +36,6 @@ AC_PROG_INSTALL
|
|||||||
AC_PROG_MKDIR_P
|
AC_PROG_MKDIR_P
|
||||||
|
|
||||||
# Configuration.
|
# Configuration.
|
||||||
AC_HEADER_STDC
|
|
||||||
AC_CHECK_HEADERS([termios.h sys/ioctl.h mntent.h sys/sysmacros.h])
|
AC_CHECK_HEADERS([termios.h sys/ioctl.h mntent.h sys/sysmacros.h])
|
||||||
AC_CHECK_FUNCS([strstr getopt getmntent getmntent_r])
|
AC_CHECK_FUNCS([strstr getopt getmntent getmntent_r])
|
||||||
|
|
||||||
@@ -45,8 +48,8 @@ AC_TYPE_UINT32_T
|
|||||||
PKG_PROG_PKG_CONFIG
|
PKG_PROG_PKG_CONFIG
|
||||||
|
|
||||||
# Check for required libraries
|
# Check for required libraries
|
||||||
PKG_CHECK_MODULES([uev], [libuev >= 2.2.0])
|
PKG_CHECK_MODULES([uev], [libuev >= 2.4.1])
|
||||||
PKG_CHECK_MODULES([lite], [libite >= 2.2.0])
|
PKG_CHECK_MODULES([lite], [libite >= 2.6.1])
|
||||||
|
|
||||||
# Check for configured Finit features
|
# Check for configured Finit features
|
||||||
AC_ARG_ENABLE(auto_reload,
|
AC_ARG_ENABLE(auto_reload,
|
||||||
@@ -65,12 +68,24 @@ AC_ARG_ENABLE(fsckfix,
|
|||||||
AS_HELP_STRING([--enable-fsckfix], [Run fsck fix mode (options: -yf) on filesystems listed in /etc/fstab]),,[
|
AS_HELP_STRING([--enable-fsckfix], [Run fsck fix mode (options: -yf) on filesystems listed in /etc/fstab]),,[
|
||||||
enable_fsckfix=no])
|
enable_fsckfix=no])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(cgroup,
|
||||||
|
AS_HELP_STRING([--disable-cgroup], [Disable cgroup v2 support, default: autodetect from /sys/fs/cgroup]),,[
|
||||||
|
enable_cgroup=yes])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(libcap,
|
||||||
|
AS_HELP_STRING([--disable-libcap], [Disable Linux capabilities support]),,[
|
||||||
|
enable_libcap=yes])
|
||||||
|
|
||||||
AC_ARG_ENABLE(redirect,
|
AC_ARG_ENABLE(redirect,
|
||||||
AS_HELP_STRING([--disable-redirect], [Disable redirection of service output to /dev/null]),,[
|
AS_HELP_STRING([--disable-redirect], [Disable redirection of service output to /dev/null]),,[
|
||||||
enable_redirect=yes])
|
enable_redirect=yes])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(kernel_logging,
|
||||||
|
AS_HELP_STRING([--disable-kernel-logging], [Disable kernel logging to console (use 'quiet' instead!]),,[
|
||||||
|
enable_kernel_logging=yes])
|
||||||
|
|
||||||
AC_ARG_ENABLE(logrotate,
|
AC_ARG_ENABLE(logrotate,
|
||||||
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp, default enabled]),,[
|
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp]),,[
|
||||||
enable_logrotate=yes])
|
enable_logrotate=yes])
|
||||||
|
|
||||||
AC_ARG_ENABLE(doc,
|
AC_ARG_ENABLE(doc,
|
||||||
@@ -81,22 +96,34 @@ AC_ARG_ENABLE(contrib,
|
|||||||
AS_HELP_STRING([--disable-contrib], [Disable build and install of contrib section]),,[
|
AS_HELP_STRING([--disable-contrib], [Disable build and install of contrib section]),,[
|
||||||
enable_contrib=yes])
|
enable_contrib=yes])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([rescue],
|
||||||
|
AS_HELP_STRING([--disable-rescue], [Disable potentially unsafe rescue mode]),,
|
||||||
|
[enable_rescue=yes])
|
||||||
|
|
||||||
# Check for extra plugins to enable
|
# Check for extra plugins to enable
|
||||||
enable_all_plugins=auto
|
AC_ARG_ENABLE(all_plugins,
|
||||||
|
AS_HELP_STRING([--enable-all-plugins], [Enable all plugins, default: auto]),
|
||||||
|
enable_all_plugins=$enableval, enable_all_plugins=auto)
|
||||||
AC_PLUGIN([alsa-utils], [no], [Save and restore ALSA sound settings using alsactl])
|
AC_PLUGIN([alsa-utils], [no], [Save and restore ALSA sound settings using alsactl])
|
||||||
AC_PLUGIN([dbus], [no], [Setup and start system message bus, D-Bus])
|
AC_PLUGIN([dbus], [no], [Setup and start system message bus, D-Bus])
|
||||||
AC_PLUGIN([modules-load], [no], [Scans /etc/modules-load.d for modules to load])
|
AC_PLUGIN([modules-load], [no], [Scans /etc/modules-load.d for modules to load])
|
||||||
AC_PLUGIN([modprobe], [yes], [Coldplug modules using modalias magic])
|
AC_PLUGIN([modprobe], [no], [Coldplug modules using modalias magic])
|
||||||
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
|
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
|
||||||
AC_PLUGIN([x11-common], [no], [Console setup (for X)])
|
AC_PLUGIN([x11-common], [no], [Console setup (for X)])
|
||||||
AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.])
|
AC_PLUGIN([netlink], [yes], [Basic netlink plugin for IFUP/IFDN and GW events. Can be replaced with externally built plugin that links with libnl or similar.])
|
||||||
AC_PLUGIN([hook-scripts], [no], [Trigger script execution from hook points])
|
AC_PLUGIN([hook-scripts], [no], [Trigger script execution from hook points])
|
||||||
AC_PLUGIN([hotplug], [yes], [Setup and start udev or mdev hotplug daemon])
|
AC_PLUGIN([hotplug], [yes], [Start udevd or mdev kernel event datamon])
|
||||||
AC_PLUGIN([rtc], [yes], [Save and restore RTC using hwclock])
|
AC_PLUGIN([rtc], [yes], [Save and restore RTC using hwclock])
|
||||||
AC_PLUGIN([tty], [yes], [Automatically activate new TTYs, e.g. USB-to-serial])
|
AC_PLUGIN([tty], [yes], [Automatically activate new TTYs, e.g. USB-to-serial])
|
||||||
AC_PLUGIN([urandom], [yes], [Setup and save random seed at boot/shutdown])
|
AC_PLUGIN([urandom], [yes], [Setup and save random seed at boot/shutdown])
|
||||||
|
AC_PLUGIN([plymouth], [no], [Plymouth boot splash integration])
|
||||||
|
AC_PLUGIN([testserv], [no], [Test plugin to start test serv daemon])
|
||||||
|
|
||||||
# Check for extra arguments or packages
|
# Check for extra arguments or packages
|
||||||
|
AC_ARG_WITH([bash-completion-dir],
|
||||||
|
AS_HELP_STRING([--with-bash-completion-dir[=PATH]], [Directory to install Bash completion, default: auto]),
|
||||||
|
[bash_dir=$withval], [bash_dir=yes])
|
||||||
|
|
||||||
AC_ARG_WITH(fstab,
|
AC_ARG_WITH(fstab,
|
||||||
AS_HELP_STRING([--with-fstab=FILE], [System default fstab, default $sysconfdir/fstab]),
|
AS_HELP_STRING([--with-fstab=FILE], [System default fstab, default $sysconfdir/fstab]),
|
||||||
[fstab=$withval], [fstab=yes])
|
[fstab=$withval], [fstab=yes])
|
||||||
@@ -141,16 +168,31 @@ AC_ARG_WITH(keventd,
|
|||||||
AS_HELP_STRING([--with-keventd], [Enable built-in keventd, default: no]),, [with_keventd=no])
|
AS_HELP_STRING([--with-keventd], [Enable built-in keventd, default: no]),, [with_keventd=no])
|
||||||
|
|
||||||
AC_ARG_WITH(sulogin,
|
AC_ARG_WITH(sulogin,
|
||||||
AS_HELP_STRING([--with-sulogin], [Enable built-in sulogin, default: no.]),, [with_sulogin=no])
|
AS_HELP_STRING([--with-sulogin@<:@=USER@:>@], [Enable built-in sulogin, optional USER to request password for (default root), default: no.]),[sulogin=$withval],[with_sulogin=no])
|
||||||
|
|
||||||
AC_ARG_WITH(watchdog,
|
AC_ARG_WITH(watchdog,
|
||||||
AS_HELP_STRING([--with-watchdog=[DEV]], [Enable built-in watchdog, default: /dev/watchdog]),
|
AS_HELP_STRING([--with-watchdog@<:@=DEV@:>@], [Enable built-in watchdog, default: /dev/watchdog]),
|
||||||
[watchdog=$withval], [with_watchdog=no watchdog=])
|
[watchdog=$withval], [with_watchdog=no watchdog=])
|
||||||
|
|
||||||
|
AC_ARG_WITH(libsystemd,
|
||||||
|
AS_HELP_STRING([--with-libsystemd], [Build replacement libsystemd library, default: yes]),
|
||||||
|
[with_libsystemd=$withval], [with_libsystemd=no])
|
||||||
|
|
||||||
AC_ARG_WITH(hook-scripts-path,
|
AC_ARG_WITH(hook-scripts-path,
|
||||||
AS_HELP_STRING([--with-hook-scripts-path=DIR], [Base directory for hook scripts, default $libexecdir/finit/hook]),
|
AS_HELP_STRING([--with-hook-scripts-path=DIR], [Base directory for hook scripts, default $libexecdir/finit/hook]),
|
||||||
[hook_scripts_path=$withval], [hook_scripts_path=yes])
|
[hook_scripts_path=$withval], [hook_scripts_path=yes])
|
||||||
|
|
||||||
|
AC_ARG_WITH(plugin-path,
|
||||||
|
AS_HELP_STRING([--with-plugin-path=DIR], [Search path for external plugins, default /usr/lib/finit/plugins:/usr/local/lib/finit/plugins]),
|
||||||
|
[plugin_path=$withval], [plugin_path=yes])
|
||||||
|
|
||||||
|
AC_ARG_WITH(rtc-date,
|
||||||
|
AS_HELP_STRING([--with-rtc-date=DATE], [If RTC date/time is too old, restore to DATE, format "YYYY-MM-DD HH:MM:SS", default "2000-01-01 00:00:00"]),
|
||||||
|
[rtc_date=$withval], [rtc_date=no])
|
||||||
|
|
||||||
|
AC_ARG_WITH(rtc-file,
|
||||||
|
AS_HELP_STRING([--with-rtc-file=FILE], [If RTC is missing, save and restore system clock from this file, default: no]),
|
||||||
|
[rtc_file=$withval], [rtc_file=no])
|
||||||
|
|
||||||
### Enable features ###########################################################################
|
### Enable features ###########################################################################
|
||||||
|
|
||||||
@@ -161,6 +203,22 @@ AS_IF([test "x$enable_auto_reload" = "xyes"], [
|
|||||||
AS_IF([test "x$enable_kernel_cmdline" = "xyes"], [
|
AS_IF([test "x$enable_kernel_cmdline" = "xyes"], [
|
||||||
AC_DEFINE(KERNEL_CMDLINE, 1, [Dumpster diving after init args from /proc/cmdline])])
|
AC_DEFINE(KERNEL_CMDLINE, 1, [Dumpster diving after init args from /proc/cmdline])])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_kernel_logging" = "xyes"], [
|
||||||
|
AC_DEFINE(KERNEL_LOGGING, 1, [Keep kernel warn/err logs to console])])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_cgroup" = "xyes"], [
|
||||||
|
AC_DEFINE(CGROUP2_ENABLED, 1, [Autodetect cgroup v2 support from /sys/fs/cgroup])])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_libcap" = "xyes"], [
|
||||||
|
AC_CHECK_LIB([cap], [cap_from_text], [
|
||||||
|
AC_DEFINE(HAVE_LIBCAP, 1, [Have libcap for Linux capabilities support])
|
||||||
|
LIBS="$LIBS -lcap"
|
||||||
|
], [
|
||||||
|
AC_MSG_WARN([libcap not found, capabilities support disabled])
|
||||||
|
enable_libcap=no
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
AS_IF([test "x$enable_fastboot" = "xyes"], [
|
AS_IF([test "x$enable_fastboot" = "xyes"], [
|
||||||
AC_DEFINE(FAST_BOOT, 1, [Skip fsck check on filesystems listed in /etc/fstab])])
|
AC_DEFINE(FAST_BOOT, 1, [Skip fsck check on filesystems listed in /etc/fstab])])
|
||||||
|
|
||||||
@@ -174,9 +232,18 @@ AS_IF([test "x$enable_redirect" = "xyes"], [
|
|||||||
AS_IF([test "x$enable_logrotate" != "xno"], [
|
AS_IF([test "x$enable_logrotate" != "xno"], [
|
||||||
AC_DEFINE(LOGROTATE_ENABLED, 1, [Enable built-in rotation of /var/log/wtmp et al.])])
|
AC_DEFINE(LOGROTATE_ENABLED, 1, [Enable built-in rotation of /var/log/wtmp et al.])])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_rescue" != "xno"], [
|
||||||
|
AC_DEFINE([RESCUE_MODE], 1, [Define to enable support for rescue mode.])])
|
||||||
|
|
||||||
AM_CONDITIONAL(LOGROTATE, [test "x$enable_logrotate" = "xyes"])
|
AM_CONDITIONAL(LOGROTATE, [test "x$enable_logrotate" = "xyes"])
|
||||||
|
|
||||||
### With features ##############################################################################
|
### With features ##############################################################################
|
||||||
|
AS_IF([test "x$bash_dir" = "xyes"], [
|
||||||
|
PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0],
|
||||||
|
[BASH_DIR="$(pkg-config --variable=completionsdir bash-completion)"],
|
||||||
|
[BASH_DIR="$datadir/bash-completion/completions"])], [
|
||||||
|
BASH_DIR="$bash_dir"])
|
||||||
|
|
||||||
AS_IF([test "x$with_fstab" != "xno"], [
|
AS_IF([test "x$with_fstab" != "xno"], [
|
||||||
AS_IF([test "x$fstab" = "xyes"], [fstab=$sysconfdir/fstab])
|
AS_IF([test "x$fstab" = "xyes"], [fstab=$sysconfdir/fstab])
|
||||||
AC_EXPAND_DIR(fstab_path, "$fstab")
|
AC_EXPAND_DIR(fstab_path, "$fstab")
|
||||||
@@ -198,10 +265,9 @@ AC_DEFINE_UNQUOTED(FINIT_RCSD, "$rcsd_path", [Finit rcS.d/, default /etc/finit.d
|
|||||||
AC_SUBST(FINIT_RCSD, "$rcsd_path")
|
AC_SUBST(FINIT_RCSD, "$rcsd_path")
|
||||||
|
|
||||||
AS_IF([test "x$with_rc_local" != "xno"], [
|
AS_IF([test "x$with_rc_local" != "xno"], [
|
||||||
AS_IF([test "x$rclocal" = "xyes"], [
|
AS_IF([test "x$rclocal" = "xyes"], [rclocal=$sysconfdir/rc.local])
|
||||||
rclocal=$sysconfdir/rc.local])])
|
AC_EXPAND_DIR(rclocal_path, "$rclocal")
|
||||||
AC_EXPAND_DIR(rclocal_path, "$rclocal")
|
AC_DEFINE_UNQUOTED(FINIT_RC_LOCAL, "$rclocal_path", [Compat SysV /etc/rc.local file to run last at boot.])])
|
||||||
AC_DEFINE_UNQUOTED(FINIT_RC_LOCAL, "$rclocal_path", [Compat SysV /etc/rc.local file to run last at boot.])
|
|
||||||
|
|
||||||
AS_IF([test "x$with_sysconfig" != "xno"], [
|
AS_IF([test "x$with_sysconfig" != "xno"], [
|
||||||
AS_IF([test "x$sysconfig" != "xdefault"], [
|
AS_IF([test "x$sysconfig" != "xdefault"], [
|
||||||
@@ -235,9 +301,25 @@ AS_IF([test "x$with_random_seed" != "xno"], [
|
|||||||
AC_EXPAND_DIR(random_path, "$random_seed")
|
AC_EXPAND_DIR(random_path, "$random_seed")
|
||||||
AC_DEFINE_UNQUOTED(RANDOMSEED, "$random_path", [Improve random at boot by seeding it with sth from before.])])
|
AC_DEFINE_UNQUOTED(RANDOMSEED, "$random_path", [Improve random at boot by seeding it with sth from before.])])
|
||||||
|
|
||||||
|
AS_IF([test "x$rtc_date" != "xno"], [
|
||||||
|
AC_DEFINE_UNQUOTED(RTC_TIMESTAMP_CUSTOM, "$rtc_date", [Custom RTC restore date, default: 2000-01-01 00:00])], [
|
||||||
|
rtc_date=""])
|
||||||
|
|
||||||
|
AS_IF([test "x$rtc_file" != "xno"], [
|
||||||
|
AS_IF([test "x$rtc_file" = "xyes"], [
|
||||||
|
rtc_file=/var/lib/misc/rtc])
|
||||||
|
AC_EXPAND_DIR(rtcfile_path, "$rtc_file")
|
||||||
|
AC_DEFINE_UNQUOTED(RTC_FILE, "$rtcfile_path", [Save and restore system time from this file if /dev/rtc is missing.])],[
|
||||||
|
AC_DEFINE_UNQUOTED(RTC_FILE, NULL)])
|
||||||
|
|
||||||
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
|
AS_IF([test "x$with_keventd" != "xno"], [with_keventd=yes])
|
||||||
|
|
||||||
AS_IF([test "x$with_sulogin" != "xno"], [with_sulogin=yes])
|
AS_IF([test "x$with_sulogin" != "xno"], [
|
||||||
|
AS_IF([test "x$sulogin" = "xyes"], [
|
||||||
|
sulogin=root])
|
||||||
|
with_sulogin=yes
|
||||||
|
AC_DEFINE_UNQUOTED(SULOGIN_USER, "$sulogin", [Built-in sulogin user, default: root])], [
|
||||||
|
sulogin=])
|
||||||
|
|
||||||
AS_IF([test "x$with_watchdog" != "xno"], [
|
AS_IF([test "x$with_watchdog" != "xno"], [
|
||||||
AS_IF([test "x$watchdog" = "xyes"], [
|
AS_IF([test "x$watchdog" = "xyes"], [
|
||||||
@@ -246,37 +328,74 @@ AS_IF([test "x$with_watchdog" != "xno"], [
|
|||||||
AC_DEFINE_UNQUOTED(WDT_DEVNODE, "$watchdog", [Built-in watchdog device node])], [
|
AC_DEFINE_UNQUOTED(WDT_DEVNODE, "$watchdog", [Built-in watchdog device node])], [
|
||||||
watchdog=])
|
watchdog=])
|
||||||
|
|
||||||
AS_IF([test "x$enable_hook_scripts_plugin" = "xyes" -a "x$with_hook_scripts_path" != "xno"], [
|
AS_IF([test "x$with_libsystemd" != "xno"], [
|
||||||
|
AC_DEFINE(HAVE_LIBSYSTEMD, 1, [Build replacement libsystemd library support])])
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_hook_scripts_plugin" != "xno"], [
|
||||||
AS_IF([test "x$hook_scripts_path" = "xyes"], [hook_scripts_path=$libexecdir/finit/hook])
|
AS_IF([test "x$hook_scripts_path" = "xyes"], [hook_scripts_path=$libexecdir/finit/hook])
|
||||||
AC_EXPAND_DIR(hook_scripts_path, "$hook_scripts_path")
|
AC_EXPAND_DIR(hook_scripts_path, "$hook_scripts_path")
|
||||||
AC_DEFINE_UNQUOTED(PLUGIN_HOOK_SCRIPTS_PATH, "$hook_scripts_path", [Built-in default: $libexecdir/finit])])
|
AC_DEFINE_UNQUOTED(PLUGIN_HOOK_SCRIPTS_PATH, "$hook_scripts_path", [Built-in default: $libexecdir/finit])])
|
||||||
|
|
||||||
|
AS_IF([test "x$with_plugin_path" != "xno"], [
|
||||||
|
AS_IF([test "x$plugin_path" = "xyes"], [plugin_path=/usr/lib/finit/plugins:/usr/local/lib/finit/plugins])
|
||||||
|
AC_EXPAND_DIR(plugin_path, "$plugin_path")
|
||||||
|
AC_DEFINE_UNQUOTED(EXTERNAL_PLUGIN_PATH, "$plugin_path", [Built-in default: /usr/lib/finit/plugins:/usr/local/lib/finit/plugins])])
|
||||||
|
|
||||||
# Control build with automake flags
|
# Control build with automake flags
|
||||||
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
|
AM_CONDITIONAL(BASH, [test "x$bash_dir" != "xno"])
|
||||||
AM_CONDITIONAL(KEVENTD, [test "x$with_keventd" != "xno"])
|
AM_CONDITIONAL(STATIC, [test "x$enable_static" = "xyes"])
|
||||||
AM_CONDITIONAL(SULOGIN, [test "x$with_sulogin" != "xno"])
|
AM_CONDITIONAL(KEVENTD, [test "x$with_keventd" != "xno"])
|
||||||
AM_CONDITIONAL(WATCHDOGD, [test "x$with_watchdog" != "xno"])
|
AM_CONDITIONAL(SULOGIN, [test "x$with_sulogin" != "xno"])
|
||||||
AM_CONDITIONAL(DOC, [test "x$enable_doc" = "xyes"])
|
AM_CONDITIONAL(WATCHDOGD, [test "x$with_watchdog" != "xno"])
|
||||||
AM_CONDITIONAL(CONTRIB, [test "x$enable_contrib" = "xyes"])
|
AM_CONDITIONAL(LIBSYSTEMD, [test "x$with_libsystemd" != "xno"])
|
||||||
|
AM_CONDITIONAL(DOC, [test "x$enable_doc" = "xyes"])
|
||||||
|
AM_CONDITIONAL(CONTRIB, [test "x$enable_contrib" = "xyes"])
|
||||||
|
AM_CONDITIONAL(TESTSERV, [test "x$enable_testserv_plugin" = "xyes"])
|
||||||
|
|
||||||
|
# Workaround for as-of-yet unreleased runstatedir support, planned for
|
||||||
|
# autoconf 2.70, which some major distros have backported.
|
||||||
|
AS_IF([test -z "$runstatedir"], runstatedir="$localstatedir/run")
|
||||||
|
AC_SUBST(runstatedir)
|
||||||
|
|
||||||
# Override default libdir, used for plugins and rescue.conf
|
# Override default libdir, used for plugins and rescue.conf
|
||||||
pkglibdir=$libdir/finit
|
pkglibdir=$libdir/finit
|
||||||
AC_SUBST(pkglibexecdir)
|
AC_SUBST(pkglibexecdir)
|
||||||
AC_EXPAND_DIR(pkglibexecdir, "$libexecdir/finit")
|
AC_EXPAND_DIR(pkglibexecdir, "$libexecdir/finit")
|
||||||
AC_DEFINE_UNQUOTED(FINIT_LIBPATH_, "$pkglibexecdir", [Finit libexec path])
|
AC_DEFINE_UNQUOTED(FINIT_EXECPATH_, "$pkglibexecdir", [Finit libexec path])
|
||||||
|
AC_EXPAND_DIR(finit_runpath, "$runstatedir/finit/system")
|
||||||
|
AC_DEFINE_UNQUOTED(FINIT_RUNPATH_, "$finit_runpath", [Finit runtime dynamic system services])
|
||||||
|
|
||||||
AC_EXPAND_DIR(plugin_path, "$libdir/finit/plugins")
|
AC_EXPAND_DIR(plugin_path, "$pkglibdir/plugins")
|
||||||
AC_SUBST(plugin_path)
|
AC_SUBST(plugin_path)
|
||||||
AC_DEFINE_UNQUOTED(PLUGIN_PATH, "$plugin_path", [Finit plugin path])
|
AC_DEFINE_UNQUOTED(PLUGIN_PATH, "$plugin_path", [Finit plugin path])
|
||||||
|
|
||||||
AC_EXPAND_DIR(rescue_conf, "$libdir/finit/rescue.conf")
|
AC_EXPAND_DIR(tmpfiles_path, "$libdir/tmpfiles.d")
|
||||||
|
AC_SUBST(tmpfiles_path)
|
||||||
|
AC_DEFINE_UNQUOTED(TMPFILES_PATH_, "$tmpfiles_path", [Main tmpfiles.d/, override in /etc])
|
||||||
|
|
||||||
|
AC_EXPAND_DIR(finit_tmpfiles, "$pkglibdir/tmpfiles.d")
|
||||||
|
AC_SUBST(finit_tmpfiles)
|
||||||
|
AC_DEFINE_UNQUOTED(FINIT_TMPFILES, "$finit_tmpfiles", [Finit tmpfiles.d/ .conf path])
|
||||||
|
|
||||||
|
AC_EXPAND_DIR(system_path, "$pkglibdir/system")
|
||||||
|
AC_SUBST(system_path)
|
||||||
|
AC_DEFINE_UNQUOTED(FINIT_SYSPATH_, "$system_path", [Static services, previously generated at runtime by plugins])
|
||||||
|
|
||||||
|
AC_EXPAND_DIR(rescue_conf, "$pkglibdir/rescue.conf")
|
||||||
AC_DEFINE_UNQUOTED(RESCUE_CONF, "$rescue_conf", [Finit rescue mode .conf])
|
AC_DEFINE_UNQUOTED(RESCUE_CONF, "$rescue_conf", [Finit rescue mode .conf])
|
||||||
AC_EXPAND_DIR(sample_conf, "$libdir/finit/sample.conf")
|
AC_EXPAND_DIR(sample_conf, "$pkglibdir/sample.conf")
|
||||||
AC_DEFINE_UNQUOTED(SAMPLE_CONF, "$sample_conf", [Finit sameple.conf for initctl create])
|
AC_DEFINE_UNQUOTED(SAMPLE_CONF, "$sample_conf", [Finit sameple.conf for initctl create])
|
||||||
|
|
||||||
|
AC_EXPAND_DIR(bash_completion_dir, "$BASH_DIR")
|
||||||
|
AC_SUBST(BASH_DIR, "$bash_completion_dir")
|
||||||
|
|
||||||
AS_IF([test "$heading" = ""], [heading="<DEFAULT>"])
|
AS_IF([test "$heading" = ""], [heading="<DEFAULT>"])
|
||||||
AS_IF([test "$heading" = "no"], [heading="<NONE>"])
|
AS_IF([test "$heading" = "no"], [heading="<NONE>"])
|
||||||
|
|
||||||
|
RTC_DATE=$rtc_date
|
||||||
|
AS_IF([test "$rtc_date" = ""], [RTC_DATE="<DEFAULT>"])
|
||||||
|
AS_IF([test "$rtc_date" = "no"], [RTC_DATE="<DEFAULT>"])
|
||||||
|
|
||||||
# Generate all files
|
# Generate all files
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
@@ -284,15 +403,16 @@ cat <<EOF
|
|||||||
|
|
||||||
------------------ Summary ------------------
|
------------------ Summary ------------------
|
||||||
$PACKAGE_NAME version $PACKAGE_VERSION
|
$PACKAGE_NAME version $PACKAGE_VERSION
|
||||||
Prefix................: $prefix
|
Prefix................: $(eval echo $prefix)
|
||||||
Exec prefix...........: $eprefix
|
Exec prefix...........: $(eval echo $exec_prefix)
|
||||||
|
Libdir................: $(eval echo $libdir)
|
||||||
Sysconfdir............: `eval echo $sysconfdir`
|
Sysconfdir............: `eval echo $sysconfdir`
|
||||||
Localstatedir.........: `eval echo $localstatedir`
|
Localstatedir.........: `eval echo $localstatedir`
|
||||||
Default fstab.........: `eval echo $fstab`
|
Default fstab.........: `eval echo $fstab`
|
||||||
Finit config file.....: $conf_path
|
Finit config file.....: $conf_path
|
||||||
Finit config.d path...: $rcsd_path
|
Finit config.d path...: $rcsd_path
|
||||||
Finit plugin path.....: $plugin_path
|
Finit plugin path.....: $plugin_path
|
||||||
Compat rc.local path..: $rclocal_path
|
Compat rc.local path..: `eval echo $rclocal`
|
||||||
System environment....: ${sysconfig_path:-${sysconfig}}
|
System environment....: ${sysconfig_path:-${sysconfig}}
|
||||||
Random seed path......: $random_path
|
Random seed path......: $random_path
|
||||||
C Compiler............: $CC $CFLAGS $CPPFLAGS $LDFLAGS $LIBS
|
C Compiler............: $CC $CFLAGS $CPPFLAGS $LDFLAGS $LIBS
|
||||||
@@ -301,17 +421,26 @@ cat <<EOF
|
|||||||
Behavior:
|
Behavior:
|
||||||
Boot heading..........: $heading
|
Boot heading..........: $heading
|
||||||
Plugins...............: $plugins
|
Plugins...............: $plugins
|
||||||
|
RTC restore date......: $RTC_DATE
|
||||||
|
RTC fallback file.....: $rtc_file
|
||||||
|
|
||||||
Optional features:
|
Optional features:
|
||||||
Install doc/..........: $enable_doc
|
Install doc/..........: $enable_doc
|
||||||
Install contrib/......: $enable_contrib
|
Install contrib/......: $enable_contrib
|
||||||
|
Bash completion.......: $bash_completion_dir
|
||||||
Built-in keventd......: $with_keventd
|
Built-in keventd......: $with_keventd
|
||||||
Built-in sulogin......: $with_sulogin
|
Built-in sulogin......: $with_sulogin $sulogin
|
||||||
Built-in watchdogd....: $with_watchdog $watchdog
|
Built-in watchdogd....: $with_watchdog $watchdog
|
||||||
Built-in logrotate....: $enable_logrotate
|
Built-in logrotate....: $enable_logrotate
|
||||||
|
Replacement libsystemd: $with_libsystemd
|
||||||
|
Use cgroup v2.........: $enable_cgroup
|
||||||
|
Use libcap............: $enable_libcap
|
||||||
|
Parse kernel cmdline..: $enable_kernel_cmdline
|
||||||
|
Keep kernel logging...: $enable_kernel_logging
|
||||||
Skip fsck check.......: $enable_fastboot
|
Skip fsck check.......: $enable_fastboot
|
||||||
Run fsck fix mode.....: $enable_fsckfix
|
Run fsck fix mode.....: $enable_fsckfix
|
||||||
Redirect output.......: $enable_redirect
|
Redirect output.......: $enable_redirect
|
||||||
|
Rescue mode...........: $enable_rescue
|
||||||
Default hostname......: $hostname
|
Default hostname......: $hostname
|
||||||
Default group.........: $group
|
Default group.........: $group
|
||||||
Default runlevel......: $runlevel
|
Default runlevel......: $runlevel
|
||||||
|
|||||||
@@ -3,3 +3,8 @@ bin_SCRIPT = service
|
|||||||
docsdir := @docdir@/contrib
|
docsdir := @docdir@/contrib
|
||||||
docs_DATA = README.md finit.conf procmon.sh
|
docs_DATA = README.md finit.conf procmon.sh
|
||||||
EXTRA_DIST = $(docs_DATA)
|
EXTRA_DIST = $(docs_DATA)
|
||||||
|
|
||||||
|
if BASH
|
||||||
|
bashdir = $(BASH_DIR)
|
||||||
|
dist_bash_DATA = initctl
|
||||||
|
endif
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ install and try out Finit on various Linux distributions.
|
|||||||
|
|
||||||
* [Alpine](alpine/)
|
* [Alpine](alpine/)
|
||||||
* [Debian](debian/)
|
* [Debian](debian/)
|
||||||
|
* [Void](void/)
|
||||||
|
|
||||||
If you have ideas on how to simplify, extend, or even add new example
|
If you have ideas on how to simplify, extend, or even add new example
|
||||||
configurations for other distributions you are most welcome! :)
|
configurations for other distributions you are most welcome! :)
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
HowTo: Finit on Alpine Linux 3.4-3.6
|
HowTo: Finit on Alpine Linux 3.4...3.19
|
||||||
====================================
|
=======================================
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> https://troglobit.com/post/2021-02-12-alpine-linux-with-finit/
|
||||||
|
|
||||||
HowTo use Finit to boot an [Alpine Linux][] system. It is assumed that
|
HowTo use Finit to boot an [Alpine Linux][] system. It is assumed that
|
||||||
the user has already installed make, a compiler, C library header files,
|
the user has already installed make, a compiler, C library header files,
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
|
|||||||
--prefix=/usr --exec-prefix= \
|
--prefix=/usr --exec-prefix= \
|
||||||
--sysconfdir=/etc --localstatedir=/var \
|
--sysconfdir=/etc --localstatedir=/var \
|
||||||
--enable-dbus-plugin --enable-x11-common-plugin \
|
--enable-dbus-plugin --enable-x11-common-plugin \
|
||||||
--enable-alsa-utils-plugin --with-watchdog \
|
--enable-alsa-utils-plugin --without-watchdog \
|
||||||
--with-keventd
|
--with-keventd --with-sulogin
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "*** Building ..."
|
echo "*** Building ..."
|
||||||
@@ -35,4 +35,3 @@ fi
|
|||||||
echo
|
echo
|
||||||
echo "*** Done"
|
echo "*** Done"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
SUBDIRS = available
|
SUBDIRS = available
|
||||||
docsdir := @docdir@/contrib/alpine/finit.d
|
docsdir := @docdir@/contrib/alpine/finit.d
|
||||||
d_LINKS = acpid.conf crond.conf dropbear.conf getty.conf \
|
d_LINKS = acpid.conf crond.conf dropbear.conf getty.conf \
|
||||||
keymap.conf modules.conf ntpd.conf \
|
keymap.conf modules.conf ntpd.conf syslogd.conf
|
||||||
klogd.conf syslogd.conf
|
|
||||||
|
|
||||||
install-exec-hook:
|
install-exec-hook:
|
||||||
@$(MKDIR_P) $(DESTDIR)$(docsdir)/available
|
@$(MKDIR_P) $(DESTDIR)$(docsdir)/available
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
docsdir := @docdir@/contrib/alpine/finit.d/available
|
docsdir := @docdir@/contrib/alpine/finit.d/available
|
||||||
docs_DATA = acpid.conf crond.conf dropbear.conf getty.conf keymap.conf \
|
docs_DATA = acpid.conf crond.conf dropbear.conf getty.conf keymap.conf \
|
||||||
lxdm.conf modules.conf ntpd.conf syslog.conf watchdog.conf
|
lxdm.conf modules.conf ntpd.conf syslogd.conf watchdog.conf
|
||||||
EXTRA_DIST = $(docs_DATA)
|
EXTRA_DIST = $(docs_DATA)
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
#module evdev
|
#module evdev
|
||||||
#module mousedev
|
#module mousedev
|
||||||
#module 8139cp
|
#module 8139cp
|
||||||
module softdog
|
#module softdog
|
||||||
|
|||||||
@@ -1,45 +1,53 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ "x`id -u`" != "x0" ]; then
|
if [ "$(id -u)" != "0" ]; then
|
||||||
echo
|
printf "\n\e[1m*** This script must run as root\e[0m\n\n"
|
||||||
echo "*** This script must run as root"
|
|
||||||
echo
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# shellcheck disable=SC3037,SC3045,SC2154
|
||||||
|
yorn()
|
||||||
|
{
|
||||||
|
printf "\e[1m> %s (y/N)?\e[0m " "$*"
|
||||||
|
read -rn1 yorn
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ "$yorn" = "y" ] || [ "$yorn" = "Y" ]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# Adjust base directory
|
# Adjust base directory
|
||||||
grep -q alpine Makefile 2>/dev/null
|
if grep -q contrib/alpine Makefile 2>/dev/null; then
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
cd ../..
|
cd ../..
|
||||||
elif [ ! -e configure.ac ]; then
|
fi
|
||||||
echo "*** Please run this script from the Finit base directory."
|
|
||||||
|
if [ ! -e configure.ac ]; then
|
||||||
|
printf "\n\e[1m*** Please run this script from the Finit base directory.\e[0m\n"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
printf "\n\e[1mInstall Finit on Alpine Linux\n"
|
||||||
echo "*** Install Finit on Alpine Linux"
|
printf "========================================================================\e[0m\n"
|
||||||
echo "========================================================================"
|
printf "/sbin/finit - PID 1\n"
|
||||||
echo "/sbin/finit - PID 1"
|
printf "/lib/finit/plugins/* - All enabled Finit plugins\n"
|
||||||
echo "/lib/finit/plugins/* - All enabled Finit plugins"
|
printf "/etc/finit.conf - Finit configuration file\n"
|
||||||
echo "/etc/finit.conf - Finit configuration file"
|
printf "/etc/finit.d/ - Finit services\n"
|
||||||
echo "/etc/finit.d/ - Finit services"
|
|
||||||
echo
|
|
||||||
read -p "Do you want to continue (y/N)? " yorn
|
|
||||||
|
|
||||||
if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
|
if yorn "Do you want to continue"; then
|
||||||
echo
|
printf "\n\e[1m*** Installing Finit files ...\e[0m\n"
|
||||||
echo "*** Installing Finit files ..."
|
|
||||||
make install
|
make install
|
||||||
cd /usr/share/doc/finit/contrib/alpine
|
cd /usr/share/doc/finit/contrib/alpine || exit 1
|
||||||
for file in finit.conf rc.local; do
|
for file in finit.conf rc.local; do
|
||||||
install -vbD $file /etc/$file
|
install -vbD $file /etc/$file
|
||||||
done
|
done
|
||||||
cp -va finit.d /etc/
|
cp -va finit.d /etc/
|
||||||
|
|
||||||
read -p "*** Install Finit as the system default Init (y/N)? " yorn
|
if yorn "Install Finit as the system default Init"; then
|
||||||
if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
|
printf "\e[1m*** Updating /sbin/init symlink --> finit ...\e[0m\n"
|
||||||
echo "*** Updating /sbin/init symlink --> finit ..."
|
cd /sbin || exit 1
|
||||||
cd /sbin
|
|
||||||
rm init
|
rm init
|
||||||
ln -s finit init
|
ln -s finit init
|
||||||
|
|
||||||
@@ -48,10 +56,8 @@ if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
|
|||||||
ln -s reboot shutdown
|
ln -s reboot shutdown
|
||||||
ln -s reboot suspend
|
ln -s reboot suspend
|
||||||
fi
|
fi
|
||||||
echo "*** Done"
|
printf "\n\e[1m*** Done\e[0m\n"
|
||||||
echo
|
echo
|
||||||
else
|
else
|
||||||
echo
|
printf "\n\e[1m*** Aborting install.\e[0m\n\n"
|
||||||
echo "*** Aborting install."
|
|
||||||
echo
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ tools pre-systemd work as intended.
|
|||||||
|
|
||||||
root@debian:~# apt install initscripts console-setup
|
root@debian:~# apt install initscripts console-setup
|
||||||
|
|
||||||
> **Note:** as of Debian 11 (Bullseye), libuev and libite are part of
|
> [!TIP]
|
||||||
> the main section of Debian. So just install the -dev packages :)
|
> As of Debian 11 (Bullseye), libuev and libite are part of the main
|
||||||
|
> section of Debian. So just install the -dev packages :)
|
||||||
|
|
||||||
The following script can then be used to configure, build, install and
|
The following script can then be used to configure, build, install and
|
||||||
set up your system to run Finit:
|
set up your system to run Finit:
|
||||||
@@ -47,7 +48,8 @@ comands to `initctl`, followed by `reload` to activate your changes.
|
|||||||
You can also use a standard [/etc/rc.local](rc.local) for one-shot tasks
|
You can also use a standard [/etc/rc.local](rc.local) for one-shot tasks
|
||||||
and initialization like keyboard language etc.
|
and initialization like keyboard language etc.
|
||||||
|
|
||||||
> **NOTE:** X Window system, you may need to `sudo apt install elogind`
|
> [!NOTE]
|
||||||
|
> For the X Window system, you may need to `sudo apt install elogind`
|
||||||
> (Bullseye and later), followed by `initctl reload` to activate it (it
|
> (Bullseye and later), followed by `initctl reload` to activate it (it
|
||||||
> is enabled by default), and logout/login again. The elogind daemon
|
> is enabled by default), and logout/login again. The elogind daemon
|
||||||
> ensures a regular non-root user can start and interact with an X
|
> ensures a regular non-root user can start and interact with an X
|
||||||
|
|||||||
@@ -59,6 +59,3 @@ else
|
|||||||
echo "*** Use 'sudo contrib/debian/install.sh' later to install Finit"
|
echo "*** Use 'sudo contrib/debian/install.sh' later to install Finit"
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# On some systems, bootstrap can be really quick and cause elogind
|
# On some systems, bootstrap can be really quick and cause elogind
|
||||||
# to not start before a user has managed to log in. To prevent
|
# to not start before a user has managed to log in. To prevent
|
||||||
# this, add <pid/elogind> as condition to your TTYs in getty.conf
|
# this, add <pid/elogind> as condition to your TTYs in getty.conf
|
||||||
service [2345] <pid/syslogd> /lib/elogind/elogind -- Login manager
|
service [2345] <pid/syslogd> /usr/libexec/elogind -- Login manager
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
_cond()
|
||||||
|
{
|
||||||
|
initctl -pt cond dump | awk '{print $4}' | sed 's/<\(.*\)>/\1/'
|
||||||
|
}
|
||||||
|
|
||||||
|
_ident()
|
||||||
|
{
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
initctl ident | grep -q $1
|
||||||
|
else
|
||||||
|
initctl ident
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_svc()
|
||||||
|
{
|
||||||
|
initctl ls -pt | grep $1 | sed "s/.*\/\(.*\)/\1/g" | sort -u
|
||||||
|
}
|
||||||
|
|
||||||
|
_enabled()
|
||||||
|
{
|
||||||
|
echo "$(_svc enabled)"
|
||||||
|
}
|
||||||
|
|
||||||
|
_available()
|
||||||
|
{
|
||||||
|
all=$(mktemp)
|
||||||
|
ena=$(mktemp)
|
||||||
|
echo "$(_svc available)" >$all
|
||||||
|
echo "$(_svc enabled)" >$ena
|
||||||
|
grep -v -f $ena $all
|
||||||
|
rm $all $ena
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine first non-option word. Usually the command
|
||||||
|
_firstword() {
|
||||||
|
local firstword i
|
||||||
|
|
||||||
|
firstword=
|
||||||
|
for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
|
||||||
|
if [[ ${COMP_WORDS[i]} != -* ]]; then
|
||||||
|
firstword=${COMP_WORDS[i]}
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $firstword
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine last non-option word. Uusally a sub-command
|
||||||
|
_lastword() {
|
||||||
|
local lastword i
|
||||||
|
|
||||||
|
lastword=
|
||||||
|
for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do
|
||||||
|
if [[ ${COMP_WORDS[i]} != -* ]] && [[ -n ${COMP_WORDS[i]} ]] && [[ ${COMP_WORDS[i]} != $cur ]]; then
|
||||||
|
lastword=${COMP_WORDS[i]}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo $lastword
|
||||||
|
}
|
||||||
|
|
||||||
|
_initctl()
|
||||||
|
{
|
||||||
|
local cur command
|
||||||
|
|
||||||
|
cur=${COMP_WORDS[COMP_CWORD]}
|
||||||
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
firstword=$(_firstword)
|
||||||
|
lastword=$(_lastword)
|
||||||
|
|
||||||
|
commands="status cond debug help kill ls log version list enable \
|
||||||
|
disable touch show cat edit create delete reload start \
|
||||||
|
stop restart signal cgroup ps top plugins runlevel reboot \
|
||||||
|
halt poweroff suspend utmp"
|
||||||
|
cond_cmds="set get clear status dump"
|
||||||
|
cond_types="hook net pid service task usr"
|
||||||
|
signals="int term hup stop tstp cont usr1 usr2 pwr"
|
||||||
|
options="-b --batch \
|
||||||
|
-c --create \
|
||||||
|
-d --debug \
|
||||||
|
-f --force \
|
||||||
|
-h --help \
|
||||||
|
-j --json \
|
||||||
|
-n --noerr \
|
||||||
|
-1 --once \
|
||||||
|
-p --plain \
|
||||||
|
-q --quiet \
|
||||||
|
-t --no-heading \
|
||||||
|
-v --verbose \
|
||||||
|
-V --version"
|
||||||
|
|
||||||
|
case "${firstword}" in
|
||||||
|
enable)
|
||||||
|
COMPREPLY=($(compgen -W "$(_available)" -- $cur))
|
||||||
|
;;
|
||||||
|
disable|touch)
|
||||||
|
COMPREPLY=($(compgen -W "$(_enabled)" -- $cur))
|
||||||
|
;;
|
||||||
|
show|cat|edit|delete)
|
||||||
|
COMPREPLY=($(compgen -W "$(_svc .)" -- $cur))
|
||||||
|
;;
|
||||||
|
start|stop|restart|log|status)
|
||||||
|
COMPREPLY=($(compgen -W "$(_ident)" -- $cur))
|
||||||
|
;;
|
||||||
|
signal|kill)
|
||||||
|
if $(_ident "${prev}"); then
|
||||||
|
COMPREPLY=($(compgen -W "$signals" -- $cur))
|
||||||
|
else
|
||||||
|
COMPREPLY=($(compgen -W "$(_ident)" -- $cur))
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
cond)
|
||||||
|
case "${lastword}" in
|
||||||
|
set|clear)
|
||||||
|
compopt -o nospace
|
||||||
|
COMPREPLY=($(compgen -W "usr/" -- $cur))
|
||||||
|
;;
|
||||||
|
get)
|
||||||
|
COMPREPLY=($(compgen -W "$(_cond)" -- $cur))
|
||||||
|
;;
|
||||||
|
dump)
|
||||||
|
COMPREPLY=($(compgen -W "$cond_types" -- $cur))
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
COMPREPLY=($(compgen -W "$cond_cmds" -- $cur))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
COMPREPLY=($(compgen -W "$commands" -- $cur))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ $cur == -* ]]; then
|
||||||
|
COMPREPLY=($(compgen -W "$options" -- $cur))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _initctl initctl
|
||||||
@@ -18,7 +18,7 @@ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/lib/pkgconfig ./configure \
|
|||||||
--sysconfdir=/etc --localstatedir=/var \
|
--sysconfdir=/etc --localstatedir=/var \
|
||||||
--enable-dbus-plugin --enable-x11-common-plugin \
|
--enable-dbus-plugin --enable-x11-common-plugin \
|
||||||
--enable-alsa-utils-plugin --with-watchdog \
|
--enable-alsa-utils-plugin --with-watchdog \
|
||||||
--with-keventd
|
--with-keventd --with-sulogin
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "*** Building ..."
|
echo "*** Building ..."
|
||||||
@@ -35,4 +35,3 @@ fi
|
|||||||
echo
|
echo
|
||||||
echo "*** Done"
|
echo "*** Done"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,859 @@ Change Log
|
|||||||
|
|
||||||
All relevant changes are documented in this file.
|
All relevant changes are documented in this file.
|
||||||
|
|
||||||
|
[4.17][] - 2026-04-28
|
||||||
|
---------------------
|
||||||
|
|
||||||
[4.3][UNRELEASED]
|
### Changes
|
||||||
|
|
||||||
|
- Add Plymouth boot splash plugin to manage the `plymouthd` lifecycle across boot,
|
||||||
|
`switch_root`, and shutdown. Activated by the `splash` kernel command line
|
||||||
|
argument. By Aaron Andersen
|
||||||
|
- Add `tty:` option for run/task/service stanzas to acquire a controlling
|
||||||
|
terminal. The device is opened as stdin, set as the session's controlling TTY
|
||||||
|
via `TIOCSCTTY`, and `TERM` is set automatically — `linux` for virtual terminals
|
||||||
|
and `vt102` for serial lines. By Ollie Gutierrez
|
||||||
|
- Improve console output atomicity at boot and shutdown: description and status
|
||||||
|
(`[ OK ]` / `[FAIL]`) are emitted in a single write so kernel messages cannot
|
||||||
|
split them. If output has been scrolled away, the description is re-printed
|
||||||
|
before the final status line. Console buffer is drained with `tcdrain(2)` and
|
||||||
|
ANSI attributes are reset before handing control back to the kernel at
|
||||||
|
shutdown/reboot
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- Fix reverse-dependency condition handling on reload: when a service without
|
||||||
|
SIGHUP support is reloaded, its condition is now cleared immediately so
|
||||||
|
dependents transition to `STOPPING` before `SIGTERM` is sent to the parent,
|
||||||
|
preventing them from crashing with an incremented restart counter
|
||||||
|
- Fix `/var/tmp` mode in `tmpfiles.d/var.conf` from `0777` to `1777` (sticky bit)
|
||||||
|
to match `/tmp`, by Aaron Andersen
|
||||||
|
- Fix potential memory corruption in config parser: stale pointer captures of
|
||||||
|
`PATH` and `SHELL` at startup could dangle after environment modification;
|
||||||
|
`conf_reset_env()` now reads from the live environment instead, by Vasily Zubko
|
||||||
|
- Fix plugin name registration: replace `__FILE__` macro with explicit string
|
||||||
|
literals in all plugin structs and debug messages, preventing subtle build-
|
||||||
|
system–dependent macro expansion issues, by Vasily Zubko
|
||||||
|
|
||||||
|
|
||||||
|
[4.16][] - 2026-02-27
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
- Add `initctl switch-root` command and plugin hook point. Useful for
|
||||||
|
systems requiring early boot tasks like LUKS unlock, LVM activation,
|
||||||
|
or network boot before mounting the real root, by Aaron Andersen
|
||||||
|
- Set USER and LOGNAME environment variables when dropping privileges.
|
||||||
|
Fixes issues with software like rootless Podman that determines user
|
||||||
|
identity from environment variables, by Aaron Andersen
|
||||||
|
- Add `remain:yes` option for run/task oneshot commands, similar to the
|
||||||
|
systemd `RemainAfterExit=yes`, by Aaron Andersen
|
||||||
|
- Clear service conditions on `initctl reload NAME` to ensure dependent
|
||||||
|
services are properly updated
|
||||||
|
- Run service `stop:` and `reload:` scripts as non-blocking processes,
|
||||||
|
preventing Finit from stalling on long-running helper scripts
|
||||||
|
- Guard shutdown with timer watchdog to detect and debug shutdown hangs
|
||||||
|
- Add `~` condition prefix to propagate reload from a dependency to the
|
||||||
|
dependent service. E.g., `<!~pid/netd>` means not only a regular
|
||||||
|
condition, but when `netd` reloads, restart this service too. Similar
|
||||||
|
to systemd's directive `PropagatesReloadTo=`, but declared on the
|
||||||
|
consumer side. Issue #416
|
||||||
|
- `tmpfiles`: add support for `-E` and `--exclude-prefix` flags
|
||||||
|
contributed by Aaron Andersen
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #464: invalid user:group examples in cgroups.md
|
||||||
|
- Fix #466: elogind path for Debian-based distros, by Jackie Liu
|
||||||
|
- Fix #467: TTY services stuck in restart state after non-zero exit.
|
||||||
|
Throttling logic introduced in v4.15 had duplicate checks causing
|
||||||
|
infinite timer loop, and TTYs lacked default restart timeout
|
||||||
|
- Fix #475: clear pid condition on service collection to fix stale
|
||||||
|
deps. When a service crashes (SIGKILL), the RUNNING → HALTED path
|
||||||
|
bypasses STOPPING where `cond_clear()` is normally called, leaving
|
||||||
|
dependents stuck
|
||||||
|
- Fix #476: dependents not restarted after SIGHUP reload of service in
|
||||||
|
dependency chain. Add `service_step_all()` at end of reload cycle to
|
||||||
|
guarantee convergence after conditions are reasserted. See also the
|
||||||
|
new `~` condition prefix (above) to propagate reload to dependents
|
||||||
|
- Fix #478: fix `<dev/foo>` conditions at boot, conditions that exist
|
||||||
|
before inotify was set up. Found and fixed by Mattias Walström
|
||||||
|
- Fix reload of SIGHUP-capable services incorrectly disrupting their
|
||||||
|
dependents. E.g., `initctl reload syslogd` would stop dbus, dnsmasq,
|
||||||
|
etc. even though syslogd handles SIGHUP gracefully and its PID persists
|
||||||
|
- Only remove managed pidfiles in service cleanup. For SysV services
|
||||||
|
with `pid:!/path`, the pidfile belongs to the service itself and Finit
|
||||||
|
should not delete it
|
||||||
|
- Silence spurious cgroup warnings for short-lived processes where the
|
||||||
|
kernel reaps the child before cgroup assignment completes
|
||||||
|
- Fix handling of already-mounted cgroups in `cgroup_init()`, can occur
|
||||||
|
after switch_root or in container environments
|
||||||
|
- Improve cgroups documentation clarity, grammar, and examples
|
||||||
|
|
||||||
|
|
||||||
|
[4.15][] - 2026-01-01
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
The Finit project now has a new home page: <https://finit-project.github.io>
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Change default reboot to SOC reset from WDT reset, issue #460
|
||||||
|
- Bump required versions of libite (v2.6.2) and libuev (v2.4.1)
|
||||||
|
- Allow longer service identifiers (`:id`), up to 64 characters
|
||||||
|
- Allow skipping bootstrap wait (180 sec) with Ctrl-C
|
||||||
|
- Unlock `initctl` commands start/stop/restart/reload service during bootstrap,
|
||||||
|
shutdown, and reboot. Also, allow `initctl reload` in bootstrap. This makes
|
||||||
|
it possible to start manual:yes type services at botostrap, for example, which
|
||||||
|
has been a common feature request
|
||||||
|
- Add support for `clone3()` syscall with atomic cgroup assignment, from Linux
|
||||||
|
kernel 5.3+. Eliminates race conditions where forked processes (e.g., logger
|
||||||
|
processes) ended up in wrong cgroups. Falls back to `fork()` on older kernels
|
||||||
|
- Add support for cgroup delegation, useful for, e.g., container runtimes
|
||||||
|
creating sub-groups for the container instance's processes
|
||||||
|
- Add cgroup leaf name override: `cgroup.system,name:udevd` allows using
|
||||||
|
descriptive names like `/system/udevd/` instead of filename derived names
|
||||||
|
like `/system/10-hotplug/`. Syntax supports combining with other options:
|
||||||
|
`cgroup.system,name:foo,delegate,cpu.max:10000`
|
||||||
|
- Add support for Linux capabilities, allowing services to run with minimal
|
||||||
|
required privileges instead of running as root. Uses the modern IAB API
|
||||||
|
(Inheritable, Ambient, Bounding) from libcap. By Aaron Andersen
|
||||||
|
- Add support for supplementary groups for services. Uses the syntax
|
||||||
|
`@user:group,sup1,sup2` to explicitly specify supplementary groups, in
|
||||||
|
addition to reading group membership from `/etc/group`. By Aaron Andersen
|
||||||
|
- Add CPU throttled information to `initctl` output, showing when a service
|
||||||
|
has been throttled due to reaching its CPU quota
|
||||||
|
- Add memory field to `initctl --json` status output for cgroup-enabled
|
||||||
|
services
|
||||||
|
- Default to user and group `root` (UID 0) for services
|
||||||
|
- Always check that service user and group resolve to valid UID/GID pairs,
|
||||||
|
otherwise log error and refuse to start service
|
||||||
|
- Hide cursor at boot and shutdown for cleaner visual experience
|
||||||
|
- Rename `tty` services early from `init` -> `getty` even though no getty
|
||||||
|
process has been started yet. This to aid in boot timing detection using
|
||||||
|
tools like `bootchartd` (BusyBox version or bootchart2 project) when Finit
|
||||||
|
only shows *"Please press Enter to activate this console."*
|
||||||
|
- Services with `respawn` option (including TTYs) now delay retry on non-zero
|
||||||
|
exit codes instead of immediate respawn. Prevents busy-loop when service
|
||||||
|
fails repeatedly, which on some systems may have a crippling effect
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #453: RTC plugin fixes by Ming Liu, Atlas Copco
|
||||||
|
- Fix #455: ANSI escape sequences logged by tools using glib logging,
|
||||||
|
caused by use of PTY instead of pipe for stdout/stderr redirection
|
||||||
|
- Fix #462: `/dev/pts` mounted with wrong mode (400 instead of 620), causing
|
||||||
|
permission issues with pseudo-terminals
|
||||||
|
- getty: fix terminal scrollback issues after login on console TTY. Mouse
|
||||||
|
scroll wheel and Shift+PgUp/PgDn sometimes would not work properly
|
||||||
|
- Fix flickering and artifacts in `initctl top`
|
||||||
|
- Fix file descriptor leak in `initctl top`
|
||||||
|
- Fix incorrect "max" limit reporting in `initctl [top|cgroup|--json]` output
|
||||||
|
for child cgroups. Resolves effective limits by walking the cgroup hierarchy
|
||||||
|
- Fix issue with running Finit under `bootchartd` (bootchart2 project), always
|
||||||
|
set `PATH` and `SHELL` envs early, before attempting to mount `/proc` et al
|
||||||
|
- Always reset ownership and permissions on TTY device nodes before launching getty
|
||||||
|
- Ensure mount/unmount skips `noauto` entries
|
||||||
|
|
||||||
|
|
||||||
|
[4.14][] - 2025-08-29
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Minor bug fix release.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Add exit status/signal info when a process dies, by Mattias Berthel
|
||||||
|
- Extend `service kill:SEC` to support up to 300 sec.
|
||||||
|
- Extend `norespawn` debug to cover `service_retry()`
|
||||||
|
- Build *without* libsystemd replacement by default
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #449: ALSA plugin fail-to-build-from-source
|
||||||
|
- Fix `sysv` stop command process environment, should be same as start
|
||||||
|
- Fix state machine ordering issue: enter new config generation *after*
|
||||||
|
services disabled in previous generation have been stopped
|
||||||
|
|
||||||
|
|
||||||
|
[4.13][] - 2025-07-10
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This release introduce a bare bones `libsystemd` replacement with an
|
||||||
|
> `<systemd/sd-daemon>.h` include file. Other systemd features are the
|
||||||
|
> `reload:script` and `stop:script`, mimicking ExecReload and ExecStop.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- `initctl signal` command has been renamed to `initctl kill`
|
||||||
|
- Drop xz tarballs from distribution, gzip is good enough
|
||||||
|
- New `tmpfiles` stand-alone program, refactored from the existing
|
||||||
|
tmpfiles.d support in Finit, by Aaron Andersen, PR #439
|
||||||
|
- `--remove` command runs only the `r` and `R` rules
|
||||||
|
- `--create` is used for all other cases (bootstrap)
|
||||||
|
- All `notify:systemd` services now log with `logit` by default. This
|
||||||
|
because it supports systemd style log severity, leading `"<NUM>"`
|
||||||
|
- Support for quoted arguments to run/task/service options, issue #441
|
||||||
|
- Clear command line arguments after bootstrap, issue #442
|
||||||
|
- Support for `stop:'script [args]'` to stop a sysv/service instead of
|
||||||
|
the common `foo-stop-start.sh stop`, or `SIGTERM`, issue #412
|
||||||
|
- Support for `reload:'script [args]'` to trigger a configuration
|
||||||
|
reload in a service, issue #446
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #437: buffer overflow in `initctl status`
|
||||||
|
- Fix #438: support very long command lines in `initctl ps/top`
|
||||||
|
- Fix #440: broken systemd and s6 readiness notification
|
||||||
|
- Fix #443: build warnings, by Ming Liu, Atlas Copco
|
||||||
|
- Fix #444: handle loooooong arguments, by Aaron Andersen
|
||||||
|
- Fix service's redirected stdout/stderr log priority in fallback mode,
|
||||||
|
when neither `logger` or `logit` is available. This fix also checks
|
||||||
|
for systemd style log severity, leading `"<NUM>"` in log messages
|
||||||
|
- Ensure API socket used by `initctl` is non-blocking (event loop)
|
||||||
|
|
||||||
|
|
||||||
|
[4.12][] - 2025-04-28
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Improve notify:s6 readiness compatibility, by Aaron Andersen
|
||||||
|
- Update `runparts` usage text
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix variable overloading in urandom plugin
|
||||||
|
- Fix buffer overwrite in urandom plugin, reported by Aaron Andersen
|
||||||
|
|
||||||
|
|
||||||
|
[4.11][] - 2025-03-27
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Update documentation regarding transition from runlevel S to 2, how
|
||||||
|
run/tasks must "complete" before Finit can move to the next runlevel
|
||||||
|
- Improve argument handling in bundled getty when launching login
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #432: allow services in `setup` state to be stopped. This fixes
|
||||||
|
a serious blocker introduced in 4.10 that prevented systems from
|
||||||
|
being rebooted when any service was in this state
|
||||||
|
- Fix fallback `SIGKILL` when stopping a service with `SIGTERM` does
|
||||||
|
not work. This fixes a serious issue with services not responding to
|
||||||
|
the default `SIGTERM`
|
||||||
|
- Fix pre/post/ready/cleanup script execution if service has an
|
||||||
|
optional `env:file` (leading `-`)
|
||||||
|
- Fix blocked signals for pre/post/ready/cleanup scripts preventing
|
||||||
|
normal shutdown when a service/sysv is stopped in its setup state
|
||||||
|
- Fix issue where a pre:script creates a PID file in `/run` cause the
|
||||||
|
service to move from setup state to running. Any `svc_t` in setup,
|
||||||
|
teardown, or cleanup state should be ignored in the pidfile plugin
|
||||||
|
|
||||||
|
|
||||||
|
[4.10][] - 2025-03-03
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Add support for `cleanup:[0-3600,]script`, runs before service is
|
||||||
|
removed, unlike `post:script` that runs when service is stopped
|
||||||
|
- Improved entropy gathering in tertiary fallback of urandom plugin
|
||||||
|
- Reclassify `sysv` from run/task class to `service`
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #427: using an external getty with custom login program cause
|
||||||
|
Finit to use login program as the getty command
|
||||||
|
- Fix #428: allow `sysctl` path to be set at build time
|
||||||
|
- Fix #429: regression in v4.9 causing Finit to segfault at shutdown
|
||||||
|
- Fix possible memory leak when sourcing a service `env:file`
|
||||||
|
- Finit now waits until all `post:scripts` have run before returning
|
||||||
|
OK to `initctl <reload|runlevel>`. This also applies to the new
|
||||||
|
`cleanup:scripts` introduced in this release
|
||||||
|
- RFC3154 conformance formatting fix for `/dev/kmsg` fallback logging
|
||||||
|
|
||||||
|
|
||||||
|
[4.9][] - 2025-02-15
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> This release changes how Finit reacts to the exit status of `pre:`
|
||||||
|
> scripts. Finit will now no longer start the main process if its
|
||||||
|
> `pre:` script fails for any reason. So, if you have pre scripts that,
|
||||||
|
> e.g., create directories, make sure they are idempotent.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Add individual timeout (optional) support for pre/post/ready scripts
|
||||||
|
- Add support for systems with broken RTC, i.e., those that at power-on
|
||||||
|
may reset the RTC to a random date instead of zero, issue #418
|
||||||
|
- Add support for detecting "in-container" when in `systemd-nspawn`
|
||||||
|
- Check exit status of `pre:` scripts, on failure drive service/sysv to
|
||||||
|
`crashed` state. (The exit code of `post:` scripts remain ignored)
|
||||||
|
- All pre/post/ready scripts are now also searched for in `$PATH`
|
||||||
|
- Reset color attributes and clear screen when starting up. This is
|
||||||
|
for boot loaders like GRUB, which leave background color artifacts
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #415: only mark reverse-dependencies "dirty" if the main service
|
||||||
|
does not support SIGHUP. This helps avoid unnecessary restarts of
|
||||||
|
services that depend on a service that supports SIGHUP
|
||||||
|
- Fix #417: leaking inotify watchers in the cgroup subsystem
|
||||||
|
- Fix #421: add support for `nofail` mount option in `/etc/fstab`
|
||||||
|
- Fix #425: ordering bug in detecting .conf file changes to services
|
||||||
|
and `initctl reload`, or runlevel changes
|
||||||
|
- Fix `initctl touch` of template services, previously marking a
|
||||||
|
service created from a template as "dirty" did not take
|
||||||
|
- Fix unintended restart of template "siblings". I.e., `initctl touch`
|
||||||
|
of instantiated template service A affected B from same template
|
||||||
|
- Fix buggy `--with-rtc-date=DATE` configure option
|
||||||
|
- Fix kill on timeout of pre/post/ready scripts
|
||||||
|
|
||||||
|
|
||||||
|
[4.8][] - 2024-10-13
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Avoid remounting already mounted `/run` and `/tmp` directories. This
|
||||||
|
extends the existing support for detecting mounted directories to
|
||||||
|
include complex mount hierarchies are in use, overlayfs and tmpfs
|
||||||
|
mounts. Feature by Mathias Thore, Atlas Copco
|
||||||
|
- getty: trigger /etc/issue compat mode for Alpine Linux
|
||||||
|
- tmpfiles.d: skip `x11.conf` unless X11 common plugin is enabled
|
||||||
|
- tmpfiles.d: ignore x/X command, nos support for cleanup at runtime
|
||||||
|
- Drop debug mode `-D` from `udevd` in `hotplug.conf.in`, allow the
|
||||||
|
user to set this in `/etc/default/udevd` instead
|
||||||
|
- Certain initctl APIs at bootstrap are not supported, update warning
|
||||||
|
log to include command (number) for troubleshooting, issue #398
|
||||||
|
- Add support for hwrng to urandom plugin and check for empty seed
|
||||||
|
- Add `runparts -b` (batch mode) support, disables escape sequences
|
||||||
|
- New configure `--without-rc-local`, disables `/etc/rc.local` support
|
||||||
|
- New configure `--disable-cgroup` option, disables cgroup v2 detection
|
||||||
|
- `initctl show template@foo.conf` now shows how an enabled template
|
||||||
|
service has been evaluated by Finit, issue #411
|
||||||
|
- Extend `initctl` timeout connecting and waiting for Finit reply. The
|
||||||
|
previous 2 + 2 second poll timeout has proved to be too short on more
|
||||||
|
complex systems. Now a 15 + 15 second timeout is applied which should
|
||||||
|
be more resistant to temporary overload scenarios, issue #407
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #397: system shutdown/reboot can block on console input if action
|
||||||
|
is started remotely (ssh). Caused by legacy TTY screen size probing,
|
||||||
|
removed from both bootstrap and shutdown/reboot
|
||||||
|
- Fix #400: both `HOOK_MOUNT_ERROR` and `sulogin()` fail to trigger on
|
||||||
|
either mount or `fsck` errors. Problem caused by unresolved status
|
||||||
|
from pipe, calling `pclose()` without extracting exit status
|
||||||
|
- Fix #402: `initctl touch` does not respect `-n` (no error) flag
|
||||||
|
- Fix #403: `initctl touch` does not support template services
|
||||||
|
- Fix #404: possible undefined behavior when `--with-fstab=no` is set
|
||||||
|
- Fix #405: `@console` getty does not work with `tty0 ttyS0`
|
||||||
|
- Fix #409: prevent tmpfiles from following symlinks for `L+` and `R`,
|
||||||
|
otherwise symlink targets would also be removed. Found and fixed by
|
||||||
|
Mathias Thore and Ming Liu, Atlas Copco
|
||||||
|
- Fix #414: Frr Zebra immediately restarts on `initctl stop zebra`.
|
||||||
|
The fix likely works for all Frr/Quagga services due to the way they
|
||||||
|
create and delete their pid file
|
||||||
|
- Cosmetic issue with `[ OK ]` messages being printed out of order at
|
||||||
|
shutdown/reboot. Caused by nested calls to `service_stop()`
|
||||||
|
- Cosmetic issue with duplicate "Restoring RTC" message at bootstrap
|
||||||
|
|
||||||
|
|
||||||
|
[4.7][] - 2024-01-07
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Silence "not available" messages for run/task/service with `nowarn`
|
||||||
|
- Update docs, `cgroup.root` workaround for `SCHED_RR` tasks
|
||||||
|
- Drop runlevels 0 and 6 from `keventd`, not needed at reboot/poweroff
|
||||||
|
- Mount `/dev/shm` with mode 1777 (sticky bit)
|
||||||
|
- Mount `/dev/mqueue` if available, inspiration from Alpine Linux
|
||||||
|
- Update Alpine Linux installer and configuration files, tested on
|
||||||
|
Alpine v3.19, some assembly still required
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix confusing warning message when tmpfiles.d fails to install symlink
|
||||||
|
- Fix tmpfiles.d legacy `/run/lock/subsys`, ordering
|
||||||
|
- Add missing `/var/tmp` and `/var/lock -> /run/lock` (tmpfiles.d)
|
||||||
|
- Fix #388: log redirection broken unless Finit runs in debug mode.
|
||||||
|
Found and fixed by Ryan Rorison
|
||||||
|
- Fix #389: must libc requires `libgen.h` for `basename()` function.
|
||||||
|
Reported and worked around with new `basenm()` function by Stargirl
|
||||||
|
- Fix #392: `service/foo/ready` condition reasserted on pidfile removal
|
||||||
|
|
||||||
|
|
||||||
|
[4.6][] - 2023-11-13
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Add support for service `notify:pid` and `readiness none` global
|
||||||
|
option to change how Finit expects readiness notification, issue #386
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #383: dbus and runparts regression in Finit v4.5. The configure
|
||||||
|
script must expand `FINIT_RUNPATH_` before defining it in `config.h`
|
||||||
|
- Fix #384: service environment variables drop everything but the first
|
||||||
|
argument, e.g., `VAR="foo bar qux"` drops everything but `foo`
|
||||||
|
- Fix #385: internal conditions, e.g., `<int/bootstrap>` turn into flux
|
||||||
|
when leaving bootstrap, causing depending services to stop
|
||||||
|
- Fix #387: global environment variables declared with `set VAR=NAME` do
|
||||||
|
not drop leading `set `, causing `'set VAR'='NAME'` in env.
|
||||||
|
- Sanity check environment variables, for services and globally. Ensure
|
||||||
|
the variable name (key) does not contain spaces, or a leading `set `
|
||||||
|
|
||||||
|
|
||||||
|
[4.5][] - 2023-10-30
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Refactor `runparts` and `/etc/rc.local` to no longer block the main
|
||||||
|
loop, allowing `initctl` calls to interact with Finit. Issue #356
|
||||||
|
- Refactor the `run` stanza to no longer block the main loop, issue #362
|
||||||
|
- Allow `sulogin` with a user different from `root`, issue #357
|
||||||
|
- Allow disabling invocation of rescue mode from kernel command line
|
||||||
|
- Add `initctl -f` to force-skip asking Finit for existing services
|
||||||
|
when creating new services during bootstrap, e.g. `/etc/rc.local`
|
||||||
|
- `initctl runlevel` now returns `N S` instead of `N 10` in bootstrap
|
||||||
|
- `initctl runlevel N` during bootstrap is now allowed. It changes
|
||||||
|
the next runlevel to go to when bootstrap has completed. Effectively
|
||||||
|
overriding the `runlevel N` statement in `/etc/finit.conf`
|
||||||
|
- Improved logging on failure to `execvp()` a run/task/service, now
|
||||||
|
with `errno`, e.g., "No such file or directory" when the command
|
||||||
|
is missing from `$PATH`
|
||||||
|
- Add Bash completion support for `initctl`, configurable, issue #360
|
||||||
|
- Handle absolute path to `initctl [enable|disable]`, not supported
|
||||||
|
- Update `finit.conf(5)` man page with the recommended directory
|
||||||
|
hierarchy in `/etc/finit.d/`
|
||||||
|
- The `runparts` code has been split into `/libexec/finit/runparts`
|
||||||
|
- The `runparts` command now takes two options: `sysv` and `progress`.
|
||||||
|
The former ensures only `SNNfoo` and `KNNfoo` scripts are run.
|
||||||
|
- Add SysV Init Compatibility section to documentation
|
||||||
|
- Increased MAX path for commands, and arguments: 64 -> 256
|
||||||
|
- The bundled watchdog daemon no longer tries to log at startup, because
|
||||||
|
syslog is not available yet, any startup message leak to console
|
||||||
|
- Extend `if:` option with runtime evaluation of conditions. E.g., start
|
||||||
|
a task only `if:<run/foo/failure>` (here the run task 'foo' failed)
|
||||||
|
- Document new `if:`, `conflict:`, `nowarn` options for run/task/service
|
||||||
|
first introduced in v4.4
|
||||||
|
- Failure to open fstab should log to console, not just log to `/dev/kmsg`
|
||||||
|
- Rename `/lib/finit/system/*.conf`, added numbered prefix to ensure
|
||||||
|
proper execution order, e.g., `udevd` should always run first
|
||||||
|
- Plugins and bundled services: dbus, keventd, watchdogd, and runparts,
|
||||||
|
are now loaded *after* all services in `/lib/finit/system/`. A new
|
||||||
|
runtime-only path (for inspection) in `/run/finit/system/` is used
|
||||||
|
- Redirect `log*` output to console when `finit.debug` is enabled
|
||||||
|
- Assert `<int/container>` condition if we detect running in container
|
||||||
|
- Add support for mdev's netlink daemon mode, issue #367
|
||||||
|
- Add support for mdevd in `10-hotplug.conf`, preferred over plain mdev
|
||||||
|
- Disable modprobe plugin by default, udevd and mdev/mdevd loads modules
|
||||||
|
- Update documentation for run/task shell limitations, issue #376
|
||||||
|
- Update documentation regarding automount of `/run` and `/tmp`
|
||||||
|
- Update plugin documentation, add section about limited tmpfiles.d(5) support
|
||||||
|
- Skip registering service when `if:!name` matches a known service.
|
||||||
|
This allows conditional loading of alternative services, e.g. if udevd
|
||||||
|
is already loaded we do not need mdevd
|
||||||
|
- Drop `doc/bootstrap.md`, inaccurate and confusing to users
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix #227: believed to have been fixed in v4.3, the root cause was
|
||||||
|
actually that Finit was waiting for a process that was no longer in
|
||||||
|
the system. The fix is to ask the kernel on process-stop-timeout and
|
||||||
|
replay the lost PID so that Finit can continue with reboot/shutdown
|
||||||
|
- Fix #358: fix inotify events for `/etc/finit.conf`, improved log
|
||||||
|
messages and error handling
|
||||||
|
- Fix #361: cgroup move fail if run/task/services start as non-root.
|
||||||
|
Regression in the v4.4 release cycle while adding support for the
|
||||||
|
pre:/post:/ready: scripts. Now the latter scripts also properly run
|
||||||
|
in their correct cgroup
|
||||||
|
- Fix #366: document `fsck.*` kernel command line options and simplify
|
||||||
|
the configure flags `--enable-fsckfix` and `--enable-fastboot` to
|
||||||
|
only adjust the default values for the `fsck.*` options.
|
||||||
|
- Fix #371: swap load order of `/lib/finit/system/*` vs `/etc/finit.d/*`
|
||||||
|
We must run `10-hotplug.conf` first to ensure devices and modules are
|
||||||
|
up and loaded before the user's run/task/services are called. The order
|
||||||
|
at bootstrap is now saved in `/run/finit/conf.order` for inspection,
|
||||||
|
`/run/finit/exec.order` shows the start order of each process
|
||||||
|
- Fix #372: lost `udevadm` calls due to overloading
|
||||||
|
- Adjust final `udevadm settle` timeout: 5 -> 30 sec
|
||||||
|
- Fixed dbus plugin, the function that located `<pidfile> ...` in the
|
||||||
|
`dbus/system.conf` caused spurious line breaks which led to the
|
||||||
|
service not being loaded properly
|
||||||
|
- The `runparts` executor now skips backup files (`foo~`)
|
||||||
|
- The `runparts` stanza now properly appends ` start` to scripts that
|
||||||
|
start with `S[0-9]+`. This has been broken for a very long time.
|
||||||
|
- Fix #377: expand service `env:file` variables, allow constructs like:
|
||||||
|
|
||||||
|
RUNDIR=/var/run/somesvc
|
||||||
|
DAEMON_ARGS=--workdir $RUNDIR --other-args...
|
||||||
|
- Fix #378: warn on console if run/task times out during bootstrap
|
||||||
|
- Fix #378: add run/task support for `<!>` to allow transition from
|
||||||
|
bootstrap to multi-user runlevel even though task has not run yet.
|
||||||
|
- Fix #382: do not clear `<service/foo/STATE>` conditions on reload.
|
||||||
|
Introduced back in v4.3-rc2, 82cc10be8, the support for automatic
|
||||||
|
service conditions have had a weird and unintended behavior. Any
|
||||||
|
change in state (see `doc/svc-machine.png`) caused Finit to clear
|
||||||
|
out *all* previously acquired service conditions.
|
||||||
|
|
||||||
|
However, when moving between RUNNING and PAUSED states, a service
|
||||||
|
should not have its conditions cleared. The PAUSED state, seen
|
||||||
|
also by all conditions moving to FLUX, is only temporary while an
|
||||||
|
`initctl reload` is processed. If a service has no changes to be
|
||||||
|
applied it will move back to RUNNING.
|
||||||
|
|
||||||
|
Also, we cannot clear the service conditions because other run/task
|
||||||
|
or services may depend on it and clearing them would cause Finit to
|
||||||
|
`SIGTERM` these processes (since they are no longer eligible to run).
|
||||||
|
|
||||||
|
|
||||||
|
[4.4][] - 2023-05-15
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
> **Note 1:** this release contains changes to the `.conf` parser. If you
|
||||||
|
> have .conf file statements with comment character (`#`) in the command
|
||||||
|
> options or description, you must now escape them (`\#`). Issue #186
|
||||||
|
>
|
||||||
|
> **Note 2:** prior to this release, runlevel `S` and `0` were after
|
||||||
|
> boot treated as the same runlevel. This caused `task [06] ...` to
|
||||||
|
> also run at bootstrap instead of just at shutdown and reboot. The
|
||||||
|
> changes made to Finit to separate `S` from `0` require you to update
|
||||||
|
> the allowed runlevels for services that are allowed to continue
|
||||||
|
> running at shutdown. I.e., change `[S123456789]` to `[S0123456789]`
|
||||||
|
> for, e.g., `sysklogd`. Issue #352
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Add limited tmpfiles.d(5) support
|
||||||
|
|
||||||
|
This change adds very basic `tmpfiles.d/` support to Finit. Most of
|
||||||
|
the basic types are supported, but not all, so for now, please check
|
||||||
|
the code and examples for details on what is working.
|
||||||
|
|
||||||
|
* If a run/task/service command does not exist, skip registering it
|
||||||
|
|
||||||
|
This changes the semantics of Finit a bit by checking for the command
|
||||||
|
to run when registering it, skipping commands that cannot be found in
|
||||||
|
the absolute path provided in the command, or in `$PATH`
|
||||||
|
|
||||||
|
This change includes a new `nowarn` flag that can be used to prevent
|
||||||
|
Finit from warning for missing commands. See below for an example.
|
||||||
|
|
||||||
|
* Add run/task/service support for `conflict:foo` handling
|
||||||
|
* Add run/task/service support for `if:[!]ident` and `if:<[!]cond>`
|
||||||
|
|
||||||
|
Conditional loading of stanza depending on ident is already loaded (or
|
||||||
|
not), or condition satisfied (or not). E.g., do not run `mdev` if we
|
||||||
|
found and registered `udevd`, or load service only if `<boot/testing>`
|
||||||
|
condition is set.
|
||||||
|
|
||||||
|
The optional leading `!` negates the comparison, if NOT foo then ...
|
||||||
|
|
||||||
|
* Add support for static services in `/lib/finit/system/*.conf`
|
||||||
|
|
||||||
|
Slowly migrating away from hard-coded services in plugins. This way
|
||||||
|
it's possible for the user to both inspect and override as needed.
|
||||||
|
|
||||||
|
* Migrate hotplug plugin to a conditional `/lib/finit/system/hotplug.conf`
|
||||||
|
|
||||||
|
This is the first example of the just minted advanced stanza syntax with
|
||||||
|
`if:`-statements, `conflict:` handling, and `nowarn` flags.
|
||||||
|
|
||||||
|
* Initial support for template services, `foo@.conf`, similar to systemd
|
||||||
|
|
||||||
|
$ initctl show avahi-autoipd@
|
||||||
|
service :%i avahi-autoipd --syslog %i -- ZeroConf for %i
|
||||||
|
|
||||||
|
To enable ZeroConf for, e.g., `eth0`, use
|
||||||
|
|
||||||
|
$ initctl enable avahi-autoipd@eth0.conf
|
||||||
|
|
||||||
|
The enabled symlink will be set up to `avahi-autoipd@.conf` and every
|
||||||
|
instance of `%i` will in the instantiated directive be replaced with
|
||||||
|
`eth0`. Inspect the result with:
|
||||||
|
|
||||||
|
$ initctl status avahi-autoipd:eth0
|
||||||
|
|
||||||
|
* Add `devmon`, a `<dev/foo>` condition provider, issue #185
|
||||||
|
* Support for line continuation character `\` in .conf files, issue #186
|
||||||
|
|
||||||
|
service name:sysklogd [S123456789] \
|
||||||
|
env:-/etc/default/sysklogd \
|
||||||
|
syslogd -F $SYSLOGD_ARGS \
|
||||||
|
-- System log daemon
|
||||||
|
|
||||||
|
* `HOOK_BASEFS_UP` has been moved! External plugins that need to call
|
||||||
|
`service_register()`, please use `HOOK_SVC_PLUGIN` from now on.
|
||||||
|
Apologies for any inconveniences this might cause!
|
||||||
|
* getty: add support for `/etc/os-release` to replace `uname` output
|
||||||
|
This change, which has a fallback to `/usr/lib/os-release`, overrides
|
||||||
|
traditional modifiers with the os-release variant. These values were
|
||||||
|
taken from `uname`, which on Linux systems are pretty useless since
|
||||||
|
they always return the kernel name and version instead of the
|
||||||
|
distro/OS values.
|
||||||
|
|
||||||
|
E.g., \s becomes `PRETTY_NAME` instead of 'Linux' and \v becomes the
|
||||||
|
pretty `VERSION`, while \r becomes `VERSION_ID`.
|
||||||
|
* Support for overriding `/etc/finit.conf` and `/etc/finit.d` issue #235
|
||||||
|
New (kernel) command line option `finit.config=PATH` which can be used
|
||||||
|
to redirect Finit to start up with, e.g., `/etc/factory.conf` instead of
|
||||||
|
`/etc/finit.conf`.
|
||||||
|
|
||||||
|
For the complete experience a new top-level configuration file directive
|
||||||
|
`rcsd PATH` has also been added. It in turn can be used by `factory.conf`
|
||||||
|
as follows to override `/etc/finit.d`:
|
||||||
|
|
||||||
|
rcsd /etc/factory.d
|
||||||
|
|
||||||
|
* Support for overriding `/etc/finit.d` from the alternate `finit.conf`
|
||||||
|
with a new `rcsd /path/to/dot.d/` .conf file directive
|
||||||
|
* Support for `fsck_mode=[auto,skip,force]` + `fsck_repair=[preen,no,yes]`
|
||||||
|
* Add `set` keyword for environment variables set in `/etc/finit.conf`
|
||||||
|
* Support `finit.cond=foo` cmdline `<boot/foo>` conditions, issue #250
|
||||||
|
* `initctl` JSON output support for status and conditions, issue #273
|
||||||
|
Example:
|
||||||
|
|
||||||
|
root@infix:~$ initctl status -j resolvconf
|
||||||
|
{
|
||||||
|
"identity": "resolvconf",
|
||||||
|
"description": "Update DNS configuration",
|
||||||
|
"type": "task",
|
||||||
|
"forking": false,
|
||||||
|
"status": "done",
|
||||||
|
"exit": { "code": 0 },
|
||||||
|
"origin": "/etc/finit.d/enabled/sysrepo.conf",
|
||||||
|
"command": "resolvconf -u",
|
||||||
|
"restarts": 0,
|
||||||
|
"pidfile": "none",
|
||||||
|
"pid": 0,
|
||||||
|
"user": "root",
|
||||||
|
"group": "root",
|
||||||
|
"uptime": 0,
|
||||||
|
"runlevels": [ 1, 2, 3, 4, 5, 7, 8, 9 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
The excellent tool `jq` can be used to extract parts of the output for
|
||||||
|
further scripting. E.g. `initctl status -j foo | jq .exit.status`
|
||||||
|
|
||||||
|
* Add JSON support to `initctl ls` command
|
||||||
|
|
||||||
|
This allows for easy access to the *disabled* services:
|
||||||
|
|
||||||
|
root@anarchy:~# initctl ls --json |jq '.available - .enabled'
|
||||||
|
[
|
||||||
|
"chronyd.conf",
|
||||||
|
"dnsmasq.conf",
|
||||||
|
"gdbserver.conf",
|
||||||
|
"inadyn.conf",
|
||||||
|
"inetd.conf",
|
||||||
|
"isisd.conf",
|
||||||
|
"lldpd.conf",
|
||||||
|
"mstpd.conf",
|
||||||
|
"ntpd.conf",
|
||||||
|
"ospf6d.conf",
|
||||||
|
"ospfd.conf",
|
||||||
|
"querierd.conf",
|
||||||
|
"ripd.conf",
|
||||||
|
"ripng.conf",
|
||||||
|
"sshd.conf",
|
||||||
|
"syslogd.conf",
|
||||||
|
"telnetd.conf",
|
||||||
|
"uftpd.conf",
|
||||||
|
"wpa_supplicant.conf",
|
||||||
|
"zebra.conf"
|
||||||
|
]
|
||||||
|
|
||||||
|
* Allow `manual:yes` on sysv/service/run/task stanzas, issue #274
|
||||||
|
* Add support for `oncrash:script` to call the `post:script` action, if
|
||||||
|
defined, for a crashing service. The `EXIT_CODE` variable sent to the
|
||||||
|
script is set to `crashed`. Issue #282
|
||||||
|
* Search for plugins in `/usr` and `/usr/local` as well, issue #284
|
||||||
|
* tty: add support for `passenv` flag to `/bin/login`, issue #286
|
||||||
|
* Add reboot/shutdown/poweroff timeout `-t SEC` to initctl, issue #295
|
||||||
|
* Add support for s6 and systemd readiness notification, issue #299.
|
||||||
|
Service readiness notification to support daemons employing systemd
|
||||||
|
and s6 notification. Complementing the native Finit readiness support
|
||||||
|
using PID files that exist already.
|
||||||
|
|
||||||
|
The two have slightly different ways of implementing readiness:
|
||||||
|
|
||||||
|
- https://www.freedesktop.org/software/systemd/man/sd_notify.html
|
||||||
|
- https://skarnet.org/software/s6/notifywhenup.html
|
||||||
|
|
||||||
|
Finit now provides both a `NOTIFY_SOCKET` environment variable, for
|
||||||
|
systemd, and a way to start s6 daemons with a descriptor argument.
|
||||||
|
|
||||||
|
For details on the syntax, see the `service` documentation.
|
||||||
|
|
||||||
|
This change also renames internal states for run/task/services to
|
||||||
|
avoid any confusion with the introduction of `ready:scripts`:
|
||||||
|
|
||||||
|
- `WAITING -> PAUSED`
|
||||||
|
- `READY -> WAITING`
|
||||||
|
|
||||||
|
A service condition that used, e.g., `<service/foo/ready>` should now
|
||||||
|
instead use `<service/foo/waiting>`
|
||||||
|
|
||||||
|
* Add `ready:script` for services, called when daemon is ready, issue #300
|
||||||
|
* Add support for running scripts at shutdown at two new hook points
|
||||||
|
during the shutdown process, issue #302. See doc/plugins.md for details:
|
||||||
|
|
||||||
|
- `HOOK_SVC_DN`: after all services and non-reserved processes have been
|
||||||
|
killed (and collected)
|
||||||
|
- `HOOK_SYS_DN`: after all file systems have been unmounted, *just prior*
|
||||||
|
to Finit calling `reboot()` to shut down or reboot the system
|
||||||
|
|
||||||
|
* The `modules-load` plugin now default to runlevel `[S]`, in previous
|
||||||
|
releases it was `[2345]`. This breaking change is to align it more
|
||||||
|
with what users mostly want (modules loaded before services start) and
|
||||||
|
can be changed back to the old behavior with a per-file setting:
|
||||||
|
|
||||||
|
set runlevel 2345
|
||||||
|
|
||||||
|
* The `modules-load` plugin now adds silent tasks for modprobe. This to
|
||||||
|
prevent confusing `[ OK ]` boot messages when in fact modprobe failed.
|
||||||
|
* The `modules-load` plugin now support `set modprobe /path/to/modprobe`
|
||||||
|
* The header files `finit/conf.h` and `finit/service.h` are now exported
|
||||||
|
for external plugins
|
||||||
|
* Add support for multiple args to `initctl cond set/clr`, issue #329
|
||||||
|
* Silence confusing `[ OK ]` progress from modules-load plugin, issue #332
|
||||||
|
|
||||||
|
This change drops the confusing status progress output, which was always
|
||||||
|
OK since the actual modprobe operation runs in the background. No need
|
||||||
|
to show status of the "added a task to finit, found modprobe" command.
|
||||||
|
|
||||||
|
* dbus plugin: adapt to other operating systems
|
||||||
|
|
||||||
|
Not all Linux systems are based on Debian, and even if they are inspired
|
||||||
|
by Debian (Buildroot), they do not necessarily use the same defaults.
|
||||||
|
Probes the system at runtime for:
|
||||||
|
|
||||||
|
- dbus user and group
|
||||||
|
- dbus PID file
|
||||||
|
|
||||||
|
If the user/group cannot be found we fall back to `root`, if the PID
|
||||||
|
file cannot be determined we ignore PID file readiness.
|
||||||
|
|
||||||
|
* Improve documentation for runparts and hook scripts. Issue #315, #320
|
||||||
|
* Add `HOOK_NETWORK_DN`, called after change to runlevel 6 or 0, issue #319
|
||||||
|
* Use sysklogd `logger` tool instead of legacy `logit` tool, issue #344
|
||||||
|
|
||||||
|
For log redirection Finit has the legacy `logit` tool. This change
|
||||||
|
allows Finit to use the `sysklogd` project's extended `logger` tool
|
||||||
|
instead, when available. Allowing logging with the process' PID.
|
||||||
|
|
||||||
|
* Add `initctl` aliases: `cat -> show`, `kill -> signal`
|
||||||
|
* Add `initctl -n,--noerr` to return OK(0) if services do not exist, for
|
||||||
|
integration with openresolv and scripts with similar requirements
|
||||||
|
* Add `initctl plugins`, list installed plugins
|
||||||
|
* Add timestamp to log messages in fallback and logging to `stderr`.
|
||||||
|
When there is no log daemon, and we are running in a container, or we
|
||||||
|
cannot log to the kernel ring buffer, then we log to `stderr`. This
|
||||||
|
change improves log output by prefixing each message with a timestamp.
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Fix #254: document limitations in `rc.local` and `runparts` scripts
|
||||||
|
* Fix #269: add compulsory kernel symlinks in `/dev`
|
||||||
|
* Fix #275: `initctl status foo` should list all instances, regression
|
||||||
|
introduced in v4.3
|
||||||
|
* Fix #278: enforce conditions also for running `pre:` scripts
|
||||||
|
* Fix #279: allow `restart:always`, of crashing services. Similar to
|
||||||
|
`respawn` but honors `restart_sec`
|
||||||
|
* Fix #280: allow calling `initctl restart foo` from within foo
|
||||||
|
* Fix #283: too quick timeout at bootstrap of lingering tasks
|
||||||
|
* Fix #285: `initctl restart` should start crashed service
|
||||||
|
* Fix #288: enable built-in `sulogin` in Alpine and Void Linux builds
|
||||||
|
* Fix #293: modprobe plugin: support for coldplugging more devices. It
|
||||||
|
turns out, not all buses in Linux add `modalias` attributes to their
|
||||||
|
devices in sysfs. One notable exception are MDIO buses. The plugin's
|
||||||
|
scan routine would thus not pick them up.
|
||||||
|
* Fix #294: `shutdown --help` mistakenly shuts down system
|
||||||
|
* Fix #310: Always use configured restart delay for crashing services.
|
||||||
|
If no delay is configured, default to an initial 2000 msec for forking
|
||||||
|
daemons and start-stop scripts, and 1 msec for non-forking daemons
|
||||||
|
* Fix #311: document how to combine device tree with conditions
|
||||||
|
* Fix #312: restart services with respawn set, e.g. ttys, immediately
|
||||||
|
* Fix #313: Cancel pending restart timer on stop/start/restart/reload
|
||||||
|
* Fix #314: skip run/task/service restart if conditions are lost
|
||||||
|
* Fix #315: add environment variables to hook scripts
|
||||||
|
|
||||||
|
All hook scripts are called with at least one environment variable
|
||||||
|
set, `FINIT_HOOK_NAME`, useful when reusing the same hook script for
|
||||||
|
multiple hook points. It is set to the string name, also used by the
|
||||||
|
path, e.g., `hook/net/up`
|
||||||
|
|
||||||
|
For all hook points from hook/sys/shutdown and later, `FINIT_SHUTDOWN`
|
||||||
|
is also set, to one of: `halt`, `poweroff`, `reboot`
|
||||||
|
|
||||||
|
* Fix #317: make sure hook scripts don't run twice, also fixes #316
|
||||||
|
* Fix #318: only show `[ OK ] Calling foo` progress for `runparts ...`
|
||||||
|
* Fix #320: the API/IPC socket is closed immediately at shutdown/reboot
|
||||||
|
to protect hook scripts or services calling initctl. There is no way
|
||||||
|
to service these requests safely at that time
|
||||||
|
* Fix #333: consider a service dirty if command line args have changed
|
||||||
|
|
||||||
|
This fixes `initctl reload` correctly restarting all daemons that have
|
||||||
|
new command line arguments.
|
||||||
|
|
||||||
|
Previously command line arguments changes were only acted upon if the
|
||||||
|
service was explicitly reloaded `initctl reload myservice`.
|
||||||
|
|
||||||
|
Found and fixed by Jack Newman
|
||||||
|
|
||||||
|
* Fix #338: ensure shutdown hooks are called properly; `hook/sys/down`
|
||||||
|
and `hook/svc/down` hook scripts, found and fixed by Jack Newman
|
||||||
|
* Fix #339: use absolute path in `/etc/finit.d/enabled/` symlinks, for
|
||||||
|
use-cases when `/etc` is read-only and `/etc/finit.d/enabled ->
|
||||||
|
/mnt/finit.d/enabled`, reported by Jack Newman
|
||||||
|
* Fix #340: Finit ignores deleted/moved `.conf` file sin `/etc/finit.d`
|
||||||
|
* Fix #342: in runlevel S (bootstrap), not all `initctl` commands can be
|
||||||
|
supported, block the following: runlevel, reload, start/stop, restart,
|
||||||
|
reload, halt, poweroff, suspend. Also, prevent `SIGHUP` and `SIGUSR1`
|
||||||
|
signals when in shutdown or reboot
|
||||||
|
* Fix #352: separate runlevel S from runlevel 0
|
||||||
|
* Fix #355: regression in v3.2 stopping a process and its group
|
||||||
|
|
||||||
|
In Finit v3.2 a regression was introduced that affects the way Finit
|
||||||
|
stops a supervised process and its process group.
|
||||||
|
|
||||||
|
Instead of sending SIGTERM to the process, and thus delegating the
|
||||||
|
responsibility to that process to inform any children it may have, as
|
||||||
|
of commit 91a9c83 Finit sends SIGTERM to the entire process group.
|
||||||
|
For SIGKILL this is fine, SIGKILL only runs as cleanup and as a last
|
||||||
|
ditch effort if the process doesn't respond to SIGTERM.
|
||||||
|
|
||||||
|
This regression, introduced in v3.2, directly affects services like
|
||||||
|
`avahi-autoipd` that have forked off children that it needs to tell to
|
||||||
|
exit cleanly before it returns. With the patch in question these
|
||||||
|
children are never allowed to complete, which in turn causes lingering
|
||||||
|
169.254 link-local addresses on interfaces.
|
||||||
|
|
||||||
|
* Fix bootmisc plugin: octal permission on `/run/lock` and `/var/lock`
|
||||||
|
|
||||||
|
* Ensure `initctl cond get` support the flux state (exit code 255)
|
||||||
|
* Fix potential socket leak at bootstrap and shutdown
|
||||||
|
* Fix potential NULL pointer deref in kernel command line parser
|
||||||
|
* Fix lingering condition in service after reload of service with new
|
||||||
|
config that has no condition
|
||||||
|
* Fix wrong path to command in service after reload, may have changed
|
||||||
|
* `logit`: fall back to package name if `$LOGNAME` and `$USER` are
|
||||||
|
unset. **Note:** you should probably not use `logit` in your own
|
||||||
|
scripts, it is only meant for internal use by Finit. We recommend
|
||||||
|
using `logger` from the `bsdutils` or `sysklogd` packages instead
|
||||||
|
* Fix issue where `env:`/`pre:`/`post:`/etc. is removed from a service
|
||||||
|
|
||||||
|
The trick is when reloading a service like this:
|
||||||
|
|
||||||
|
service env:/etc/env serv -np -e foo:bar
|
||||||
|
|
||||||
|
into this:
|
||||||
|
|
||||||
|
service pre:/bin/pre.sh serv -np
|
||||||
|
|
||||||
|
In the second the `env:` has been removed and `pre:` added. Prior to
|
||||||
|
this patch, `env:` was kept leading to unintended behavior.
|
||||||
|
* Fix parse/diff of command line args, e.g., `nginx -g 'daemon off;'`
|
||||||
|
|
||||||
|
Starting a service like this works fine:
|
||||||
|
|
||||||
|
service [2345789] env:-/etc/default/nginx nginx -g 'daemon off;'
|
||||||
|
|
||||||
|
However, on `initctl reload` (and no change to .conf files) the arg
|
||||||
|
list was lost while parsing the .conf files. Leading to a false
|
||||||
|
positive 'diff' in args causing nginx to be unnecessarily restarted.
|
||||||
|
* Fix issue with disabled "linewrap" on the console TTY after login.
|
||||||
|
The root cause is `qemu-system-x86_64 -nographics` disabling it when
|
||||||
|
starting up. The correct `\e[?7h` escape code is now used.
|
||||||
|
|
||||||
|
|
||||||
|
[4.3][] - 2022-05-15
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
Critical bug fix release. If you run a 32-bit target with GLIBC 2.34
|
Critical bug fix release. If you run a 32-bit target with GLIBC 2.34
|
||||||
@@ -63,6 +914,14 @@ you *need* to upgrade!
|
|||||||
* Document secret service option `respawn`, which bypasses the crash
|
* Document secret service option `respawn`, which bypasses the crash
|
||||||
semantics, allowing endless restarts
|
semantics, allowing endless restarts
|
||||||
* Document secret `HOOK_BANNER`, the first hook point before the banner
|
* Document secret `HOOK_BANNER`, the first hook point before the banner
|
||||||
|
* Document slightly confusing `initctl reload foo` command. It does
|
||||||
|
*not* reload the service's `.conf` file! Issue #263
|
||||||
|
* Log changes; all instances where previously the `basename cmd` of a
|
||||||
|
service was used to identify the service, now the proper `name:id` is
|
||||||
|
used instead. Meaning, a service without a custom `:ID` or `name:`
|
||||||
|
will display the same as before, but with any of those customizations
|
||||||
|
the name and name:id will now be shown. **Note:** this may affect any
|
||||||
|
log scrapers out there!
|
||||||
* New plugin: `hook-scripts`, allows [run-parts(8)][] style scripts to
|
* New plugin: `hook-scripts`, allows [run-parts(8)][] style scripts to
|
||||||
run on any hook point. Contributed by Tobias Waldekranz
|
run on any hook point. Contributed by Tobias Waldekranz
|
||||||
* `initctl` (`reboot`) falls back to `-f` when it detects it is in
|
* `initctl` (`reboot`) falls back to `-f` when it detects it is in
|
||||||
@@ -75,6 +934,12 @@ you *need* to upgrade!
|
|||||||
in lexicographic order and UNIX backup files (`foo.conf~`) are skipped
|
in lexicographic order and UNIX backup files (`foo.conf~`) are skipped
|
||||||
* The `name:id` tuple is now more consistently used in all log and debug
|
* The `name:id` tuple is now more consistently used in all log and debug
|
||||||
messages instead of the basename of the command
|
messages instead of the basename of the command
|
||||||
|
* Simplify error output of `initctl start/stop/restart/signal`, no more
|
||||||
|
extra usage help, just a plain error message
|
||||||
|
* Exit codes of `initctl` have changed to use LSB script standard and BSD
|
||||||
|
sysexits.h exit codes. As before, a non-zero exit is error or missing
|
||||||
|
* Add support for `initctl -q` to more commands: stop, start, restart,
|
||||||
|
reload, signal, etc.
|
||||||
|
|
||||||
[run-parts(8)]: https://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
[run-parts(8)]: https://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
||||||
|
|
||||||
@@ -93,7 +958,7 @@ you *need* to upgrade!
|
|||||||
* Fix #233: initctl shows wrong status for run/task, by Sergio Morlans
|
* Fix #233: initctl shows wrong status for run/task, by Sergio Morlans
|
||||||
and Ming Liu, Atlas Copco
|
and Ming Liu, Atlas Copco
|
||||||
* Fix #248: source `env:file` also in `pre:` and `post` scripts
|
* Fix #248: source `env:file` also in `pre:` and `post` scripts
|
||||||
* Fix #260: drop limit on device name in `Checking filesystem`...` output
|
* Fix #260: drop limit on device name in `Checking filesystem...` output
|
||||||
* Fix start/stop and monitoring (restart) of SysV init scripts and
|
* Fix start/stop and monitoring (restart) of SysV init scripts and
|
||||||
forking services, see the updated documentation for details
|
forking services, see the updated documentation for details
|
||||||
* Fix call to `swapoff` at shutdown, does not support `-e` flag
|
* Fix call to `swapoff` at shutdown, does not support `-e` flag
|
||||||
@@ -307,7 +1172,7 @@ make sure to read the whole change log when upgrading.
|
|||||||
previously hard-coded in Finit, e.g., starting the bundled watchdogd,
|
previously hard-coded in Finit, e.g., starting the bundled watchdogd,
|
||||||
various distro packed udevd and other hotplugging tools
|
various distro packed udevd and other hotplugging tools
|
||||||
* A proper rescue mode has been added. It is started extremely early
|
* A proper rescue mode has been added. It is started extremely early
|
||||||
and is protected with a bundled `suslogin`. Exiting rescue mode now
|
and is protected with a bundled `sulogin`. Exiting rescue mode now
|
||||||
brings up the system as a normal boot, as one expects
|
brings up the system as a normal boot, as one expects
|
||||||
* Support for `sysv` start/stop scripts as well as monitoring forking
|
* Support for `sysv` start/stop scripts as well as monitoring forking
|
||||||
services, stared using `sysv` or `service` stanza
|
services, stared using `sysv` or `service` stanza
|
||||||
@@ -1138,38 +2003,52 @@ Major bug fix release.
|
|||||||
|
|
||||||
* Initial release
|
* Initial release
|
||||||
|
|
||||||
[UNRELEASED]: https://github.com/troglobit/finit/compare/4.2...HEAD
|
[UNRELEASED]: https://github.com/finit-project/finit/compare/4.17...HEAD
|
||||||
[4.3]: https://github.com/troglobit/finit/compare/4.2...4.3
|
[4.17]: https://github.com/finit-project/finit/compare/4.16...4.17
|
||||||
[4.2]: https://github.com/troglobit/finit/compare/4.1...4.2
|
[4.16]: https://github.com/finit-project/finit/compare/4.15...4.16
|
||||||
[4.1]: https://github.com/troglobit/finit/compare/4.0...4.1
|
[4.15]: https://github.com/finit-project/finit/compare/4.14...4.15
|
||||||
[4.0]: https://github.com/troglobit/finit/compare/3.1...4.0
|
[4.14]: https://github.com/finit-project/finit/compare/4.13...4.14
|
||||||
[3.1]: https://github.com/troglobit/finit/compare/3.0...3.1
|
[4.13]: https://github.com/troglobit/finit/compare/4.12...4.13
|
||||||
[3.0]: https://github.com/troglobit/finit/compare/2.4...3.0
|
[4.12]: https://github.com/troglobit/finit/compare/4.11...4.12
|
||||||
[2.4]: https://github.com/troglobit/finit/compare/2.3...2.4
|
[4.11]: https://github.com/troglobit/finit/compare/4.10...4.11
|
||||||
[2.3]: https://github.com/troglobit/finit/compare/2.2...2.3
|
[4.10]: https://github.com/troglobit/finit/compare/4.9...4.10
|
||||||
[2.2]: https://github.com/troglobit/finit/compare/2.1...2.2
|
[4.9]: https://github.com/troglobit/finit/compare/4.8...4.9
|
||||||
[2.1]: https://github.com/troglobit/finit/compare/2.0...2.1
|
[4.8]: https://github.com/troglobit/finit/compare/4.7...4.8
|
||||||
[2.0]: https://github.com/troglobit/finit/compare/1.12...2.0
|
[4.7]: https://github.com/troglobit/finit/compare/4.6...4.7
|
||||||
|
[4.6]: https://github.com/troglobit/finit/compare/4.5...4.6
|
||||||
|
[4.5]: https://github.com/troglobit/finit/compare/4.4...4.5
|
||||||
|
[4.4]: https://github.com/troglobit/finit/compare/4.3...4.4
|
||||||
|
[4.3]: https://github.com/troglobit/finit/compare/4.2...4.3
|
||||||
|
[4.2]: https://github.com/troglobit/finit/compare/4.1...4.2
|
||||||
|
[4.1]: https://github.com/troglobit/finit/compare/4.0...4.1
|
||||||
|
[4.0]: https://github.com/troglobit/finit/compare/3.1...4.0
|
||||||
|
[3.1]: https://github.com/troglobit/finit/compare/3.0...3.1
|
||||||
|
[3.0]: https://github.com/troglobit/finit/compare/2.4...3.0
|
||||||
|
[2.4]: https://github.com/troglobit/finit/compare/2.3...2.4
|
||||||
|
[2.3]: https://github.com/troglobit/finit/compare/2.2...2.3
|
||||||
|
[2.2]: https://github.com/troglobit/finit/compare/2.1...2.2
|
||||||
|
[2.1]: https://github.com/troglobit/finit/compare/2.0...2.1
|
||||||
|
[2.0]: https://github.com/troglobit/finit/compare/1.12...2.0
|
||||||
[1.12]: https://github.com/troglobit/finit/compare/1.11...1.12
|
[1.12]: https://github.com/troglobit/finit/compare/1.11...1.12
|
||||||
[1.11]: https://github.com/troglobit/finit/compare/1.10...1.11
|
[1.11]: https://github.com/troglobit/finit/compare/1.10...1.11
|
||||||
[1.10]: https://github.com/troglobit/finit/compare/1.9...1.10
|
[1.10]: https://github.com/troglobit/finit/compare/1.9...1.10
|
||||||
[1.9]: https://github.com/troglobit/finit/compare/1.8...1.9
|
[1.9]: https://github.com/troglobit/finit/compare/1.8...1.9
|
||||||
[1.8]: https://github.com/troglobit/finit/compare/1.7...1.8
|
[1.8]: https://github.com/troglobit/finit/compare/1.7...1.8
|
||||||
[1.7]: https://github.com/troglobit/finit/compare/1.6...1.7
|
[1.7]: https://github.com/troglobit/finit/compare/1.6...1.7
|
||||||
[1.6]: https://github.com/troglobit/finit/compare/1.5...1.6
|
[1.6]: https://github.com/troglobit/finit/compare/1.5...1.6
|
||||||
[1.5]: https://github.com/troglobit/finit/compare/1.4...1.5
|
[1.5]: https://github.com/troglobit/finit/compare/1.4...1.5
|
||||||
[1.4]: https://github.com/troglobit/finit/compare/1.3...1.4
|
[1.4]: https://github.com/troglobit/finit/compare/1.3...1.4
|
||||||
[1.3]: https://github.com/troglobit/finit/compare/1.2...1.3
|
[1.3]: https://github.com/troglobit/finit/compare/1.2...1.3
|
||||||
[1.2]: https://github.com/troglobit/finit/compare/1.1...1.2
|
[1.2]: https://github.com/troglobit/finit/compare/1.1...1.2
|
||||||
[1.1]: https://github.com/troglobit/finit/compare/1.0...1.1
|
[1.1]: https://github.com/troglobit/finit/compare/1.0...1.1
|
||||||
[1.0]: https://github.com/troglobit/finit/compare/0.9...1.0
|
[1.0]: https://github.com/troglobit/finit/compare/0.9...1.0
|
||||||
[0.9]: https://github.com/troglobit/finit/compare/0.8...0.9
|
[0.9]: https://github.com/troglobit/finit/compare/0.8...0.9
|
||||||
[0.8]: https://github.com/troglobit/finit/compare/0.7...0.8
|
[0.8]: https://github.com/troglobit/finit/compare/0.7...0.8
|
||||||
[0.7]: https://github.com/troglobit/finit/compare/0.6...0.7
|
[0.7]: https://github.com/troglobit/finit/compare/0.6...0.7
|
||||||
[0.6]: https://github.com/troglobit/finit/compare/0.5...0.6
|
[0.6]: https://github.com/troglobit/finit/compare/0.5...0.6
|
||||||
[0.5]: https://github.com/troglobit/finit/compare/0.4...0.5
|
[0.5]: https://github.com/troglobit/finit/compare/0.4...0.5
|
||||||
[0.4]: https://github.com/troglobit/finit/compare/0.3...0.4
|
[0.4]: https://github.com/troglobit/finit/compare/0.3...0.4
|
||||||
[0.3]: https://github.com/troglobit/finit/compare/0.2...0.3
|
[0.3]: https://github.com/troglobit/finit/compare/0.2...0.3
|
||||||
[0.2]: https://github.com/troglobit/finit/compare/0.1...0.2
|
[0.2]: https://github.com/troglobit/finit/compare/0.1...0.2
|
||||||
[libuEv]: https://github.com/troglobit/libuev
|
[libuEv]: https://github.com/troglobit/libuev
|
||||||
[dea3ae8]: https://github.com/troglobit/finit/commit/dea3ae8
|
[dea3ae8]: https://github.com/troglobit/finit/commit/dea3ae8
|
||||||
@@ -1,4 +1,11 @@
|
|||||||
docsdir := @docdir@/doc
|
SUBDIRS = config
|
||||||
docs_DATA = config.md conditions.md distro.md plugins.md \
|
EXTRA_DIST = AUTHORS ChangeLog.md
|
||||||
service.md signals.md svc-machine.png cmdline.md
|
|
||||||
EXTRA_DIST = $(docs_DATA)
|
docsdir := @docdir@/doc
|
||||||
|
dist_docs_DATA = build.md cmdline.md commands.md conditions.md \
|
||||||
|
distro.md example.md features.md index.md initctl.md \
|
||||||
|
keventd.md plugins.md requirements.md runlevels.md \
|
||||||
|
runparts.md service.md signals.md state-machine.md \
|
||||||
|
watchdog.md
|
||||||
|
dist_docs_DATA += img/logo.png img/svc-machine.png img/svc-machine.svg \
|
||||||
|
img/alpine-screenshot2.png
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
config.md
|
index.md
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
Bootstrap
|
|
||||||
=========
|
|
||||||
|
|
||||||
0. Get bearings, disable kernel logs, initialize TTY and print banner,
|
|
||||||
unless `HOOK_BANNER` is defined, then call that instead
|
|
||||||
1. Prepare emergency shell, if enabled
|
|
||||||
2. Set up initial signal handlers
|
|
||||||
3. Set up default $PATH early
|
|
||||||
4. Mount `/proc` and `/sys`
|
|
||||||
5. Check kernel command line for `debug` to figure out log level
|
|
||||||
6. Load all `.so` plugins
|
|
||||||
7. Call `fsck` on file systems listed in `/etc/fstab`
|
|
||||||
8. Populate `/dev` using either udev or mdev, depending on system type
|
|
||||||
9. Parse `/etc/finit.conf`
|
|
||||||
10. Start built-in watchdog, if enabled and `WDT_DEVNODE` exists. This
|
|
||||||
means any WDT that requires a kernel module need to be either
|
|
||||||
compiled into the kernel, or insmod'ed in `/etc/finit.conf`
|
|
||||||
11. Load all `/etc/finit.d/*.conf` files and set hostname
|
|
||||||
12. Remount `/` read-write if `/` is listed in `/etc/fstab` without `ro`
|
|
||||||
13. Call 1st level hooks, `HOOK_ROOTFS_UP`
|
|
||||||
14. Mount all file systems listed in `/etc/fstab` and swap, if available.
|
|
||||||
On mount error `HOOK_MOUNT_ERROR` is called. After mount, regardless
|
|
||||||
of error, `HOOK_MOUNT_POST` is called
|
|
||||||
15. Enable SysV init signals
|
|
||||||
16. Call 2nd level hooks, `HOOK_BASEFS_UP`
|
|
||||||
17. Cleanup stale files from `/tmp/*` et al, handled by `bootmisc` plugin
|
|
||||||
18. Load kernel params from `/etc/sysctl.d/*.conf`, `/etc/sysctl.conf`
|
|
||||||
et al. (Supports all locations that SysV init does.), handled by
|
|
||||||
`procps` plugin
|
|
||||||
19. Start all 'S' runlevel tasks and services
|
|
||||||
20. Bring up loopback interface and all `/etc/network/interfaces`, if
|
|
||||||
the `.conf` setting `network <SCRIPT>` is set, it is called instead
|
|
||||||
21. Call 3rd level hooks, `HOOK_NETWORK_UP`
|
|
||||||
22. If `runparts <DIR>` is set, [run-parts(8)][] is called on `<DIR>`
|
|
||||||
23. Switch to the configured runlevel from `/etc/finit.conf`, default 2.
|
|
||||||
At every runlevel change all `*.conf` files in `/etc/finit.d/` are
|
|
||||||
(re)loaded and new services, tasks, and blocking run commands are
|
|
||||||
started. Provided they are allowed in the new runlevel and all of
|
|
||||||
their conditions, if any, are set.
|
|
||||||
24. Call 4th level hooks, `HOOK_SVC_UP`
|
|
||||||
25. Call `/etc/rc.local`, if it exists and is an executable shell script
|
|
||||||
26. Call 5th level (last) hooks, `HOOK_SYSTEM_UP`
|
|
||||||
27. Start all configured TTYs
|
|
||||||
|
|
||||||
In (19) and (23) tasks and services defined in `/etc/finit.conf` and
|
|
||||||
`/etc/finit.d/*.conf` are started.
|
|
||||||
|
|
||||||
Notice the seven hook points that are called at various point in the
|
|
||||||
bootstrap process. This is where plugins can extend the boot in any
|
|
||||||
way they please. There are other hook points available, for more on
|
|
||||||
this, see [plugins.md](plugins.md).
|
|
||||||
|
|
||||||
For instance, at `HOOK_BASEFS_UP` a plugin could read an XML file from a
|
|
||||||
USB stick, convert/copy its contents to the system's `/etc/` directory,
|
|
||||||
well before all 'S' runlevel tasks are started. This could be used with
|
|
||||||
system images that are created read-only and all configuration is stored
|
|
||||||
on external media.
|
|
||||||
|
|
||||||
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
|
||||||
@@ -1,15 +1,5 @@
|
|||||||
Building
|
Building Finit
|
||||||
========
|
==============
|
||||||
|
|
||||||
* [Introduction](#introduction)
|
|
||||||
* [Configure](#configure)
|
|
||||||
* [Example](#example)
|
|
||||||
* [Running](#running)
|
|
||||||
* [Debugging](#debugging)
|
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
------------
|
|
||||||
|
|
||||||
Finit comes with a traditional configure script to control features and
|
Finit comes with a traditional configure script to control features and
|
||||||
optional plugins to enable. It depends on two external libraries:
|
optional plugins to enable. It depends on two external libraries:
|
||||||
@@ -17,14 +7,15 @@ optional plugins to enable. It depends on two external libraries:
|
|||||||
- [libuEv][], the event loop
|
- [libuEv][], the event loop
|
||||||
- [libite][] (-lite), much needed frog DNA
|
- [libite][] (-lite), much needed frog DNA
|
||||||
|
|
||||||
**NOTE:** Most free/open source software that uses `configure` default
|
> [!IMPORTANT]
|
||||||
to install to `/usr/local`. However, some Linux distributions do no
|
> Most free/open source software packages that use `configure` default
|
||||||
longer search that path for installed software, e.g. Fedora and Alpine
|
> to install to `/usr/local`. However, some Linux distributions do no
|
||||||
Linux. To get finit's configure script to find its dependencies you
|
> longer search that path for installed software, e.g. Fedora and Alpine
|
||||||
have to help the `pkg-config` tool a bit if you do not change the
|
> Linux. To get finit's configure script to find its dependencies you
|
||||||
default prefix path:
|
> have to help the `pkg-config` tool a bit if you do not change the
|
||||||
|
> default prefix path:
|
||||||
PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure
|
>
|
||||||
|
> PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig ./configure
|
||||||
|
|
||||||
The configure script checks for all dependencies, including the correct
|
The configure script checks for all dependencies, including the correct
|
||||||
version of the above mentioned libraries. Currently required versions:
|
version of the above mentioned libraries. Currently required versions:
|
||||||
@@ -65,18 +56,19 @@ Below are a few of the main switches to configure:
|
|||||||
|
|
||||||
* `--enable-x11-common-plugin`: Enable the optional X Window `x11-common.so` plugin.
|
* `--enable-x11-common-plugin`: Enable the optional X Window `x11-common.so` plugin.
|
||||||
|
|
||||||
* `--with-sulgin`: Enable bundled `sulogin` program. Default is to use the
|
* `--with-sulogin`: Enable bundled `sulogin` program. Default is to use the
|
||||||
system `sulogin(8)`. The sulogin shipped with Finit *allows password-less*
|
system `sulogin(8)`. The sulogin shipped with Finit *allows password-less*
|
||||||
login if the `root` user is disabled or has no password at all.
|
login if the `root` user is disabled or has no password at all.
|
||||||
|
|
||||||
For more configure flags, see <kbd>./configure --help</kbd>
|
For more configure flags, see <kbd>./configure --help</kbd>
|
||||||
|
|
||||||
> **Note:** the configure script is not available in the GIT sources. It is
|
> [!NOTE]
|
||||||
> however included in (officially supported) released tarballs. The
|
> The configure script is not available in the GIT sources. It is
|
||||||
> idea is that you should not need GNU autotools to build, only the
|
> however included in (officially supported) released tarballs. The
|
||||||
> above mentioned dependencies, a POSIX shell, a C compiler and make.
|
> idea is that you should not need GNU autotools to build, only the
|
||||||
> Any contributing to Finit can generate it from `configure.ac` using
|
> above mentioned dependencies, a POSIX shell, a C compiler and make.
|
||||||
> the `autogen.sh` script.
|
> Any contributing to Finit can generate it from `configure.ac` using
|
||||||
|
> the `autogen.sh` script.
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
@@ -115,10 +107,11 @@ Linux config to:
|
|||||||
|
|
||||||
CONFIG_UEVENT_HELPER_PATH="/sbin/mdev"
|
CONFIG_UEVENT_HELPER_PATH="/sbin/mdev"
|
||||||
|
|
||||||
**Note:** If you run into problems starting Finit, take a look at
|
> [!TIP]
|
||||||
`finit.c`. One of the most common problems is a custom Linux kernel
|
> If you run into problems starting Finit, take a look at `finit.c`.
|
||||||
build that lack `CONFIG_DEVTMPFS`. Another is too much cruft in the
|
> One of the most common problems is a custom Linux kernel build that
|
||||||
system `/etc/fstab`.
|
> lack `CONFIG_DEVTMPFS`. Another is too much cruft in the system
|
||||||
|
> `/etc/fstab`.
|
||||||
|
|
||||||
|
|
||||||
Running
|
Running
|
||||||
@@ -157,8 +150,10 @@ enabled. The default Finit rescue mode configuration is installed into
|
|||||||
|
|
||||||
By default the a root shell, without login, is started.
|
By default the a root shell, without login, is started.
|
||||||
|
|
||||||
> **Note:** in this mode `initctl` will not work. Use the `-f` flag to
|
> [!IMPORTANT]
|
||||||
> force `reboot`, `shutdown`, or `poweroff`.
|
> In rescue mode `initctl` will not work, the same goes for `reboot`,
|
||||||
|
> `shutdown`, and `poweroff` commands, provided they are the Finit
|
||||||
|
> versions of these commands. Use the `-f` flag to force the action.
|
||||||
|
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
@@ -187,10 +182,10 @@ kernel usually reboots: `configure --enable-emergency-shell`. However,
|
|||||||
the behavior of Finit is severely limited when this is enabled, so use
|
the behavior of Finit is severely limited when this is enabled, so use
|
||||||
it only for debugging start up issues when Finit crashes.
|
it only for debugging start up issues when Finit crashes.
|
||||||
|
|
||||||
**NOTE:** Neither of these options should be enabled on production
|
> [!CAUTION]
|
||||||
systems since they can potentially give a user root access.
|
> None of these options should be enabled on production systems since
|
||||||
|
> they can potentially give a user root access.
|
||||||
|
|
||||||
|
[1]: https://github.com/finit-project/finit/releases/download/4.3/finit-4.3.tar.gz
|
||||||
[1]: ftp://troglobit.com/finit/finit-4.3.tar.gz
|
|
||||||
[libuEv]: https://github.com/troglobit/libuev
|
[libuEv]: https://github.com/troglobit/libuev
|
||||||
[libite]: https://github.com/troglobit/libite
|
[libite]: https://github.com/troglobit/libite
|
||||||
|
|||||||
@@ -4,14 +4,46 @@ Tips & Tricks with the kernel cmdline
|
|||||||
This document summarizes the different boot parameters that can be
|
This document summarizes the different boot parameters that can be
|
||||||
passed on the Linux kernel command line. Not limited to Finit.
|
passed on the Linux kernel command line. Not limited to Finit.
|
||||||
|
|
||||||
The `bool` setting is one of `on, off, true false, 1, 0`.
|
> [!IMPORTANT]
|
||||||
|
> Remember to use `--` to separate kernel parameters from parameters to
|
||||||
|
> init. E.g., `init=/sbin/finit -- finit.debug rescue`
|
||||||
|
|
||||||
> **NOTE:** remember to use `--` to separate kernel parameters from
|
The `bool` setting is one of `on, off, true false, 1, 0`.
|
||||||
> parameters to init. E.g., `init=/sbin/finit -- finit.debug rescue`
|
|
||||||
|
|
||||||
* `debug`: Enable kernel debug. Debug messages are printed to the
|
* `debug`: Enable kernel debug. Debug messages are printed to the
|
||||||
console until Finit starts up, unless `loglevel=7` (below) is used.
|
console until Finit starts up, unless `loglevel=7` (below) is used.
|
||||||
|
|
||||||
|
* `fsck.mode=<auto,force,skip>`, default: `auto`, unless built with
|
||||||
|
`configure --enable-fastboot`, in which case the default is `skip`
|
||||||
|
|
||||||
|
* `fsck.repair=<preen,yes,no>`, default: `preen`, unless built with
|
||||||
|
`configure --enable-fsckfix`, in which case the default is `yes`.
|
||||||
|
This configure option also sets `fsck.mode=force`, unless fastboot
|
||||||
|
is selected at the same time. I.e., the `--enable-fastboot` build
|
||||||
|
option overrides the `fsck.mode` default value.
|
||||||
|
|
||||||
|
* `finit.cond=foo[,bar[,baz]]`: set `<boot/foo>` condition, optionally
|
||||||
|
multiple conditions can be set using the same option, separated with a
|
||||||
|
comma. Alternatively, multiple `foo.cond=arg` can be given. Each will
|
||||||
|
result in a `<boot/arg>` condition being set to control the rest of the
|
||||||
|
system bootstrap.
|
||||||
|
|
||||||
|
Very useful for selecting different boot modes, e.g. manufacturing test,
|
||||||
|
firmware upgrade, or [rescue mode][rescue].
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> `<boot/...>` conditions cannot be cleared with `initctl`!
|
||||||
|
|
||||||
|
* `finit.config=/path/to/alternative/finit.conf`: override the
|
||||||
|
compile-time bootstrap config file, default:
|
||||||
|
|
||||||
|
./configure --with-config=/etc/finit.conf
|
||||||
|
|
||||||
|
Useful when starting up in various [rescue mode][rescue], factory, or
|
||||||
|
production test setups. Use the top-level configuration file
|
||||||
|
directive `rcsd /path/to/finit.d` to override the default rcS.d
|
||||||
|
directory.
|
||||||
|
|
||||||
* `finit.debug[=bool]`: Enable finit debug. This is operated
|
* `finit.debug[=bool]`: Enable finit debug. This is operated
|
||||||
independently of the kernel `debug` setting. New as of Finit v4.
|
independently of the kernel `debug` setting. New as of Finit v4.
|
||||||
|
|
||||||
@@ -43,7 +75,7 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
|
|||||||
* `init=/bin/sh`: Bypass system default init and tell kernel to start a
|
* `init=/bin/sh`: Bypass system default init and tell kernel to start a
|
||||||
shell. Note, this shell is very limited and does not support
|
shell. Note, this shell is very limited and does not support
|
||||||
signals and has no job control. Recommend using, and modifying,
|
signals and has no job control. Recommend using, and modifying,
|
||||||
`rescue` mode instead.
|
[`rescue` mode][rescue] instead.
|
||||||
|
|
||||||
* `loglevel=<0-7>`, sets the kernel's log level, which is more granular
|
* `loglevel=<0-7>`, sets the kernel's log level, which is more granular
|
||||||
than `debug`. Also, when `loglevel=7`, Finit will *not disable*
|
than `debug`. Also, when `loglevel=7`, Finit will *not disable*
|
||||||
@@ -58,20 +90,22 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
|
|||||||
* `quiet`: Suppress kernel logging to console, except for warnings and
|
* `quiet`: Suppress kernel logging to console, except for warnings and
|
||||||
errors. Also, see `loglevel` and `quiet` above.
|
errors. Also, see `loglevel` and `quiet` above.
|
||||||
|
|
||||||
* `rescue`: Start rescue/maintenance mode. If your system comes with
|
* `rescue`: Start [rescue/maintenance mode][rescue]. If your system
|
||||||
the bundled `sulogin` program (Finit, or from util-linux/Busybox),
|
comes with the bundled `sulogin` program (Finit, or from util-linux,
|
||||||
you will be given a root login to a maintenance shell. However, if
|
or Busybox), you will be given a root login to a maintenance shell.
|
||||||
`sulogin` is missing, the file `/lib/finit/rescue.conf` is read and
|
However, if `sulogin` is missing, the file `/lib/finit/rescue.conf`
|
||||||
the system booted in a limited fallback mode. See [config.md][]
|
is read and the system booted in a limited fallback mode.
|
||||||
for more information.
|
|
||||||
|
This option can be disabled with `configure --without-rescue`
|
||||||
|
|
||||||
**Note:** in this mode `initctl` will not work. Correct the problem
|
**Note:** in this mode `initctl` will not work. Correct the problem
|
||||||
and use `reboot -f` to force reboot.
|
and use `reboot -f` to force reboot.
|
||||||
|
|
||||||
* `single`, or `S`: Single user mode, runlevel 1, in Finit. Useful to
|
* `single`, or `S`: Overrides the configured runlevel (default: 2) to go
|
||||||
debug problems with the regular runlevel. All services and TTYs in
|
to after bootstrap by forcing it to runlevel 1, this is also known
|
||||||
`[1]` will be started, so a `tty [1] @console nologin` configuration
|
as single user mode. Useful to debug startup problems. All services
|
||||||
presents you with a root console without login.
|
and TTYs in `[1]` will be started, so a `tty [1] @console nologin`
|
||||||
|
configuration presents you with a root console without login.
|
||||||
|
|
||||||
* `1-9`, except `6`: override the configured `runlevel`. Like the `S`
|
* `1-9`, except `6`: override the configured `runlevel`. Like the `S`
|
||||||
and `rescue`, giving a single number on the kernel command line tells
|
and `rescue`, giving a single number on the kernel command line tells
|
||||||
@@ -81,5 +115,5 @@ The `bool` setting is one of `on, off, true false, 1, 0`.
|
|||||||
|
|
||||||
For more on kernel boot parameters, see the man page [bootparam(7)][].
|
For more on kernel boot parameters, see the man page [bootparam(7)][].
|
||||||
|
|
||||||
[config.md]: config.md#rescue-mode
|
[rescue]: config/rescue.md
|
||||||
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
|
[bootparam(7)]: https://www.man7.org/linux/man-pages/man7/bootparam.7.html
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Rebooting & Halting
|
||||||
|
===================
|
||||||
|
|
||||||
|
Traditionally, rebooting and halting a UNIX system is done by switching
|
||||||
|
to the corresponding runlevel (0 or 6). Over time this has changed and
|
||||||
|
Finit comes with its own tooling providing: `shutdown`, `reboot`,
|
||||||
|
`poweroff`, and `suspend`. These commands are also available from the
|
||||||
|
[`initctl`](initctl.md) tool.
|
||||||
|
|
||||||
|
For compatibility reasons Finit listens to the same set of signals as
|
||||||
|
BusyBox init. This is not 100% compatible with SysV init, but clearly
|
||||||
|
the more common combination for Finit. For more details, see the
|
||||||
|
[Signal](signals.md) section.
|
||||||
@@ -1,21 +1,8 @@
|
|||||||
Finit Conditions
|
Conditions
|
||||||
================
|
==========
|
||||||
|
|
||||||

|
Conditions were added to Finit in v3 with the intention of providing a
|
||||||
|
mechanism for common synchronization problems. For example:
|
||||||
* [Introduction](#introduction)
|
|
||||||
* [Triggering](#triggering)
|
|
||||||
* [Built-in Conditions](#built-in--conditions)
|
|
||||||
* [Debugging](#debugging)
|
|
||||||
* [Internals](#internals)
|
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
------------
|
|
||||||
|
|
||||||
Conditions are a new addition to Finit, introduced in v3, with the
|
|
||||||
intention of providing a mechanism for common synchronization problems.
|
|
||||||
For example:
|
|
||||||
|
|
||||||
- *"wait for service A to start before starting service B"*, or
|
- *"wait for service A to start before starting service B"*, or
|
||||||
- *"wait for basic network access to be available"*
|
- *"wait for basic network access to be available"*
|
||||||
@@ -27,6 +14,16 @@ specified separated by comma. Multiple conditions are logically AND'ed
|
|||||||
during evaluation, i.e. all conditions must be satisfied in order for a
|
during evaluation, i.e. all conditions must be satisfied in order for a
|
||||||
service to run.
|
service to run.
|
||||||
|
|
||||||
|
Two special prefixes can be used inside the angle brackets:
|
||||||
|
|
||||||
|
- `!` -- service does not support `SIGHUP` (noreload), or run/task
|
||||||
|
should not block runlevel changes (i.e., bootstrap)
|
||||||
|
- `~` -- propagate reload from this dependency, see below
|
||||||
|
|
||||||
|
Finit guarantees by default that all run/tasks run (at least) once
|
||||||
|
per runlevel. For most tasks this is a good default, for example
|
||||||
|
checking SSH host keys or loading keymap. However, for conditions
|
||||||
|
that are unlikely to happen it is not. (See example below.)
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
@@ -35,22 +32,65 @@ service to run.
|
|||||||
In this example the Network monitor daemon `netd` is not started until
|
In this example the Network monitor daemon `netd` is not started until
|
||||||
both the `pid/setupd` *and* `pid/zebra` conditions are satisfied. A
|
both the `pid/setupd` *and* `pid/zebra` conditions are satisfied. A
|
||||||
`pid/` condition is satisfied by the corresponding service's PID file
|
`pid/` condition is satisfied by the corresponding service's PID file
|
||||||
being created.
|
being created, i.e., the service's default readiness notification.
|
||||||
|
|
||||||
**NOTE:** Conditions also stop services when a condition is no longer
|
> [!IMPORTANT]
|
||||||
asserted. I.e., if the Zebra process above stops or restarts, netd
|
> Conditions also stop services when a condition is no longer asserted.
|
||||||
will also stop or restart.
|
> I.e., if the `zebra` process above stops or restarts, `netd` will also
|
||||||
|
> stop or restart.
|
||||||
|
|
||||||
|
Another example is `dropbear`, it does not support `SIGHUP`, but we can
|
||||||
|
also see optional sourcing of arguments from an environment file:
|
||||||
|
|
||||||
|
service [2345789] <!> env:-/etc/default/dropbear dropbear -F -R $DROPBEAR_ARGS -- Dropbear SSH daemon
|
||||||
|
|
||||||
|
Finally, the weird "block runlevel changes" example. Here we see what
|
||||||
|
happens when Finit receives `SIGPWR`, sent from a power daemon like
|
||||||
|
[powstatd(8)][]. A condition is asserted and a user can set up their
|
||||||
|
own task to act on it. We do not want this task to block Finit from
|
||||||
|
moving to the next runlevel after bootstrap, so we set `<!>`:
|
||||||
|
|
||||||
|
task [S0123456789] <!sys/pwr/fail> name:pwrfail initctl poweroff -- Power failure, shutting down
|
||||||
|
|
||||||
|
|
||||||
|
Propagating Reload in Dependencies
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
By default, when a service reloads during `initctl reload`, dependent
|
||||||
|
services are paused (`SIGSTOP`) and simply resumed (`SIGCONT`) when the
|
||||||
|
condition is reasserted. This is correct for barrier-style dependencies
|
||||||
|
like `<pid/syslogd>`, where dependents just need syslogd running and do
|
||||||
|
not care if it reloads its config.
|
||||||
|
|
||||||
|
For services that need to react when their upstream reloads, the `~`
|
||||||
|
prefix propagates the reload from the dependency:
|
||||||
|
|
||||||
|
service <pid/svc_a> name:svc_b /sbin/svc_b -- Needs A (barrier)
|
||||||
|
service <!~pid/svc_b> name:svc_c /sbin/svc_c -- Propagate reload from B
|
||||||
|
|
||||||
|
Here, `<~pid/svc_b>` means: propagate a reload of `svc_b` to `svc_c`.
|
||||||
|
When `svc_b` reloads, `svc_c` will be restarted (because of `!`,
|
||||||
|
noreload) instead of merely resumed. If `svc_c` supported `SIGHUP`
|
||||||
|
(no `!` prefix), it would be sent `SIGHUP` instead.
|
||||||
|
|
||||||
|
This is similar to systemd's `PropagatesReloadTo=` directive, but
|
||||||
|
declared on the consumer side rather than the provider side.
|
||||||
|
|
||||||
|
|
||||||
Triggering
|
Triggering
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Conditions are mainly triggered (asserted) by built-in plugins, e.g.,
|
Conditions are mainly triggered (asserted) by built-in plugins, e.g.,
|
||||||
`netlink.so` and `pidfile.so`, see below for built-in conditions. Finit
|
|
||||||
also supports user-defined conditions, sometimes referred to as static
|
- `netlink.so`: provides `<net/...>`
|
||||||
or one-shot conditions. They live in the `<usr/...` namespace and are
|
- `pidfile.so`: provides `<pid/...>`
|
||||||
constrained to a flat hierarchy without any sub-directories, unlike the
|
- Cmdline `finit.cond=arg`: provides `<boot/arg>`
|
||||||
pidfile plugin, for instance.
|
|
||||||
|
See below for built-in conditions. Finit also supports user-defined
|
||||||
|
conditions, sometimes referred to as static or one-shot conditions.
|
||||||
|
They live in the `<usr/...>` namespace and are constrained to a flat
|
||||||
|
hierarchy without any sub-directories, unlike the pidfile plugin, for
|
||||||
|
instance.
|
||||||
|
|
||||||
User-defined conditions are controlled using the `initctl cond set` and
|
User-defined conditions are controlled using the `initctl cond set` and
|
||||||
`initctl cond clear` commands:
|
`initctl cond clear` commands:
|
||||||
@@ -60,7 +100,8 @@ User-defined conditions are controlled using the `initctl cond set` and
|
|||||||
|
|
||||||
The purpose of user-defined conditions is to be able to start or stop
|
The purpose of user-defined conditions is to be able to start or stop
|
||||||
services, or run/task jobs, on external site-dependent stimuli.
|
services, or run/task jobs, on external site-dependent stimuli.
|
||||||
Example:
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
service [2345] <usr/foo> alarm --arg foo -- Foo alarm
|
service [2345] <usr/foo> alarm --arg foo -- Foo alarm
|
||||||
|
|
||||||
@@ -78,24 +119,49 @@ on this, see [Internals](#internals).) Thus, after a reconfiguration it
|
|||||||
is up to the "owner" of the condition to convey the new (or possibly
|
is up to the "owner" of the condition to convey the new (or possibly
|
||||||
unchanged) state of it.
|
unchanged) state of it.
|
||||||
|
|
||||||
> **Note:** For `pid/` conditions it is expected that services "touch"
|
|
||||||
> or recreate their PID file on `SIGHUP`.
|
|
||||||
|
|
||||||
Static (one-shot) conditions, like `usr/`, never enter the `flux` state.
|
Static (one-shot) conditions, like `usr/`, never enter the `flux` state.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> For `pid/` conditions it is expected that the service reassert, i.e.,
|
||||||
|
> "touch" or recreate, their PID file on `SIGHUP`. This can be done by
|
||||||
|
> calling `utimensat()` on the PID file. Provided, of course, that the
|
||||||
|
> service supports reloading on `SIGHUP`, otherwise it will be restarted
|
||||||
|
> by Finit when they instead exit on the signal. For such services, use
|
||||||
|
> `<!>` to tell Finit the service does not support `SIGHUP`.
|
||||||
|
|
||||||
|
|
||||||
Built-in Conditions
|
Built-in Conditions
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Finit comes with a set of plugins for conditions: `pidfile`, `netlink`,
|
Finit comes with a set of plugins for conditions:
|
||||||
`sys`, and `usr`. The `pidfile` plugin (recursively) watches `/run/`
|
|
||||||
(recursively) for PID files created by the monitored services, and sets
|
- `devmon` (built-in)
|
||||||
a corresponding condition in the `pid/` namespace. Similarly, the
|
- `netlink`
|
||||||
`netlink` plugin provides basic conditions for when an interface is
|
- `pidfile`
|
||||||
brought up/down and when a default route (gateway) is set, in the `net/`
|
- `sys`
|
||||||
namespace. The `sys` and `usr` plugins monitor are passive condition
|
- `usr`
|
||||||
monitors where the action is provided by `keventd`, signal handlers,
|
|
||||||
and in the case of `usr`, the end-user via the `initctl` tool
|
The `devmon` (built-in) plugin monitors `/dev` and `/dev/dir` for device
|
||||||
|
nodes being created and removed. It is active only when a run, task, or
|
||||||
|
service has declared a `<dev/foo>` or `<dev/dir/bar>` condition.
|
||||||
|
|
||||||
|
The `pidfile` plugin (recursively) watches `/run/` (recursively) for PID
|
||||||
|
files created by the monitored services, and sets a corresponding
|
||||||
|
condition in the `pid/` namespace.
|
||||||
|
|
||||||
|
Similarly, the `netlink` plugin provides basic conditions for when an
|
||||||
|
interface is brought up/down and when a default route (gateway) is set,
|
||||||
|
in the `net/` namespace.
|
||||||
|
|
||||||
|
The `sys` and `usr` plugins monitor are passive condition monitors where
|
||||||
|
the action is provided by `keventd`, signal handlers, and in the case of
|
||||||
|
`usr`, the end-user via the `initctl` tool.
|
||||||
|
|
||||||
|
Additionally, the various states of a run/task/sysv/service can also be
|
||||||
|
used as conditions, the image above shows the state names. The syntax
|
||||||
|
for a `service` type process: `<service/foo/STATE>`. The other types,
|
||||||
|
in particular run/task/sysv, there are the additional states `success`
|
||||||
|
and `failure`.
|
||||||
|
|
||||||
With the example listed above, finit does not start the `/sbin/netd`
|
With the example listed above, finit does not start the `/sbin/netd`
|
||||||
daemon until `setupd` and `zebra` has started *and* created their PID
|
daemon until `setupd` and `zebra` has started *and* created their PID
|
||||||
@@ -114,14 +180,19 @@ Built-in conditions:
|
|||||||
- `net/<IFNAME>/exist`
|
- `net/<IFNAME>/exist`
|
||||||
- `net/<IFNAME>/up`
|
- `net/<IFNAME>/up`
|
||||||
- `net/<IFNAME>/running`
|
- `net/<IFNAME>/running`
|
||||||
|
- `service/<NAME[:ID]>/<STATE>`
|
||||||
|
- `{run, task, sysv}/<NAME[:ID]>/{<STATE>, success, failure}`
|
||||||
- `sys/pwr/ac`
|
- `sys/pwr/ac`
|
||||||
- `sys/pwr/fail`
|
- `sys/pwr/fail`
|
||||||
- `sys/key/ctrlaltdel`
|
- `sys/key/ctrlaltdel`
|
||||||
- `usr/foo`
|
- `usr/foo`
|
||||||
|
- `boot/arg`
|
||||||
|
- `dev/node` and `dev/dir/node`
|
||||||
|
|
||||||
**Note:** `up` means administratively up, the interface flag `IFF_UP`.
|
> [!NOTE]
|
||||||
`running` is the `IFF_RUNNING` flag, meaning operatively up. The
|
> Here, `up` means administratively up, the interface flag `IFF_UP`.
|
||||||
difference is that `running` tells if the NIC has link.
|
> `running` is the `IFF_RUNNING` flag, meaning operatively up. The
|
||||||
|
> difference is that `running` tells if the NIC has link.
|
||||||
|
|
||||||
|
|
||||||
Composition
|
Composition
|
||||||
@@ -147,14 +218,19 @@ When Finit configuration files are changed and the `initctl reload`
|
|||||||
command is called, it is expected of services to touch their PID files
|
command is called, it is expected of services to touch their PID files
|
||||||
for Finit to reassert their conditions.
|
for Finit to reassert their conditions.
|
||||||
|
|
||||||
|
Similarly, when a single service is reloaded with `initctl reload NAME`,
|
||||||
|
its conditions are cleared and reasserted, ensuring dependent services
|
||||||
|
are properly updated.
|
||||||
|
|
||||||
Daemons that don't create PID files, or fail to touch them on reload,
|
Daemons that don't create PID files, or fail to touch them on reload,
|
||||||
can be worked around by using the `pid:/path/to/file.pid` syntax in
|
can be worked around by using the `pid:/path/to/file.pid` syntax in
|
||||||
the service stanza for the daemon. It is far from optimal since any
|
the service stanza for the daemon. It is far from optimal since any
|
||||||
synchronization of depending services may fail due to the daemon not
|
synchronization of depending services may fail due to the daemon not
|
||||||
having reinitialized/created their IPC sockets, or similar.
|
having reinitialized/created their IPC sockets, or similar.
|
||||||
|
|
||||||
> **Note:** in versions of Finit prior to v4, the PID conditions were
|
> [!NOTE]
|
||||||
> called 'svc' conditions, and they were far more complex.
|
> In versions of Finit prior to v4, the PID conditions were called 'svc'
|
||||||
|
> conditions, and they were far more complex.
|
||||||
|
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
@@ -163,7 +239,7 @@ Debugging
|
|||||||
If a service is not being started as it should, the problem might be
|
If a service is not being started as it should, the problem might be
|
||||||
that one of its conditions is not in the expected state. Use the
|
that one of its conditions is not in the expected state. Use the
|
||||||
command `initctl status` to inspect service status. Services in the
|
command `initctl status` to inspect service status. Services in the
|
||||||
`ready` state are pending a condition.
|
`waiting` state are pending a condition.
|
||||||
|
|
||||||
In that situation, running `initctl cond show` reveals which of the
|
In that situation, running `initctl cond show` reveals which of the
|
||||||
conditions that are not satisfied. Listed as `off` below.
|
conditions that are not satisfied. Listed as `off` below.
|
||||||
@@ -217,6 +293,8 @@ A condition is always in one of three states:
|
|||||||
All conditions that have not explicitly been set are interpreted as
|
All conditions that have not explicitly been set are interpreted as
|
||||||
being in the `off` state.
|
being in the `off` state.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
When a reconfiguration is requested, Finit transitions all conditions to
|
When a reconfiguration is requested, Finit transitions all conditions to
|
||||||
the `flux` state. As a result, services that depend on a condition are
|
the `flux` state. As a result, services that depend on a condition are
|
||||||
sent `SIGSTOP`. Once the new state of the condition is asserted, the
|
sent `SIGSTOP`. Once the new state of the condition is asserted, the
|
||||||
@@ -227,7 +305,14 @@ This STOP/CONT handling minimizes the number of unnecessary service
|
|||||||
restarts that would otherwise occur because a depending service was sent
|
restarts that would otherwise occur because a depending service was sent
|
||||||
`SIGHUP` for example.
|
`SIGHUP` for example.
|
||||||
|
|
||||||
|
Services with the `~` prefix are an exception to this rule: when their
|
||||||
|
conditions return to `on` after being in `flux`, the reload is propagated
|
||||||
|
-- the service is reloaded (SIGHUP) or restarted (noreload `!`) instead
|
||||||
|
of simply being resumed.
|
||||||
|
|
||||||
Therefore, any plugin that supplies Finit with conditions must ensure
|
Therefore, any plugin that supplies Finit with conditions must ensure
|
||||||
that their state is updated after each reconfiguration. This can be
|
that their state is updated after each reconfiguration. This can be
|
||||||
done by binding to the `HOOK_SVC_RECONF` hook. For an example of how
|
done by binding to the `HOOK_SVC_RECONF` hook. For an example of how
|
||||||
to do this, see `plugins/pidfile.c`.
|
to do this, see `plugins/pidfile.c`.
|
||||||
|
|
||||||
|
[powstatd(8)]: https://manpages.ubuntu.com/manpages/trusty/en/man8/powstatd.8.html
|
||||||
|
|||||||
@@ -1,796 +0,0 @@
|
|||||||
Configuration
|
|
||||||
=============
|
|
||||||
|
|
||||||
* [Introduction](#introduction)
|
|
||||||
* [Service Environment](#service-environment)
|
|
||||||
* [Service Wrapper Scripts](#service-wrapper-scripts)
|
|
||||||
* [Cgroups](#cgroups)
|
|
||||||
* [Configuration File Syntax](#configuration-file-syntax)
|
|
||||||
* [Hostname](#hostname)
|
|
||||||
* [Kernel Modules](#kernel-modules)
|
|
||||||
* [Networking](#networking)
|
|
||||||
* [Resource Limits](#resource-limits)
|
|
||||||
* [Runlevels](#runlevels)
|
|
||||||
* [One-shot Commands (sequence)](#one-shot-commands--sequence-)
|
|
||||||
* [One-shot Commands (parallel)](#one-shot-commands--parallel-)
|
|
||||||
* [SysV Init Scripts](#sysv-init-scripts)
|
|
||||||
* [Services](#services)
|
|
||||||
* [Run-parts Scripts](#run-parts-scripts)
|
|
||||||
* [Including Finit Configs](#including-finit-configs)
|
|
||||||
* [General Logging](#general-logging)
|
|
||||||
* [TTYs and Consoles](#ttys-and-consoles)
|
|
||||||
* [Non-privileged Services](#non-privileged-services)
|
|
||||||
* [Redirecting Output](#redirecting-output)
|
|
||||||
* [Rescue Mode](#rescue-mode)
|
|
||||||
* [Limitations](#limitations)
|
|
||||||
* [/etc/finit.conf](#etcfinitconf)
|
|
||||||
* [/etc/finit.d](#etcfinitd)
|
|
||||||
* [Watchdog](#watchdog)
|
|
||||||
* [keventd](#keventd)
|
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
------------
|
|
||||||
|
|
||||||
Finit can be configured using only the original `/etc/finit.conf` file
|
|
||||||
or in combination with `/etc/finit.d/*.conf`. Useful for package-based
|
|
||||||
Linux distributions -- each package can provide its own "script" file.
|
|
||||||
|
|
||||||
- `/etc/finit.conf`: main configuration file
|
|
||||||
- `/etc/finit.d/*.conf`: snippets, usually one service per file
|
|
||||||
|
|
||||||
Not all configuration directives are available in `/etc/finit.d/*.conf`
|
|
||||||
and some directives are only available at [bootstrap][], runlevel `S`,
|
|
||||||
see the section [Limitations](#limitations) below for details.
|
|
||||||
|
|
||||||
To add a new service, drop a `.conf` file in `/etc/finit.d` and run
|
|
||||||
`initctl reload`. (It is also possible to `SIGHUP` to PID 1, or call
|
|
||||||
`finit q`, but that has been deprecated with the `initctl` tool). Finit
|
|
||||||
monitors all known active `.conf` files, so if you want to force a
|
|
||||||
restart of any service you can touch its corresponding `.conf` file in
|
|
||||||
`/etc/finit.d` and call `initctl reload`. Finit handle any and all
|
|
||||||
conditions and dependencies between services automatically.
|
|
||||||
|
|
||||||
It is also possible to drop `.conf` files in `/etc/finit.d/available/`
|
|
||||||
and use `initctl enable` to enable a service `.conf` file. This may be
|
|
||||||
useful in particular to Linux distributions that may want to install all
|
|
||||||
files for a package and let the user decide when to enable a service.
|
|
||||||
|
|
||||||
On `initctl reload` the following is checked for all services:
|
|
||||||
|
|
||||||
- If a service's `.conf` file has been removed, or its conditions are no
|
|
||||||
longer satisfied, the service is stopped.
|
|
||||||
- If the file is modified, or a service it depends on has been reloaded,
|
|
||||||
the service is reloaded (stopped and started).
|
|
||||||
- If a new service is added it is automatically started — respecting
|
|
||||||
runlevels and return values from any callbacks.
|
|
||||||
|
|
||||||
For more info on the different states of a service, see the separate
|
|
||||||
document [Finit Services](service.md).
|
|
||||||
|
|
||||||
> When running <kbd>make install</kbd> no default `/etc/finit.conf` is
|
|
||||||
> installed since system requirements differ too much. There are some
|
|
||||||
> examples in the `contrib/` directory, which can be used as a base.
|
|
||||||
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
In Finit v4.3 support for setting environment variables in `finit.conf`,
|
|
||||||
and any `*.conf`, was added. It is worth noting that these are global
|
|
||||||
and *shared with all* services -- the only way to have service-local
|
|
||||||
environment is detailed in the next section.
|
|
||||||
|
|
||||||
The syntax for global environment variables is straight forward:
|
|
||||||
|
|
||||||
foo=bar
|
|
||||||
baz="qux"
|
|
||||||
|
|
||||||
On reload of .conf files, all tracked environment variables are cleared
|
|
||||||
so if `foo=bar` is removed from `finit.conf`, or any `finit.d/*.conf`
|
|
||||||
file, it will no longer be used by Finit or any new (!) started
|
|
||||||
run/tasks or services. The environment of already started processes can
|
|
||||||
not be changed.
|
|
||||||
|
|
||||||
The only variables reset to sane defaults on .conf reload are:
|
|
||||||
|
|
||||||
PATH=_PATH_STDPATH
|
|
||||||
SHELL=_PATH_BSHELL
|
|
||||||
LOGNAME=root
|
|
||||||
USER=root
|
|
||||||
|
|
||||||
It is entirely possible to override these as well from the .conf files,
|
|
||||||
but be careful. Changing SHELL changes the behavior of `system()` and a
|
|
||||||
lot of other commands as well.
|
|
||||||
|
|
||||||
|
|
||||||
Service Environment
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Finit supports sourcing environment variables from `/etc/default/*`, or
|
|
||||||
similar `--with-sysconfig=DIR`. This is a common pattern from SysV init
|
|
||||||
scripts, where the start-stop script is a generic script for the given
|
|
||||||
service, `foo`, and the options for the service are sourced from the
|
|
||||||
file `/etc/default/foo`. Like this:
|
|
||||||
|
|
||||||
* `/etc/default/foo`:
|
|
||||||
|
|
||||||
FOO_OPTIONS=--extra-arg="bar" -s -x
|
|
||||||
|
|
||||||
* `/etc/finit.conf`:
|
|
||||||
|
|
||||||
service [2345] env:-/etc/default/foo foo -n $FOO_OPTIONS -- Example foo daemon
|
|
||||||
|
|
||||||
Here the service `foo` is started with `-n`, to make sure it runs in the
|
|
||||||
foreground, and the with the options found in the environment file. With
|
|
||||||
the `ps` command we can see that the process is started with:
|
|
||||||
|
|
||||||
foo -n --extra-arg=bar -s -x
|
|
||||||
|
|
||||||
> **Note:** the leading `-` determines if Finit should treat a missing
|
|
||||||
> environment file as blocking the start of the service or not. When
|
|
||||||
> `-` is used, a missing environment file does *not* block the start.
|
|
||||||
|
|
||||||
|
|
||||||
Service Wrapper Scripts
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
If your service requires to run additional commands, executed before the
|
|
||||||
service is actually started, like the systemd `ExecStartPre`, you can
|
|
||||||
use a wrapper shell script to start your service.
|
|
||||||
|
|
||||||
The Finit service `.conf` file can be put into `/etc/finit.d/available`,
|
|
||||||
so you can control the service using `initctl`. Then use the path to
|
|
||||||
the wrapper script in the Finit `.conf` service stanza. The following
|
|
||||||
example employs a wrapper script in `/etc/start.d`.
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
* `/etc/finit.d/available/program.conf`:
|
|
||||||
|
|
||||||
service [235] <!> /etc/start.d/program -- Example Program
|
|
||||||
|
|
||||||
* `/etc/start.d/program:`
|
|
||||||
|
|
||||||
#!/bin/sh
|
|
||||||
# Prepare the command line options
|
|
||||||
OPTIONS="-u $(cat /etc/username)"
|
|
||||||
|
|
||||||
# Execute the program
|
|
||||||
exec /usr/bin/program $OPTIONS
|
|
||||||
|
|
||||||
> **Note:** the example sets `<!>` to denote that it doesn't support
|
|
||||||
> `SIGHUP`. That way Finit will stop/start the service
|
|
||||||
> instead of sending SIGHUP at restart/reload events.
|
|
||||||
|
|
||||||
|
|
||||||
Cgroups
|
|
||||||
-------
|
|
||||||
|
|
||||||
There are three major cgroup configuration directives:
|
|
||||||
|
|
||||||
1. Global top-level group: init, system, user, or a custom group
|
|
||||||
2. Selecting a top-level group for a set of run/task/services
|
|
||||||
3. Per run/task/service limits
|
|
||||||
|
|
||||||
Top-level group configuration.
|
|
||||||
|
|
||||||
# Top-level cgroups and their default settings. All groups mandatory
|
|
||||||
# but more can be added, max 8 groups in total currently. The cgroup
|
|
||||||
# 'root' is also available, reserved for RT processes. Settings are
|
|
||||||
# as-is, only one shorthand 'mem.' exists, other than that it's the
|
|
||||||
# cgroup v2 controller default names.
|
|
||||||
cgroup init cpu.weight:100
|
|
||||||
cgroup user cpu.weight:100
|
|
||||||
cgroup system cpu.weight:9800
|
|
||||||
|
|
||||||
Adding an extra cgroup `maint/` will require you to adjust the weight of
|
|
||||||
the above three. We leave `init/` and `user/` as-is reducing weight of
|
|
||||||
`system/` to 9700.
|
|
||||||
|
|
||||||
cgroup system cpu.weight:9700
|
|
||||||
|
|
||||||
# Example extra cgroup 'maint'
|
|
||||||
cgroup maint cpu.weight:100
|
|
||||||
|
|
||||||
By default, the `system/` cgroup is selected for almost everything. The
|
|
||||||
`init/` cgroup is reserved for PID 1 itself and its closest relatives.
|
|
||||||
The `user/` cgroup is for local TTY logins spawned by getty.
|
|
||||||
|
|
||||||
To select a different top-level cgroup, e.g. `maint/`, one can either
|
|
||||||
define it for a group of run/task/service directives in a `.conf` or per
|
|
||||||
each stanza:
|
|
||||||
|
|
||||||
cgroup.maint
|
|
||||||
service [...] <...> /path/to/foo args -- description
|
|
||||||
service [...] <...> /path/to/bar args -- description
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
service [...] <...> cgroup.maint /path/to/foo args -- description
|
|
||||||
|
|
||||||
The latter form also allows per-stanza limits on the form:
|
|
||||||
|
|
||||||
service [...] <...> cgroup.maint:cpu.max:10000,mem.max:655360 /path/to/foo args -- description
|
|
||||||
|
|
||||||
Notice the comma separation and the `mem.` exception to the rule: every
|
|
||||||
cgroup setting maps directly to cgroup v2 syntax. I.e., `cpu.max` maps
|
|
||||||
to the file `/sys/fs/cgroup/maint/foo/cpu.max`. There is no filtering,
|
|
||||||
except for expanding the shorthand `mem.` to `memory.`, if the file is
|
|
||||||
not available, either the cgroup controller is not available in your
|
|
||||||
Linux kernel, or the name is misspelled.
|
|
||||||
|
|
||||||
> Linux cgroups and details surrounding values are not explained in the
|
|
||||||
> Finit documentation. The Linux admin-guide cover this well:
|
|
||||||
> <https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html>
|
|
||||||
|
|
||||||
|
|
||||||
Configuration File Syntax
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
### Hostname
|
|
||||||
|
|
||||||
**Syntax:** `host <NAME>`, or `hostname <NAME>`
|
|
||||||
|
|
||||||
Set system hostname to NAME, unless `/etc/hostname` exists in which case
|
|
||||||
the contents of that file is used.
|
|
||||||
|
|
||||||
Deprecated. We recommend using `/etc/hostname` instead.
|
|
||||||
|
|
||||||
> **Note:** only read and executed in runlevel S ([bootstrap][]).
|
|
||||||
|
|
||||||
|
|
||||||
### Kernel Modules
|
|
||||||
|
|
||||||
**Syntax:** `module <MODULE> [ARGS]`
|
|
||||||
|
|
||||||
Load a kernel module, with optional arguments. Similar to `insmod`
|
|
||||||
command line tool.
|
|
||||||
|
|
||||||
Deprecated, there is both a `modules-load.so` and a `modprobe.so` plugin
|
|
||||||
that can handle module loading better. The former supports loading from
|
|
||||||
`/etc/modules-load.d/`, the latter uses kernel modinfo to automatically
|
|
||||||
load (or coldplug) every required module. For hotplug we recommend the
|
|
||||||
BusyBox mdev tool, add to `/etc/mdev.conf`:
|
|
||||||
|
|
||||||
$MODALIAS=.* root:root 0660 @modprobe -b "$MODALIAS"
|
|
||||||
|
|
||||||
> **Note:** only read and executed in runlevel S ([bootstrap][]).
|
|
||||||
|
|
||||||
|
|
||||||
### Networking
|
|
||||||
|
|
||||||
**Syntax:** `network <PATH>`
|
|
||||||
|
|
||||||
Script or program to bring up networking, with optional arguments.
|
|
||||||
|
|
||||||
Deprecated. We recommend using dedicated task/run stanzas per runlevel,
|
|
||||||
or `/etc/network/interfaces` if you have a system with `ifupdown`, like
|
|
||||||
Debian, Ubuntu, Linux Mint, or an embedded BusyBox system.
|
|
||||||
|
|
||||||
> **Note:** only read and executed in runlevel S ([bootstrap][]).
|
|
||||||
|
|
||||||
|
|
||||||
### Resource Limits
|
|
||||||
|
|
||||||
**Syntax:** `rlimit [hard|soft] RESOURCE <LIMIT|unlimited>`
|
|
||||||
|
|
||||||
Set the hard or soft limit for a resource, or both if that argument is
|
|
||||||
omitted. `RESOURCE` is the lower-case `RLIMIT_` string constants from
|
|
||||||
`setrlimit(2)`, without prefix. E.g. to set `RLIMIT_CPU`, use `cpu`.
|
|
||||||
|
|
||||||
LIMIT is an integer that depends on the resource being modified, see
|
|
||||||
the man page, or the kernel `/proc/PID/limits` file, for details.
|
|
||||||
Finit versions before v3.1 used `infinity` for `unlimited`, which is
|
|
||||||
still supported, albeit deprecated.
|
|
||||||
|
|
||||||
# No process is allowed more than 8MB of address space
|
|
||||||
rlimit hard as 8388608
|
|
||||||
|
|
||||||
# Core dumps may be arbitrarily large
|
|
||||||
rlimit soft core infinity
|
|
||||||
|
|
||||||
# CPU limit for all services, soft & hard = 10 sec
|
|
||||||
rlimit cpu 10
|
|
||||||
|
|
||||||
`rlimit` can be set globally, in `/etc/finit.conf`, or locally per
|
|
||||||
each `/etc/finit.d/*.conf` read. I.e., a set of task/run/service
|
|
||||||
stanzas can share the same rlimits if they are in the same .conf.
|
|
||||||
|
|
||||||
|
|
||||||
### Runlevels
|
|
||||||
|
|
||||||
**Syntax:** `runlevel <N>`
|
|
||||||
|
|
||||||
The system runlevel to go to after [bootstrap][] (S) has completed. `N`
|
|
||||||
is the runlevel number 0-9, where 6 is reserved for reboot and 0 for
|
|
||||||
halt.
|
|
||||||
|
|
||||||
Default: 2
|
|
||||||
|
|
||||||
> **Note:** only read and executed in runlevel S ([bootstrap][]).
|
|
||||||
|
|
||||||
|
|
||||||
### One-shot Commands (sequence)
|
|
||||||
|
|
||||||
**Syntax:** `run [LVLS] <COND> /path/to/cmd ARGS -- Optional description`
|
|
||||||
|
|
||||||
One-shot command to run in sequence when entering a runlevel, with
|
|
||||||
optional arguments and description.
|
|
||||||
|
|
||||||
`run` commands are guaranteed to be completed before running the next
|
|
||||||
command. Highly useful if true serialization is needed.
|
|
||||||
|
|
||||||
> `<COND>` is described in the [Services](#services) section.
|
|
||||||
|
|
||||||
|
|
||||||
### One-shot Commands (parallel)
|
|
||||||
|
|
||||||
**Syntax:** `task [LVLS] <COND> /path/to/cmd ARGS -- Optional description`
|
|
||||||
|
|
||||||
One-shot like 'run', but starts in parallel with the next command.
|
|
||||||
|
|
||||||
Both `run` and `task` commands are run in a shell, so pipes and
|
|
||||||
redirects can be freely used:
|
|
||||||
|
|
||||||
task [s] echo "foo" | cat >/tmp/bar
|
|
||||||
|
|
||||||
> `<COND>` is described in the [Services](#services) section.
|
|
||||||
|
|
||||||
|
|
||||||
### SysV Init Scripts
|
|
||||||
|
|
||||||
**Syntax:** `sysv [LVLS] <COND> /path/to/init-script -- Optional description`
|
|
||||||
|
|
||||||
Similar to `task` is the `sysv` stanza, which can be used to call SysV
|
|
||||||
style scripts. The primary intention for this command is to be able to
|
|
||||||
re-use much of existing setup and init scripts in Linux distributions.
|
|
||||||
|
|
||||||
When entering an allowed runlevel, Finit calls `init-script start`, when
|
|
||||||
entering a disallowed runlevel, Finit calls `init-script stop`, and if
|
|
||||||
the Finit .conf, where `sysv` stanza is declared, is modified, Finit
|
|
||||||
calls `init-script restart` on `initctl reload`. Similar to how
|
|
||||||
`service` stanzas work.
|
|
||||||
|
|
||||||
Forking services started with `sysv` scripts can be monitored by Finit
|
|
||||||
by declaring the PID file to look for: `pid:!/path/to/pidfile.pid`.
|
|
||||||
Notice the leading `!`, it signifies Finit should not try to create the
|
|
||||||
file, but rather watch that file for the resulting forked-off PID. This
|
|
||||||
syntax also works for forking daemons that do not have a command line
|
|
||||||
option to run it in the foreground, more on this below in `service`.
|
|
||||||
|
|
||||||
> `<COND>` is described in the [Services](#services) section.
|
|
||||||
|
|
||||||
|
|
||||||
### Services
|
|
||||||
|
|
||||||
**Syntax:** `service [LVLS] <COND> /path/to/daemon ARGS -- Optional description`
|
|
||||||
|
|
||||||
Service, or daemon, to be monitored and automatically restarted if it
|
|
||||||
exits prematurely. Finit tries to restart services that die, by
|
|
||||||
default 10 times before giving up and marking them as *crashed*.
|
|
||||||
After which they have to be manually restarted with `initctl restart
|
|
||||||
NAME`. The limits controling this are configurable, see the options
|
|
||||||
below.
|
|
||||||
|
|
||||||
> **Tip:** to allow endless restarts, see below option `respawn`
|
|
||||||
|
|
||||||
For daemons that support it, we recommend appending `--foreground`,
|
|
||||||
`--no-background`, `-n`, `-F`, or similar command line argument to
|
|
||||||
prevent them from forking off a sub-process in the background. This is
|
|
||||||
the most reliable way to monitor a service.
|
|
||||||
|
|
||||||
However, not all daemons support running in the foreground, or they may
|
|
||||||
start logging to the foreground as well, these are forking daemons and
|
|
||||||
are supported using the same syntax as forking `sysv` services, using
|
|
||||||
the `pid:!/path/to/pidfile.pid` syntax. There is an alternative syntax
|
|
||||||
that may be more intuitive, where Finit can also guess the PID file
|
|
||||||
based on the daemon's command name:
|
|
||||||
|
|
||||||
service type:forking ntpd -- NTP daemon
|
|
||||||
|
|
||||||
This example lets BusyBox `ntpd` daemonize itself. Finit uses the
|
|
||||||
basename of the binary to guess the PID file to watch for the PID:
|
|
||||||
`/var/run/ntpd.pid`. If Finit guesses wrong, you have to submit the
|
|
||||||
full `pid:!/path/to/file.pid`.
|
|
||||||
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
In the case of `ospfd` (below), we omit the `-d` flag (daemonize) to
|
|
||||||
prevent it from forking to the background:
|
|
||||||
|
|
||||||
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
|
|
||||||
|
|
||||||
`[2345]` denote the runlevels `ospfd` is allowed to run in, they are
|
|
||||||
optional and default to level 2-5 if omitted.
|
|
||||||
|
|
||||||
`<...>` is the condition for starting `ospfd`. In this example Finit
|
|
||||||
waits for another service, `zebra`, to have created its PID file in
|
|
||||||
`/var/run/quagga/zebra.pid` before starting `ospfd`. Finit watches
|
|
||||||
*all* files in `/var/run`, for each file named `*.pid`, or `*/pid`,
|
|
||||||
Finit opens it and find the matching `NAME:ID` using the PID.
|
|
||||||
|
|
||||||
Some services do not maintain a PID file and rather than patching each
|
|
||||||
application Finit provides a workaround. A `pid` keyword can be set
|
|
||||||
to have Finit automatically create (when starting) and later remove
|
|
||||||
(when stopping) the PID file. The file is created in the `/var/run`
|
|
||||||
directory using the `basename(1)` of the service. The default can be
|
|
||||||
modified with an optional `pid:`-argument:
|
|
||||||
|
|
||||||
pid[:[/path/to/]filename[.pid]]
|
|
||||||
|
|
||||||
For example, by adding `pid:/run/foo.pid` to the service `/sbin/bar`,
|
|
||||||
that PID file will, not only be created and removed automatically, but
|
|
||||||
also be used by the Finit condition subsystem. So a service/run/task
|
|
||||||
can depend on `<pid/bar>`.
|
|
||||||
|
|
||||||
> For a detailed description of conditions, and how to debug them,
|
|
||||||
> see the [Finit Conditions](conditions.md) document.
|
|
||||||
|
|
||||||
If a service should not be automatically started, it can be configured
|
|
||||||
as manual with the optional `manual` argument. The service can then be
|
|
||||||
started at any time by running `initctl start <service>`.
|
|
||||||
|
|
||||||
manual:yes
|
|
||||||
|
|
||||||
The name of a service, shown by the `initctl` tool, defaults to the
|
|
||||||
basename of the service executable. It can be changed with the
|
|
||||||
optional `name` argument:
|
|
||||||
|
|
||||||
name:<service-name>
|
|
||||||
|
|
||||||
As mentioned previously, services are automatically restarted, this is
|
|
||||||
configurable with the following options:
|
|
||||||
|
|
||||||
* `restart:NUM` -- number of times Finit tries to restart a crashing
|
|
||||||
service, default: 10, max: 255. When this limit is reached the
|
|
||||||
service is marked *crashed* and must be restarted manually with
|
|
||||||
`initctl restart NAME`
|
|
||||||
* `restart_sec:SEC` -- number of seconds before Finit tries to restart
|
|
||||||
a crashing service, default: 2 seconds for the first five retries,
|
|
||||||
then back-off to 5 seconds. The maximum of this configured value
|
|
||||||
and the above (2 and 5) will be used
|
|
||||||
* `norestart` -- dont restart on failures, same as `restart:0`
|
|
||||||
* `respawn` -- bypasses the `restart` mechanism completely, allows
|
|
||||||
endless restarts. Useful in many use-cases, but not what `service`
|
|
||||||
was originally designed for so not the default behavior
|
|
||||||
* `oncrash:reboot` -- when all retries have failed, and the service
|
|
||||||
has *crashed*, if this option is set the system is rebooted.
|
|
||||||
Note, future releases may include other `oncrash:` actions
|
|
||||||
|
|
||||||
When stopping a service (run/task/sysv/service), either manually or
|
|
||||||
when moving to another runlevel, Finit starts by sending `SIGTERM`, to
|
|
||||||
allow the process to shut down gracefully. If the process has not
|
|
||||||
been collected within 3 seconds, Finit sends `SIGKILL`. To halt the
|
|
||||||
process using a different signal, use the option `halt:SIGNAL`, e.g.,
|
|
||||||
`halt:SIGPWR`. To change the delay between your halt signal and KILL,
|
|
||||||
use the option `kill:SEC`, e.g., `kill:10` to wait 10 seconds before
|
|
||||||
sending `SIGKILL`.
|
|
||||||
|
|
||||||
Services support `pre:script` and `post:script` actions as well. These
|
|
||||||
run as the same `@USER:GROUP` as the service itself, with any `env:file`
|
|
||||||
sourced. The scripts must use an absolute path, but are executed from
|
|
||||||
the `$HOME` of the given user. The scripts are not called with any
|
|
||||||
argument (currently), but both get the `SERVICE_IDENT=foo` environment
|
|
||||||
variable set. Here `foo` denotes the identity of the service, which if
|
|
||||||
there are multiple services named `foo`, may be `foo:1`, or any unique
|
|
||||||
identifier specified in the .conf file. The `post:script` is called
|
|
||||||
with an additional set of environment variables:
|
|
||||||
|
|
||||||
- `EXIT_CODE=[exited,signal]`: set to one of `exited` or `signal`
|
|
||||||
- `EXIT_STATUS=[num,SIGNAME]`: set to one of exit status code from
|
|
||||||
the program, if it exited normally, or the signal name (`HUP`,
|
|
||||||
`TERM`, etc.) if it exited due to signal
|
|
||||||
|
|
||||||
The scripts have a default execution time of 3 seconds before they are
|
|
||||||
SIGKILLed, this can be adjusted using the above `kill:SEC` syntax.
|
|
||||||
|
|
||||||
> **Note:** the `pre:script` _must_ be idempotent, because a service
|
|
||||||
> can transition between READY and HALTED states any number
|
|
||||||
> of times before going to RUNNING.
|
|
||||||
|
|
||||||
|
|
||||||
### Run-parts Scripts
|
|
||||||
|
|
||||||
**Syntax:** `runparts <DIR>`
|
|
||||||
|
|
||||||
Call [run-parts(8)][] on `DIR` to run start scripts. All executable
|
|
||||||
files, or scripts, in the directory are called, in alphabetic order.
|
|
||||||
The scripts in this directory are executed at the very end of runlevel
|
|
||||||
`S`, [bootstrap][].
|
|
||||||
|
|
||||||
It can be beneficial to use `S01name`, `S02othername`, etc. if there
|
|
||||||
is a dependency order between the scripts. Symlinks to existing
|
|
||||||
daemons can talso be used, but make sure they daemonize by default.
|
|
||||||
|
|
||||||
Similar to the `/etc/rc.local` shell script, make sure that all your
|
|
||||||
services and programs either terminate or start in the background or
|
|
||||||
you will block Finit.
|
|
||||||
|
|
||||||
> **Note:** only read and executed in runlevel S ([bootstrap][]).
|
|
||||||
|
|
||||||
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
|
||||||
|
|
||||||
|
|
||||||
### Including Finit Configs
|
|
||||||
|
|
||||||
**Syntax:** `include <CONF>`
|
|
||||||
|
|
||||||
Include another configuration file. Absolute path required.
|
|
||||||
|
|
||||||
|
|
||||||
### General Logging
|
|
||||||
|
|
||||||
**Syntax:** `log size:200k count:5`
|
|
||||||
|
|
||||||
Log rotation for run/task/services using the `log` sub-option with
|
|
||||||
redirection to a log file. Global setting, applies to all services.
|
|
||||||
|
|
||||||
The size can be given as bytes, without a specifier, or in `k`, `M`,
|
|
||||||
or `G`, e.g. `size:10M`, or `size:3G`. A value of `size:0` disables
|
|
||||||
log rotation. The default is `200k`.
|
|
||||||
|
|
||||||
The count value is recommended to be between 1-5, with a default 5.
|
|
||||||
Setting count to 0 means the logfile will be truncated when the MAX
|
|
||||||
size limit is reached.
|
|
||||||
|
|
||||||
### TTYs and Consoles
|
|
||||||
|
|
||||||
**Syntax:** `tty [LVLS] <COND> DEV [BAUD] [noclear] [nowait] [nologin] [TERM]`
|
|
||||||
`tty [LVLS] <COND> CMD <ARGS> [noclear] [nowait]`
|
|
||||||
`tty [LVLS] <COND> [notty] [rescue]`
|
|
||||||
|
|
||||||
The first variant of this option uses the built-in getty on the given
|
|
||||||
TTY device DEV, in the given runlevels. DEV may be the special keyword
|
|
||||||
`@console`, which is expanded from `/sys/class/tty/console/active`,
|
|
||||||
useful on embedded systems.
|
|
||||||
|
|
||||||
The default baud rate is 0, i.e., keep kernel default.
|
|
||||||
|
|
||||||
> The `tty` stanza inherits runlevel, condition (and other feature)
|
|
||||||
> parsing from the `service` stanza. So TTYs can run in one or many
|
|
||||||
> runlevels and depend on any condition supported by Finit. This is
|
|
||||||
> useful e.g. to depend on `<pid/elogind>` before starting a TTY.
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
tty [12345] /dev/ttyAMA0 115200 noclear vt220
|
|
||||||
|
|
||||||
The second `tty` syntax variant is for using an external getty, like
|
|
||||||
agetty or the BusyBox getty.
|
|
||||||
|
|
||||||
The third variant is for board bringup and the `rescue` boot mode. No
|
|
||||||
device node is required in this variant, the same output that the kernel
|
|
||||||
uses is reused for stdio. If the `rescue` option is omitted, a shell is
|
|
||||||
started (`nologin`, `noclear`, and `nowait` are implied), if the rescue
|
|
||||||
option is set the bundled `/libexec/finit/sulogin` is started to present
|
|
||||||
a bare-bones root login prompt. If the root (uid:0, gid:0) user does
|
|
||||||
not have a password set, no rescue is possible. For more information,
|
|
||||||
see the [Rescue Mode](#rescue-mode) section.
|
|
||||||
|
|
||||||
By default, the first two syntax variants *clear* the TTY and *wait* for
|
|
||||||
the user to press enter before starting getty.
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
tty [12345] /sbin/getty -L 115200 /dev/ttyAMA0 vt100
|
|
||||||
tty [12345] /sbin/agetty -L ttyAMA0 115200 vt100 nowait
|
|
||||||
|
|
||||||
The `noclear` option disables clearing the TTY after each session.
|
|
||||||
Clearing the TTY when a user logs out is usually preferable.
|
|
||||||
|
|
||||||
The `nowait` option disables the `press Enter to activate console`
|
|
||||||
message before actually starting the getty program. On small and
|
|
||||||
embedded systems running multiple unused getty wastes both memory
|
|
||||||
and CPU cycles, so `wait` is the preferred default.
|
|
||||||
|
|
||||||
The `nologin` option disables getty and `/bin/login`, and gives the
|
|
||||||
user a root (login) shell on the given TTY `<DEV>` immediately.
|
|
||||||
Needless to say, this is a rather insecure option, but can be very
|
|
||||||
useful for developer builds, during board bringup, or similar.
|
|
||||||
|
|
||||||
Notice the ordering, the `TERM` option to the built-in getty must be
|
|
||||||
the last argument.
|
|
||||||
|
|
||||||
Embedded systems may want to enable automatic `DEV` by supplying the
|
|
||||||
special `@console` device. This works regardless weather the system
|
|
||||||
uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit figures
|
|
||||||
it out by querying sysfs: `/sys/class/tty/console/active`. The speed
|
|
||||||
can be omitted to keep the kernel default.
|
|
||||||
|
|
||||||
> Most systems get by fine by just using `console`, which will evaluate
|
|
||||||
> to `/dev/console`. If you have to use `@console` to get any output,
|
|
||||||
> you may have some issue with your kernel config.
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
tty [12345] @console noclear vt220
|
|
||||||
|
|
||||||
On really bare bones systems, or for board bringup, Finit can give you a
|
|
||||||
shell prompt as soon as [bootstrap][] is done, without opening any
|
|
||||||
device node:
|
|
||||||
|
|
||||||
tty [12345789] notty
|
|
||||||
|
|
||||||
This should of course not be enabled on production systems. Because it
|
|
||||||
may give a user root access without having to log in. However, for
|
|
||||||
board bringup and system debugging it can come in handy.
|
|
||||||
|
|
||||||
One can also use the `service` stanza to start a stand-alone shell:
|
|
||||||
|
|
||||||
service [12345] /bin/sh -l
|
|
||||||
|
|
||||||
|
|
||||||
### Non-privileged Services
|
|
||||||
|
|
||||||
Every `run`, `task`, or `service` can also list the privileges the
|
|
||||||
`/path/to/cmd` should be executed with. Prefix the command with
|
|
||||||
`@USR[:GRP]`, group is optional, like this:
|
|
||||||
|
|
||||||
run [2345] @joe:users logger "Hello world"
|
|
||||||
|
|
||||||
For multiple instances of the same command, e.g. a DHCP client or
|
|
||||||
multiple web servers, add `:ID` somewhere between the `run`, `task`,
|
|
||||||
`service` keyword and the command, like this:
|
|
||||||
|
|
||||||
service :80 [2345] httpd -f -h /http -p 80 -- Web server
|
|
||||||
service :8080[2345] httpd -f -h /http -p 8080 -- Old web server
|
|
||||||
|
|
||||||
Without the `:ID` to the service the latter will overwrite the former
|
|
||||||
and only the old web server would be started and supervised.
|
|
||||||
|
|
||||||
|
|
||||||
### Redirecting Output
|
|
||||||
|
|
||||||
The `run`, `task`, and `service` stanzas also allow the keyword `log` to
|
|
||||||
redirect `stderr` and `stdout` of the application to a file or syslog
|
|
||||||
using the native `logit` tool. This is useful for programs that do not
|
|
||||||
support syslog on their own, which is sometimes the case when running
|
|
||||||
in the foreground.
|
|
||||||
|
|
||||||
The full syntax is:
|
|
||||||
|
|
||||||
log:/path/to/file
|
|
||||||
log:prio:facility.level,tag:ident
|
|
||||||
log:console
|
|
||||||
log:null
|
|
||||||
log
|
|
||||||
|
|
||||||
Default `prio` is `daemon.info` and default `tag` is the basename of the
|
|
||||||
service or run/task command.
|
|
||||||
|
|
||||||
Log rotation is controlled using the global `log` setting.
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
|
|
||||||
service log:prio:user.warn,tag:ntpd /sbin/ntpd pool.ntp.org -- NTP daemon
|
|
||||||
|
|
||||||
|
|
||||||
Rescue Mode
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Finit supports a rescue mode which is activated by the `rescue` option
|
|
||||||
on the kernel command line. See [cmdline docs](cmdline.md) for how to
|
|
||||||
activate it.
|
|
||||||
|
|
||||||
The rescue mode comes in two flavors; *traditional* and *fallback*.
|
|
||||||
|
|
||||||
> **Note:** in this mode `initctl` will not work. Use the `-f` flag to
|
|
||||||
> force `reboot`, `shutdown`, or `poweroff`.
|
|
||||||
|
|
||||||
|
|
||||||
### Traditional
|
|
||||||
|
|
||||||
This is what most users expect. A very early maintenance login prompt,
|
|
||||||
served by the bundled `/libexec/finit/sulogin` program, or the standard
|
|
||||||
`sulogin` from util-linux or BusyBox is searched for in the UNIX default
|
|
||||||
`$PATH`. If a successful login is made, or the user exits (Ctrl-D), the
|
|
||||||
rescue mode is ended and the system boots up normally.
|
|
||||||
|
|
||||||
> **Note:** if the user (UID 0 and GID 0) does not have a password, or
|
|
||||||
> __the account is locked__, the user is presented with a password-less
|
|
||||||
> `"Press enter to enter maintenance mode."`, prompt which opens up a
|
|
||||||
> root shell.
|
|
||||||
|
|
||||||
|
|
||||||
### Fallback
|
|
||||||
|
|
||||||
If no `sulogin` program is found, Finit tries to bring up as much of its
|
|
||||||
own functionality as possible, yet limiting many aspects, meaning; no
|
|
||||||
network, no `fsck` of file systems in `/etc/fstab`, no `/etc/rc.local`,
|
|
||||||
no `runparts`, and most plugins are skipped (except those that provide
|
|
||||||
functionality for the condition subsystem).
|
|
||||||
|
|
||||||
Instead of reading `/etc/finit.conf` et al, system configuration is read
|
|
||||||
from `/lib/finit/rescue.conf`, which can be freely modified by the
|
|
||||||
system administrator.
|
|
||||||
|
|
||||||
The bundled default `rescue.conf` contains nothing more than:
|
|
||||||
|
|
||||||
runlevel 1
|
|
||||||
tty [12345] rescue
|
|
||||||
|
|
||||||
The `tty` has the `rescue` option set, which works similar to the board
|
|
||||||
bring-up tty option `notty`. The major difference being that `sulogin`
|
|
||||||
is started to query for root/admin password. If `sulogin` is not found,
|
|
||||||
`rescue` behaves like `notty` and gives a plain root shell prompt.
|
|
||||||
|
|
||||||
If Finit cannot find `/lib/finit/rescue.conf` it defaults to:
|
|
||||||
|
|
||||||
tty [12345] rescue
|
|
||||||
|
|
||||||
There is no way to exit the *fallback* rescue mode.
|
|
||||||
|
|
||||||
|
|
||||||
Limitations
|
|
||||||
-----------
|
|
||||||
|
|
||||||
As of Finit v4 there are no limitations to where `.conf` settings can be
|
|
||||||
placed. Except for the system/global `rlimit` and `cgroup` top-level
|
|
||||||
group declarations, which can only be set from `/etc/finit.conf`, since
|
|
||||||
it is the first `.conf` file Finit reads.
|
|
||||||
|
|
||||||
Originally, `/etc/finit.conf` was the only way to set up a Finit system.
|
|
||||||
Today it is mainly used for bootstrap settings like system hostname,
|
|
||||||
early module loading for watchdogd, network bringup and system shutdown.
|
|
||||||
These can now also be set in any `.conf` file in `/etc/finit.d`.
|
|
||||||
|
|
||||||
There is, however, nothing preventing you from having all configuration
|
|
||||||
settings in `/etc/finit.conf`.
|
|
||||||
|
|
||||||
> **Note:** The `/etc/finit.d` directory was previously the default
|
|
||||||
> Finit [runparts](#run-parts-scripts) directory. Finit no
|
|
||||||
> longer has a default `runparts`, make sure to update your
|
|
||||||
> setup, or the finit configuration, accordingly.
|
|
||||||
|
|
||||||
|
|
||||||
Watchdog
|
|
||||||
--------
|
|
||||||
|
|
||||||
When built `--with-watchdog` a separate service is built and installed
|
|
||||||
in `/libexec/finit/watchdogd`. If this exists at runtime, and the WDT
|
|
||||||
device node exists, Finit will start it and treat it as the elected
|
|
||||||
watchdog service to delegate its reboot to. See [bootstrap][] for
|
|
||||||
details. This delegation is to ensure that the system is rebooted by a
|
|
||||||
hardware watchdog timer -- on many embedded systems this is crucial to
|
|
||||||
ensure all circuits on the board are properly reset for the next boot,
|
|
||||||
in effect ensuring the system works the same after both a power-on and
|
|
||||||
reboot event.
|
|
||||||
|
|
||||||
The delegation is performed at the very last steps of system shutdown,
|
|
||||||
if reboot has been selected and an elected watchdog is known, first a
|
|
||||||
`SIGPWR` is sent to advise watchdogd of the pending reboot. Then, when
|
|
||||||
the necessary steps of preparing the system for shutdown (umount etc.)
|
|
||||||
are completed, Finit sends `SIGTERM` to watchdogd and puts itself in a
|
|
||||||
10 sec timeout loop waiting for the WDT to reset the board. If a reset
|
|
||||||
is not done before the timeout, Finit falls back to`reboot(RB_AUTOBOOT)`
|
|
||||||
which tells the kernel to do the reboot.
|
|
||||||
|
|
||||||
An external watchdog service can also be used. The more advanced cousin
|
|
||||||
[watchdogd](https://github.com/troglobit/watchdogd/) is the recommended
|
|
||||||
option here. It can register itself with Finit using the same IPC as
|
|
||||||
`initctl`. If the bundled watchdogd is running a hand-over takes place,
|
|
||||||
so it's safe to have both services installed on a system. For the
|
|
||||||
hand-over to work it requires that the WDT driver supports the safe exit
|
|
||||||
functionality where `"V"` is written to the device before closing the
|
|
||||||
device descriptor. If the kernel driver has been built without this,
|
|
||||||
the only option is to remove `/libexec/finit/watchdogd` or build without
|
|
||||||
it at configure time.
|
|
||||||
|
|
||||||
[bootstrap]: bootstrap.md
|
|
||||||
|
|
||||||
|
|
||||||
keventd
|
|
||||||
-------
|
|
||||||
|
|
||||||
The kernel event daemon bundled with Finit is a simple uevent monitor
|
|
||||||
for `/sys/class/power_supply`. It provides the `sys/pwr/ac` condition,
|
|
||||||
which can be useful to prevent power hungry services like anacron to run
|
|
||||||
when a laptop is only running on battery, for instance.
|
|
||||||
|
|
||||||
Since keventd is not an integral part of Finit yet it is not enabled by
|
|
||||||
default. Enable it using `./configuure --with-keventd`. The bundled
|
|
||||||
contrib build scripts for Debian, Alpine, and Void have this enabled.
|
|
||||||
|
|
||||||
This daemon is planned to be extended with monitoring of other uevents,
|
|
||||||
patches and ideas are welcome in the issue tracker.
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
docsdir := @docdir@/doc/config
|
||||||
|
dist_docs_DATA = cgroups.md env.md files.md index.md limitations.md \
|
||||||
|
logging.md rescue.md runlevels.md runparts.md \
|
||||||
|
service-env.md service-opts.md service-sync.md \
|
||||||
|
service-wrappers.md services.md sysv.md \
|
||||||
|
task-and-run.md templating.md tty.md
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
index.md
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
Linux Capabilities
|
||||||
|
==================
|
||||||
|
|
||||||
|
Finit supports Linux capabilities, allowing services to run with minimal
|
||||||
|
required privileges instead of running as root. This significantly improves
|
||||||
|
system security by following the principle of least privilege.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Linux capabilities divide the traditional root privileges into distinct units
|
||||||
|
that can be independently granted to processes. For example, a web server only
|
||||||
|
needs the capability to bind to privileged ports (< 1024), not full root access.
|
||||||
|
|
||||||
|
Finit uses the modern IAB (Inheritable, Ambient, Bounding) API from libcap,
|
||||||
|
which is the same approach used by other modern service managers like dinit.
|
||||||
|
|
||||||
|
## Basic Usage
|
||||||
|
|
||||||
|
Capabilities are specified using the `caps:` directive in service configuration:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
service [2345] name:nginx \
|
||||||
|
@www-data:www-data \
|
||||||
|
caps:^cap_net_bind_service \
|
||||||
|
/usr/sbin/nginx -g 'daemon off;' \
|
||||||
|
-- Web server
|
||||||
|
```
|
||||||
|
|
||||||
|
This example allows nginx to bind to privileged ports (like 80 and 443) while
|
||||||
|
running as the unprivileged `www-data` user.
|
||||||
|
|
||||||
|
## IAB Format
|
||||||
|
|
||||||
|
The capability string uses the IAB (Inheritable, Ambient, Bounding) format
|
||||||
|
with the following prefixes:
|
||||||
|
|
||||||
|
- `^` **Ambient** (and Inheritable) - **Recommended for most use cases**
|
||||||
|
- Capabilities survive across `exec()` calls
|
||||||
|
- Automatically raised to effective after exec
|
||||||
|
- Example: `^cap_net_bind_service`
|
||||||
|
|
||||||
|
- `%` **Inheritable** only
|
||||||
|
- Requires the executed binary to have matching file capabilities
|
||||||
|
- Less common, more complex setup
|
||||||
|
- Example: `%cap_net_admin`
|
||||||
|
|
||||||
|
- `!` **Bounding** - Block capability from bounding set
|
||||||
|
- Prevents the service from ever acquiring this capability
|
||||||
|
- Useful for security hardening
|
||||||
|
- Example: `!cap_sys_admin`
|
||||||
|
|
||||||
|
Multiple capabilities can be specified as a comma-separated list:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
caps:^cap_net_raw,^cap_net_admin,^cap_net_bind_service
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Use Cases
|
||||||
|
|
||||||
|
### Web Server (Privileged Ports)
|
||||||
|
|
||||||
|
Allow a web server to bind to ports 80 and 443 without running as root:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
service [2345] name:webserver \
|
||||||
|
@www-data:www-data \
|
||||||
|
caps:^cap_net_bind_service \
|
||||||
|
/usr/sbin/nginx -g 'daemon off;'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Network Monitoring (Raw Sockets)
|
||||||
|
|
||||||
|
Allow packet capture without root privileges:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
service [2345] name:tcpdump \
|
||||||
|
@tcpdump \
|
||||||
|
caps:^cap_net_raw,^cap_net_admin \
|
||||||
|
/usr/sbin/tcpdump -i eth0 -w /var/log/capture.pcap
|
||||||
|
```
|
||||||
|
|
||||||
|
### NTP Daemon (System Time)
|
||||||
|
|
||||||
|
Allow time synchronization without full root:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
service [2345] name:ntpd \
|
||||||
|
@ntp \
|
||||||
|
caps:^cap_sys_time,^cap_sys_nice \
|
||||||
|
/usr/sbin/ntpd -n
|
||||||
|
```
|
||||||
|
|
||||||
|
## Available Capabilities
|
||||||
|
|
||||||
|
Common capabilities include (see `man 7 capabilities` for the complete list):
|
||||||
|
|
||||||
|
- `cap_chown` - Make arbitrary changes to file UIDs and GIDs
|
||||||
|
- `cap_dac_override` - Bypass file read, write, and execute permission checks
|
||||||
|
- `cap_dac_read_search` - Bypass file read permission checks
|
||||||
|
- `cap_fowner` - Bypass permission checks on operations that normally require filesystem UID
|
||||||
|
- `cap_kill` - Bypass permission checks for sending signals
|
||||||
|
- `cap_net_admin` - Perform various network-related operations
|
||||||
|
- `cap_net_bind_service` - Bind to privileged ports (< 1024)
|
||||||
|
- `cap_net_raw` - Use RAW and PACKET sockets
|
||||||
|
- `cap_setgid` - Make arbitrary manipulations of process GIDs
|
||||||
|
- `cap_setuid` - Make arbitrary manipulations of process UIDs
|
||||||
|
- `cap_sys_admin` - Perform system administration operations (very powerful!)
|
||||||
|
- `cap_sys_module` - Load and unload kernel modules
|
||||||
|
- `cap_sys_nice` - Raise process nice value and change scheduling
|
||||||
|
- `cap_sys_time` - Set system clock
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
1. **Use the minimum required capabilities**
|
||||||
|
- Only grant what the service actually needs
|
||||||
|
- Don't grant `cap_sys_admin` unless absolutely necessary
|
||||||
|
|
||||||
|
2. **Specify a user (preferably non-root)**
|
||||||
|
- The `@user` directive is **required** for `caps:` to take effect
|
||||||
|
- For ambient capabilities (`^`), use a non-root user (not `@root`)
|
||||||
|
- Example: `@www-data`, `@nginx`, `@tcpdump`
|
||||||
|
|
||||||
|
3. **Use ambient capabilities (`^`)**
|
||||||
|
- The `^` prefix ensures capabilities survive exec()
|
||||||
|
- Simpler than setting file capabilities on binaries
|
||||||
|
|
||||||
|
4. **Block dangerous capabilities**
|
||||||
|
- Use `!` to explicitly block capabilities you don't want
|
||||||
|
- Example: `!cap_sys_admin,!cap_sys_module`
|
||||||
|
|
||||||
|
5. **Test with `getpcaps`**
|
||||||
|
- After starting a service, verify its capabilities:
|
||||||
|
```bash
|
||||||
|
getpcaps $(pidof nginx)
|
||||||
|
```
|
||||||
|
- Should show only the capabilities you granted
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
After configuring a service with capabilities, verify it works correctly:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start the service
|
||||||
|
initctl start webserver
|
||||||
|
|
||||||
|
# Check the process capabilities
|
||||||
|
getpcaps $(pidof nginx)
|
||||||
|
|
||||||
|
# Should show something like:
|
||||||
|
# 12345: cap_net_bind_service=eip
|
||||||
|
|
||||||
|
# Verify the user
|
||||||
|
ps -o user,pid,cmd -p $(pidof nginx)
|
||||||
|
|
||||||
|
# Should show the service running as the specified user
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Linux kernel 4.3+ (for ambient capabilities support)
|
||||||
|
- libcap library installed
|
||||||
|
- Finit built with `--enable-libcap`
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- The `caps:` directive requires `@user` to be specified for it to take effect
|
||||||
|
- Without `@user`, the service runs as root with full capabilities and
|
||||||
|
the `caps:` configuration is silently ignored
|
||||||
|
- You can use `@root` with `caps:`, but see below about ambient capabilities
|
||||||
|
- For ambient capabilities (`^`, recommended), the user **must be non-root**
|
||||||
|
- Using `@root` with `caps:^...` will not work effectively, as ambient
|
||||||
|
capabilities are only added to the effective set when euid ≠ 0
|
||||||
|
- Use inheritable (`%`) or bounding (`!`) capabilities with `@root` if needed
|
||||||
|
- Services without `caps:` use standard privilege dropping:
|
||||||
|
- Services with `@user` (non-root) have no special capabilities
|
||||||
|
- Services without `@user` run as root with full capabilities
|
||||||
|
- Some very old binaries may not work correctly with ambient capabilities
|
||||||
|
- File system capabilities are not managed by Finit (use `setcap` for that)
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [capabilities(7)](https://man7.org/linux/man-pages/man7/capabilities.7.html) - Linux capabilities overview
|
||||||
|
- [cap_iab(3)](https://man7.org/linux/man-pages/man3/cap_iab.3.html) - IAB capability API documentation
|
||||||
|
- [setcap(8)](https://man7.org/linux/man-pages/man8/setcap.8.html) - Set file capabilities
|
||||||
|
- [getcap(8)](https://man7.org/linux/man-pages/man8/getcap.8.html) - Query file capabilities
|
||||||
|
- [capsh(1)](https://man7.org/linux/man-pages/man1/capsh.1.html) - Capability shell wrapper
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
Finit provides three different cgroup directives for controlling resource allocation:
|
||||||
|
|
||||||
|
1. **Top-level cgroup definition**: `cgroup NAME settings`
|
||||||
|
- Defines a top-level cgroup (e.g., `init`, `system`, `user`) with default settings
|
||||||
|
- Space-separated syntax
|
||||||
|
- Example: `cgroup system cpu.weight:9700`
|
||||||
|
|
||||||
|
2. **Global cgroup selector**: `cgroup.NAME[,options]` (standalone directive)
|
||||||
|
- Sets the default cgroup for subsequent services in a `.conf` file
|
||||||
|
- Dot-separated with optional comma-separated options
|
||||||
|
- Example: `cgroup.maint` or `cgroup.system,delegate`
|
||||||
|
|
||||||
|
3. **Per-service cgroup option**: `cgroup.NAME[,options]` or `cgroup:options`
|
||||||
|
- Overrides the cgroup for a specific service
|
||||||
|
- Part of the service directive line
|
||||||
|
- Example: `service [...] cgroup.maint,mem.max:1G /path/to/cmd`
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Linux cgroups and details surrounding values are not explained in the
|
||||||
|
> Finit documentation. The Linux admin-guide covers this well:
|
||||||
|
> <https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html>
|
||||||
|
|
||||||
|
Top-level Cgroup Definition
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
**Syntax:** `cgroup NAME settings`
|
||||||
|
|
||||||
|
# Top-level cgroups and their default settings. All groups mandatory
|
||||||
|
# but more can be added, max 8 groups in total currently. The cgroup
|
||||||
|
# 'root' is also available, reserved for RT processes. Settings are
|
||||||
|
# as-is, only one shorthand 'mem.' exists, other than that it's the
|
||||||
|
# cgroup v2 controller default names.
|
||||||
|
cgroup init cpu.weight:100
|
||||||
|
cgroup user cpu.weight:100
|
||||||
|
cgroup system cpu.weight:9800
|
||||||
|
|
||||||
|
Adding an extra cgroup `maint/` will require you to adjust the weight of
|
||||||
|
the above three. We leave `init/` and `user/` as-is reducing weight of
|
||||||
|
`system/` to 9700.
|
||||||
|
|
||||||
|
cgroup system cpu.weight:9700
|
||||||
|
|
||||||
|
# Example extra cgroup 'maint'
|
||||||
|
cgroup maint cpu.weight:100
|
||||||
|
|
||||||
|
By default, the `system/` cgroup is selected for almost everything. The
|
||||||
|
`init/` cgroup is reserved for PID 1 itself and its closest relatives.
|
||||||
|
The `user/` cgroup is for local TTY logins spawned by getty.
|
||||||
|
|
||||||
|
Global Cgroup Selector
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
**Syntax:** `cgroup.NAME[,options]` (standalone directive)
|
||||||
|
|
||||||
|
To select a different top-level cgroup, e.g. `maint/`, for a group of
|
||||||
|
run/task/service directives in a `.conf` file, use the `cgroup.NAME`
|
||||||
|
directive as a standalone line:
|
||||||
|
|
||||||
|
cgroup.maint
|
||||||
|
service [...] <...> /path/to/foo args -- description
|
||||||
|
service [...] <...> /path/to/bar args -- description
|
||||||
|
|
||||||
|
Both services will run in the `maint/` cgroup.
|
||||||
|
|
||||||
|
You can also include options with the global selector:
|
||||||
|
|
||||||
|
cgroup.system,delegate
|
||||||
|
service [...] <...> /path/to/foo args -- description
|
||||||
|
|
||||||
|
Per-Service Cgroup Option
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
**Syntax:** `cgroup.NAME[,options]` or `cgroup:options` (service option)
|
||||||
|
|
||||||
|
To override the cgroup for a specific service, use the `cgroup.NAME`
|
||||||
|
option within the service directive:
|
||||||
|
|
||||||
|
service [...] <...> cgroup.maint /path/to/foo args -- description
|
||||||
|
|
||||||
|
This form also allows per-service limits. Two syntaxes are supported:
|
||||||
|
|
||||||
|
**New comma-separated syntax (recommended):**
|
||||||
|
|
||||||
|
service [...] <...> cgroup.maint,cpu.max:10000,mem.max:655360 /path/to/foo args -- description
|
||||||
|
|
||||||
|
**Old colon-separated syntax (legacy):**
|
||||||
|
|
||||||
|
service [...] <...> cgroup.maint:cpu.max:10000,mem.max:655360 /path/to/foo args -- description
|
||||||
|
|
||||||
|
You can also apply options to the current default cgroup (without changing it)
|
||||||
|
using the `cgroup:options` syntax:
|
||||||
|
|
||||||
|
service [...] <...> cgroup:cpu.max:10000,mem.max:655360 /path/to/foo args -- description
|
||||||
|
|
||||||
|
Both syntaxes work identically. The new comma-separated syntax is recommended
|
||||||
|
as it's more consistent with other option parsing in Finit.
|
||||||
|
|
||||||
|
Note the `mem.` exception to the rule: every cgroup setting maps directly to
|
||||||
|
cgroup v2 syntax. I.e., `cpu.max` maps to the file `/sys/fs/cgroup/maint/foo/cpu.max`.
|
||||||
|
There is no filtering, except for expanding the shorthand `mem.` to `memory.`.
|
||||||
|
If the file is not available, either the cgroup controller is not available
|
||||||
|
in your Linux kernel, or the name is misspelled.
|
||||||
|
|
||||||
|
### Overriding Cgroup Leaf Names
|
||||||
|
|
||||||
|
By default, the cgroup leaf directory name is derived from the service
|
||||||
|
configuration filename (without the `.conf` extension). For example, a
|
||||||
|
service defined in `system/10-hotplug.conf` would create a cgroup at
|
||||||
|
`/sys/fs/cgroup/system/10-hotplug/` by default.
|
||||||
|
|
||||||
|
To use a more descriptive name (recommended for clarity), you can specify
|
||||||
|
`name:` in the cgroup directive:
|
||||||
|
|
||||||
|
service [...] <...> cgroup.system,name:udevd /lib/systemd/systemd-udevd -- Device event daemon
|
||||||
|
|
||||||
|
This creates the cgroup at `/sys/fs/cgroup/system/udevd/` instead.
|
||||||
|
|
||||||
|
The syntax supports combining the name override with other options:
|
||||||
|
|
||||||
|
service [...] <...> cgroup.system,name:udevd,cpu.max:10000 /lib/systemd/systemd-udevd -- Device event daemon
|
||||||
|
|
||||||
|
Or with delegation:
|
||||||
|
|
||||||
|
service [2345] @podman:podman \
|
||||||
|
cgroup.containers,name:podman,delegate,mem.max:4G \
|
||||||
|
/usr/bin/podman system service -- Podman API
|
||||||
|
|
||||||
|
A daemon using `SCHED_RR` currently needs to run outside the default cgroups.
|
||||||
|
|
||||||
|
service [...] <...> cgroup.root /path/to/daemon arg -- Real-Time process
|
||||||
|
|
||||||
|
Cgroup Delegation
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
For services that need to create their own child cgroups (container runtimes
|
||||||
|
like Docker, Podman, systemd-nspawn, LXC), use the `delegate` option:
|
||||||
|
|
||||||
|
service [2345] @dockerd:dockerd \
|
||||||
|
cgroup.system,delegate /usr/bin/dockerd -- Docker daemon
|
||||||
|
|
||||||
|
Or with the old colon syntax:
|
||||||
|
|
||||||
|
service [2345] @dockerd:dockerd \
|
||||||
|
cgroup.system:delegate /usr/bin/dockerd -- Docker daemon
|
||||||
|
|
||||||
|
This allows the container runtime to:
|
||||||
|
|
||||||
|
- Create child cgroups for containers
|
||||||
|
- Manage controller settings for containers
|
||||||
|
- Move processes between cgroups
|
||||||
|
|
||||||
|
When delegation is enabled, Finit:
|
||||||
|
|
||||||
|
1. Creates the service cgroup as a **domain group** (not a leaf)
|
||||||
|
2. Enables all available controllers in `cgroup.subtree_control`
|
||||||
|
3. Changes ownership of delegation files to the service user
|
||||||
|
4. Moves the service process to the cgroup root
|
||||||
|
5. Lets the container runtime manage its own subdirectories
|
||||||
|
|
||||||
|
**Requirements:**
|
||||||
|
|
||||||
|
- The service should specify `@user:group` for proper ownership
|
||||||
|
- Controllers are delegated from the parent cgroup
|
||||||
|
|
||||||
|
**Example with additional config (new syntax):**
|
||||||
|
|
||||||
|
service [2345] @podman:podman \
|
||||||
|
cgroup.containers,delegate,mem.max:4G \
|
||||||
|
/usr/bin/podman system service -- Podman API
|
||||||
|
|
||||||
|
**Or with old syntax:**
|
||||||
|
|
||||||
|
service [2345] @podman:podman \
|
||||||
|
cgroup.containers:delegate,mem.max:4G \
|
||||||
|
/usr/bin/podman system service -- Podman API
|
||||||
|
|
||||||
|
Both examples delegate the cgroup while also setting a 4GB memory limit.
|
||||||
|
|
||||||
|
**Container template example:**
|
||||||
|
|
||||||
|
Here's a real-world example from [Infix OS](https://github.com/kernelkit/infix)
|
||||||
|
for running rootful podman container instances using delegation:
|
||||||
|
|
||||||
|
sysv log:prio:local1,tag:%i kill:30 pid:!/run/container:%i.pid \
|
||||||
|
pre:0,/usr/sbin/container cleanup:0,/usr/sbin/container \
|
||||||
|
cgroup.system,delegate \
|
||||||
|
[2345] <!> :%i container -n %i -- container %i
|
||||||
|
|
||||||
|
This template uses `sysv` type with delegation, demonstrating that cgroup
|
||||||
|
delegation works with different service types, not just `service`.
|
||||||
|
|
||||||
|
**Cgroup structure with delegation:**
|
||||||
|
|
||||||
|
Initially, the service process runs directly in the cgroup root:
|
||||||
|
|
||||||
|
/sys/fs/cgroup/system/container@web/
|
||||||
|
├── cgroup.procs (service PID - owned by service user)
|
||||||
|
├── cgroup.subtree_control (+cpu +memory +io - owned by service user)
|
||||||
|
└── (container children will be created here)
|
||||||
|
|
||||||
|
Once the container runtime creates child cgroups (e.g., `libpod-*/`), cgroups v2
|
||||||
|
enforces the "no internal processes" rule. When Finit detects this (`EBUSY` error),
|
||||||
|
it automatically creates an `supervisor/` subdirectory and moves service-related
|
||||||
|
processes there:
|
||||||
|
|
||||||
|
/sys/fs/cgroup/system/container@web/
|
||||||
|
├── cgroup.procs (empty)
|
||||||
|
├── cgroup.subtree_control (+cpu +memory +io)
|
||||||
|
├── supervisor/ (service processes)
|
||||||
|
│ └── cgroup.procs (conmon PIDs, etc.)
|
||||||
|
└── libpod-$HASH/ (container processes)
|
||||||
|
└── cgroup.procs (container PIDs)
|
||||||
|
|
||||||
|
This happens automatically - no configuration needed. Without delegation, the
|
||||||
|
cgroup would be a leaf and the container runtime could not create child cgroups.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
Environment Variables
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
In Finit v4.3 support for setting environment variables in `finit.conf`,
|
||||||
|
and any `*.conf`, was added. It is worth noting that these are global
|
||||||
|
and *shared with all* services -- the only way to have a service-local
|
||||||
|
environment is detailed in [Services Environment](service-env.md).
|
||||||
|
|
||||||
|
The syntax for global environment variables is straight forward. In
|
||||||
|
Finit v4.4 the `set` keyword was added for completeness, but the old
|
||||||
|
syntax (without the `set ` prefix) is still honored:
|
||||||
|
|
||||||
|
set foo=bar
|
||||||
|
set baz="qux"
|
||||||
|
|
||||||
|
On reload of .conf files, all tracked environment variables are cleared
|
||||||
|
so if `foo=bar` is removed from `finit.conf`, or any `finit.d/*.conf`
|
||||||
|
file, it will no longer be used by Finit or any new (!) started
|
||||||
|
run/tasks or services. The environment of already started processes can
|
||||||
|
not be changed.
|
||||||
|
|
||||||
|
The only variables reset to sane defaults on .conf reload are:
|
||||||
|
|
||||||
|
PATH=_PATH_STDPATH
|
||||||
|
SHELL=_PATH_BSHELL
|
||||||
|
LOGNAME=root
|
||||||
|
USER=root
|
||||||
|
|
||||||
|
It is entirely possible to override these as well from the .conf files,
|
||||||
|
but be careful. Changing SHELL changes the behavior of `system()` and a
|
||||||
|
lot of other commands as well.
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
Files & Layout
|
||||||
|
==============
|
||||||
|
|
||||||
|
Originally Finit was configured using a single file, `/etc/finit.conf`,
|
||||||
|
and although still possible to use a single configuration file, today
|
||||||
|
the following layout is recommended:
|
||||||
|
|
||||||
|
/
|
||||||
|
|- etc/
|
||||||
|
| |- finit.d/
|
||||||
|
| | |- available/
|
||||||
|
| | | `- my-service.conf
|
||||||
|
| : |- enabled/
|
||||||
|
| : | `- my-service.conf -> ../available/my-service.conf
|
||||||
|
| : :
|
||||||
|
| : |- static-service.conf
|
||||||
|
| : `- another-static.conf
|
||||||
|
| :
|
||||||
|
| `- finit.conf
|
||||||
|
|- lib
|
||||||
|
| `- finit/
|
||||||
|
| `- system/
|
||||||
|
| |- 10-hotplug.conf
|
||||||
|
| `- ...
|
||||||
|
`- run/
|
||||||
|
`- finit/
|
||||||
|
`- system/
|
||||||
|
|- dbus.conf
|
||||||
|
|- keventd.conf
|
||||||
|
|- runparts.conf
|
||||||
|
|- watchdogd.conf
|
||||||
|
`- ...
|
||||||
|
|
||||||
|
Configuration files in `/etc` are provided by the user, or projects like
|
||||||
|
[finit-skel](https://github.com/finit-project/finit-skel) and extended by
|
||||||
|
the user.
|
||||||
|
|
||||||
|
The files in `/lib/finit/system/*.conf` are system critical services and
|
||||||
|
setup provided by Finit, e.g. udev/mdev that must run very early at system
|
||||||
|
bootstrap. This system directory was introduced in Finit v4.4 to replace
|
||||||
|
the hard-coded services provided by plugins before. All .conf files in this
|
||||||
|
directory be either replaced by a system administrator or overridden by a
|
||||||
|
file with the same name in `/etc/finit.d/`.
|
||||||
|
|
||||||
|
The files in `/run/finit/system/*.conf` are created by plugins and Finit
|
||||||
|
bundled services like runparts, [watchdog](../watchdog.md), and
|
||||||
|
[`keventd`](../keventd.md) if they are enabled. Like
|
||||||
|
`/lib/finit/system/*.conf`, these files can be overridden by file with
|
||||||
|
the same name in `/etc/finit.d/`.
|
||||||
|
|
||||||
|
Services in the `available/` and `enabled/` sub-directories are called
|
||||||
|
dynamic services, in contrast to static services -- the only difference
|
||||||
|
being where they are installed and if the `initctl` tool can manage them
|
||||||
|
with the `enable` and `disable` commands. An administrator can always
|
||||||
|
create files and symlinks manually.
|
||||||
|
|
||||||
|
At bootstrap, and `initctl reload`, all .conf files are read, starting
|
||||||
|
with `finit.conf`, then `/lib/finit/system/*.conf`, `finit.d/*.conf`,
|
||||||
|
and finally all `finit.d/enabled/*.conf` files. Each directory is a
|
||||||
|
unique group, where files within each group are sorted alphabetically.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
/lib/finit/system/10-hotplug.conf
|
||||||
|
/lib/finit/system/90-testserv.conf
|
||||||
|
/run/finit/system/dbus.conf
|
||||||
|
/run/finit/system/runparts.conf
|
||||||
|
/etc/finit.d/10-abc.conf
|
||||||
|
/etc/finit.d/20-abc.conf
|
||||||
|
/etc/finit.d/enabled/1-aaa.conf
|
||||||
|
/etc/finit.d/enabled/1-abc.conf
|
||||||
|
|
||||||
|
The resulting combined configuration is read line by line, each `run`,
|
||||||
|
`task`, and `service` added to an ordered list that ensures they are
|
||||||
|
started in the same order. This is important because of the blocking
|
||||||
|
properties of the `run` statement. For an example on the relation of
|
||||||
|
`service` and `run` statements, and dependency handling between them,
|
||||||
|
see [Conditional Loading](services.md#conditional-loading), below.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The names `finit.conf` and `finit.d/` are only defaults. They can be
|
||||||
|
> changed at compile-time with two `configure` options:
|
||||||
|
> `--with-config=/etc/foo.conf` and `--with-rcsd=/var/foo.d`.
|
||||||
|
>
|
||||||
|
> They can also be overridden from the [kernel command line](../cmdline.md)
|
||||||
|
> using: `-- finit.config=/etc/bar.conf` and in that file use the
|
||||||
|
> top-level configuration directive `rcsd /path/to/finit.d`.
|
||||||
|
|
||||||
|
Filesystem Layout
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Finit is most comfortable with a traditional style Linux filesystem
|
||||||
|
layout, as specified in the [FHS][]:
|
||||||
|
|
||||||
|
/.
|
||||||
|
|- bin/
|
||||||
|
|- dev/ # Mounted automatically if devtmpfs is available
|
||||||
|
| |- pts/ # Mounted automatically by Finit if it exists
|
||||||
|
| `- shm/ # Mounted automatically by Finit if it exists
|
||||||
|
|- etc/
|
||||||
|
| |- finit.d/
|
||||||
|
| | |- available/
|
||||||
|
| | `- enabled/
|
||||||
|
| `- finit.conf
|
||||||
|
|- home/
|
||||||
|
|- lib/
|
||||||
|
|- libexec/
|
||||||
|
|- mnt/
|
||||||
|
|- proc/ # Mounted automatically by Finit if it exists
|
||||||
|
|- root/
|
||||||
|
|- run/ # Mounted automatically by Finit if it exists
|
||||||
|
| `- lock/ # Created automatically if Finit mounts /run
|
||||||
|
|- sbin/
|
||||||
|
|- sys/ # Mounted automatically by Finit if it exists
|
||||||
|
|- tmp/ # Mounted automatically by Finit if it exists
|
||||||
|
|- usr/
|
||||||
|
`- var/
|
||||||
|
|- cache/
|
||||||
|
|- db/
|
||||||
|
|- lib/
|
||||||
|
| `- misc/
|
||||||
|
|- lock/
|
||||||
|
|- log/
|
||||||
|
|- run -> ../run
|
||||||
|
|- spool/
|
||||||
|
`- tmp/
|
||||||
|
|
||||||
|
Finit starts by mounting the critical file systems `/dev`, `/proc/`, and
|
||||||
|
`/sys`, unless they are already mounted. When all plugins and other,
|
||||||
|
core Finit functions, have been set up, all relevant filesystems (where
|
||||||
|
`PASS > 0`) are checked and mounted from the selected `fstab`, either
|
||||||
|
the default `/etc/fstab`, or any custom one selected from the command
|
||||||
|
line, or at build time.
|
||||||
|
|
||||||
|
To provide a smooth ride, file system not listed in the given `fstab`,
|
||||||
|
e.g. `/tmp` and `/run`, are automatically mounted by Finit, as listed
|
||||||
|
above, provided their respective mount point exists.
|
||||||
|
|
||||||
|
With all filesystems mounted, Finit calls `swapon`.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> To see what happens when all filesystems are mounted, have a look at
|
||||||
|
> the [`bootmisc.so` plugin](../plugins.md).
|
||||||
|
|
||||||
|
At shutdown, and after having stopped all services and other lingering
|
||||||
|
processes have been killed, filesystems are unmounted in the reverse
|
||||||
|
order, and `swapoff` is called.
|
||||||
|
|
||||||
|
[FHS]: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
|
||||||
|
|
||||||
|
Managing Services
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Using `initctl disable my-service` the symlink (above) is removed and
|
||||||
|
the service is queued for removal. Several changes can be made to the
|
||||||
|
system, but it is not until `initctl reload` is called that the changes
|
||||||
|
are activated.
|
||||||
|
|
||||||
|
To add a new static service, drop a `.conf` file in `/etc/finit.d/` and
|
||||||
|
run `initctl reload`. (It is also possible to `SIGHUP` PID 1, or call
|
||||||
|
`finit q`, but that has been deprecated with the `initctl` tool). Finit
|
||||||
|
monitors all known active `.conf` files, so if you want to force a
|
||||||
|
restart of any service you can touch its corresponding `.conf` file in
|
||||||
|
`/etc/finit.d` and call `initctl reload`. Finit handles all conditions
|
||||||
|
and dependencies between services automatically, see the section on
|
||||||
|
[Service Synchronization](service-sync.md) for more details.
|
||||||
|
|
||||||
|
On `initctl reload` the following is checked for all services:
|
||||||
|
|
||||||
|
- If a service's `.conf` file has been removed, or its conditions are no
|
||||||
|
longer satisfied, the service is stopped.
|
||||||
|
- If the file is modified, or a service it depends on has been reloaded,
|
||||||
|
the service is reloaded (stopped and started).
|
||||||
|
- If a new service is added it is automatically started — respecting
|
||||||
|
runlevels and return values from any callbacks.
|
||||||
|
|
||||||
|
For more info on the different states of a service, see the separate
|
||||||
|
document [Finit Services](../service.md).
|
||||||
|
|
||||||
|
Alternate finit.d/
|
||||||
|
------------------
|
||||||
|
|
||||||
|
**Syntax:** `rcsd /path/to/finit.d`
|
||||||
|
|
||||||
|
The Finit rcS.d directory is set at compile time with:
|
||||||
|
|
||||||
|
./configure --with-rcsd=/etc/finit.d
|
||||||
|
|
||||||
|
A system with multiple use-cases may be bootstrapped with different
|
||||||
|
configurations, starting with the kernel command line option:
|
||||||
|
|
||||||
|
-- finit.config=/etc/factory.conf
|
||||||
|
|
||||||
|
This file in turn can use the `rcsd` directive to tell Finit to use
|
||||||
|
another set of .conf files, e.g.:
|
||||||
|
|
||||||
|
rcsd /etc/factory.d
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This directive is only available from the top-level bootstrap .conf
|
||||||
|
> file, usually `/etc/finit.conf`.
|
||||||
|
|
||||||
|
Including Finit Configs
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
**Syntax:** `include <CONF>`
|
||||||
|
|
||||||
|
Include another configuration file. Absolute path required.
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
This section provides an overview of Finit's configuration system. For
|
||||||
|
detailed information on specific topics, see the individual sections in
|
||||||
|
the navigation menu.
|
||||||
|
|
||||||
|
|
||||||
|
Configuration File Syntax
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
The file format is line based, empty lines and comments, lines starting
|
||||||
|
with `#`, are ignored. A configuration directive starts with a keyword
|
||||||
|
followed by a space and the rest of the line is treated as the value.
|
||||||
|
|
||||||
|
As of Finit v4.4, configuration directives can be broken up in multiple
|
||||||
|
lines using the continuation character `\`, and trailing comments are
|
||||||
|
also allowed. Example:
|
||||||
|
|
||||||
|
```aconf
|
||||||
|
# Escape \# chars if you want them literal in, e.g., descriptions
|
||||||
|
service name:sysklogd [S123456789] \
|
||||||
|
env:-/etc/default/sysklogd \
|
||||||
|
syslogd -F $SYSLOGD_ARGS \
|
||||||
|
-- System log daemon \# 1 # Comments allowed
|
||||||
|
```
|
||||||
|
|
||||||
|
The .conf files `/etc/finit.conf` and `/etc/finit.d/*` support many
|
||||||
|
directives. Some are restricted, e.g., only available at bootstrap,
|
||||||
|
runlevel `S`. Read on in [Files & Layout](files.md) for more on how
|
||||||
|
to structure your .conf files.
|
||||||
|
|
||||||
|
For details on restrictions, see [Limitations](limitations.md).
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
Limitations
|
||||||
|
===========
|
||||||
|
|
||||||
|
As of Finit v4 there are no limitations to where `.conf` settings can be
|
||||||
|
placed. Except for the system/global `rlimit` and `cgroup` top-level
|
||||||
|
group declarations, which can only be set from `/etc/finit.conf`, since
|
||||||
|
it is the first `.conf` file Finit reads.
|
||||||
|
|
||||||
|
Originally, `/etc/finit.conf` was the only way to set up a Finit system.
|
||||||
|
Today it is mainly used for bootstrap settings like system hostname,
|
||||||
|
early module loading for watchdogd, network bringup and system shutdown.
|
||||||
|
These can now also be set in any `.conf` file in `/etc/finit.d`.
|
||||||
|
|
||||||
|
There is, however, nothing preventing you from having all configuration
|
||||||
|
settings in `/etc/finit.conf`.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> The default `rcsd`, i.e., `/etc/finit.d`, was previously the Finit
|
||||||
|
> [runparts](runparts.md) directory. Finit >=v4.0 no longer has a
|
||||||
|
> default `runparts` directory, make sure to update your setup, or the
|
||||||
|
> finit configuration, accordingly.
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
General Logging
|
||||||
|
===============
|
||||||
|
|
||||||
|
**Syntax:** `log size:200k count:5`
|
||||||
|
|
||||||
|
Log rotation for run/task/services using the `log` sub-option with
|
||||||
|
redirection to a log file. Global setting, applies to all services.
|
||||||
|
|
||||||
|
The size can be given as bytes, without a specifier, or in `k`, `M`,
|
||||||
|
or `G`, e.g. `size:10M`, or `size:3G`. A value of `size:0` disables
|
||||||
|
log rotation. The default is `200k`.
|
||||||
|
|
||||||
|
The count value is recommended to be between 1-5, with a default 5.
|
||||||
|
Setting count to 0 means the logfile will be truncated when the MAX
|
||||||
|
size limit is reached.
|
||||||
|
|
||||||
|
Redirecting Output
|
||||||
|
------------------
|
||||||
|
|
||||||
|
The `run`, `task`, and `service` stanzas also allow the keyword `log` to
|
||||||
|
redirect `stderr` and `stdout` of the application to a file or syslog
|
||||||
|
using the native `logit` tool. This is useful for programs that do not
|
||||||
|
support syslog on their own, which is sometimes the case when running
|
||||||
|
in the foreground.
|
||||||
|
|
||||||
|
The full syntax is:
|
||||||
|
|
||||||
|
log:/path/to/file
|
||||||
|
log:prio:facility.level,tag:ident
|
||||||
|
log:console
|
||||||
|
log:null
|
||||||
|
log
|
||||||
|
|
||||||
|
Default `prio` is `daemon.info` and default `tag` is the basename of the
|
||||||
|
service or run/task command.
|
||||||
|
|
||||||
|
Log rotation is controlled using the global `log` setting.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
service log:prio:user.warn,tag:ntpd /sbin/ntpd pool.ntp.org -- NTP daemon
|
||||||
|
|
||||||
|
Output Buffering
|
||||||
|
----------------
|
||||||
|
|
||||||
|
When using the `log` directive, Finit redirects the service's stdout and
|
||||||
|
stderr to a pipe connected to a logger process. Programs detect this as
|
||||||
|
non-interactive output (i.e., `isatty()` returns false) and typically
|
||||||
|
switch from line-buffered to fully-buffered mode.
|
||||||
|
|
||||||
|
Most well-behaved daemons explicitly flush their output or use syslog
|
||||||
|
directly, so this is rarely an issue. However, if a service's log
|
||||||
|
messages appear delayed or batched, you can force line-buffered output
|
||||||
|
by wrapping the command with `stdbuf`:
|
||||||
|
|
||||||
|
service log /usr/bin/stdbuf -oL /path/to/command -- My service
|
||||||
|
|
||||||
|
The `-oL` option forces line-buffered output, and `-o0` forces unbuffered
|
||||||
|
output. See `stdbuf(1)` for details.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Using `stdbuf` is rarely necessary. Only use it if you observe actual
|
||||||
|
> buffering issues with a specific service.
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
Rescue Mode
|
||||||
|
===========
|
||||||
|
|
||||||
|
Finit supports a rescue mode which is activated by the `rescue` option
|
||||||
|
on the kernel command line. See [cmdline docs](../cmdline.md) for how to
|
||||||
|
activate it.
|
||||||
|
|
||||||
|
This rescue mode can be disabled at configure time using:
|
||||||
|
|
||||||
|
configure --without-rescue
|
||||||
|
|
||||||
|
The rescue mode comes in two flavors; *traditional* and *fallback*.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> In this mode `initctl` will not work. Use the `-f` flag to force
|
||||||
|
> `reboot`, `shutdown`, or `poweroff`.
|
||||||
|
|
||||||
|
Traditional
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This is what most users expect. A very early maintenance login prompt,
|
||||||
|
served by the system `sulogin` program from util-linux, or BusyBox. If
|
||||||
|
that is not found in `$PATH`, the bundled `/libexec/finit/sulogin`
|
||||||
|
program is used instead. If a successful login is made, or if the user
|
||||||
|
exits (Ctrl-D), the rescue mode is ended and the system boots up
|
||||||
|
normally.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> The bundled sulogin in Finit can at configure time be given another
|
||||||
|
> user than the default (root). If the sulogin user does not have a
|
||||||
|
> password, or __the account is locked__, the user is presented with a
|
||||||
|
> prompt: `"Press enter to enter maintenance mode."`, which will open
|
||||||
|
> up a root shell *without prompting for password*!
|
||||||
|
|
||||||
|
Fallback
|
||||||
|
--------
|
||||||
|
|
||||||
|
If no `sulogin` program is found, Finit tries to bring up as much of its
|
||||||
|
own functionality as possible, yet limiting many aspects, meaning; no
|
||||||
|
network, no `fsck` of file systems in `/etc/fstab`, no `/etc/rc.local`,
|
||||||
|
no `runparts`, and most plugins are skipped (except those that provide
|
||||||
|
functionality for the condition subsystem).
|
||||||
|
|
||||||
|
Instead of reading `/etc/finit.conf` et al, system configuration is read
|
||||||
|
from `/lib/finit/rescue.conf`, which can be freely modified by the
|
||||||
|
system administrator.
|
||||||
|
|
||||||
|
The bundled default `rescue.conf` contains nothing more than:
|
||||||
|
|
||||||
|
runlevel 1
|
||||||
|
tty [12345] rescue
|
||||||
|
|
||||||
|
The `tty` has the `rescue` option set, which works similar to the board
|
||||||
|
bring-up tty option `notty`. The major difference being that `sulogin`
|
||||||
|
is started to query for root/admin password. If `sulogin` is not found,
|
||||||
|
`rescue` behaves like `notty` and gives a plain root shell prompt.
|
||||||
|
|
||||||
|
If Finit cannot find `/lib/finit/rescue.conf` it defaults to:
|
||||||
|
|
||||||
|
tty [12345] rescue
|
||||||
|
|
||||||
|
There is no way to exit the *fallback* rescue mode.
|
||||||
@@ -0,0 +1,187 @@
|
|||||||
|
Runlevels
|
||||||
|
=========
|
||||||
|
|
||||||
|
Finit supports runlevels, but unlike other init systems runlevels are
|
||||||
|
declared per service/run/task/sysv command. When booting up a system
|
||||||
|
Finit pass through three phases:
|
||||||
|
|
||||||
|
1. Setting up the console, parsing any command line options, and other
|
||||||
|
housekeeping tasks like mounting all filesystems, and calling `fsck`
|
||||||
|
2. Starting all run/task/services in runlevel S, then waiting for all
|
||||||
|
services to have started, and all run/tasks to have completed
|
||||||
|
3. Go to runlevel 2, or whatever the user has set in the configuration
|
||||||
|
|
||||||
|
Available runlevels:
|
||||||
|
|
||||||
|
- ` S`: bootStrap
|
||||||
|
- ` 1`: Single user mode
|
||||||
|
- `2-5`: traditional multi-user mode
|
||||||
|
- ` 6`: reboot
|
||||||
|
- `7-9`: multi-user mode (extra)
|
||||||
|
- ` 0`: shutdown
|
||||||
|
|
||||||
|
Runlevel S (bootStrap), is for tasks supposed to run once at boot, and
|
||||||
|
services like `syslogd`, which need to start early and run throughout
|
||||||
|
the lifetime of your system.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
task [S] /lib/console-setup/console-setup.sh
|
||||||
|
service [S12345] env:-/etc/default/rsyslog rsyslogd -n $RSYSLOGD_ARGS
|
||||||
|
|
||||||
|
When bootstrap has completed, Finit moves to runlevel 2. This can be
|
||||||
|
changed in `/etc/finit.conf` using the `runlevel N` directive, or by a
|
||||||
|
script running in runlevel S that calls, e.g., `initctl runlevel 9`.
|
||||||
|
The latter is useful if startup scripts detect problems outside of
|
||||||
|
Finit's control, e.g., critical services/devices missing or hardware
|
||||||
|
problems.
|
||||||
|
|
||||||
|
Each runlevel must be allowed to "complete". Meaning, all services in
|
||||||
|
runlevel S must have started and all run/tasks have been started and
|
||||||
|
collected (exited). Finit waits 120 seconds for all run/tasks in S to
|
||||||
|
complete before proceeding to 2.
|
||||||
|
|
||||||
|
Finit first stops everything that is not allowed to run in 2, and then
|
||||||
|
brings up networking. Networking is expected to be available in all
|
||||||
|
runlevels except: S, 1 (single user level), 6, and 0. Networking is
|
||||||
|
enabled either by the `network script` directive, or if you have an
|
||||||
|
`/etc/network/interfaces` file, Finit calls `ifup -a` -- at the very
|
||||||
|
least the loopback interface is brought up.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> When moving from runlevel S to 2, all run/task/services that were
|
||||||
|
> constrained to runlevel S only are dropped from bookkeeping. So when
|
||||||
|
> reaching the prompt, `initctl` will not show these run/tasks. This is
|
||||||
|
> a safety mechanism to prevent bootstrap-only tasks from accidentally
|
||||||
|
> being run again. E.g., `console-setup.sh` above.
|
||||||
|
|
||||||
|
Runlevel Configuration
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
**Syntax:** `runlevel <N>`
|
||||||
|
|
||||||
|
The system runlevel to go to after bootstrap (S) has completed. `N` is
|
||||||
|
the runlevel number 0-9, where 6 is reserved for reboot and 0 for halt.
|
||||||
|
Completed in this context means all services have been started and all
|
||||||
|
run/tasks have been started and collected.
|
||||||
|
|
||||||
|
It is recommended to keep runlevel 1 as single-user mode, because
|
||||||
|
Finit disables networking in this mode.
|
||||||
|
|
||||||
|
*Default:* 2
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Only read and executed in runlevel S (bootstrap).
|
||||||
|
|
||||||
|
Networking
|
||||||
|
----------
|
||||||
|
|
||||||
|
**Syntax:** `network <PATH>`
|
||||||
|
|
||||||
|
Script or program to bring up networking, with optional arguments.
|
||||||
|
|
||||||
|
Deprecated. We recommend using dedicated task/run stanzas per runlevel,
|
||||||
|
or `/etc/network/interfaces` if you have a system with `ifupdown`, like
|
||||||
|
Debian, Ubuntu, Linux Mint, or an embedded BusyBox system.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Only read and executed in runlevel S (bootstrap).
|
||||||
|
|
||||||
|
System Hostname
|
||||||
|
---------------
|
||||||
|
|
||||||
|
**Syntax:** `host <NAME>`, or `hostname <NAME>`
|
||||||
|
|
||||||
|
Set system hostname to NAME, unless `/etc/hostname` exists in which case
|
||||||
|
the contents of that file is used.
|
||||||
|
|
||||||
|
Deprecated. We recommend using `/etc/hostname` instead.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Only read and executed in runlevel S (bootstrap).
|
||||||
|
|
||||||
|
Kernel Modules
|
||||||
|
--------------
|
||||||
|
|
||||||
|
**Syntax:** `module <MODULE> [ARGS]`
|
||||||
|
|
||||||
|
Load a kernel module, with optional arguments. Similar to `insmod`
|
||||||
|
command line tool.
|
||||||
|
|
||||||
|
Deprecated, there is both a `modules-load.so` and a `modprobe.so` plugin
|
||||||
|
that can handle module loading better. The former supports loading from
|
||||||
|
`/etc/modules-load.d/`, the latter uses kernel modinfo to automatically
|
||||||
|
load (or coldplug) every required module. For hotplug we recommend the
|
||||||
|
BusyBox mdev tool, add to `/etc/mdev.conf`:
|
||||||
|
|
||||||
|
$MODALIAS=.* root:root 0660 @modprobe -b "$MODALIAS"
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Only read and executed in runlevel S (bootstrap).
|
||||||
|
|
||||||
|
Resource Limits
|
||||||
|
---------------
|
||||||
|
|
||||||
|
**Syntax:** `rlimit [hard|soft] RESOURCE <LIMIT|unlimited>`
|
||||||
|
|
||||||
|
Set the hard or soft limit for a resource, or both if that argument is
|
||||||
|
omitted. `RESOURCE` is the lower-case `RLIMIT_` string constants from
|
||||||
|
`setrlimit(2)`, without prefix. E.g. to set `RLIMIT_CPU`, use `cpu`.
|
||||||
|
|
||||||
|
LIMIT is an integer that depends on the resource being modified, see
|
||||||
|
[setrlimit(2)](https://man7.org/linux/man-pages/man2/setrlimit.2.html),
|
||||||
|
or the kernel `/proc/PID/limits` file, for details. Finit versions
|
||||||
|
before v3.1 used `infinity` for `unlimited`, which is still supported,
|
||||||
|
albeit deprecated.
|
||||||
|
|
||||||
|
# No process is allowed more than 8MB of address space
|
||||||
|
rlimit hard as 8388608
|
||||||
|
|
||||||
|
# Core dumps may be arbitrarily large
|
||||||
|
rlimit soft core infinity
|
||||||
|
|
||||||
|
# CPU limit for all services, soft & hard = 10 sec
|
||||||
|
rlimit cpu 10
|
||||||
|
|
||||||
|
`rlimit` can be set globally, in `/etc/finit.conf`, or locally per
|
||||||
|
each `/etc/finit.d/*.conf` read. I.e., a set of task/run/service
|
||||||
|
stanzas can share the same rlimits if they are in the same .conf.
|
||||||
|
|
||||||
|
Miscellaneous Settings
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
**Syntax:** `reboot-delay <0-60>`
|
||||||
|
|
||||||
|
Optional delay at reboot (or shutdown or halt) to allow kernel
|
||||||
|
filesystem threads to complete after calling `sync(2)` before
|
||||||
|
rebooting. This applies primarily to filesystems that do not
|
||||||
|
have a reboot notifier implemented. At the point of writing,
|
||||||
|
the only known filesystems affected are: ubifs, jffs2.
|
||||||
|
|
||||||
|
*Default:* 0 (disabled)
|
||||||
|
|
||||||
|
When enabled (non-zero), this delay runs after file systems have been
|
||||||
|
unmounted and the root filesystem has been remounted read-only, and
|
||||||
|
sync(2) has been called, twice.
|
||||||
|
|
||||||
|
> "On Linux, sync is only guaranteed to schedule the dirty blocks for
|
||||||
|
> writing; it can actually take a short time before all the blocks are
|
||||||
|
> finally written.
|
||||||
|
|
||||||
|
**Syntax:** `reboot-watchdog <on|off|true|false|1|0>`
|
||||||
|
|
||||||
|
Controls whether the system should reboot via the watchdog timer (WDT)
|
||||||
|
or directly via the SoC/kernel. When enabled, Finit will:
|
||||||
|
|
||||||
|
1. Send `SIGPWR` to the registered watchdog daemon before shutdown
|
||||||
|
2. Send `SIGTERM` to the watchdog daemon and wait up to 10 seconds
|
||||||
|
for the watchdog to trigger a hardware reset
|
||||||
|
|
||||||
|
When disabled (default), Finit skips the watchdog reboot logic and
|
||||||
|
calls the kernel's `reboot(2)` syscall directly for a clean SoC reboot.
|
||||||
|
|
||||||
|
*Default:* off (reboot via SoC)
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This setting only affects reboots. The watchdog daemon will still
|
||||||
|
> run and monitor the system during normal operation.
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
Run-parts Scripts
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
**Syntax:** `runparts [progress] [sysv] <DIR>`
|
||||||
|
|
||||||
|
Call [run-parts(8)][] on `DIR` to run start scripts. All executable
|
||||||
|
files in the directory are called, in alphabetic order. The scripts in
|
||||||
|
this directory are executed at the very end of runlevel `S`.
|
||||||
|
|
||||||
|
A common use-case for runparts scripts is to create and enable/disable
|
||||||
|
services, which Finit will then apply when changing runlevel from S to
|
||||||
|
whatever the next runlevel is set to be (default 2). E.g., generate a
|
||||||
|
`/etc/chrony.conf` and call `initctl enable chronyd`.
|
||||||
|
|
||||||
|
**Options:**
|
||||||
|
|
||||||
|
- `progress`: display the progress of each script being executed
|
||||||
|
- `sysv`: run only SysV style scripts, i.e., `SNNfoo`, or `KNNbar`,
|
||||||
|
where `NN` is a number (0-99).
|
||||||
|
|
||||||
|
If global debug mode is enabled, the `runparts` program is also called
|
||||||
|
with the debug flag.
|
||||||
|
|
||||||
|
**Limitations:**
|
||||||
|
|
||||||
|
Scripts called from `runparts`, or hook scripts (see below), are limited
|
||||||
|
in their interaction with Finit. Like the standalone `run` stanza and
|
||||||
|
the `/etc/rc.local` shell script, Finit waits for their completion
|
||||||
|
before continuing. None of them can issue commands to start, stop, or
|
||||||
|
restart other services. Also, ensure all your services and programs
|
||||||
|
either terminate or start in the background or you will block Finit.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> `runparts` scripts are only read and executed in runlevel S. See
|
||||||
|
> [hook scripts](../plugins.md#hooks) for other ways to run scripts at
|
||||||
|
> certain points during the complete lifetime of the system.
|
||||||
|
|
||||||
|
**Recommendations:**
|
||||||
|
|
||||||
|
It can be beneficial to use `01-name`, `02-othername`, etc., to ensure
|
||||||
|
the scripts are started in that order, e.g., if there is a dependency
|
||||||
|
order between scripts. Symlinks to existing daemons can talso be used,
|
||||||
|
but make sure they daemonize (background) themselves properly, otherwise
|
||||||
|
Finit will lock up.
|
||||||
|
|
||||||
|
If `S[0-9]foo` and `K[0-9]bar` style naming is used, the executable will
|
||||||
|
be called with an extra argument, `start` and `stop`, respectively.
|
||||||
|
E.g., `S01foo` will be called as `S01foo start`. Of course, `S01foo`
|
||||||
|
and `K01foo` may be a symlink to to `another/directory/foo`.
|
||||||
|
|
||||||
|
[run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
Service Environment
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Finit supports sourcing environment variables from `/etc/default/*`, or
|
||||||
|
similar `--with-sysconfig=DIR`. This is a common pattern from SysV init
|
||||||
|
scripts, where the start-stop script is a generic script for the given
|
||||||
|
service, `foo`, and the options for the service are sourced from the
|
||||||
|
file `/etc/default/foo`. Like this:
|
||||||
|
|
||||||
|
* `/etc/default/foo`:
|
||||||
|
|
||||||
|
FOO_OPTIONS=--extra-arg="bar" -s -x
|
||||||
|
|
||||||
|
* `/etc/finit.conf`:
|
||||||
|
|
||||||
|
service [2345] env:-/etc/default/foo foo -n $FOO_OPTIONS -- Example foo daemon
|
||||||
|
|
||||||
|
Here the service `foo` is started with `-n`, to make sure it runs in the
|
||||||
|
foreground, and the with the options found in the environment file. With
|
||||||
|
the `ps` command we can see that the process is started with:
|
||||||
|
|
||||||
|
foo -n --extra-arg=bar -s -x
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The leading `-` in `env:` determines if Finit should treat a missing
|
||||||
|
> environment file as blocking the start of the service or not. When
|
||||||
|
> `-` is used, a missing environment file does *not* block the start.
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
Service Options
|
||||||
|
===============
|
||||||
|
|
||||||
|
The run/task/tty/service/sysv directives take modifiers, or options, to
|
||||||
|
control their behavior. This section lists them with their limitations.
|
||||||
|
All modifiers must be placed between the directive and its command.
|
||||||
|
|
||||||
|
The name of a service, shown by the `initctl` tool, defaults to the
|
||||||
|
basename of the service executable. It can be changed with the `name:`
|
||||||
|
option:
|
||||||
|
|
||||||
|
name:<service-name>
|
||||||
|
|
||||||
|
For multiple instances of a service, with the same `name`, set the
|
||||||
|
identifier `:ID` to prevent Finit from replacing previous instances:
|
||||||
|
|
||||||
|
service name:ssdp :eth1 ssdpd eth1 -- Windows discovery on eth1
|
||||||
|
service name:ssdp :eth2 ssdpd eth2 -- Windows discovery on eth2
|
||||||
|
|
||||||
|
The [`initctl`](../initctl.md) tool will list these two services as:
|
||||||
|
|
||||||
|
- ssdp:eth1
|
||||||
|
- ssdp:eth2
|
||||||
|
|
||||||
|
Conflicting services that must be prevented from starting, use the
|
||||||
|
`conflict:` option:
|
||||||
|
|
||||||
|
service [S12345789] udevd -- Device event management daemon
|
||||||
|
run [S] conflict:udevd mdev -s -- Populating device tree
|
||||||
|
|
||||||
|
Multiple conflicting services can be separated using `,`:
|
||||||
|
|
||||||
|
service :1 abc
|
||||||
|
service :2 abc
|
||||||
|
service conflict:abc:1,abc:2 cde
|
||||||
|
|
||||||
|
If a service should not be automatically started, it can be configured
|
||||||
|
as manual with the optional `manual` argument. The service can then be
|
||||||
|
started at any time by running `initctl start <service>`.
|
||||||
|
|
||||||
|
manual:yes
|
||||||
|
|
||||||
|
Other run/task/service options are:
|
||||||
|
|
||||||
|
* `caps:...` -- see the [Linux Capabilities](capabilities.md) section
|
||||||
|
* `cgroup.NAME[,opts]` or `cgroup:opts` -- see the [Cgroups](cgroups.md) section
|
||||||
|
* `env:[-]/path/to/env` -- see the [Service Environment](service-env.md) section
|
||||||
|
* `log:...` -- see [Redirecting Output](logging.md#redirecting-output)
|
||||||
|
* `tty:<dev>` -- see [Controlling TTY](tty.md#controlling-tty)
|
||||||
|
* `nowarn` -- see [Conditional Loading](services.md#conditional-loading)
|
||||||
|
* `notify:...` -- see [Service Synchronization](service-sync.md)
|
||||||
|
* `if:...` -- see [Conditional Execution](services.md#conditional-execution)
|
||||||
|
* `type:forking` -- see description of the [service](services.md) directive
|
||||||
|
|
||||||
|
As mentioned previously, services are automatically started, restarted,
|
||||||
|
and stopped, depending on the configuration and conditions. Within the
|
||||||
|
confines of that the following options are available:
|
||||||
|
|
||||||
|
* `restart:NUM` -- number of times Finit tries to restart a crashing
|
||||||
|
service, default: 10, max: 255. When this limit is reached the
|
||||||
|
service is marked *crashed* and must be restarted manually with
|
||||||
|
`initctl restart NAME`
|
||||||
|
* `restart_sec:SEC` -- number of seconds before Finit tries to restart
|
||||||
|
a crashing service, default: 2 seconds for the first five retries,
|
||||||
|
then back-off to 5 seconds. The maximum of this configured value
|
||||||
|
and the above (2 and 5) will be used
|
||||||
|
* `restart:always` -- no upper limit on the number of times Finit
|
||||||
|
tries to restart a crashing service. Same as `restart:-1`
|
||||||
|
* `norestart` -- dont restart on failures, same as `restart:0`
|
||||||
|
* `respawn` -- bypasses the `restart` mechanism completely, allows
|
||||||
|
endless restarts. Useful in many use-cases, but not what `service`
|
||||||
|
was originally designed for so not the default behavior
|
||||||
|
* `remain:yes` -- for `run` and `task` only. Prevents the task from
|
||||||
|
re-running on runlevel re-entry and ensures the `post:` script runs
|
||||||
|
when the task is explicitly stopped or leaves its valid runlevels.
|
||||||
|
Similar to systemd's `RemainAfterExit=yes`. See [Task and Run](task-and-run.md)
|
||||||
|
for more details
|
||||||
|
* `oncrash:reboot` -- when all retries have failed, and the service
|
||||||
|
has *crashed*, if this option is set the system is rebooted
|
||||||
|
* `oncrash:script` -- similarly, but instead of rebooting, call the
|
||||||
|
`post:script` action with exit code `crashed`, see below
|
||||||
|
* `reload:'script [args]'` -- some services do not support `SIGHUP` but
|
||||||
|
may have other ways to update the configuration of a running daemon.
|
||||||
|
When `reload:script` is defined it is preferred over `SIGHUP`. Like
|
||||||
|
systemd, Finit sets `$MAINPID` as a convenience to scripts, which in
|
||||||
|
effect also allow `reload:'kill -HUP $MAINPID'`
|
||||||
|
* `stop:'script [args]'` -- some services may require alternate methods
|
||||||
|
to be stopped. If a `stop:script` is defined it is preferred over
|
||||||
|
`SIGTERM` and `stop`, for `service` and `sysv`, respectively.
|
||||||
|
Similar to `reload:script`, Finit sets `$MAINPID`
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> Both `reload:script` and `stop:script` are called as PID 1, without
|
||||||
|
> any timeout! Meaning, it is up to you to ensure the script is not
|
||||||
|
> blocking for seconds at a time or never terminates.
|
||||||
|
|
||||||
|
When stopping a service (run/task/sysv/service), either manually or when
|
||||||
|
moving to another runlevel, Finit starts by sending `SIGTERM`, to allow
|
||||||
|
the process to shut down gracefully (unless a `stop:'script'` is used).
|
||||||
|
However, if the process has not been collected within 3 seconds, Finit
|
||||||
|
will send `SIGKILL`. To stop the process using a different signal than
|
||||||
|
`SIGTERM`, use `halt:SIGNAL`, e.g., `halt:SIGPWR`. To change the delay
|
||||||
|
between the stop signal and KILL, use the option `kill:<1-60>`, e.g.,
|
||||||
|
`kill:10` to wait 10 seconds before sending `SIGKILL`.
|
||||||
|
|
||||||
|
Services, including the `sysv` variant, support pre/post/ready and
|
||||||
|
cleanup scripts:
|
||||||
|
|
||||||
|
* `pre:[0-3600,]script` -- called before the sysv/service is stated
|
||||||
|
* `post:[0-3600,]script` -- called after the sysv/service has stopped
|
||||||
|
* `ready:[0-3600,]script` -- called when the sysv/service is ready
|
||||||
|
* `cleanup:[0-3600,]script` -- called when run/task/sysv/service is removed
|
||||||
|
|
||||||
|
The optional number (0-3600) is the timeout before Finit kills the
|
||||||
|
script, it defaults to the kill delay value and can be disabled by
|
||||||
|
setting it to zero. These scripts run as the same `@USER:GROUP` as the
|
||||||
|
service itself, with any `env:file` sourced. The scripts are executed
|
||||||
|
from the `$HOME` of the given user. The scripts are not called with any
|
||||||
|
argument, but get a set of environment variables:
|
||||||
|
|
||||||
|
* `SERVICE_IDENT=foo:1`
|
||||||
|
* `SERVICE_NAME=foo`
|
||||||
|
* `SERVICE_ID=1`
|
||||||
|
|
||||||
|
The `post:script` is called with an additional set of environment
|
||||||
|
variables. Yes, the text is correct, the naming was an accident:
|
||||||
|
|
||||||
|
- `EXIT_CODE=[exited,signal,crashed]`: normal exit, signaled, or
|
||||||
|
crashed
|
||||||
|
- `EXIT_STATUS=[num,SIGNAME]`: set to one of exit status code from
|
||||||
|
the program, if it exited normally, or the signal name (`HUP`,
|
||||||
|
`TERM`, etc.) if it exited due to signal
|
||||||
|
|
||||||
|
When a run/task/sys/service is removed (disable + reload) it is first
|
||||||
|
stopped and then removed from the runlevel. The `post:script` always
|
||||||
|
runs when the process has stopped, and the `cleanup:script` runs when
|
||||||
|
the the stanza has been removed from the runlevel.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> These script actions are intended for setup, cleanup, and readiness
|
||||||
|
> notification. It is up to the user to ensure the scripts terminate.
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
Service Synchronization
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Finit was created for fast booting systems. Faster than a regular SysV
|
||||||
|
Init based system at the time. Early on the need for a guaranteed start
|
||||||
|
order of services (daemons) arose. I.e., service `A` must be guaranteed
|
||||||
|
to have started (and be ready!) before `B`. The model that was chosen
|
||||||
|
to determine this was very simple: PID files.
|
||||||
|
|
||||||
|
Early on in UNIX daemons were controlled with basic IPC like signals,
|
||||||
|
and the way for a user to know that a daemon was ready to respond to
|
||||||
|
signals (minimally having set up its signal handler), was to tell the
|
||||||
|
user;
|
||||||
|
|
||||||
|
> "Hey, you can send signals to me using the PID in this file:
|
||||||
|
> `/var/run/daemon.pid`".
|
||||||
|
|
||||||
|
Since most systems run fairly unchanged after boot, Finit could rely on
|
||||||
|
the PID file for `A` being created before launching `B`. This method
|
||||||
|
has worked well for a long time, and for systems based on Open Source it
|
||||||
|
was easy to either add PID file support to a daemon without support for
|
||||||
|
it, or fix ordering issues (PID file created before signal handler is
|
||||||
|
set up) in existing daemons.
|
||||||
|
|
||||||
|
However, with the advent of other Init systems (Finit is rather old),
|
||||||
|
most notably systemd and s6, other methods for signaling "readiness"
|
||||||
|
arrived and daemons were adapted to these new schemes to a larger
|
||||||
|
extent.
|
||||||
|
|
||||||
|
As of Finit v4.4 partial support for systemd and s6 style readiness
|
||||||
|
notification is available, and the native PID file mode of operation is,
|
||||||
|
as of Finit v4.6 optional, by default it is still enabled, but this can
|
||||||
|
be changed in `finit.conf`:
|
||||||
|
|
||||||
|
readiness none
|
||||||
|
|
||||||
|
This will be made the default in Finit 5.0. In this mode of operation,
|
||||||
|
every service needs to explicitly declare their readiness notification,
|
||||||
|
like this:
|
||||||
|
|
||||||
|
service notify:pid watchdogd
|
||||||
|
service notify:systemd foo
|
||||||
|
service notify:s6 bar
|
||||||
|
service notify:none qux
|
||||||
|
|
||||||
|
The `notify:none` syntax is for completeness in systems which run in
|
||||||
|
`readiness pid` mode (default). Services declared with `notify:none`
|
||||||
|
will transition to ready as soon as Finit has started them, e.g.,
|
||||||
|
`service/qux/ready`.
|
||||||
|
|
||||||
|
To synchronize two services the following condition can be used:
|
||||||
|
|
||||||
|
service notify:pid watchdogd
|
||||||
|
service <service/watchdogd/ready> stress-ng --cpu 8
|
||||||
|
|
||||||
|
For details on the syntax and options, see below.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> On `initctl reload` conditions are set in "flux", while figuring out
|
||||||
|
> which services to stop, start or restart. Services that need to be
|
||||||
|
> restarted have their `ready` condition removed before Finit issue a
|
||||||
|
> SIGHUP (if they support that), or stop-starting them. A daemon is
|
||||||
|
> expected to reassert its readiness, e.g. systemd style daemons to
|
||||||
|
> write `READY=1\n`.
|
||||||
|
>
|
||||||
|
> However, the s6 notify mode does not support this because in s6 you
|
||||||
|
> are expected to close your notify descriptor after having written
|
||||||
|
> `\n`. This means s6 style daemons currently must be stop-started.
|
||||||
|
> (Declare the service with `<!>` in its condition statement.)
|
||||||
|
>
|
||||||
|
> For default, PID file style readiness notification, daemons are
|
||||||
|
> expected to either create their PID files, or touch it using
|
||||||
|
> `utimensat()` to reassert readiness. Triggering both the `<pid/>`
|
||||||
|
> and `<.../ready>` conditions.
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
Service Wrapper Scripts
|
||||||
|
=======================
|
||||||
|
|
||||||
|
If your service requires to run additional commands, executed before the
|
||||||
|
service is actually started, like the systemd `ExecStartPre`, you can
|
||||||
|
use a wrapper shell script to start your service.
|
||||||
|
|
||||||
|
The Finit service `.conf` file can be put into `/etc/finit.d/available`,
|
||||||
|
so you can control the service using `initctl`. Then use the path to
|
||||||
|
the wrapper script in the Finit `.conf` service stanza. The following
|
||||||
|
example employs a wrapper script in `/etc/start.d`.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
* `/etc/finit.d/available/program.conf`:
|
||||||
|
|
||||||
|
service [235] <!> /etc/start.d/program -- Example Program
|
||||||
|
|
||||||
|
* `/etc/start.d/program:`
|
||||||
|
|
||||||
|
#!/bin/sh
|
||||||
|
# Prepare the command line options
|
||||||
|
OPTIONS="-u $(cat /etc/username)"
|
||||||
|
|
||||||
|
# Execute the program
|
||||||
|
exec /usr/bin/program $OPTIONS
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The example sets `<!>` to denote that it doesn't support `SIGHUP`.
|
||||||
|
> That way Finit will stop/start the service instead of sending SIGHUP
|
||||||
|
> at restart/reload events.
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
Services
|
||||||
|
========
|
||||||
|
|
||||||
|
**Syntax:** `service [LVLS] <COND> /path/to/daemon ARGS -- Optional description`
|
||||||
|
|
||||||
|
Service, or daemon, to be monitored and automatically restarted if it
|
||||||
|
exits prematurely. Finit tries to restart services that die, by default
|
||||||
|
10 times before giving up and marking them as *crashed*. After which
|
||||||
|
they have to be manually restarted with `initctl restart NAME`. The
|
||||||
|
limits controlling this are configurable, see the options below.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> To allow endless restarts, see the [`respawn` option](service-opts.md)
|
||||||
|
|
||||||
|
For daemons that support it, we recommend appending `--foreground`,
|
||||||
|
`--no-background`, `-n`, `-F`, or similar command line argument to
|
||||||
|
prevent them from forking off a sub-process in the background. This is
|
||||||
|
the most reliable way to monitor a service.
|
||||||
|
|
||||||
|
However, not all daemons support running in the foreground, or they may
|
||||||
|
start logging to the foreground as well, these are forking daemons and
|
||||||
|
are supported using the same syntax as forking `sysv` services, using
|
||||||
|
the `pid:!/path/to/pidfile.pid` syntax. There is an alternative syntax
|
||||||
|
that may be more intuitive, where Finit can also guess the PID file
|
||||||
|
based on the daemon's command name:
|
||||||
|
|
||||||
|
service type:forking ntpd -- NTP daemon
|
||||||
|
|
||||||
|
This example lets BusyBox `ntpd` daemonize itself. Finit uses the
|
||||||
|
basename of the binary to guess the PID file to watch for the PID:
|
||||||
|
`/var/run/ntpd.pid`. If Finit guesses wrong, you have to submit the
|
||||||
|
full `pid:!/path/to/file.pid`.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
In the case of `ospfd` (below), we omit the `-d` flag (daemonize) to
|
||||||
|
prevent it from forking to the background:
|
||||||
|
|
||||||
|
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
|
||||||
|
|
||||||
|
`[2345]` denote the runlevels `ospfd` is allowed to run in, they are
|
||||||
|
optional and default to level 2-5 if omitted.
|
||||||
|
|
||||||
|
`<...>` is the condition for starting `ospfd`. In this example Finit
|
||||||
|
waits for another service, `zebra`, to have created its PID file in
|
||||||
|
`/var/run/quagga/zebra.pid` before starting `ospfd`. Finit watches
|
||||||
|
*all* files in `/var/run`, for each file named `*.pid`, or `*/pid`,
|
||||||
|
Finit opens it and find the matching `NAME:ID` using the PID.
|
||||||
|
|
||||||
|
The condition can be prefixed with `!` and/or `~`:
|
||||||
|
|
||||||
|
- `<!pid/zebra>` -- `ospfd` does not support `SIGHUP` (noreload)
|
||||||
|
- `<~pid/zebra>` -- propagate reload from `zebra` to `ospfd`
|
||||||
|
- `<!~pid/zebra>` -- both: noreload and propagate reload
|
||||||
|
|
||||||
|
For details, see the [Finit Conditions](../conditions.md) document.
|
||||||
|
|
||||||
|
Some services do not maintain a PID file and rather than patching each
|
||||||
|
application Finit provides a workaround. A `pid` keyword can be set
|
||||||
|
to have Finit automatically create (when starting) and later remove
|
||||||
|
(when stopping) the PID file. The file is created in the `/var/run`
|
||||||
|
directory using the `basename(1)` of the service. The default can be
|
||||||
|
modified with an optional `pid:`-argument:
|
||||||
|
|
||||||
|
pid[:[/path/to/]filename[.pid]]
|
||||||
|
|
||||||
|
For example, by adding `pid:/run/bar.pid` to the service `/sbin/bar`,
|
||||||
|
that PID file will, not only be created and removed automatically, but
|
||||||
|
also be used by the Finit condition subsystem. So a service/run/task
|
||||||
|
can depend on `<pid/bar>`, like this foo will not be started until bar
|
||||||
|
has started:
|
||||||
|
|
||||||
|
service pid:/run/bar.pid bar -- Bar Service
|
||||||
|
service <pid/bar> foo -- Foo Service
|
||||||
|
|
||||||
|
Needless to say, it is better if `bar` creates its own PID file when it
|
||||||
|
has completed starting up and is ready for service.
|
||||||
|
|
||||||
|
As an alternative "readiness" notification, Finit supports both systemd
|
||||||
|
and s6 style notification. This can be enabled by using the `notify`
|
||||||
|
option:
|
||||||
|
|
||||||
|
* `notify:systemd` -- tells Finit the service uses the `sd_notify()`
|
||||||
|
API to signal PID 1 when it has completed its startup and is ready
|
||||||
|
to service events. The [sd_notify()][] API expects `NOTIFY_SOCKET`
|
||||||
|
to be set to the socket where the application can send `"READY=1\n"`
|
||||||
|
when it is starting up or has processed a `SIGHUP`.
|
||||||
|
* `notify:s6` -- puts Finit in s6 compatibility mode. Compared to the
|
||||||
|
systemd notification, [s6 expect][] compliant daemons to send `"\n"`
|
||||||
|
and then close their socket. Finit takes care of "hard-wiring" the
|
||||||
|
READY state as long as the application is running, events across any
|
||||||
|
`SIGHUP`. Since s6 can give its applications the descriptor number
|
||||||
|
(must be >3) on then command line, Finit provides the following
|
||||||
|
syntax (`%n` is replaced by Finit with then descriptor number):
|
||||||
|
|
||||||
|
service [S12345789] notify:s6 mdevd -O 4 -D %n
|
||||||
|
|
||||||
|
[sd_notify()]: https://www.freedesktop.org/software/systemd/man/sd_notify.html
|
||||||
|
[s6 expect]: https://skarnet.org/software/s6/notifywhenup.html
|
||||||
|
|
||||||
|
When a service is ready, either by Finit detecting its PID file, or
|
||||||
|
their respective readiness mechanism has been triggered, Finit creates
|
||||||
|
then service's ready condition which other services can depend on:
|
||||||
|
|
||||||
|
$ initctl -v cond get service/mdevd/ready
|
||||||
|
on
|
||||||
|
|
||||||
|
This can be used to synchronize the start of another run/task/service:
|
||||||
|
|
||||||
|
task [S] <service/mdevd/ready> @root:root mdevd-coldplug
|
||||||
|
|
||||||
|
Finit waits for `mdevd` to notify it, before starting `mdevd-coldplug`.
|
||||||
|
Notice how both start in runlevel S, and the coldplug task only runs in
|
||||||
|
S. When the system moves to runlevel 2 (the default), coldplug is no
|
||||||
|
longer part of the running configuration (`initctl show`), this is to
|
||||||
|
ensure that coldplug is not called more than once.
|
||||||
|
|
||||||
|
> For a detailed description of conditions, and how to debug them,
|
||||||
|
> see the [Finit Conditions](../conditions.md) document.
|
||||||
|
|
||||||
|
|
||||||
|
Non-privileged Services
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Every `run`, `task`, or `service` can also list the privileges the
|
||||||
|
`/path/to/cmd` should be executed with. Prefix the command with
|
||||||
|
`@USR[:GRP[,SUPP,...]]`, where group and supplementary groups are
|
||||||
|
optional, like this:
|
||||||
|
|
||||||
|
run [2345] @joe:users logger "Hello world"
|
||||||
|
|
||||||
|
Finit reads the user's supplementary group membership from `/etc/group`
|
||||||
|
automatically. Any groups the user belongs to will be inherited by
|
||||||
|
the service.
|
||||||
|
|
||||||
|
To specify additional supplementary groups beyond those in `/etc/group`,
|
||||||
|
append them after the primary group, separated by commas:
|
||||||
|
|
||||||
|
service @caddy:caddy,ssl-cert /usr/bin/caddy run
|
||||||
|
|
||||||
|
This runs the `caddy` service as user `caddy`, with primary group
|
||||||
|
`caddy`, inheriting any groups `caddy` is a member of in `/etc/group`,
|
||||||
|
plus the additional `ssl-cert` group. This is useful when a service
|
||||||
|
needs access to resources owned by groups not listed in `/etc/group`.
|
||||||
|
|
||||||
|
For multiple instances of the same command, e.g. a DHCP client or
|
||||||
|
multiple web servers, add `:ID` somewhere between the `run`, `task`,
|
||||||
|
`service` keyword and the command, like this:
|
||||||
|
|
||||||
|
service :80 [2345] httpd -f -h /http -p 80 -- Web server
|
||||||
|
service :8080[2345] httpd -f -h /http -p 8080 -- Old web server
|
||||||
|
|
||||||
|
Without the `:ID` to the service the latter will overwrite the former
|
||||||
|
and only the old web server would be started and supervised.
|
||||||
|
|
||||||
|
|
||||||
|
Conditional Loading
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Finit support conditional loading of stanzas. The following example is
|
||||||
|
take from the `system/hotplug.conf` file in the Finit distribution.
|
||||||
|
Here we only show a simplified subset.
|
||||||
|
|
||||||
|
Starting with the `nowarn` option.
|
||||||
|
|
||||||
|
service nowarn name:udevd pid:udevd /lib/systemd/systemd-udevd
|
||||||
|
service nowarn name:udevd pid:udevd udevd
|
||||||
|
|
||||||
|
When loading the .conf file Finit looks for `/lib/systemd/systemd-udevd`
|
||||||
|
if that is not found Finit automatically logs a warning. The `nowarn`
|
||||||
|
option disables this warning so that the second line can be evaluated,
|
||||||
|
which also provides a service named `udevd`.
|
||||||
|
|
||||||
|
run nowarn if:udevd <pid/udevd> :1 udevadm settle -t 0
|
||||||
|
|
||||||
|
This line is only loaded if we know of a service named `udevd`. Again,
|
||||||
|
we do not warn if `udevadm` is not found, execution will also stop here
|
||||||
|
until the PID condition is asserted, i.e., Finit detecting udevd has
|
||||||
|
started.
|
||||||
|
|
||||||
|
run nowarn conflict:udevd [S] mdev -s -- Populating device tree
|
||||||
|
|
||||||
|
If `udevd` is not available, we try to run `mdev`, but if that is not
|
||||||
|
found, again we do not warn.
|
||||||
|
|
||||||
|
Conditional loading statements can also be negated, so the previous stanza
|
||||||
|
can also be written as:
|
||||||
|
|
||||||
|
run nowarn if:!udevd [S] mdev -s -- Populating device tree
|
||||||
|
|
||||||
|
The reason for using `conflict` in this example is that a conflict can be
|
||||||
|
resolved. Stanzas marked with `conflict:foo` are rechecked at runtime.
|
||||||
|
|
||||||
|
|
||||||
|
Conditional Execution
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Similar to conditional loading of stanzas there is conditional runtime
|
||||||
|
execution. This can be confusing at first, since Finit already has a
|
||||||
|
condition subsystem, but this is more akin to the qualification to a
|
||||||
|
runlevel. E.g., a `task [123]` is qualified to run only in runlevel 1,
|
||||||
|
2, and 3. It is not considered for other runlevels.
|
||||||
|
|
||||||
|
Conditional execution qualify a run/task/service based on a condition.
|
||||||
|
Consider this (simplified) example from the Infix operating system:
|
||||||
|
|
||||||
|
run [S] name:startup <pid/sysrepo> confd -b --load startup-config
|
||||||
|
run [S] if:<usr/fail-startup> name:failure <pid/sysrepo> confd --load failure-config
|
||||||
|
|
||||||
|
The two run statements reside in the same .conf file so Finit runs them
|
||||||
|
in true sequence. If loading the file `startup-config` fails confd sets
|
||||||
|
the condition `usr/fail-startup`, thus allowing the next run statement
|
||||||
|
to load `failure-config`.
|
||||||
|
|
||||||
|
Notice the critical difference between the `<pid/sysrepo>` condition and
|
||||||
|
`if:<usr/fail-startup>`. The former is a condition for starting and the
|
||||||
|
latter is a condition to check if a run/task/service is qualified to
|
||||||
|
even be considered.
|
||||||
|
|
||||||
|
Conditional execution statements can also be negated, so provided the
|
||||||
|
file loaded did the opposite, i.e., set a condition on success, the
|
||||||
|
previous stanza can also be written as:
|
||||||
|
|
||||||
|
run [S] if:<!usr/startup-ok> name:failure <pid/sysrepo> confd ...
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
SysV Init Compatibility
|
||||||
|
=======================
|
||||||
|
|
||||||
|
It is not possible to run unmodified SysV init systems with Finit. This
|
||||||
|
was never the intention and is not the strength of Finit. However, it
|
||||||
|
comes with a few SysV Init compatibility features to ease the transition
|
||||||
|
from a serialized boot process.
|
||||||
|
|
||||||
|
SysV Init Scripts
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
**Syntax:** `sysv [LVLS] <COND> /path/to/init-script -- Optional description`
|
||||||
|
|
||||||
|
> `<COND>` is described in the [Services](services.md) section.
|
||||||
|
|
||||||
|
Similar to `task` is the `sysv` stanza, which can be used to call SysV
|
||||||
|
style scripts. The primary intention for this command is to be able to
|
||||||
|
reuse much of existing setup and init scripts in Linux distributions.
|
||||||
|
|
||||||
|
When entering an allowed runlevel, Finit calls `init-script start`, when
|
||||||
|
entering a disallowed runlevel, Finit calls `init-script stop`, and if
|
||||||
|
the Finit .conf, where `sysv` stanza is declared, is modified, Finit
|
||||||
|
calls `init-script restart` on `initctl reload`. Similar to how
|
||||||
|
`service` stanzas work.
|
||||||
|
|
||||||
|
Forking services started with `sysv` scripts can be monitored by Finit
|
||||||
|
by declaring the PID file to look for: `pid:!/path/to/pidfile.pid`.
|
||||||
|
Notice the leading `!`, it signifies Finit should not try to create the
|
||||||
|
file, but rather watch that file for the resulting forked-off PID. This
|
||||||
|
syntax also works for forking daemons that do not have a command line
|
||||||
|
option to run it in the foreground, more on this below in `service`.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> See also [SysV Init Compatibility](#sysv-init-compatibility).
|
||||||
|
|
||||||
|
`runparts DIRECTORY`
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
For a directory with traditional start/stop scripts that should run, in
|
||||||
|
order, at bootstrap, Finit provides the `runparts` directive. It runs
|
||||||
|
in runlevel S, at the very end of it (before calling `/etc/rc.local`)
|
||||||
|
making it perfect for most scenarios.
|
||||||
|
|
||||||
|
For syntax details, see the [Run-parts Scripts](runparts.md) section.
|
||||||
|
Here is an example take from a Debian installation:
|
||||||
|
|
||||||
|
runparts /etc/rc2.d
|
||||||
|
|
||||||
|
Files in these directories are usually named `SNNfoo` and `KNNfoo`,
|
||||||
|
which Finit knows about and automatically appends the correct argument:
|
||||||
|
|
||||||
|
/bin/sh -c /etc/rc2.d/S01openbsd-inetd start
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
/bin/sh -c /etc/rc0.d/K01openbsd-inetd stop
|
||||||
|
|
||||||
|
Files that do not match this pattern are started similarly but without
|
||||||
|
the extra command line argument.
|
||||||
|
|
||||||
|
Start/Stop Scripts
|
||||||
|
------------------
|
||||||
|
|
||||||
|
For syntax details, see [SysV Init Scripts](#sysv-init-scripts), above.
|
||||||
|
Here follows an example taken from a Debian installation:
|
||||||
|
|
||||||
|
sysv [2345] <pid/syslogd> /etc/init.d/openbsd-inetd -- OpenBSD inet daemon
|
||||||
|
|
||||||
|
The init script header could be parsed to extract `Default-Start:` and
|
||||||
|
other parameters for the `sysv` command to Finit. There is currently no
|
||||||
|
way to detail a generic syslogd dependency in Finit, so `Should-Start:`
|
||||||
|
in the header must be mapped to the condition system in Finit using an
|
||||||
|
absolute reference, here we depend on the sysklogd project's syslogd.
|
||||||
|
|
||||||
|
`/etc/rc.local`
|
||||||
|
---------------
|
||||||
|
|
||||||
|
One often requested feature, early on, was a way to run a site specific
|
||||||
|
script to set up, e.g., static routes or firewall rules. A user can add
|
||||||
|
a `task` or `run` command in the Finit configuration for this, but for
|
||||||
|
compatibility reasons the more widely know `/etc/rc.local` is used if
|
||||||
|
it exists, and is executable. It is called very late in the boot process
|
||||||
|
when the system has left runlevel S, stopped all old and started all new
|
||||||
|
services in the target runlevel (default 2).
|
||||||
|
|
||||||
|
> In Finit releases before v4.5 this script blocked Finit execution and
|
||||||
|
> made it as good as impossible to call `initctl` during that time.
|
||||||
|
|
||||||
|
`init q`
|
||||||
|
--------
|
||||||
|
|
||||||
|
When `/sbin/finit` is installed as `/sbin/init`, it is possible to use
|
||||||
|
`init q` to reload the configuration. This is the same as calling
|
||||||
|
`initctl reload`.
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
run (sequence)
|
||||||
|
--------------
|
||||||
|
|
||||||
|
**Syntax:** `run [LVLS] <COND> /path/to/cmd ARGS -- Optional description`
|
||||||
|
|
||||||
|
> `<COND>` is described in the [Services](services.md) section.
|
||||||
|
|
||||||
|
One-shot command to run in sequence when entering a runlevel, with
|
||||||
|
optional arguments and description. `run` commands are guaranteed to be
|
||||||
|
completed before running the next command. Useful when serialization is
|
||||||
|
required.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Try to avoid the `run` command. It blocks much of the functionality
|
||||||
|
> in Finit, like (re)starting other (perhaps crashing) services while a
|
||||||
|
> `run` task is executing. Use other synchronization mechanisms
|
||||||
|
> instead, like conditions.
|
||||||
|
|
||||||
|
Incomplete list of unsupported `initctl` commands in `run` tasks:
|
||||||
|
|
||||||
|
- `initctl runlevel N`, setting runlevel
|
||||||
|
- `initctl reboot`
|
||||||
|
- `initctl halt`
|
||||||
|
- `initctl poweroff`
|
||||||
|
- `initctl suspend`
|
||||||
|
|
||||||
|
To prevent `initctl` from calling Finit when enabling and disabling
|
||||||
|
services from inside a `run` task, use the `--force` option. See
|
||||||
|
also the `--quiet` and `--batch` options.
|
||||||
|
|
||||||
|
task (parallel)
|
||||||
|
---------------
|
||||||
|
|
||||||
|
**Syntax:** `task [LVLS] <COND> /path/to/cmd ARGS -- Optional description`
|
||||||
|
|
||||||
|
> `<COND>` is described in the [Services](services.md) section.
|
||||||
|
|
||||||
|
One-shot like 'run', but starts in parallel with the next command.
|
||||||
|
|
||||||
|
Both `run` and `task` commands are run in a shell, so basic pipes and
|
||||||
|
redirects can be used:
|
||||||
|
|
||||||
|
task [s] echo "foo" | cat >/tmp/bar
|
||||||
|
|
||||||
|
Please note, `;`, `&&`, `||`, and similar are *not supported*. Any
|
||||||
|
non-trivial constructs are better placed in a separate shell script.
|
||||||
|
|
||||||
|
|
||||||
|
remain:yes
|
||||||
|
----------
|
||||||
|
|
||||||
|
By default, a `run` or `task` will re-run each time its runlevel is
|
||||||
|
entered, and its `post:` script does not run on completion.
|
||||||
|
|
||||||
|
With `remain:yes`, the task runs once and does not re-run on runlevel
|
||||||
|
re-entry:
|
||||||
|
|
||||||
|
task [2345] remain:yes /usr/sbin/setup-firewall -- Firewall setup
|
||||||
|
|
||||||
|
This has the following effects:
|
||||||
|
|
||||||
|
* The task does not re-run on runlevel re-entry
|
||||||
|
* The `post:` script runs when:
|
||||||
|
- The task is explicitly stopped (`initctl stop NAME`)
|
||||||
|
- The task leaves its valid runlevels (e.g., runlevel change)
|
||||||
|
|
||||||
|
This is useful for tasks that set up persistent state where:
|
||||||
|
|
||||||
|
* Cleanup should only happen on explicit stop or when leaving valid runlevels
|
||||||
|
* The setup should not be re-run on every runlevel entry
|
||||||
|
|
||||||
|
**Example:** Setting up firewall rules with cleanup on shutdown:
|
||||||
|
|
||||||
|
```
|
||||||
|
task [2345] remain:yes \
|
||||||
|
post:/usr/sbin/teardown-firewall \
|
||||||
|
/usr/sbin/setup-firewall -- Firewall setup
|
||||||
|
```
|
||||||
|
|
||||||
|
The firewall rules are created once. The `post:` script runs when
|
||||||
|
entering runlevel 0 (halt) or 6 (reboot), or on explicit stop.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The `remain:yes` option is not supported for bootstrap-only tasks
|
||||||
|
> (tasks with only runlevel S). Bootstrap tasks are deleted immediately
|
||||||
|
> after completion, and their `post:` scripts never run. A warning is
|
||||||
|
> logged if `remain:yes` is used on such tasks.
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
Templating
|
||||||
|
==========
|
||||||
|
|
||||||
|
Finit comes with rudimentary support for templating, similar to that of
|
||||||
|
systemd. Best illustrated with an example:
|
||||||
|
|
||||||
|
$ initctl show avahi-autoipd@
|
||||||
|
service :%i avahi-autoipd --syslog %i -- ZeroConf for %i
|
||||||
|
|
||||||
|
To enable ZeroConf for, e.g., `eth0`, use
|
||||||
|
|
||||||
|
$ initctl enable avahi-autoipd@eth0.conf
|
||||||
|
|
||||||
|
The enabled symlink will be set up to `avahi-autoipd@.conf` and every
|
||||||
|
instance of `%i` will in the instantiated directive be replaced with
|
||||||
|
`eth0`. Inspect the resulting instantiated template with `initctl show
|
||||||
|
avahi-autoipd:eth0` and check the status of a running instance with:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ initctl status avahi-autoipd:eth0
|
||||||
|
Status : running
|
||||||
|
Identity : avahi-autoipd:eth0
|
||||||
|
Description : ZeroConf for eth0
|
||||||
|
Origin : /etc/finit.d/enabled/avahi-autoipd@eth0.conf
|
||||||
|
Environment : -/etc/default/avahi-autoipd-eth0
|
||||||
|
Command : avahi-autoipd $AVAHI_AUTOIPD_ARGS eth0
|
||||||
|
PID file : /run/avahi-autoipd.eth0.pid
|
||||||
|
PID : 4190
|
||||||
|
User : root
|
||||||
|
Group : root
|
||||||
|
Uptime : 24 sec
|
||||||
|
Restarts : 0 (0/10)
|
||||||
|
Runlevels : [---2345-789]
|
||||||
|
Memory : 20.0k
|
||||||
|
CGroup : /system/avahi-autoipd@eth0 cpu 0 [100, max] mem [0, max]
|
||||||
|
└─ 4190 avahi-autoipd: [eth0] bound 169.254.1.9
|
||||||
|
|
||||||
|
Jul 8 11:51:42 infix-c0-ff-ee finit[1]: Starting avahi-autoipd:eth0[4190]
|
||||||
|
```
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
TTYs and Consoles
|
||||||
|
=================
|
||||||
|
|
||||||
|
**Syntax:** `tty [LVLS] <COND> DEV [BAUD] [noclear] [nowait] [nologin] [TERM]`
|
||||||
|
`tty [LVLS] <COND> CMD <ARGS> [noclear] [nowait]`
|
||||||
|
`tty [LVLS] <COND> [notty] [rescue]`
|
||||||
|
|
||||||
|
The first variant of this option uses the built-in getty on the given
|
||||||
|
TTY device DEV, in the given runlevels. DEV may be the special keyword
|
||||||
|
`@console`, which is expanded from `/sys/class/tty/console/active`,
|
||||||
|
useful on embedded systems.
|
||||||
|
|
||||||
|
The default baud rate is 0, i.e., keep kernel default.
|
||||||
|
|
||||||
|
> The `tty` stanza inherits runlevel, condition (and other feature)
|
||||||
|
> parsing from the `service` stanza. So TTYs can run in one or many
|
||||||
|
> runlevels and depend on any condition supported by Finit. This is
|
||||||
|
> useful e.g. to depend on `<pid/elogind>` before starting a TTY.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
tty [12345] /dev/ttyAMA0 115200 noclear vt220
|
||||||
|
|
||||||
|
The second `tty` syntax variant is for using an external getty, like
|
||||||
|
agetty or the BusyBox getty.
|
||||||
|
|
||||||
|
The third variant is for board bringup and the `rescue` boot mode. No
|
||||||
|
device node is required in this variant, the same output that the kernel
|
||||||
|
uses is reused for stdio. If the `rescue` option is omitted, a shell is
|
||||||
|
started (`nologin`, `noclear`, and `nowait` are implied), if the rescue
|
||||||
|
option is set the bundled `/libexec/finit/sulogin` is started to present
|
||||||
|
a bare-bones root login prompt. If the root (uid:0, gid:0) user does
|
||||||
|
not have a password set, no rescue is possible. For more information,
|
||||||
|
see the [Rescue Mode](rescue.md) section.
|
||||||
|
|
||||||
|
By default, the first two syntax variants *clear* the TTY and *wait* for
|
||||||
|
the user to press enter before starting getty.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
tty [12345] /sbin/getty -L 115200 /dev/ttyAMA0 vt100
|
||||||
|
tty [12345] /sbin/agetty -L ttyAMA0 115200 vt100 nowait
|
||||||
|
|
||||||
|
The `noclear` option disables clearing the TTY after each session.
|
||||||
|
Clearing the TTY when a user logs out is usually preferable.
|
||||||
|
|
||||||
|
The `nowait` option disables the `press Enter to activate console`
|
||||||
|
message before actually starting the getty program. On small and
|
||||||
|
embedded systems running multiple unused getty wastes both memory
|
||||||
|
and CPU cycles, so `wait` is the preferred default.
|
||||||
|
|
||||||
|
The `nologin` option disables getty and `/bin/login`, and gives the
|
||||||
|
user a root (login) shell on the given TTY `<DEV>` immediately.
|
||||||
|
Needless to say, this is a rather insecure option, but can be very
|
||||||
|
useful for developer builds, during board bringup, or similar.
|
||||||
|
|
||||||
|
Notice the ordering, the `TERM` option to the built-in getty must be
|
||||||
|
the last argument.
|
||||||
|
|
||||||
|
Embedded systems may want to enable automatic `DEV` by supplying the
|
||||||
|
special `@console` device. This works regardless weather the system
|
||||||
|
uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit figures
|
||||||
|
it out by querying sysfs: `/sys/class/tty/console/active`. The speed
|
||||||
|
can be omitted to keep the kernel default.
|
||||||
|
|
||||||
|
> Most systems get by fine by just using `console`, which will evaluate
|
||||||
|
> to `/dev/console`. If you have to use `@console` to get any output,
|
||||||
|
> you may have some issue with your kernel config.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
tty [12345] @console noclear vt220
|
||||||
|
|
||||||
|
On really bare bones systems, or for board bringup, Finit can give you a
|
||||||
|
shell prompt as soon as bootstrap is done, without opening any device
|
||||||
|
node:
|
||||||
|
|
||||||
|
tty [12345789] notty
|
||||||
|
|
||||||
|
This should of course not be enabled on production systems. Because it
|
||||||
|
may give a user root access without having to log in. However, for
|
||||||
|
board bringup and system debugging it can come in handy.
|
||||||
|
|
||||||
|
One can also use the `service` stanza to start a stand-alone shell:
|
||||||
|
|
||||||
|
service [12345] /bin/sh -l
|
||||||
|
|
||||||
|
Controlling TTY for Services
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
The `tty:<dev>` option gives a `run`, `task`, or `service` a controlling
|
||||||
|
terminal on the given device. The device is opened, set as the
|
||||||
|
controlling terminal for the session (after `setsid()`), and connected to
|
||||||
|
the process's stdin, stdout, and stderr. A default `TERM` environment
|
||||||
|
variable is set based on the device type: `vt102` for serial lines and
|
||||||
|
`linux` for virtual terminals.
|
||||||
|
|
||||||
|
`<dev>` may be a device node like `/dev/ttyS0`, or the special keyword
|
||||||
|
`@console` (see above). Note that `@console` expands only to the
|
||||||
|
first console, not all.
|
||||||
|
|
||||||
|
When `tty:` is combined with `log:`, stdout and stderr are redirected
|
||||||
|
to the log sink instead of the TTY, but stdin remains connected to the
|
||||||
|
TTY device.
|
||||||
|
|
||||||
|
> The `tty:<dev>` option is for `run`, `task`, and `service` stanzas only.
|
||||||
|
> The `tty` directive itself (for getty/login) has its own syntax, see
|
||||||
|
> above.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
service [2345] tty:/dev/ttyS0 /usr/sbin/foo -- Foo on serial console
|
||||||
|
task [S] tty:@console my-setup-script -- Board bringup on console
|
||||||
@@ -1,79 +1,139 @@
|
|||||||
Distro Recommendations
|
Distro Recommendations
|
||||||
======================
|
======================
|
||||||
|
|
||||||
By default Finit uses the following directories for configuration files:
|
Finit supports two directory layouts for managing service configurations:
|
||||||
|
|
||||||
|
1. **Simple layout** - all configuration files directly in `/etc/finit.d/`
|
||||||
|
2. **Distro layout** - separate `available/` and `enabled/` directories
|
||||||
|
|
||||||
|
The distro layout is recommended for distributions that need clear
|
||||||
|
separation between installed and enabled services, and want to use the
|
||||||
|
`initctl enable/disable` commands for service management.
|
||||||
|
|
||||||
|
## Simple Layout
|
||||||
|
|
||||||
|
Finit supports using a flat directory structure:
|
||||||
|
|
||||||
```
|
```
|
||||||
/etc/
|
/etc/
|
||||||
|-- finit.d/ -- Regular (enabled) services
|
|-- finit.d/ -- All enabled services
|
||||||
| |-- lighttpd.conf
|
| |-- lighttpd.conf
|
||||||
| `- *.conf
|
| `- *.conf
|
||||||
|-- finit.conf -- Bootstrap tasks and services
|
|-- finit.conf -- Bootstrap tasks and services
|
||||||
:
|
:
|
||||||
```
|
```
|
||||||
|
|
||||||
To enable a service one simply drops a small configuration file in the
|
In this layout, you enable a service by placing its `.conf` file in
|
||||||
`/etc/finit.d/` directory. This practice works with systems that
|
`/etc/finit.d/` and disable it by removing the file. This works well for
|
||||||
keep disabled services elsewhere, or generates them as needed from some
|
embedded systems or custom setups where services are managed by other tools
|
||||||
other tool.
|
or generated dynamically.
|
||||||
|
|
||||||
Distributions, however, may want a clearer separation of enabled and
|
> [!NOTE] No tooling support
|
||||||
available (installed but not enabled) services. They may even want to
|
> The `initctl enable/disable` commands **do not work** with this layout.
|
||||||
customize the directories used, for brand labeling or uniformity.
|
> You must manually manage files in `/etc/finit.d/`.
|
||||||
|
|
||||||
To that end Finit allows for a sub-directory `/etc/finit.d/available/`
|
## Distro Layout
|
||||||
where installed but disabled services can reside. Adding a symlink to a
|
|
||||||
configuration in this sub-directory enables the service, but it will not
|
|
||||||
be started.
|
|
||||||
|
|
||||||
To change the default configuration directory and configuration file
|
Distributions typically want clearer separation between available (installed)
|
||||||
names the Finit `configure` script offers the following two options at
|
and enabled services. Finit supports this through the `available/` and
|
||||||
build time:
|
`enabled/` subdirectories:
|
||||||
|
|
||||||
|
```
|
||||||
|
/etc/
|
||||||
|
|-- finit.d/
|
||||||
|
| |-- available/ -- Installed but disabled services
|
||||||
|
| | |-- httpd.conf
|
||||||
|
| | |-- ntpd.conf
|
||||||
|
| | `-- sshd.conf
|
||||||
|
| |-- enabled/ -- Enabled services (symlinks)
|
||||||
|
| | `- sshd.conf -- Symlink to ../available/sshd.conf
|
||||||
|
|-- finit.conf -- Bootstrap tasks and services
|
||||||
|
:
|
||||||
|
```
|
||||||
|
|
||||||
|
In this layout:
|
||||||
|
- **available/** contains all installed service configurations
|
||||||
|
- **enabled/** contains symlinks to configurations that should start at boot
|
||||||
|
- Services are enabled/disabled by creating/removing symlinks
|
||||||
|
|
||||||
|
> [!IMPORTANT] Recommended
|
||||||
|
> This is the recommended layout. In fact, the `initctl enable/disable`
|
||||||
|
> commands **require** this layout with both `available/` and `enabled/`
|
||||||
|
> directories and will not work without it.
|
||||||
|
|
||||||
|
## Managing Services with initctl
|
||||||
|
|
||||||
|
When using the distro layout, the `initctl` tool provides convenient commands
|
||||||
|
for managing service configurations:
|
||||||
|
|
||||||
|
```
|
||||||
|
list List all .conf in /etc/finit.d/
|
||||||
|
enable <CONF> Enable .conf by creating symlink in enabled/
|
||||||
|
disable <CONF> Disable .conf by removing symlink from enabled/
|
||||||
|
reload Reload *.conf in /etc/finit.d/ (activate changes)
|
||||||
|
```
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable sshd (creates enabled/sshd.conf -> ../available/sshd.conf)
|
||||||
|
initctl enable sshd
|
||||||
|
|
||||||
|
# Disable httpd (removes enabled/httpd.conf symlink)
|
||||||
|
initctl disable httpd
|
||||||
|
|
||||||
|
# Apply changes (reload configuration and start/stop services)
|
||||||
|
initctl reload
|
||||||
|
```
|
||||||
|
|
||||||
|
The `.conf` suffix is optional - `initctl` adds it automatically if missing.
|
||||||
|
|
||||||
|
> [!NOTE] Remember `initctl reload`
|
||||||
|
> Changes made with `enable`/`disable` take effect only after running
|
||||||
|
> `initctl reload`, unless Finit was built with `--enable-auto-reload`
|
||||||
|
> which automatically detects and applies configuration changes.
|
||||||
|
|
||||||
|
### Service Overrides
|
||||||
|
|
||||||
|
The `initctl` tool only operates on symlinks in the `enabled/` directory.
|
||||||
|
If you place a regular (non-symlink) `.conf` file directly in the parent
|
||||||
|
directory (e.g., `/etc/finit.d/`), `initctl` will ignore it. This allows
|
||||||
|
you to create system-level overrides that cannot be accidentally disabled
|
||||||
|
by package management tools.
|
||||||
|
|
||||||
|
## Customizing Directory Paths
|
||||||
|
|
||||||
|
Distributions can customize the directory names and locations at build time
|
||||||
|
using the Finit `configure` script:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./configure --with-rcsd=/etc/init.d --with-config=/etc/init.d/init.conf
|
./configure --with-rcsd=/etc/init.d --with-config=/etc/init.d/init.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note:** remember `--prefix` et al as well, the default is likely
|
This changes the default `/etc/finit.d/` to `/etc/init.d/` and moves the
|
||||||
> *not* what you want. See the [build docs][1] for details.
|
bootstrap configuration file accordingly.
|
||||||
|
|
||||||
The resulting directory structure is depicted below. Please notice how
|
> [!IMPORTANT] Remember to set `--prefix`
|
||||||
`/etc/finit.conf` now resides in the same sub-directory as a non-symlink
|
> Remember to set `--prefix` and related options appropriately. The default
|
||||||
`/etc/init.d/init.conf`:
|
> prefix is `/usr/local`, which is likely not what you want for a system
|
||||||
|
> init. See the [build documentation][1] for details.
|
||||||
|
|
||||||
|
Example with custom paths:
|
||||||
|
|
||||||
```
|
```
|
||||||
/etc/
|
/etc/
|
||||||
|-- init.d/
|
|-- init.d/
|
||||||
| |-- available/ -- Regular (disabled) services
|
| |-- available/ -- Installed services
|
||||||
| | |-- httpd.conf
|
| | |-- httpd.conf
|
||||||
| | |-- ntpd.conf
|
| | |-- ntpd.conf
|
||||||
| | `-- sshd.conf
|
| | `-- sshd.conf
|
||||||
| |-- sshd.conf -- Symlink to available/sshd.conf
|
| |-- enabled/ -- Enabled services (symlinks)
|
||||||
|
| | `- sshd.conf -- Symlink to ../available/sshd.conf
|
||||||
| `- init.conf -- Bootstrap tasks and services
|
| `- init.conf -- Bootstrap tasks and services
|
||||||
:
|
:
|
||||||
```
|
```
|
||||||
|
|
||||||
To facilitate the task of managing configurations, be it a service,
|
Notice how both the service directory and bootstrap configuration file now
|
||||||
task, run, or other stanza, the `initctl` tool has a a few built-in
|
use the custom `/etc/init.d/` path specified at build time.
|
||||||
commands:
|
|
||||||
|
|
||||||
```
|
|
||||||
list List all .conf in /etc/finit.d/
|
|
||||||
enable <CONF> Enable .conf in /etc/finit.d/available/
|
|
||||||
disable <CONF> Disable .conf in /etc/finit.d/[enabled/]
|
|
||||||
reload Reload *.conf in /etc/finit.d/ (activates changes)
|
|
||||||
```
|
|
||||||
|
|
||||||
To enable a service like `sshd.conf`, above, use
|
|
||||||
|
|
||||||
initctl enable sshd
|
|
||||||
|
|
||||||
The `.conf` suffix is not needed, `initctl` adds it implicitly if it is
|
|
||||||
missing. The `disable` command works in a similar fashion.
|
|
||||||
|
|
||||||
Note, however, that `initctl` only operates on symlinks and it always
|
|
||||||
requires the `available/` sub-directory. Any non-symlink in the parent
|
|
||||||
directory, here `/etc/init.d/`, will be considered a system override by
|
|
||||||
`initctl`.
|
|
||||||
|
|
||||||
[1]: build.md#configure
|
[1]: build.md#configure
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
Configuration Example
|
||||||
|
=====================
|
||||||
|
|
||||||
|
This example `/etc/finit.conf` can also be split up in multiple `.conf`
|
||||||
|
files in `/etc/finit.d`. Available, but not yet enabled, services can
|
||||||
|
be placed in `/etc/finit.d/available` and enabled by an operator using
|
||||||
|
the [initctl](initctl.md) tool.
|
||||||
|
|
||||||
|
See the [contrib/][contrib] directory on GitHub for examples, or take a
|
||||||
|
peek at systems using Finit, like [Infix OS][infix] and [myLinux][].
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> As of Finit v4.4, `.conf` lines can be broken up using the standard UNIX
|
||||||
|
> continuation character (`\`), trailing comments are also supported. The
|
||||||
|
> latter means you must escape any hashes used in directives and descriptions
|
||||||
|
> (`\#`). For more on this and examples, see the [finit.conf(5)][] manual or
|
||||||
|
> the [Configuration](config/index.md) section.
|
||||||
|
|
||||||
|
```ApacheConf
|
||||||
|
# Fallback if /etc/hostname is missing
|
||||||
|
host default
|
||||||
|
|
||||||
|
# Runlevel to start after bootstrap, 'S', default: 2
|
||||||
|
#runlevel 2
|
||||||
|
|
||||||
|
# Support for setting global environment variables, using foo=bar syntax
|
||||||
|
# be careful though with variables like PATH, SHELL, LOGNAME, etc.
|
||||||
|
#PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||||
|
|
||||||
|
# Max file size for each log file: 100 kiB, rotate max 4 copies:
|
||||||
|
# log => log.1 => log.2.gz => log.3.gz => log.4.gz
|
||||||
|
log size=100k count=4
|
||||||
|
|
||||||
|
# Services to be monitored and respawned as needed
|
||||||
|
service [S12345] env:-/etc/conf.d/watchdog watchdog $WATCHDOG_OPTS $WATCHDOG_DEV -- System watchdog daemon
|
||||||
|
service [S12345] env:-/etc/conf.d/syslog syslogd -n $SYSLOGD_OPTS -- System log daemon
|
||||||
|
service [S12345] <pid/syslogd> env:-/etc/conf.d/klogd klogd -n $KLOGD_OPTS -- Kernel log daemon
|
||||||
|
service [2345] env:-/etc/conf.d/lldpd lldpd -d $LLDPD_OPTS -- LLDP daemon (IEEE 802.1ab)
|
||||||
|
|
||||||
|
# The BusyBox ntpd does not use syslog when running in the foreground
|
||||||
|
# So we use this trick to redirect stdout/stderr to a log file. The
|
||||||
|
# log file is rotated with the above settings. The condition declares
|
||||||
|
# a dependency on a system default route (gateway) to be set. A single
|
||||||
|
# <!> at the beginning means ntpd does not respect SIGHUP for restart.
|
||||||
|
service [2345] log:/var/log/ntpd.log <!net/route/default> ntpd -n -l -I eth0 -- NTP daemon
|
||||||
|
|
||||||
|
# For multiple instances of the same service, add :ID somewhere between
|
||||||
|
# the service/run/task keyword and the command.
|
||||||
|
service :80 [2345] merecat -n -p 80 /var/www -- Web server
|
||||||
|
service :8080 [2345] merecat -n -p 8080 /var/www -- Old web server
|
||||||
|
|
||||||
|
# Alternative method instead of below runparts, can also use /etc/rc.local
|
||||||
|
#sysv [S] /etc/init.d/keyboard-setup -- Setting up preliminary keymap
|
||||||
|
#sysv [S] /etc/init.d/acpid -- Starting ACPI Daemon
|
||||||
|
#task [S] /etc/init.d/kbd -- Preparing console
|
||||||
|
|
||||||
|
# Hidden from boot progress, using empty `--` description
|
||||||
|
#sysv [S] /etc/init.d/keyboard-setup --
|
||||||
|
#sysv [S] /etc/init.d/acpid --
|
||||||
|
#task [S] /etc/init.d/kbd --
|
||||||
|
|
||||||
|
# Run start scripts from this directory
|
||||||
|
# runparts /etc/start.d
|
||||||
|
|
||||||
|
# Virtual consoles run BusyBox getty, keep kernel default speed
|
||||||
|
tty [12345] /sbin/getty -L 0 /dev/tty1 linux nowait noclear
|
||||||
|
tty [2345] /sbin/getty -L 0 /dev/tty2 linux nowait noclear
|
||||||
|
tty [2345] /sbin/getty -L 0 /dev/tty3 linux nowait noclear
|
||||||
|
|
||||||
|
# Use built-in getty for serial port and USB serial
|
||||||
|
#tty [12345] /dev/ttyAMA0 noclear nowait
|
||||||
|
#tty [12345] /dev/ttyUSB0 noclear
|
||||||
|
|
||||||
|
# Just give me a shell, I need to debug this embedded system!
|
||||||
|
#tty [12345] console noclear nologin
|
||||||
|
```
|
||||||
|
|
||||||
|
The `service` stanza, as well as `task`, `run` and others are described in
|
||||||
|
full in the [Services Syntax](config/services.md) section.
|
||||||
|
|
||||||
|
Here's a quick overview of some of the most common components needed to start
|
||||||
|
a UNIX daemon:
|
||||||
|
|
||||||
|
```
|
||||||
|
service [LVLS] <COND> log env:[-]/etc/default/daemon daemon ARGS -- Example daemon
|
||||||
|
^ ^ ^ ^ ^ ^ ^ ^
|
||||||
|
| | | | | | | `---------- Optional description
|
||||||
|
| | | | | | `------------------ Daemon arguments
|
||||||
|
| | | | | `------------------------- Path to daemon
|
||||||
|
| | | | `---------------------------------------------------- Optional env. file
|
||||||
|
| | | `-------------------------------------------------------- Redirect output to log
|
||||||
|
| | `--------------------------------------------------------------- Optional conditions
|
||||||
|
| `---------------------------------------------------------------------- Optional Runlevels
|
||||||
|
`------------------------------------------------------------------------------ Supervised program (daemon)
|
||||||
|
```
|
||||||
|
|
||||||
|
Some components are optional: runlevel(s), condition(s) and description,
|
||||||
|
making it easy to create simple start scripts and still possible for more
|
||||||
|
advanced uses as well:
|
||||||
|
|
||||||
|
service /usr/sbin/sshd -D
|
||||||
|
|
||||||
|
Dependencies are handled using [conditions](conditions.md). One of
|
||||||
|
the most common conditions is to wait for basic networking to become
|
||||||
|
available:
|
||||||
|
|
||||||
|
service <net/route/default> nginx -- High performance HTTP server
|
||||||
|
|
||||||
|
Here is another example where we instruct Finit to not start BusyBox
|
||||||
|
`ntpd` until `syslogd` has started properly. Finit waits for `syslogd`
|
||||||
|
to create its PID file, by default `/var/run/syslogd.pid`.
|
||||||
|
|
||||||
|
service [2345] log <!pid/syslogd> ntpd -n -N -p pool.ntp.org
|
||||||
|
service [S12345] syslogd -n -- Syslog daemon
|
||||||
|
|
||||||
|
Notice the `log` keyword, BusyBox `ntpd` uses `stderr` for logging when
|
||||||
|
run in the foreground. With `log` Finit redirects `stdout` + `stderr`
|
||||||
|
to the system log daemon using the command line `logger(1)` tool.
|
||||||
|
|
||||||
|
A service, or task, can have multiple dependencies listed. Here we wait
|
||||||
|
for *both* `syslogd` to have started and basic networking to be up:
|
||||||
|
|
||||||
|
service [2345] log <pid/syslogd,net/route/default> ntpd -n -N -p pool.ntp.org
|
||||||
|
|
||||||
|
If either condition fails, e.g. loss of networking, `ntpd` is stopped
|
||||||
|
and as soon as it comes back up again `ntpd` is restarted automatically.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Make sure daemons do *not* fork and detach themselves from the controlling
|
||||||
|
> TTY, usually an `-n` or `-f` flag, or `-D` as in the case of OpenSSH above.
|
||||||
|
> If it detaches itself, Finit cannot monitor it and will instead try to
|
||||||
|
> restart it.
|
||||||
|
|
||||||
|
[finit.conf(5)]: https://man.troglobit.com/man5/finit.conf.5.html
|
||||||
|
[infix]: https://kernelkit.github.io
|
||||||
|
[myLinux]: https://github.com/troglobit/myLinux/
|
||||||
|
[contrib]: https://github.com/finit-project/finit/tree/master/contrib
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
.md-header__topic:first-child {
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-header__title {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 2.6rem;
|
||||||
|
}
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
Finit Features
|
||||||
|
==============
|
||||||
|
|
||||||
|
This page highlights some of Finit's key features with examples and usage
|
||||||
|
scenarios. For complete documentation, configuration syntax, and advanced
|
||||||
|
options, see the [Configuration](config/index.md) section.
|
||||||
|
|
||||||
|
**Process Supervision**
|
||||||
|
|
||||||
|
Start, monitor and restart services should they fail.
|
||||||
|
|
||||||
|
|
||||||
|
**Getty**
|
||||||
|
|
||||||
|
Finit supports external getty but also comes with a limited built-in
|
||||||
|
Getty, useful for really small systems. A getty sets up the TTY and
|
||||||
|
waits for user input before handing over to `/bin/login`, which is
|
||||||
|
responsible for handling the actual authentication.
|
||||||
|
|
||||||
|
```conf
|
||||||
|
tty [12345] /dev/tty1 nowait linux
|
||||||
|
tty [12345] /dev/ttyAMA0 noclear vt100
|
||||||
|
tty [12345] /sbin/getty -L /dev/ttyAMA0 vt100
|
||||||
|
```
|
||||||
|
|
||||||
|
Users of embedded systems may want to enable automatic serial console
|
||||||
|
with the special `@console` device. This works regardless whether the
|
||||||
|
system uses `ttyS0`, `ttyAMA0`, `ttyMXC0`, or anything else. Finit
|
||||||
|
figures it out by querying sysfs: `/sys/class/tty/console/active`.
|
||||||
|
|
||||||
|
```conf
|
||||||
|
tty [12345] @console linux noclear
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice the optional `noclear`, `nowait`, and `nologin` flags. The
|
||||||
|
latter is for skipping the login process entirely. For more information,
|
||||||
|
see the [TTY and Consoles](config/tty.md) section.
|
||||||
|
|
||||||
|
|
||||||
|
**Runlevels**
|
||||||
|
|
||||||
|
Support for SysV init-style [runlevels][5] is available, in the same
|
||||||
|
minimal style as everything else in Finit. The `[2345]` syntax can be
|
||||||
|
applied to service, task, run, and TTY stanzas.
|
||||||
|
|
||||||
|
Reserved runlevels are 0 and 6, halt and reboot, respectively just like
|
||||||
|
SysV init. Runlevel 1 can be configured freely, but is recommended to
|
||||||
|
be kept as the system single-user runlevel since Finit will not start
|
||||||
|
networking here. The configured `runlevel NUM` from `/etc/finit.conf`
|
||||||
|
is what Finit changes to after bootstrap, unless 'single' (or 'S') is
|
||||||
|
given on the kernel cmdline, in which case runlevel 1 is started.
|
||||||
|
|
||||||
|
All services in runlevel S) are started first, followed by the desired
|
||||||
|
run-time runlevel. Run tasks in runlevel S can be started in sequence
|
||||||
|
by using `run [S] cmd`. Changing runlevels at runtime is done like any
|
||||||
|
other init, e.g. <kbd>init 4</kbd>, but also using the more advanced
|
||||||
|
[`initctl`](initctl.md) tool.
|
||||||
|
|
||||||
|
|
||||||
|
**Conditions**
|
||||||
|
|
||||||
|
As mentioned previously, Finit has an advanced dependency system to
|
||||||
|
handle synchronization, called [conditions](conditions.md). It can
|
||||||
|
be used in many ways; depend on another service, network availability,
|
||||||
|
etc.
|
||||||
|
|
||||||
|
One *really cool* example useful for embedded systems is to run certain
|
||||||
|
scripts if a board has a certain feature encoded in its device tree. At
|
||||||
|
bootstrap we run the following `ident` script:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/bin/sh
|
||||||
|
conddir=/var/run/finit/cond/hw/model
|
||||||
|
dtmodel=/sys/firmware/devicetree/base/model
|
||||||
|
|
||||||
|
if ! test -e $dtmodel; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
model=$(cat $dtmodel | tr "[A-Z] " "[a-z]-")
|
||||||
|
mkdir -p $conddir && ln -s ../../reconf $conddir/$model
|
||||||
|
```
|
||||||
|
|
||||||
|
Provided the device tree node exists, and is a string, we can then use
|
||||||
|
the condition `<hw/model/foo>` when starting other scripts. Here is an
|
||||||
|
example:
|
||||||
|
|
||||||
|
```
|
||||||
|
run [S] /path/to/ident --
|
||||||
|
task [2] <hw/model/foo> /path/to/foo-init -- Initializing Foo board
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> Notice the trick with an empty description to hide the call to `ident`
|
||||||
|
> in the Finit progress output.
|
||||||
|
|
||||||
|
|
||||||
|
**Plugins**
|
||||||
|
|
||||||
|
Plugins can *extend* the functionality of Finit and *hook into* the
|
||||||
|
different stages of the boot process and at runtime. Plugins are
|
||||||
|
written in C and compiled into a dynamic library loaded automatically by
|
||||||
|
finit at boot. A basic set of plugins are bundled in the `plugins/`
|
||||||
|
directory.
|
||||||
|
|
||||||
|
Capabilities:
|
||||||
|
|
||||||
|
- **Hooks**
|
||||||
|
Hook into the boot at predefined points to extend Finit
|
||||||
|
- **I/O**
|
||||||
|
Listen to external events and control Finit behavior/services
|
||||||
|
|
||||||
|
Extensions and functionality not purely related to what an `/sbin/init`
|
||||||
|
needs to start a system are available as a set of plugins that either
|
||||||
|
hook into the boot process or respond to various I/O.
|
||||||
|
|
||||||
|
For more information, see the [Plugins](plugins.md) section.
|
||||||
|
|
||||||
|
|
||||||
|
**Automatic Reload**
|
||||||
|
|
||||||
|
By default, Finit monitors `/etc/finit.d/` and `/etc/finit.d/enabled/`
|
||||||
|
registering any changes to `.conf` files. To activate a change the user
|
||||||
|
must call `initctl reload`, which reloads all modified files, stops any
|
||||||
|
removed services, starts new ones, and restarts any modified ones. If the
|
||||||
|
command line arguments of a service have changed, the process will be
|
||||||
|
terminated and then started again with the updated arguments. If the arguments
|
||||||
|
have not been modified and the process supports SIGHUP, the process will
|
||||||
|
receive a SIGHUP rather than being terminated and started.
|
||||||
|
|
||||||
|
For some use-cases the extra step of calling `initctl reload` creates an
|
||||||
|
unnecessary overhead, which can be removed at build-time using:
|
||||||
|
|
||||||
|
configure --enable-auto-reload
|
||||||
|
|
||||||
|
|
||||||
|
**Linux Capabilities**
|
||||||
|
|
||||||
|
Finit supports Linux capabilities, allowing services to run with minimal
|
||||||
|
required privileges instead of running as root. This improves security by
|
||||||
|
following the principle of least privilege.
|
||||||
|
|
||||||
|
```conf
|
||||||
|
service [2345] name:nginx \
|
||||||
|
www-data:www-data \
|
||||||
|
caps:^cap_net_bind_service \
|
||||||
|
/usr/sbin/nginx -g 'daemon off;'
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, nginx runs as the unprivileged `www-data` user but retains
|
||||||
|
the ability to bind to privileged ports (80, 443) through the
|
||||||
|
`cap_net_bind_service` capability.
|
||||||
|
|
||||||
|
The `caps:` directive uses the IAB (Inheritable, Ambient, Bounding) format:
|
||||||
|
- `^` = Ambient (recommended) - capabilities survive exec()
|
||||||
|
- `%` = Inheritable only - requires file capabilities
|
||||||
|
- `!` = Bounding - block from acquiring capability
|
||||||
|
|
||||||
|
Multiple capabilities can be specified as comma-separated:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
caps:^cap_net_raw,^cap_net_admin,!cap_sys_admin
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [Linux Capabilities](config/capabilities.md) section for detailed
|
||||||
|
information, examples, and security best practices.
|
||||||
|
|
||||||
|
|
||||||
|
**Supplementary Groups**
|
||||||
|
|
||||||
|
Finit supports supplementary groups for services, allowing them to access
|
||||||
|
resources owned by multiple groups without running as root. This complements
|
||||||
|
capabilities for fine-grained privilege control.
|
||||||
|
|
||||||
|
```conf
|
||||||
|
service @caddy:caddy,ssl-cert /usr/bin/caddy run
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, the Caddy web server runs as user `caddy` with primary group
|
||||||
|
`caddy`, but also has access to resources owned by the `ssl-cert` group (such
|
||||||
|
as TLS certificates).
|
||||||
|
|
||||||
|
Finit automatically reads the user's supplementary group membership from
|
||||||
|
`/etc/group`. Additional groups can be specified explicitly using the syntax
|
||||||
|
`@user:group,sup1,sup2,...`.
|
||||||
|
|
||||||
|
See the [Non-privileged Services](config/services.md#non-privileged-services)
|
||||||
|
section for more information.
|
||||||
|
|
||||||
|
|
||||||
|
**Cgroups**
|
||||||
|
|
||||||
|
Finit supports cgroups v2 and comes with the following default groups in
|
||||||
|
which services and user sessions are placed in:
|
||||||
|
|
||||||
|
/sys/fs/cgroup
|
||||||
|
|-- init/ # cpu.weight:100
|
||||||
|
|-- system/ # cpu.weight:9800
|
||||||
|
`-- user/ # cpu.weight:100
|
||||||
|
|
||||||
|
Finit itself and its helper scripts and services are placed in the
|
||||||
|
top-level leaf-node group `init/`, which also is _reserved_.
|
||||||
|
|
||||||
|
All run/task/service/sysv processes are placed in their own sub-group
|
||||||
|
in `system/`. The name of each sub-group is taken from the respective
|
||||||
|
`.conf` file from `/etc/finit.d`.
|
||||||
|
|
||||||
|
All getty/tty processes are placed in their own sub-group in `user/`.
|
||||||
|
The name of each sub-group is taken from the username.
|
||||||
|
|
||||||
|
A fourth group also exists, the `root` group. It is also _reserved_ and
|
||||||
|
primarily intended for RT tasks. If you have RT tasks they need to be
|
||||||
|
declared as such in their service stanza like this:
|
||||||
|
|
||||||
|
service [...] <...> cgroup.root /path/to/foo args -- description
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
cgroup.root
|
||||||
|
service [...] <...> /path/to/foo args -- description
|
||||||
|
service [...] <...> /path/to/bar args -- description
|
||||||
|
|
||||||
|
See the [Cgroups](config/cgroups.md) section for more information, e.g.,
|
||||||
|
how to configure per-group limits.
|
||||||
|
|
||||||
|
The `initctl` tool has three commands to help debug and optimize the
|
||||||
|
setup and monitoring of cgroups. See the `ps`, `top`, and `cgroup`
|
||||||
|
commands for details.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Systems that do not support cgroups, specifically version 2, are
|
||||||
|
> automatically detected. On such systems the above functionality is
|
||||||
|
> disabled early at boot.
|
||||||
|
|
||||||
|
|
||||||
|
**Service Management**
|
||||||
|
|
||||||
|
Finit includes the `initctl` tool for managing services and system state at
|
||||||
|
runtime. Key capabilities include:
|
||||||
|
|
||||||
|
- **Enable/Disable services**: Manage which services start at boot by moving
|
||||||
|
configuration files between `/etc/finit.d/available` and
|
||||||
|
`/etc/finit.d/enabled`
|
||||||
|
- **Start/Stop/Restart**: Control individual services without requiring a
|
||||||
|
full system reboot
|
||||||
|
- **Status monitoring**: View service state, PID, uptime, and resource usage
|
||||||
|
- **Condition management**: Set and clear user-defined conditions to control
|
||||||
|
service dependencies
|
||||||
|
- **Cgroup monitoring**: Real-time process and resource monitoring with
|
||||||
|
`initctl top`, similar to the traditional `top` command but cgroup-aware
|
||||||
|
|
||||||
|
Example commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
initctl enable myservice # Enable service for next boot
|
||||||
|
initctl start myservice # Start service now
|
||||||
|
initctl status # Show all services
|
||||||
|
initctl top # Interactive resource monitor
|
||||||
|
initctl cond set usr/custom # Set custom condition
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [Commands & Status](initctl.md) section for complete documentation.
|
||||||
|
|
||||||
|
|
||||||
|
**Rescue Mode**
|
||||||
|
|
||||||
|
Finit provides a built-in rescue mode for system recovery and maintenance.
|
||||||
|
When booting with the `rescue` kernel parameter, the system enters a
|
||||||
|
protected maintenance shell.
|
||||||
|
|
||||||
|
If the bundled `sulogin` program is available (from Finit, util-linux, or
|
||||||
|
BusyBox), you'll be prompted for the root password before accessing the
|
||||||
|
maintenance shell. This provides secure access for system recovery.
|
||||||
|
|
||||||
|
If `sulogin` is not available, Finit falls back to reading
|
||||||
|
`/lib/finit/rescue.conf` and boots the system in a limited maintenance mode.
|
||||||
|
|
||||||
|
```
|
||||||
|
# Kernel command line
|
||||||
|
linux /vmlinuz root=/dev/sda1 rescue
|
||||||
|
```
|
||||||
|
|
||||||
|
In rescue mode, `initctl` will not work. After fixing the problem, use
|
||||||
|
`reboot -f` to force reboot.
|
||||||
|
|
||||||
|
Rescue mode can be disabled at build time with `configure --without-rescue`.
|
||||||
|
|
||||||
|
See the [Rescue Mode](config/rescue.md) section for more information.
|
||||||
|
|
||||||
|
|
||||||
|
**Switch Root**
|
||||||
|
|
||||||
|
Finit supports switching from an initramfs to a real root filesystem using
|
||||||
|
the built-in `initctl switch-root` command. This allows Finit to serve as
|
||||||
|
the init system in an initramfs for early boot tasks (LUKS unlock, LVM
|
||||||
|
activation, network boot) before transitioning to the real root.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# In initramfs, after mounting the real root:
|
||||||
|
initctl switch-root /mnt/root
|
||||||
|
```
|
||||||
|
|
||||||
|
The switch-root operation:
|
||||||
|
|
||||||
|
1. Runs the `HOOK_SWITCH_ROOT` hook for cleanup
|
||||||
|
2. Stops all services gracefully
|
||||||
|
3. Moves virtual filesystems (`/dev`, `/proc`, `/sys`, `/run`) to the new root
|
||||||
|
4. Deletes initramfs contents to free memory
|
||||||
|
5. Pivots to the new root and execs the new init
|
||||||
|
|
||||||
|
See the [Switch Root](switchroot.md) section for complete documentation.
|
||||||
|
|
||||||
|
|
||||||
|
[5]: https://en.wikipedia.org/wiki/Runlevel
|
||||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 320 KiB |
|
After Width: | Height: | Size: 814 KiB |
@@ -0,0 +1,82 @@
|
|||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
{ align=right width=40% }
|
||||||
|
|
||||||
|
> Reverse engineered from the [EeePC fastinit][]
|
||||||
|
> "gaps filled with frog DNA …"
|
||||||
|
> — [Claudio Matsuoka][]
|
||||||
|
|
||||||
|
Finit is a process starter and [supervisor][1] designed to run as PID 1
|
||||||
|
on Linux systems. It consists of a set of [plugins](plugins.md) and can
|
||||||
|
be set up using [configuration files](config/files.md). Plugins start
|
||||||
|
at [hook points](plugins.md#hooks) and can run various set up tasks
|
||||||
|
and/or install event handlers that later provide runtime services, e.g.,
|
||||||
|
PID file monitoring, or [conditions](conditions.md).
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
* [Runlevels](config/runlevels.md), defined per service
|
||||||
|
* [One-shot tasks](config/task-and-run.md), [services](config/services.md) (daemons), or [SysV init][4] start/stop scripts
|
||||||
|
* [Runparts](config/runparts.md) and `/etc/rc.local` support
|
||||||
|
* Process supervision similar to [systemd][]
|
||||||
|
* Fine-grained privilege control:
|
||||||
|
- [Linux capabilities](config/capabilities.md) for minimal required privileges
|
||||||
|
- [Supplementary groups](config/services.md#non-privileged-services) for multi-group resource access
|
||||||
|
* [Sourcing environment files](config/service-env.md)
|
||||||
|
* [Conditions](conditions.md) for network/process/custom dependencies
|
||||||
|
* [Readiness notification](config/service-sync.md); PID files (native) for synchronizing system
|
||||||
|
startup, support for systemd [sd_notify()][], or [s6 style][] too
|
||||||
|
* Limited support for [tmpfiles.d(5)][] (no aging, attributes, or subvolumes)
|
||||||
|
* [Pre/Post script actions](config/service-wrappers.md)
|
||||||
|
* Rudimentary [templating support](config/templating.md)
|
||||||
|
* [Tooling](initctl.md) to enable/disable services
|
||||||
|
* [Automatic reload](features.md#automatic-reload) of modified configuration files (optional)
|
||||||
|
* [Built-in getty](config/tty.md)
|
||||||
|
* Built-in watchdog, with support for hand-over to [watchdogd][]
|
||||||
|
* Built-in support for Debian/BusyBox [`/etc/network/interfaces`][3]
|
||||||
|
* [Cgroups v2](config/cgroups.md), both configuration and monitoring in [`initctl top`](initctl.md)
|
||||||
|
* [Plugin support](plugins.md) for customization
|
||||||
|
* Proper [rescue mode](config/rescue.md) with bundled `sulogin` for protected maintenance shell
|
||||||
|
* [Switch root](switchroot.md) support for initramfs-to-real-root transitions
|
||||||
|
* Integration with [watchdogd][] for full system supervision
|
||||||
|
* [Logging](config/logging.md) to kernel ring buffer before `syslogd` has started, see the
|
||||||
|
recommended [sysklogd][] project for complete logging integration
|
||||||
|
and how to log to the kernel ring buffer from scripts using `logger`
|
||||||
|
|
||||||
|
For a more thorough overview, see the [Features](features.md) section.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> See [SysV Init Compatibility](config/sysv.md) for help to
|
||||||
|
> quickly get going with an existing SysV or BusyBox init setup.
|
||||||
|
|
||||||
|
|
||||||
|
Origin
|
||||||
|
------
|
||||||
|
|
||||||
|
This project is based on the [original finit][] by [Claudio Matsuoka][]
|
||||||
|
which was reverse engineered from syscalls of the [EeePC fastinit][].
|
||||||
|
|
||||||
|
Finit is developed and maintained by [Joachim Wiberg][] at [GitHub][6].
|
||||||
|
Please file bug reports, clone it, or send pull requests for bug fixes
|
||||||
|
and proposed extensions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[1]: https://en.wikipedia.org/wiki/Process_supervision
|
||||||
|
[3]: https://manpages.debian.org/unstable/ifupdown2/interfaces.5.en.html
|
||||||
|
[4]: https://en.wikipedia.org/wiki/Init
|
||||||
|
[5]: https://en.wikipedia.org/wiki/Runlevel
|
||||||
|
[6]: https://github.com/finit-project/finit
|
||||||
|
[dinit]: https://davmac.org/projects/dinit/
|
||||||
|
[systemd]: https://www.freedesktop.org/wiki/Software/systemd/
|
||||||
|
[sd_notify()]: https://www.freedesktop.org/software/systemd/man/sd_notify.html
|
||||||
|
[s6 style]: https://skarnet.org/software/s6/notifywhenup.html
|
||||||
|
[tmpfiles.d(5)]: https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html
|
||||||
|
[EeePC fastinit]: https://web.archive.org/web/20071208212450/http://wiki.eeeuser.com/boot_process:the_boot_process
|
||||||
|
[original finit]: http://helllabs.org/finit/
|
||||||
|
[Claudio Matsuoka]: https://github.com/cmatsuoka
|
||||||
|
[Joachim Wiberg]: https://troglobit.com
|
||||||
|
[watchdogd]: https://troglobit.com/watchdogd.html
|
||||||
|
[sysklogd]: https://github.com/troglobit/sysklogd/
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
Commands & Status
|
||||||
|
=================
|
||||||
|
|
||||||
|
Finit also implements a modern API to query status, and start/stop
|
||||||
|
services, called `initctl`. Unlike `telinit` the `initctl` tool does
|
||||||
|
not return until the given command has fully completed.
|
||||||
|
|
||||||
|
```
|
||||||
|
Usage: initctl [OPTIONS] [COMMAND]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-b, --batch Batch mode, no screen size probing
|
||||||
|
-c, --create Create missing paths (and files) as needed
|
||||||
|
-f, --force Ignore missing files and arguments, never prompt
|
||||||
|
-h, --help This help text
|
||||||
|
-j, --json JSON output in 'status' and 'cond' commands
|
||||||
|
-1, --once Only one lap in commands like 'top'
|
||||||
|
-p, --plain Use plain table headings, no ctrl chars
|
||||||
|
-q, --quiet Silent, only return status of command
|
||||||
|
-t, --no-heading Skip table headings
|
||||||
|
-v, --verbose Verbose output
|
||||||
|
-V, --version Show program version
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
debug Toggle Finit (daemon) debug
|
||||||
|
help This help text
|
||||||
|
version Show program version
|
||||||
|
|
||||||
|
ls | list List all .conf in /etc/finit.d
|
||||||
|
create <CONF> Create .conf in /etc/finit.d/available
|
||||||
|
delete <CONF> Delete .conf in /etc/finit.d/available
|
||||||
|
show <CONF> Show .conf in /etc/finit.d/available
|
||||||
|
edit <CONF> Edit .conf in /etc/finit.d/available
|
||||||
|
touch <CONF> Change .conf in /etc/finit.d/available
|
||||||
|
enable <CONF> Enable .conf in /etc/finit.d/available
|
||||||
|
disable <CONF> Disable .conf in /etc/finit.d/enabled
|
||||||
|
reload Reload *.conf in /etc/finit.d (activate changes)
|
||||||
|
|
||||||
|
cond set <COND> Set (assert) user-defined conditions +usr/COND
|
||||||
|
cond get <COND> Get status of user-defined condition, see $? and -v
|
||||||
|
cond clear <COND> Clear (deassert) user-defined conditions -usr/COND
|
||||||
|
cond status Show condition status, default cond command
|
||||||
|
cond dump [TYPE] Dump all, or a type of, conditions and their status
|
||||||
|
|
||||||
|
log [NAME] Show ten last Finit, or NAME, messages from syslog
|
||||||
|
start <NAME>[:ID] Start service by name, with optional ID
|
||||||
|
stop <NAME>[:ID] Stop/Pause a running service by name
|
||||||
|
reload <NAME>[:ID] Reload service as if .conf changed (SIGHUP or restart)
|
||||||
|
This allows restart of run/tasks that have already run
|
||||||
|
Note: Finit .conf file(s) are *not* reloaded!
|
||||||
|
restart <NAME>[:ID] Restart (stop/start) service by name
|
||||||
|
kill <NAME>[:ID] <S> Send signal S to service by name, with optional ID
|
||||||
|
ident [NAME] Show matching identities for NAME, or all
|
||||||
|
status <NAME>[:ID] Show service status, by name
|
||||||
|
status Show status of services, default command
|
||||||
|
|
||||||
|
cgroup List cgroup config overview
|
||||||
|
ps List processes based on cgroups
|
||||||
|
top Show top-like listing based on cgroups
|
||||||
|
|
||||||
|
plugins List installed plugins
|
||||||
|
|
||||||
|
runlevel [0-9] Show or set runlevel: 0 halt, 6 reboot
|
||||||
|
reboot Reboot system
|
||||||
|
halt Halt system
|
||||||
|
poweroff Halt and power off system
|
||||||
|
suspend Suspend system
|
||||||
|
switch-root NEWROOT [INIT] Switch to new root filesystem (initramfs only)
|
||||||
|
|
||||||
|
utmp show Raw dump of UTMP/WTMP db
|
||||||
|
```
|
||||||
|
|
||||||
|
For services *not* supporting `SIGHUP` the `<!>` notation in the .conf
|
||||||
|
file must be used to tell Finit to stop and start it on `reload` and
|
||||||
|
`runlevel` changes. If `<>` holds more [conditions](conditions.md),
|
||||||
|
these will also affect how a service is maintained.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Even though it is possible to start services not belonging in the
|
||||||
|
> current runlevel these services will not be respawned automatically by
|
||||||
|
> Finit if they exit (crash). Hence, if the runlevel is 2, the below
|
||||||
|
> Dropbear SSH service will not be restarted if it is killed or exits.
|
||||||
|
|
||||||
|
The `status` command is the default, it displays a quick overview of all
|
||||||
|
monitored run/task/services. Here we call `initctl -p`, suitable for
|
||||||
|
scripting and documentation:
|
||||||
|
|
||||||
|
```
|
||||||
|
alpine:~# initctl -p
|
||||||
|
PID IDENT STATUS RUNLEVELS DESCRIPTION
|
||||||
|
======================================================================
|
||||||
|
1506 acpid running [---2345----] ACPI daemon
|
||||||
|
1509 crond running [---2345----] Cron daemon
|
||||||
|
1489 dropbear running [---2345----] Dropbear SSH daemon
|
||||||
|
1511 klogd running [S-12345----] Kernel log daemon
|
||||||
|
1512 ntpd running [---2345----] NTP daemon
|
||||||
|
1473 syslogd running [S-12345----] Syslog daemon
|
||||||
|
|
||||||
|
alpine:~# initctl -pv
|
||||||
|
PID IDENT STATUS RUNLEVELS COMMAND
|
||||||
|
======================================================================
|
||||||
|
1506 acpid running [---2345----] acpid -f
|
||||||
|
1509 crond running [---2345----] crond -f -S $CRON_OPTS
|
||||||
|
1489 dropbear running [---2345----] dropbear -R -F $DROPBEAR_OPTS
|
||||||
|
1511 klogd running [S-12345----] klogd -n $KLOGD_OPTS
|
||||||
|
1512 ntpd running [---2345----] ntpd -n $NTPD_OPTS
|
||||||
|
1473 syslogd running [S-12345----] syslogd -n
|
||||||
|
```
|
||||||
|
|
||||||
|
The environment variables to each of the services above are read from,
|
||||||
|
in the case of Alpine Linux, `/etc/conf.d/`. Other distributions may
|
||||||
|
have other directories, e.g., Debian use `/etc/default/`.
|
||||||
|
|
||||||
|
The `status` command takes an optional `NAME:ID` argument. Here we
|
||||||
|
check the status of `dropbear`, which only has one instance in this
|
||||||
|
system:
|
||||||
|
|
||||||
|
```
|
||||||
|
alpine:~# initctl -p status dropbear
|
||||||
|
Status : running
|
||||||
|
Identity : dropbear
|
||||||
|
Description : Dropbear SSH daemon
|
||||||
|
Origin : /etc/finit.d/enabled/dropbear.conf
|
||||||
|
Environment : -/etc/conf.d/dropbear
|
||||||
|
Condition(s):
|
||||||
|
Command : dropbear -R -F $DROPBEAR_OPTS
|
||||||
|
PID file : !/run/dropbear.pid
|
||||||
|
PID : 1485
|
||||||
|
User : root
|
||||||
|
Group : root
|
||||||
|
Uptime : 2 hour 46 min 56 sec
|
||||||
|
Runlevels : [---2345----]
|
||||||
|
Memory : 1.2M
|
||||||
|
CGroup : /system/dropbear cpu 0 [100, max] mem [--.--, max]
|
||||||
|
|- 1485 dropbear -R -F
|
||||||
|
|- 2634 dropbear -R -F
|
||||||
|
|- 2635 ash
|
||||||
|
`- 2652 initctl -p status dropbear
|
||||||
|
|
||||||
|
Apr 8 12:19:49 alpine authpriv.info dropbear[1485]: Not backgrounding
|
||||||
|
Apr 8 12:37:45 alpine authpriv.info dropbear[2300]: Child connection from 192.168.121.1:47834
|
||||||
|
Apr 8 12:37:46 alpine authpriv.notice dropbear[2300]: Password auth succeeded for 'root' from 192.168.121.1:47834
|
||||||
|
Apr 8 12:37:46 alpine authpriv.info dropbear[2300]: Exit (root) from <192.168.121.1:47834>: Disconnect received
|
||||||
|
Apr 8 15:02:11 alpine authpriv.info dropbear[2634]: Child connection from 192.168.121.1:48576
|
||||||
|
Apr 8 15:02:12 alpine authpriv.notice dropbear[2634]: Password auth succeeded for 'root' from 192.168.121.1:48576
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Switch Root
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The `switch-root` command is used when running Finit in an initramfs to
|
||||||
|
transition to the real root filesystem. This is similar to the standalone
|
||||||
|
`switch_root(8)` utility but integrated into Finit.
|
||||||
|
|
||||||
|
```
|
||||||
|
initctl switch-root /mnt/root [/sbin/init]
|
||||||
|
```
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
- Must be run during runlevel S (bootstrap) or runlevel 1
|
||||||
|
- The new root must be a mount point (different device than /)
|
||||||
|
- Can only be used when Finit is running as PID 1 in an initramfs
|
||||||
|
|
||||||
|
For complete documentation and usage examples, see the dedicated
|
||||||
|
[Switch Root](switchroot.md) section.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
keventd
|
||||||
|
=======
|
||||||
|
|
||||||
|
The kernel event daemon bundled with Finit is a simple uevent monitor
|
||||||
|
for `/sys/class/power_supply`. It provides the `sys/pwr/ac` condition,
|
||||||
|
which can be useful to prevent power hungry services like anacron to run
|
||||||
|
when a laptop is only running on battery, for instance.
|
||||||
|
|
||||||
|
Since keventd is not an integral part of Finit yet it is not enabled by
|
||||||
|
default. Enable it using `./configure --with-keventd`. The bundled
|
||||||
|
`contrib/` build scripts for Debian, Alpine, and Void have this enabled.
|
||||||
|
|
||||||
|
This daemon is planned to be extended with monitoring of other uevents,
|
||||||
|
patches and ideas are welcome in the issue tracker.
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
Hooks & Plugins
|
Hooks & Plugins
|
||||||
===============
|
===============
|
||||||
|
|
||||||
* [Plugins](#plugins)
|
|
||||||
* [Hooks](#hooks)
|
|
||||||
* [Bootstrap Hooks](#bootstrap-hooks)
|
|
||||||
* [Runtime Hooks](#runtime-hooks)
|
|
||||||
* [Shutdown Hooks](#shutdown-hooks)
|
|
||||||
|
|
||||||
Finit can be extended to add general functionality in the form of I/O
|
Finit can be extended to add general functionality in the form of I/O
|
||||||
monitors, or hook plugins.
|
monitors, or hook plugins. It is even possible to run scripts at these
|
||||||
|
hook points, see below.
|
||||||
|
|
||||||
The following sections detail existing plugins and hook points. For
|
The following sections detail existing plugins and hook points. For
|
||||||
more information, see the plugins listed below.
|
more information, see the plugins listed below.
|
||||||
@@ -27,21 +22,45 @@ For your convenience a set of *optional* plugins are available:
|
|||||||
system and runs at `HOOK_BASEFS_UP`. The `/var`, `/run`, and `/dev`
|
system and runs at `HOOK_BASEFS_UP`. The `/var`, `/run`, and `/dev`
|
||||||
file systems must be writable for this plugin to work.
|
file systems must be writable for this plugin to work.
|
||||||
|
|
||||||
Note: On an embedded system both `/var` and `/run` can be `tmpfs` RAM
|
This plugin is a wrapper for the [tmpfiles.d(5)][] implementation that
|
||||||
disks and `/dev` is usually a `devtmpfs`. This must be defined in the
|
Finit has. Capable but limited: no aging, attributes, or subvolumes.
|
||||||
`/etc/fstab` file and in the Linux kernel config.
|
|
||||||
|
By default, `/lib/finit/tmpfiles.d` carries all the default .conf
|
||||||
|
files distributed with Finit. It is read first but can be overridden
|
||||||
|
by any of the standard tmpfiles.d directories, e.g. `/etc/tmpfiles.d`.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> On an embedded system both `/var` and `/run` can be `tmpfs` RAM
|
||||||
|
> disks and `/dev` is usually a `devtmpfs`. This must be defined in
|
||||||
|
> the `/etc/fstab` file and in the Linux kernel config.
|
||||||
|
|
||||||
* *dbus.so*: Setup and start system message bus, D-Bus, at boot.
|
* *dbus.so*: Setup and start system message bus, D-Bus, at boot.
|
||||||
_Optional plugin._
|
_Optional plugin._
|
||||||
|
|
||||||
* *hook-scripts.so*: Trigger the execution of scripts from plugin hook
|
* *hook-scripts.so*: Trigger the execution of scripts from plugin hook
|
||||||
points (see [Hooks](#hooks)). Scripts are located in
|
points (see [Hooks](#hooks)). _Optional plugin._
|
||||||
`/libexec/finit/hook` by default, this can be build-time customized
|
|
||||||
by using the `--with-hook-scripts-path=PATH` argument to
|
|
||||||
`configure`. _Optional plugin._
|
|
||||||
|
|
||||||
* *hotplug.so*: Setup and start either udev or mdev hotplug daemon, if
|
This plugin is particularly useful for early boot debugging that needs
|
||||||
available. Enabled by default.
|
to take place before regular services are available.
|
||||||
|
|
||||||
|
For example, say that you want to enable some kernel tracing before
|
||||||
|
modules are loaded. With hook scripts, you can just drop in a shell
|
||||||
|
script in `/libexec/finit/hook/mount/all/` that will poke the right
|
||||||
|
control files in tracefs.
|
||||||
|
|
||||||
|
Scripts are located in `/libexec/finit/hook` by default, this can be
|
||||||
|
customized at build-time using the `--with-hook-scripts-path=PATH`
|
||||||
|
argument to `configure`.
|
||||||
|
|
||||||
|
* *hotplug.so*: Replaced with `/lib/finit/system/10-hotplug.conf`, which
|
||||||
|
checks for `udevd` and `mdev` at boot. This file can be overridden by a
|
||||||
|
file in `/etc/finit.d/10-hotplug.conf`.
|
||||||
|
|
||||||
|
Enabled by default.
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> See the [Services](config/services.md) section in the configuration
|
||||||
|
> guide for an example how to run `mdevd`, alternative to plain mdev.
|
||||||
|
|
||||||
* *rtc.so*: Restore and save system clock from/to RTC on boot/halt.
|
* *rtc.so*: Restore and save system clock from/to RTC on boot/halt.
|
||||||
Enabled by default.
|
Enabled by default.
|
||||||
@@ -49,20 +68,34 @@ For your convenience a set of *optional* plugins are available:
|
|||||||
* *modules-load.so*: Scans `/etc/modules-load.d/*.conf` for modules to
|
* *modules-load.so*: Scans `/etc/modules-load.d/*.conf` for modules to
|
||||||
load using `modprobe`. Each file can contain multiple lines with the
|
load using `modprobe`. Each file can contain multiple lines with the
|
||||||
name of the module to load. Any line starting with the standard UNIX
|
name of the module to load. Any line starting with the standard UNIX
|
||||||
comment character, `#`, is skipped.
|
comment character, `#`, or `;`, is skipped.
|
||||||
|
|
||||||
Modules are loaded when entering runlevel `[2345]` using the `task`
|
Modules are by default loaded in runlevel `S` using the `task` stanza.
|
||||||
stanza. Each module gets a unique `name:modprobe.foo`, and
|
Each module gets a unique `name:modprobe.foo`, and optional`:ID`. The
|
||||||
optional`:ID`. The `:ID` is a globally incremented index, which can
|
runlevel can be changed per file using:
|
||||||
be disabled per file (anywhere) using the following config line:
|
|
||||||
|
set runlevel 2345
|
||||||
|
|
||||||
|
The `:ID` is a globally incremented index, which can be disabled per
|
||||||
|
file (anywhere) using the following config line:
|
||||||
|
|
||||||
set noindex
|
set noindex
|
||||||
|
|
||||||
**Note:** unlike the traditional .conf `module` directive, which load
|
To change the index used by the plugin:
|
||||||
any listed module immediately, this plugin creates standard `taks`
|
|
||||||
directives which load the module(s) in the background. As long as
|
set index 1234
|
||||||
the `modprobe` program is found in the path, these tasks will always
|
|
||||||
return `[ OK ]` at boot. Check the actual status using `initctl`.
|
Since these tasks run in the background, they return `[ OK ]` at boot,
|
||||||
|
unless the modprobe tool does not exist. Check syslog for warnings
|
||||||
|
and the actual status of the operation using `initctl`.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> Unlike the traditional .conf `module` directive, which load any listed
|
||||||
|
> module immediately, this plugin creates a background `task` which load
|
||||||
|
> the module(s) in the background. The program is modprobe,
|
||||||
|
> `/sbin/modprobe`, which you can override per .conf file:
|
||||||
|
>
|
||||||
|
> set modprobe /path/to/maybe-a-modprobe-wrapper
|
||||||
|
|
||||||
* *netlink.so*: Listens to Linux kernel Netlink events for gateway and
|
* *netlink.so*: Listens to Linux kernel Netlink events for gateway and
|
||||||
interfaces. These events are then sent to the Finit service monitor
|
interfaces. These events are then sent to the Finit service monitor
|
||||||
@@ -91,45 +124,117 @@ state, etc. Available hook points are:
|
|||||||
Hooks
|
Hooks
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
In the below listings, the first label is the hook point for a C plugin,
|
||||||
|
the second is the condition name and hook script path. A hook script is
|
||||||
|
a plain shell script, or program, that does a very small dedicated job
|
||||||
|
at the below hook points.
|
||||||
|
|
||||||
|
See [Run-parts Scripts](config/runparts.md) for details on the
|
||||||
|
requirements, possibilities, and *limitations* of hook scripts.
|
||||||
|
|
||||||
|
All hook scripts are called with at least one environment variable set,
|
||||||
|
the hook name, useful when reusing the same hook script for multiple
|
||||||
|
hook points:
|
||||||
|
|
||||||
|
- `FINIT_HOOK_NAME`: set to the second label, e.g., `hook/net/up`
|
||||||
|
- `FINIT_SHUTDOWN`: set for `hook/sys/shutdown` and later to one
|
||||||
|
of `halt`, `poweroff`, or `reboot`.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
$ mkdir -p /libexec/finit/hook/sys/down
|
||||||
|
$ cat <<EOF >/libexec/finit/hook/sys/down/foo.sh
|
||||||
|
#!/bin/sh
|
||||||
|
echo 'I run just before the reboot() syscall at shutdown/reboot'
|
||||||
|
echo 'I have access to /dev since devtmpfs is exempt from umount'
|
||||||
|
echo "FINIT_HOOK_NAME: $FINIT_HOOK_NAME"
|
||||||
|
if [ -n "$FINIT_SHUTDOWN" ]; then
|
||||||
|
echo "FINIT_SHUTDOWN: $FINIT_SHUTDOWN"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
EOF
|
||||||
|
$ chmod +x /libexec/finit/hook/sys/down/foo.sh
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> To use hook scripts, even for pre-bootstrap and pre-shutdown tasks,
|
||||||
|
> you must build with `configure --enable-hook-scripts-plugin`.
|
||||||
|
|
||||||
|
|
||||||
### Bootstrap Hooks
|
### Bootstrap Hooks
|
||||||
|
|
||||||
* `HOOK_BANNER`: The very first point at which a plugin can run.
|
* `HOOK_BANNER`, `hook/sys/banner`: The very first point at which a
|
||||||
Intended to be used as a banner replacement. Essentially this runs
|
plugin can run. Intended to be used as a banner replacement.
|
||||||
just before entering runlevel S. Assume nothing is available, so
|
Essentially this runs just before entering runlevel S. Assume nothing
|
||||||
be prepared to use absolute paths, etc.
|
is available, so be prepared to use absolute paths, etc.
|
||||||
|
|
||||||
* `HOOK_ROOTFS_UP`: When `finit.conf` has been read and `/` has is
|
* `HOOK_ROOTFS_UP`, `hook/mount/root`: When `finit.conf` has been read
|
||||||
mounted — very early
|
and `/` has is mounted — very early
|
||||||
|
|
||||||
* `HOOK_BASEFS_UP`: All of `/etc/fstab` is mounted, swap is available
|
* `HOOK_MOUNT_ERROR`, `hook/mount/error`: executed if `mount -a` fails
|
||||||
and default init signals are setup
|
|
||||||
|
|
||||||
* `HOOK_NETWORK_UP`: System bootstrap, runlevel S, has completed and
|
* `HOOK_MOUNT_POST`, `hook/mount/post`: always executed after `mount -a`
|
||||||
networking is up (`lo` is up and the `network` script has run)
|
|
||||||
|
|
||||||
* `HOOK_SVC_UP`: All services in the active runlevel has been launched
|
* `HOOK_BASEFS_UP`, `hook/mount/all`: All of `/etc/fstab` is mounted,
|
||||||
|
swap is available and default init signals are setup
|
||||||
|
|
||||||
* `HOOK_SYSTEM_UP`: All services *and* everything in `/etc/finit.d`
|
* `HOOK_SVC_PLUGIN`, `hook/svc/plugin`: Called in `conf_init()` right
|
||||||
has been launched
|
before loading `/etc/finit.conf`. For plugins to register any early
|
||||||
|
run/task/services, please do NOT use any earlier hook point. That
|
||||||
|
will cause uninitialized rlimits that lead to unpredictable results
|
||||||
|
when Finit later tries to start the run/task/service.
|
||||||
|
|
||||||
|
* `HOOK_NETWORK_UP`, `hook/net/up`: System bootstrap, runlevel S, has
|
||||||
|
completed and networking is up (`lo` is up and the `network` script
|
||||||
|
has run)
|
||||||
|
|
||||||
|
* `HOOK_SVC_UP`, `hook/svc/up`: All services in the active runlevel have
|
||||||
|
been launched
|
||||||
|
|
||||||
|
* `HOOK_SYSTEM_UP`, `hook/sys/up`: All services *and* everything in
|
||||||
|
`/etc/finit.d` has been launched
|
||||||
|
|
||||||
### Runtime Hooks
|
### Runtime Hooks
|
||||||
|
|
||||||
* `HOOK_SVC_RECONF`: Called when the user has changed something in the
|
* `HOOK_SVC_RECONF`, N/A: Called when the user has changed something in
|
||||||
`/etc/finit.d` directory and issued `SIGHUP`. The hook is called when
|
the `/etc/finit.d` directory and issued `SIGHUP`. The hook is called
|
||||||
all modified/removed services have been stopped. When the hook has
|
when all modified/removed services have been stopped. When the hook
|
||||||
completed, Finit continues to start all modified and new services.
|
has completed, Finit continues to start all modified and new services.
|
||||||
|
|
||||||
* `HOOK_RUNLEVEL_CHANGE`: Called when the user has issued a runlevel
|
* `HOOK_RUNLEVEL_CHANGE`, N/A: Called when the user has issued a
|
||||||
change. The hook is called when services not matching the new
|
runlevel change. The hook is called when services not matching the
|
||||||
runlevel have been been stopped. When the hook has completed, Finit
|
new runlevel have been been stopped. When the hook has completed,
|
||||||
continues to start all services in the new runlevel.
|
Finit continues to start all services in the new runlevel.
|
||||||
|
|
||||||
|
### Switch Root Hooks
|
||||||
|
|
||||||
|
* `HOOK_SWITCH_ROOT`, `hook/sys/switchroot`: Called when
|
||||||
|
`initctl switch-root` is issued, before the transition begins. Use
|
||||||
|
this hook to save state, unmount initramfs-only filesystems, or perform
|
||||||
|
cleanup before switching to the new root. Only runs when Finit is
|
||||||
|
operating as PID 1 in an initramfs.
|
||||||
|
|
||||||
|
See the [Switch Root](switchroot.md) section for more information.
|
||||||
|
|
||||||
### Shutdown Hooks
|
### Shutdown Hooks
|
||||||
|
|
||||||
* `HOOK_SHUTDOWN`: Called at shutdown/reboot, right before all
|
* `HOOK_NETWORK_DN`, `hook/net/down`: Called right after having changed
|
||||||
services are sent `SIGTERM`
|
to runlevel 6, or 0, when all services have received their 'stop' signal.
|
||||||
|
|
||||||
|
* `HOOK_SHUTDOWN`, `hook/sys/shutdown`: Called at shutdown/reboot, right
|
||||||
|
before all services are sent `SIGTERM`
|
||||||
|
|
||||||
|
* `HOOK_SVC_DN`, `hook/svc/down`: In shutdown/reboot, all services and
|
||||||
|
non-reserved processes have been killed. **Note:** only hook scripts
|
||||||
|
can run here!
|
||||||
|
|
||||||
|
* `HOOK_SYSTEM_DN`, `hook/sys/down`: In shutdown/reboot, called after
|
||||||
|
all non-reserved file systems have been unmounted, just before Finit
|
||||||
|
tells the kernel to reboot or shut down. **Note:** only hook scripts
|
||||||
|
can run here!
|
||||||
|
|
||||||
Plugins like `tty.so` extend finit by acting on events, they are called
|
Plugins like `tty.so` extend finit by acting on events, they are called
|
||||||
I/O plugins and are called from the finit main loop when `poll()`
|
I/O plugins and are called from the finit main loop when `poll()`
|
||||||
detects an event. See the source code for `plugins/*.c` for more help
|
detects an event. See the source code for `plugins/*.c` for more help
|
||||||
and ideas.
|
and ideas.
|
||||||
|
|
||||||
|
[tmpfiles.d(5)]: https://www.freedesktop.org/software/systemd/man/tmpfiles.d.html
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
Requirements
|
||||||
|
============
|
||||||
|
|
||||||
|
Finit is capable of running on both desktop/server systems with udev and
|
||||||
|
embedded systems that usually come with BusyBox mdev. Some systems have
|
||||||
|
systemd-udev or eudev today instead of the original udev, Finit probes
|
||||||
|
for all of them at runtime and expects `/dev/` to be a writable file
|
||||||
|
system using `devtmpfs`. It is also possible to run on a statically set
|
||||||
|
up `/dev` if needed. It is however not a good idea to have both udev
|
||||||
|
and mdev installed at the same time, this will lead to unpredictable
|
||||||
|
results.
|
||||||
|
|
||||||
|
At boot Finit calls either `mdev` or `udevd` to populate `/dev`, this is
|
||||||
|
done slightly differently and on systems with udev you might want to add
|
||||||
|
the following one-shot task early in your `/etc/finit.conf`:
|
||||||
|
|
||||||
|
```conf
|
||||||
|
run [S] udevadm settle --timeout=120 -- Waiting for udev
|
||||||
|
```
|
||||||
|
|
||||||
|
Finit has a built-in Getty for TTYs, but requires a working `/bin/login`
|
||||||
|
or `/bin/sh`, if no TTYs are configured in `/etc/finit.conf`.
|
||||||
|
|
||||||
|
For a fully operational system `/var`, `/run` and `/tmp` must be set up
|
||||||
|
properly in `/etc/fstab` -- which is iterated over at boot.
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
Runlevel Support
|
||||||
|
================
|
||||||
|
|
||||||
|
Basic support for [runlevels][5] is included in Finit from v1.8. By
|
||||||
|
default all services, tasks, run commands and TTYs listed without a set
|
||||||
|
of runlevels get a default set `[234]` assigned. The default runlevel
|
||||||
|
after boot is 2.
|
||||||
|
|
||||||
|
Finit supports runlevels 0-9, and S, with 0 reserved for halt, 6 reboot
|
||||||
|
and S for services that only run at bootstrap. Runlevel 1 is the single
|
||||||
|
user level, where usually no networking is enabled. In Finit this is
|
||||||
|
more of a policy for the user to define. Normally only runlevels 1-6
|
||||||
|
are used, and even more commonly, only the default runlevel is used.
|
||||||
|
|
||||||
|
To specify an allowed set of runlevels for a `service`, `run` command,
|
||||||
|
`task`, or `tty`, add `[NNN]` to your `/etc/finit.conf`, like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
service [S12345] syslogd -n -x -- System log daemon
|
||||||
|
run [S] /etc/init.d/acpid start -- Starting ACPI Daemon
|
||||||
|
task [S] /etc/init.d/kbd start -- Preparing console
|
||||||
|
service [S12345] <pid/syslogd> klogd -n -x -- Kernel log daemon
|
||||||
|
|
||||||
|
tty [12345] /dev/tty1
|
||||||
|
tty [2] /dev/tty2
|
||||||
|
tty [2] /dev/tty3
|
||||||
|
tty [2] /dev/tty4
|
||||||
|
tty [2] /dev/tty5
|
||||||
|
tty [2] /dev/tty6
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example syslogd is first started, in parallel, and then acpid is
|
||||||
|
called using a conventional SysV init script. It is called with the run
|
||||||
|
command, meaning the following task command to start the kbd script is
|
||||||
|
not called until the acpid init script has fully completed. Then the
|
||||||
|
keyboard setup script is called in parallel with klogd as a monitored
|
||||||
|
service.
|
||||||
|
|
||||||
|
Again, tasks and services are started in parallel, while run commands
|
||||||
|
are called in the order listed and subsequent commands are not started
|
||||||
|
until a run command has completed. Also, task and run commands are run
|
||||||
|
in a shell, so pipes and redirects can be used.
|
||||||
|
|
||||||
|
The following examples illustrate this. Bootstrap task and run commands
|
||||||
|
are also removed when they have completed, `initctl show` will not list
|
||||||
|
them.
|
||||||
|
|
||||||
|
```
|
||||||
|
task [S] echo "foo" | cat >/tmp/bar
|
||||||
|
run [S] echo "$HOME" >/tmp/secret
|
||||||
|
```
|
||||||
|
|
||||||
|
Switching between runlevels can be done by calling init with a single
|
||||||
|
argument, e.g. <kbd>init 5</kbd>, or using `initctl runlevel 5`, both
|
||||||
|
switch to runlevel 5. When changing runlevels Finit also automatically
|
||||||
|
reloads all `.conf` files in the `/etc/finit.d/` directory. So if you
|
||||||
|
want to set a new system config, switch to runlevel 1, change all config
|
||||||
|
files in the system, and touch all `.conf` files in `/etc/finit.d`
|
||||||
|
before switching back to the previous runlevel again — that way Finit
|
||||||
|
can both stop old services and start any new ones for you, without
|
||||||
|
rebooting the system.
|
||||||
|
|
||||||
|
|
||||||
|
[5]: https://en.wikipedia.org/wiki/Runlevel
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
Runparts & `/etc/rc.local`
|
||||||
|
==========================
|
||||||
|
|
||||||
|
At the end of the boot, when all bootstrap (`S`) tasks and services have
|
||||||
|
started, but not networking, Finit calls its built-in [run-parts(8)][]
|
||||||
|
command on any configured `runparts <DIR>` directory. This happens just
|
||||||
|
before changing to the configured runlevel (default 2). (Networking is
|
||||||
|
enabled just prior to changing from single user mode.)
|
||||||
|
|
||||||
|
```shell
|
||||||
|
runparts /etc/rc.d/
|
||||||
|
```
|
||||||
|
|
||||||
|
Right after the runlevel change when all services have started properly,
|
||||||
|
`/etc/rc.local` is called.
|
||||||
|
|
||||||
|
No configuration stanza in `/etc/finit.conf` is required for `rc.local`.
|
||||||
|
If it exists and is an executable shell script Finit calls it at the very
|
||||||
|
end of the boot, before calling the `HOOK_SYSTEM_UP`. See more in the
|
||||||
|
[Hook Scripts](plugins.md#hooks) section.
|
||||||
|
|
||||||
|
|
||||||
|
### Limitations
|
||||||
|
|
||||||
|
It is not possible to call Finit via signals or use `initctl` in any
|
||||||
|
runparts or `/etc/rc.local` script. This because Finit is single
|
||||||
|
threaded and is calling these scripts in a blocking fashion at the end
|
||||||
|
of runlevel S, at which point the event loop has not yet been started.
|
||||||
|
|
||||||
|
The event loop is the whole thing which Finit is built around, except
|
||||||
|
for runlevel S, which remains a slow procession through a lot of set up,
|
||||||
|
with a few hooks and blocking call outs to external scripts.
|
||||||
|
|
||||||
|
However, not all `initctl` commands are prohibited. Supported commands:
|
||||||
|
|
||||||
|
- `initctl cond`: only operate on files in `/run/finit/cond`
|
||||||
|
- `initctl enable/disable`: enabled run/task/service is activated on
|
||||||
|
the runlevel change from S to 2
|
||||||
|
- `initctl touch/show/create/delete/list`: `create`, provided the
|
||||||
|
non-interactive mode is used, again changes take effect in the
|
||||||
|
runlevel change directly after bootstrap
|
||||||
|
- `initctl -f reboot/poweroff/halt`: provided the `-f` flag is used to
|
||||||
|
force direct kernel commands
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> you can set a `usr/` condition in `/etc/rc.local` and have a
|
||||||
|
> service/task in runlevel 2 depend on it to execute.
|
||||||
|
|
||||||
|
[run-parts(8)]: https://manpages.debian.org/cgi-bin/man.cgi?query=run-parts
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
Finit Services
|
|
||||||
==============
|
|
||||||
|
|
||||||
Starting & Monitoring
|
Starting & Monitoring
|
||||||
---------------------
|
=====================
|
||||||
|
|
||||||
Finit can start and monitor the following types of daemons:
|
Finit can start and monitor the following types of daemons:
|
||||||
|
|
||||||
* Forks to background, creates a PID file
|
* Forks to background, creates a PID file
|
||||||
* Runs in foreground:
|
* Runs in foreground and signals ready by:
|
||||||
- creates a PID file
|
- creating a PID file
|
||||||
- does not create a PID file -- Finit can create it for you (optional)
|
- does not create a PID file -- Finit can create it for you (optional)
|
||||||
|
- [other mechanism][1] (systemd, s6)
|
||||||
|
|
||||||
Finit can *not* start and monitor a daemon that:
|
Finit can *not* start and monitor a daemon that:
|
||||||
|
|
||||||
@@ -22,10 +20,12 @@ Finit can *not* start and monitor a daemon that:
|
|||||||
| ✔ | No | No | Yes, optionally |
|
| ✔ | No | No | Yes, optionally |
|
||||||
| ✘ | Yes | No | No |
|
| ✘ | Yes | No | No |
|
||||||
|
|
||||||
> **Note:** PID files is one mechanism used to assert conditions to
|
> [!NOTE]
|
||||||
> synchronize the start and stop of other, dependent, services.
|
> PID files is one mechanism used to assert conditions to synchronize
|
||||||
|
> the start and stop of other, dependent, services. Other mechanisms
|
||||||
|
> are described in the [Service Synchronization][1] section.
|
||||||
|
|
||||||
### Forks to Background w/ PID File
|
### Forks to bg w/ PID file
|
||||||
|
|
||||||
There are two syntax variants, type 1 and type 2. The former is the
|
There are two syntax variants, type 1 and type 2. The former is the
|
||||||
traditional one used also for `sysv` start/stop scripts, and the latter
|
traditional one used also for `sysv` start/stop scripts, and the latter
|
||||||
@@ -39,49 +39,19 @@ In this example the resulting files to watch for are `/run/serv.pid` and
|
|||||||
`/var/run/serv.pid`, respectively. On most modern Linux systems this is
|
`/var/run/serv.pid`, respectively. On most modern Linux systems this is
|
||||||
the same directory (`/var/run` is a symlink to `../run`).
|
the same directory (`/var/run` is a symlink to `../run`).
|
||||||
|
|
||||||
### Runs in Foreground w/ PID File
|
### Runs in fg w/ PID file
|
||||||
|
|
||||||
service serv -n -p -- Foreground service w/ PID file
|
service serv -n -p -- Foreground service w/ PID file
|
||||||
|
|
||||||
### Runs in Foreground w/o PID File
|
### Runs in fg w/o PID file
|
||||||
|
|
||||||
Same as previous, but we tell Finit to create the PID file, because we
|
Same as previous, but we tell Finit to create the PID file, because we
|
||||||
need it to synchronize start/stop of a dependent service.
|
need it to synchronize start/stop of a dependent service.
|
||||||
|
|
||||||
service pid:/run/serv.pid serv -n -- Foreground service w/o PID file
|
service pid:/run/serv.pid serv -n -- Foreground service w/o PID file
|
||||||
|
|
||||||
### Runs in Foreground w/ Custom PID File
|
### Runs in fg w/ custom PID file
|
||||||
|
|
||||||
service pid:/run/servy.pid serv -n -p -P /run/servy.pid -- Foreground service w/ custom PID file
|
service pid:/run/servy.pid serv -n -p -P /run/servy.pid -- Foreground service w/ custom PID file
|
||||||
|
|
||||||
|
[1]: config/service-sync.md
|
||||||
State Machine
|
|
||||||
-------------
|
|
||||||
|
|
||||||
A service is bound to a state machine that is in one of six (6) states.
|
|
||||||
For `run`s and `task`s there is an additional end state called `DONE`,
|
|
||||||
not shown in the diagram for brevity. Services start in the `HALTED`
|
|
||||||
state.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
The current state depends on the two following conditions:
|
|
||||||
|
|
||||||
* `E`: Service enabled. In order for `E` to be satisfied, the service
|
|
||||||
must be allowed to run in the current runlevel and not be stopped.
|
|
||||||
|
|
||||||
A service may be stopped, or blocked, for several reasons:
|
|
||||||
|
|
||||||
- The user has manually stopped the service using `initctl stop NAME`
|
|
||||||
- The program exits immediately. I.e. keeps crashing (make sure to use
|
|
||||||
the 'run this service in the foreground' command line option)
|
|
||||||
- The binary is missing in the filesystem
|
|
||||||
|
|
||||||
* `C`: Service conditions are satisfied:
|
|
||||||
|
|
||||||
- `on` (+): The condition is asserted.
|
|
||||||
- `off` (-): The condition is deasserted.
|
|
||||||
- `flux` (~): The condition state is unknown.
|
|
||||||
|
|
||||||
For a detailed description of conditions, and how to debug them,
|
|
||||||
see the [Finit Conditions](conditions.md) document.
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
State Machine
|
||||||
|
=============
|
||||||
|
|
||||||
|
A service is bound to a state machine that is in one of ten states. For
|
||||||
|
run/tasks there is an additional end state called `DONE`. All processes
|
||||||
|
managed by Finit start in the `HALTED` state. The image shows how both
|
||||||
|
conditions and commands drive the machine.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The current state depends on the two following conditions:
|
||||||
|
|
||||||
|
* `E`: Service enabled. In order for `E` to be satisfied, the service
|
||||||
|
must be allowed to run in the current runlevel and not be stopped.
|
||||||
|
|
||||||
|
A service may be stopped, or blocked, for several reasons:
|
||||||
|
|
||||||
|
- The user has manually stopped the service using `initctl stop NAME`
|
||||||
|
- The program exits immediately. I.e. keeps crashing (make sure to use
|
||||||
|
the 'run this service in the foreground' command line option)
|
||||||
|
- The binary is missing in the filesystem
|
||||||
|
|
||||||
|
* `C`: Service conditions are satisfied:
|
||||||
|
|
||||||
|
- `on` (+): The condition is asserted.
|
||||||
|
- `off` (-): The condition is deasserted.
|
||||||
|
- `flux` (~): The condition state is unknown.
|
||||||
|
|
||||||
|
For a detailed description of conditions, and how to debug them,
|
||||||
|
see the [Finit Conditions](conditions.md) document.
|
||||||
|
Before Width: | Height: | Size: 138 KiB |
@@ -0,0 +1,149 @@
|
|||||||
|
Switch Root
|
||||||
|
===========
|
||||||
|
|
||||||
|
Finit supports switching from an initramfs to a real root filesystem
|
||||||
|
using the `initctl switch-root` command. This is useful for systems
|
||||||
|
that use an initramfs for early boot (LUKS, LVM, network boot, etc.)
|
||||||
|
and need to transition to the real root before starting services.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
```sh
|
||||||
|
initctl switch-root NEWROOT [INIT]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `NEWROOT`: Path to the mounted new root filesystem (e.g., `/mnt/root`)
|
||||||
|
- `INIT`: Optional path to init on the new root (default: `/sbin/init`)
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
1. Must be run during runlevel S (bootstrap) or runlevel 1
|
||||||
|
2. `NEWROOT` must be a mount point (different device than /)
|
||||||
|
3. `INIT` must exist and be executable on the new root
|
||||||
|
4. Finit must be running as PID 1 (in initramfs)
|
||||||
|
|
||||||
|
|
||||||
|
How It Works
|
||||||
|
------------
|
||||||
|
|
||||||
|
1. Runs `HOOK_SWITCH_ROOT` for any cleanup scripts/plugins
|
||||||
|
2. Runs `HOOK_SHUTDOWN` to notify plugins
|
||||||
|
3. Stops all services and kills remaining processes
|
||||||
|
4. Exits all plugins gracefully
|
||||||
|
5. Moves `/dev`, `/proc`, `/sys`, `/run` to new root
|
||||||
|
6. Deletes initramfs contents (if on tmpfs/ramfs) to free memory
|
||||||
|
7. Moves new root mount to `/`
|
||||||
|
8. Chroots to new root
|
||||||
|
9. Reopens `/dev/console` for stdin/stdout/stderr
|
||||||
|
10. Execs new init as PID 1
|
||||||
|
|
||||||
|
|
||||||
|
Example: Initramfs finit.conf
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Configuration file `/etc/finit.conf` in the initramfs:
|
||||||
|
|
||||||
|
```
|
||||||
|
# /etc/finit.conf in initramfs
|
||||||
|
|
||||||
|
# Mount the real root filesystem
|
||||||
|
run [S] name:mount-root /bin/mount /dev/sda1 /mnt/root -- Mounting root filesystem
|
||||||
|
|
||||||
|
# Switch to real root after mount completes
|
||||||
|
run [S] name:switch-root /sbin/initctl switch-root /mnt/root -- Switching to real root
|
||||||
|
```
|
||||||
|
|
||||||
|
For more complex setups (LUKS, LVM, etc.):
|
||||||
|
|
||||||
|
```
|
||||||
|
# Unlock LUKS volume
|
||||||
|
# The tty:@console stanza is required so cryptsetup can prompt for a passphrase
|
||||||
|
run [S] name:cryptsetup tty:@console /sbin/cryptsetup open /dev/sda2 cryptroot -- Unlocking encrypted root
|
||||||
|
|
||||||
|
# Activate LVM
|
||||||
|
run [S] name:lvm /sbin/lvm vgchange -ay -- Activating LVM volumes
|
||||||
|
|
||||||
|
# Mount root
|
||||||
|
run [S] name:mount-root /bin/mount /dev/vg0/root /mnt/root -- Mounting root
|
||||||
|
|
||||||
|
# Switch root
|
||||||
|
run [S] name:switch-root /sbin/initctl switch-root /mnt/root -- Switching to real root
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Example: Using Runlevel 1 for Switch Root
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
For more complex initramfs setups where ordering of tasks becomes
|
||||||
|
difficult in runlevel S, you can perform the switch-root in runlevel 1:
|
||||||
|
|
||||||
|
```
|
||||||
|
# /etc/finit.conf in initramfs
|
||||||
|
|
||||||
|
# Start mdevd for device handling
|
||||||
|
service [S] name:mdevd notify:s6 /sbin/mdevd -D %n -- Device event daemon
|
||||||
|
run [S] name:coldplug <service/mdevd/ready> /sbin/mdevd-coldplug -- Coldplug devices
|
||||||
|
|
||||||
|
# Mount the real root filesystem (after devices are ready)
|
||||||
|
run [S] name:mount-root <run/coldplug/success> /bin/mount /dev/sda1 /mnt/root -- Mounting root
|
||||||
|
|
||||||
|
# Transition to runlevel 1 after all S tasks complete
|
||||||
|
# The switch-root runs cleanly in runlevel 1
|
||||||
|
run [1] name:switch-root /sbin/initctl switch-root /mnt/root -- Switching to real root
|
||||||
|
```
|
||||||
|
|
||||||
|
This approach separates the initramfs setup (runlevel S) from the
|
||||||
|
switch-root operation (runlevel 1), making task ordering simpler.
|
||||||
|
|
||||||
|
|
||||||
|
Hooks
|
||||||
|
-----
|
||||||
|
|
||||||
|
The `HOOK_SWITCH_ROOT` hook runs before the switch begins. Use it for:
|
||||||
|
|
||||||
|
- Saving state to the new root
|
||||||
|
- Unmounting initramfs-only mounts
|
||||||
|
- Cleanup tasks
|
||||||
|
|
||||||
|
Plugins can register for `HOOK_SWITCH_ROOT` just like other hooks:
|
||||||
|
|
||||||
|
```c
|
||||||
|
static void my_switch_root_hook(void *arg)
|
||||||
|
{
|
||||||
|
/* Cleanup before switch_root */
|
||||||
|
}
|
||||||
|
|
||||||
|
static plugin_t plugin = {
|
||||||
|
.name = "my-plugin",
|
||||||
|
.hook[HOOK_SWITCH_ROOT] = {
|
||||||
|
.cb = my_switch_root_hook
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PLUGIN_INIT(plugin_init)
|
||||||
|
{
|
||||||
|
plugin_register(&plugin);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Conditions
|
||||||
|
----------
|
||||||
|
|
||||||
|
After switch_root, the new finit instance starts fresh. No conditions
|
||||||
|
or state are preserved across the switch. The new finit will:
|
||||||
|
|
||||||
|
1. Re-read `/etc/finit.conf` from the new root
|
||||||
|
2. Re-initialize all conditions
|
||||||
|
3. Start services according to the new configuration
|
||||||
|
|
||||||
|
|
||||||
|
See Also
|
||||||
|
--------
|
||||||
|
|
||||||
|
- [switch_root(8)](https://man7.org/linux/man-pages/man8/switch_root.8.html) - util-linux switch_root utility
|
||||||
|
- [Kernel initramfs documentation](https://docs.kernel.org/filesystems/ramfs-rootfs-initramfs.html)
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
Bundled Watchdog Daemon
|
||||||
|
=======================
|
||||||
|
|
||||||
|
When built `--with-watchdog` a separate service is built and installed
|
||||||
|
in `/libexec/finit/watchdogd`. If this exists at runtime, and the WDT
|
||||||
|
device node exists, Finit will start it and treat it as the elected
|
||||||
|
watchdog service to delegate its reboot to. This delegation is to
|
||||||
|
ensure that the system is rebooted by a hardware watchdog timer -- on
|
||||||
|
many embedded systems this is crucial to ensure all circuits on the
|
||||||
|
board are properly reset for the next boot, in effect ensuring the
|
||||||
|
system works the same after both a power-on and reboot event.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The watchdog reboot delegation can be enabled with the `reboot-watchdog`
|
||||||
|
> configuration option in `/etc/finit.conf`. By default this is disabled
|
||||||
|
> and the system reboots directly via the SoC using the kernel's `reboot(2)`
|
||||||
|
> syscall. See [Runlevels](config/runlevels.md) for details.
|
||||||
|
|
||||||
|
The delegation is performed at the very last steps of system shutdown,
|
||||||
|
if reboot has been selected, `reboot-watchdog` is enabled, and an elected
|
||||||
|
watchdog is known. First a `SIGPWR` is sent to advise watchdogd of the
|
||||||
|
pending reboot. Then, when the necessary steps of preparing the system
|
||||||
|
for shutdown (umount etc.) are completed, Finit sends `SIGTERM` to
|
||||||
|
watchdogd and puts itself in a 10 sec timeout loop waiting for the WDT
|
||||||
|
to reset the board. If a reset is not done before the timeout, Finit
|
||||||
|
falls back to `reboot(RB_AUTOBOOT)` which tells the kernel to do the
|
||||||
|
reboot.
|
||||||
|
|
||||||
|
An external watchdog service can also be used. The more advanced cousin
|
||||||
|
[watchdogd](https://github.com/troglobit/watchdogd/) is the recommended
|
||||||
|
option here. It can register itself with Finit using the same IPC as
|
||||||
|
`initctl`. If the bundled watchdogd is running a hand-over takes place,
|
||||||
|
so it's safe to have both services installed on a system. For the
|
||||||
|
hand-over to work it requires that the WDT driver supports the safe exit
|
||||||
|
functionality where `"V"` is written to the device before closing the
|
||||||
|
device descriptor. If the kernel driver has been built without this,
|
||||||
|
the only option is to remove `/libexec/finit/watchdogd` or build without
|
||||||
|
it at configure time.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
.deps/*
|
||||||
|
.libs/*
|
||||||
|
.dirstamp
|
||||||
|
*.lo
|
||||||
|
libsystemd.*
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# libsystemd replacement library
|
||||||
|
lib_LTLIBRARIES = libsystemd.la
|
||||||
|
libsystemd_la_SOURCES = sd-daemon.c sd-daemon.h
|
||||||
|
libsystemd_la_LDFLAGS = -version-info 0:0:0
|
||||||
|
libsystemd_la_CFLAGS = $(lite_CFLAGS)
|
||||||
|
libsystemd_la_LIBADD = $(lite_LIBS)
|
||||||
|
|
||||||
|
# pkg-config support
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = libsystemd.pc
|
||||||
|
|
||||||
|
# Install header to systemd/ subdirectory
|
||||||
|
systemddir = $(includedir)/systemd
|
||||||
|
systemd_HEADERS = sd-daemon.h
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: libsystemd
|
||||||
|
Description: Finit replacement for systemd notification library
|
||||||
|
Version: @PACKAGE_VERSION@
|
||||||
|
Libs: -L${libdir} -lsystemd
|
||||||
|
Cflags: -I${includedir}
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
/* SPDX-License-Identifier: MIT-0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* systemd notify protocol, supporting readiness notification on startup
|
||||||
|
* and reloading, according to the protocol defined at:
|
||||||
|
* https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html
|
||||||
|
*
|
||||||
|
* This protocol is guaranteed to be stable as per:
|
||||||
|
* https://systemd.io/PORTABILITY_AND_STABILITY/
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE 1
|
||||||
|
#include <errno.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifdef _LIBITE_LITE
|
||||||
|
# include <libite/lite.h>
|
||||||
|
#else
|
||||||
|
# include <lite/lite.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sd-daemon.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: As per spec., this function does not return POSIX OK(0) but
|
||||||
|
* rather "a positive value", i.e., 1.
|
||||||
|
*/
|
||||||
|
int sd_notify(int unset_environment, const char *state)
|
||||||
|
{
|
||||||
|
struct sockaddr_un sun = {
|
||||||
|
.sun_family = AF_UNIX,
|
||||||
|
};
|
||||||
|
size_t len, sun_len;
|
||||||
|
const char *path;
|
||||||
|
ssize_t written;
|
||||||
|
int sd;
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
len = strlen(state);
|
||||||
|
if (len == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* If the variable is not set, the protocol is a noop */
|
||||||
|
path = getenv("NOTIFY_SOCKET");
|
||||||
|
if (!path)
|
||||||
|
return 0; /* Not set? Nothing to do */
|
||||||
|
|
||||||
|
/* Only AF_UNIX is supported, with path or abstract sockets */
|
||||||
|
if (path[0] != '/' && path[0] != '@')
|
||||||
|
return -EAFNOSUPPORT;
|
||||||
|
|
||||||
|
/* Ensure there is room for NUL byte */
|
||||||
|
sun_len = strlen(path);
|
||||||
|
if (sun_len >= sizeof(sun.sun_path))
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
|
strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
|
||||||
|
if (sun.sun_path[0] == '@')
|
||||||
|
sun.sun_path[0] = 0;
|
||||||
|
|
||||||
|
sd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||||
|
if (sd == -1)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (connect(sd, (struct sockaddr *)&sun, offsetof(struct sockaddr_un, sun_path) + sun_len) == -1) {
|
||||||
|
close(sd);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unset_environment)
|
||||||
|
unsetenv("NOTIFY_SOCKET");
|
||||||
|
|
||||||
|
written = write(sd, state, len);
|
||||||
|
close(sd);
|
||||||
|
if (written != (ssize_t) len)
|
||||||
|
return written < 0 ? -errno : -EPROTO;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Printf-style notification function
|
||||||
|
*/
|
||||||
|
int sd_notifyf(int unset_environment, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
char *state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!format)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
ret = vasprintf(&state, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = sd_notify(unset_environment, state);
|
||||||
|
free(state);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PID-specific notification function
|
||||||
|
*/
|
||||||
|
int sd_pid_notify(pid_t pid, int unset_environment, const char *state)
|
||||||
|
{
|
||||||
|
char path[256], *env;
|
||||||
|
size_t len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
len = strlen(state);
|
||||||
|
if (len == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
pid = getpid();
|
||||||
|
|
||||||
|
env = getenv("NOTIFY_SOCKET");
|
||||||
|
if (env) {
|
||||||
|
env = strdup(env);
|
||||||
|
if (!env)
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(path, sizeof(path), "@run/finit/notify/%d", pid);
|
||||||
|
setenv("NOTIFY_SOCKET", path, 1);
|
||||||
|
|
||||||
|
ret = sd_notify(unset_environment, state);
|
||||||
|
|
||||||
|
if (env) {
|
||||||
|
setenv("NOTIFY_SOCKET", env, 1);
|
||||||
|
free(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PID-specific printf-style notification function
|
||||||
|
*/
|
||||||
|
int sd_pid_notifyf(pid_t pid, int unset_environment, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
char *state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!format)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
ret = vasprintf(&state, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = sd_pid_notify(pid, unset_environment, state);
|
||||||
|
free(state);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Socket activation stub - Finit doesn't support socket activation yet
|
||||||
|
* Returns 0 (no file descriptors passed)
|
||||||
|
*/
|
||||||
|
int sd_listen_fds(int unset_environment)
|
||||||
|
{
|
||||||
|
if (unset_environment) {
|
||||||
|
unsetenv("LISTEN_PID");
|
||||||
|
unsetenv("LISTEN_FDS");
|
||||||
|
unsetenv("LISTEN_FDNAMES");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Watchdog stub - Finit doesn't support watchdog yet
|
||||||
|
* Returns 0 (no watchdog enabled)
|
||||||
|
*/
|
||||||
|
int sd_watchdog_enabled(int unset_environment, uint64_t *usec)
|
||||||
|
{
|
||||||
|
if (unset_environment) {
|
||||||
|
unsetenv("WATCHDOG_PID");
|
||||||
|
unsetenv("WATCHDOG_USEC");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usec)
|
||||||
|
*usec = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System detection function
|
||||||
|
* Returns 1 to indicate systemd compatibility (trick applications)
|
||||||
|
*/
|
||||||
|
int sd_booted(void)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef SD_DAEMON_H_
|
||||||
|
#define SD_DAEMON_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#define SD_LISTEN_FDS_START 3
|
||||||
|
|
||||||
|
/* systemd logging defines for stderr parsing by Finit */
|
||||||
|
#define SD_EMERG "<0>" /* system is unusable */
|
||||||
|
#define SD_ALERT "<1>" /* action must be taken immediately */
|
||||||
|
#define SD_CRIT "<2>" /* critical conditions */
|
||||||
|
#define SD_ERR "<3>" /* error conditions */
|
||||||
|
#define SD_WARNING "<4>" /* warning conditions */
|
||||||
|
#define SD_NOTICE "<5>" /* normal but significant condition */
|
||||||
|
#define SD_INFO "<6>" /* informational */
|
||||||
|
#define SD_DEBUG "<7>" /* debug-level messages */
|
||||||
|
|
||||||
|
/* Basic notification function */
|
||||||
|
int sd_notify(int unset_environment, const char *state);
|
||||||
|
|
||||||
|
/* Printf-style notification functions */
|
||||||
|
int sd_notifyf(int unset_environment, const char *format, ...);
|
||||||
|
|
||||||
|
/* PID-specific notification functions */
|
||||||
|
int sd_pid_notify(pid_t pid, int unset_environment, const char *state);
|
||||||
|
int sd_pid_notifyf(pid_t pid, int unset_environment, const char *format, ...);
|
||||||
|
|
||||||
|
/* Socket activation stubs */
|
||||||
|
int sd_listen_fds(int unset_environment);
|
||||||
|
|
||||||
|
/* Watchdog stub */
|
||||||
|
int sd_watchdog_enabled(int unset_environment, uint64_t *usec);
|
||||||
|
|
||||||
|
/* System detection */
|
||||||
|
int sd_booted(void);
|
||||||
|
|
||||||
|
#endif /* SD_DAEMON_H_ */
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
# From https://github.com/collectd/collectd/blob/master/configure.ac
|
# From https://github.com/collectd/collectd/blob/master/configure.ac
|
||||||
# Dependency handling currently unused
|
# Dependency handling currently unused
|
||||||
|
|
||||||
define([toupper], [translit([$1], [a-z], [A-Z])])
|
|
||||||
define([sanitize], [translit([$1], [-], [_])])
|
|
||||||
define([enadis], [ifelse([$1], [yes], [disable], [enable])])
|
define([enadis], [ifelse([$1], [yes], [disable], [enable])])
|
||||||
|
|
||||||
# AC_PLUGIN(name, default, info)
|
# AC_PLUGIN(name, default, info)
|
||||||
@@ -10,27 +8,25 @@ define([enadis], [ifelse([$1], [yes], [disable], [enable])])
|
|||||||
AC_DEFUN([AC_PLUGIN],[
|
AC_DEFUN([AC_PLUGIN],[
|
||||||
m4_divert_once([HELP_ENABLE], [
|
m4_divert_once([HELP_ENABLE], [
|
||||||
Optional Plugins:])
|
Optional Plugins:])
|
||||||
|
define(PLUGGY, m4_translit([$1],[a-z-][A-Z-]))dnl
|
||||||
|
AC_ARG_ENABLE([$1-plugin], AS_HELP_STRING([--enadis($2)-$1-plugin], [$3]), [
|
||||||
|
if test "x$enableval" = "xyes"; then
|
||||||
|
enable_plugin="yes"
|
||||||
|
else
|
||||||
enable_plugin="no"
|
enable_plugin="no"
|
||||||
define(pluggy, sanitize($1))
|
fi], [
|
||||||
define(PLUGGY, toupper(pluggy))
|
if test "x$enable_all_plugins" = "xauto"; then
|
||||||
AC_ARG_ENABLE([$1-plugin], AS_HELP_STRING([--enadis($2)-$1-plugin], [$3]), [
|
if test "x$2" = "xyes"; then
|
||||||
if test "x$enableval" = "xyes"; then
|
enable_plugin="yes"
|
||||||
enable_plugin="yes"
|
|
||||||
else
|
else
|
||||||
enable_plugin="no"
|
enable_plugin="no"
|
||||||
fi], [
|
|
||||||
if test "x$enable_all_plugins" = "xauto"; then
|
|
||||||
if test "x$2" = "xyes"; then
|
|
||||||
enable_plugin="yes"
|
|
||||||
else
|
|
||||||
enable_plugin="no"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
enable_plugin="$enable_all_plugins"
|
|
||||||
fi])
|
|
||||||
if test "x$enable_plugin" = "xyes"; then
|
|
||||||
AC_DEFINE([HAVE_]PLUGGY[_PLUGIN], 1, [Define to 1 if the $1 plugin is enabled.])
|
|
||||||
plugins="$1 $plugins"
|
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([BUILD_]PLUGGY[_PLUGIN], test "x$enable_plugin" = "xyes")
|
else
|
||||||
enable_pluggy="$enable_plugin"])
|
enable_plugin="$enable_all_plugins"
|
||||||
|
fi])
|
||||||
|
if test "x$enable_plugin" = "xyes"; then
|
||||||
|
AC_DEFINE(HAVE_[]m4_translit($1,[-a-z],[_A-Z])_PLUGIN, 1, [Define to 1 if the $1 plugin is enabled.])
|
||||||
|
plugins="$1 $plugins"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL(BUILD_[]m4_translit($1,[-a-z],[_A-Z])_PLUGIN, test "x$enable_plugin" = "xyes")])
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
.\" First parameter, NAME, should be all caps
|
.\" First parameter, NAME, should be all caps
|
||||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
.\" other parameters are allowed: see man(7), man(1)
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
.Dd June 6, 2021
|
.Dd Jul 9, 2025
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
.Dt FINIT 8 SMM
|
.Dt FINIT 8 SMM
|
||||||
.Os Linux
|
.Os Linux
|
||||||
@@ -10,24 +10,66 @@
|
|||||||
.Nm finit
|
.Nm finit
|
||||||
.Nd Fast init for Linux systems
|
.Nd Fast init for Linux systems
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm /sbin/finit
|
.Nm /sbin/finit --
|
||||||
.Op --
|
.Op debug
|
||||||
.Op finit.debug
|
.Op quiet
|
||||||
.Op finit.fstab=/etc/fstab.alt
|
|
||||||
.Op finit.status=<on,off>
|
|
||||||
.Op finit.status_style=<classic,modern>
|
|
||||||
.Op rescue | recover
|
.Op rescue | recover
|
||||||
.Op single | S
|
.Op single | S
|
||||||
|
.Op panic=SEC
|
||||||
|
.Op loglevel=<0-7>
|
||||||
|
.Op fsck.mode=[auto,skip,force]
|
||||||
|
.Op fsck.repair=[no,yes,preen]
|
||||||
|
.Op finit.debug=<true,false>
|
||||||
|
.Op finit.fstab=/path/to/fstab
|
||||||
|
.Op finit.cond=foo[,bar[,baz]]
|
||||||
|
.Op finit.config=/path/to/finit.conf
|
||||||
|
.Op finit.status_style=<classic,modern>
|
||||||
|
.Op finit.status=<on,off>
|
||||||
.Nm /sbin/telinit
|
.Nm /sbin/telinit
|
||||||
.Op Fl hv
|
.Op Fl hv
|
||||||
.Op q | Q | 0-9
|
.Op q | Q | s | S | 0-9
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
Fast init for Linux systems. Reverse engineered from the EeePC
|
Fast init for Linux systems. Reverse engineered from the EeePC
|
||||||
fastinit, 10+ years ago by Claudio Matsuoka, "gaps filled with frog
|
fastinit, 10+ years ago by Claudio Matsuoka, "gaps filled with frog
|
||||||
DNA ...". Focus is on small and embedded systems, although Finit is
|
DNA ...". Focus is on small and embedded systems, although Finit is
|
||||||
fully usable on server and desktop systems as well.
|
fully usable on server and desktop systems as well.
|
||||||
|
.Sh OPTIONS
|
||||||
|
When
|
||||||
|
.Sy not
|
||||||
|
started as PID 1,
|
||||||
|
.Nm
|
||||||
|
behaves like
|
||||||
|
.Nm telinit ,
|
||||||
|
following classic UNIX command line syntax. The options are:
|
||||||
.Pp
|
.Pp
|
||||||
Features include:
|
.Bl -tag -width Ds -compact -offset indent
|
||||||
|
.It Fl h
|
||||||
|
Show built-in help text.
|
||||||
|
.It Fl v
|
||||||
|
Show program version.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
More options are implemented for SysV init support, but are ignored.
|
||||||
|
.Sh ARGUMENTS
|
||||||
|
When
|
||||||
|
.Sy not
|
||||||
|
started as PID 1,
|
||||||
|
.Nm ,
|
||||||
|
or
|
||||||
|
.Nm telinit ,
|
||||||
|
take these arguments:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width Ds -compact -offset indent
|
||||||
|
.It q | Q
|
||||||
|
Reload configuration, same as
|
||||||
|
.Cm initctl reload .
|
||||||
|
.It 0 - 9
|
||||||
|
Go to runlevel N, same as
|
||||||
|
.Cm initctl reload N .
|
||||||
|
.It s | S
|
||||||
|
Go to single user mode, runlevel 1.
|
||||||
|
.El
|
||||||
|
.Sh FEATURES
|
||||||
.Bl -bullet -width 1n -compact
|
.Bl -bullet -width 1n -compact
|
||||||
.It
|
.It
|
||||||
Runlevels, defined per service
|
Runlevels, defined per service
|
||||||
@@ -45,6 +87,15 @@ Sourcing environment files
|
|||||||
.It
|
.It
|
||||||
Conditions for network/process/custom dependencies
|
Conditions for network/process/custom dependencies
|
||||||
.It
|
.It
|
||||||
|
Process readiness notification for synchronizing system startup as well
|
||||||
|
as reconfiguration at runtime. Natively PID files are used, but systemd
|
||||||
|
.Cm sd_notify()
|
||||||
|
and s6 notification is also supported.
|
||||||
|
.It
|
||||||
|
Limited support for
|
||||||
|
.Xr tmpfiles.d 5 ,
|
||||||
|
no aging, attributes, or subvolumes
|
||||||
|
.It
|
||||||
Pre/Post script actions
|
Pre/Post script actions
|
||||||
.It
|
.It
|
||||||
Tooling to enable/disable services
|
Tooling to enable/disable services
|
||||||
@@ -73,6 +124,59 @@ PID 1. For more information on this, and available kernel command line
|
|||||||
options, see
|
options, see
|
||||||
.Xr bootparam 7 .
|
.Xr bootparam 7 .
|
||||||
.Bl -tag -width pid -offset indent
|
.Bl -tag -width pid -offset indent
|
||||||
|
.It Cm debug
|
||||||
|
Enable kernel debug. Debug messages are printed to the console until
|
||||||
|
Finit starts up, unless
|
||||||
|
.Cm loglevel=7
|
||||||
|
(below) is used.
|
||||||
|
.It Cm fsck.mode=<auto,force,skip>
|
||||||
|
Defaults to
|
||||||
|
.Cm auto ,
|
||||||
|
unless Finit is built with
|
||||||
|
.Cm configure --enable-fastboot ,
|
||||||
|
in which case the default is
|
||||||
|
.Cm skip .
|
||||||
|
.It Cm fsck.repair=<preen,yes,no>
|
||||||
|
Defaults to
|
||||||
|
.Cm preen ,
|
||||||
|
unless Finit is built with
|
||||||
|
.Cm configure --enable-fsckfix ,
|
||||||
|
in which case the default is
|
||||||
|
.Cm yes .
|
||||||
|
This configure option also sets
|
||||||
|
.Cm fsck.mode=force ,
|
||||||
|
unless fastboot is also enabled. I.e.,
|
||||||
|
.Cm configure --enable-fastboot
|
||||||
|
build option overrides the
|
||||||
|
.Cm fsck.mode
|
||||||
|
default value.
|
||||||
|
.It Cm finit.cond=foo[,bar[,baz]]
|
||||||
|
set
|
||||||
|
.Cm <boot/foo>
|
||||||
|
condition, optionally multiple conditions can be set using the same
|
||||||
|
option, separated with a comma. Alternatively, multiple
|
||||||
|
.Cm foo.cond=arg
|
||||||
|
can be given. Each will result in a
|
||||||
|
.Cm <boot/arg>
|
||||||
|
condition being set to control the rest of the system bootstrap.
|
||||||
|
.Pp
|
||||||
|
Very useful for selecting different boot modes, e.g. manufacturing test,
|
||||||
|
firmware upgrade, or rescue mode.
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
.Cm <boot/...>
|
||||||
|
conditions cannot be cleared with
|
||||||
|
.Nm initctl !
|
||||||
|
.It Cm finit.config=/path/to/alternative/finit.conf
|
||||||
|
override the compile-time bootstrap config file, default:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
./configure --with-config=/etc/finit.conf
|
||||||
|
.Ed
|
||||||
|
Useful when starting up in various rescue mode, factory, or
|
||||||
|
production test setups. Use the top-level configuration file
|
||||||
|
directive
|
||||||
|
.Cm rcsd Ar /path/to/finit.d
|
||||||
|
to override the default rcS.d directory.
|
||||||
.It Cm finit.debug
|
.It Cm finit.debug
|
||||||
Enable Finit debug messages on system console and log. Sometimes useful
|
Enable Finit debug messages on system console and log. Sometimes useful
|
||||||
when doing board bringup. Before the system log daemon has started,
|
when doing board bringup. Before the system log daemon has started,
|
||||||
@@ -121,6 +225,33 @@ Control finit boot progress, including banner. This used to be called
|
|||||||
which still works but is deprecated.
|
which still works but is deprecated.
|
||||||
.It Cm finit.status_style=<classic,modern>
|
.It Cm finit.status_style=<classic,modern>
|
||||||
Set Finit boot progress style, when enabled.
|
Set Finit boot progress style, when enabled.
|
||||||
|
.It Cm loglevel=<0-7>
|
||||||
|
set the kernel's log level, which is more granular than
|
||||||
|
.Cm debug .
|
||||||
|
Also, when
|
||||||
|
.Cm loglevel=7 ,
|
||||||
|
Finit will
|
||||||
|
.Em not disable
|
||||||
|
kernel logs to the console. This is very useful when debugging the
|
||||||
|
kernel at system bring-up. Since
|
||||||
|
.Cm loglevel=7
|
||||||
|
is the same as
|
||||||
|
.Cm debug
|
||||||
|
this means you have to use
|
||||||
|
.Cm quiet
|
||||||
|
for a quiet boot, until sysklogd takes over logging of kernel events.
|
||||||
|
.It Cm panic=SEC
|
||||||
|
By default the kernel does not reboot after a kernel panic. This
|
||||||
|
setting will cause a kernel reboot after
|
||||||
|
.Ar SEC
|
||||||
|
seconds.
|
||||||
|
.It Cm quiet
|
||||||
|
Suppress kernel logging to console, except for warnings and errors.
|
||||||
|
Also, see
|
||||||
|
.Cm loglevel
|
||||||
|
and
|
||||||
|
.Cm quiet
|
||||||
|
above.
|
||||||
.It Cm rescue | recover
|
.It Cm rescue | recover
|
||||||
Start rescue/maintenance mode. If your system comes with the bundled
|
Start rescue/maintenance mode. If your system comes with the bundled
|
||||||
.Cm sulogin
|
.Cm sulogin
|
||||||
@@ -139,6 +270,10 @@ the regular runlevel. All services and TTYs in
|
|||||||
will be started, e.g., a
|
will be started, e.g., a
|
||||||
.Cm tty [1] @console nologin
|
.Cm tty [1] @console nologin
|
||||||
configuration presents you with a root console without login.
|
configuration presents you with a root console without login.
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
by definition, single user mode does not have networking enabled. This
|
||||||
|
is also true for runlevel 1.
|
||||||
.El
|
.El
|
||||||
.Sh BOOTING
|
.Sh BOOTING
|
||||||
.Pp
|
.Pp
|
||||||
@@ -192,14 +327,22 @@ file removed, service B is also stopped.
|
|||||||
.Pp
|
.Pp
|
||||||
The following condition families are available today:
|
The following condition families are available today:
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width pid -offset indent
|
.Bl -tag -width service -offset indent
|
||||||
.It Cm net
|
.It Cm net
|
||||||
Linux netlink events, e.g. net/route/default, net/eth0/up, and
|
Linux netlink events, e.g. net/route/default, net/eth0/up, and
|
||||||
net/et0/running
|
net/et0/running
|
||||||
.It Cm pid
|
.It Cm pid
|
||||||
PID files basd on the service declaration
|
PID files based on the service declaration
|
||||||
.Cm name:id ,
|
.Cm name:id ,
|
||||||
gives the condition pid/name:id
|
gives the condition pid/name:id
|
||||||
|
.It Cm service
|
||||||
|
Tracks run/task/service state stansitions, including readiness. E.g.,
|
||||||
|
.Cm service/foo/ready
|
||||||
|
can be used as a condition for service
|
||||||
|
.Cm bar ,
|
||||||
|
provided
|
||||||
|
.Cm foo
|
||||||
|
properly signals its readiness to Finit.
|
||||||
.It Cm sys
|
.It Cm sys
|
||||||
System conditions, e.g. sys/key/ctrlaltdel and sys/pwr/fail
|
System conditions, e.g. sys/key/ctrlaltdel and sys/pwr/fail
|
||||||
.It Cm usr
|
.It Cm usr
|
||||||
@@ -255,6 +398,7 @@ Runtime files, including the condition subsystem
|
|||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr finit.conf 5
|
.Xr finit.conf 5
|
||||||
.Xr initctl 8
|
.Xr initctl 8
|
||||||
|
.Xr tmpfiles.d 5
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.Nm
|
.Nm
|
||||||
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
|
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
.\" First parameter, NAME, should be all caps
|
.\" First parameter, NAME, should be all caps
|
||||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
.\" other parameters are allowed: see man(7), man(1)
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
.Dd Oct 17, 2020
|
.Dd July 10, 2025
|
||||||
.Dt FINIT.CONF 5 SMM
|
.Dt FINIT.CONF 5 SMM
|
||||||
.Os Linux
|
.Os Linux
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -12,48 +12,79 @@
|
|||||||
.Nm /etc/finit.conf
|
.Nm /etc/finit.conf
|
||||||
.Nm /etc/finit.d/*.conf
|
.Nm /etc/finit.d/*.conf
|
||||||
.Nm /etc/finit.d/available/*.conf
|
.Nm /etc/finit.d/available/*.conf
|
||||||
|
.Nm /etc/finit.d/enabled/*.conf
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm finit
|
.Nm Finit
|
||||||
can be configured using only the original
|
based systems can be set up with a single file:
|
||||||
.Pa /etc/finit.conf
|
.Pa /etc/finit.conf .
|
||||||
file or in combination with
|
This is the traditional way of doing it which can be ideal for some
|
||||||
.Pa /etc/finit.d/*.conf .
|
setups since it gives a great overview of the system configuration.
|
||||||
Useful for package-based Linux distributions \(em each package can
|
|
||||||
provide its own "script" file.
|
|
||||||
.Pp
|
.Pp
|
||||||
.Bl -tag -width /etc/finit.d/*.conf -offset indent -compact
|
More comprehensive setups, however, require more careful planning.
|
||||||
.It Pa /etc/finit.conf
|
The recommendation is per-package
|
||||||
Main configuration file
|
.Cm *.conf
|
||||||
.It Pa /etc/finit.d/*.conf
|
files in
|
||||||
Snippets, usually one service per file
|
.Pa /etc/finit.d/available/ .
|
||||||
.El
|
This allows end users to enable and disable parts of the system
|
||||||
|
configuration at runtime. Finit tracks which tasks and services belong
|
||||||
|
to a given file, so that when the user calls
|
||||||
|
.Cm initctl reload
|
||||||
|
to activate the changes they have made, only the affected tasks and
|
||||||
|
services are stopped, started, or restarted. Hence, this approach is
|
||||||
|
useful for modern package-based Linux distributions.
|
||||||
.Pp
|
.Pp
|
||||||
Not all configuration directives are available in
|
The following sections describe the more of this in detail, starting
|
||||||
.Pa /etc/finit.d/*.conf
|
with files, the file format, and available directives. Remember to
|
||||||
and some directives are only available at bootstrap, runlevel
|
also visit the other manual pages (references at the bottom).
|
||||||
.Cm S ,
|
|
||||||
see the section
|
|
||||||
.Sx Limitations
|
|
||||||
below for details.
|
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width /etc/finit.d/available/*.conf -compact
|
.Bl -tag -width /etc/finit.d/available/*.conf -compact
|
||||||
.It Pa /etc/finit.conf
|
.It Pa /etc/finit.conf
|
||||||
Main configuration file
|
Main configuration file, optional
|
||||||
.It Pa /etc/finit.d/*.conf
|
.It Pa /etc/finit.d/*.conf
|
||||||
Static service definitions
|
Static (system) service definitions
|
||||||
.It Pa /etc/finit.d/available/*.conf
|
.It Pa /etc/finit.d/available/*.conf
|
||||||
Available services
|
Available (installed) services
|
||||||
.It Pa /etc/finit.d/enabled/*.conf
|
.It Pa /etc/finit.d/enabled/*.conf
|
||||||
Enabled services, symlinks from available
|
Enabled services (symlink back)
|
||||||
.El
|
.El
|
||||||
.Sh FILE FORMAT
|
|
||||||
Lines starting with `#' are ignored. Note that end-of-line comments are
|
|
||||||
NOT supported, comments must be on a line of their own.
|
|
||||||
.Pp
|
.Pp
|
||||||
A configuration stanza must be on a single (long) line and
|
Static services,
|
||||||
.Em cannot
|
.Cm .conf
|
||||||
be broken up in multiple lines by use of a backslash as the last
|
files in
|
||||||
character.
|
.Pa /etc/finit.d/ ,
|
||||||
|
cannot be enabled or disabled using
|
||||||
|
.Cm initctl [enable | disable] service[.conf] .
|
||||||
|
An enabled service is a symlink back to the corresponding
|
||||||
|
.Cm ../available/
|
||||||
|
service
|
||||||
|
.Cm .conf
|
||||||
|
file. Please use the
|
||||||
|
.Cm initctl
|
||||||
|
tool to manage these symlinks to ensure proper operation.
|
||||||
|
.Pp
|
||||||
|
.Sy NOTE:
|
||||||
|
Previous versions of
|
||||||
|
.Nm Finit
|
||||||
|
created symlinks in
|
||||||
|
.Pa /etc/finit.d/
|
||||||
|
if
|
||||||
|
.Pa /etc/finit.d/enabled/
|
||||||
|
was missing, this is as of v4.4 not supported.
|
||||||
|
.Sh FILE FORMAT
|
||||||
|
The file format is line based, empty lines and comments, lines starting
|
||||||
|
with `#', are ignored. A configuration directive starts with a keyword
|
||||||
|
followed by a space and the rest of the line is treated as the value.
|
||||||
|
.Pp
|
||||||
|
As of Finit v4.4, configuration directives can be broken up in multiple
|
||||||
|
lines using the continuation character `\\', and trailing comments are
|
||||||
|
also allowed. Example:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
# Escape \\# chars if you want them literal in, e.g., descriptions
|
||||||
|
service name:sysklogd [S123456789] \\
|
||||||
|
env:-/etc/default/sysklogd \\
|
||||||
|
syslogd -F $SYSLOGD_ARGS \\
|
||||||
|
-- System log daemon \\# 1 # Comments allowed now
|
||||||
|
.Ed
|
||||||
.Sh DIRECTIVES
|
.Sh DIRECTIVES
|
||||||
This section lists all supported configuration directives. There also exist
|
This section lists all supported configuration directives. There also exist
|
||||||
deprecated directives, see the Markdown documentation for details on these.
|
deprecated directives, see the Markdown documentation for details on these.
|
||||||
@@ -108,6 +139,10 @@ is the runlevel number 0-9, where 6 is reserved for reboot and 0 for
|
|||||||
halt. All other can be used by operating system administrators.
|
halt. All other can be used by operating system administrators.
|
||||||
Default: 2
|
Default: 2
|
||||||
.Pp
|
.Pp
|
||||||
|
It s recommended to keep runlevel 1 as single-user mode, because
|
||||||
|
.Nm
|
||||||
|
disables networking in this mode.
|
||||||
|
.Pp
|
||||||
.Sy Note:
|
.Sy Note:
|
||||||
only read and executed in runlevel S (bootstrap).
|
only read and executed in runlevel S (bootstrap).
|
||||||
.It Cm run Oo LVLS Oc Ao COND Ac Ar /path/to/cmd ARGS Op -- Optional description
|
.It Cm run Oo LVLS Oc Ao COND Ac Ar /path/to/cmd ARGS Op -- Optional description
|
||||||
@@ -140,13 +175,13 @@ task [s] echo "foo" | cat >/tmp/bar
|
|||||||
.Ed
|
.Ed
|
||||||
.It Cm sysv Oo LVLS Oc Ao COND Ac Ar /path/to/script ARGS Op -- Optional description
|
.It Cm sysv Oo LVLS Oc Ao COND Ac Ar /path/to/script ARGS Op -- Optional description
|
||||||
Similar to
|
Similar to
|
||||||
.Cm task
|
.Cm service
|
||||||
is the
|
is the
|
||||||
.Cm sysv
|
.Cm sysv
|
||||||
stanza, which can be used to call SysV style start/stop scripts. The
|
directive, which can be used to call SysV style start/stop scripts. The
|
||||||
primary intention for this command is to be able to re-use much of
|
primary intention for this command is to be able to re-use traditional
|
||||||
existing setup and init scripts in Linux distributions.
|
SysV init scripts in Linux distributions.
|
||||||
.Pp
|
.Pp
|
||||||
When entering an allowed runlevel, Finit calls
|
When entering an allowed runlevel, Finit calls
|
||||||
.Cm init-script start ,
|
.Cm init-script start ,
|
||||||
when entering a disallowed runlevel, Finit calls
|
when entering a disallowed runlevel, Finit calls
|
||||||
@@ -159,7 +194,7 @@ on
|
|||||||
.Cm initctl reload .
|
.Cm initctl reload .
|
||||||
Similar to how
|
Similar to how
|
||||||
.Cm service
|
.Cm service
|
||||||
stanzas work.
|
directives work.
|
||||||
.Pp
|
.Pp
|
||||||
Forking services started with
|
Forking services started with
|
||||||
.Cm sysv
|
.Cm sysv
|
||||||
@@ -275,6 +310,51 @@ can depend on the
|
|||||||
.Cm <pid/bar>
|
.Cm <pid/bar>
|
||||||
condition.
|
condition.
|
||||||
.Pp
|
.Pp
|
||||||
|
As an alternative "readiness" notification, Finit supports both systemd
|
||||||
|
and s6 style notification. This can be enabled by using the `notify`
|
||||||
|
option:
|
||||||
|
.Bl -tag -width 1n
|
||||||
|
.It Cm notify:systemd
|
||||||
|
tells Finit the service uses the
|
||||||
|
.Cm sd_notify()
|
||||||
|
API to signal PID 1 when it has completed its startup and is ready
|
||||||
|
to service events. This API expects
|
||||||
|
the environment variable
|
||||||
|
.Cm NOTIFY_SOCKET
|
||||||
|
to be set to the socket where the application can send
|
||||||
|
.Cm "READY=1\n"
|
||||||
|
when it is starting up or has processed a
|
||||||
|
.Cm SIGHUP .
|
||||||
|
For details, see:
|
||||||
|
.Pp
|
||||||
|
.Lk https://www.freedesktop.org/software/systemd/man/sd_notify.html
|
||||||
|
.It Cm notify:s6
|
||||||
|
puts Finit in s6 compatibility mode. Compared to the systemd
|
||||||
|
notification, s6 expect compliant daemons to send
|
||||||
|
.Cm "\\n"
|
||||||
|
and then close their socket. For details, see:
|
||||||
|
.Pp
|
||||||
|
.Lk https://skarnet.org/software/s6/notifywhenup.html
|
||||||
|
.Pp
|
||||||
|
Finit takes care of "hard-wiring" the READY state as long as the
|
||||||
|
application is running, events across any `SIGHUP`. Since s6 can give
|
||||||
|
its applications the descriptor number (must be >3) on then command
|
||||||
|
line, Finit provides the following syntax (
|
||||||
|
.Cm %n
|
||||||
|
is replaced by Finit with then descriptor number):
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service notify:s6 mdevd -C -O 4 -D %n
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
When a service is ready, either by Finit detecting its PID file, or
|
||||||
|
their respective readiness mechanism has been triggered, Finit creates
|
||||||
|
then service's ready condition which other services can depend on:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
$ initctl -v cond get service/mdevd/ready
|
||||||
|
on
|
||||||
|
.Ed
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
If a service should not be automatically started, it can be configured
|
If a service should not be automatically started, it can be configured
|
||||||
as manual with the
|
as manual with the
|
||||||
.Cm manual:yes
|
.Cm manual:yes
|
||||||
@@ -304,6 +384,10 @@ number of seconds before Finit tries to restart
|
|||||||
a crashing service, default: 2 seconds for the first five retries,
|
a crashing service, default: 2 seconds for the first five retries,
|
||||||
then back-off to 5 seconds. The maximum of this configured value
|
then back-off to 5 seconds. The maximum of this configured value
|
||||||
and the above (2 and 5) will be used
|
and the above (2 and 5) will be used
|
||||||
|
.It Cm restart:always
|
||||||
|
no upper limit on the number of times Finit tries to restart a crashing
|
||||||
|
service. Same as
|
||||||
|
.Cm restart:-1
|
||||||
.It Cm norestart
|
.It Cm norestart
|
||||||
dont restart on failures, same as
|
dont restart on failures, same as
|
||||||
.Cm restart:0
|
.Cm restart:0
|
||||||
@@ -314,14 +398,62 @@ mechanism completely, allows endless restarts. Useful in many
|
|||||||
use-cases, but not what
|
use-cases, but not what
|
||||||
.Cm service
|
.Cm service
|
||||||
was originally designed for so not the default behavior.
|
was originally designed for so not the default behavior.
|
||||||
|
.It Cm remain:yes
|
||||||
|
for
|
||||||
|
.Cm run
|
||||||
|
and
|
||||||
|
.Cm task
|
||||||
|
only. Prevents the task from re-running on runlevel re-entry and
|
||||||
|
ensures the
|
||||||
|
.Cm post:
|
||||||
|
script runs when the task is explicitly stopped or leaves its valid
|
||||||
|
runlevels. Similar to systemd's
|
||||||
|
.Cm RemainAfterExit=yes .
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
not supported for bootstrap-only tasks (runlevels [S] only).
|
||||||
.It Cm oncrash:reboot
|
.It Cm oncrash:reboot
|
||||||
when all retries have failed, and the service
|
when all retries have failed, and the service
|
||||||
has
|
has
|
||||||
.Em crashed ,
|
.Em crashed ,
|
||||||
if this option is set the system is rebooted. Note, future releases
|
if this option is set the system is rebooted.
|
||||||
may include other
|
.It Cm oncrash:script
|
||||||
.Cm oncrash:
|
Similar to
|
||||||
actions.
|
.Cm oncrash:reboot ,
|
||||||
|
but instead of rebooting this action calls the
|
||||||
|
.Cm post:script
|
||||||
|
(see below) to let the operator decide the best course of action. If
|
||||||
|
the post:script option is not set, this is a no-op.
|
||||||
|
.Pp
|
||||||
|
The post:script is called with the same environment variables
|
||||||
|
.Sy except
|
||||||
|
for the
|
||||||
|
.Cm EXIT_CODE
|
||||||
|
variable which is set to
|
||||||
|
.Cm "crashed"
|
||||||
|
.It Cm reload:'script [args]'
|
||||||
|
some services do not support SIGHUP but may have other ways to update
|
||||||
|
the configuration of a running daemon. When
|
||||||
|
.Cm reload:script
|
||||||
|
is defined it is preferred over SIGHUP. Like systemd,
|
||||||
|
.Nm finit
|
||||||
|
sets
|
||||||
|
.Cm $MAINPID
|
||||||
|
as a convenience to scripts, which in effect also allow
|
||||||
|
.Cm reload:'kill -HUP $MAINPID'
|
||||||
|
.It Cm stop:'script [args]'
|
||||||
|
Some services may require alternate methods to be stopped. When
|
||||||
|
.Cm stop:script
|
||||||
|
is defined it is preferred over SIGTERM and stop, for
|
||||||
|
.Cm service
|
||||||
|
and
|
||||||
|
.Cm sysv
|
||||||
|
directives, respectively.
|
||||||
|
Similar to
|
||||||
|
.Cm reload:script ,
|
||||||
|
.Nm finit
|
||||||
|
sets
|
||||||
|
.Cm $MAINPID .
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
When stopping a service (run/task/sysv/service), either manually or when
|
When stopping a service (run/task/sysv/service), either manually or when
|
||||||
@@ -339,52 +471,61 @@ e.g.,
|
|||||||
.Cm kill:10
|
.Cm kill:10
|
||||||
to wait 10 seconds before sending SIGKILL.
|
to wait 10 seconds before sending SIGKILL.
|
||||||
.Pp
|
.Pp
|
||||||
Services support the
|
Services, including the
|
||||||
.Cm pre:script
|
.Cm sysv
|
||||||
and
|
variant, support pre/post/ready and cleanup scripts:
|
||||||
.Cm post:script
|
.Bl -tag -width 1n
|
||||||
command actions as well. These run as the same
|
.It Cm pre:[0-3600,]script
|
||||||
|
called before the sysv/service is stated
|
||||||
|
.It Cm post:[0-3600,]script
|
||||||
|
called after the sysv/service has stopped
|
||||||
|
.It Cm ready:[0-3600,]script
|
||||||
|
called when the sysv/service is ready
|
||||||
|
.It Cm cleanup:[0-3600,]script
|
||||||
|
called when run/task/sysv/service is removed
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
The optional number (0-3600) is the timeout before Finit kills the
|
||||||
|
script, it defaults to the kill delay value and can be disabled by
|
||||||
|
setting it to zero. These scripts run as the same
|
||||||
.Cm @USER:GROUP
|
.Cm @USER:GROUP
|
||||||
as the service itself, with any
|
as the service itself, with any
|
||||||
.Cm env:file
|
.Cm env:file
|
||||||
sourced. The scripts must use an absolute path, but are executed from
|
sourced. The scripts must use an absolute path, but are executed from
|
||||||
the
|
the
|
||||||
.Cm $HOME
|
.Cm $HOME
|
||||||
of the given user. The scripts are not called with any argument
|
of the given user. The scripts are not called with any argument, but
|
||||||
(currently), but both get the
|
both get a set of environment variables:
|
||||||
.Cm SERVICE_IDENT=foo
|
.Pp
|
||||||
environment variable set. Here
|
.Bl -tag -width 1n -compact
|
||||||
.Cm foo
|
.It Cm SERVICE_IDENT=foo:1
|
||||||
denotes the identity of the service, which if there are multiple
|
.It Cm SERVICE_NAME=foo
|
||||||
services named
|
.It Cm SERVICE_ID=1
|
||||||
.Cm foo ,
|
.El
|
||||||
may be
|
.Pp
|
||||||
.Cm foo:1 ,
|
The
|
||||||
or any unique identifier specified in the .conf file. The
|
|
||||||
.Cm post:script
|
.Cm post:script
|
||||||
is called with an additional set of environment variables:
|
is called with an additional set of environment variables, and yes the
|
||||||
|
naming looks like it should be swapped:
|
||||||
.Bl -tag -offset indent -width 1n
|
.Bl -tag -offset indent -width 1n
|
||||||
.It Cm EXIT_CODE=[exited,signal]
|
.It Cm EXIT_CODE=[exited,signal,crashed]
|
||||||
set to one of
|
set to one of
|
||||||
.Cm exited
|
.Cm exited ,
|
||||||
|
.Cm signal ,
|
||||||
or
|
or
|
||||||
.Cm signal
|
.Cm crashed
|
||||||
|
(see above).
|
||||||
.It Cm EXIT_STATUS=[num,SIGNAME]
|
.It Cm EXIT_STATUS=[num,SIGNAME]
|
||||||
set to one of exit status code from the program, if it exited normally,
|
set to one of exit status code from the program, if it exited normally,
|
||||||
or the signal name (HUP, TERM, etc.) if it exited due to signal
|
or the signal name (HUP, TERM, etc.) if it exited due to signal
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The scripts have a default execution time of 3 seconds before they are
|
When a run/task/sys/service is removed (disable + reload) it is first
|
||||||
SIGKILLed, this can be adjusted using the
|
stopped and then removed from the runlevel. The
|
||||||
.Cm kill:SEC
|
.Cm post:script
|
||||||
modifier syntax.
|
always runs when the process has stopped, and the
|
||||||
.Pp
|
.Cm cleanup:script
|
||||||
.Sy Note:
|
runs when the the stanza has been removed from the runlevel.
|
||||||
the
|
|
||||||
.Cm pre:script
|
|
||||||
.Em must
|
|
||||||
be idempotent, because a service can transition between READY and HALTED
|
|
||||||
states any number of times before going to RUNNING.
|
|
||||||
.It Cm runparts Aq DIR
|
.It Cm runparts Aq DIR
|
||||||
Call
|
Call
|
||||||
.Xr run-parts 8
|
.Xr run-parts 8
|
||||||
@@ -431,7 +572,7 @@ size limit is reached.
|
|||||||
.It Cm tty Oo LVLS Oc Ao COND Ac Ar DEV Oo BAUD Oc Oo noclear Oc Oo nowait Oc Oo nologin Oc Oo TERM Oc
|
.It Cm tty Oo LVLS Oc Ao COND Ac Ar DEV Oo BAUD Oc Oo noclear Oc Oo nowait Oc Oo nologin Oc Oo TERM Oc
|
||||||
This form of the
|
This form of the
|
||||||
.Cm tty
|
.Cm tty
|
||||||
stanza uses the built-in getty on the given TTY device
|
directive uses the built-in getty on the given TTY device
|
||||||
.Ar DEV ,
|
.Ar DEV ,
|
||||||
in the given runlevels.
|
in the given runlevels.
|
||||||
.Ar DEV may be the special keyword
|
.Ar DEV may be the special keyword
|
||||||
@@ -441,8 +582,8 @@ useful on embedded systems.
|
|||||||
.Pp
|
.Pp
|
||||||
The default baud rate is 0, i.e., keep kernel default.
|
The default baud rate is 0, i.e., keep kernel default.
|
||||||
.Pp
|
.Pp
|
||||||
The `tty` stanza inherits runlevel, condition (and other feature)
|
The `tty` directive inherits runlevel, condition (and other feature)
|
||||||
parsing from the `service` stanza. So TTYs can run in one or many
|
parsing from the `service` directive. So TTYs can run in one or many
|
||||||
runlevels and depend on any condition supported by Finit. This is
|
runlevels and depend on any condition supported by Finit. This is
|
||||||
useful e.g. to depend on `<pid/elogind>` before starting a TTY.
|
useful e.g. to depend on `<pid/elogind>` before starting a TTY.
|
||||||
.Bd -unfilled -offset indent
|
.Bd -unfilled -offset indent
|
||||||
@@ -451,7 +592,7 @@ tty [12345] /dev/ttyAMA0 115200 noclear vt220
|
|||||||
.It Cm tty Oo LVLS Oc Ao COND Ac Ar CMD DEV Oo noclear Oc Oo nowait Oc
|
.It Cm tty Oo LVLS Oc Ao COND Ac Ar CMD DEV Oo noclear Oc Oo nowait Oc
|
||||||
This form of the
|
This form of the
|
||||||
.Cm tty
|
.Cm tty
|
||||||
stanza is for using an external getty, like agetty or the BusyBox getty.
|
directive is for using an external getty, like agetty or the BusyBox getty.
|
||||||
.Pp
|
.Pp
|
||||||
By default, these first two syntax variants
|
By default, these first two syntax variants
|
||||||
.Em clear
|
.Em clear
|
||||||
@@ -521,7 +662,7 @@ board bringup and system debugging it can come in handy.
|
|||||||
.Pp
|
.Pp
|
||||||
One can also use the
|
One can also use the
|
||||||
.Cm service
|
.Cm service
|
||||||
stanza to start a stand-alone shell:
|
directive to start a stand-alone shell:
|
||||||
.Bd -unfilled -offset indent
|
.Bd -unfilled -offset indent
|
||||||
service [12345] /bin/sh -l
|
service [12345] /bin/sh -l
|
||||||
.Ed
|
.Ed
|
||||||
@@ -546,9 +687,9 @@ is started to present a bare-bones root login prompt. If the root
|
|||||||
(uid:0, gid:0) user does not have a password set, no rescue is possible.
|
(uid:0, gid:0) user does not have a password set, no rescue is possible.
|
||||||
.El
|
.El
|
||||||
.Sh COMMAND MODIFIERS
|
.Sh COMMAND MODIFIERS
|
||||||
The run/task/tty/service/sysv stanzas take modifiers, or options, to
|
The run/task/tty/service/sysv directives take modifiers, or options, to
|
||||||
control their behavior. This section lists them with their limitations.
|
control their behavior. This section lists them with their limitations.
|
||||||
All modifiers must be placed between the stanza and its command.
|
All modifiers must be placed between the directive and its command.
|
||||||
.Bl -tag -width 1n
|
.Bl -tag -width 1n
|
||||||
.It Cm @user:group
|
.It Cm @user:group
|
||||||
Every
|
Every
|
||||||
@@ -603,6 +744,37 @@ is
|
|||||||
and the default
|
and the default
|
||||||
.Cm tag
|
.Cm tag
|
||||||
identity is the basename of the service or run/task command.
|
identity is the basename of the service or run/task command.
|
||||||
|
.It Cm tty:\&<dev>
|
||||||
|
Give the
|
||||||
|
.Cm run , task ,
|
||||||
|
or
|
||||||
|
.Cm service
|
||||||
|
a controlling terminal on
|
||||||
|
.Cm <dev> .
|
||||||
|
The device is opened, set as the controlling terminal for the session
|
||||||
|
(after
|
||||||
|
.Fn setsid ) ,
|
||||||
|
and connected to stdin, stdout, and stderr.
|
||||||
|
A default
|
||||||
|
.Ev TERM
|
||||||
|
variable is set based on the device type:
|
||||||
|
.Cm vt102
|
||||||
|
for serial lines and
|
||||||
|
.Cm linux
|
||||||
|
for virtual terminals.
|
||||||
|
.Cm <dev>
|
||||||
|
may be a device node like
|
||||||
|
.Pa /dev/ttyS0 ,
|
||||||
|
or the special keyword
|
||||||
|
.Cm @console
|
||||||
|
(see TTYs and Consoles above).
|
||||||
|
When combined with
|
||||||
|
.Cm log: ,
|
||||||
|
stdout and stderr are redirected to the log sink instead, but stdin
|
||||||
|
remains connected to the TTY device.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service [2345] tty:/dev/ttyS0 /usr/sbin/foo -- Foo on serial console
|
||||||
|
.Ed
|
||||||
.El
|
.El
|
||||||
.Sh RESCUE MODE
|
.Sh RESCUE MODE
|
||||||
Finit supports a rescue mode which is activated by the
|
Finit supports a rescue mode which is activated by the
|
||||||
@@ -753,6 +925,31 @@ the example sets
|
|||||||
to denote that it doesn't support SIGHUP. That way Finit will
|
to denote that it doesn't support SIGHUP. That way Finit will
|
||||||
stop/start the service instead of sending SIGHUP at restart/reload
|
stop/start the service instead of sending SIGHUP at restart/reload
|
||||||
events.
|
events.
|
||||||
|
.Sh TEMPLATING
|
||||||
|
Finit comes with rudimentary support for templating, similar to that of
|
||||||
|
systemd. Best illustrated with an example:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
$ initctl show avahi-autoipd@
|
||||||
|
service :%i avahi-autoipd --syslog %i -- ZeroConf for %i
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
To enable ZeroConf for, e.g.,
|
||||||
|
.Cm eth0 ,
|
||||||
|
use
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
$ initctl enable avahi-autoipd@eth0.conf
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The enabled symlink will be set up to
|
||||||
|
.Cm avahi-autoipd@.conf
|
||||||
|
and every instance of
|
||||||
|
.Cm %i
|
||||||
|
will in the instantiated directive be replaced with
|
||||||
|
.Cm eth0 .
|
||||||
|
Inspect the result with:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
$ initctl status avahi-autoipd:eth0
|
||||||
|
.Ed
|
||||||
.Sh CGROUPS
|
.Sh CGROUPS
|
||||||
There are three major cgroup configuration directives:
|
There are three major cgroup configuration directives:
|
||||||
.Pp
|
.Pp
|
||||||
@@ -817,9 +1014,10 @@ or
|
|||||||
service [...] <...> cgroup.maint /path/to/foo args -- description
|
service [...] <...> cgroup.maint /path/to/foo args -- description
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
The latter form also allows per-stanza limits on the form:
|
The latter form also allows per-stanza limits on the form (notice the
|
||||||
|
single quotes for arguments that contain spaces):
|
||||||
.Bd -unfilled -offset indent
|
.Bd -unfilled -offset indent
|
||||||
service [...] <...> cgroup.maint:cpu.max:10000,mem.max:655360 /path/to/foo args -- description
|
service [...] <...> cgroup.maint:cpu.max:'200000 100000',mem.max:655360 /path/to/foo args -- description
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
Notice the comma separation and the
|
Notice the comma separation and the
|
||||||
@@ -839,6 +1037,97 @@ available in your Linux kernel, or the name is misspelled.
|
|||||||
Linux cgroups and details surrounding values are not explained in the
|
Linux cgroups and details surrounding values are not explained in the
|
||||||
Finit documentation. The Linux admin-guide cover this well:
|
Finit documentation. The Linux admin-guide cover this well:
|
||||||
.Lk https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
|
.Lk https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
|
||||||
|
.Sh CONDITIONAL LOADING
|
||||||
|
Finit support conditional loading of stanzas. The following example is
|
||||||
|
take from the
|
||||||
|
.Pa system/hotplug.conf
|
||||||
|
file in the Finit distribution. Here we only show a simplified subset.
|
||||||
|
.Pp
|
||||||
|
Starting with the
|
||||||
|
.Cm nowarn
|
||||||
|
option.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
service nowarn name:udevd pid:udevd /lib/systemd/systemd-udevd
|
||||||
|
service nowarn name:udevd pid:udevd udevd
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
When loading the .conf file Finit looks for
|
||||||
|
.Pa /lib/systemd/systemd-udevd
|
||||||
|
if that is not found Finit automatically logs a warning. The
|
||||||
|
.Cm nowarn
|
||||||
|
option disables this warning so that the second line can be evaluated,
|
||||||
|
which also provides a service named
|
||||||
|
.Cm udevd .
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
run nowarn if:udevd <pid/udevd> :1 udevadm settle -t 0
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
This line is only loaded if we know of a service named
|
||||||
|
.Cm udevd .
|
||||||
|
Again, we do not warn if
|
||||||
|
.Cm udevadm
|
||||||
|
is not found, execution will also stop here until the PID condition is
|
||||||
|
asserted, i.e., Finit detecting udevd has started.
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
run nowarn conflict:udevd [S] mdev -s -- Populating device tree
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
If
|
||||||
|
.Cm udevd
|
||||||
|
is not available, we try to run
|
||||||
|
.Cm mdev ,
|
||||||
|
but if that is not found, again we do not warn.
|
||||||
|
.Pp
|
||||||
|
Conditional loading statements can also be negated, so the previous stanza
|
||||||
|
can also be written as:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
run nowarn if:!udevd [S] mdev -s -- Populating device tree
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The reason for using
|
||||||
|
.Cm conflict
|
||||||
|
in this example is that a conflict can be resolved. Stanzas marked with
|
||||||
|
.C, conflict:foo
|
||||||
|
are rechecked at runtime.
|
||||||
|
.Sh CONDITIONAL EXECUTION
|
||||||
|
Similar to conditional loading of stanzas there is conditional runtime
|
||||||
|
execution. This can be confusing at first, since Finit already has a
|
||||||
|
condition subsystem, but this is more akin to the qualification to a
|
||||||
|
runlevel. E.g., a
|
||||||
|
.Cm task [123]
|
||||||
|
is qualified to run only in runlevel 1, 2, and 3. It is not considered
|
||||||
|
for other runlevels.
|
||||||
|
.Pp
|
||||||
|
Conditional execution qualify a run/task/service based on a condition.
|
||||||
|
Consider this (simplified) example from the Infix operating system:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
run [S] name:startup <pid/sysrepo> confd -b --load startup-config
|
||||||
|
run [S] if:<usr/fail-startup> name:failure <pid/sysrepo> confd --load failure-config
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
The two run statements reside in the same .conf file so Finit runs them
|
||||||
|
in true sequence. If loading the file
|
||||||
|
.Cm startup-config
|
||||||
|
fails
|
||||||
|
.Cm confd
|
||||||
|
sets the condition
|
||||||
|
.Cm usr/fail-startup ,
|
||||||
|
thus allowing the next run statement to load
|
||||||
|
.Cm failure-config .
|
||||||
|
.Pp
|
||||||
|
Notice the critical difference between the
|
||||||
|
.Cm <pid/sysrepo>
|
||||||
|
condition and
|
||||||
|
.Cm if:<usr/fail-startup> .
|
||||||
|
The former is a condition for starting and the latter is a condition to
|
||||||
|
check if a run/task/service is qualified to even be considered.
|
||||||
|
.Pp
|
||||||
|
Conditional execution statements can also be negated, so provided the
|
||||||
|
file loaded did the opposite, i.e., set a condition on success, the
|
||||||
|
previous stanza can also be written as:
|
||||||
|
.Bd -unfilled -offset indent
|
||||||
|
run [S] if:<!usr/startup-ok> name:failure <pid/sysrepo> confd ...
|
||||||
|
.Ed
|
||||||
.Sh LIMITATIONS
|
.Sh LIMITATIONS
|
||||||
As of Finit v4 there are no limitations to where
|
As of Finit v4 there are no limitations to where
|
||||||
.Cm .conf
|
.Cm .conf
|
||||||
@@ -869,6 +1158,6 @@ settings in
|
|||||||
.Xr finit 8 ,
|
.Xr finit 8 ,
|
||||||
.Xr initctl 8
|
.Xr initctl 8
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.Nm finit
|
.Nm Finit
|
||||||
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
|
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
|
||||||
maintained by Joachim Wiberg, with contributions by many others.
|
maintained by Joachim Wiberg, with contributions by many others.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
.\" First parameter, NAME, should be all caps
|
.\" First parameter, NAME, should be all caps
|
||||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
.\" other parameters are allowed: see man(7), man(1)
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
.Dd June 6, 2021
|
.Dd July 10, 2025
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
.Dt INITCTL 8 SMM
|
.Dt INITCTL 8 SMM
|
||||||
.Os Linux
|
.Os Linux
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
.Nd Control tool for Finit
|
.Nd Control tool for Finit
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm /sbin/initctl
|
.Nm /sbin/initctl
|
||||||
.Op Fl bcfhlpqtvV
|
.Op Fl bcfhjlpqtvV
|
||||||
.Op COMMAND
|
.Op COMMAND
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
@@ -24,25 +24,39 @@ This program follows the usual UNIX command line syntax, with long
|
|||||||
options starting with two dashes (`-'). The options are as follows:
|
options starting with two dashes (`-'). The options are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Fl b, -batch
|
.It Fl b, -batch
|
||||||
Batch mode, no screen size probing.
|
Batch mode, no screen size probing. Useful for scripting
|
||||||
.It Fl c, -create
|
.It Fl c, -create
|
||||||
Create missing paths (and files) as needed. Useful with the edit command.
|
Create missing paths (and files) as needed. Useful with the
|
||||||
|
.Cm edit
|
||||||
|
command
|
||||||
.It Fl f, -force
|
.It Fl f, -force
|
||||||
Ignore missing files and arguments, never prompt.
|
Ignore missing files and arguments, never prompt
|
||||||
.It Fl h, -help
|
.It Fl h, -help
|
||||||
Show built-in help text.
|
Show built-in help text
|
||||||
|
.It Fl j, -json
|
||||||
|
JSON output in
|
||||||
|
.Ar status
|
||||||
|
and
|
||||||
|
.Ar cond
|
||||||
|
commands
|
||||||
|
.It Fl n, -noerr
|
||||||
|
When scripting
|
||||||
|
.Nm
|
||||||
|
to stop, start, restart, or signal a task or service, this option can be
|
||||||
|
used to ignore error 69 (no such task or service) and instead return 0
|
||||||
|
(OK)
|
||||||
.It Fl 1, -once
|
.It Fl 1, -once
|
||||||
Only one lap in commands like top.
|
Only one lap in commands like top
|
||||||
.It Fl p, -plain
|
.It Fl p, -plain
|
||||||
Use plain table headings, no ANSI control characters.
|
Use plain table headings, no ANSI control characters
|
||||||
.It Fl q, -quiet
|
.It Fl q, -quiet
|
||||||
Silent, only return status of command.
|
Silent, only return status of command
|
||||||
.It Fl t, -no-heading
|
.It Fl t, -no-heading
|
||||||
Skip table headings.
|
Skip table headings
|
||||||
.It Fl v, -verbose
|
.It Fl v, -verbose
|
||||||
Verbose output, where applicable.
|
Verbose output, where applicable
|
||||||
.It Fl V, -version
|
.It Fl V, -version
|
||||||
Show program version.
|
Show program version
|
||||||
.El
|
.El
|
||||||
.Sh COMMANDS
|
.Sh COMMANDS
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
@@ -64,7 +78,16 @@ files in
|
|||||||
Create
|
Create
|
||||||
.Cm .conf
|
.Cm .conf
|
||||||
in
|
in
|
||||||
.Pa /etc/finit.d/available
|
.Pa /etc/finit.d/available .
|
||||||
|
.Pp
|
||||||
|
Piping the contents into
|
||||||
|
.Nm
|
||||||
|
works as one would expect:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
echo "task name:foo /tmp/foo.sh -- Foo logger" | initctl create foo
|
||||||
|
initctl enable foo
|
||||||
|
initctl reload
|
||||||
|
.Ed
|
||||||
.It Nm Ar delete Ar CONF
|
.It Nm Ar delete Ar CONF
|
||||||
Delete
|
Delete
|
||||||
.Cm .conf
|
.Cm .conf
|
||||||
@@ -89,9 +112,10 @@ like
|
|||||||
.Ar edit
|
.Ar edit
|
||||||
this tells
|
this tells
|
||||||
.Nm finit
|
.Nm finit
|
||||||
that a configuration has been changed and is a candidate to be restarted
|
that a configuration has been changed and is a candidate to be reloaded
|
||||||
(or SIGHUP'ed) on
|
(SIGHUP'ed or restarted) on
|
||||||
.Cm initctl reload
|
.Cm initctl reload
|
||||||
|
in dependency order
|
||||||
.It Nm Ar enable Ar CONF
|
.It Nm Ar enable Ar CONF
|
||||||
Enable
|
Enable
|
||||||
.Cm .conf
|
.Cm .conf
|
||||||
@@ -106,22 +130,40 @@ in
|
|||||||
.Pa /etc/finit.d/enabled ,
|
.Pa /etc/finit.d/enabled ,
|
||||||
i.e., removes symlink
|
i.e., removes symlink
|
||||||
.It Nm Ar reload
|
.It Nm Ar reload
|
||||||
Reload
|
Reload all (touched)
|
||||||
.Cm *.conf in
|
.Cm *.conf in
|
||||||
.Pa /etc/finit.d ,
|
.Pa /etc/finit.d
|
||||||
i.e., activates changes
|
and activate changes
|
||||||
.It Nm Ar cond set Ar COND
|
.It Nm Ar cond set Ar COND Op COND ...
|
||||||
Set (assert) user-defined condition,
|
Set (assert) user-defined condition,
|
||||||
.Cm +usr/COND
|
.Cm +usr/COND
|
||||||
.It Nm Ar cond clr | clear Ar COND
|
.It Nm Ar cond get Ar COND
|
||||||
|
Get (quietly) the status of any condition. Defaults to user-defined
|
||||||
|
condions, but if a slash is detected, e.g.,
|
||||||
|
.Cm pid/foo
|
||||||
|
or
|
||||||
|
.Cm net/eth0/exist ,
|
||||||
|
then any condition can be read.
|
||||||
|
.Pp
|
||||||
|
The command is geared for scripting, check the exit code to get the
|
||||||
|
status of the condition: 0 - on, 1 - off, 255 - flux. For a more
|
||||||
|
verbose output, use the
|
||||||
|
.Fl v
|
||||||
|
option
|
||||||
|
.It Nm Ar cond clr | clear Ar COND Op COND ...
|
||||||
Clear (deassert) user-defined condition,
|
Clear (deassert) user-defined condition,
|
||||||
.Cm -usr/COND
|
.Cm -usr/COND
|
||||||
.It Nm Ar cond status
|
.It Nm Ar cond status
|
||||||
Show condition status, default
|
Show condition status, default
|
||||||
.Cm cond
|
.Cm cond
|
||||||
command.
|
command. Also supports the
|
||||||
.It Nm Ar cond dump
|
.Fl j
|
||||||
Dump all conditions and their status
|
option for detailed JSON output
|
||||||
|
.It Nm Ar cond dump Op Cm TYPE
|
||||||
|
Dump all, or a given type of, conditions and their status. Also
|
||||||
|
supports the
|
||||||
|
.Fl j
|
||||||
|
option for detailed JSON output
|
||||||
.It Nm Ar ident Op Cm NAME
|
.It Nm Ar ident Op Cm NAME
|
||||||
Display indentities of all run/task/services, or only instances
|
Display indentities of all run/task/services, or only instances
|
||||||
matching
|
matching
|
||||||
@@ -139,49 +181,93 @@ Start service by name, with optional ID, e.g.,
|
|||||||
.It Nm Ar stop Cm NAME[:ID]
|
.It Nm Ar stop Cm NAME[:ID]
|
||||||
Stop/Pause a running service by name
|
Stop/Pause a running service by name
|
||||||
.It Nm Ar reload Cm NAME[:ID]
|
.It Nm Ar reload Cm NAME[:ID]
|
||||||
Reload service by name (SIGHUP or restart)
|
Reload service as if its configuration had changed. Internally,
|
||||||
.It Nm Ar signal Cm NAME:[ID] S
|
.Nm finit
|
||||||
|
marks the named service as "dirty" and turns the state machine,
|
||||||
|
resulting in a SIGHUP or restart of (at least) the named service.
|
||||||
|
Any dependant services are also restarted.
|
||||||
|
.Pp
|
||||||
|
.Sy Note:
|
||||||
|
no .conf file is reloaded with this variant of the command. Essentially
|
||||||
|
it is the same as calling
|
||||||
|
.Cm restart .
|
||||||
|
Except for two things:
|
||||||
|
.Bl -enum -offset indent -compact
|
||||||
|
.It
|
||||||
|
if the service supports HUP (or has a
|
||||||
|
.Cm reload:script )
|
||||||
|
it is signaled instead of stop-started, and
|
||||||
|
.It
|
||||||
|
it allows restarting run/task in the same runlevel -- which is otherwise
|
||||||
|
restricted
|
||||||
|
.El
|
||||||
|
.It Nm Ar <kill | signal> Cm NAME:[ID] S
|
||||||
Send signal S to service, by name.
|
Send signal S to service, by name.
|
||||||
.Cm S
|
.Cm S
|
||||||
may be a complete signal name such as SIGHUP, or short name such as HUP, or the signal number such as 1 (SIGHUP).
|
may be a complete signal name such as SIGHUP, or short name such as HUP, or the signal number such as 1 (SIGHUP)
|
||||||
.It Nm Ar restart Cm NAME[:ID]
|
.It Nm Ar restart Cm NAME[:ID]
|
||||||
Restart (stop/start) service by name
|
Restart (stop/start) service by name
|
||||||
.It Nm Ar status Cm NAME[:ID]
|
.It Nm Ar status Cm NAME[:ID]
|
||||||
Show service status, by name. If only
|
Show service status, by name. If only
|
||||||
.Cm NAME
|
.Cm NAME
|
||||||
is given and multiple instances exits, a summary of all matching
|
is given and multiple instances exits, a summary of all matching
|
||||||
instances are shown. Only an exact match displays the detailed status
|
instances are shown. Only an exact match displays detailed status
|
||||||
for a particular instance
|
for a given instance.
|
||||||
|
.Pp
|
||||||
|
With the
|
||||||
|
.Fl q
|
||||||
|
option this command is silent, provided the
|
||||||
|
.Ar NAME[:ID]
|
||||||
|
selection matches a single run/task/service. The exit code of
|
||||||
|
.Nm
|
||||||
|
is non-zero if there is a problem. Zero is returned if a run/task has
|
||||||
|
run (at least) once in the current runlevel, and when a service is running
|
||||||
|
(as expected). See the
|
||||||
|
.Fl j
|
||||||
|
option for detailed JSON output suitable for machine parsing.
|
||||||
|
.Pp
|
||||||
|
.Sy Tip:
|
||||||
|
.Xr jq 1
|
||||||
|
is a useful scripting tool in combination with JSON output
|
||||||
.It Nm Ar status
|
.It Nm Ar status
|
||||||
Show status of all services, default command
|
Show status of all services, default command. Also supports the
|
||||||
|
.Fl j
|
||||||
|
option for detailed JSON output
|
||||||
.It Nm Ar cgroup
|
.It Nm Ar cgroup
|
||||||
List cgroup config overview
|
List cgroup config overview
|
||||||
.It Nm Ar ps
|
.It Nm Ar ps
|
||||||
List processes based on cgroups
|
List processes based on cgroups
|
||||||
.It Nm Ar top
|
.It Nm Ar top
|
||||||
Show top-like listing based on cgroups
|
Show top-like listing based on cgroups
|
||||||
|
.It Nm Ar plugins
|
||||||
|
List installed plugins
|
||||||
.It Nm Ar runlevel Op Ar 0-9
|
.It Nm Ar runlevel Op Ar 0-9
|
||||||
Show or set runlevel: 0 halt, 6 reboot
|
Show or set runlevel: 0 halt, 6 reboot.
|
||||||
|
.Pp
|
||||||
|
If called at boot (runlevel S) to set the runlevel, Finit only schedules
|
||||||
|
the change, effectively overriding the configured runlevel from
|
||||||
|
.Pa /etc/finit.conf .
|
||||||
|
Useful to trigger a fail-safe mode, or similar
|
||||||
.It Nm Ar reboot
|
.It Nm Ar reboot
|
||||||
Reboot system, default if
|
Reboot system, default if
|
||||||
.Cm reboot
|
.Cm reboot
|
||||||
is symlinked to
|
is symlinked to
|
||||||
.Nm
|
.Nm
|
||||||
.It Nm Ar halt
|
.It Nm Ar halt
|
||||||
Halt system, default if
|
Halt system, default if
|
||||||
.Cm halt
|
.Cm halt
|
||||||
is symlinked to
|
is symlinked to
|
||||||
.Nm
|
.Nm
|
||||||
.It Nm Ar poweroff
|
.It Nm Ar poweroff
|
||||||
Power-off system, default if
|
Power-off system, default if
|
||||||
.Cm poweroff
|
.Cm poweroff
|
||||||
is symlinked to
|
is symlinked to
|
||||||
.Nm
|
.Nm
|
||||||
.It Nm Ar suspend
|
.It Nm Ar suspend
|
||||||
Suspend system, default if
|
Suspend system, default if
|
||||||
.Cm suspend
|
.Cm suspend
|
||||||
is symlinked to
|
is symlinked to
|
||||||
.Nm
|
.Nm
|
||||||
.It Nm Ar utmp show
|
.It Nm Ar utmp show
|
||||||
Raw dump of UTMP/WTMP db
|
Raw dump of UTMP/WTMP db
|
||||||
.El
|
.El
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
site_name: ""
|
||||||
|
site_description: Fast Init for Linux Systems
|
||||||
|
site_url: http://finit-project.github.io
|
||||||
|
repo_url: https://github.com/finit-project/finit
|
||||||
|
repo_name: Finit Project
|
||||||
|
copyright: Copyright © 2008-2025 Joachim Wiberg
|
||||||
|
docs_dir: doc/
|
||||||
|
edit_uri: edit/master/doc/
|
||||||
|
extra_css:
|
||||||
|
- extra.css
|
||||||
|
|
||||||
|
exclude_docs: |
|
||||||
|
TODO.md
|
||||||
|
ChangeLog.md
|
||||||
|
|
||||||
|
theme:
|
||||||
|
logo: img/logo.png
|
||||||
|
name: material
|
||||||
|
features:
|
||||||
|
- toc.follow
|
||||||
|
- toc.integrate
|
||||||
|
- navigation.path
|
||||||
|
- navigation.instant
|
||||||
|
- navigation.instant.progress
|
||||||
|
- navigation.tracking
|
||||||
|
- navigation.tabs
|
||||||
|
# - navigation.sections
|
||||||
|
# - navigation.expand
|
||||||
|
# - navigation.top
|
||||||
|
- navigation.footer
|
||||||
|
- search.highlight
|
||||||
|
- search.share
|
||||||
|
# - content.action.edit
|
||||||
|
- content.code.copy
|
||||||
|
- content.code.annotate
|
||||||
|
palette:
|
||||||
|
- media: "(prefers-color-scheme: light)"
|
||||||
|
scheme: default
|
||||||
|
primary: orange
|
||||||
|
accent: orange
|
||||||
|
toggle:
|
||||||
|
icon: material/weather-night
|
||||||
|
name: Switch to dark mode
|
||||||
|
- media: "(prefers-color-scheme: dark)"
|
||||||
|
scheme: slate
|
||||||
|
primary: black
|
||||||
|
accent: black
|
||||||
|
toggle:
|
||||||
|
icon: material/weather-sunny
|
||||||
|
name: Switch to light mode
|
||||||
|
|
||||||
|
nav:
|
||||||
|
- Getting Started:
|
||||||
|
- Introduction: index.md
|
||||||
|
- Features: features.md
|
||||||
|
- Quick Example: example.md
|
||||||
|
- Building: build.md
|
||||||
|
- Configuration:
|
||||||
|
- Overview: config/index.md
|
||||||
|
- Files & Layout: config/files.md
|
||||||
|
- Conditions: conditions.md
|
||||||
|
- Runlevels: config/runlevels.md
|
||||||
|
- One-shot Tasks: config/task-and-run.md
|
||||||
|
- Services:
|
||||||
|
- Syntax: config/services.md
|
||||||
|
- Options: config/service-opts.md
|
||||||
|
- Environment: config/service-env.md
|
||||||
|
- Synchronization: config/service-sync.md
|
||||||
|
- Wrapper Scripts: config/service-wrappers.md
|
||||||
|
- Run-parts Scripts: config/runparts.md
|
||||||
|
- TTY & Console: config/tty.md
|
||||||
|
- Environment Variables: config/env.md
|
||||||
|
- Logging: config/logging.md
|
||||||
|
- Cgroups: config/cgroups.md
|
||||||
|
- Capabilities: config/capabilities.md
|
||||||
|
- Templating: config/templating.md
|
||||||
|
- SysV Compatibility: config/sysv.md
|
||||||
|
- Rescue Mode: config/rescue.md
|
||||||
|
- Limitations: config/limitations.md
|
||||||
|
- Usage:
|
||||||
|
- Commands & Status: initctl.md
|
||||||
|
- Switch Root: switchroot.md
|
||||||
|
- Rebooting & Halting: commands.md
|
||||||
|
- Command Line Options: cmdline.md
|
||||||
|
- Managing Services: service.md
|
||||||
|
- Signals: signals.md
|
||||||
|
- Reference:
|
||||||
|
- Runlevels Overview: runlevels.md
|
||||||
|
- Runparts & rc.local: runparts.md
|
||||||
|
- Plugins: plugins.md
|
||||||
|
- Watchdog: watchdog.md
|
||||||
|
- keventd: keventd.md
|
||||||
|
- Service State Machine: state-machine.md
|
||||||
|
- Distributions: distro.md
|
||||||
|
- Requirements: requirements.md
|
||||||
|
|
||||||
|
markdown_extensions:
|
||||||
|
- admonition
|
||||||
|
- attr_list
|
||||||
|
- pymdownx.details
|
||||||
|
- pymdownx.superfences
|
||||||
|
- pymdownx.highlight:
|
||||||
|
anchor_linenums: true
|
||||||
|
- pymdownx.inlinehilite
|
||||||
|
- pymdownx.snippets
|
||||||
|
- pymdownx.tabbed:
|
||||||
|
alternate_style: true
|
||||||
|
- tables
|
||||||
|
- toc:
|
||||||
|
permalink: true
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
- search
|
||||||
|
- callouts
|
||||||
|
- glightbox
|
||||||
|
|
||||||
|
extra:
|
||||||
|
homepage: https://finit-project.github.io/
|
||||||
|
social:
|
||||||
|
- icon: fontawesome/brands/github
|
||||||
|
link: https://github.com/finit-project/finit
|
||||||
|
name: Finit on GitHub
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
pkglibdir = $(plugin_path)
|
pkglibdir = $(plugin_path)
|
||||||
AM_LDFLAGS = -module -avoid-version -shared
|
AM_LDFLAGS = -module -avoid-version -shared
|
||||||
AM_CFLAGS = -W -Wall -Wextra -Wno-unused-parameter -std=gnu99
|
AM_CFLAGS = -W -Wall -Wextra -Wno-unused-parameter -std=gnu99
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/src -U_FORTIFY_SOURCE
|
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||||
AM_CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE -D_DEFAULT_SOURCE
|
AM_CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE -D_DEFAULT_SOURCE
|
||||||
AM_CPPFLAGS += $(lite_CFLAGS) $(uev_CFLAGS)
|
AM_CPPFLAGS += -D__FINIT__ $(lite_CFLAGS) $(uev_CFLAGS)
|
||||||
|
|
||||||
if STATIC
|
if STATIC
|
||||||
noinst_LTLIBRARIES = libplug.la
|
noinst_LTLIBRARIES = libplug.la
|
||||||
@@ -17,10 +17,6 @@ if BUILD_DBUS_PLUGIN
|
|||||||
libplug_la_SOURCES += dbus.c
|
libplug_la_SOURCES += dbus.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_HOTPLUG_PLUGIN
|
|
||||||
libplug_la_SOURCES += hotplug.c
|
|
||||||
endif
|
|
||||||
|
|
||||||
if BUILD_MODULES_LOAD_PLUGIN
|
if BUILD_MODULES_LOAD_PLUGIN
|
||||||
libplug_la_SOURCES += modules-load.c
|
libplug_la_SOURCES += modules-load.c
|
||||||
endif
|
endif
|
||||||
@@ -33,6 +29,10 @@ if BUILD_NETLINK_PLUGIN
|
|||||||
libplug_la_SOURCES += netlink.c
|
libplug_la_SOURCES += netlink.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILD_PLYMOUTH_PLUGIN
|
||||||
|
libplug_la_SOURCES += plymouth.c
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_RESOLVCONF_PLUGIN
|
if BUILD_RESOLVCONF_PLUGIN
|
||||||
libplug_la_SOURCES += resolvconf.c
|
libplug_la_SOURCES += resolvconf.c
|
||||||
endif
|
endif
|
||||||
@@ -68,10 +68,6 @@ if BUILD_HOOK_SCRIPTS_PLUGIN
|
|||||||
pkglib_LTLIBRARIES += hook-scripts.la
|
pkglib_LTLIBRARIES += hook-scripts.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if BUILD_HOTPLUG_PLUGIN
|
|
||||||
pkglib_LTLIBRARIES += hotplug.la
|
|
||||||
endif
|
|
||||||
|
|
||||||
if BUILD_MODULES_LOAD_PLUGIN
|
if BUILD_MODULES_LOAD_PLUGIN
|
||||||
pkglib_LTLIBRARIES += modules-load.la
|
pkglib_LTLIBRARIES += modules-load.la
|
||||||
endif
|
endif
|
||||||
@@ -84,6 +80,10 @@ if BUILD_NETLINK_PLUGIN
|
|||||||
pkglib_LTLIBRARIES += netlink.la
|
pkglib_LTLIBRARIES += netlink.la
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if BUILD_PLYMOUTH_PLUGIN
|
||||||
|
pkglib_LTLIBRARIES += plymouth.la
|
||||||
|
endif
|
||||||
|
|
||||||
if BUILD_RESOLVCONF_PLUGIN
|
if BUILD_RESOLVCONF_PLUGIN
|
||||||
pkglib_LTLIBRARIES += resolvconf.la
|
pkglib_LTLIBRARIES += resolvconf.la
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Save and restore ALSA sound settings using alsactl
|
/* Save and restore ALSA sound settings using alsactl
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2025 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -27,21 +27,23 @@
|
|||||||
# include <lite/lite.h>
|
# include <lite/lite.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "conf.h"
|
||||||
#include "finit.h"
|
#include "finit.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#define ALSACTL "alsactl"
|
#define ALSACTL "alsactl"
|
||||||
|
|
||||||
static void save(void *arg)
|
static void save(void *arg)
|
||||||
{
|
{
|
||||||
if (rescue) {
|
if (rescue) {
|
||||||
_d("Skipping %s plugin in rescue mode.", __FILE__);
|
dbg("Skipping %s plugin in rescue mode.", "alsa-utils");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (whichp(ALSACTL)) {
|
if (whichp(ALSACTL)) {
|
||||||
_d("Saving sound settings ...");
|
dbg("Saving sound settings ...");
|
||||||
run_interactive(ALSACTL " -g store", "Saving sound settings");
|
run_interactive(ALSACTL " -g store", "Saving sound settings");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,28 +51,28 @@ static void save(void *arg)
|
|||||||
static void restore(void *arg)
|
static void restore(void *arg)
|
||||||
{
|
{
|
||||||
if (rescue) {
|
if (rescue) {
|
||||||
_d("Skipping %s plugin in rescue mode.", __FILE__);
|
dbg("Skipping %s plugin in rescue mode.", "alsa-utils");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (whichp(ALSACTL)) {
|
if (whichp(ALSACTL)) {
|
||||||
_d("Restoring sound settings ...");
|
dbg("Restoring sound settings ...");
|
||||||
run_interactive(ALSACTL " -g restore", "Restoring sound settings");
|
run_interactive(ALSACTL " -g restore", "Restoring sound settings");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
.name = __FILE__,
|
.name = "alsa-utils",
|
||||||
.hook[HOOK_BASEFS_UP] = { .cb = restore },
|
.hook[HOOK_BASEFS_UP] = { .cb = restore },
|
||||||
.hook[HOOK_SHUTDOWN] = { .cb = save }
|
.hook[HOOK_SHUTDOWN] = { .cb = save }
|
||||||
};
|
};
|
||||||
|
|
||||||
PLUGIN_INIT(plugin_init)
|
PLUGIN_INIT(__init)
|
||||||
{
|
{
|
||||||
plugin_register(&plugin);
|
plugin_register(&plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(__exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
plugin_unregister(&plugin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Setup necessary system files for, e.g. UTMP (tracking logins)
|
/* Setup necessary system files for, e.g. UTMP (tracking logins)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2025 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utmp-api.h"
|
#include "utmp-api.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
static int is_tmpfs(char *path)
|
static int is_tmpfs(char *path)
|
||||||
{
|
{
|
||||||
@@ -80,7 +81,7 @@ static int bootclean(const char *fpath, const struct stat *sb, int tflag, struct
|
|||||||
if (ftw->level == 0)
|
if (ftw->level == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
_d("Removing %s ...", fpath);
|
dbg("Removing %s ...", fpath);
|
||||||
(void)remove(fpath);
|
(void)remove(fpath);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -110,10 +111,43 @@ static void clean(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ln(const char *target, const char *linkpath)
|
/* Kernel defines the following compulsory and recommended links
|
||||||
|
* https://github.com/torvalds/linux/blob/v5.18/Documentation/admin-guide/devices.rst#compulsory-links
|
||||||
|
*/
|
||||||
|
static void kernel_links(void)
|
||||||
{
|
{
|
||||||
if (symlink(target, linkpath) && errno != EEXIST)
|
struct {
|
||||||
_pe("Failed creating %s -> %s symlink", target, linkpath);
|
char *tgt, *lnk;
|
||||||
|
int optional;
|
||||||
|
} k[] = {
|
||||||
|
{ "/proc/self/fd", "/dev/fd", 0 },
|
||||||
|
{ "fd/0", "/dev/stdin", 0 },
|
||||||
|
{ "fd/1", "/dev/stdout", 0 },
|
||||||
|
{ "fd/2", "/dev/stderr", 0 },
|
||||||
|
{ "socksys", "/dev/nfsd", 0 },
|
||||||
|
{ "null", "/dev/X0R", 0 },
|
||||||
|
{ "/proc/kcore", "/dev/core", 1 },
|
||||||
|
{ "ram0", "/dev/ramdisk", 1 },
|
||||||
|
{ "qft0", "/dev/ftape", 1 },
|
||||||
|
{ "video0", "/dev/bttv0", 1 },
|
||||||
|
{ "radio0", "/dev/radio", 1 },
|
||||||
|
};
|
||||||
|
char *fn, buf[80];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < NELEMS(k); i++) {
|
||||||
|
fn = k[i].tgt;
|
||||||
|
|
||||||
|
if (k[i].optional) {
|
||||||
|
if (fn[0] != '/') {
|
||||||
|
snprintf(buf, sizeof(buf), "/dev/%s", k[i].tgt);
|
||||||
|
fn = buf;
|
||||||
|
}
|
||||||
|
if (!fexist(fn))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ln(k[i].tgt, k[i].lnk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -125,103 +159,31 @@ static void setup(void *arg)
|
|||||||
|
|
||||||
prev = umask(0);
|
prev = umask(0);
|
||||||
|
|
||||||
_d("Setting up FHS structure in /var ...");
|
/* Kernel symlinks, e.g. /proc/self/fd -> /dev/fd */
|
||||||
makedir("/var/cache", 0755);
|
kernel_links();
|
||||||
makedir("/var/db", 0755); /* _PATH_VARDB on some systems */
|
|
||||||
makedir("/var/games", 0755);
|
|
||||||
makedir("/var/lib", 0755);
|
|
||||||
makedir("/var/lib/misc", 0755); /* _PATH_VARDB on some systems */
|
|
||||||
makedir("/var/lib/alarm", 0755);
|
|
||||||
makedir("/var/lib/urandom",0755);
|
|
||||||
if (fisdir("/run")) {
|
|
||||||
_d("System with new /run tmpfs ...");
|
|
||||||
if (!fisdir("/run/lock"))
|
|
||||||
makedir("/run/lock", 1777);
|
|
||||||
ln("/run/lock", "/var/lock");
|
|
||||||
ln("/dev/shm", "/run/shm");
|
|
||||||
|
|
||||||
/* compat only, should really be set up by OS/dist */
|
/* Create all system tmpfiles.d(5) */
|
||||||
ln("/run", "/var/run");
|
run_interactive(_PATH_TMPFILES " --create", "Creating required directories and files");
|
||||||
} else {
|
|
||||||
makedir("/var/lock", 1777);
|
|
||||||
makedir("/var/run", 0755);
|
|
||||||
}
|
|
||||||
makedir("/var/log", 0755);
|
|
||||||
makedir("/var/mail", 0755);
|
|
||||||
makedir("/var/opt", 0755);
|
|
||||||
makedir("/var/spool", 0755);
|
|
||||||
makedir("/var/spool/cron", 0755);
|
|
||||||
makedir("/var/tmp", 0755);
|
|
||||||
makedir("/var/empty", 0755);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* UTMP actually needs multiple db files
|
|
||||||
*/
|
|
||||||
if (has_utmp()) {
|
|
||||||
int gid;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If /etc/group or "utmp" group is missing, default to
|
|
||||||
* "root", or "wheel", group.
|
|
||||||
*/
|
|
||||||
_d("Setting up necessary UTMP files ...");
|
|
||||||
gid = getgroup("utmp");
|
|
||||||
if (gid < 0)
|
|
||||||
gid = 0;
|
|
||||||
|
|
||||||
create("/var/run/utmp", 0644, 0, gid); /* Currently logged in */
|
|
||||||
create("/var/log/wtmp", 0644, 0, gid); /* Login history */
|
|
||||||
create("/var/log/btmp", 0600, 0, gid); /* Failed logins */
|
|
||||||
create("/var/log/lastlog", 0644, 0, gid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set BOOT_TIME UTMP entry */
|
/* Set BOOT_TIME UTMP entry */
|
||||||
utmp_set_boot();
|
utmp_set_boot();
|
||||||
|
|
||||||
#ifdef TOUCH_ETC_NETWORK_RUN_IFSTATE
|
|
||||||
touch("/etc/network/run/ifstate");
|
|
||||||
#else
|
|
||||||
erase("/etc/network/run/ifstate");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_d("Setting up misc files ...");
|
|
||||||
makedir("/var/run/network",0755); /* Needed by Debian/Ubuntu ifupdown */
|
|
||||||
makedir("/var/run/lldpd", 0755); /* Needed by lldpd */
|
|
||||||
makedir("/var/run/pluto", 0755); /* Needed by Openswan */
|
|
||||||
mksubsys("/var/run/quagga", 0755, "quagga", "quagga");
|
|
||||||
mksubsys("/var/log/quagga", 0755, "quagga", "quagga");
|
|
||||||
mksubsys("/var/run/frr", 0755, "frr", "frr");
|
|
||||||
mksubsys("/var/log/frr", 0755, "frr", "frr");
|
|
||||||
makedir("/var/run/sshd", 01755); /* OpenSSH */
|
|
||||||
|
|
||||||
if (!fexist("/etc/mtab"))
|
|
||||||
ln("../proc/self/mounts", "/etc/mtab");
|
|
||||||
|
|
||||||
/* Void Linux has a uuidd that runs as uuid:uuid and needs /run/uuid */
|
|
||||||
mksubsys("/var/run/uuidd", 0755, "uuidd", "uuidd");
|
|
||||||
|
|
||||||
/* Debian has /run/sudo, ensure correct perms and SELinux label */
|
|
||||||
mksubsys("/var/run/sudo", 0711, "root", "root");
|
|
||||||
mksubsys("/var/run/sudo/ts", 0700, "root", "root");
|
|
||||||
if (whichp("restorecon"))
|
|
||||||
run("restorecon /var/run/sudo /var/run/sudo/ts", "restorecon");
|
|
||||||
|
|
||||||
umask(prev);
|
umask(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
.name = __FILE__,
|
.name = "bootmisc",
|
||||||
.hook[HOOK_MOUNT_POST] = { .cb = clean },
|
.hook[HOOK_MOUNT_POST] = { .cb = clean },
|
||||||
.hook[HOOK_BASEFS_UP] = { .cb = setup },
|
.hook[HOOK_BASEFS_UP] = { .cb = setup },
|
||||||
.depends = { "pidfile" },
|
.depends = { "pidfile" },
|
||||||
};
|
};
|
||||||
|
|
||||||
PLUGIN_INIT(plugin_init)
|
PLUGIN_INIT(__init)
|
||||||
{
|
{
|
||||||
plugin_register(&plugin);
|
plugin_register(&plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(__exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
plugin_unregister(&plugin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* Setup and start system message bus, D-Bus
|
/* Setup and start system message bus, D-Bus
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012-2022 Joachim Wiberg <troglobit@gmail.com>
|
* Copyright (c) 2012-2025 Joachim Wiberg <troglobit@gmail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -33,70 +33,147 @@
|
|||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
|
#include "util.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#define DAEMON "dbus-daemon"
|
#define DBUS_DAEMON "dbus-daemon"
|
||||||
#define ARGS "--nofork --system --syslog-only"
|
#define DBUS_ARGS "--nofork --system --syslog-only"
|
||||||
#define DESC "D-Bus message bus daemon"
|
#define DBUS_DESC "D-Bus message bus daemon"
|
||||||
|
|
||||||
#ifndef DAEMONUSER
|
#ifndef DBUS_DAEMONUSER
|
||||||
#define DAEMONUSER "messagebus"
|
#define DBUS_DAEMONUSER "messagebus"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DAEMONPIDFILE
|
#ifndef DBUS_DAEMONGROUP
|
||||||
#define DAEMONPIDFILE "/var/run/dbus/pid"
|
#define DBUS_DAEMONGROUP "messagebus"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dumnpster diving for the D-Bus main configuration file
|
||||||
|
* where <pidfile> is defined.
|
||||||
|
*/
|
||||||
|
static char *dbus_pidfn(void)
|
||||||
|
{
|
||||||
|
char *alt[] = {
|
||||||
|
"/usr/share/dbus-1/system.conf",
|
||||||
|
"/etc/dbus-1/system.conf",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; alt[i]; i++) {
|
||||||
|
char *fn = alt[i];
|
||||||
|
char buf[256];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen(fn, "r");
|
||||||
|
if (!fp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fn = NULL;
|
||||||
|
while (fgets(buf, sizeof(buf), fp)) {
|
||||||
|
char *pos;
|
||||||
|
|
||||||
|
pos = strstr(buf, "<pidfile>");
|
||||||
|
if (!pos)
|
||||||
|
continue;
|
||||||
|
fn = pos + strlen("<pidfile>");
|
||||||
|
pos = strstr(fn, "</pidfile>");
|
||||||
|
if (!pos) {
|
||||||
|
fn = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pos = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
if (fn)
|
||||||
|
return strdup(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void setup(void *arg)
|
static void setup(void *arg)
|
||||||
{
|
{
|
||||||
|
char *group = DBUS_DAEMONGROUP;
|
||||||
|
char *user = DBUS_DAEMONUSER;
|
||||||
char line[256];
|
char line[256];
|
||||||
|
char *pidfn;
|
||||||
mode_t prev;
|
mode_t prev;
|
||||||
char *cmd;
|
char *cmd;
|
||||||
|
|
||||||
if (rescue) {
|
if (rescue) {
|
||||||
_d("Skipping %s plugin in rescue mode.", __FILE__);
|
dbg("Skipping %s plugin in rescue mode.", "dbus");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = which(DAEMON);
|
cmd = which(DBUS_DAEMON);
|
||||||
if (!cmd) {
|
if (!cmd) {
|
||||||
_d("Skipping plugin, %s is not installed.", DAEMON);
|
dbg("Skipping plugin, %s is not installed.", DBUS_DAEMON);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev =umask(0);
|
if (getuser(user, NULL) == -1) {
|
||||||
|
if (getuser("dbus", NULL) == -1)
|
||||||
|
user = "root"; /* fallback */
|
||||||
|
else
|
||||||
|
user = "dbus"; /* e.g., Buildroot */
|
||||||
|
}
|
||||||
|
|
||||||
mksubsys("/var/run/dbus", 0755, DAEMONUSER, DAEMONUSER);
|
if (getgroup(group) == -1) {
|
||||||
if (whichp("dbus-uuidgen"))
|
if (getgroup("dbus") == -1)
|
||||||
run_interactive("dbus-uuidgen --ensure", "Creating machine UUID for D-Bus");
|
group = "root"; /* fallback */
|
||||||
|
else
|
||||||
|
group = "dbus"; /* e.g., Buildroot */
|
||||||
|
}
|
||||||
|
|
||||||
/* Clean up from any previous pre-bootstrap run */
|
/* Clean up from any previous pre-bootstrap run */
|
||||||
remove(DAEMONPIDFILE);
|
pidfn = dbus_pidfn();
|
||||||
|
if (pidfn)
|
||||||
/* Register service with Finit */
|
remove(pidfn);
|
||||||
snprintf(line, sizeof(line), "[S12345789] cgroup.system pid:!%s @%s:%s %s %s -- %s",
|
|
||||||
DAEMONPIDFILE, DAEMONUSER, DAEMONUSER, cmd, ARGS, DESC);
|
|
||||||
if (service_register(SVC_TYPE_SERVICE, line, global_rlimit, NULL))
|
|
||||||
_pe("Failed registering %s", DAEMON);
|
|
||||||
free(cmd);
|
|
||||||
|
|
||||||
|
dbg("Creating D-Bus Required Directories ...");
|
||||||
|
prev = umask(0);
|
||||||
|
mksubsys("/var/run/dbus", 0755, user, group);
|
||||||
|
mksubsys("/var/run/lock/subsys", 0755, user, group);
|
||||||
|
mksubsys("/var/lib/dbus", 0755, user, group);
|
||||||
|
mksubsys("/tmp/dbus", 0755, user, group);
|
||||||
umask(prev);
|
umask(prev);
|
||||||
|
|
||||||
|
/* Generate machine id for dbus */
|
||||||
|
if (whichp("dbus-uuidgen"))
|
||||||
|
run_interactive("dbus-uuidgen --ensure", "Verifying D-Bus machine UUID");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register service with Finit
|
||||||
|
* Note: dbus drops privs after starting up.
|
||||||
|
*/
|
||||||
|
if (pidfn) {
|
||||||
|
snprintf(line, sizeof(line), "[S123456789] cgroup.system notify:none name:dbus pid:!%s %s %s -- %s",
|
||||||
|
pidfn, cmd, DBUS_ARGS, DBUS_DESC);
|
||||||
|
free(pidfn);
|
||||||
|
} else
|
||||||
|
snprintf(line, sizeof(line), "[S123456789] cgroup.system notify:none name:dbus %s %s -- %s",
|
||||||
|
cmd, DBUS_ARGS, DBUS_DESC);
|
||||||
|
|
||||||
|
conf_save_service(SVC_TYPE_SERVICE, line, "dbus.conf");
|
||||||
|
free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
.name = __FILE__,
|
.name = "dbus",
|
||||||
.hook[HOOK_BASEFS_UP] = {
|
.hook[HOOK_SVC_PLUGIN] = { .cb = setup },
|
||||||
.cb = setup
|
|
||||||
},
|
|
||||||
.depends = { "bootmisc", },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PLUGIN_INIT(plugin_init)
|
PLUGIN_INIT(__init)
|
||||||
{
|
{
|
||||||
plugin_register(&plugin);
|
plugin_register(&plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(__exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
plugin_unregister(&plugin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,18 +26,11 @@
|
|||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#define CHOOSE(x, y) y
|
extern void plugin_script_run(hook_point_t no);
|
||||||
static const char *hscript_paths[] = HOOK_TYPES;
|
|
||||||
#undef CHOOSE
|
|
||||||
|
|
||||||
static void hscript_run_parts(hook_point_t hook)
|
static void hscript_run_parts(hook_point_t no)
|
||||||
{
|
{
|
||||||
char path[CMD_SIZE] = "";
|
plugin_script_run(no);
|
||||||
|
|
||||||
strlcat(path, PLUGIN_HOOK_SCRIPTS_PATH, sizeof(path));
|
|
||||||
strlcat(path, hscript_paths[hook] + 4, sizeof(path));
|
|
||||||
|
|
||||||
run_parts(path, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hscript_banner(void *arg)
|
static void hscript_banner(void *arg)
|
||||||
@@ -86,7 +79,7 @@ static void hscript_shutdown(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static plugin_t plugin = {
|
static plugin_t plugin = {
|
||||||
.name = __FILE__,
|
.name = "hook-scripts",
|
||||||
.hook[HOOK_BANNER] = { .cb = hscript_banner },
|
.hook[HOOK_BANNER] = { .cb = hscript_banner },
|
||||||
.hook[HOOK_ROOTFS_UP] = { .cb = hscript_rootfs_up },
|
.hook[HOOK_ROOTFS_UP] = { .cb = hscript_rootfs_up },
|
||||||
.hook[HOOK_MOUNT_ERROR] = { .cb = hscript_mount_error },
|
.hook[HOOK_MOUNT_ERROR] = { .cb = hscript_mount_error },
|
||||||
@@ -96,14 +89,22 @@ static plugin_t plugin = {
|
|||||||
.hook[HOOK_SVC_UP] = { .cb = hscript_svc_up },
|
.hook[HOOK_SVC_UP] = { .cb = hscript_svc_up },
|
||||||
.hook[HOOK_SYSTEM_UP] = { .cb = hscript_system_up },
|
.hook[HOOK_SYSTEM_UP] = { .cb = hscript_system_up },
|
||||||
.hook[HOOK_SHUTDOWN] = { .cb = hscript_shutdown },
|
.hook[HOOK_SHUTDOWN] = { .cb = hscript_shutdown },
|
||||||
|
/*
|
||||||
|
* We have exited here, so these are handled a bit differently by Finit,
|
||||||
|
* when hook scripts are enabled, just to provide the user with the same
|
||||||
|
* interface:
|
||||||
|
*
|
||||||
|
* .hook[HOOK_SVC_DN] = { .cb = hscript_svc_down },
|
||||||
|
* .hook[HOOK_SYS_DN] = { .cb = hscript_system_down },
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
PLUGIN_INIT(plugin_init)
|
PLUGIN_INIT(__init)
|
||||||
{
|
{
|
||||||
plugin_register(&plugin);
|
plugin_register(&plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
PLUGIN_EXIT(plugin_exit)
|
PLUGIN_EXIT(__exit)
|
||||||
{
|
{
|
||||||
plugin_unregister(&plugin);
|
plugin_unregister(&plugin);
|
||||||
}
|
}
|
||||||
|
|||||||