Protect against corner cases where pid conditions are not cleaned up.
We don't want such conditions to remain asserted when the process has
terminated.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When we try to start a service/run/task we call whichp() to see if the
binary exists, either tha absolute path given in the .conf file, or in
the $PATH we run with. If binary, or the env: file, doesn't exist we
now set svc_missing() state.
On `initctl reload` we unblock the service to be able to check again.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes a few really hard problems wrt PID files:
1. Listening for IN_CREATE events means we get notified immediately by
the kernel when someone calls open()/fopen() on a PID file. Reading
the contents returns 0, thank you atoi() ... so we drop IN_CREATE
and instead look for IN_CLOSE_WRITE, there fixed it! Not quite ...
2. Some programs, like Zebra, and other Quagga/Frr daemons, don't
close() their PID files after creation. Instead they ftruncate()
and keep them open, and locked. Presumably to get a mechanism to
detect already running instances -- messes life up a bit for the
rest of us though. So we need to read files after IN_MODIFY too.
3. We also want to track IN_DELETE so we can deassert conditions when
services exit gracefully and clean up their PID files
The rest fo the commit is debug instrumentation changes.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In 7447192 we dropped support for 'cond set' and 'cond clear' commands
with the motivation they were unsafe and sent the wrong message to the
user. That was true, but mostly because it was too generic and required
the user to call `initctl reload` to apply the changes.
This patch restores the behavior, albeit in a very reduced and simple
format. All conditions set with this command are constrained to the
'usr/...' namespace. No subdirectories are allowed. The argument to
the 'cond set|clear' command is disallowed if it contains '/' or '.'
but anything else is supported, for example:
initctl cond set foo:2
creates a static/oneshot condition in /run/finit/cond/usr/foo:2
These conditions are static and are fully handled by the user. The
initctl command is the recommended, and only supported, way of setting
and clearing usr conditions.
This patch also includes a new plugin, usr.so, which is a very simple
inotify plugin for the /run/finit/cond/usr/ directory. When files are
created or removed here the plugin tells the Finit condition engine to
update and trigger service changes.
For instance, the following service is not started by default at boot:
service <usr/foo> myservice -- MyService
However, as soon as `initctl cond set foo` is called, myservice starts.
Consequently, it is stopped when `initctl cond clr foo` is called.
Another major difference from the original is that this implementation
doesn't send IPC commands to create/delete the conditions. This makes
calling these new commands non-blocking so they can be used very early
in the bootstrap, by plugins, if needed.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Use _PATH_foo for all condition paths, *with* trailing /
- Read condition file first, may not exist, in which case we save time
- Change from libte makepath() to mkpath(), this changes from hard-coded
0777 perms on all cond dirs to 0755 -- possible security fix
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Provided a configuration that looks like this:
ospfd.conf:
service [2345] <!pid/zebra> log ospfd -A 127.0.0.1 -u root -g root -- OSPF daemon
zebra.conf:
service [2345] <!> log zebra -A 127.0.0.1 -u root -g root -- Zebra Routing daemon
If zebra.conf is changed, we restart it when `initctl reload` is issued.
This change ensures that ospfd is also restarted, because ospfd depends
on zebra, we must restart it too.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Fix ev->len validation; must check against sz read(), not total buffer
size. Also, fix off-by-one in comparison.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is a major refactor to use the same construct as in the pidfile.so
plugin to parse kernel inotify events for when TTYs are added removed
from the system.
Found by Coverity Scan.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Align the two implementations in logit.c and utmp-api.c
- Use libite APIs to handle common constructs
- If gzip fails, don't remove rotated-to file
- Don't try gzip if rename fails
- Issues found by Coverity Scan
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Ignore EBUSY errors, the kernel has the ability to automount /dev as
soon as the rootfs has been mounted. This may be added to procfs and
sysfs later, so we make this a general change in fs_init().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Decleare some return values with (void)fn(), for cases where
we don't care (dropping table headers), or best effor
- Check return value from fgets() and chdir() in some cases that
are valid, i.e., continuing execution is pointless
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No point in using rq.data, which could have been modified, instead use
the input argument to the function in the error message.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
While skimming through the results of the latest Coverity Scan, I
discovered that that the reset logic of global rlimits was broken.
This it seems to have been since its first introduction in Finit.
We fix this by reading initial rlimits at bootstrap, then for each
reconf, including the first, we seed global rlimits with the initial
ones -- thus resetting between each reconf.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The utmp_set() function allows id==NULL, so default the line to NULL and
avoid parsing empty lines. Which is better code anyway.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Mostly used during development, doesn't really provide any value to the
user at normal runtime. Leave it commented out though so user can do
debug themselves if needed.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Refactor screen_init()
- use native impl. of TTY probing from pimd project
- check if TIOCWINSZ works
- check if we're running in watch(1), for initctl
- check if ANSI goto(999,999) escape seq. works (invasive)
- fallback to 80x24
- Drop screen_exit()
- Rename screen_init() to get_width(), for now, matching pimd
- Relocate call in main() to banner(), first fn to write to TTY
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the recent changes to the condition handling it has become more and
more evident that the canonical reference for a task/run/service is the
NAME:ID representation. Up until now we've kept the older JOB:ID for
some sort of compatibility fallback.
This patch removes the support to simplify maintenance going forward.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This is quite possibly the ugliest pieces of code in this project.
It is a quick fix to the problem with strtok() to split up the cmd into
cmd + args[]. Without it wordexp() will later get very cranky about
trying to expand `"Partial` strings from commands like this:
/sbin/udhcpc-wrapper.sh -f -S -V "myOS v9.99" -t 8 -T 5 -A 10 -R -p \
/var/run/udhcpc-vlan1.pid -i vlan1 -x hostname:myos-12-34-50 -o \
-O 1 -O 3 -O 6 -O 7 -O 12 -O 15 -O 42 -O 121 -a
Yes really.
It's an obviously far from perfect solution. One might even start to
question why we have an args[64[64] per svc_t and not just a cmd + arg?
Well, there's a lot of improvement potential here, let's talk!
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
If mg doesn't exist, command doesn't evaluate the second argument (vi),
so we need to use `... || command -v vi` instead. Found during demo,
because why not.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes an issue with rescue mode on Alpine Linux where the
rescue shell was never properly started.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>