1

In Ubuntu 18.04 I lost the ability to automatically mount network shares from fstab on startup. Every time I start my computer I have to manually mount all shares with sudo mount -a... I have already tried to include a @reboot mount -a on crontab but it does not work... It happened to me with Ubuntu MATE 18.04 and Kubuntu 18.04 so it seems to be a Core Ubuntu problem and not a desktop issue...

Cheers Bruno

  • If you haven't resolved this, please [edit] your question and add the complete listing of your fstab file. This problem is almost certainly fixable. – Organic Marble Dec 23 '18 at 15:14

3 Answers3

1

I tried these options to solve the same problem on Ubuntu 18.04LTS:

  • Insert "comment=systemd.automount" into the relevant mount statements in /etc/fstab. PROBLEM: This option produced multiple mounts of the same network shares when I tried to use it for two different network shares.
  • Insert "mount -a" into /etc/rc.local. PROBLEM:This seemed to have no effect! As superuser, create a script with the following text in directory /etc/network/if-up.d/ and give it execute permissions:
  • As superuser, create a script with the following text in directory /etc/network/if-up.d/ and give it execute permissions:

#!/bin/sh mount -a

PROBLEM SOLVED! The last solution works well. Scripts located in /etc/network/if-up.d/ run after a network connection is established. This script then mounts the network shares (and any other pending mounts) already stipulated in /etc/fstab.

django
  • 183
  • 2
  • 8
0

I have had the same issue, and tried using autofs and startup commands, and others, with unsatisfactory results. I finally solved it by writing my own script that I add as an Autostart script. This script requires python and that the user has sudo privileges (without a password) for at least the mount command.

Here is the Python script (main.py):

"""
Code to do a user level mounts/unmounts

Usage:
    python3 main.py mount|unmount

The mounts list contains the information needed to perform the mount and unmount.
These mounts should not appear in the /etc/fstab file.
each element of the mounts list is itself a list in the format:
    [device, mount_dir, mount_options, ...]
where `device` is the device to be mounted such as '//192.168.1.3/Public'
      'mount_dir' is the mount point
      'mount_options' is the options to be used by the mount command.
            Each option must be an element itself.
            for example: '-t', 'cifs', '-o', 'rw,users,noperm,guest,soft,cache=none,sec=none'
Edit the `mounts` list to your needs.

The mount command issued will be 'sudo mount <mount_options> <device> <mount_dir>`.
The unmount command will be `sudo umount <mount_dir>`.
This requires that the user be in the `sudoers` group with the
"NOPASSWD" argument, for example:
    jra ALL=(ALL) NOPASSWD: ALL
gives user `jra` the ability to use the `sudo` command without ever
providing a password. (This can be modified to limit
the commands allowed without a password).

Upon start of this script, attempts will be made to mount each element
in the mounts list.
Failed mounts are added to the `waiting_mounts` list, and mounts for
those failures are retried after delays specified in 'SLEEP_SECONDS' list.

Unmounting is performed by the OS, normally not by this script.

A log directory `.simpleAutomount` is created in the users home directory.

"""

import subprocess
import time
import sys
from datetime import datetime
import os.path
import shutil

# this is the list of mounts to be performed (list of lists)
mounts=[
        ['//192.168.1.3/Public', '/mnt/mybook', '-t', 'cifs', '-o', 'rw,_netdev,users,noperm,guest,soft,cache=none,sec=none,vers=1.0' ],
#        ['/dev/sda4', '/windows', '-t', 'ntfs']
    ]

SLEEP_SECONDS = [5, 5, 5, 10, 20, 100, 100]  # number of seconds to sleep between successive mount attempts
MAX_TRIES = len(SLEEP_SECONDS)
waiting_mounts = []


def ping(host):
    """
    ping the specified host and return the exit value of the ping

    success == 0 means success
    success == 1 means no reply received
    success == 2 means no network available
    """
    cmd = ['ping', host, '-c 1']
    success = subprocess.call(cmd, stdout=subprocess.PIPE)
    return success


def process_mount(mnt):
    """
    attempt to perform one mount as indicated in the mnt list

    :param mnt: one element from the mounts list (which is a list in itself)
    :return: True if the mount was successful (or the mount should not be attempted again). False if the mount should be tried again later
    """
    host = None
    if mnt[0].startswith('//'):          # format is //host/directory
        index = mnt[0].index('/', 2)
        host = mnt[0][2:index]
    elif ':' in mnt[0]:                  # format is host:directory
        index = mnt[0].index(':')
        host = mnt[0][:index]
    mnt_cmd = ['sudo', 'mount']
    mnt_cmd.extend(mnt[2:])
    mnt_cmd.extend(mnt[0:2])
    if host is None:        # this is not a network mount, do not need to ping
        logFile.write('running ' + str(mnt_cmd) + '\n')
        logFile.flush()
        returnCode = subprocess.call(mnt_cmd)
        logFile.write('\t' + str(mnt_cmd) + ' finished with return code: ' + str(returnCode) + '\n')
        logFile.flush()
        return True
    elif ping(host) == 0:
        logFile.write('running ' + str(mnt_cmd) + '\n')
        logFile.flush()
        returnCode = subprocess.call(mnt_cmd)
        logFile.write('\t' + str(mnt_cmd) + ' finished with return code: ' + str(returnCode) + '\n')
        logFile.flush()
        return True
    else:
        return False


def usage(unrecognized_opt=None):
    if unrecognized_opt is not None:
        print('Unrecognized option: ' + str(unrecognized_opt) + '\n')
        logFile.write('Unrecognized option: ' + str(unrecognized_opt) + '\n')
    print('usage:\n\tpython3 ' + sys.argv[0] + ' mount|unmount\n')
    logFile.write('usage:\n\tpython3 ' + sys.argv[0] + ' mount|unmount\n')
    logFile.flush()


if __name__ == '__main__':
    """
    The starting point for the SimpleAutomount script

    Legal arguments are 'mount' or 'unmount'
    'mount' will inspect each element of the mounts list and attempt the mounts
    'unmount' will attempt to unmount each element of the mount list
    """
    if len(sys.argv) != 2:
        usage()
        sys.exit(1)

    theDate = datetime.now()

    # create a log file in the users ~/.simpleAutomount directory
    home = os.path.expanduser("~")
    sam = os.path.join(home, '.simpleAutomount')
    if not os.path.exists(sam):
        os.mkdir(sam, 0o755)
    logFileName = os.path.join(sam, "simpleAutomount.log")
    logFile = open(logFileName, 'a')

    # start logging
    logFile.write('\n\nSimpleAutomount started at ' + str(theDate) + ' with arg: ' + sys.argv[1] + '\n')
    logFile.flush()

    if sys.argv[1].lower() == 'mount':    # do mount
        os.spawnlp(os.P_NOWAIT, sys.executable, sys.executable, sys.argv[0], 'forked_mount') # fork so that systemd does not wait and delay login
        sys.exit(0) # indicate success
    elif sys.argv[1].lower() == 'forked_mount':  # we are forked, so we can take our time here
        for mnt in mounts:
            if not process_mount(mnt):  # the mount was not successful and should be tried again later
                logFile.write('appending ' + mnt[0] + ' to waiting mounts\n')
                logFile.flush()
                waiting_mounts.append((mnt))    # add this mount to the waiting_mounts list to be tried again later

        # if any mounts were unsuccessful and should be tried again, loop to try mounting again
        try_count = 0
        while len(waiting_mounts) > 0 and try_count < MAX_TRIES:
            logFile.write('sleeping for ' + str(SLEEP_SECONDS[try_count]) + ' seconds\n')
            logFile.flush()
            time.sleep(SLEEP_SECONDS[try_count])

            # process waiting_mounts, starting at the end for ease of deletion
            indx = len(waiting_mounts) - 1
            for i in range(indx, -1, -1):
                mnt = waiting_mounts[i]
                logFile.write('Attempting to mount ' + mnt[0] + ' for try number ' + str(try_count) + '\n')
                logFile.flush()
                # try this mount again
                if process_mount(mnt):
                    del waiting_mounts[i]    # mount was successful, so remove this entry from waiting mounts
            try_count += 1
        logFile.write('SimpleAutomount exiting with ' + str(len(waiting_mounts)) + ' remaining unmounted\n')
    elif sys.argv[1].lower() == 'unmount':    # do unmount
        for mnt in mounts:
            cmd = ['sudo', 'umount', mnt[1]]
            #journal.send('running ' + str(cmd), SYSLOG_IDENTIFIER='simple_automount', SYSLOG_PID=str(os.getpid()))
            logFile.write('running ' + str(cmd) + '\n')
            logFile.flush()
            returnCode = subprocess.call(cmd)
            logFile.write('\t' + str(cmd) + ' finished with return code: ' + str(returnCode) + '\n')
            logFile.flush()
        sys.exit(0)
    else:
        usage(unrecognized_opt=sys.argv[1])
        sys.exit(1)
  • 1
    Thanks a lot for the answer but this does not seem a good solution for me. Sometimes I just turn on the computer and do not login. On Ubuntu 17.10 this was done automatically on the background, so something broke on 18.04. I wanted to get back the behaviour ubuntu had previously. One thing would help would be someone pointing me out where can I report this bug so that it gets fixed. – Bruno René Santos Jun 30 '18 at 13:26
0

In Ubuntu 18.04 the hard disk assignments have changed. The /dev/sda3 device which I used in Ubuntu 16.04 has moved to /dev/sde3 in Ubuntu 18.04.

Before I changed the fstab entry, the booting stops with a severe error.

After I found the right device assignments, the system continued booting and mounts all partitions I assigned in fstab.

To get the possible assignments try the command:

sudo fdisk -l

Best regards