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.

  • di you run it as root, and did you restart your system? – George Udosen Feb 23 '17 at 19:00
  • @George yes, I did both – Saurabh Sharma Feb 23 '17 at 19:01
  • try this – George Udosen Feb 23 '17 at 19:08
  • @George That's not working as well – Saurabh Sharma Feb 23 '17 at 19:27
  • Just saw this hack, see if it flies... – George Udosen Feb 23 '17 at 19:32
up vote 42 down vote accepted

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 workaround (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 want.

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 ...).

  • 1
    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 Oct 25 at 14:16

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

  • 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 – Danny182 Oct 13 '17 at 18:40
  • As the the answer by @Jan points out, creating a whole new service is not necessary as systemd supports rc.local already. – TommyPeanuts Jun 4 at 6:29

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.

  • 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. – David Foerster Jun 19 at 16:05

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.