mirror of
https://github.com/troglobit/finit.git
synced 2026-10-14 10:19:36 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
534d50c03a | ||
|
|
9a42883a96 | ||
|
|
7c77e2c2b6 | ||
|
|
ea8c46cd30 | ||
|
|
fead3b0671 | ||
|
|
081990b49e | ||
|
|
6b89f8c6db | ||
|
|
373097040a | ||
|
|
a4ab75172c | ||
|
|
5cf9958957 | ||
|
|
b137e08e84 | ||
|
|
a1af8e8687 | ||
|
|
53c7ddcb22 | ||
|
|
3872077ff1 |
No files matched your search
+26
-7
@@ -4,6 +4,31 @@ Change Log
|
|||||||
All relevant changes are documented in this file.
|
All relevant changes are documented in this file.
|
||||||
|
|
||||||
|
|
||||||
|
[4.1][UNRELEASED]
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Bug fix release.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
* Change behavior on SIGUSR1 to be compatible with sysvinit and systemd.
|
||||||
|
Previously SIGUSR1 caused Finit to halt, like BusyBox init. This had
|
||||||
|
"interesting" side effects on Debian systems when coexisting with
|
||||||
|
sysvinit (upgrading/reinstalling causes scripts to `kill -USR1 1`)
|
||||||
|
* Change how `contrib/debian/install.sh` sets up a Grub boot entry for
|
||||||
|
finit. We now modify the $SUPPORTED_INITS variable in `10_linux`
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Stricter interface name validation in netlink plugin, modeled after
|
||||||
|
the kernel. Suggested by Coverity Scan
|
||||||
|
* The `contrib/*/install.sh` scripts failed to run from tarball
|
||||||
|
* Fix #170: detect loss of default route when interfaces go down. This
|
||||||
|
emulates the missing kernel netlink message to remove the condition
|
||||||
|
net/default/route to allow stopping dependent services
|
||||||
|
* Fix #171: restore automatic mount of `/dev/shm`, `/dev/pts`, `/run`
|
||||||
|
and `/tmp`, unless mounted already by `/etc/fstab`. This is what most
|
||||||
|
desktop systems expect PID 1 to do
|
||||||
|
|
||||||
|
|
||||||
[4.0][] - 2021-04-26
|
[4.0][] - 2021-04-26
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
@@ -875,7 +900,7 @@ Major bug fix release.
|
|||||||
|
|
||||||
* Initial release
|
* Initial release
|
||||||
|
|
||||||
[UNRELEASED]: https://github.com/troglobit/finit/compare/3.1...HEAD
|
[UNRELEASED]: https://github.com/troglobit/finit/compare/4.0...HEAD
|
||||||
[4.0]: https://github.com/troglobit/finit/compare/3.1...4.0
|
[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.1]: https://github.com/troglobit/finit/compare/3.0...3.1
|
||||||
[3.0]: https://github.com/troglobit/finit/compare/2.4...3.0
|
[3.0]: https://github.com/troglobit/finit/compare/2.4...3.0
|
||||||
@@ -907,9 +932,3 @@ Major bug fix release.
|
|||||||
[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
|
||||||
|
|
||||||
<!--
|
|
||||||
-- Local Variables:
|
|
||||||
-- mode: markdown
|
|
||||||
-- End:
|
|
||||||
-->
|
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT(Finit, 4.0, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
|
AC_INIT(Finit, 4.1-rc1, https://github.com/troglobit/finit/issues, finit, https://troglobit.com/finit.html)
|
||||||
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 dist-xz subdir-objects])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
@@ -8,7 +8,7 @@ AC_CONFIG_HEADER([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/grub.d/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
|
||||||
plugins/Makefile
|
plugins/Makefile
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ fi
|
|||||||
# Adjust base directory
|
# Adjust base directory
|
||||||
if [ -e alpine-release ]; then
|
if [ -e alpine-release ]; then
|
||||||
cd ../..
|
cd ../..
|
||||||
elif [ ! -e autogen.sh ]; then
|
elif [ ! -e configure.ac ]; then
|
||||||
echo "*** Please run this script from the Finit base directory."
|
echo "*** Please run this script from the Finit base directory."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
SUBDIRS = finit.d grub.d
|
SUBDIRS = finit.d
|
||||||
docsdir := @docdir@/contrib/debian
|
docsdir := @docdir@/contrib/debian
|
||||||
docs_DATA = README.md finit.conf os-release build.sh install.sh
|
docs_DATA = README.md finit.conf os-release build.sh install.sh
|
||||||
EXTRA_DIST = $(docs_DATA)
|
EXTRA_DIST = $(docs_DATA)
|
||||||
@@ -29,10 +29,10 @@ set up your system to run Finit:
|
|||||||
user@debian:~/finit$ contrib/debian/build.sh
|
user@debian:~/finit$ contrib/debian/build.sh
|
||||||
|
|
||||||
However, since `/sbin/init` already exists on your system, the script
|
However, since `/sbin/init` already exists on your system, the script
|
||||||
creates another entry in your GRUB config, in `/etc/grub.d/40_custom`,
|
creates another entry in your GRUB config by updating `$SUPPORTED_INITS`
|
||||||
where `init=/sbin/finit` is added to your kernel line. It is of course
|
in `/etc/grub.d/10_inux` and run `update-grub`. On reboot you will find
|
||||||
also possible to change the default init to Finit, if you do you can
|
a (finit) entry in the "Advanced options for Debian GNU/Linux" section.
|
||||||
remove the custom Grub entry:
|
It is of course also possible to change the default init to Finit:
|
||||||
|
|
||||||
user@debian:~/finit# cd /sbin
|
user@debian:~/finit# cd /sbin
|
||||||
user@debian:/sbin# sudo mv init oldinit
|
user@debian:/sbin# sudo mv init oldinit
|
||||||
@@ -51,7 +51,8 @@ If you want to use the X Window system, `sudo apt install elogind`
|
|||||||
(Bullseye and later). Followed by `initctl reload` (enabled by default)
|
(Bullseye and later). Followed by `initctl reload` (enabled by default)
|
||||||
and logout/login again. The elogind daemon ensures a regular non-root
|
and logout/login again. The elogind daemon ensures a regular non-root
|
||||||
user can start and interact with an X session, otherwise keyboard and
|
user can start and interact with an X session, otherwise keyboard and
|
||||||
mouse won't work.
|
mouse won't work. When you're happy, you can enable the lightdm.conf,
|
||||||
|
change the default runlevel to 3, and presto! you have a desktop again.
|
||||||
|
|
||||||
|
|
||||||
Have fun!
|
Have fun!
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
exec tail -n +3 $0
|
|
||||||
# This file provides an easy way to add custom menu entries. Simply type the
|
|
||||||
# menu entries you want to add after this comment. Be careful not to change
|
|
||||||
# the 'exec tail' line above.
|
|
||||||
|
|
||||||
menuentry '$MENU with Finit' --class $TYPE --class gnu-linux --class gnu --class os --user {
|
|
||||||
insmod gzio
|
|
||||||
insmod part_msdos
|
|
||||||
insmod ext2
|
|
||||||
search --no-floppy --fs-uuid --set=root $BOOT
|
|
||||||
linux /vmlinuz root=UUID=$ROOT ro quiet init=/sbin/finit
|
|
||||||
initrd /initrd.img
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
docsdir := @docdir@/contrib/debian/grub.d
|
|
||||||
docs_DATA = 40_custom
|
|
||||||
EXTRA_DIST = $(docs_DATA)
|
|
||||||
@@ -11,7 +11,7 @@ fi
|
|||||||
grep -q Debian os-release 2>/dev/null
|
grep -q Debian os-release 2>/dev/null
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
cd ../..
|
cd ../..
|
||||||
elif [ ! -e autogen.sh ]; then
|
elif [ ! -e configure.ac ]; then
|
||||||
echo "*** Please run this script from the Finit base directory."
|
echo "*** Please run this script from the Finit base directory."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@@ -23,7 +23,7 @@ echo "/sbin/finit - PID 1"
|
|||||||
echo "/lib/finit/plugins/* - All enabled Finit plugins"
|
echo "/lib/finit/plugins/* - All enabled Finit plugins"
|
||||||
echo "/etc/finit.conf - Finit configuration file"
|
echo "/etc/finit.conf - Finit configuration file"
|
||||||
echo "/etc/finit.d/ - Finit services"
|
echo "/etc/finit.d/ - Finit services"
|
||||||
echo "/etc/grub.d/40_custom - Add menu entry to the Grub boot loader"
|
echo "/etc/grub.d/10_linux - Add Finit to Grub's SUPPORTED_INITS"
|
||||||
echo
|
echo
|
||||||
read -p "Do you want to continue (y/N)? " yorn
|
read -p "Do you want to continue (y/N)? " yorn
|
||||||
echo
|
echo
|
||||||
@@ -38,12 +38,18 @@ if [ "x$yorn" = "xy" -o "x$yorn" = "xY" ]; then
|
|||||||
cp -va finit.d /etc/
|
cp -va finit.d /etc/
|
||||||
|
|
||||||
echo "*** Setting up a GRUB boot entry ..."
|
echo "*** Setting up a GRUB boot entry ..."
|
||||||
MENU=`grep gnu-linux /boot/grub/grub.cfg |head -1 |sed "s/menuentry '\([^']*\).*/\1/"`
|
fn=/etc/grub.d/10_linux
|
||||||
TYPE=`grep gnu-linux /boot/grub/grub.cfg |head -1 |sed "s/.*' --class \([a-z]*\).*/\1/"`
|
if [ -e $fn ]; then
|
||||||
BOOT=`grep set=root /boot/grub/grub.cfg |head -1 |sed 's/.* \([a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*\).*/\1/'`
|
if `grep SUPPORTED_INITS $fn |head -1 |grep -q finit`; then
|
||||||
ROOT=`grep root=UUID /boot/grub/grub.cfg |head -1 |sed 's/.*UUID=\([a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*-[a-f0-9]*\).*/\1/'`
|
echo "Already installed, done."
|
||||||
cat grub.d/40_custom | sed "s,\$BOOT,$BOOT,;s,\$ROOT,$ROOT,;s,\$TYPE,$TYPE,;s,\$MENU,$MENU," >/etc/grub.d/40_custom
|
else
|
||||||
update-grub
|
echo "Adding Finit to list of SUPPORTED_INITS ..."
|
||||||
|
sed -i 's/SUPPORTED_INITS="[^"]*/& finit:\/sbin\/finit/' $fn
|
||||||
|
update-grub
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Cannot find $fn, you'll have to set up your bootloader on your own."
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "*** Done"
|
echo "*** Done"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ fi
|
|||||||
# Adjust base directory
|
# Adjust base directory
|
||||||
if [ -e xbps ]; then
|
if [ -e xbps ]; then
|
||||||
cd ../..
|
cd ../..
|
||||||
elif [ ! -e autogen.sh ]; then
|
elif [ ! -e configure.ac ]; then
|
||||||
echo "*** Please run this script from the Finit base directory."
|
echo "*** Please run this script from the Finit base directory."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
+17
-9
@@ -12,28 +12,36 @@ have been adopted:
|
|||||||
Same effect as `finit q`, `init q`, or `initctl reload`, reloads all
|
Same effect as `finit q`, `init q`, or `initctl reload`, reloads all
|
||||||
*.conf files in `/etc/finit.d/`
|
*.conf files in `/etc/finit.d/`
|
||||||
|
|
||||||
|
This also restarts the API (initctl) socket, like SysV init and systemd
|
||||||
|
does on USR1 with their FIFO/D-Bus.
|
||||||
|
|
||||||
|
|
||||||
`SIGUSR1`
|
`SIGUSR1`
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Calls shutdown hooks, including `HOOK_SHUTDOWN`, stopping all running
|
Since Finit 4.1 this signal causes Finit to restart its API (initctl)
|
||||||
processes, and unmounts all file systems. Then tells kernel to halt.
|
socket, like SysV init and systemd does on USR1 with their FIFO/D-Bus.
|
||||||
Most people these days want `SIGUSR2` though.
|
|
||||||
|
Finit <= 4.0 performed a system halt (like USR2 without power-off), but
|
||||||
|
this caused compatibility problems with systemd and sysvinit on desktop
|
||||||
|
systems. Hence, since Finit 4.1 it is no longer possible to halt a
|
||||||
|
system with a signal.
|
||||||
|
|
||||||
SysV init and systemd use this to re-open their FIFO/D-Bus.
|
|
||||||
|
|
||||||
`SIGUSR2`
|
`SIGUSR2`
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Like SIGUSR1, but tell kernel to power-off the system, if ACPI or
|
Calls shutdown hooks, including `HOOK_SHUTDOWN`, stopping all running
|
||||||
similar exists to actually do this. If the kernel fails power-off,
|
processes, and unmounts all file systems. Then tells kernel to power
|
||||||
Finit falls back to halt.
|
off the system, if ACPI or similar exists to actually do this. If the
|
||||||
|
kernel fails power-off, Finit falls back to halt.
|
||||||
|
|
||||||
SysV init N/A, systemd dumps its internal state to log.
|
SysV init N/A, systemd dumps its internal state to log.
|
||||||
|
|
||||||
`SIGTERM`
|
`SIGTERM`
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Like `SIGUSR1`, but tell kernel to reboot the system when done.
|
Like `SIGUSR2`, but tell kernel to reboot the system when done.
|
||||||
|
|
||||||
SysV init N/A, systemd rexecutes itself.
|
SysV init N/A, systemd rexecutes itself.
|
||||||
|
|
||||||
|
|||||||
+108
-10
@@ -31,6 +31,9 @@
|
|||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
|
static int ifdown = 0;
|
||||||
|
|
||||||
|
|
||||||
static int nlmsg_validate(struct nlmsghdr *nh, size_t len)
|
static int nlmsg_validate(struct nlmsghdr *nh, size_t len)
|
||||||
{
|
{
|
||||||
if (!NLMSG_OK(nh, len))
|
if (!NLMSG_OK(nh, len))
|
||||||
@@ -51,10 +54,16 @@ static int nlmsg_validate(struct nlmsghdr *nh, size_t len)
|
|||||||
|
|
||||||
static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
|
static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
|
||||||
{
|
{
|
||||||
|
char daddr[INET_ADDRSTRLEN];
|
||||||
|
char gaddr[INET_ADDRSTRLEN];
|
||||||
|
struct in_addr ind, ing;
|
||||||
struct rtmsg *r;
|
struct rtmsg *r;
|
||||||
struct rtattr *a;
|
struct rtattr *a;
|
||||||
|
int plen = 0;
|
||||||
|
int dst = 0;
|
||||||
|
int idx = 0;
|
||||||
|
int gw = 0;
|
||||||
int la;
|
int la;
|
||||||
int gw = 0, dst = 0, mask = 0, idx = 0;
|
|
||||||
|
|
||||||
if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg))) {
|
if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtmsg))) {
|
||||||
_e("Packet too small or truncated!");
|
_e("Packet too small or truncated!");
|
||||||
@@ -80,8 +89,8 @@ static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
|
|||||||
|
|
||||||
case RTA_DST:
|
case RTA_DST:
|
||||||
dst = *((int *)data);
|
dst = *((int *)data);
|
||||||
mask = r->rtm_dst_len;
|
plen = r->rtm_dst_len;
|
||||||
//_d("MASK: 0x%04x", mask);
|
//_d("Prefix LEN: 0x%04x", plen);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RTA_OIF:
|
case RTA_OIF:
|
||||||
@@ -93,7 +102,13 @@ static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
|
|||||||
a = RTA_NEXT(a, la);
|
a = RTA_NEXT(a, la);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!dst && !mask) && (gw || idx)) {
|
ind.s_addr = dst;
|
||||||
|
ing.s_addr = gw;
|
||||||
|
inet_ntop(AF_INET, &ind, daddr, sizeof(daddr));
|
||||||
|
inet_ntop(AF_INET, &ing, gaddr, sizeof(gaddr));
|
||||||
|
_d("Got gw %s dst/len %s/%d ifindex %d", gaddr, daddr, plen, idx);
|
||||||
|
|
||||||
|
if ((!dst && !plen) && (gw || idx)) {
|
||||||
if (nlmsg->nlmsg_type == RTM_DELROUTE)
|
if (nlmsg->nlmsg_type == RTM_DELROUTE)
|
||||||
cond_clear("net/route/default");
|
cond_clear("net/route/default");
|
||||||
else
|
else
|
||||||
@@ -101,6 +116,36 @@ static void nl_route(struct nlmsghdr *nlmsg, ssize_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nl_default(struct nlmsghdr *nlh, struct in_addr *dst, struct in_addr *gw)
|
||||||
|
{
|
||||||
|
struct in_addr nil = { 0 };
|
||||||
|
struct rtattr *a;
|
||||||
|
struct rtmsg *r;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
r = (struct rtmsg *)NLMSG_DATA(nlh);
|
||||||
|
if ((r->rtm_family != AF_INET) || (r->rtm_table != RT_TABLE_MAIN))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
len = RTM_PAYLOAD(nlh);
|
||||||
|
for (a = RTM_RTA(r); RTA_OK(a, len); a = RTA_NEXT(a, len)) {
|
||||||
|
switch (a->rta_type) {
|
||||||
|
case RTA_GATEWAY:
|
||||||
|
memcpy(gw, RTA_DATA(a), sizeof(*gw));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTA_DST:
|
||||||
|
memcpy(dst, RTA_DATA(a), sizeof(*dst));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(dst, &nil, sizeof(nil)) && memcmp(gw, &nil, sizeof(nil)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void net_cond_set(char *ifname, char *cond, int set)
|
static void net_cond_set(char *ifname, char *cond, int set)
|
||||||
{
|
{
|
||||||
char msg[MAX_ARG_LEN];
|
char msg[MAX_ARG_LEN];
|
||||||
@@ -117,14 +162,14 @@ static int validate_ifname(const char *ifname)
|
|||||||
if (!ifname || !ifname[0])
|
if (!ifname || !ifname[0])
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (strlen(ifname) >= IFNAMSIZ)
|
if (strnlen(ifname, IFNAMSIZ) == IFNAMSIZ)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (strstr(ifname, ".."))
|
if (!strcmp(ifname, ".") || !strcmp(ifname, ".."))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
while (*ifname) {
|
while (*ifname) {
|
||||||
if (*ifname == '/' || isspace(*ifname))
|
if (*ifname == '/' || *ifname == ':' || isspace(*ifname))
|
||||||
return 1;
|
return 1;
|
||||||
ifname++;
|
ifname++;
|
||||||
}
|
}
|
||||||
@@ -134,10 +179,10 @@ static int validate_ifname(const char *ifname)
|
|||||||
|
|
||||||
static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
|
static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
|
||||||
{
|
{
|
||||||
int la;
|
|
||||||
char ifname[IFNAMSIZ + 1];
|
char ifname[IFNAMSIZ + 1];
|
||||||
struct rtattr *a;
|
|
||||||
struct ifinfomsg *i;
|
struct ifinfomsg *i;
|
||||||
|
struct rtattr *a;
|
||||||
|
int la;
|
||||||
|
|
||||||
if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) {
|
if (nlmsg->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) {
|
||||||
_e("Packet too small or truncated!");
|
_e("Packet too small or truncated!");
|
||||||
@@ -172,6 +217,8 @@ static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
|
|||||||
net_cond_set(ifname, "exist", 1);
|
net_cond_set(ifname, "exist", 1);
|
||||||
net_cond_set(ifname, "up", i->ifi_flags & IFF_UP);
|
net_cond_set(ifname, "up", i->ifi_flags & IFF_UP);
|
||||||
net_cond_set(ifname, "running", i->ifi_flags & IFF_RUNNING);
|
net_cond_set(ifname, "running", i->ifi_flags & IFF_RUNNING);
|
||||||
|
if (!(i->ifi_flags & IFF_UP) || !(i->ifi_flags & IFF_RUNNING))
|
||||||
|
ifdown = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RTM_DELLINK:
|
case RTM_DELLINK:
|
||||||
@@ -180,6 +227,7 @@ static void nl_link(struct nlmsghdr *nlmsg, ssize_t len)
|
|||||||
net_cond_set(ifname, "exist", 0);
|
net_cond_set(ifname, "exist", 0);
|
||||||
net_cond_set(ifname, "up", 0);
|
net_cond_set(ifname, "up", 0);
|
||||||
net_cond_set(ifname, "running", 0);
|
net_cond_set(ifname, "running", 0);
|
||||||
|
ifdown = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RTM_NEWADDR:
|
case RTM_NEWADDR:
|
||||||
@@ -211,6 +259,9 @@ static void nl_callback(void *arg, int sd, int events)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for interface changes -> loss of default route */
|
||||||
|
ifdown = 0;
|
||||||
|
|
||||||
for (nh = (struct nlmsghdr *)buf; !nlmsg_validate(nh, len); nh = NLMSG_NEXT(nh, len)) {
|
for (nh = (struct nlmsghdr *)buf; !nlmsg_validate(nh, len); nh = NLMSG_NEXT(nh, len)) {
|
||||||
//_d("Well formed netlink message received. type %d ...", nh->nlmsg_type);
|
//_d("Well formed netlink message received. type %d ...", nh->nlmsg_type);
|
||||||
if (nh->nlmsg_type == RTM_NEWROUTE || nh->nlmsg_type == RTM_DELROUTE)
|
if (nh->nlmsg_type == RTM_NEWROUTE || nh->nlmsg_type == RTM_DELROUTE)
|
||||||
@@ -218,6 +269,53 @@ static void nl_callback(void *arg, int sd, int events)
|
|||||||
else
|
else
|
||||||
nl_link(nh, len);
|
nl_link(nh, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linux doesn't send route changes, when interfaces go down, so
|
||||||
|
* we need to check ourselves, e.g. for loss of default route.
|
||||||
|
*/
|
||||||
|
if (ifdown) {
|
||||||
|
unsigned int seq = 0;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
sd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
||||||
|
if (sd < 0) {
|
||||||
|
_pe("netlink socket");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
nh = (struct nlmsghdr *)buf;
|
||||||
|
nh->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
||||||
|
nh->nlmsg_type = RTM_GETROUTE;
|
||||||
|
nh->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
|
||||||
|
nh->nlmsg_seq = seq++;
|
||||||
|
nh->nlmsg_pid = 1;
|
||||||
|
|
||||||
|
if (send(sd, nh, nh->nlmsg_len, 0) < 0) {
|
||||||
|
_pe("Failed netlink route request");
|
||||||
|
close(sd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = recv(sd, buf, sizeof(buf), 0);
|
||||||
|
close(sd);
|
||||||
|
|
||||||
|
for (; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
|
||||||
|
struct in_addr dst = { 0 };
|
||||||
|
struct in_addr gw = { 0 };
|
||||||
|
|
||||||
|
if (nl_default(nh, &dst, &gw))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_d("default via %s\n", inet_ntoa(gw));
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We already get notification when adding default rt */
|
||||||
|
if (!found)
|
||||||
|
cond_clear("net/route/default");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nl_reconf(void *arg)
|
static void nl_reconf(void *arg)
|
||||||
@@ -236,8 +334,8 @@ static plugin_t plugin = {
|
|||||||
|
|
||||||
PLUGIN_INIT(plugin_init)
|
PLUGIN_INIT(plugin_init)
|
||||||
{
|
{
|
||||||
int sd;
|
|
||||||
struct sockaddr_nl sa;
|
struct sockaddr_nl sa;
|
||||||
|
int sd;
|
||||||
|
|
||||||
sd = socket(AF_NETLINK, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, NETLINK_ROUTE);
|
sd = socket(AF_NETLINK, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, NETLINK_ROUTE);
|
||||||
if (sd < 0) {
|
if (sd < 0) {
|
||||||
|
|||||||
+41
@@ -186,6 +186,44 @@ static void fs_remount_root(int fsckerr)
|
|||||||
}
|
}
|
||||||
#endif /* SYSROOT */
|
#endif /* SYSROOT */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Opinionated file system setup. Checks for critical mount points and
|
||||||
|
* mounts them as most users expect. All file systems are checked with
|
||||||
|
* /proc/mounts before mounting.
|
||||||
|
*
|
||||||
|
* Embedded systems, and other people who want full control, can set up
|
||||||
|
* their system with /etc/fstab, which is handled before this function
|
||||||
|
* is called. For systems like Debian/Ubuntu, who only have / and swap
|
||||||
|
* in their /etc/fstab, this function does all the magic necessary.
|
||||||
|
*/
|
||||||
|
static void fs_finalize(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Some systems rely on us to both create /dev/shm and, to mount
|
||||||
|
* a tmpfs there. Any system with dbus needs shared memory, so
|
||||||
|
* mount it, unless its already mounted, but not if listed in
|
||||||
|
* the /etc/fstab file already.
|
||||||
|
*/
|
||||||
|
if (!fismnt("/dev/shm")) {
|
||||||
|
makedir("/dev/shm", 0777);
|
||||||
|
mount("shm", "/dev/shm", "tmpfs", 0, "mode=0777");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modern systems use /dev/pts */
|
||||||
|
if (!fismnt("/dev/pts")) {
|
||||||
|
makedir("/dev/pts", 0755);
|
||||||
|
mount("devpts", "/dev/pts", "devpts", 0, "gid=5,mode=620,ptmxmode=0666");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modern systems use tmpfs for /run */
|
||||||
|
if (!fismnt("/run"))
|
||||||
|
mount("tmpfs", "/run", "tmpfs", 0, "mode=0755,nosuid,nodev,noexec,relatime");
|
||||||
|
|
||||||
|
/* Modern systems use tmpfs for /tmp */
|
||||||
|
if (!fismnt("/tmp"))
|
||||||
|
mount("tmpfs", "/tmp", "tmpfs", 0, "mode=0755,nosuid,nodev");
|
||||||
|
}
|
||||||
|
|
||||||
static void fs_mount(void)
|
static void fs_mount(void)
|
||||||
{
|
{
|
||||||
if (!rescue)
|
if (!rescue)
|
||||||
@@ -201,6 +239,9 @@ static void fs_mount(void)
|
|||||||
plugin_run_hooks(HOOK_MOUNT_POST);
|
plugin_run_hooks(HOOK_MOUNT_POST);
|
||||||
|
|
||||||
run("swapon -ea");
|
run("swapon -ea");
|
||||||
|
|
||||||
|
_d("Finalize, ensure common file systems are available ...");
|
||||||
|
fs_finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+1
-1
@@ -206,7 +206,7 @@ int reboot_main(int argc, char *argv[])
|
|||||||
|
|
||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
if (do_halt(NULL))
|
if (do_halt(NULL))
|
||||||
do_kill(SIGUSR1, msg);
|
do_kill(SIGUSR2, msg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_POWEROFF:
|
case CMD_POWEROFF:
|
||||||
|
|||||||
@@ -31,21 +31,24 @@
|
|||||||
* does on USR1 with their FIFO/D-Bus.
|
* does on USR1 with their FIFO/D-Bus.
|
||||||
*
|
*
|
||||||
* SIGUSR1
|
* SIGUSR1
|
||||||
* Calls shutdown hooks, including HOOK_SHUTDOWN, stops all running
|
* Restarts API (initctl) socket, like SysV init and systemd does
|
||||||
* processes, and unmounts all file systems. Then tells kernel to
|
* on USR1 with their FIFO/D-Bus.
|
||||||
* halt. Most people these days want SIGUSR2 though.
|
|
||||||
*
|
*
|
||||||
* (SysV init and systemd use this to re-open their FIFO/D-Bus.)
|
* Finit <= 4.0 used to perform a system halt on USR1. This caused
|
||||||
|
* some quite nasty problems on systems with both systemd/sysvinit
|
||||||
|
* installed alongside finit. For compatibility reasons Finit 4.1
|
||||||
|
* changed to partial SIGHUP (api_exit/init).
|
||||||
*
|
*
|
||||||
* SIGUSR2
|
* SIGUSR2
|
||||||
* Like SIGUSR1, but tell kernel to power-off the system, if ACPI
|
* Calls shutdown hooks, including HOOK_SHUTDOWN, stops all running
|
||||||
* or similar exists to actually do this. If the kernel fails
|
* processes, and unmounts all file systems. Then tells kernel to
|
||||||
* power-off, Finit falls back to halt.
|
* power-off the system, if ACPI or similar exists to actually do
|
||||||
|
* this. If the kernel fails power-off, Finit falls back to halt.
|
||||||
*
|
*
|
||||||
* (SysV init N/A, systemd dumps its internal state to log.)
|
* (SysV init N/A, systemd dumps its internal state to log.)
|
||||||
*
|
*
|
||||||
* SIGTERM
|
* SIGTERM
|
||||||
* Like SIGUSR1, but tell kernel to reboot the system when done.
|
* Like SIGUSR2, but tell kernel to reboot the system when done.
|
||||||
*
|
*
|
||||||
* (SysV init N/A, systemd rexecutes itself.)
|
* (SysV init N/A, systemd rexecutes itself.)
|
||||||
*
|
*
|
||||||
@@ -323,7 +326,7 @@ static void sigint_cb(uev_t *w, void *arg, int events)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SIGUSR1: BusyBox style halt
|
* SIGUSR1: SysV init/systemd API socket restart
|
||||||
*/
|
*/
|
||||||
static void sigusr1_cb(uev_t *w, void *arg, int events)
|
static void sigusr1_cb(uev_t *w, void *arg, int events)
|
||||||
{
|
{
|
||||||
@@ -333,8 +336,9 @@ static void sigusr1_cb(uev_t *w, void *arg, int events)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
halt = SHUT_HALT;
|
/* Restart initctl API domain socket, similar to systemd/SysV init */
|
||||||
service_runlevel(0);
|
api_exit();
|
||||||
|
api_init(w->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -520,7 +524,7 @@ void sig_setup(uev_ctx_t *ctx)
|
|||||||
/* Standard SysV init calls ctrl-alt-delete handler */
|
/* Standard SysV init calls ctrl-alt-delete handler */
|
||||||
uev_signal_init(ctx, &sigint_watcher, sigint_cb, NULL, SIGINT);
|
uev_signal_init(ctx, &sigint_watcher, sigint_cb, NULL, SIGINT);
|
||||||
|
|
||||||
/* BusyBox init style signals for halt, power-off and reboot. */
|
/* BusyBox/SysV init style signals for halt, power-off and reboot. */
|
||||||
uev_signal_init(ctx, &sigusr1_watcher, sigusr1_cb, NULL, SIGUSR1);
|
uev_signal_init(ctx, &sigusr1_watcher, sigusr1_cb, NULL, SIGUSR1);
|
||||||
uev_signal_init(ctx, &sigusr2_watcher, sigusr2_cb, NULL, SIGUSR2);
|
uev_signal_init(ctx, &sigusr2_watcher, sigusr2_cb, NULL, SIGUSR2);
|
||||||
uev_signal_init(ctx, &sigpwr_watcher, sigusr2_cb, NULL, SIGPWR);
|
uev_signal_init(ctx, &sigpwr_watcher, sigusr2_cb, NULL, SIGPWR);
|
||||||
|
|||||||
Reference in new issue
Block a user