Code Monkey home page Code Monkey logo

dinit's People

Contributors

amano-kenji avatar asherikov avatar capezotte avatar davmac314 avatar dependabot[bot] avatar duncaen avatar firasuke avatar fpoussin avatar iacore avatar ingwiephoenix avatar into-the-v0id avatar james-knippes avatar konimex avatar mobin-2008 avatar mskarbek avatar q66 avatar realroot2185 avatar roze061 avatar travankor avatar vext01 avatar yukarichiba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dinit's Issues

[Feature request] status of service

I would like to see status and small log of specific service using
dinitctl status service-name
Using dinitctl list does show status , but it fill up whole screen.

CI: Provide "fuzz" for dinit!

Goal

Provide "fuzz" step for dinit in CI

ToDo

  • Checkout dinit fuzzer backend (For debugging,improve...) (#91)
  • Learn more about Fuzzer & LLVM's libfuzzer
  • Provide "fuzz" ci workflow(s) (#96)

References

https://en.wikipedia.org/wiki/Fuzzing: Fuzzing, From Wikipedia, the free encyclopedia:

In programming and software development, fuzzing or fuzz testing is an automated software testing technique that involves providing invalid, unexpected, or random data as inputs to a computer program. The program is then monitored for exceptions such as crashes, failing built-in code assertions, or potential memory leaks. Typically, fuzzers are used to test programs that take structured inputs. This structure is specified, e.g., in a file format or protocol and distinguishes valid from invalid input. An effective fuzzer generates semi-valid inputs that are "valid enough" in that they are not directly rejected by the parser, but do create unexpected behaviors deeper in the program and are "invalid enough" to expose corner cases that have not been properly dealt with.
For the purpose of security, input that crosses a trust boundary is often the most useful.[1] For example, it is more important to fuzz code that handles the upload of a file by any user than it is to fuzz the code that parses a configuration file that is accessible only to a privileged user.

https://github.com/davmac314/dinit/blob/master/BUILD file description:

dinit/BUILD

Lines 116 to 128 in ececd16

In addition to the standard test suite, there is experimental support for fuzzing the control
protocol handling using LLVM/clang's fuzzer (libFuzzer). Change to the `src/tests/cptests`
directory and build the "fuzz" target:
make fuzz
Then create a "corpus" directory and run the fuzzer:
mkdir corpus
./fuzz corpus
This will auto-generate test data as it finds input which triggers new execution paths. Check
libFuzzer documentation for further details.

LLVM's libfuzzer project page:

https://llvm.org/docs/LibFuzzer.html

Test fails after commit 18acacf

make check fails after "base_process_service: properly clean up in destructor" commit

$ make check
make -C src check
make[1]: Entering directory '/home/marcin.skarbek/projects/dinit/src'
make -C tests check
make[2]: Entering directory '/home/marcin.skarbek/projects/dinit/src/tests'
mkdir -p includes
rm -rf includes/*.h
cd includes; ln -sf ../../includes/*.h .
cd includes; ln -sf ../test-includes/*.h .
g++ -D_GLIBCXX_USE_CXX11_ABI=1 -std=c++11 -Os -Wall -fno-rtti -fno-plt -flto -fsanitize=address,undefined -MMD -MP -Iincludes -I../dasynq -c ../proc-service.cc -o proc-service.o
In file included from ../proc-service.cc:8:0:
includes/proc-service.h: In destructor ‘virtual base_process_service::~base_process_service()’:
includes/proc-service.h:141:28: error: ‘class service_child_watcher’ has no member named ‘unreserve’; did you mean ‘add_reserved’?
             child_listener.unreserve(event_loop);
                            ^~~~~~~~~
                            add_reserved
includes/proc-service.h:143:23: error: ‘class process_restart_timer’ has no member named ‘deregister’
         restart_timer.deregister(event_loop);
                       ^~~~~~~~~~
make[2]: *** [Makefile:29: proc-service.o] Error 1
make[2]: Leaving directory '/home/marcin.skarbek/projects/dinit/src/tests'
make[1]: *** [Makefile:27: check] Error 2
make[1]: Leaving directory '/home/marcin.skarbek/projects/dinit/src'
make: *** [Makefile:7: check] Error 2```

[Feature request] Environment variables in command

Did you considered handling variables in service command?
Use case: running confd service inside docker container with ETCD_HOST variable provided by docker and dinit as PID 1.

type = process
command = /usr/bin/confd -interval 5 -node ${ETCD_HOST}
options = runs-on-console

Currently that has to be handled by sh script that is wrapping confd command.

before and after support?

it might be handy to be able to specify a constraint that a service has to start before or after (like waits-for but without actually requesting the named service to start, instead only having an effect if the named service is enabled) some other service starts; e.g. like before = foo

this would allow for more flexible handling of ordering when writing service files, without having to touch other service files to get it

`make fuzz` target is broken!

Hello.
I was working on the fuzzer when I ran into several problems:

  1. includes addresses is broken:

    fuzz: fuzz.cc $(fuzz_parent_test_objects) $(fuzz_objects)
    clang++ -std=c++11 -g -O1 -Iincludes -I../../dasynq -fsanitize=fuzzer,address,undefined,leak fuzz.cc $(fuzz_parent_test_objects) $(fuzz_objects) -o fuzz
    $(fuzz_parent_test_objects): fuzz-%.o: ../%.cc
    clang -O1 -fsanitize=address,undefined,fuzzer-no-link,leak -MMD -MP -I../includes -I../../dasynq -c $< -o $@
    $(fuzz_objects): fuzz-%.o: ../../%.cc
    clang -O1 -fsanitize=address,undefined,fuzzer-no-link,leak -MMD -MP -Iincludes -I../../dasynq -c $< -o $@

    (fixed by #92).

  2. prepare-incdir target not runned by make when building fuzz target! its target prepare include dirs for building tests/fuzz (fixed by #94)

  3. because fuzz target not runned by upstream MakeFile, mconfig.h not exist but we need mconfig.h for buliding fuzz target (fixed by #95):

❯ make fuzz
clang -O1 -fsanitize=address,undefined,fuzzer-no-link,leak -MMD -MP -Iincludes -I../../../dasynq/include -c ../test-bpsys.cc -o fuzz-test-bpsys.o
clang -O1 -fsanitize=address,undefined,fuzzer-no-link,leak -MMD -MP -Iincludes -I../../../dasynq/include -c ../test-dinit.cc -o fuzz-test-dinit.o
clang -O1 -fsanitize=address,undefined,fuzzer-no-link,leak -MMD -MP -Iincludes -I../../../dasynq/include -c ../../control.cc -o fuzz-control.o
In file included from ../../control.cc:6:
In file included from includes/control.h:16:
In file included from includes/service-listener.h:4:
includes/service-constants.h:4:10: fatal error: 'mconfig.h' file not found
#include "mconfig.h"
         ^~~~~~~~~~~
1 error generated.

regards

serverless dinitctl

In a installation dinit has never been launched yet, so I cant enable important services like networkmanager, ssh... (I dont remember this problem before, is this a new change?)

I'd like to dinitctl to enable/disable services without dinit server, or at least enable... if I execute the command as root. Always or with a option ? or maybe a workaround ?
Thanks.

Dinit should diagnose deadlock when a service and its dependency both require console

Simple situation - docker container with 3 services:
crond (/etc/dinit.d/crond ):

type = process
command = /usr/sbin/crond -n -m off
restart = false

confd (/etc/dinit.d/confd):

type = scripted
command = /etc/dinit.d/confd.sh start
restart = false
options = runs-on-console

confd.sh (/etc/dinit.d/confd.sh):

#!/bin/sh

if [ "$1" = start ]; then
    /usr/bin/confd -onetime -backend etcd -node ${ETCD_HOST}
fi

nodejsapp (/etc/dinit.d/nodejsapp)

type = process
command = /usr/bin/node app.js
restart = false
options = runs-on-console
depends-ms = confd
start-timeout = 10

All that run by boot:

type = internal

waits-for = confd
waits-for = crond
waits-for = nodejsapp

Dinit fails to start nodejsapp. Container hangs at:

# docker exec -it nodejsapp bash
# dinitctl -s list
[{ }<<   ] boot
[{+}     ] confd
[{+}     ] crond
[{ }<<   ] nodejsapp

confd successfully finished it's job end exited with 0, crond works fine but nodejsapp never starts:

# docker exec -it nodejsapp bash
# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  13724  3160 ?        Ss   16:32   0:00 /usr/sbin/dinit -s -d /etc/dinit.d
root         8  0.0  0.0  22964  2828 ?        Ss   16:32   0:00 /usr/sbin/crond -n -m off
root        19  0.0  0.0  12124  3188 pts/0    Ss   16:33   0:00 bash
root        49  0.0  0.0  34936  2992 pts/0    R+   16:45   0:00 ps aux

If you exec into container and manually stop and then start nodejsapp then it starts fine and have correct status in dinitctl -s list. start-timeout = 10 seems to have no effect, container just hangs in that state for ever.

Security policy

I know it's too early to do that. dinit is currently in version 0.15.1 and due to one of the design principles of dinit "Limited Feature Scope" it is very unlikely that we will encounter security vulnerabilities but again I think it is useful to consider a "Security policy" .
Just specify how to report a security vulnerability (github issues would definitely be a bad idea. I personally recommend email)

This is a marginal issue right now, but I personally think it will be important in the future.

regards

Ability to restart a service

Hi,

I don't think there's a way to restart a service short of stopping and starting it?

It'd be neat to have dinitctl restart <service>.

Suggestions about comparison with InitNG

dinit/doc/COMPARISON

Lines 287 to 294 in 716fc4d

InitNG (http://initng.org/trac; defunct)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
A highly modular init system which apparently offers dependency management
(as Dinit does). Portability status is unclear; may be Linux-only (Dinit
strives for portability). Development may have ceased (website is now showing
Japanese text which I am unable to read) although there are what looks like
maintenance commits from 2017 in the Github repository at
https://github.com/initng/initng.

  • development ceased in February 2013.
  • focused on Linux but portable, there used to be a port for Haiku.
  • Website is dead.
  • offers dependencies.

Variable substitution outside command paths

In my system I'm implementing a concept of systemwide user services. For this, having the ability to do some kind of variable substitution in non-command paths (e.g. socket-listen and notably logfile) would be good (e.g. homedir, or current user ID). As far as I can tell there is no way to accomplish this currently.

Possible dinitcheck dependency resolution failure (0.8.0)

Report from user; dinitcheck is not finding all dependencies:

> dinitctl list     
[{+}     ] boot
[{+}     ] mail-loop (pid: 53615)
[{+}     ] syncthing (pid: 89252)
[{+}     ] mpd (pid: 28838)
> dinitcheck        
Checking service: boot...
Checking service: mpd...
No problems found.

Dependencies from list should all be found:

> cat boot           
type = internal
waits-for.d = /home/edd/.dinit
> ls -1 /home/edd/.dinit
mail-loop
mpd
syncthing

Additional:

> cat mail-loop 
type = process
command = /home/edd/eck2/bin/mail-loop
termsignal = KILL
>
> cat mpd
type = process
command = /usr/local/bin/mpd --no-daemon
>
> cat syncthing 
type = process
command = /usr/local/bin/syncthing -no-browser -logfile=/tmp/stlog

container example?

I read your blog post, and was intrigued, i've been looking for a lightweight systemd replacement for containers, focusing on simple service management, without going back to sysvinit with shell scripts.

I tried using it as a general purpose service manager, to allow child containers to just copy in a /etc/dinit.d/boot, and let dinit just take over... but i'm getting "free(): invalid pointer" whenever trying to use /sbin/dinit as the container's PID 1.

Any suggestions? I'm trying 0.8.0

notify-send support

It would be neat if dinit could send desktop notifications when run in user mode. For example, when a service fails, or restarts.

How to Activiate dinit socket at recovery mode?

Hello. I was working on a recovery service when I ran into a problem (I do not know if it is a bug or not?)
dinit loads recovery service when boot fails but dinit does not create /run/dinitctl socket! This will make dinitctl unavailable. This makes it harder to restore the system in recovery mode.
But unlike recovery mode, in single-user mode, dinit creates the /run/dinitctl socket correctly.
How can this problem be solved? I had several solutions in mind, none of which worked better than fixing it in dinit.

regards

[RFE] Individual environment config files

It would be nice to be able to create a file with environment variables for each service. Even better when that file could be created by another service (as a dependency) and loaded during the execution of a particular service.

[RFE] Redirect stdout/stderr for all services

Currently, only one service is able to print to the console, the rest is expected to use some kind of logging management (rsyslog for example). It is perfectly valid and makes sense in a bare metal/VM scenario but falls apart in containers context. It would be very beneficial for containers use case to be able to redirect stdout/stderr of all running services to console and let a container runtime manage the logs.

Current master fails to compile

$ git log -1
commit bd7762913aadb274dd89b92f15c31d0986d6d9c0 (HEAD -> master, origin/master, origin/HEAD)
(...)
$ make
make -C src all
make[1]: Entering directory '/home/marcin.skarbek/projects/dinit/src'
make[1]: *** No rule to make target 'service.h', needed by 'dinit.o'.  Stop.
make[1]: Leaving directory '/home/marcin.skarbek/projects/dinit/src'
make: *** [Makefile:4: all] Error 2

How to load "Specifie" service from bootloader/kernel comand line?

Hello.

We can start the single service using dinit by entering single in the Bootloader command line.
But unfortunately, it is not possible to load another service with this method.
This is important to me because I'm considering replacing the single service with rescue and also want to implement a systemd target-like structure in @Dinit-on-Devuan.
This feature (calling any service using the Bootloader command line) makes it possible to run any target at system startup.

@davmac314 Now my question is whether it is possible to do this or whether such a feature has been implemented or not?

regards

[Feature request] Enable/disable service

I know that what I will propose is a lot like systemd but IMO it's worth considering.
I would like to have separate service configuration dir - /var/lib/dinit.d and be able to enable service by linking services in it to /etc/dinit.d dir. boot service could automatically assume that everything in /etc/dinit.d should be treated as waits-for.
Reasoning behind that is to be able to package service config file with software, install/uninstall and manage that service using simple %post/%preun rpm macros without parsing and editing boot file.

dinit readiness notification support

I was wondering if you'd be interested in having support for readiness notification of dinit itself, in a similar manner to how it handles it for services themselves, I was thinking something like having a launch parameter to pass a file descriptor number to which dinit would write after finishing startup of its initial services (boot or the ones passed on command line).

My use case for this is for dinit-userservd, which is Chimera's daemon that automatically manages user instances of dinit while keeping track of logins/logouts (via a PAM module; the PAM module connects to the daemon's socket, which is considered a login, and disconnection is considered a logout).

Right now I have a bit clunky mechanism in place - the daemon generates the boot service it starts dinit with, which then does startup of user services (your custom boot.d which lives in your home directory), and the daemon itself basically creates a named pipe, while the generated boot service pokes the write end of that pipe, which then signals the daemon and the daemon allows the login to proceed on PAM side.

If I was able to specify the file descriptor and the readiness was handled in dinit itself, I would be able to create a local unnamed pipe in-process and pass the write end to dinit (since it's a child process) and otherwise keep things the same (just without having to touch the filesystem).

I was going to implement this, but I first wanted to know your opinion and/or if you have any better ideas.

[Feature Request] check-command for scripted services

Right now, scripted services cannot be supervised, however in some scenarios there might be a way to supervise them via command line arguments (for example, for a service that listens on a port, we could check if the port is still open). Having a check-command field in the service description files could therefore be useful for that kind of purpose.
I imagine the command outputting a non-zero exit value if the process is not running (stopped or starting) and zero if the service is running.
Additionally, a check-command-interval could prove useful so that Dinit can poll the status every X seconds and restart a service if needed.

bgprocess fails to read pid-file

dinit fails to read pid file:

dinit: cntlm: read pid file: No such file or directory
[FAILED] cntlm
[  OK  ] boot
cntlm[11]: Daemon ready

Process is working correctly and creates pid file in the right place but I suspect that dinit tries to read it too soon.
Service file:

type = bgprocess
command = /usr/sbin/cntlm -c /etc/cntlm.conf -U cntlm -P /run/cntlm/cntlmd.pid
pid-file = /run/cntlm/cntlmd.pid
restart = true
smooth-recovery = true
options = runs-on-console
depends-on = cntlm-config

cf37c78 broke make check

g++ -D_GLIBCXX_USE_CXX11_ABI=1 -std=c++11 -Os -Wall -fno-rtti -fno-plt -flto -fsanitize=address,undefined -MMD -MP -Iincludes -I../../dasynq -c ../../service.cc -o service.o
g++ -fsanitize=address,undefined -o cptests cptests.o ../test-bpsys.o ../test-dinit.o control.o dinit-log.o service.o load-service.o proc-service.o baseproc-service.o run-child-proc.o -flto -Os
make[3]: Leaving directory '/root/dinit/src/tests/cptests'
./tests
test1...                     tests: tests.cc:71: void test1(): Assertion `s2->get_state() == service_state_t::STOPPED' failed.
make[2]: *** [Makefile:12: run-tests] Aborted (core dumped)
make[2]: Leaving directory '/root/dinit/src/tests'
make[1]: *** [Makefile:54: check] Error 2
make[1]: Leaving directory '/root/dinit/src'
make: *** [Makefile:12: check] Error 2

Commit earlier make check and make check-igr finished with success.

Command naming

The names looks like systemd commands with the "ctl" suffix. Totally distinctive names will avoid any confusion. Especially if the project is made in reaction of systemd.

load-options and environment variables

Description

I've been reading the docs about load-options, and I'm a bit confused of what and how environment variables are read. The code has env-file option, but there's no documentation on dinit-service(5). I'm using a test scripted service with GNU Hello to see how load-options work, with its output piped to /run/hello.log. However, when I start the service, /run/hello.log has no contents at all, when it should've been greet1 as per addendum.

Addenda

Contents of /etc/dinit.d/hello

type = scripted
command = /usr/bin/hello -g $GREET
logfile = /run/hello.log
load-options = sub-vars
env-file = /etc/hello.conf

Contents of hello.conf

GREET="greet1"

dinitctl socket unreachable

Hi,

It seems like the socket at /dev/dinitctl becomes unavailable as we are mounting /dev to tmpfs.
I haven't had a deep look at the code, but I assume it should re-open a file descriptor after /dev has been mounted (instead of during / rw remount) in order for it to work.

# dinitctl -s list
dinitctl: connect: No such file or directory

# netstat -lna
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node Path
unix  2      [ ACC ]     SEQPACKET  LISTENING       7040 /run/udev/control
unix  2      [ ACC ]     STREAM     LISTENING       8594 /dev/dinitctl
unix  3      [ ]         DGRAM                      8602 
unix  3      [ ]         DGRAM                      8601 

# lsof 1
1       /sbin/dinit     /dev/console
1       /sbin/dinit     /dev/console
1       /sbin/dinit     /dev/console
1       /sbin/dinit     anon_inode:[eventpoll]
1       /sbin/dinit     anon_inode:[timerfd]
1       /sbin/dinit     anon_inode:[timerfd]
1       /sbin/dinit     anon_inode:[signalfd]
1       /sbin/dinit     socket:[8594]
1       /sbin/dinit     /etc/dinit.d/boot.d

/dev/dinitctl is not present.
I'm using eudev.

`run-as` does not work as advertised

man specifies that run-as will set group to the primary group of the specified user. Unfortunately that doesn't work, for user uid=998(gitlab-runner) gid=995(gitlab-runner) groups=995(gitlab-runner) process with run-as set to gitlab-runner works as gitlab-runner:root.

dinit run as pid 1 (root:root) in container.

Package in Fedora/EPEL repos

I would like to finally publish my package in the main Fedora repo and then add it to EPEL. For that, I would like to have recently added -o in a released version. So what's the plan for the next release?

integration testing

What is your take on 'integration testing' scenario, i.e., the situation when service crashes must not be recoverable. For example, diinit could start some sort of crash handler service on failure or terminate everything including itself. It looks like depends-on is an option, but there is no depends-on.d, which is quite inconvenient. It would also be interesting to set default service parameters depending on scenario (testing/production) via service templates.

dinitctl: `dinitctl status` shows `Process ID:` for scripted services!

Hi.
I created a service as follows:

type = scripted
command = /etc/init.d/resolvconf start
stop-command = /etc/init.d/resolvconf stop
logfile = /var/log/resolvconf.log

depends-on = networking
waits-for = dnscrypt-proxy

Then I saw its status via dinitctl status resolvconf command:

Service: resolvconf
    State: STARTED
    Activation: explicitly started
    Process ID: 0

But dinitctl try to show Process ID for scripted services!
This appears to be a regression as this was not an issue in the past.

regards

command to export environment variables into activation env

This would be similar to systemd, which provides a way to export environment variables into its activation environment that is then used for services that are started later. I'm thinking this could perhaps be a command for dinitctl; thus it would require the same access level as starting/stopping services and so on.

My main use for this would be able to e.g. smoothly export the dbus session bus address into environment for user services, as well as other session-related variables that are currently not available (because the user-instance of dinit runs separately from the login so that it can properly persist when you say, log in on another tty and then log out on the first one) so that user services can handle things that rely on these, without needing clunky command wrappers.

My other option is to implement this as a part of dinit-userservd (which is my daemon that manages automatic user instances of dinit) and then provide a special command that will invoke another command through environment managed by dinit-userservd and have user services do something like command = /usr/bin/dinit-run-session another-command ... but I would first like to hear whether you'd consider implementing this into dinit itself (or accept contribution of such functionality) as it would make for nicer service files, and make the functionality available to system services as well (though this could actually be an anti-feature, not quite sure yet)

Integration tests will crash on version 0.15.0 or later!

Hello.
I researched the strange breakdown of integration tests and came to an important conclusion!
I found that these bugs only exist in 0.15.0 or 0.15.1 and 0.14.0 has no problem with that!
"Why did I come to this conclusion?"
1- When integration tests in github actions are turned on, they are broken!
2- I tested this issue on drone.mobintestserver.ir. 0.14.0 has no problem with make check-igr. But 0.15.1 fails in make check-igr‍.
0.14.0: https://drone.mobintestserver.ir/Dinit_on_Devuan/dinit/42/1/2
0.15.1: https://drone.mobintestserver.ir/Dinit_on_Devuan/dinit/45

But there is a strange thing:
make check-igr on my computer does not fail with any of the dinit versions!

Really weird problem!

[Feature Request] Silent boot

Something like systemd and s6 (s6-linux-init) do when the quiet argument is passed through cmdline (e.g, using grub).

make fails with more than one job

make -j tries to build mconfig.h at the same time as other sourcefiles which require mconfig.h.

Adding

$(dinit_objects): includes/mconfig.h

and changing the dinit target to dinit: $(dinit_objects) in src/makefile fixes this problem for me.

make check -j also fails, but i did not look further into this.

[Feature Request] Set-target

Something like dinitctl set-target is needed. Systemd handles this with .target files, so dinit will need to either use another form of .sh files or incorporate .target files.

[Documentation] Using dinit on LFS/BLFS - could a subsection be added to the main README.md or elsewhere?

Hey Davin,

Not sure if you have time/energy, but it may be interesting to see how to use and apply dinit to a LFS/BLFS setup (linux from scratch / beyond linux from scratch).

E. g. ideally a short recipe how to get that to work, for people who never before used dinit but would like to try it out. Please feel free to close this if this seems too much work or is otherwise not wanted, no problem!

Failed to build with GCC 10

With GCC 8.3 dinit 0.8.2 compiles just fine and all tests passed but with GCC 10.1:

g++ -D_GLIBCXX_USE_CXX11_ABI=1 -std=c++11 -Os -Wall -fno-rtti -fno-plt -flto -MMD -MP -Iincludes -Idasynq -c proc-service.cc -o proc-service.o
In file included from dasynq/dasynq.h:7,
                 from includes/dinit.h:4,
                 from proc-service.cc:7:
dasynq/dasynq-stableheap.h:21:5: error: 'uint64_t' does not name a type; did you mean 'u_int64_t'?
   21 |     uint64_t order;
      |     ^~~~~~~~
      |     u_int64_t
dasynq/dasynq-stableheap.h:24:25: error: expected ')' before 'o'
   24 |     stable_prio(uint64_t o, U... u) : p(u...), order(o)
      |                ~        ^~
      |                         )
dasynq/dasynq-stableheap.h:62:5: error: 'uint64_t' does not name a type; did you mean 'u_int64_t'?
   62 |     uint64_t sequence = 0;
      |     ^~~~~~~~
      |     u_int64_t
dasynq/dasynq-stableheap.h: In member function 'bool dasynq::stable_heap<H, T, P, C>::insert(dasynq::stable_heap<H, T, P, C>::handle_t&, P)':
dasynq/dasynq-stableheap.h:71:34: error: 'sequence' was not declared in this scope
   71 |         auto sp = stable_prio<P>(sequence++, pval);
      |                                  ^~~~~~~~
dasynq/dasynq-stableheap.h: In instantiation of 'bool dasynq::compare_stable_prio<P, C>::operator()(const dasynq::stable_prio<P>&, const dasynq::stable_prio<P>&) [with P = int; C = std::less<int>]':
dasynq/dasynq-daryheap.h:165:23:   required from 'void dasynq::dary_heap<T, P, Compare, N>::bubble_up(dasynq::dary_heap<T, P, Compare, N>::hindex_t, dasynq::dary_heap<T, P, Compare, N>::handle_t&, const P&) [with T = dasynq::dprivate::empty_node; P = dasynq::stable_prio<int>; Compare = dasynq::compare_stable_prio<int, std::less<int> >; int N = 4; dasynq::dary_heap<T, P, Compare, N>::hindex_t = long unsigned int]'
dasynq/dasynq-daryheap.h:188:22:   required from 'void dasynq::dary_heap<T, P, Compare, N>::remove_h(dasynq::dary_heap<T, P, Compare, N>::hindex_t) [with T = dasynq::dprivate::empty_node; P = dasynq::stable_prio<int>; Compare = dasynq::compare_stable_prio<int, std::less<int> >; int N = 4; dasynq::dary_heap<T, P, Compare, N>::hindex_t = long unsigned int]'
dasynq/dasynq-daryheap.h:280:9:   required from 'void dasynq::dary_heap<T, P, Compare, N>::remove(dasynq::dary_heap<T, P, Compare, N>::handle_t&) [with T = dasynq::dprivate::empty_node; P = dasynq::stable_prio<int>; Compare = dasynq::compare_stable_prio<int, std::less<int> >; int N = 4]'
dasynq/dasynq-stableheap.h:112:21:   required from 'void dasynq::stable_heap<H, T, P, C>::remove(dasynq::stable_heap<H, T, P, C>::handle_t_r) [with H = dasynq::dprivate::dary_heap_def; T = dasynq::dprivate::empty_node; P = int; C = std::less<int>; dasynq::stable_heap<H, T, P, C>::handle_t_r = dasynq::dary_heap<dasynq::dprivate::empty_node, dasynq::stable_prio<int>, dasynq::compare_stable_prio<int, std::less<int> >, 4>::handle_t&]'
dasynq/dasynq.h:453:35:   required from 'void dasynq::dprivate::event_dispatch<Traits, LoopTraits>::dequeue_watcher(dasynq::dprivate::base_watcher*) [with Traits = dasynq::epoll_traits; LoopTraits = dasynq::default_traits<dasynq::null_mutex>]'
dasynq/dasynq.h:1065:34:   required from 'void dasynq::event_loop<T_Mutex, Traits>::dequeue_watcher(dasynq::event_loop<T_Mutex, Traits>::base_watcher*) [with T_Mutex = dasynq::null_mutex; Traits = dasynq::default_traits<dasynq::null_mutex>; dasynq::event_loop<T_Mutex, Traits>::base_watcher = dasynq::dprivate::base_watcher]'
dasynq/dasynq.h:1703:34:   required from 'void dasynq::dprivate::fd_watcher<T_Loop>::set_enabled(dasynq::dprivate::fd_watcher<T_Loop>::event_loop_t&, bool) [with EventLoop = dasynq::event_loop<dasynq::null_mutex>; dasynq::dprivate::fd_watcher<T_Loop>::event_loop_t = dasynq::event_loop<dasynq::null_mutex>]'
proc-service.cc:67:59:   required from here
dasynq/dasynq-stableheap.h:49:18: error: 'const class dasynq::stable_prio<int>' has no member named 'order'
   49 |         return a.order < b.order;
      |                ~~^~~~~
dasynq/dasynq-stableheap.h:49:28: error: 'const class dasynq::stable_prio<int>' has no member named 'order'
   49 |         return a.order < b.order;
      |                          ~~^~~~~
make[1]: *** [Makefile:51: proc-service.o] Error 1

[Feature Request] Enable stop-command for process and bgprocess

Rationale

Certain services, such as ejabberd, prosody (for process) and mailman (for bgprocess), require a stop command to cleanly finish before the process is terminated.

While using scripted is also possible, I want to know whether we can supervise these processes or it's a lost cause for these kind of services.

Tweak documentation/comments about `-t`/`--service` in `dinit.cc`

It needs to be revised:

dinit/src/dinit.cc

Lines 375 to 396 in a5a5e43

// If we are running as init (PID=1), the Linux kernel gives us all command line arguments it was
// given but didn't recognize, and, uh, *some* that it did recognize, which means we can't assume
// that anything is a service name (for example "nopti" seems to get passed through to init).
// However, we can look for special names that we know aren't kernel parameters, such as "single".
//
// (Note this may have been fixed in recent kernels: see changelog for 5.15.46/5.18.3,
// "x86: Fix return value of __setup handlers")
//
// LILO puts "auto" on the command line for unattended boots, but we don't care about that and want
// it filtered.
//
// We don't expect to see options beginning with '-' appear on the kernel command line either, so we
// can interpret those as dinit arguments. In particular if we see -m or -o, we assume that every
// name we see from then is a service name (i.e. process_sys_args is set false when we seem them,
// see above).
//
// (Note, you can give "--" on the kernel command line to pass every option from that point to init
// directly, but init doesn't see the "--" itself, which makes it less useful, since we still can't
// tell whether a "name" was intended as a kernel parameter or init parameter).
// So, long story short: if we think we're PID 1 and we haven't seen -m or -c options yet, only
// recognise "single" as a service name and ignore everything else.

Related: #69 & #76

stop-command memory issue

The argv for stop-command is using a string that is later moved, leaving behind an argv (from separate_args) with invalid references to the string.
This specifically happens in my case when the string is <=16 bytes and is stack allocated, apparently any use of the underlying memory would be invalid/undefined after std::move, so just making sure the string is heap allocated is not a full fix.

==6138==    at 0x4D03FD3: __execvpe_common (execvpe.c:75)
==6138==    by 0x1257E2: base_process_service::run_child_proc(run_proc_params) (run-child-proc.cc:336)
==6138==    by 0x11ECF8: base_process_service::start_ps_process(std::vector<char const*, std::allocator<char const*> > const&, bool) (baseproc-service.cc:199)
==6138==    by 0x11CB65: scripted_service::bring_down() (proc-service.cc:800)
==6138==    by 0x110C45: service_set::process_queues() (service.h:916)
==6138==    by 0x11BF6D: scripted_service::handle_exit_status(bp_sys::exit_status) (proc-service.cc:614)
==6138==    by 0x11BA47: service_child_watcher::status_change(dasynq::event_loop<dasynq::null_mutex, dasynq::default_traits<dasynq::null_mutex> >&, int, int) (proc-service.cc:238)
==6138==    by 0x11F3E4: dasynq::dprivate::child_proc_watcher_impl<dasynq::event_loop<dasynq::null_mutex, dasynq::default_traits<dasynq::null_mutex> >, service_child_watcher>::dispatch(void*) (dasynq.h:2216)
==6138==    by 0x112323: dasynq::event_loop<dasynq::null_mutex, dasynq::default_traits<dasynq::null_mutex> >::process_events(int) (dasynq.h:1463)
==6138==    by 0x112BA6: dasynq::event_loop<dasynq::null_mutex, dasynq::default_traits<dasynq::null_mutex> >::run(int) (dasynq.h:1501)
==6138==    by 0x10FE5B: dinit_main(int, char**) (dinit.cc:607)
==6138==    by 0x10E609: main (dinit-main.cc:12)
==6138==  Address 0x1ffefff8e0 is on thread 1's stack
==6138==  912 bytes below stack pointer

[Feature Request] populate $SERVICE_NAME or logdir configuration

It would be helpful to make $SERVICE_NAME or similar expand to the service name on service load (if sub-vars is set).
This could eliminate the need to retype the logfile name for each service.

alternatively it could also be quite nice to have a logdir option (or handle dirs in logfiles) by creating a logfile <service name>.log in that directory.

If that is already a thing then I did not find it yet.

external readiness notification mechanism

I wonder if it would be worthwhile to implement another mechanism for readiness notification of services. Currently we can do that from the service itself using a file descriptor passed either directly or through an environment variable. This is a simple and fairly flexible mechanism, but it cannot be applied universally.

I was thinking of possibly introducing a new mechanism that would utilize some kind of ready-command field. I'm thinking the system could simply do:

  1. If present, issue the command alongside the service's command
  2. Wait for the ready-command to exit
  3. If the exit status of it was 0, service is considered ready
  4. In case of a non-zero exit status, bring down the service

This could be adapted to lots of things that do not directly support any kind of readiness notification. In my particular case I would use this for the dbus activation support I am working on (the command would take care of waiting for the service to appear on the bus).

WDYT?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.