Compare commits

..
164 Commits
Author SHA1 Message Date
Joachim Nilsson 2b2fcb740c Fix installation paths and update README on building, bump version
The installation path for plugins was encoded wrong in the finit binary
if *not* unset, i.e., "prefix=".

Updated the README with information on all build related environment
variables.  Much of it is perhaps only needed for packagers and
distributions.

New version bump, v1.2 already.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-27 09:33:55 +02:00
Joachim Nilsson 7542f4e199 Update ChangeLog and bump version for release. 2012-09-26 23:17:18 +02:00
Joachim Nilsson 1fece1f9b5 Work around compiler error for breaking strict-aliasing rules
This commit fixes the following warning on an ARM eabi/uClibc system.
helpers.c:86: error: dereferencing pointer 'a' does break strict-aliasing rules

The fix is trivial. Simply set IPv4 addressing scheme in the
struct ifreq instead of the struct sockaddr_in, whic is just
a pointer into the same ifreq anyway.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 23:10:53 +02:00
Joachim Nilsson 814ff1f77e Fix build problem on ARM eabi/uClibc by removing unused Linux header file.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 23:00:46 +02:00
Joachim Nilsson fbfffbc9a4 Eliminate name clash with system signal.h header file.
Tried to solve the signal.h name clash by using #include_next, but
seeing as this is not recommended[1] and breaks builds on some cross
compilers, the files were simply renamed: signal.[ch] --> sig.[ch]

[1] - http://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 22:57:25 +02:00
Joachim Nilsson e496913f5c README: Redo feature table into a definition list.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 13:53:25 +02:00
Joachim Nilsson 5bc9ff0e20 README: Slight syntax change in feature table
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 13:49:32 +02:00
Joachim Nilsson dd0220fd2c Update and clarify README
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 13:47:57 +02:00
Joachim Nilsson bb0a378f1c Rename README --> README.rst and symlink README to it.
This change is purely for people interacting with the GitHub interface.
The README itself is written in the plain text reST format.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 13:30:05 +02:00
Joachim Nilsson 2a025356d4 Bump version, update README and add TODO and dist: target to Makefile
Preparing for 1.0 release.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 13:20:21 +02:00
Joachim Nilsson c49d89dfe0 Revert new experimental libev backend due to time constraints
Due to time constraints I had to revert the new libev backend to the
service, I/O and signals monitor.  Employed instead is the tried and
tested signals based service monitor, with a small extension for an
additional I/O monitor using poll() for the I/O plugins to use.

Tried restoring the startx finit.conf directive on top of the service
implementation. However, it's currently not usable to run /usr/bin/startx
for any other user than root. I recommend using the examples/finit.conf
and run /usr/sbin/gdm instead.

finit.c:
        New run_loop() function, replaces libev ev_run().

helpers.c:
        Refactor start_process() into svc_start().

plugin.c:
        Add fds[] array for use in the io_monitor() called by the
        new run_loop().

signal.c:
        Ignore SIGCHLD. Handled by waitpid() in svc_monitor() now,
        which is called by the new run_loop().

svc.c:
        svc_register(): Optional @username parsing for the command line.
        svc_monitor(): Replaced libev callback with waitpid()
        svc_start(): Refactored to use most of helpers.c:start_process()

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-26 12:18:54 +02:00
Joachim Nilsson 75eb5cc043 Move fork() of console to run_getty() and remove startx conf option
New function helpers.c:run_getty() refactored from main(). Used to
start a default console getty.

Removed startx finit.conf option, superseded by service statement,
see examples/finit.conf for a working use case.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-25 15:20:55 +02:00
Joachim Nilsson dfa0fe6428 Refactor conf-file parser into a file of its own.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-25 14:49:33 +02:00
Joachim Nilsson 0e02429e75 Convert finit to use libev and fix so plugin ctors runs on dlopen().
Lots of cleanup and simplification of the main code in this commit.
Most notably libev has been added to take care of the main loop and
monitor services. Still TODO is migrating to use the libev signal
handling.

Convert initctl.c:listen_initctl() to a plugin instead.  This also
meant introducing a new form of I/O plugin to finit, also handled
by libev.

Load plugins *after* we've setup the base filesystem (BASEFS) in case
plugins reside on a filesystem not reachable before "mount -a" has run.
This also has the side effect of lining up nicely with the first level
plugin hooks.

If a plugin wants to hook up with a loded service we connect them by
their respective numeric IDs in plugin_register().  I.e., the service
monitor checks if a service has a registered callback, which in turn
decides if a service should be started, stopped or reloaded.

Rip out old EeePC distribution defines from finit.h, none of it really
applies anymore.  If you need distribution specific settings this is
the place to put them.

Make hookpoint names (#defines) clearer: after BASEFS, after networking,
after all setup, etc.

Use #inlude_next <signal.h> in signal.h to include system header file!

Simplify service monitor: move essential code to svc.c and rip out
the TIPC dependency. Write your own service.so plugin, or wait for
a more complete example of how to extend service monitoring using
the primitives in svc.c

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-25 14:23:23 +02:00
Joachim Nilsson 5dda9051ac Refactor main() into more functions and convert #ifdef hell into plugins.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-21 03:32:07 +02:00
Joachim Nilsson 239772d667 Add basic support for dynamically loadable plugins
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-21 00:33:46 +02:00
Joachim Nilsson a0fa877520 Move example configuration files to examples subdirectory
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-21 00:31:13 +02:00
Joachim Nilsson 23ef745985 Remove deprecated finit implementations, see the 0.6-pre tag for reference.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-20 17:54:29 +02:00
Joachim Nilsson 077a7e82e0 Debian now boots to X!
finit.conf:
        Use this as /etc/finit.conf on a Debian 6.0 based system with X
        installed and sysklogd instead of rsyslogd.  Works.

services:
        Alternative method for extending the finit boot procedure. Simply
        place this script file in an /etc/finit.d/ directory.  The script
        uses the standard run-parts tool to chain load other start scripts.

helpers.c:
        o New functions:
          - run(): home grown system() replacement
          - run_interactive(): display progress and status when called

        o Bugfix start_process(), make sure to use same signal setup for
          children as in run() and run_interactive(). Also, use execvp()
          instead of execv() to allow searching $PATH for executables.

finit.h:
        o Move signal specific code to new signal.h.
        o Bypass verbosity setting to let echo() always print to screen.

finit.c:
        o Make run_parts() the default, remove external deps, it works.

        o Use run() and run_interactive() to speed up execution further
          on embedded systems where forking is expensive.

        o Kernel cmdline "quiet" should not close STDIO since this makes
          it impossible to run some daemons and start scripts.  Instead,
          we let "quiet" toggle the finit verbosity setting.

        o Remove kernel cmdline "--verbose" (Upstart compat), to be used
          to enable verbose finit when kernel should be quiet.

        o Setup kernel specific settings in /etc/sysctl.conf

        o Fix D-Bus startup problems. Probably what caused X from not
          working initially. Silly rabbit.

        o Use system() workaround to start X, cannot get it to start
          at all using run() or run_interactive() at the moment.

signal.h:
        New file, header file for signal.c.  Was about time.

signal.c:
        Remove blocking of SIGCHLD from sig_setup(), instead we setup
        SIGCHLD early in sig_init() to handle fork() in run() & C:o.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-20 17:50:53 +02:00
Joachim Nilsson d21dc2b477 Westermo service starter and supervisor, inspired by daemontools
finit.c:
        o New service and shell_service stanzas for finit.conf
        o Run service_startup() before /etc/finit.d/ hooks
        o Run service_monitor() at end of startup

helpers.c:
        o Several new functions:
          - print_desc() displays a service starting up
          - print_result() shows if service started OK or not
          - start_process() is used by the services framework

svc.c:
        Generic API for managing svc_t structures

ipc.o:
        TIPC based framework for communicating with the service monitor.
        E.g., to relay (re)configuration signals from a Web/CLI
        front-end via finit to one or many setup daemons, and back.

services.c:
        Service monitor framework

strlcpy.c:
        Secure strncpy() replacement from OpenBSD under the free ISC License.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-20 01:16:00 +02:00
Joachim Nilsson c0356b5c7a Massive cleanup to be able to boot Debian 6.0
Update license and copyright information details in all files.
Much cleanup by moving hard coded strings/data to #defines and using more
common default values for each such #define.

finit.c:
        o Make sdown[], startx[] allocated strings by default NULL
        o This fixes the issues where the shutdown handler segfaulted
        o Add ability to handle NULL input to build_cmd() by allocating space
        o Ignore kernel cmdline "quiet" if in debug mode
        o Add support for "network" stanza in finit.conf
        o Mount -n to skip removing /etc/mtab
        o Call swapon to enable swap if enabled in /etc/fstab
        o Cleanup /tmp, /var/run and /var/lock
        o Move sig_setup() *after* mount, sig_init() otoh runs early
        o Start initctl monitor before forking off startx/getty process
        o The startx process is now the console process. Only a getty is
          started when in debug mode. Otherwise only X is started if it
          is properly setup in /etc/finit.conf
        o NOTE: Currently X evdev does not work!
        o Support for /usr/sbin/services.sh has been replaced with finit
          now instead supporting builtin run-parts for /etc/finit.d/

helpers.c:
        o Bug fixes in run_parts() and also added chdir(oldpwd) at bottom.
        o New functions:
          - getuser() similar to getgroup()
          - cls() clear screen, only runs when not in debug mode
          - set_procname() used to set name "console" on console process
          - set_hostname() encapsulates /etc/hostname and sethostname()

signal.c:
        o Split sig_setup() in two: sig_init() and sig_setup()
          The former to be called as soon as possible, while latter is
          supposed to run when the base filesystem is properly up.
        o Remove hard coded distribution specific progress bar write()
        o Add debug messages to do_shutdown()
        o Remove any lingering sync files in sig_setup()

initctl.c:
        o Add debug messages and a new default: case to catch stray runlevels

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-19 18:06:12 +02:00
Joachim Nilsson 855c7d8251 Assume kernel has devtmpfs enabled --> cleanup device creation & mount
Cleanup device creation and initial mount by assuming that the kernel
has devtmpfs enabled.  This is the default for most modern GNU/Linux
distributions.  See http://lwn.net/Articles/331818/ for more info.

Also, since finit is targeted at deeply embedded systems hooks for the
BusyBox udev replacement, mdev has been added.  If MDEV is defined in
the build it will take care of both hotplugging of devices and initial
setup of /dev

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-17 16:05:41 +02:00
Joachim Nilsson 2f527215d0 Compat kernel command line debug option --verbose
Check for "--verbose", as well as "finit_debug", on kernel command
line to enable debugging of finit.  The former is a compatibility
option with upstart, see http://upstart.ubuntu.com/wiki/Debugging

Add the following to the kernel command line to enable:

    "init=/sbin/finit --verbose"

Without the quote characters.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-17 11:09:35 +02:00
Joachim Nilsson 5da4f4cfc3 Add support for standard UNIX comment chars in finit.conf
finit.c:
        Skip standard UNIX comment character '#' if it appears at the
        beginning of a row in finit.conf

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-17 10:43:06 +02:00
Joachim Nilsson b0aec188bc Further cleanup, move signal setup to a file of its own.
finit.c:
        o Perform signal setup as soon as possible, no need to do any
          mounting of /proc or /sys beforehand
        o Move signal setup and callbacks to a file of its own
        o Use more #defines for hard coded strings
        o Use a more neutral default hostname

signal.c:
        o New file, for setup and signal handlers
        o Add support for SIGSTOP/SIGSTP and SIGCONT.  This pauses finit
          respawning of xinit/shell.  Useful for, e.g., debugging
        o Document each ignored and handled signal better
        o Disable SIGUSR1 and SIGUSR2 for now, will be reenabled later

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-17 10:41:18 +02:00
Joachim Nilsson 4657d9713a Minor cleanup. Moved code around a bit, to functions, away from main().
This commit is in preparation for importing the Westermo code changes.
Slowly refactoring the finit core into a more modularized unit to be a
bit more maintainable.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-17 01:51:37 +02:00
Joachim Nilsson a654d99b92 Archive previous versions for reference.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-14 13:23:17 +02:00
Joachim Nilsson e2c4a6ceaf Remove optional --directisa call to hwclock, this is the default anyway.
This is a followup to Olivier Blin's patch from 88ffb93 in that it
applies the same patch to finit-mod.c that is already in finit.c, or
finit-alt.c as it was called then.

Also, the optional --directisa argument to hwclock is not necessary.
The hwclock utility has a built-in fallback to use excplicit I/O over
the /dev/rtc in case the latter does not exist.  See the hwclock(8) man
page for more information on this.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-14 13:11:31 +02:00
Joachim Nilsson 5816c9cab9 Embedded finit for small embedded Linux systems and servers.
o Make finit-alt.c the new finit.c, save old finit.c as finit-org.c
o Keep original finit-alt.c for reference.
o Update README and ChangeLog with direction of this fork
o Correct ChangeLog date for v0.1 and set release date for
  the 0.6-pre release to 20100614, which is the last commit
  by the original author.
o Add standard LICENSE file for MIT License
o Add standard AUTHORS file to document history of project
o Bump version to 1.0-pre to distance fork from original

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-14 13:10:39 +02:00
Claudio Matsuoka f92438d42a Add hook to call shutdown script
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2010-07-14 18:09:16 -03:00
Claudio Matsuoka 6afbcbdd6e Mount /sys earlier (modprobe modprobe might use it) (blino)
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2009-04-29 12:49:01 -03:00
Claudio Matsuoka b9583fb354 Don't set Pentium M arch by default
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2009-04-14 12:59:48 -03:00
Claudio Matsuoka 37af9970d4 Disable annoying warning caused by attribute warn_unused_result
Example:
gcc -c -Os -Wall -DVERSION=\"0.6-pre\" -DWHOAMI=\"`whoami`@`hostname`\" -march=pentium-m -DBUILTIN_RUNPARTS -o finit-mod.o finit-mod.c
finit-mod.c: In function ‘main’:
finit-mod.c:107: warning: ignoring return value of ‘chdir’, declared with attribute warn_unused_result
finit-mod.c:137: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result
finit-mod.c:164: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result
finit-mod.c:168: warning: ignoring return value of ‘system’, declared with attribute warn_unused_result

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2009-04-14 12:55:44 -03:00
Claudio Matsuoka 3a7f7cd61a Create /dev/vcsX, /dev/vcsaX when building for Mandriva (caio)
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2009-04-14 12:46:29 -03:00
Claudio Matsuoka b11d6c6d4e Make the version information a debug message (caio)
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2009-04-06 11:42:53 -03:00
Claudio Matsuoka 88ffb9351d Don't mess mess localtime/UTC setting in finit
Signed-off-by: Olivier Blin <oblin@mandriva.com>
2009-04-06 11:36:19 -03:00
Claudio Matsuoka c70872f19e Honor quiet flag in kernel command line
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-12-04 14:25:29 -02:00
Claudio Matsuoka 9e0b22ddb6 Hmm, maybe not. We'll see.
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-10-16 14:28:00 -02:00
Claudio Matsuoka 321264f0dc So hnoring quiet was important after all
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-10-16 13:51:21 -02:00
Claudio Matsuoka 65c971925c Remove usplash and nologin from Asus legacy code
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-10-10 13:03:31 -03:00
Claudio Matsuoka a2de2c1591 Add comment for DISPLAY setting
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-10-07 17:19:38 -03:00
Claudio Matsuoka 85fedac866 Set DISPLAY before invoking xinit (miura)
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-10-06 14:33:13 -03:00
Claudio Matsuoka 29ab953a87 Make startx command configurable from finit.conf
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-10-01 16:50:38 -03:00
Claudio Matsuoka 1843a0e66f Don't close descriptors on kernel "quiet" flag
(Asus legacy). Closing them prevents fsck output when booting quietly.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-09-11 16:45:19 -03:00
Claudio Matsuoka 6a8a3fd4ab Remove timestamping debug messages
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-09-04 15:24:24 -03:00
Claudio Matsuoka d096efe643 Remove extra sleep before executing services.sh
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-09-04 14:02:51 -03:00
Claudio Matsuoka e33d385f0c Update gdium makefile
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-09-03 14:41:13 -03:00
Claudio Matsuoka 7ebc19782f Update changelog
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-09-02 13:07:28 -03:00
Claudio Matsuoka 4af58f8bb0 Disable USE_VAR_RUN_RESOLVCONF for Mandriva, unset TERM
Unsetting TERM in distributions using bash as /bin/sh prevents execution
of loadkeys from bashrc when creating the user environment to run X

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-09-02 13:03:25 -03:00
Claudio Matsuoka ed4abc952a Unmount all filesystems before rebooting
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-27 17:17:26 -03:00
Claudio Matsuoka 52feb6f51c Invoke xinit directly instead of startx
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-26 19:10:09 -03:00
Claudio Matsuoka c7c388e567 Remove consolekit and superfluous 0.5s delay
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-25 15:19:34 -03:00
Claudio Matsuoka 95a70ed2af Update changelog
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-25 13:53:02 -03:00
Claudio Matsuoka 4554377e4d Don't start consolekit manually in mandriva
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-25 13:31:36 -03:00
Claudio Matsuoka 3811275df5 Post-0.5 release
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-21 15:32:55 -03:00
Claudio Matsuoka 7360ef1f08 Fix distribution filelist
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-21 15:31:38 -03:00
Claudio Matsuoka 529224153f Update docs for 0.5
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-21 15:30:34 -03:00
Claudio Matsuoka 0f8393ef0e Start dbus directly instead of calling initscript
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-20 13:13:10 -03:00
Claudio Matsuoka a1d7e48225 Improve profiling messages
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-19 15:11:47 -03:00
Claudio Matsuoka 938773765c Add some profiling aids
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-19 13:58:19 -03:00
Claudio Matsuoka 367049a11c Set time value before using it!
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-19 13:41:16 -03:00
Claudio Matsuoka efcdc141c8 Use relative timestamp
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-19 13:25:10 -03:00
Claudio Matsuoka dfed328d47 Timestamp fixes
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-19 10:27:42 -03:00
Claudio Matsuoka 804aa3c747 Add timestamps to debug messages to help profiling
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-19 10:25:42 -03:00
Claudio Matsuoka 3ce7638dab Update changelog
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-15 19:08:39 -03:00
Claudio Matsuoka b0746f5220 Add bloat for gnome-volume-manager: start dbus and consolekit
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-15 18:59:49 -03:00
Claudio Matsuoka c324eff01a New README with better SNR
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-13 15:56:59 -03:00
Claudio Matsuoka a6f534621c Fix filesystem initialization order
Fsck filesystems before mounting root as read-write. Mountdev and
device creation can stay there because they're tmpfs.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-13 13:14:33 -03:00
Claudio Matsuoka b0e3dbc47f Add .gitignore
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-12 18:01:44 -03:00
Claudio Matsuoka 220b2c9ae3 Create basic device nodes when mounting /dev as tmpfs
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-12 18:00:37 -03:00
Claudio Matsuoka 173853ca17 finit.conf commands accepts multiple parameters
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-11 19:02:55 -03:00
Claudio Matsuoka 9f83bbe788 Allow creation of device nodes from configuration file
Using command "mknod", same syntax as mknod(1)

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-08-11 18:03:52 -03:00
Claudio Matsuoka a187b88dd9 Final changes to boot Guillemot
- call shutdown() directly instead of raising signal
- use blino's sanity check for /dev/null

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-07-04 17:24:25 -03:00
Claudio Matsuoka 134d9f3463 Mount /dev as tmpfs before creating directories inside
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-27 08:56:47 -03:00
Claudio Matsuoka 25e9d84673 Add experimental mountdev option
If "mountdev" is specified in /etc/finit.conf, finit-alt will try
to mount tmpfs on /dev prior to creating device nodes.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-25 19:10:36 -03:00
Claudio Matsuoka 765bef0991 Don't fix /dev/null permissions if it fails in creation
By doing so we'll be masking a symptom of the problem instead of fixing
it. If permissions of /dev/null fail, most likely other problems will
also happen (e.g. pts permissions). Keep /dev/null alarm (which leads
to X server starting problems) to alert us if something is wrong.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-18 11:39:38 -03:00
Claudio Matsuoka 7d10388158 Conditional build of /etc/resolveconf/run support
Xandros actually uses it.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-18 11:34:52 -03:00
Claudio Matsuoka a0382dfab8 Keep /etc/resolveconf/run code commented until we check Xandros
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-13 20:31:49 -03:00
Claudio Matsuoka ead2eb7076 Merge branch 'master' of claudio@git.mandriva.com:/people/blino/finit 2008-06-13 20:15:21 -03:00
Claudio Matsuoka 0f2a14bf4f Remove old code to load AGP drivers
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-13 19:58:31 -03:00
Claudio Matsuoka 4e8be438e9 Use smurfy's /dev/initctl handler
If we handle it using pselect() in the parent process we'll end up
with a lot of zombie processes because SIGCHLD is not handled correctly.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-13 19:55:34 -03:00
Olivier Blin 2f3404165f make sure /dev/null is world-writable 2008-06-06 18:35:44 +02:00
Olivier Blin ca9ee99f59 create resolv.conf symlink in /var 2008-06-06 17:52:00 +02:00
Olivier Blin 0ab62c8871 create /var/run/resolvconf/interface 2008-06-06 17:52:00 +02:00
Olivier Blin efdac3fc2d remove useless /etc/resolvconfig/run clean, it's a symlink to /var/run which is tmpfs 2008-06-06 17:52:00 +02:00
Olivier Blin c127735e2d do not create useless resolvconf and network dirs in /dev/shm 2008-06-06 17:51:53 +02:00
Olivier Blin d621b0ba15 include limits.h for INT_MAX 2008-06-06 17:42:26 +02:00
Claudio Matsuoka 33469873a5 Don't build vanilla finit
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-02 18:20:03 -03:00
Claudio Matsuoka 36043c04f9 Fix permission of utmp
Also remove other redundant or seemingly unneeded permission settings

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-02 17:28:31 -03:00
Claudio Matsuoka ec10fecd8d Add pterjan's services.sh
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-02 17:28:16 -03:00
Claudio Matsuoka 0fc7654a83 Set owner of /var/run/utmp to root:utmp
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-06-02 17:22:35 -03:00
Claudio Matsuoka ba9c897e83 Ajusted options for eeeXubuntu
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-31 16:28:19 -03:00
Claudio Matsuoka 4948844f82 Merged usplash support from smurfy's port
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-31 10:56:40 -03:00
Claudio Matsuoka 9f99f38561 Initial eeeXubuntu port merged from smurfy's port
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-31 10:43:43 -03:00
Claudio Matsuoka f516108ca6 Merge branch 'master' of cmatsuoka@helllabs.org:git/eeepc 2008-05-29 11:13:44 -03:00
Claudio Matsuoka 04b91da9f9 Remove unused variables
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-28 19:24:18 -03:00
Claudio Matsuoka f94504ad96 Write runlevel to utmp
This is needed by Printerdrake (by Pascal Terjan)

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-28 12:51:30 -03:00
Claudio Matsuoka 698c5a1852 Changelog updates
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-27 16:45:20 -03:00
Claudio Matsuoka d5037d1352 Finit-alt listens to /dev/initctl
This allows us to use the standard reboot utility in Linux to perform
a fast reboot.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-27 16:29:34 -03:00
Claudio Matsuoka 57ad91136b Build finit-alt from finit-alt.c
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-26 20:09:25 -03:00
Claudio Matsuoka 9488e65998 Merge branch 'master' of cmatsuoka@helllabs.org:git/eeepc 2008-05-18 22:36:50 -03:00
Claudio Matsuoka 19540d148e Cosmetic coding style fix
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-18 22:36:21 -03:00
Claudio Matsuoka df14fd5255 Post-0.4
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-16 16:23:19 -03:00
Claudio Matsuoka 821a6853fe Version 0.4
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-16 16:20:29 -03:00
Claudio Matsuoka dbdf8ccc72 Merge branch 'master' of cmatsuoka@helllabs.org:git/eeepc 2008-05-16 10:54:27 -03:00
Claudio Matsuoka b2f143e623 Rollback removal of /dev/tty0 creation
This is need by xorg to start

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-16 10:53:13 -03:00
Claudio Matsuoka 2ffafc3d03 More robust command line parsing
Allow multiple spaces or tabs between keyword and argument, also set
hostname only once.

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-16 09:19:29 -03:00
Claudio Matsuoka 3158733ced Update example services script
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-15 18:36:39 -03:00
Claudio Matsuoka 1aa6358611 Mount "none" as pseudo filesystems
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-15 18:27:55 -03:00
root ce998373e5 Merge branch 'master' of cmatsuoka@helllabs.org:git/eeepc 2008-05-15 20:39:59 -03:00
root d0b6457f01 Better string matching
Signed-off-by: root <root@eviltwin.(none)>
2008-05-15 20:32:51 -03:00
root 349593d41b Configure hostname from finit.conf
Signed-off-by: root <root@test.(none)>
2008-05-15 17:47:14 -03:00
Claudio Matsuoka b8daa9c869 Documentation update
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-15 17:39:01 -03:00
root f21b0a2580 Open terminal in VT2 using openvt(1)
Signed-off-by: root <root@test.(none)>
2008-05-15 17:37:51 -03:00
Claudio Matsuoka 4e18bc3724 Fix module name in finit.conf example
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-14 17:33:22 -03:00
Claudio Matsuoka 90c8c73470 Fix fsck options (hopefully)
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-14 13:31:53 -03:00
Claudio Matsuoka c8e7b34b4c Move conffile parsing to proper function
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-08 11:46:21 -03:00
Claudio Matsuoka 6ff7f2e52b Create tty0
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-05 16:06:40 -03:00
Claudio Matsuoka b6bf00ed06 *sigh*
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-05 16:00:28 -03:00
Claudio Matsuoka 136dfeb41a And I mean it!
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-05 15:55:20 -03:00
Claudio Matsuoka 7867db7b23 And do it right this time
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-05 15:34:21 -03:00
Claudio Matsuoka 75d755afad Chomp trailing LF in line from conf file
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-05 15:24:01 -03:00
Claudio Matsuoka 01509376cc Don't reboot automatically after fsck
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-05 14:51:23 -03:00
Claudio Matsuoka c55afaadb3 User, modules and checkfs configurable from /etc/finit.conf
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-05 13:41:01 -03:00
Claudio Matsuoka ccd49f2024 Dynamic username setting
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-02 17:33:32 -03:00
Claudio Matsuoka 0fdf97653f Document kernel command line parameters
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-02 15:35:51 -03:00
Claudio Matsuoka 9d164ac312 Enable runtime debug in finit-alt if DEBUG parameter is specified
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-05-02 15:34:13 -03:00
Claudio Matsuoka 5acd2cd441 Don't force fsck every time.
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-29 15:19:14 -03:00
Claudio Matsuoka 1f7eab37a0 Erm. Fix wrong string size in strncpy.
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-24 16:15:01 -03:00
Claudio Matsuoka d87fb47cf3 finit-mdv checks filesystem if CHECKFS= parameter specified
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-24 16:05:46 -03:00
Claudio Matsuoka 7caf633259 Mount /proc/bus/usb
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-24 13:55:45 -03:00
Claudio Matsuoka ba6470f5a6 Update documentation
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-18 17:20:51 -03:00
Claudio Matsuoka fa23155593 Change console.lock path to /var/run/console/
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-18 17:16:50 -03:00
Claudio Matsuoka 996cb2ec1e Merge branch 'master' of cmatsuoka@helllabs.org:git/eeepc
Conflicts:

	Changelog
	finit-mod.c

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-18 16:03:21 -03:00
Claudio Matsuoka 4e3d6ec976 Handle pam_console permissions in finit-alt for Mandriva
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-18 16:01:11 -03:00
Claudio Matsuoka 0857a0846f Ignore signal instead of setting to an empty handler
As suggested by Metalshark

Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-04-18 15:48:15 -03:00
Claudio Matsuoka a3ad99798e Don't mount dev as tmpfs
Otherwise we won't be able to mount stuff

Signed-off-by: Claudio Matsuoka <claudio@frohike.(none)>
2008-03-20 05:12:58 -03:00
Claudio Matsuoka c79b823f17 Fix default user setting in Makefile
Otherwise the default user name is set to the name of the current user

Signed-off-by: Claudio Matsuoka <claudio@frohike.(none)>
2008-03-20 05:10:07 -03:00
Claudio Matsuoka 71ce4b98e9 Minor documentation updates
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-18 16:38:08 -03:00
Claudio Matsuoka 9908a6e680 Documentaion update
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-18 16:24:40 -03:00
Claudio Matsuoka f94a76ed17 Minor documentation updates
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-17 12:29:47 -03:00
Claudio Matsuoka 6fc2a6b108 Add KDE dbus note
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 18:37:07 -03:00
Claudio Matsuoka a52c932085 Cosmetic changes
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 18:03:23 -03:00
Claudio Matsuoka 2e7952645a Make it like the original
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 17:56:05 -03:00
Claudio Matsuoka 494f182b13 Minor fixes, updated comments
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 17:17:17 -03:00
Claudio Matsuoka 5ad9ff48c5 Use macro for line size, reuse line buffer for hostname and filename
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 17:07:14 -03:00
Claudio Matsuoka b5e2af21a6 Add example services.sh for Mandriva 2008 running KDE
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 16:06:38 -03:00
Claudio Matsuoka eb5445628f Mount /dev as tmpfs in finit-alt if MAKE_DEVICES is set
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 15:45:03 -03:00
Claudio Matsuoka 89854a579f Add nash-plugin patch, move Mandriva specifics to its own README file
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 13:57:22 -03:00
Claudio Matsuoka 1c88ae1f61 Run-parts code cleanup and minor fixes
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-16 12:47:37 -03:00
Claudio Matsuoka f972ff4d30 /usr on squashfs must be mounted after creation of loop0
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-15 15:39:14 -03:00
Claudio Matsuoka 904c12d06a Add a contrib directory
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-15 14:37:46 -03:00
Claudio Matsuoka a85b0cf481 Remove USE_SQUASHFS hack
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-15 14:33:54 -03:00
Claudio Matsuoka 286711237d Fixed run-parts bug
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-15 14:31:34 -03:00
Claudio Matsuoka 434ec4c533 Add option to use built-in run-parts instead of /bin/run-parts
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-15 10:34:05 -03:00
Claudio Matsuoka 6371f82fea Always use /bin/run-parts in Mandriva with squashfs
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-14 17:36:26 -03:00
Claudio Matsuoka b2233a6f4b Merge branch 'master' of cmatsuoka@helllabs.org:git/eeepc 2008-03-14 16:44:24 -03:00
Claudio Matsuoka 6c807c3a95 Add a run-parts implementation, not sure if really needed
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-14 16:43:59 -03:00
Claudio Matsuoka e4f675fa1a Create loopback device in finit-alt (for squashfs)
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-14 14:16:29 -03:00
Claudio Matsuoka 880b5f8a92 Reboot/poweroff documentation update
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-11 09:09:07 -03:00
Claudio Matsuoka c8f171556b Rollback previous finit-alt initctl patch, not really needed.
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-10 19:14:26 -03:00
Claudio Matsuoka 2a9bfa7fd7 Default user for finit-alt configurable from Makefile
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-10 17:41:11 -03:00
Claudio Matsuoka 98624a3d21 Create initctl fifo in finit-alt
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-03-10 17:12:40 -03:00
Claudio Matsuoka 6565cc67ee Update version information to post-0.3
Signed-off-by: Claudio Matsuoka <cmatsuoka@gmail.com>
2008-02-23 08:55:12 -03:00
37 changed files with 3335 additions and 1102 deletions
+6
View File
@@ -0,0 +1,6 @@
*.o
.*.d
*.so
*.gz
*.map
finit
+6
View File
@@ -0,0 +1,6 @@
Current Maintainer(s):
* Joachim Nilsson <troglobit@gmail.com>
Original Author(s):
* Claudio Matsuoka <cmatsuoka@gmail.com>
+62
View File
@@ -0,0 +1,62 @@
1.2 (20120927)
- Fix installation paths encoded in finit binary
- Update README with section on building and enviroment variables
1.1 (20120927)
- Build fixes for ARM eabi/uClibc
- Rename signal.[ch]-->sig.[ch] to avoid name clash w/ system headers
1.0 (20120926)
- New plugin based system for all odd extensions
- New service monitor that restarts services if they die
- New maintainer at GitHub http://github.com/troglobit/finit
- Add standard LICENSE and AUTHORS files
- New focus: embedded systems and small headless servers
0.6 (20100614)
- don't start consolekit manually, dbus starts it (rtp)
- unmount all filesystems before rebooting
- disable USE_VAR_RUN_RESOLVCONF for Mandriva
- unset terminal type in Mandriva before running X
- remove extra sleep in finit-alt before calling services.sh (caio)
0.5 (20080821)
- add option to start dbus and consolekit before the X server
- finit-alt listens to /dev/initctl to work with reboot(8) (smurfy)
- write runlevel to utmp, needed by Printerdrake (Pascal Terjan)
- fix ownership of /var/run/utmp (reported by Pascal Terjan)
- remove obsolete code to load AGP drivers
- conditional build of /etc/resolveconf/run support
- add support to /var/run/resolvconf in Mandriva (blino)
O.4 (20080516)
- default username for finit-alt configurable in Makefile
- create loopback device node in finit-alt (for squashfs)
- add option to use built-in run-parts instead of /bin/run-parts
- ignore signal instead of setting to an empty handler (Metalshark)
- handle pam_console permissions in finit-alt for Mandriva
- add services.sh example and nash-hotplug patch for Mandriva
- mount /proc/bus/usb in Mandriva
- add runtime debug to finit-alt if finit_debug parameter is specified
- read configuration from /etc/finit.conf
- run getty with openvt on the virtual terminal
0.3 (20080223)
- Change poweroff method to reboot(RB_POWER_OFF) (Metalshark)
- Remove duplicate unionctl() reimplementation error
- Fix string termination in path creation
- Mount /var/lock and /var/run as tmpfs
0.2 (20080219)
- replace system("touch") with touch() in finit-mod (Metalshark)
- disable NO_HCTOSYS by default to match stock Eeepc kernel
- drop system("rm -f") to clean /tmp, its a fresh mounted tmpfs
- write ACPI sleep state to /sys/power/state instead of
/proc/acpi/sleep (Metalshark)
- use direct calls to set loopback instead of system("ifconfig")
- replace system("cat") and system("dd") with C implementation
- moved finit-mod and finit-alt helpers to helpers.c
- replace system("echo;cat") to draw shutdown splash with C calls
0.1 (20080214)
- initial release
-19
View File
@@ -1,19 +0,0 @@
0.3 ()
- Change poweroff method to reboot(RB_POWER_OFF) (Metalshark)
- Remove duplicate unionctl() reimplementation error
- Fix string termination in path creation
- Mount /var/lock and /var/run as tmpfs
0.2 (20080219)
- replace system("touch") with touch() in finit-mod (Metalshark)
- disable NO_HCTOSYS by default to match stock Eeepc kernel
- drop system("rm -f") to clean /tmp, its a fresh mounted tmpfs
- write ACPI sleep state to /sys/power/state instead of
/proc/acpi/sleep (Metalshark)
- use direct calls to set loopback instead of system("ifconfig")
- replace system("cat") and system("dd") with C implementation
- moved finit-mod and finit-alt helpers to helpers.c
- replace system("echo;cat") to draw shutdown splash with C calls
0.1 (20081214)
- initial release
+20
View File
@@ -0,0 +1,20 @@
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+89 -49
View File
@@ -1,65 +1,105 @@
CC = gcc # finit - The Improved fast init
CFLAGS = -Os -Wall -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\" #
LD = gcc # Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
LDFLAGS = # Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
LIBS = #
VERSION = 0.3 # Permission is hereby granted, free of charge, to any person obtaining a copy
PKG = finit-$(VERSION) # of this software and associated documentation files (the "Software"), to deal
DFILES = Makefile README finit.c finit-mod.c finit-alt.c helpers.c helpers.h # in the Software without restriction, including without limitation the rights
BINS = finit finit-mod finit-mdv # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
.PHONY: all romfs clean
#### Configurable parameters # Top directory for building complete system, fall back to this directory
ROOTDIR ?= $(shell pwd)
# Add -DDEBUG to build with debug messages, also drops to terminal after X # Installation paths, always prepended with DESTDIR if set
#CFLAGS += -DDEBUG prefix ?= /usr/local
sysconfdir ?= /etc
datadir = $(prefix)/share/doc/finit
mandir = $(prefix)/share/man/man8
# Parameters added by Metalshark # Plugin directory, fall back to this directory if unset in environment
PLUGIN_DIR ?= $(prefix)/lib/finit/plugins
# Use -march=pentium-m to build for Eeepc #VERSION ?= $(shell git tag -l | tail -1)
CFLAGS += -march=pentium-m VERSION ?= 1.2
EXEC = finit
PKG = $(EXEC)-$(VERSION)
ARCHIVE = $(PKG).tar.xz
OBJS = finit.o conf.o helpers.o sig.o svc.o plugin.o
OBJS += strlcpy.o
SRCS = $(OBJS:.o=.c)
DEPS = $(addprefix .,$(SRCS:.c=.d))
CFLAGS += -W -Wall -Werror -Os
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
CPPFLAGS += -U_FORTIFY_SOURCE
CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\"
CPPFLAGS += -DPLUGIN_PATH=\"$(PLUGIN_DIR)\"
LDFLAGS += -rdynamic
LDLIBS += -ldl
# Omit the first /sbin/hwclock if CONFIG_RTC_HCTOSYS is enabled in the kernel include common.mk
#CFLAGS += -DNO_HCTOSYS export PLUGIN_DIR ROOTDIR CPPFLAGS
# Append –directisa to /sbin/hwclock lines if the user has disabled all: Makefile $(EXEC)
# CONFIG_GENRTC and enabled CONFIG_RTC but not enabled CONFIG_HPET_TIMER $(MAKE) -C plugins $@
# and CONFIG_HPET_RTC_IRQ.
#CFLAGS += -DDIRECTISA
$(OBJS): Makefile
$(EXEC): $(OBJS)
.c.o: # @ln -sf /sbin/finit /sbin/init
$(CC) -c $(CFLAGS) -o $*.o $< install: all
@install -d $(DESTDIR)$(prefix)/sbin
@install -d $(DESTDIR)$(sysconfdir)
@install -d $(DESTDIR)$(datadir)
@install -d $(DESTDIR)$(mandir)
@for file in $(EXEC); do \
printf " INSTALL $(DESTDIR)$(prefix)/sbin/$$file\n"; \
install -m 0755 $$file $(DESTDIR)$(prefix)/sbin/$$file; \
done
$(MAKE) -C plugins $@
all: $(BINS) uninstall:
-@for file in $(EXEC); do \
finit: finit.o printf " REMOVE $(DESTDIR)$(prefix)/sbin/$$file\n"; \
$(LD) $(LDFLAGS) -o $@ $+ $(LIBS) rm $(DESTDIR)$(prefix)/sbin/$$file 2>/dev/null; \
strip $@ done
$(MAKE) -C plugins $@
finit-mod: finit-mod.o helpers.o
$(LD) $(LDFLAGS) -o $@ $+ $(LIBS)
strip $@
finit-mdv: finit-mdv.o helpers.o
$(LD) $(LDFLAGS) -o $@ $+ $(LIBS)
strip $@
finit-mdv.o: finit-alt.c Makefile
$(CC) -c $(CFLAGS) -DDIST_MDV -o $@ finit-alt.c
clean: clean:
rm -f *.o core *~ $(BINS) -@$(RM) $(OBJS) $(DEPS) $(EXEC)
$(MAKE) -C plugins $@
finit.o: finit.c Makefile distclean: clean
-@$(RM) $(JUNK) unittest *.o
finit-mod.o: finit-mod.c Makefile $(MAKE) -C plugins $@
dist: dist:
rm -Rf $(PKG) @echo "Building xz tarball of $(PKG) in parent dir..."
mkdir $(PKG) git archive --format=tar --prefix=$(PKG)/ $(VERSION) | xz >../$(ARCHIVE)
cp Makefile $(DFILES) $(PKG) @(cd ..; md5sum $(ARCHIVE) | tee $(ARCHIVE).md5)
tar cf - $(PKG) | gzip -c > $(PKG).tar.gz
rm -Rf $(PKG) # Include automatically generated rules, such as:
ls -l $(PKG).tar.gz # uncgi.o: .../some/dir/uncgi.c /usr/include/stdio.h
# but don't bother during clean!
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),distclean)
-include $(DEPS)
endif
endif
-77
View File
@@ -1,77 +0,0 @@
Eeepc "fastinit" reimplementations
----------------------------------
finit.c is a reimplementation of the Asus Eeepc fastinit program based
on its library calls. It tries to be an accurate re-creation and keeps
the original bugs and lack of optimization.
finit-mod.c is a fixed/improved version of finit.c.
finit-alt.c is a fixed/improved version of finit.c for alternative Linux
distributions running on the Eeepc (previously ffinit.c). Currently able
to boot unmodified Mandriva Linux.
See Makefile for configurable parameters to better suit your system.
* Eeepc boot process
The essential steps in the boot process carried out in initramfs are:
ROOT=`sed 's!.*root=\([^ ]*\).*!\1!' < /proc/cmdline`
mount -t proc proc /proc
mount -t ext2 -o ro $ROOT /mnt-system
mount -t ext3 -o rw /dev/sda2 /mnt-user
mount -t unionfs -o dirs=/mnt-user=rw:/mnt-system=ro unionfs /mnt
mount --move /mnt-system /mnt/mnt
umount -l /mnt-user
umount /proc
exec switch_root /mnt /sbin/fastinit "$@" </mnt/dev/console >/mnt/dev/console
If mounting the root filesystem fails, execute a maintenance shell. If
mounting the user filesystem fails, fsck and reboot.
* Utilities available in the Eeepc initramfs busybox:
[ cat cp cut dd
dmesg echo env expr false
grep insmod ln losetup ls
mdev mkdir mknod mount mv
pivot_root realpath rm rmmod sed
sh sleep switch_root test true
umount vi
* Devices in the Eeepc initramfs /dev:
console fb null ram0 sda1 sda2 sda3 sr0 tty0
Using finit with alternative systems
------------------------------------
Currently tested only with Mandriva 2008. Proceed with caution, there are
problems related to udev and pam.
1 - Add init=/sbin/finit-mdv to the kernel boot line
2 - Provide a suitable /usr/sbin/services.sh, this is the one I use in my
test system:
mkdir /var/lock/subsys
chmod 1777 /var/lock/subsys
/etc/init.d/network start
dhclient eth0
/sbin/start_udev&
/etc/init.d/portmap start
/etc/init.d/nfs-common start
3 - Provide /etc/hostname if you don't have it already
4 - Set the pointer device in the X server configuration to /dev/input/mice
5 - Have a user named "user", or change DEFUSER in the source file
Symlink
+1
View File
@@ -0,0 +1 @@
README.rst
+169
View File
@@ -0,0 +1,169 @@
==============================================================================
Finit — A fast plugin-based /sbin/init with service monitoring
==============================================================================
Welcome to finit!
This is a heavily extended version of the original /sbin/init replacement
finit_. The original was a reimplementation of the EeePC "fastinit" daemon
based on its system calls with gaps filled with frog DNA.
Focus of this extended version is on small embedded GNU/Linux systems and
headless miniature servers with a need for extremely fast boot. In such
environments configurations rarely change and setup is rather static and
straight forward.
In the world of finit we write C "scripts" to boot our system, this is what
gives the system its raw performance and the user full control.
If you chose finit you know what you want, a fast boot with no hassle.
Features
--------
**Service monitoring**
Restarting a service when it exits
**Plugins**
Extend and modify finit behavior. See examples in plugins/ directory.
Plugin capabilities:
* Service callbacks — should the service run/restart/stop?
* Hooks — hook into the boot at predefined points to extend finit
* I/O — listen to external events and control finit behaviour/services
Most extensions and functionality not purely related to what an /sbin/init
needs to start a system from the original finit_ has been reactored into
plugins with either hooks or I/O demands.
/etc/finit.conf
---------------
Contrary to most script based init alternatives (SysV init_, upstart_, OpenRC_
and the likes) finit reads its configuration from /etc/finit.conf, see the
source code for available options.
Try out the examples/finit.conf for a Debian 6.0 example configuration
capable of service monitoring SSH, sysklogd, gdm and a console getty!
/etc/finit.d
------------
At the end of the boot, when networking and all services are up, finit calls
its built-in run-parts(8) on the /etc/finit.d/ directory, akin to how the
/ec/rc.local file works in most other inits, only finit runs a directory of
scripts. This replaces the earlier /usr/sbin/services.sh support of the
original finit_.
Rebooting and Halting
---------------------
Finit handles SIGUSR1 and SIGUSR2 for reboot and halt, and listens to
/dev/initctl so standard Linux reboot and halt commands should also
work.
Building
--------
The finit build system does not employ the GNU Configure and Build System,
instead standard makefiles are used. The user is encouraged to make source
code changes, using defines and conditionally building plugins instead to
alter the behavior of finit.
The following environment variables are checked by the makefiles and control
what is built and where resulting binaries are installed.
**ROOTDIR=**
Top directory for building complete system, used in pretty printing
**PLUGINS=**
List of stock finit plugins to build and install.
**PLUGIN_DIR=**
Absolute path to where finit should look for dynamically loadable plugins
at runtime. At installation prepended by ''DESTDIR'' and ''prefix''-
**VERSION=**
Defaults to the currently released version of finit, e.g., 1.2 but can
be overridden by packages to add a suffix or completely alter the version.
**CFLAGS=**
Standard CFLAGS are inherited from the build enviornmant.
**CPPFLAGS=**
Standard CPPFLAGS are inherited from the build enviornmant.
**LDFLAGS=**
Standard LDFLAGS are inherited from the build enviornmant.
**LDLIBS=**
Standard LIBLIBS are inherited from the build enviornmant.
**prefix=**
Path to where resulting binaries should install to. Used in concert
with the ''DESTDIR'' variable. Defaults to /usr/local
**sysconfdir=**
Used after ''prefix'' to create the path to finit.conf configuration
file. Defaults to /etc
**DESTDIR=**
Used by packagers and distributions when building a relocatable
bundle of files. Alwawys prepended to the ''prefix'' destination
directory.
**Example**::
$ tar xfJ finit-1.2.tar.xz
$ PLUGINS="initctl.so hwclock.so" prefix= DESTDIR=/tmp/finit/dst \
make -C finit-1.2/ clean install
make: Entering directory `/home/troglobit/finit-1.2'
CC finit.o
CC conf.o
CC helpers.o
CC sig.o
CC svc.o
CC plugin.o
CC strlcpy.o
LINK finit
CC plugins/initctl.o
PLUGIN plugins/initctl.so
CC plugins/hwclock.o
PLUGIN plugins/hwclock.so
INSTALL /tmp/finit/dst/sbin/finit
INSTALL /tmp/finit/dst/lib/finit/plugins/initctl.so
INSTALL /tmp/finit/dst/lib/finit/plugins/hwclock.so
make: Leaving directory `/home/troglobit/finit-1.2'
In this example the finit-1.2.tar.xz archive is unpacked to the user's
home directory, built and installed to a temporary staging directory.
The enviroment variables ''prefix'', ''DESTDIR'' and ''PLUGINS'' are all
changed to suit this particular build.
Debugging
---------
Add finit_debug, or --debug, to the kernel command line to enable trace
messages. A console getty is always started, see the file finit.h for
more useful comile-time tweaks.
Contact
-------
Finit is maintained collaborativly at https://github.com/troglobit/finit —
please file a bug report, clone it, or send pull requests for bug fixes and
proposed extensions, or become a co-maintainer by contacting the main author.
Regards
/Joachim Nilsson <troglobit@gmail.com>
.. _finit: http://helllabs.org/finit/
.. _init: http://savannah.nongnu.org/projects/sysvinit
.. _upstart: http://upstart.ubuntu.com/
.. _openrc: http://www.gentoo.org/proj/en/base/openrc/
+5
View File
@@ -0,0 +1,5 @@
* FHS changes, see http://askubuntu.com/questions/57297/why-has-var-run-been-migrated-to-run
* Look at Erik Troan's nash linuxrc parser for more inspiration
* Look at how to support a standard SysV init runlevel mechanism
* Arguments to finit, like to SysV init "init q" to reload finit.conf at runtime, etc.
* Implement initctl stop|start|reload <SVC> and service <SVC> stop|start|reload on top
+23
View File
@@ -0,0 +1,23 @@
# Some junk files we always want to be removed when doing a make clean.
JUNK = *~ *.bak *.aux *.dvi *.idx *.ind *.log *.ps *.map .*.d DEADJOE semantic.cache *.gdb *.elf core core.*
MAKE := @$(MAKE)
MAKEFLAGS = --no-print-directory
# Smart autodependecy generation via GCC -M.
.%.d: %.c
@$(SHELL) -ec "$(CC) -MM $(CFLAGS) $(CPPFLAGS) $< \
| sed 's,.*: ,$*.o $@ : ,g' > $@; \
[ -s $@ ] || rm -f $@"
# Override default implicit rules
%.o: %.c
@printf " CC $(subst $(ROOTDIR)/,,$(shell pwd)/$@)\n"
@$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
%: %.o
@printf " LINK $(subst $(ROOTDIR)/,,$(shell pwd)/$@)\n"
@$(CC) $(CFLAGS) $(LDFLAGS) -Wl,-Map,$@.map -o $@ $^ $(LDLIBS$(LDLIBS-$(@)))
%.so: %.o
@printf " PLUGIN $(subst $(ROOTDIR)/,,$(shell pwd)/$@)\n"
@$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+145
View File
@@ -0,0 +1,145 @@
/* Parser for finit.conf
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include "finit.h"
#include "svc.h"
#include "helpers.h"
/* Match one command. */
#define MATCH_CMD(l, c, x) \
(!strncmp(l, c, strlen(c)) && (x = (l) + strlen(c)))
static char *build_cmd(char *cmd, char *line, int len)
{
int l;
char *c;
/* Trim leading whitespace */
while (*line && (*line == ' ' || *line == '\t'))
line++;
if (!cmd) {
cmd = malloc (strlen(line) + 1);
if (!cmd) {
_e("No memory left for '%s'", line);
return NULL;
}
*cmd = 0;
}
c = cmd + strlen(cmd);
for (l = 0; *line && *line != '#' && *line != '\t' && l < len; l++)
*c++ = *line++;
*c = 0;
_d("cmd = %s", cmd);
return cmd;
}
void parse_finit_conf(char *file)
{
FILE *fp;
char line[LINE_SIZE];
char cmd[CMD_SIZE];
/* Default username and hostname */
username = strdup(DEFUSER);
hostname = strdup(DEFHOST);
if ((fp = fopen(file, "r")) != NULL) {
char *x;
_d("Parse %s ...", file);
while (!feof(fp)) {
if (!fgets(line, sizeof(line), fp))
continue;
chomp(line);
_d("conf: %s", line);
/* Skip comments. */
if (MATCH_CMD(line, "#", x)) {
continue;
}
/* Do this before mounting / read-write */
if (MATCH_CMD(line, "check ", x)) {
strcpy(cmd, "/sbin/fsck -C -a ");
build_cmd(cmd, x, CMD_SIZE);
run_interactive(cmd, "Checking file system integrity on %s", x);
continue;
}
if (MATCH_CMD(line, "user ", x)) {
if (username) free(username);
username = build_cmd(NULL, x, USERNAME_SIZE);
continue;
}
if (MATCH_CMD(line, "host ", x)) {
if (hostname) free(hostname);
hostname = build_cmd(NULL, x, HOSTNAME_SIZE);
continue;
}
if (MATCH_CMD(line, "shutdown ", x)) {
if (sdown) free(sdown);
sdown = build_cmd(NULL, x, CMD_SIZE);
continue;
}
if (MATCH_CMD(line, "module ", x)) {
strcpy(cmd, "/sbin/modprobe ");
build_cmd(cmd, x, CMD_SIZE);
run_interactive(cmd, " Loading module %s", x);
continue;
}
if (MATCH_CMD(line, "mknod ", x)) {
strcpy(cmd, "/bin/mknod ");
build_cmd(cmd, x, CMD_SIZE);
run_interactive(cmd, " Creating device node %s", x);
continue;
}
if (MATCH_CMD(line, "network ", x)) {
if (network) free(network);
network = build_cmd(NULL, x, CMD_SIZE);
continue;
}
if (MATCH_CMD(line, "startx ", x)) {
svc_register(x, username);
continue;
}
if (MATCH_CMD(line, "service ", x)) {
svc_register(x, NULL);
continue;
}
}
fclose(fp);
}
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+12
View File
@@ -0,0 +1,12 @@
# Simple Debian finit.conf
check /dev/vda1
module evdev
module loop
module psmouse
user admin
host testbed
network service networking start
service /sbin/klogd -n -- Kernel logging server
service /sbin/syslogd -n -- Syslog server
service /usr/sbin/sshd -D -- OpenSSH server
service /usr/sbin/gdm -- GNOME Display Manager
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
# Alternative boot method for other distributions than Debian 6.0
# Place this file in a /etc/finit.d/ directory. At boot finit will
# run all files, using its built-in run_parts(), in that directory.
#
# Here we chain load Debian /etc/rcS.d and /etc/rc2.d directories
# in sequence using the standard run-parts tool.
run-parts /etc/rcS.d --arg=start
run-parts /etc/rc2.d --arg=start
# You can also place other commands in this services file, akin to
# the old finit /usr/sbin/services.sh (not supported anymore).
#service acpid start
#service networking start
#service ssh start
-384
View File
@@ -1,384 +0,0 @@
/*
Improved fast init
Copyright (c) 2008 Claudio Matsuoka
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/reboot.h>
#include <sys/wait.h>
#include <linux/fs.h>
#include "helpers.h"
#ifdef DEBUG
#define debug(x...) do { \
printf("finit: %d: ", __LINE__); printf(x); printf("\n"); \
} while (0)
#else
#define debug(x...)
#endif
/* Distribution configuration */
#ifdef DIST_MDV /* Mandriva */
#define RANDOMSEED "/var/lib/random-seed"
#define SYSROOT "/sysroot"
#define GETTY "/sbin/mingetty tty3"
#define RUNPARTS "/usr/bin/run-parts --arg=-i"
#define DEFUSER "user"
#define HOMEDEV "/dev/sda6"
#define AGPDRV "intel-agp"
#define REMOUNT_ROOTFS_RW
#define MAKE_DEVICES
#else /* original Eeepc distribution */
#define RANDOMSEED "/var/lib/urandom/random-seed"
#define SYSROOT "/mnt"
#define GETTY "/sbin/getty 38400 tty3"
#define RUNPARTS "/bin/run-parts --arg=-i"
#define DEFUSER "user"
#define TOUCH_ETC_NETWORK_RUN_IFSTATE
#endif
#ifdef DIRECTISA
#define HWCLOCK_DIRECTISA " --directisa"
#else
#define HWCLOCK_DIRECTISA
#endif
/* From sysvinit */
/* Set a signal handler. */
#define SETSIG(sa, sig, fun, flags) \
do { \
sa.sa_handler = fun; \
sa.sa_flags = flags; \
sigemptyset(&sa.sa_mask); \
sigaction(sig, &sa, NULL); \
} while (0)
#define touch(x) mknod((x), S_IFREG|0644, 0)
#define chardev(x,m,maj,min) mknod((x), S_IFCHR|(m), makedev((maj),(min)))
void shutdown(int);
void signal_handler(int);
void chld_handler(int);
int main()
{
int i;
FILE *f;
char line[2096];
int fd;
DIR *dir;
struct dirent *d;
char filename[1024];
struct sigaction sa, act;
char hline[1024];
char *x;
sigset_t nmask, nmask2;
puts("finit-alt " VERSION " (built " __DATE__ " by " WHOAMI ")");
chdir("/");
umask(022);
/*
* Signal management
*/
for (i = 1; i < NSIG; i++)
SETSIG(sa, i, SIG_IGN, SA_RESTART);
SETSIG(sa, SIGINT, shutdown, 0);
SETSIG(sa, SIGPWR, signal_handler, 0);
SETSIG(sa, SIGUSR1, shutdown, 0);
SETSIG(sa, SIGUSR2, shutdown, 0);
SETSIG(sa, SIGTERM, signal_handler, 0);
SETSIG(sa, SIGALRM, signal_handler, 0);
SETSIG(sa, SIGHUP, signal_handler, 0);
SETSIG(sa, SIGCONT, signal_handler, SA_RESTART);
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
/* Block sigchild while forking */
sigemptyset(&nmask);
sigaddset(&nmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &nmask, NULL);
reboot(RB_DISABLE_CAD);
mount("proc", "/proc", "proc", 0, NULL);
/*
* Parse kernel parameters
*/
if ((f = fopen("/proc/cmdline", "r")) != NULL) {
fgets(line, 2095, f);
if (strstr(line, "quiet")) {
close(0);
close(1);
close(2);
}
fclose(f);
}
setsid();
/*
* Mount filesystems
*/
debug("mount filesystems");
#ifdef REMOUNT_ROOTFS_RW
system("/bin/mount -n -o remount,rw /");
#endif
umask(0);
mkdir("/dev/shm", 0755);
mkdir("/dev/pts", 0755);
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("devpts", "/dev/pts", "devpts", 0, "gid=5,mode=620");
mount("tmpfs", "/dev/shm", "tmpfs", 0, NULL);
mount("tmpfs", "/tmp", "tmpfs", 0, "mode=1777,size=128m");
mount("tmpfs", "/var/run", "tmpfs", 0, "mode=0755");
mount("tmpfs", "/var/lock", "tmpfs", 0, "mode=1777");
mount(SYSROOT, "/", NULL, MS_MOVE, NULL);
unlink("/etc/mtab");
system("mount -a");
#ifdef MAKE_DEVICES
debug("make devices");
mkdir("/dev/input", 0755);
chardev("/dev/urandom", 0666, 1, 9);
chardev("/dev/ptmx", 0666, 5, 2);
chardev("/dev/null", 0666, 1, 3);
chardev("/dev/mem", 0640, 1, 1);
chmod("/dev/null", 0667);
chmod("/dev/mem", 0640);
chardev("/dev/tty", 0666, 5, 0);
chardev("/dev/input/mice", 0660, 13, 63);
chardev("/dev/input/event0", 0660, 13, 64);
chardev("/dev/agpgart", 0660, 10, 175);
#endif
umask(0022);
/*
* Time adjustments
*/
if ((fd = open("/etc/adjtime", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) {
write(fd, "0.0 0 0.0\n", 10);
close(fd);
}
#ifndef NO_HCTOSYS
system("/sbin/hwclock --hctosys --localtime" HWCLOCK_DIRECTISA);
#endif
/*
* Network stuff
*/
makepath("/dev/shm/network");
makepath("/dev/shm/resolvconf/interface");
if ((dir = opendir("/etc/resolvconf/run/interface")) != NULL) {
while ((d = readdir(dir)) != NULL) {
if (isalnum(d->d_name[0]))
continue;
sprintf(filename, "/etc/resolvconf/run/interface/%s",
d->d_name);
unlink(filename);
}
closedir(dir);
}
touch("/var/run/utmp");
touch("/etc/resolvconf/run/enable-updates");
chdir("/etc/resolvconf/run/interface");
system(RUNPARTS " /etc/resolvconf/update.d");
chdir("/");
#ifdef TOUCH_ETC_NETWORK_RUN_IFSTATE
touch("/etc/network/run/ifstate");
#endif
if ((f = fopen("/etc/hostname", "r")) != NULL) {
fgets(hline, 1023, f);
if ((x = strchr(hline, 0x0a)) != NULL)
*x = 0;
sethostname(hline, strlen(hline));
fclose(f);
}
ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
/*
* Set random seed
*/
copyfile(RANDOMSEED, "/dev/urandom", 0);
unlink(RANDOMSEED);
umask(077);
copyfile("/dev/urandom", RANDOMSEED, 4096);
umask(0);
/*
* Console setup (for X)
*/
makepath("/var/run/console");
touch("/var/run/console/" DEFUSER);
/*
* Misc setup
*/
mkdir("/tmp/.X11-unix", 01777);
mkdir("/tmp/.ICE-unix", 01777);
umask(022);
debug("forking");
if (!fork()) {
/* child process */
vhangup();
close(2);
close(1);
close(0);
if (open("/dev/tty1", O_RDWR, 0))
exit(1);
sigemptyset(&act.sa_mask);
act.sa_handler = SIG_DFL;
sigemptyset(&nmask2);
sigaddset(&nmask2, SIGCHLD);
sigprocmask(SIG_UNBLOCK, &nmask2, NULL);
for (i = 1; i < NSIG; i++)
sigaction(i, &sa, NULL);
dup2(0, 0);
dup2(0, 1);
dup2(0, 2);
touch("/tmp/nologin");
#ifdef AGPDRV
system("/sbin/modprobe agpgart");
system("/sbin/modprobe " AGPDRV);
#endif
while (access("/tmp/shutdown", F_OK) < 0) {
debug("start X as " DEFUSER);
#ifdef DEBUG
system("su -c startx -l " DEFUSER);
system("/bin/sh");
#else
system("su -c startx -l " DEFUSER " &> /dev/null");
#endif
}
exit(0);
}
/* parent process */
system(GETTY "&");
sleep(1);
system("/usr/sbin/services.sh &>/dev/null&");
while (1) {
sigemptyset(&nmask);
pselect(0, NULL, NULL, NULL, NULL, &nmask);
}
}
/*
* Shut down on INT USR1 USR2
*/
void shutdown(int sig)
{
debug("shutdown");
touch("/tmp/shutdown");
kill(-1, SIGTERM);
write(1, "\033[?25l\033[30;40m", 14);
copyfile("/boot/shutdown.fb", "/dev/fb/0", 0);
sleep(2);
system("/usr/sbin/alsactl store > /dev/null 2>&1");
system("/sbin/hwclock --systohc --localtime" HWCLOCK_DIRECTISA);
kill(-1, SIGKILL);
sync();
sync();
system("/bin/mount -n -o remount,ro /");
system("/sbin/unionctl.static / --remove / > /dev/null 2>&1");
if (sig == SIGINT || sig == SIGUSR1)
reboot(RB_AUTOBOOT);
reboot(RB_POWER_OFF);
}
/*
* SIGCHLD: one of our children has died
*/
void chld_handler(int sig)
{
int status;
while (waitpid(-1, &status, WNOHANG) != 0) {
if (errno == ECHILD)
break;
}
}
/*
* We got a signal (PWR TERM ALRM HUP CONT)
*/
void signal_handler(int sig)
{
/* do nothing */
}
-325
View File
@@ -1,325 +0,0 @@
/*
Improved fast init
Copyright (c) 2008 Claudio Matsuoka
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
Changelog from the original Eeepc fastinit:
- Use mknod() instead of close(open()) call to create empty file
- Fix random seed initialization
- Don't try to handle signal 0, SIGKILL or SIGSTOP
- Implement makepath() to avoid system("mkdir -p")
- Omit first hwclock if user has CONFIG_RTC_HCTOSYS in kernel (by Metalshark)
- Add –directisa to hwclock if user has disabled CONFIG_GENRTC and enabled
CONFIG_RTC but not CONFIG_HPET_TIMER and CONFIG_HPET_RTC_IRQ (by Metalshark)
- Drop system() call to clean /tmp, it's a fresh mounted tmpfs
- Change /proc/acpi/sleep to /sys/power/state (by Metalshark)
- Set loopback interface using direct calls instead of system("ifconfig")
- Copy 4096 data block in C instead of system("cat") or system("dd")
- Draw shutdown splash screen using C calls instead of system("echo;cat")
- Change poweroff method from writing 5 to /sys/power/state to
reboot(RB_POWER_OFF) (by Metalshark)
- Mount /var/run and /var/lock as tmpfs
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/reboot.h>
#include <sys/wait.h>
#include <linux/fs.h>
#include "helpers.h"
#ifdef DIRECTISA
#define HWCLOCK_DIRECTISA " --directisa"
#else
#define HWCLOCK_DIRECTISA
#endif
/* From sysvinit */
/* Set a signal handler. */
#define SETSIG(sa, sig, fun, flags) \
do { \
sa.sa_handler = fun; \
sa.sa_flags = flags; \
sigemptyset(&sa.sa_mask); \
sigaction(sig, &sa, NULL); \
} while(0)
#define touch(x) mknod((x), S_IFREG|0644, 0)
void shutdown(int);
void signal_handler(int);
void chld_handler(int);
int main()
{
int i;
FILE *f;
char line[2096];
int fd;
DIR *dir;
struct dirent *d;
char filename[1024];
struct sigaction sa, act;
char hline[1024];
char *x;
sigset_t nmask, nmask2;
puts("finit-mod " VERSION " (built " __DATE__ " by " WHOAMI ")");
chdir("/");
umask(022);
/*
* Signal management
*/
for (i = 1; i < NSIG; i++)
SETSIG(sa, i, SIG_IGN, SA_RESTART);
SETSIG(sa, SIGINT, shutdown, 0);
SETSIG(sa, SIGPWR, signal_handler, 0);
SETSIG(sa, SIGUSR1, shutdown, 0);
SETSIG(sa, SIGUSR2, shutdown, 0);
SETSIG(sa, SIGTERM, signal_handler, 0);
SETSIG(sa, SIGALRM, signal_handler, 0);
SETSIG(sa, SIGHUP, signal_handler, 0);
SETSIG(sa, SIGCONT, signal_handler, SA_RESTART);
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
/* Block sigchild while forking */
sigemptyset(&nmask);
sigaddset(&nmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &nmask, NULL);
reboot(RB_DISABLE_CAD);
/*
* Parse kernel parameters
*/
if ((f = fopen("/proc/cmdline", "r")) != NULL) {
fgets(line, 2095, f);
if (strstr(line, "quiet")) {
close(0);
close(1);
close(2);
}
fclose(f);
}
setsid();
/*
* Mount filesystems
*/
mount("proc", "/proc", "proc", 0, NULL);
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("devpts", "/dev/pts", "devpts", 0, "gid=5,mode=620");
mount("tmpfs", "/dev/shm", "tmpfs", 0, NULL);
mount("tmpfs", "/tmp", "tmpfs", 0, "mode=1777,size=128m");
mount("tmpfs", "/var/run", "tmpfs", 0, "mode=0755");
mount("tmpfs", "/var/lock", "tmpfs", 0, "mode=1777");
mount("/mnt", "/", NULL, MS_MOVE, NULL);
/*
* Time adjustments
*/
if ((fd = open("/etc/adjtime", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) {
write(fd, "0.0 0 0.0\n", 10);
close(fd);
}
#ifndef NO_HCTOSYS
system("/sbin/hwclock --hctosys --localtime" HWCLOCK_DIRECTISA);
#endif
/*
* Network stuff
*/
makepath("/dev/shm/network");
makepath("/dev/shm/resolvconf/interface");
if ((dir = opendir("/etc/resolvconf/run/interface")) != NULL) {
while ((d = readdir(dir)) != NULL) {
if (isalnum(d->d_name[0]))
continue;
sprintf(filename, "/etc/resolvconf/run/interface/%s",
d->d_name);
unlink(filename);
}
closedir(dir);
}
touch("/var/run/utmp");
touch("/etc/resolvconf/run/enable-updates");
chdir("/etc/resolvconf/run/interface");
system("/bin/run-parts --arg=-i /etc/resolvconf/update.d");
chdir("/");
touch("/etc/network/run/ifstate");
if ((f = fopen("/etc/hostname", "r")) != NULL) {
fgets(hline, 1023, f);
if ((x = strchr(hline, 0x0a)) != NULL)
*x = 0;
sethostname(hline, strlen(hline));
fclose(f);
}
ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
/*
* Set random seed
*/
copyfile("/var/lib/urandom/random-seed", "/dev/urandom", 0);
unlink("/var/lib/urandom/random-seed");
umask(077);
copyfile("/dev/urandom", "/var/lib/urandom/random-seed", 4096);
/*
* Misc setup
*/
unlink("/var/run/.clean");
unlink("/var/lock/.clean");
umask(0);
mkdir("/tmp/.X11-unix", 01777);
mkdir("/tmp/.ICE-unix", 01777);
umask(022);
if (!fork()) {
/* child process */
vhangup();
close(2);
close(1);
close(0);
if (open("/dev/tty1", O_RDWR, 0))
exit(1);
sigemptyset(&act.sa_mask);
act.sa_handler = SIG_DFL;
sigemptyset(&nmask2);
sigaddset(&nmask2, SIGCHLD);
sigprocmask(SIG_UNBLOCK, &nmask2, NULL);
for (i = 1; i < NSIG; i++)
sigaction(i, &sa, NULL);
dup2(0, 0);
dup2(0, 1);
dup2(0, 2);
touch("/tmp/nologin");
while (access("/tmp/shutdown", F_OK) < 0)
system("su -c startx -l user &> /dev/null");
exit(0);
}
/* parent process */
system("/sbin/getty 38400 tty3&");
sleep(1);
system("/usr/sbin/services.sh &>/dev/null&");
while (1) {
sigemptyset(&nmask);
pselect(0, NULL, NULL, NULL, NULL, &nmask);
}
}
/*
* Shut down on INT USR1 USR2
*/
void shutdown(int sig)
{
touch("/tmp/shutdown");
kill(-1, SIGTERM);
write(1, "\033[?25l\033[30;40m", 14);
copyfile("/boot/shutdown.fb", "/dev/fb/0", 0);
sleep(2);
system("/usr/sbin/alsactl store > /dev/null 2>&1");
system("/sbin/hwclock --systohc --localtime" HWCLOCK_DIRECTISA);
kill(-1, SIGKILL);
sync();
sync();
system("/bin/mount -n -o remount,ro /");
system("/sbin/unionctl.static / --remove / > /dev/null 2>&1");
if (sig == SIGINT || sig == SIGUSR1)
reboot(RB_AUTOBOOT);
reboot(RB_POWER_OFF);
}
/*
* SIGCHLD: one of our children has died
*/
void chld_handler(int sig)
{
int status;
while (waitpid(-1, &status, WNOHANG) != 0) {
if (errno == ECHILD)
break;
}
}
/*
* We got a signal (PWR TERM ALRM HUP CONT)
*/
void signal_handler(int sig)
{
/* do nothing */
}
+163 -242
View File
@@ -1,282 +1,203 @@
/* Improved fast init
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/types.h> #include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <sys/stat.h> /* umask(), mkdir() */
#include <signal.h>
#include <unistd.h> #include "finit.h"
#include <sys/reboot.h> #include "helpers.h"
#include <sys/wait.h> #include "private.h"
#include <linux/fs.h> #include "plugin.h"
#include "svc.h"
#include "sig.h"
int debug = 0;
int verbose = 1;
char *sdown = NULL;
char *network = NULL;
char *username = NULL;
char *hostname = NULL;
/* From sysvinit */ static void parse_kernel_cmdline(void)
/* Set a signal handler. */
#define SETSIG(sa, sig, fun, flags) \
do { \
sa.sa_handler = fun; \
sa.sa_flags = flags; \
sigemptyset(&sa.sa_mask); \
sigaction(sig, &sa, NULL); \
} while(0)
#define touch(x) close(open((x), O_CREAT|O_WRONLY|O_TRUNC, 0644))
void shutdown(int);
void signal_handler(int);
void chld_handler(int);
int main()
{ {
int i; FILE *fp;
FILE *f; char line[LINE_SIZE];
char line[2096];
int fd;
DIR *dir;
struct dirent *d;
char filename[1024];
struct sigaction sa, act;
char hline[1024];
char *x;
sigset_t nmask, nmask2;
chdir("/"); if ((fp = fopen("/proc/cmdline", "r")) != NULL) {
umask(022); fgets(line, sizeof(line), fp);
if (strstr(line, "finit_debug") || strstr(line, "--debug"))
debug = 1;
if (!debug && strstr(line, "quiet"))
verbose = 0;
fclose(fp);
}
}
static int run_loop(void)
{
while (1) {
svc_monitor();
io_monitor();
}
return 0;
}
int main(int UNUSED(args), char *argv[])
{
/* /*
* Signal management * Initial setup of signals, ignore all until we're up.
*/ */
for (i = 1; i < NSIG; i++) sig_init();
SETSIG(sa, i, SIG_IGN, SA_RESTART);
SETSIG(sa, SIGINT, shutdown, 0); /*
SETSIG(sa, SIGPWR, signal_handler, 0); * Mount base file system, kernel is assumed to run devtmpfs for /dev
SETSIG(sa, SIGUSR1, shutdown, 0); */
SETSIG(sa, SIGUSR2, shutdown, 0); chdir("/");
SETSIG(sa, SIGTERM, signal_handler, 0); umask(0);
SETSIG(sa, SIGKILL, signal_handler, 0); mount("none", "/proc", "proc", 0, NULL);
SETSIG(sa, SIGALRM, signal_handler, 0); mount("none", "/proc/bus/usb", "usbfs", 0, NULL);
SETSIG(sa, SIGHUP, signal_handler, 0); mount("none", "/sys", "sysfs", 0, NULL);
SETSIG(sa, SIGSTOP, signal_handler, SA_RESTART); mkdir("/dev/pts", 0755);
SETSIG(sa, SIGCONT, signal_handler, SA_RESTART); mkdir("/dev/shm", 0755);
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART); mount("none", "/dev/pts", "devpts", 0, "gid=5,mode=620");
mount("none", "/dev/shm", "tmpfs", 0, NULL);
/* Block sigchild while forking */ umask(022);
sigemptyset(&nmask);
sigaddset(&nmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &nmask, NULL);
reboot(RB_DISABLE_CAD); /*
* Populate /dev and prepare for runtime events from kernel.
*/
#if defined(USE_UDEV)
run_interactive("udevd --daemon", "Populating device tree");
#elif defined (MDEV)
run_interactive(MDEV "-s", "Populating device tree");
#endif
/* /*
* Parse kernel parameters * Parse kernel parameters
*/ */
if ((f = fopen("/proc/cmdline", "r")) != NULL) { parse_kernel_cmdline();
fgets(line, 2095, f);
if (strstr(line, "quiet")) {
close(0);
close(1);
close(2);
}
fclose(f);
}
setsid(); cls();
echo("finit " VERSION " (built " __DATE__ " " __TIME__ " by " WHOAMI ")");
/*
* Parse configuration file
*/
parse_finit_conf(FINIT_CONF);
/* /*
* Mount filesystems * Mount filesystems
*/ */
mount("proc", "/proc", "proc", 0, NULL); _d("Mount filesystems in /etc/fstab ...");
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("devpts", "/dev/pts", "devpts", 0, "gid=5,mode=620"); #ifdef REMOUNT_ROOTFS_RW
mount("tmpfs", "/dev/shm", "tmpfs", 0, NULL); run("/bin/mount -n -o remount,rw /");
mount("tmpfs", "/tmp", "tmpfs", 0, "mode=1777,size=128m"); #endif
mount("/mnt", "/", NULL, MS_MOVE, NULL); #ifdef SYSROOT
run(SYSROOT, "/", NULL, MS_MOVE, NULL);
#endif
umask(0);
run("/bin/mount -na");
run("/sbin/swapon -ea");
umask(0022);
/* Cleanup stale files, if any still linger on. */
run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories");
/* /*
* Time adjustments * Base FS up, enable standard SysV init signals
*/ */
if ((fd = open("/etc/adjtime", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) { sig_setup();
write(fd, "0.0 0 0.0\n", 10);
close(fd); /*
} * Load plugins and run first level hooks.
system("/sbin/hwclock --hctosys --localtime"); */
_d("Loading plugins ...");
load_plugins(PLUGIN_PATH);
_d("Running first level hooks ...");
run_hooks(HOOK_BASEFS_UP);
/* /*
* Network stuff * Network stuff
*/ */
system("mkdir -p /dev/shm/network");
system("mkdir -p /dev/shm/resolvconf/interface");
if ((dir = opendir("/etc/resolvconf/run/interface")) != NULL) { /* Setup kernel specific settings, e.g. allow broadcast ping, etc. */
while ((d = readdir(dir)) != NULL) { run("/sbin/sysctl -e -p /etc/sysctl.conf >/dev/null");
if (isalnum(d->d_name[0]))
continue;
sprintf(filename, "/etc/resolvconf/run/interface/%s",
d->d_name);
unlink(filename);
}
closedir(dir); /* Set initial hostname. */
} set_hostname(hostname);
touch("/var/run/utmp"); ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
touch("/etc/resolvconf/run/enable-updates"); if (network)
run_interactive(network, "Starting networking: %s", network);
chdir("/etc/resolvconf/run/interface");
system("/bin/run-parts --arg=-i /etc/resolvconf/update.d");
chdir("/");
touch("/etc/network/run/ifstate");
if ((f = fopen("/etc/hostname", "r")) != NULL) {
fgets(hline, 1023, f);
if ((x = strchr(hline, 0x0a)) != NULL)
*x = 0;
sethostname(hline, strlen(hline));
fclose(f);
}
system("/sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0 up > /dev/null");
/*
* Set random seed
*/
/* Bug: the eeepc never sets its random seed from file */
system("/bin/cat /var/lib/urandom/random-seed >/dev/urandom "
"> /dev/null 2>&1");
unlink("/var/lib/urandom/random-seed");
umask(077);
system("/bin/dd if=/dev/urandom of=/var/lib/urandom/random-seed "
"bs=4096 count=1 >/dev/null 2>&1");
/*
* Misc setup
*/
/* not really needed, /tmp is a fresh mounted tmpfs */
system("/bin/rm -rf /tmp/* /tmp/.* 2>/dev/null");
unlink("/var/run/.clean");
unlink("/var/lock/.clean");
umask(0);
mkdir("/tmp/.X11-unix", 01777);
mkdir("/tmp/.ICE-unix", 01777);
umask(022); umask(022);
if (!fork()) { /*
/* child process */ * Hooks that rely on loopback, or basic networking being up.
*/
run_hooks(HOOK_NETWORK_UP);
vhangup(); /*
* Start service monitor framework
*/
_d("Starting all static services from %s", FINIT_CONF);
svc_start_all();
close(2); /*
close(1); * Run startup scripts in /etc/finit.d/, if any.
close(0); */
_d("Running startup scripts in /etc/finit.d/ ...");
run_parts(FINIT_RCSD);
if (open("/dev/tty1", O_RDWR, 0)) /*
exit(1); * Hooks that should run at the very end
*/
run_hooks(HOOK_SYSTEM_UP);
sigemptyset(&act.sa_mask); /* Start GETTY on console */
act.sa_handler = SIG_DFL; _d("Starting getty on console ...");
run_getty(GETTY, argv);
sigemptyset(&nmask2); /*
sigaddset(&nmask2, SIGCHLD); * Enter main loop to monior /dev/initctl and services
sigprocmask(SIG_UNBLOCK, &nmask2, NULL); */
_d("Entering main loop ...");
/* Bug: no signal 0 */ return run_loop();
for (i = 0; i < NSIG; i++)
sigaction(i, &sa, NULL);
dup2(0, 0);
dup2(0, 1);
dup2(0, 2);
touch("/tmp/nologin");
while (access("/tmp/shutdown", F_OK) < 0)
system("su -c startx -l user &> /dev/null");
exit(0);
}
/* parent process */
system("/sbin/getty 38400 tty3 &");
sleep(1);
system("/usr/sbin/services.sh &> /dev/null &");
while (1) {
sigemptyset(&nmask);
pselect(0, NULL, NULL, NULL, NULL, &nmask);
}
} }
/**
/* * Local Variables:
* Shut down on INT USR1 USR2 * version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/ */
void shutdown(int sig)
{
int fd;
system("/usr/bin/touch /tmp/shutdown");
kill(-1, SIGTERM);
system("/bin/echo -e \"\033[?25l\033[30;40m\"; "
"/bin/cp /boot/shutdown.fb /dev/fb/0");
sleep(1);
sleep(1);
system("/usr/sbin/alsactl store > /dev/null 2>&1");
system("/sbin/hwclock --systohc --localtime");
kill(-1, SIGKILL);
sync();
sync();
system("/bin/mount -n -o remount,ro /");
system("/sbin/unionctl.static / --remove / > /dev/null 2>&1");
if (sig == SIGINT || sig == SIGUSR1)
reboot(RB_AUTOBOOT);
if ((fd = open("/proc/acpi/sleep", O_WRONLY)) >= 0) {
write(fd, "5", 1);
close(fd);
}
}
/*
* SIGCHLD: one of our children has died
*/
void chld_handler(int sig)
{
int status;
while (waitpid(-1, &status, WNOHANG) != 0) {
if (errno == ECHILD)
break;
}
}
/*
* We got a signal (PWR TERM ALRM HUP STOP CONT)
*/
void signal_handler(int sig)
{
/* do nothing */
}
+126
View File
@@ -0,0 +1,126 @@
/* Improved fast init
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef FINIT_H_
#define FINIT_H_
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <syslog.h>
#define DO_LOG(level, fmt, args...) \
{ \
openlog("finit", LOG_CONS | LOG_PID, LOG_DAEMON); \
syslog(LOG_DEBUG, fmt, ##args); \
closelog(); \
}
#define DEBUG(fmt, args...) DO_LOG(LOG_DEBUG, fmt, ##args)
#define ERROR(fmt, args...) DO_LOG(LOG_CRIT, fmt, ##args)
#define FINIT_FIFO "/dev/initctl"
#define FINIT_CONF "/etc/finit.conf"
#define FINIT_RCSD "/etc/finit.d"
/* Distribution configuration */
#if defined EMBEDDED_SYSTEM
# define CONSOLE "/dev/console"
# define MDEV "/sbin/mdev"
# define GETTY "/sbin/getty -L 115200 ttyS0 vt100"
# define LISTEN_INITCTL
#else /* Debian/Ubuntu based distributions */
# define RANDOMSEED "/var/lib/urandom/random-seed"
# define CONSOLE "/dev/tty1"
# define GETTY "/sbin/getty -8 38400 tty1"
# define REMOUNT_ROOTFS_RW
# define RUNLEVEL 2
# define LISTEN_INITCTL
# define USE_UDEV
# define USE_MESSAGE_BUS
#endif
#ifndef DEFUSER
# define DEFUSER "root"
#endif
#ifndef DEFHOST
# define DEFHOST "noname"
#endif
#define CMD_SIZE 256
#define LINE_SIZE 1024
#define BUF_SIZE 4096
#define USERNAME_SIZE 16
#define HOSTNAME_SIZE 32
#ifndef touch
# define touch(x) mknod((x), S_IFREG|0644, 0)
#endif
#ifndef chardev
# define chardev(x,m,maj,min) mknod((x), S_IFCHR|(m), makedev((maj),(min)))
#endif
#ifndef blkdev
# define blkdev(x,m,maj,min) mknod((x), S_IFBLK|(m), makedev((maj),(min)))
#endif
#ifndef fexist
# define fexist(x) (access(x, F_OK) != -1)
#endif
#ifndef UNUSED
#define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
#endif
#define echo(fmt, args...) do { if (1) { fprintf(stderr, fmt "\n", ##args); } } while (0)
#define _d(fmt, args...) do { if (debug) { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } } while (0)
#define _e(fmt, args...) do { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } while (0)
#define _pe(fmt, args...) do { fprintf(stderr, "finit:%s() - " fmt ". Error %d: %s\n", __func__, ##args, errno, strerror(errno)); } while (0)
extern int debug;
extern int verbose;
extern char *sdown;
extern char *network;
extern char *hostname;
extern char *username;
/* strlcpy.c */
size_t strlcpy(char *dst, const char *src, size_t siz);
/* conf.c */
void parse_finit_conf(char *file);
#endif /* FINIT_H_ */
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+528 -3
View File
@@ -1,16 +1,56 @@
/* Misc. utility functions and C-library extensions to simplify finit system setup.
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <ctype.h> /* isdigit() */
#include <string.h> #include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <dirent.h>
#include <stdarg.h>
#include <sys/wait.h>
#include <grp.h>
#include <pwd.h>
#include "finit.h"
#include "helpers.h" #include "helpers.h"
#include "private.h"
#include "sig.h"
#define NUM_ARGS 16
#define NUM_SCRIPTS 128 /* ought to be enough for anyone */
/* /*
* Helpers to replace system() calls * Helpers to replace system() calls
@@ -42,8 +82,8 @@ void ifconfig(char *name, char *inet, char *mask, int up)
return; return;
memset(&ifr, 0, sizeof (ifr)); memset(&ifr, 0, sizeof (ifr));
strncpy(ifr.ifr_name, name, IFNAMSIZ); strlcpy(ifr.ifr_name, name, IFNAMSIZ);
a->sin_family = AF_INET; ifr.ifr_addr.sa_family = AF_INET;
if (up) { if (up) {
inet_aton(inet, &a->sin_addr); inet_aton(inet, &a->sin_addr);
@@ -64,7 +104,6 @@ void ifconfig(char *name, char *inet, char *mask, int up)
close(sock); close(sock);
} }
#define BUF_SIZE 4096
void copyfile(char *src, char *dst, int size) void copyfile(char *src, char *dst, int size)
{ {
@@ -90,3 +129,489 @@ void copyfile(char *src, char *dst, int size)
} }
} }
static int print_uptime(void)
{
#if defined(CONFIG_PRINTK_TIME)
FILE * uptimefile;
float num1, num2;
char uptime_str[30];
if((uptimefile = fopen("/proc/uptime", "r")) == NULL)
return 1;
fgets(uptime_str, 20, uptimefile);
fclose(uptimefile);
sscanf(uptime_str, "%f %f", &num1, &num2);
sprintf(uptime_str, "[ %.6f ]", num1);
write(STDERR_FILENO, uptime_str, strlen(uptime_str));
#endif
return 0;
}
void print_descr(char *action, char *descr)
{
const char home[] = "\r\e[K";
const char dots[] = " .....................................................................";
write(STDERR_FILENO, home, strlen(home));
print_uptime();
write(STDERR_FILENO, action, strlen(action));
write(STDERR_FILENO, descr, strlen(descr));
write(STDERR_FILENO, dots, 60 - strlen(descr) - strlen(action)); /* pad with dots. */
}
int print_result(int fail)
{
if (fail)
fprintf(stderr, " \e[7m[FAIL]\e[0m\n");
else
fprintf(stderr, " \e[1m[ OK ]\e[0m\n");
return fail;
}
int run(char *cmd)
{
int status, result, i = 0;
FILE *fp;
char *args[NUM_ARGS + 1], *arg, *backup;
pid_t pid;
/* We must create a copy that is possible to modify. */
backup = arg = strdup(cmd);
if (!arg)
return 1; /* Failed allocating a string to be modified. */
/* Split command line into tokens of an argv[] array. */
args[i++] = strsep(&arg, "\t ");
do {
/* Handle run("su -c \"dbus-daemon --system\" messagebus");
* => "su", "-c", "\"dbus-daemon --system\"", "messagebus" */
if (*arg == '\'' || *arg == '"') {
char *p, delim[2] = " ";
delim[0] = arg[0];
args[i++] = arg++;
strsep(&arg, delim);
p = arg - 1;
*p = *delim;
*arg++ = 0;
} else {
args[i++] = strsep(&arg, "\t ");
}
} while (arg && i < NUM_ARGS);
args[i] = NULL;
#if 0
_e("Splitting: '%s' =>", cmd);
for (i = 0; args[i]; i++)
_e("\t%s", args[i]);
#endif
if (i == NUM_ARGS && args[i]) {
_e("Command too long: %s", cmd);
free(backup);
errno = EOVERFLOW;
return 1;
}
fp = fopen("/dev/null", "w");
pid = fork();
if (0 == pid) {
int i;
struct sigaction sa;
/* Reset signal handlers that were set by the parent process */
for (i = 1; i < NSIG; i++)
DFLSIG(sa, i, 0);
/* Redirect stdio if the caller requested so. */
if (fp) {
int fd = fileno(fp);
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
}
execvp(args[0], args);
_exit(1); /* Only if execv() fails. */
} else if (-1 == pid) {
_pe("%s", args[0]);
return -1;
}
if (waitpid(pid, &status, 0) == -1) {
if (errno == EINTR)
_e("Caught unblocked signal waiting for %s, aborting.", args[0]);
else if (errno == ECHILD)
_e("Caught SIGCHLD waiting for %s, aborting.", args[0]);
else
_e("Failed starting %s, error %d: %s", args[0], errno, strerror (errno));
if (fp) fclose(fp);
free(backup);
return 1;
}
result = WEXITSTATUS(status);
if (WIFEXITED(status)) {
_d("Started %s and ended OK: %d", args[0], result);
} else if (WIFSIGNALED(status)) {
_d("Process %s terminated by signal %d", args[0], WTERMSIG(status));
if (!result)
result = 1; /* Must alert callee that the command did complete successfully.
* This is necessary since not all programs trap signals and
* change their return code accordingly. --Jocke */
}
if (fp) fclose(fp);
free(backup);
return result;
}
int run_interactive(char *cmd, char *fmt, ...)
{
int status, oldout = 1, olderr = 2;
char line[LINE_SIZE];
va_list ap;
FILE *fp = tmpfile();
va_start(ap, fmt);
vsnprintf(line, sizeof(line), fmt, ap);
va_end(ap);
print_descr("", line);
if (fp && !debug) {
oldout = dup(STDOUT_FILENO);
olderr = dup(STDERR_FILENO);
dup2(fileno(fp), STDOUT_FILENO);
dup2(fileno(fp), STDERR_FILENO);
}
status = run(cmd);
if (fp && !debug) {
dup2(oldout, STDOUT_FILENO);
dup2(olderr, STDERR_FILENO);
}
print_result(status);
if (fp && !debug) {
size_t len, written;
rewind(fp);
do {
len = fread(line, 1, sizeof(line), fp);
written = fwrite(line, len, sizeof(char), stderr);
} while (len > 0 && written == len);
fclose(fp);
}
return status;
}
pid_t run_getty(char *cmd, char *argv[])
{
pid_t pid = fork();
if (!pid) {
int i;
char c;
sigset_t nmask;
struct sigaction sa;
/* Detach from initial controlling TTY */
vhangup();
close(2);
close(1);
close(0);
/* Attach TTY to console */
if (open(CONSOLE, O_RDWR) != 0)
exit(1);
sigemptyset(&sa.sa_mask);
sa.sa_handler = SIG_DFL;
sigemptyset(&nmask);
sigaddset(&nmask, SIGCHLD);
sigprocmask(SIG_UNBLOCK, &nmask, NULL);
for (i = 1; i < NSIG; i++)
sigaction(i, &sa, NULL);
dup2(0, STDIN_FILENO);
dup2(0, STDOUT_FILENO);
dup2(0, STDERR_FILENO);
set_procname(argv, "console");
while (!fexist(SYNC_SHUTDOWN)) {
static const char msg[] = "\nPlease press Enter to activate this console. ";
if (fexist(SYNC_STOPPED)) {
sleep(1);
continue;
}
i = write(STDERR_FILENO, msg, sizeof(msg) - 1);
while (read(STDIN_FILENO, &c, 1) == 1 && c != '\n')
continue;
if (fexist(SYNC_STOPPED))
continue;
run(cmd);
}
exit(0);
}
return pid;
}
static int cmp(const void *s1, const void *s2)
{
return strcmp(*(char **)s1, *(char **)s2);
}
int run_parts(char *dir, ...)
{
DIR *d;
struct dirent *e;
struct stat st;
char *oldpwd = NULL;
char *ent[NUM_SCRIPTS];
int i, num = 0, argnum = 1;
char *args[NUM_ARGS];
va_list ap;
oldpwd = getcwd (NULL, 0);
if (chdir(dir)) {
if (oldpwd) free(oldpwd);
return -1;
}
if ((d = opendir(dir)) == NULL) {
if (oldpwd) free(oldpwd);
return -1;
}
va_start(ap, dir);
while (argnum < NUM_ARGS && (args[argnum++] = va_arg(ap, char *)));
va_end(ap);
while ((e = readdir(d))) {
if (e->d_type == DT_REG && stat(e->d_name, &st) == 0) {
_d("Found %s/%s ...", dir, e->d_name);
if (st.st_mode & S_IXUSR) {
ent[num++] = strdup(e->d_name);
if (num >= NUM_SCRIPTS)
break;
}
}
}
closedir(d);
if (num == 0) {
if (oldpwd) free(oldpwd);
return 0;
}
qsort(ent, num, sizeof(char *), cmp);
for (i = 0; i < num; i++) {
pid_t pid = 0;
int status;
args[0] = ent[i];
args[1] = NULL;
pid = fork();
if (!pid) {
_d("Calling %s ...", ent[i]);
execv(ent[i], args);
exit(0);
}
waitpid(pid, &status, 0);
free(ent[i]);
}
chdir(oldpwd);
free(oldpwd);
return 0;
}
int getuser(char *s)
{
struct passwd *usr;
if (!s || (usr = getpwnam(s)) == NULL)
return -1;
return usr->pw_uid;
}
int getgroup(char *s)
{
struct group *grp;
if ((grp = getgrnam(s)) == NULL)
return -1;
return grp->gr_gid;
}
/*
* Other convenience functions
*/
void cls(void)
{
static const char cls[] = "\e[2J\e[1;1H";
if (!debug)
fprintf (stderr, "%s", cls);
}
void chomp(char *s)
{
char *x;
if ((x = strchr((s), 0x0a)) != NULL)
*x = 0;
}
void set_procname(char *args[], char *name)
{
size_t len = strlen(args[0]) + 1; /* Include terminating '\0' */
prctl(PR_SET_NAME, name, 0, 0, 0);
memset(args[0], 0, len);
strlcpy(args[0], name, len);
}
/**
* get_pidname - Find name of a process
* @pid: PID of process to find.
* @name: Pointer to buffer where to return process name, may be %NULL
* @len: Length in bytes of @name buffer.
*
* If @name is %NULL, or @len is zero the function will return
* a static string. This may be useful to one-off calls.
*
* Returns:
* %NULL on error, otherwise a va
*/
char *get_pidname(pid_t pid, char *name, size_t len)
{
int ret = 1;
FILE *fp;
char path[32];
static char line[64];
if (!name || len == 0)
name = line;
snprintf(path, sizeof(path), "/proc/%d/status", pid);
if ((fp = fopen(path, "r")) != NULL) {
if (fgets(line, sizeof (line), fp)) {
char *pname = line + 6; /* Skip first part of line --> "Name:\t" */
chomp(pname);
strlcpy(name, pname, len);
ret = 0; /* Found it! */
}
fclose(fp);
}
if (ret)
return NULL;
return name;
}
/**
* kill_procname - Send a signal to a process group by name.
* @name: Name of process to send signal to.
* @signo: Signal to send.
*
* Send a signal to a running process (group). This function searches
* for a given process @name and sends a signal, @signo, to each
* process ID matching that @name.
*
* Returns:
* Number of signals sent, i.e. number of processes who have received the signal.
*/
int kill_procname (const char *name, int signo)
{
int result = 0;
char path[32], line[64];
FILE *fp;
DIR *dir;
struct dirent *entry;
dir = opendir("/proc");
if (!dir || !name) {
errno = EINVAL;
return 0;
}
while ((entry = readdir (dir)) != NULL) {
/* Skip non-process entries in /proc */
if (!isdigit (*entry->d_name))
continue;
snprintf (path, sizeof(path), "/proc/%s/status", entry->d_name);
/* Skip non-readable files (protected?) */
if ((fp = fopen (path, "r")) == NULL)
continue;
if (fgets (line, sizeof (line), fp)) {
char *pname = line + 6; /* Skip first part of line --> "Name:\t" */
if (strncmp(pname, name, strlen(pname) - 1) == 0) {
int error = errno;
if (kill(atoi(entry->d_name), signo)) {
ERROR("Failed signalling(%d) %s: %s!", signo, name, strerror(error));
} else {
result++; /* Track number of processes we deliver the signal to. */
}
}
}
fclose(fp);
}
closedir(dir);
return result;
}
void set_hostname(char *hostname)
{
FILE *fp;
_d("Set hostname: %s", hostname);
if ((fp = fopen("/etc/hostname", "r")) != NULL) {
fgets(hostname, HOSTNAME_SIZE, fp);
chomp(hostname);
fclose(fp);
}
sethostname(hostname, strlen(hostname));
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+51 -3
View File
@@ -1,8 +1,56 @@
#ifndef __FINIT_HELPERS_H /* Misc. utility functions and C-library extensions to simplify finit system setup.
#define __FINIT_HELPERS_H *
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef FINIT_HELPERS_H_
#define FINIT_HELPERS_H_
int makepath (char *); int makepath (char *);
void ifconfig (char *, char *, char *, int); void ifconfig (char *, char *, char *, int);
void copyfile (char *, char *, int); void copyfile (char *, char *, int);
void print_descr (char *action, char *descr);
int print_result (int fail);
int start_process (char *cmd, char *args[], int console);
void cls (void);
void chomp (char *);
int getuser (char *);
int getgroup (char *);
void set_procname (char *args[], char *name);
char *get_pidname (pid_t pid, char *name, size_t len);
int kill_procname (const char *name, int signo);
void set_hostname (char *hostname);
#endif int run (char *cmd);
int run_interactive (char *cmd, char *fmt, ...);
pid_t run_getty (char *cmd, char *argv[]);
int run_parts (char *dir, ...);
#endif /* FINIT_HELPERS_H_ */
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
@@ -0,0 +1,14 @@
Prevent nash-hotplug to keep running after boot using 100% of cpu
diff -rud mkinitrd-6.0.34-orig/nash/hotplug.c mkinitrd-6.0.34/nash/hotplug.c
--- mkinitrd-6.0.34-orig/nash/hotplug.c 2008-03-06 21:20:34.000000000 -0300
+++ mkinitrd-6.0.34/nash/hotplug.c 2008-03-12 18:48:46.000000000 -0300
@@ -547,7 +547,7 @@
nashLogger(nc, NASH_ERROR, "parent exited without telling us\n");
close(nc->hp_childfd);
nc->hp_childfd = -1;
- break;
+ exit(1);
}
count += rc;
}
+222
View File
@@ -0,0 +1,222 @@
/* Plugin based services architecture for finit
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <errno.h>
#include <dlfcn.h> /* dlopen() et al */
#include <dirent.h> /* readdir() et al */
#include <poll.h>
#include <string.h>
#include <sys/queue.h> /* BSD sys/queue.h API */
#include "finit.h"
#include "private.h"
#include "helpers.h"
#include "plugin.h"
#include "svc.h"
#define is_io_plugin(p) ((p)->io.cb && (p)->io.fd >= 0)
static size_t num_fds = 0;
static struct pollfd fds[MAX_NUM_FDS];
static LIST_HEAD(, plugin) plugins = LIST_HEAD_INITIALIZER();
int plugin_register(plugin_t *plugin)
{
int inuse = 0;
if (!plugin) {
errno = EINVAL;
return 1;
}
if (!plugin->name) {
Dl_info info;
if (!dladdr(plugin, &info) || !info.dli_fname)
plugin->name = "unknown";
else
plugin->name = (char *)info.dli_fname;
}
if (is_io_plugin(plugin)) {
if (num_fds + 1 >= MAX_NUM_FDS) {
num_fds = MAX_NUM_SVC;
errno = ENOMEM;
return 1;
}
num_fds++;
inuse++;
}
if (plugin->svc.cb) {
svc_t *svc = svc_find_by_name(plugin->name);
if (svc) {
plugin->svc.id = svc_id(svc);
svc->plugin = &plugin->svc;
inuse++;
}
}
if (!inuse) {
_e("No service \"%s\" loaded, skipping plugin.", basename(plugin->name));
return 1;
}
LIST_INSERT_HEAD(&plugins, plugin, link);
return 0;
}
int plugin_unregister(plugin_t *plugin)
{
LIST_REMOVE(plugin, link);
/* XXX: Unfinished, add cleanup code here! */
return 0;
}
/* Private daemon API *******************************************************/
void run_hooks(hook_point_t no)
{
plugin_t *p;
PLUGIN_ITERATOR(p) {
if (p->hook[no].cb) {
_d("Calling %s hook n:o %d from runloop...", basename(p->name), no);
p->hook[no].cb(p->hook[no].arg);
}
}
}
void run_services(void)
{
plugin_t *p;
PLUGIN_ITERATOR(p) {
if (p->svc.cb) {
_d("Calling svc %s from runloop...", basename(p->name));
p->svc.cb(p->svc.arg, 0);
}
}
}
/* Generic libev I/O callback, looks up correct plugin and calls its callback */
static void generic_io_cb(int fd, int events)
{
plugin_t *p;
/* Find matching plugin, pick first matching fd */
PLUGIN_ITERATOR(p) {
if (is_io_plugin(p) && p->io.fd == fd) {
_d("Calling I/O %s from runloop...", basename(p->name));
p->io.cb(p->io.arg, fd, events);
break;
}
}
}
void io_monitor(void)
{
int ret;
size_t i;
while ((ret = poll(fds, num_fds, 500))) {
if (-1 == ret) {
if (EINTR == errno)
continue;
_e("Failed polling I/O plugin descriptors, error %d: %s",
errno, strerror(errno));
break;
}
/* Traverse all I/O fds and run callbacks */
for (i = 0; i < num_fds; i++) {
if (fds[i].revents)
generic_io_cb(fds[i].fd, fds[i].revents);
}
break;
}
}
/* Setup any I/O callbacks for plugins that use them */
static void init_plugins(void)
{
int i = 0;
plugin_t *p;
PLUGIN_ITERATOR(p) {
if (is_io_plugin(p)) {
_d("Initializing plugin %s for I/O", basename(p->name));
fds[i].revents = 0;
fds[i].events = p->io.flags;
fds[num_fds++].fd = p->io.fd;
}
}
}
int load_plugins(char *path)
{
DIR *dp = opendir(path);
struct dirent *entry;
if (!dp) {
_e("Failed, cannot open plugin directory %s: %s", path, strerror(errno));
return 1;
}
while ((entry = readdir(dp))) {
char *ext = entry->d_name + strlen(entry->d_name) - 3;
if (!strcmp(ext, ".so")) {
void *handle;
char filename[1024];
snprintf(filename, sizeof(filename), "%s/%s", path, entry->d_name);
print_descr(" Loading plugin ", basename(filename));
handle = dlopen(filename, RTLD_LAZY);
if (!handle) {
_d("Failed loading plugin %s: %s", filename, dlerror());
print_result(1);
return 1;
}
print_result(0);
}
}
closedir(dp);
init_plugins();
return 0;
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+121
View File
@@ -0,0 +1,121 @@
/* Plugin based services architecture for finit
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef FINIT_PLUGIN_H_
#define FINIT_PLUGIN_H_
#include <poll.h>
#include <sys/queue.h> /* BSD sys/queue.h API */
#define PLUGIN_IO_READ POLLIN
#define PLUGIN_IO_WRITE POLLOUT
#define PLUGIN_INIT(x) static void __attribute__ ((constructor)) x(void)
#define PLUGIN_EXIT(x) static void __attribute__ ((destructor)) x(void)
#define PLUGIN_ITERATOR(x) LIST_FOREACH(x, &plugins, link)
/*
* Predefined hook points for easier plugin debugging
*/
typedef enum {
HOOK_BASEFS_UP = 0,
HOOK_NETWORK_UP,
HOOK_SYSTEM_UP,
HOOK_SHUTDOWN,
HOOK_MAX_NUM
} hook_point_t;
/**
* plugin_t - Finit &plugin_t object
* @link: BSD sys/queue.h linked list node
* @name: Plugin name, or identifier to match against a &svc_t object
* @svc: Service callback for a loaded &svc_t object
* @hook: Hook callback definitions
* @io: I/O hook callback
*
* To setup an &svc_t object callback for a service monitor the @name
* must match the @svc_t @cmd exactly for them to "pair".
*
* A &plugin_t object may contain a service callback, several hooks
* and/or an I/O callback as well. This way all critical extensions
* to finit can fit in one single plugin, if needed.
*
* The "dynamic events" discussed in the svc callback is for external
* service plugins to implement. However, it can be anything that
* can cause a service to need to SIGHUP at runtime. E.g., acquiring
* a DHCP lease, or an interface going UP/DOWN.
*
* It is up to the external service plugin to track these events and
* relay them to each @dynamic service plugins' callback. I.e., to
* all those with the dynamic flag set.
*/
typedef struct plugin {
/* BSD sys/queue.h linked list node. */
LIST_ENTRY(plugin) link;
/* Plugin name, defaults to plugin path if unset.
* NOTE: Must be same as @cmd for service plugins! */
char *name;
/* Service callback to be called once per lap of runloop. */
struct plugin_svc {
/* Private */
int id; /* Service ID# to match this service plugin against, set on installation. */
/* Public */
void *arg; /* Optional argument to callback func, set by plugin. */
int dynamic; /* Reload (SIGHUP) on dynamic event? Set by plugin. */
int private; /* For callbacks to use freely, possibly to store "states", set by plugin. */
int (*cb)(void *arg, int event);
} svc;
/* List of hook callbacks. */
struct {
void *arg; /* Optional argument to callback func. */
void (*cb)(void *arg);
} hook[HOOK_MAX_NUM];
/* I/O Plugin */
struct {
int fd, flags; /* 1:READ, 2:WRITE */
void *arg;
void (*cb)(void *arg, int fd, int events);
} io;
} plugin_t;
/* Used by svc.h */
typedef struct plugin_svc plugin_svc_t;
/* Public plugin API */
int plugin_register (plugin_t *plugin);
int plugin_unregister (plugin_t *plugin);
#endif /* FINIT_PLUGIN_H_ */
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+35
View File
@@ -0,0 +1,35 @@
# Plugin based services architecture for finit -*-Makefile-*-
CFLAGS = -fPIC -g -Os
CPPFLAGS += -I..
LDFLAGS = -shared
PLUGINS ?= initctl.so alsa-utils.so bootmisc.so dbus.so hwclock.so \
resolvconf.so urandom.so x11-common.so
DEPS = $(addprefix .,$(PLUGINS:.so=.d))
include ../common.mk
all: $(PLUGINS)
clean:
-@$(RM) $(PLUGINS) *.o
distclean: clean
-@$(RM) $(JUNK) $(DEPS)
install: all
@install -d $(DESTDIR)$(prefix)$(PLUGIN_DIR)
@for plugin in $(PLUGINS); do \
echo " INSTALL $(DESTDIR)$(prefix)$(PLUGIN_DIR)/$$plugin"; \
cp $$plugin $(DESTDIR)$(prefix)$(PLUGIN_DIR); \
done
uninstall:
-@for plugin in $(PLUGINS); do \
echo " RM $(PLUGIN_DIR)/$$plugin"; \
rm $(DESTDIR)$(prefix)$(PLUGIN_DIR)/$$plugin 2>/dev/null; \
done
-@rmdir $(DESTDIR)$(prefix)$(PLUGIN_DIR) 2>/dev/null
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
+66
View File
@@ -0,0 +1,66 @@
/* Save and restore ALSA sound settings using alsactl
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
static void save(void *UNUSED(arg))
{
_d("Saving system clock to RTC ...");
run_interactive("/usr/sbin/alsactl store > /dev/null 2>&1", "Saving sound settings");
}
static void restore(void *UNUSED(arg))
{
_d("Restoring system clock from RTC ...");
run_interactive("/usr/sbin/alsactl restore > /dev/null 2>&1", "Restoring sound settings");
}
static plugin_t plugin = {
.hook[HOOK_BASEFS_UP] = {
.cb = restore
},
.hook[HOOK_SHUTDOWN] = {
.cb = save
}
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+85
View File
@@ -0,0 +1,85 @@
/* Setup necessary files for UTMP, tracking logins
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include <utmp.h>
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
static void setup(void *UNUSED(arg))
{
#ifdef RUNLEVEL
struct utmp entry;
#endif
_d("Setting up necessary UTMP files ...");
touch("/var/run/utmp");
chown("/var/run/utmp", 0, getgroup("utmp"));
chmod("/var/run/utmp", 0664);
#ifdef RUNLEVEL
memset(&entry, 0, sizeof(struct utmp));
entry.ut_type = RUN_LVL;
entry.ut_pid = '0' + RUNLEVEL;
setutent();
pututline(&entry);
endutent();
#endif
#ifdef TOUCH_ETC_NETWORK_RUN_IFSTATE
touch("/etc/network/run/ifstate");
#else
remove("/etc/network/run/ifstate");
#endif
_d("Setting up misc files ...");
mkdir("/var/run/sshd", 01755); /* OpenSSH */
mkfifo("/dev/xconsole", 0640); /* sysklogd */
chown("/dev/xconsole", 0, getgroup("tty"));
}
static plugin_t plugin = {
.hook[HOOK_BASEFS_UP] = {
.cb = setup
},
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+62
View File
@@ -0,0 +1,62 @@
/* Setup and start system message bus, D-Bus
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
static void setup(void *UNUSED(arg))
{
#ifdef USE_MESSAGE_BUS
_d("Starting D-Bus ...");
mkdir("/var/run/dbus", 0755);
mkdir("/var/lock/subsys/messagebus", 0755);
run("dbus-uuidgen --ensure");
remove("/var/run/dbus/pid");
run_interactive("dbus-daemon --system", "Starting D-Bus");
#endif
}
static plugin_t plugin = {
.hook[HOOK_NETWORK_UP] = {
.cb = setup
},
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+65
View File
@@ -0,0 +1,65 @@
/* Save and restore RTC using hwclock
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
static void save(void *UNUSED(arg))
{
_d("Saving system clock to RTC ...");
run_interactive("/sbin/hwclock --systohc --utc", "Saving system time (UTC) to RTC");
}
static void restore(void *UNUSED(arg))
{
_d("Restoring system clock from RTC ...");
run_interactive("/sbin/hwclock --hctosys --utc", "Restoring system clock (UTC) from RTC");
}
static plugin_t plugin = {
.hook[HOOK_BASEFS_UP] = {
.cb = restore
},
.hook[HOOK_SHUTDOWN] = {
.cb = save
}
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+120
View File
@@ -0,0 +1,120 @@
/* Optional /dev/initctl FIFO monitor
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <errno.h>
#include <signal.h>
#include <string.h>
#include "finit.h"
#include "plugin.h"
#define INIT_MAGIC 0x03091969
#define INIT_CMD_RUNLVL 1
struct init_request {
int magic; /* Magic number */
int cmd; /* What kind of request */
int runlevel; /* Runlevel to change to */
int sleeptime; /* Time between TERM and KILL */
char data[368];
};
#ifdef LISTEN_INITCTL
/* Standard reboot/shutdown utilities talk to init using /dev/initctl.
* We should check if the fifo was recreated and reopen it.
*/
static void read_initctl(void *UNUSED(arg), int fd, int UNUSED(events))
{
struct init_request request;
_d("Receiving request on %s...", FINIT_FIFO);
while (1) {
ssize_t len = read(fd, &request, sizeof(request));
if (-1 == len) {
_d("Error %d", errno);
break; /* Probably EAGAIN */
}
if (request.magic != INIT_MAGIC)
continue;
_d("Magic OK...");
if (request.cmd == INIT_CMD_RUNLVL) {
switch (request.runlevel) {
case '0':
_d("Halting system (SIGUSR2)");
do_shutdown(SIGUSR2);
break;
case '6':
_d("Rebooting system (SIGUSR1)");
do_shutdown(SIGUSR1);
break;
default:
_d("Unsupported runlevel: %d", request.runlevel);
break;
}
} else {
_d("Unsupported cmd: %d", request.cmd);
}
}
}
static plugin_t plugin = {
.io = {
.cb = read_initctl,
.flags = PLUGIN_IO_READ,
},
};
PLUGIN_INIT(plugin_init)
{
_d("Setting up %s", FINIT_FIFO);
mkfifo(FINIT_FIFO, 0600);
plugin.io.fd = open(FINIT_FIFO, O_RDONLY | O_NONBLOCK);
if (-1 == plugin.io.fd) {
_e("Failed opening %s FIFO, error %d: %s", FINIT_FIFO, errno, strerror(errno));
return;
}
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
#endif /* LISTEN_INITCTL */
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+89
View File
@@ -0,0 +1,89 @@
/* Setup necessary files for resolvconf
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
static void setup(void *UNUSED(arg))
{
#ifdef USE_ETC_RESOLVCONF_RUN
DIR *dir;
struct dirent *d;
#endif
_d("Setting up the resolver ...");
#ifdef USE_ETC_RESOLVCONF_RUN
makepath("/dev/shm/network");
makepath("/dev/shm/resolvconf/interface");
if ((dir = opendir("/etc/resolvconf/run/interface")) != NULL) {
while ((d = readdir(dir)) != NULL) {
if (isalnum(d->d_name[0]))
continue;
snprintf(line, sizeof(line),
"/etc/resolvconf/run/interface/%s", d->d_name);
unlink(line);
}
closedir(dir);
}
#endif
#ifdef USE_VAR_RUN_RESOLVCONF
makepath("/var/run/resolvconf/interface");
symlink("../../../etc/resolv.conf", "/var/run/resolvconf/resolv.conf");
#endif
#ifdef USE_ETC_RESOLVCONF_RUN
touch("/etc/resolvconf/run/enable-updates");
chdir("/etc/resolvconf/run/interface");
run_parts("/etc/resolvconf/update.d", "-i", NULL);
chdir("/");
#endif /* USE_ETC_RESOLVCONF_RUN */
}
static plugin_t plugin = {
.hook[HOOK_BASEFS_UP] = {
.cb = setup
},
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+65
View File
@@ -0,0 +1,65 @@
/* Setup random seed
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
static void setup(void *UNUSED(arg))
{
#ifdef RANDOMSEED
copyfile(RANDOMSEED, "/dev/urandom", 0);
unlink(RANDOMSEED);
umask(077);
copyfile("/dev/urandom", RANDOMSEED, 4096);
umask(0);
#endif
}
static plugin_t plugin = {
.hook[HOOK_BASEFS_UP] = {
.cb = setup
},
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+77
View File
@@ -0,0 +1,77 @@
/* Console setup (for X)
*
* Copyright (c) 2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
static void setup(void *UNUSED(arg))
{
#ifdef PAM_CONSOLE
int fd;
#endif
char line[LINE_SIZE];
makepath("/var/run/console");
snprintf(line, sizeof(line), "/var/run/console/%s", username);
touch(line);
#ifdef PAM_CONSOLE
if ((fd = open("/var/run/console/console.lock", O_CREAT|O_WRONLY|O_TRUNC, 0644)) >= 0) {
write(fd, username, strlen(username));
close(fd);
run("/sbin/pam_console_apply");
}
#endif
mkdir("/tmp/.X11-unix", 01777);
mkdir("/tmp/.ICE-unix", 01777);
}
static plugin_t plugin = {
.hook[HOOK_NETWORK_UP] = {
.cb = setup
},
};
PLUGIN_INIT(plugin_init)
{
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
plugin_unregister(&plugin);
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+44
View File
@@ -0,0 +1,44 @@
/* Private header file for main finit daemon, not for plugins
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef FINIT_PRIVATE_H_
#define FINIT_PRIVATE_H_
#include "plugin.h"
/* plugin.c */
void run_hooks (hook_point_t no);
void run_services (void);
int load_plugins (char *path);
void io_monitor (void);
#endif /* FINIT_PRIVATE_H_ */
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+189
View File
@@ -0,0 +1,189 @@
/* Signal management - Be conservative with what finit responds to!
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* The standard SysV init only responds to the following signals:
* SIGHUP
* Has the same effect as telinit q.
*
* SIGUSR1
* On receipt of this signals, init closes and re-opens its control
* fifo, /dev/initctl. Useful for bootscripts when /dev is remounted.
*
* SIGINT
* Normally the kernel sends this signal to init when CTRL-ALT-DEL is
* pressed. It activates the ctrlaltdel action.
*
* SIGWINCH
* The kernel sends this signal when the KeyboardSignal key is hit.
* It activates the kbrequest action.
*/
#include <sys/reboot.h>
#include <sys/wait.h>
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
#include "private.h"
#include "sig.h"
static int stopped = 0;
void do_shutdown (int sig)
{
touch(SYNC_SHUTDOWN);
if (sdown)
run_interactive(sdown, "Calling shutdown hook: %s", sdown);
_d("Sending SIGTERM to all processes.");
kill(-1, SIGTERM);
sleep(1);
/* Call all shutdown hooks, this is the last call before rebooting... */
run_hooks(HOOK_SHUTDOWN);
_d("Sending SIGKILL to remaining processes.");
kill(-1, SIGKILL);
sync();
sync();
_d("Unmounting file systems, remounting / read-only.");
run("/bin/umount -fa 2>/dev/null");
run("/bin/mount -n -o remount,ro / 2>/dev/null");
run("/sbin/swapoff -ea");
_d("%s.", sig == SIGINT || sig == SIGUSR1 ? "Rebooting" : "Halting");
if (sig == SIGINT || sig == SIGUSR1)
reboot(RB_AUTOBOOT);
reboot(RB_POWER_OFF);
}
/*
* Shut down on INT USR1 USR2
*/
static void shutdown_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
{
_d("Rebooting on signal %d from %s (PID %d)",
sig, get_pidname(info->si_pid, NULL, 0), info->si_pid);
do_shutdown(sig);
}
/*
* SIGCHLD: one of our children has died
*/
static void chld_handler(int UNUSED(sig), siginfo_t *UNUSED(info), void *UNUSED(ctx))
{
/* Do nothing, the svc_monitor() is the designated child reaper. */
}
/*
* SIGSTOP: Paused by user or netflash
*/
static void sigstop_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
{
_d("Received SIGSTOP(%d) from %s (PID %d)",
sig, get_pidname(info->si_pid, NULL, 0), info->si_pid);
touch(SYNC_STOPPED);
stopped ++;
}
static void sigcont_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
{
_d("Received SIGCONT(%d) from %s (PID %d)",
sig, get_pidname(info->si_pid, NULL, 0), info->si_pid);
stopped = 0;
remove(SYNC_STOPPED);
}
/*
* Is SIGSTOP asserted?
*/
int sig_stopped(void)
{
return stopped;
}
/*
* Inital signal setup - ignore everything but SIGCHLD until we're capable of responding
*/
void sig_init(void)
{
int i;
struct sigaction sa;
for (i = 1; i < NSIG; i++)
IGNSIG(sa, i, SA_RESTART);
SETSIG(sa, SIGCHLD, chld_handler, SA_RESTART);
}
/*
* Setup limited set of SysV compatible signals to respond to
*/
void sig_setup(void)
{
struct sigaction sa;
_d("Setup signals");
/* Cleanup any stale finit control files */
remove(SYNC_SHUTDOWN);
remove(SYNC_STOPPED);
/* Standard SysV init calls ctrl-alt-delete handler */
SETSIG(sa, SIGINT, shutdown_handler, 0);
SETSIG(sa, SIGPWR, shutdown_handler, 0);
/* Ignore SIGUSR1/2 for now, only BusyBox init implements them as reboot+halt. */
// SETSIG2(sa, SIGUSR1, reopen_initctl, 0);
// SETSIG2(sa, SIGUSR2, pwrdwn_handler, 0);
/* Init must ignore SIGTERM. May otherwise get false SIGTERM in forked children! */
IGNSIG(sa, SIGTERM, 0);
/* Some C APIs may need SIGALRM for implementing timers. */
IGNSIG(sa, SIGALRM, 0);
/* We don't have any /etc/inittab yet, reread finit.conf? */
IGNSIG(sa, SIGHUP, 0);
/* Stopping init is a bit tricky. */
SETSIG(sa, SIGSTOP, sigstop_handler, 0);
SETSIG(sa, SIGTSTP, sigstop_handler, 0);
SETSIG(sa, SIGCONT, sigcont_handler, 0);
/* Disable CTRL-ALT-DELETE from kernel, we handle shutdown gracefully with SIGINT, above */
reboot(RB_DISABLE_CAD);
setsid();
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+70
View File
@@ -0,0 +1,70 @@
/* Signal management - Be conservative with what finit responds to!
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef FINIT_SIG_H_
#define FINIT_SIG_H_
#include <signal.h>
#define SYNC_SHUTDOWN "/var/lock/finit.shutdown"
#define SYNC_STOPPED "/var/lock/finit.stopped"
#define SETSIG(sa, sig, fun, flags) \
do { \
sa.sa_sigaction = fun; \
sa.sa_flags = SA_SIGINFO | flags; \
sigemptyset(&sa.sa_mask); \
sigaction(sig, &sa, NULL); \
} while (0)
#define IGNSIG(sa, sig, flags) \
do { \
sa.sa_handler = SIG_IGN; \
sa.sa_flags = flags; \
sigemptyset(&sa.sa_mask); \
sigaction(sig, &sa, NULL); \
} while (0)
#define DFLSIG(sa, sig, flags) \
do { \
sa.sa_handler = SIG_DFL; \
sa.sa_flags = flags; \
sigemptyset(&sa.sa_mask); \
sigaction(sig, &sa, NULL); \
} while (0)
void do_shutdown (int sig);
int sig_stopped (void);
void sig_init (void);
void sig_setup (void);
#endif /* FINIT_SIG_H_ */
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+58
View File
@@ -0,0 +1,58 @@
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0) {
while (--n != 0) {
if ((*d++ = *s++) == '\0')
break;
}
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
/**
* Local Variables:
* version-control: t
* c-file-style: "bsd"
* End:
*/
+414
View File
@@ -0,0 +1,414 @@
/* Generic API for managing svc_t structures
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include <sys/wait.h>
#include "finit.h"
#include "helpers.h"
#include "private.h"
#include "sig.h"
#include "svc.h"
/* The registered services are kept in shared memory for easy read-only access
* by 3rd party APIs. Mostly because of the ability to, from the outside, query
* liveness state of all daemons that should run. */
static int svc_counter = 0; /* Number of registered services to monitor. */
static svc_t *services = NULL; /* List of registered services, in shared memory. */
/* Connect to/create shared memory area of registered servies */
static void __connect_shm(void)
{
if (!services) {
services = finit_svc_connect();
if (!services) {
/* This should never happen, but if it does we're probably
* knee-deep in more serious problems already... */
_e("Failed setting up shared memory for service monitor.\n");
abort();
}
}
}
/**
* svc_new - Create a new service object
*
* Returns:
* A pointer to an empty &svc_t object, or %NULL if out of empty slots.
*/
svc_t *svc_new(void)
{
svc_t *svc = NULL;
__connect_shm();
if (svc_counter < MAX_NUM_SVC) {
svc = &services[svc_counter];
memset(svc, 0, sizeof(*svc));
svc->id = svc_counter++;
} else {
errno = ENOMEM;
return NULL;
}
return svc;
}
/**
* svc_find_by_id - Find a service object by its logical ID#
* @id: Logical ID#
*
* Returns:
* A pointer to an &svc_t object, or %NULL if not found.
*/
svc_t *svc_find_by_id(int id)
{
__connect_shm();
if (id >= svc_counter)
return NULL;
return &services[id];
}
/**
* svc_find_by_name - Find a service object by its full path name
* @name: Full path name, e.g., /sbin/syslogd
*
* Returns:
* A pointer to an &svc_t object, or %NULL if not found.
*/
svc_t *svc_find_by_name(char *name)
{
int i;
__connect_shm();
for (i = 0; i < svc_counter; i++) {
svc_t *svc = &services[i];
if (!strncmp(name, svc->cmd, strlen(svc->cmd))) {
_d("Found a matching svc for %s", name);
return svc;
}
}
return NULL;
}
/**
* svc_iterator - Iterates over all registered services.
* @restart: Get first &svc_t object by setting @restart
*
* Returns:
* The first &svc_t when @restart is set, otherwise the next &svc_t until
* the end when %NULL is returned.
*/
svc_t *svc_iterator(int restart)
{
static int id = 0;
__connect_shm();
if (restart)
id = 0;
if (id >= svc_counter)
return NULL;
return &services[id++];
}
/**
* svc_register - Register a non-backgrounding service to be monitored
* @line: A complete command line with -- separated description text
* @username: Optional username to run service as, or %NULL to run as root
*
* Actually, the @line can optionally start with a username, denoted by
* an @ character. Like this:
*
* "service [@username] /path/to/daemon -- Description text"
*
* The [] brackets means the argument is optional. If the username is
* left out the daemon is started as root.
*
* Returns:
* POSIX OK(0) on success, or non-zero errno exit status on failure.
*/
int svc_register(char *line, char *username)
{
int i = 0;
char *cmd, *descr;
svc_t *svc;
if (!line) {
_e("Invalid input argument.");
return errno = EINVAL;
}
descr = strstr(line, "-- ");
if (descr)
*descr = 0;
cmd = strtok(line, " ");
if (!cmd) {
incomplete:
_e("Incomplete service, cannot register.");
return errno = ENOENT;
}
if (cmd[0] == '@') { /* @username */
username = &cmd[1];
/* Check if valid command follows... */
cmd = strtok(NULL, " ");
if (!cmd)
goto incomplete;
}
svc = svc_new();
if (!svc) {
_e("Out of memorym, cannot register service %s", cmd);
return errno = ENOMEM;
}
if (descr)
strlcpy(svc->descr, descr + 3, sizeof(svc->descr));
if (username)
strlcpy(svc->username, username, sizeof(svc->username));
strlcpy(svc->cmd, cmd, sizeof(svc->cmd));
strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
while ((cmd = strtok(NULL, " ")))
strlcpy(svc->args[i++], cmd, sizeof(svc->args[0]));
svc->args[i][0] = 0;
return 0;
}
/**
* svc_enabled - Should the service run?
* @svc: Pointer to &svc_t object
* @dynamic: Dynamic event, opaque flag passed to callback
*
* This method calls an associated service callback, if registered by a
* plugin, and returns the &svc_cmd_t status. If no plugin is registered
* the service is statically enabled in /etc/finit.conf and the result
* will always be %SVC_START.
*
* Returns:
* Either one of %SVC_START, %SVC_STOP, %SVC_RELOAD.
*/
svc_cmd_t svc_enabled(svc_t *svc, int dynamic)
{
if (!svc) {
errno = EINVAL;
return SVC_STOP;
}
if (!svc->plugin) {
/* Unknown service, default to enabled. */
return SVC_START;
}
return svc->plugin->cb(svc, dynamic);
}
static int is_norespawn(void)
{
return sig_stopped() ||
fexist("/mnt/norespawn") ||
fexist("/tmp/norespawn");
}
void svc_monitor(void)
{
pid_t lost;
svc_t *svc;
lost = waitpid(-1, NULL, WNOHANG);
if (lost < 1)
return;
if (fexist(SYNC_SHUTDOWN) || lost <= 1)
return;
/* Power user at the console, don't respawn tasks. */
if (is_norespawn())
return;
for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
char *name = basename(svc->cmd);
if (lost != svc->pid)
continue;
_d("Ouch, lost pid %d - %s(%d)", lost, name, svc->pid);
if (sig_stopped()) {
_e("Stopped, not respawning killed processes.");
break;
}
/* Cleanup any lingering or semi-restarting tasks before respawning */
_d("Sending SIGTERM to service group %s", name);
kill_procname(name, SIGTERM);
/* Restarting lost service. */
if (svc_enabled(svc, 0))
svc_start(svc);
break;
}
}
int svc_start(svc_t *svc)
{
int respawn = svc->pid != 0;
pid_t pid;
char *args[MAX_NUM_SVC_ARGS];
/* Ignore if finit is SIGSTOP'ed */
if (is_norespawn())
return 0;
if (!respawn)
print_descr("Starting ", svc->descr);
pid = fork();
if (pid == 0) {
int i = 0;
int uid = getuser(svc->username);
struct sigaction sa;
/* Reset signal handlers that were set by the parent process */
for (i = 1; i < NSIG; i++)
DFLSIG(sa, i, 0);
/* Set desired user */
if (uid >= 0)
setuid(uid);
/* Serve copy of args to process in case it modifies them. */
for (i = 0; svc->args[i][0] != 0 && i < MAX_NUM_SVC_ARGS; i++)
args[i] = svc->args[i];
args[i] = NULL;
if (debug) {
int fd = open (CONSOLE, O_WRONLY | O_APPEND);
if (-1 != fd) {
dup2(STDOUT_FILENO, fd);
dup2(STDERR_FILENO, fd);
}
_e("%starting %s ", respawn ? "Res" : "S", svc->cmd);
for (i = 0; args[i] && i < MAX_NUM_SVC_ARGS; i++)
_e("%s ", args[i]);
_e("");
}
execvp(svc->cmd, args);
exit(0);
}
svc->pid = pid;
if (!respawn)
print_result(svc->pid > 1 ? 0 : 1);
return 0;
}
int svc_start_by_name(char *name)
{
svc_t *svc = svc_find_by_name(name);
if (svc && svc_enabled(svc, 0))
return svc_start(svc);
return 1;
}
int svc_stop(svc_t *svc)
{
int res = 1;
if (!svc) {
_e("Failed, no svc pointer.");
return 1;
}
if (svc->pid <= 1) {
_d("Bad PID %d for %s, SIGTERM", svc->pid, svc->descr);
svc->pid = 0;
return 1;
}
print_descr("Stopping ", svc->descr);
_d("Sending SIGTERM to pid:%d name:'%s'", svc->pid, get_pidname(svc->pid, NULL, 0));
res = kill(svc->pid, SIGTERM);
print_result(res);
svc->pid = 0;
return res;
}
int svc_reload(svc_t *svc)
{
if (!svc) {
_e("Failed, no svc pointer.");
return 1;
}
if (svc->pid <= 1) {
_d("Bad PID %d for %s, SIGHUP", svc->pid, svc->cmd);
svc->pid = 0;
return 1;
}
_d("Sending SIGHUP to PID %d", svc->pid);
return kill(svc->pid, SIGHUP);
}
void svc_start_all(void)
{
svc_t *svc;
svc_cmd_t cmd;
for (svc = svc_iterator(1); svc; svc = svc_iterator(0)) {
cmd = svc_enabled(svc, 0);
if (cmd == SVC_START || (cmd == SVC_RELOAD && svc->pid == 0))
svc_start(svc);
else if (cmd == SVC_RELOAD)
svc_reload(svc);
}
/* XXX: Hook point for plugins. */
}
/**
* Local Variables:
* compile-command: "gcc -g -DUNITTEST -o unittest svc.c"
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+118
View File
@@ -0,0 +1,118 @@
/* Generic API for managing svc_t structures
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef FINIT_SVC_H_
#define FINIT_SVC_H_
#include <errno.h>
#include <string.h> /* strerror() */
#include <sys/shm.h> /* shmat() */
#include <sys/types.h> /* pid_t */
#include "finit.h"
#include "plugin.h"
typedef enum {
SVC_STOP = 0, /* Disabled */
SVC_START, /* Enabled */
SVC_RELOAD /* Enabled, needs restart */
} svc_cmd_t;
#define FINIT_SHM_ID 0x494E4954 /* "INIT", see ascii(7) */
#define MAX_ARG_LEN 64
#define MAX_STR_LEN 64
#define MAX_USER_LEN 16
#define MAX_NUM_FDS 64 /* Max number of I/O plugins */
#define MAX_NUM_SVC 64 /* Enough? */
#define MAX_NUM_SVC_ARGS 16
/* Default enable for all services, can be stopped by means
* of issuing an initctl call. E.g.
* initctl <stop|start|restart> service */
typedef struct svc {
/* Private */
int id; /* Service ID#, set by svc_new() */
pid_t pid;
char cmd[MAX_ARG_LEN];
char args[MAX_NUM_SVC_ARGS][MAX_ARG_LEN];
char descr[MAX_STR_LEN];
char username[MAX_USER_LEN];
/* Public */
int delayed_reload; /* For external service plugin. */
plugin_svc_t *plugin;
} svc_t;
typedef struct svc_map svc_map_t;
/* Put services array in shm */
static inline svc_t *finit_svc_connect(void)
{
const long ID = FINIT_SHM_ID;
static void *ptr = (void *)-1;
if ((void *)-1 == ptr) {
ptr = shmat (shmget (ID, sizeof(svc_t) * MAX_NUM_SVC, 0600 | IPC_CREAT), NULL, 0);
if ((void *)-1 == ptr) {
_d("Failed allocating shared memory, error %d: %s", errno, strerror (errno));
return NULL;
}
}
return (svc_t *)ptr;
}
static inline int svc_id(svc_t *svc)
{
if (!svc) {
errno = EINVAL;
return -1;
}
return svc->id;
}
svc_t *svc_new (void);
svc_t *svc_find_by_id (int id);
svc_t *svc_find_by_name (char *name);
svc_t *svc_iterator (int restart);
int svc_register (char *line, char *username);
int svc_id_by_name (char *name);
svc_cmd_t svc_enabled (svc_t *svc, int dynamic);
int svc_start (svc_t *svc);
int svc_start_by_name (char *name);
int svc_stop (svc_t *svc);
int svc_reload (svc_t *svc);
void svc_start_all (void);
void svc_monitor (void);
#endif /* FINIT_SVC_H_ */
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/