Contents
Why?
If you already have LibreELEC with big disk connected to it, maybe even RAID1 (mirror) which is really good for storing backups in safer way, then it could be a good idea to make LibreELEC works as cheap alternative to Apple Time Capsule.
Prerequisites
Install entware-ng (optware-like with opkg
package manager) on your LibreELEC device firstly. Follow this article: https://www.artembutusov.com/libreelec-entware-ng-installation/
Installation
Install netatalk
Please note, this manual is for netatalk v3.x, there is a difference in configuration between v2.x and v3.x. See here for more details: http://netatalk.sourceforge.net/3.1/htmldocs/upgrade.html
Connect over SSH.
opkg install netatalk
Configure netatalk
Create folder for Time Machine backups:
mkdir -p "/storage/mirror/Time Machine"
Make sure that storage path is accessible for user who will access it, for anonymous access you will need to give “rwx” for all for target directory and all parents should also have “x” for all.
nano /opt/etc/afp.conf
- uam list (authentication engine)
- vol size limit (volume size in MiB) – allowed volume size (usefull to limit max backup size)
- ea (extended attributes) – set to “none” if you don’t really care about attributes
Example with anonymous access:
[Global]
uam list = uams_guest.so
[Time Machine]
time machine = yes
path = /storage/mirror/Time Machine
vol size limit = 1048576
ea = none
[Mirror]
path = /storage/mirror
ea = none
Let anonymous (nobody) read afp.conf:
chmod 644 /opt/etc/afp.conf
Create systemd service units
Create service unit for afpd:
nano /storage/.config/system.d/netatalk.service
Please note, I set storage-mirror.mount
in After
to make sure that netatalk will start after my RAID1 will be mounted to /storage/mirror
.
[Unit]
Requires=network-online.service
After=avahi-daemon.service storage-mirror.mount
[Service]
Type=oneshot
ExecStart=/opt/etc/init.d/S27afpd start
ExecStop=/opt/etc/init.d/S27afpd stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Enable netatalk on reboot and start service:
systemctl enable netatalk
systemctl start netatalk
Create service unit for cnid_metad:
nano /storage/.config/system.d/netatalk-cnid_metad.service
[Unit]
Requires=network-online.service
After=netatalk.service
[Service]
Type=oneshot
ExecStart=/opt/etc/init.d/S26cnid_metad start
ExecStop=/opt/etc/init.d/S26cnid_metad stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Enable cnid_metad on reboot and start service:
systemctl enable netatalk-cnid_metad
systemctl start netatalk-cnid_metad
Fix avahi configuration
Avahi daemon is used for auto discovery. Properly configured Samba and AFP shares will be available for mounting directly from OS X Finder.
There is only one problem. Both Samba and AFP shares could not work together on device with the same name. At least it doesn’t work well for me.
Here is a workaround: show AFP and Samba shares under different device name. In that case you will be able to mount both types of shares and auto discovery will still work for them.
There is one small problem actually. We need to edit avahi configuration, which is located in /etc
on read only root.
We could either modify LibreELEC image OR we could use overlay fs to overlay etc. I found that second solution is easier.
Overlay /etc
Create folders for overlay fs:
mkdir -p /storage/modroot/etc /storage/modroot/.work
Create new systemd mount unit:
nano /storage/.config/system.d/etc.mount
with content:
[Unit]
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
[Mount]
What=overlay-etc
Where=/etc
Type=overlay
Options=lowerdir=/etc,upperdir=/storage/modroot/etc,workdir=/storage/modroot/.work
[Install]
WantedBy=local-fs.target
Enable and start /etc
overlay mount:
systemctl enable etc.mount
systemctl start etc.mount
Now you should be able to create new files in /etc
.
Create AFP avahi service
Create new file:
nano /etc/avahi/services/netatalk.service
with content:
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">AFP on %h</name>
<service>
<type>_afpovertcp._tcp</type>
<port>548</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=Xserve</txt-record>
</service>
</service-group>
Create Samba avahi service
Create new file:
nano /etc/avahi/services/smb.service
with content:
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">SMB on %h</name>
<service>
<type>_smb._tcp</type>
<port>445</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=Xserve</txt-record>
</service>
</service-group>
Notes:
model=Xserve
will impact on device icon in OS X Finder.
Restart avahi
Restart avahi:
systemctl restart avahi-daemon
Once you will restart avahi OS X Finder should show new devices and their shares.
Fix OS X configuration
By default OS X will not show our AFP shares as available for Time Machine backup but we could fix that.
Run in terminal on OS X:
defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
Usage
With this setup you should be able to see separate device in Finder for Samba and AFP shares. AFP device should have two mount points: Mirror and Time Machine. “Mirror” could be used for regular data and “Time Machine” should be available as backup target volume in OS X Time Machine backup tool.
You need to mount “Time Machine” volume first before it will become available in Time Machine as target backup disk.
In this setup “Time Machine” has no authentication and should be mounted with “Guest” account.
We could setup authorization but it will require modification of /etc/passwd
. It is doable but will require more effort.
NOTE: Backing up to network device could be significantly slower due to slower IO over network and due to the fact that network backups are using sparse bundle drive images as container, which is slower than backing up directly to attached physical disk.
Extra documentation
- AFP configuration: http://netatalk.sourceforge.net/3.1/htmldocs/afp.conf.5.html
- Netatalk as Time Machine backup target: https://kremalicious.com/ubuntu-as-mac-file-server-and-time-machine-volume/
- Make Time Machine backups faster: http://endlessgeek.com/2014/03/improve-time-machine-performance-big-bands
- Migration of Time Machine backups: https://apple.stackexchange.com/questions/104277/how-do-i-move-a-usb-time-machine-backup-to-a-time-capsule
EXTRA: Samba instead of AFP
This article uses AFP as recommendation but these days Samba is better, faster and fully supported by macOS.
Example samba config:
[global]
map to guest = Bad User
# enable logging
log file = /var/log/samba/%m
log level = 1
# disable old netbios protocol
disable netbios = yes
smb ports = 445
# more mac optiomizations
# https://wiki.samba.org/index.php/Configure_Samba_to_Work_Better_with_Mac_OS_X
min protocol = SMB2
ea support = yes
vfs objects = catia fruit streams_xattr
delete veto files = true
fruit:metadata = stream
fruit:model = MacSamba
fruit:veto_appledouble = yes
fruit:posix_rename = yes
fruit:zero_file_id = yes
fruit:wipe_intentionally_left_blank_rfork = yes
fruit:delete_empty_adfiles = yes
[media]
path = /media
read only = no
guest ok = yes
guest only = yes
[TimeMachineBackup]
path = /media/Disk1/TimeMachineBackup
read only = no
guest ok = yes
guest only = yes
vfs objects = catia fruit streams_xattr
fruit:time machine = yes
# limit size if needed
#fruit:time machine max size = SIZE
Avahi config:
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_smb._tcp</type>
<port>445</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=Xserve</txt-record>
</service>
</service-group>
I tested these settings on Arch Linux but they should also work on LibreELEC.
Hello Artem!
Would it make sense to add network-online.service not only to Requires= but also to After= in netatalk*.service files?
Thank you for your instructions! I am even trying to push /opt to LE:
https://forum.libreelec.tv/thread/12768-could-we-please-have-opt-in-system/
But no luck 🙁
It worked for me as it is. But here you could read more about difference between Requires and After in systemd scripts: https://serverfault.com/questions/812584/in-systemd-whats-the-difference-between-after-and-requires
Yes I read that. And my favourite is: “It is a common pattern to include a unit name in both the After= and Requires= option, in which case the unit listed will be started before the unit that is configured with these options”
The point is that for me netatalk-cnid_metad started before network-online which caused it the former to fail (saw in the logs) since the network was not up yet.
Another bit of useful information. One could edit SYSTEM by booting LE server from some linux live USB. Fedora live usb (28) is not really good – it does not have mksplashfs. Ubuntu (18.04) is better – it has mksplashfs by default.
Hello again Artem.
Did you try you instruction on the new libreelec 9.0.0? I am getting this in the log of (failed!) etc.mount service:
LibreELEC mount[177]: mount: mounting overlay-etc on /etc failed: No such device
But even if I start it manually and bounce avahi-daemon, still cannot see libreelec in Finder…
No, did not try yet on LibreELEC 9.x
Thank you for the quick reply. I will be looking forward for the updates. Something changed with 9.x…
For the record, 9.0.1 did not change anything. Still etc.mount service fails at the system startup and has to be started manually from ssh (with avahi-daemon restart afterwards)
9.0.2 – still the same, etc.mount fails at reboot but works ok from ssh “systemctl start etc.mount”
Hi Artem! Tell me please how do I preserve changes to etc between reboots ? It’s mounting /storage/modroot/etc but files in etc are not changed 🙁
Ahhh my problem is same like @Sergey Udaltsov… All clear now 😉
Same issue with 9.2.0. Artem, any updates?
The fact that manually executed etc.mount works after boot indicates that during boot it executes to early to complete. I guess it is related to order of units. Looks like in 8.x and 9.x this etc.mount unit should wait for one of other units. You could take a look on all active units and experiment which one defined as dependency can fix the issue. Unfortunately, I don’t have 8.x or 9.x installed so can’t do that on my own but would appreciate if you can post here what fixes are needed if you will find a solution.
I was trying to play with etc.mount file, could not find any params that would put it later in the boot sequence. Any hints would be appreciated…
etc.mount that worked for me:
DefaultDependencies=no
Conflicts=umount.target
Requires=storage.mount tmp.mount
After=storage.mount tmp.mount
[Mount]
What=overlay-etc
Where=/etc
Type=overlay
Options=lowerdir=/etc,upperdir=/storage/modroot/etc,workdir=/storage/modroot/.work
[Install]
WantedBy=netatalk.service
Actually WantedBy=local-fs.target is ok. The critical lines are those in [Unit] section:
Requires=storage.mount tmp.mount
After=storage.mount tmp.mount
So you got it working, right?
Right. With those 2 lines added to [Unit] section