61

I am setting up quota on my Linode server running Ubuntu 16.10, and I get the following error

Cannot stat() mounted device /dev/root: No such file or directory

So to fix this, I reached this thread for the fix which is done by adding

ln -s /dev/xvda /dev/root
/etc/init.d/quota restart

to the /etc/rc.local. But Ubuntu 16.10 doesn't uses rc.local anymore instead uses systemd. What is the alternative for rc.local, How can I run the above commands on startup?

Also I enabled the service using systemctl enable rc-local.service but it didn't work for me. Any lead would be appreciated.

10
  • di you run it as root, and did you restart your system? Commented Feb 23, 2017 at 19:00
  • @George yes, I did both Commented Feb 23, 2017 at 19:01
  • try this Commented Feb 23, 2017 at 19:08
  • @George That's not working as well Commented Feb 23, 2017 at 19:27
  • Just saw this hack, see if it flies... Commented Feb 23, 2017 at 19:32

3 Answers 3

78

Intro

I think you should not create a new service as suggested in the link by George. The rc-local.service already exists in systemd and the service file suggests that the rc.local, if it exists and is executable, gets pulled automatically into multi-user.target. So no need to recreate or force something that is just done in another way by the systemd-rc-local-generator.

One solution

A quick solution (I don't know if that's the canonical way):

In a terminal do:

printf '%s\n' '#!/bin/bash' 'exit 0' | sudo tee -a /etc/rc.local
sudo chmod +x /etc/rc.local
sudo reboot

After that the rc.local will be called upon system startup. Insert what you like.

Background

If you do in a terminal:

sudo systemctl edit --full rc-local

You can see that the head comment contains lines such as:

# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.

This indicates, that in this system, if there is a file called /etc/rc.local which is executable, then it will be pulled into multi-user.target automatically. So you just create the according file (sudo touch...) and make it executable (sudo chmod +x ...).

3
  • 4
    Don't use #!/bin/bash though, use #!/bin/sh unless you really need bash in your script. All other system scripts use dash, not bash, for performance reasons.
    – spikyjt
    Commented Oct 25, 2018 at 14:16
  • "no need to recreate or force something that is just done in another way by the systemd-rc-local-generator" rc-local doesn't allow to order it after some other unit, is it not?
    – x-yuri
    Commented Mar 16, 2019 at 14:45
  • Must exit 0 be listed as last command in /etc/rc.local ?
    – W.M.
    Commented Nov 26, 2021 at 15:40
24

I saw this solution suggested which involves use of systemd here:

  1. Create a service:

    sudo vi /etc/systemd/system/rc-local.service
    
  2. Add your code there:

    [Unit]
    Description=/etc/rc.local Compatibility
    ConditionPathExists=/etc/rc.local
    
    [Service]
    Type=forking
    ExecStart=/etc/rc.local start
    TimeoutSec=0
    StandardOutput=tty
    RemainAfterExit=yes
    SysVStartPriority=99
    
    [Install]
    WantedBy=multi-user.target
    
  3. Create and make sure /etc/rc.local is executable and add this code inside it:

    sudo chmod +x /etc/rc.local

    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    # Make sure that the script will "exit 0" on success or any other
    # value on error.
    #
    # In order to enable or disable this script just change the execution
    # bits.
    #
    # By default this script does nothing.
    
    exit 0
    
  4. Enable the service:

    sudo systemctl enable rc-local
    
  5. Start service and check status:

    sudo systemctl start rc-local.service
    sudo systemctl status rc-local.service
    
  6. If all goes well you can add your code to the /etc/rc.local file then restart it.

Note: Tested on Lubuntu 16.10.

Source:

https://www.linuxbabe.com/linux-server/how-to-enable-etcrc-local-with-systemd

3
  • I did all the steps. I have the rc.local with: touch "hello" before the exit 0. The service seems to be active but it does not create any file in the /etc/ dir Running on ubuntu 16.04 Arabian 5.31 Commented Oct 13, 2017 at 18:40
  • 1
    As the the answer by @Jan points out, creating a whole new service is not necessary as systemd supports rc.local already. Commented Jun 4, 2018 at 6:29
  • Thank youuuuuuuuuuuuuuuuuuuu, this just works
    – GPrathap
    Commented May 30, 2019 at 20:37
7

To add to Jan's answer that, unlike the usual rc.localfile, rc-local service is executed not after all services have been started, but after the network goes online.

In some cases you may want to run commands from rc.local later. For example, I wanted it to be executed after lxd start.

In this case you can edit rc-local service startup dependencies by creating a drop-in conf file: /etc/systemd/system/rc-local.service.d/override.conf with contents:

[Unit]
After=network.target lxd.service

Where you can add a needed unit name (like I added lxd.service)

Do not forget to systemctl daemon-reload after that.

1
  • Welcome to Ask Ubuntu! If you want to improve another answer please suggest an edit to it. If you want present a partial alternative please repeat or quote the parts that are the same (in case the original answer changes) and highlight the differences. In any case don’t create a new incomplete answer! Thank you. Commented Jun 19, 2018 at 16:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .