Have you seen this error when mounting a CIFS share on boot?
mount error: could not resolve address for [cifs share address]: Unknown error
Boy, do I have blog post for you.
Having performance issues with WebDav mount I’ve been using so far I tried to switch to CIFS.
The share would mount without an issue when done by hand or using a
mount -a option from the terminal. It would however fail with previously mentioned resolve error on boot.
I didn’t like common ‘solution’ found over the Internet to ‘just use an IP address’. I don’t control the CIFS server, and it could change the IP at any time resulting in unexpected failures.
1 - wait for network
See, when system mounts a CIFS share via /etc/fstab or systemd
\*.mount files it does not care for your network unless you tell it to. That’s step one.
In general adding a
\_netdev option in fstab or an
After=network-online.target in the systemd unit file should do the job.
It doesn’t always do though. Mount has very short timeouts (by default at least), and doesn’t retry on failure.
2 - wait for the proper network
In my case, network being up is not enough to reach DNS. The management (and DNS) network starts up with a service called
zerotier-one.service which setups a virtual adapter.
With systemd it’s trivial:
[Unit] After=zerotier-one.service [...]
With /etc/fstab one can use a x-systemd.after= option:
[...],_netdev,x-systemd.after=zerotier-one.service 0 0
This still didn’t work for me - turns out it takes a short while for zerotier daemon to actually connect to the network after declaring the service started. It was enough for the mount to determine it can’t reach the DNS server and fail.
At this point I decided this can’t be done with fstab - I need to use systemd or scripts in /etc/rc.local (which defeats the purpose )
2.5 - use a timer
ExectStartPre is not an option for [Mount] sections, so this common suggestion wont work here.
[Mount] ExecStartPre=/bin/sleep 30
The alternative is to use a
.timer systemd unit with the same name as our mount, and enable that instead.
This solution should work, I haven’t tried it however, as I find crude sleep commands inelegant and still error-prone with little debug information provided.
3 - make sure DNS is up
The final solution I came up with also employs an additional systemd unit, but this time of type
oneshot to check on boot if DNS is up by trying a DNS lookup in a loop until success. This has an additional benefit of delaying the start of a service in case of an external DNS failure without the need of manual service restart. Create this file as
/etc/systemd/system/dns-check.service and enable the unit.
[Unit] Description=check if DNS is up before proceeding After=network-online.target [Service] Type=oneshot ExecStartPre=/bin/bash -c 'until host [storage box username].your-storagebox.de; do sleep 1; done' ExecStart=/bin/bash -c 'echo "DNS up!"' [Install] WantedBy=multi-user.target ```<!--` syntax highlighting fix--> Next, make the mount unit start after `dns-check`: <!--` syntax highlighting fix--> ``` bash [Unit] Description=cifs mount Nextcloud data Requires=dns-check.service After=dns-check.service [Mount] What=//[storage box username].your-storagebox.de/[folder] Where=[mount point path] Options=iocharset=utf8,rw,credentials=/etc/[cifs credentials].txt,uid=apache,gid=apache,_netdev,file_mode=0660,dir_mode=0770,vers=3.0 Type=cifs [Install] WantedBy=multi-user.target ```<!--` syntax highlighting fix--> Optionally overrde the httpd (apache) systemd unit file and make the unit wait until mount is finished so Nextcloud wont try to access it's data folder until it's there.
cp /usr/lib/systemd/system/httpd.service /etc/systemd/system/
``` bash [Unit] Description=The Apache HTTP Server After=network.target remote-fs.target nss-lookup.target mnt-data.mount Depends=mnt-data-nc_mkwlab_eu.mount [...]
That’s it, no more mount errors on boot.
While my case is specific to using ZeroTier, I think it’d apply to any late DNS coming up late after network-online.target is reached by systemd.