Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Start a rust binary as a systemd daemon

I'm playing around to find out how to run a rust binary as a systemd daemon in Ubuntu, and haven't been very successful so far.

What I'm trying to achieve:

  • Create a daemon that writes the current time to a file every three seconds.

I use the daemonize crate for this. I am new to rust and have also no experience with daemons. Maybe I'm doing some basic things wrong.

extern crate daemonize;

use chrono::{DateTime, Utc};
use daemonize::Daemonize;
use std::fs::File;
use std::io::prelude::*;
use std::{thread, time};

fn main() {
    let args = std::env::args().collect::<Vec<String>>();
    let user = &(*args[1]);
    let group = &(*args[2]);
    let file = &args[3];

    let stdout = File::create("/tmp/daemon.out").unwrap();
    let stderr = File::create("/tmp/daemon.err").unwrap();

    let sleep_time = time::Duration::from_millis(3 * 1000);

    let mut file = std::fs::OpenOptions::new()
        .append(true)
        .create(true)
        .open(file)
        .unwrap();

    let daemonize = Daemonize::new()
        .user(user)
        .group(group)
        .working_directory("/tmp") // for default behaviour.
        .stdout(stdout) // Redirect stdout to `/tmp/daemon.out`.
        .stderr(stderr); // Redirect stderr to `/tmp/daemon.err`.

    match daemonize.start() {
        Ok(()) => loop {
            let now: DateTime<Utc> = Utc::now();
            let date = format!("UTC now is: {}\n", now);
            file.write_all(date.as_bytes()).unwrap();
            thread::sleep(sleep_time);
        },
        Err(err) => file
            .write_all(format!("error: {}", err).as_bytes())
            .unwrap(),
    };
}

I found a service file on the internet and adjusted it a little ...

/etc/systemd/system/daemon-test.service

After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=julian
ExecStart=/home/julian/daemon-test/target/debug/daemon-test julian julian /home/julian/Desktop/daemon.txt

[Install]
WantedBy=multi-user.target

i tried to start the service with systemctl start daemon-test but nothing happens. When I run systemctl status daemon-test I get this message:

systemctl status daemon-test                        
● daemon-test.service
     Loaded: loaded (/etc/systemd/system/daemon-test.service; disabled; vendor preset: enabled)
     Active: failed (Result: start-limit-hit) since Sat 2020-07-25 22:53:39 CEST; 31s ago
    Process: 72620 ExecStart=/home/julian/daemon-test/target/debug/daemon-test julian julian /home/julian/Desktop/daemon.txt (code=exited, status=0/SUCCESS)
   Main PID: 72620 (code=exited, status=0/SUCCESS)

Jul 25 22:53:39 jubuntu systemd[1]: daemon-test.service: Scheduled restart job, restart counter is at 5.
Jul 25 22:53:39 jubuntu systemd[1]: Stopped daemon-test.service.
Jul 25 22:53:39 jubuntu systemd[1]: daemon-test.service: Start request repeated too quickly.
Jul 25 22:53:39 jubuntu systemd[1]: daemon-test.service: Failed with result 'start-limit-hit'.
Jul 25 22:53:39 jubuntu systemd[1]: Failed to start daemon-test.service.
Jul 25 22:54:10 jubuntu systemd[1]: /etc/systemd/system/daemon-test.service:1: Assignment outside of section. Ignoring.
Jul 25 22:54:10 jubuntu systemd[1]: /etc/systemd/system/daemon-test.service:2: Assignment outside of section. Ignoring.

like image 522
jules Avatar asked Apr 15 '26 11:04

jules


1 Answers

Type=simple is for "new style daemons", you should not do the double fork daemonization dance with those, systemd takes care of it. See https://www.freedesktop.org/software/systemd/man/daemon.html

like image 163
janneb Avatar answered Apr 18 '26 04:04

janneb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!