This is a detailed step by step to properly setup miniDLNA in a jail, patch the sources with custom icons, setup the media libraries and properly setup a service daemon script with a non destructive rescan
Enjoy
Enjoy
Code:
# *************************************************************
# Requirements on TrueNAS main system:
# *************************************************************
# First, I assume the media library to stream is in TrueNAS main system under below datasets:
# - /mnt/my_media/tank/family
# - /mnt/my_media/tank/movies
# - /mnt/my_media/tank/children
# - /mnt/data/tank/shared
# Note: the media datasets can be either unix or windows SMB shares
# In TrueNAS main system, we have created a dedicated user "minidlna" UID 1008, member of a group "smb_dlna" GID 1019
# Note: choose the UID/GID that you like, but later, we will need to create the same user/group IDs in the jail
# The group "smb_dlna" has read only permissions on each of the above media datasets under "/mnt/my_media/tank/"
# For easier maintenance, I advise storing the minidlna catalog database and log files in a dataset outside of the jail directories
# That way, when the jail is destroyed, the database catalog doesn't need to be rebuilt which is a time and resource consuming operation
# I assume a UNIX type dataset under main TrueNAS system "/mnt/data/tank/common"
# In TrueNAS GUI, create a user "dlna" UID 933, member of group "dlna" GID 933
# Note: you must use the 933 IDs, because these are the IDs created by default when installing minidlna
# We can also use teh same minidlna user created previously, but I prefer distinct users for teh lib access and running the daemon
# It is the user running the minidlna daemon
# In shell, we create the database and log directories for minidlna
root@truenas:~ #
mkdir -p /mnt/data/tank/common/minidlna/db
chown dlna:dlna /mnt/data/tank/common/minidlna/db
chmod 755 /mnt/data/tank/common/minidlna/db
# The log directory can be set to root:wheel
mkdir -p /mnt/data/tank/common/minidlna/log
chown root:wheel /mnt/data/tank/common/minidlna/log
chmod 755 /mnt/data/tank/common/minidlna/log
# *************************************************************
# First step: Setup a jail named "streaming":
# *************************************************************
# - Create a jail in TrueNAS GUI
# - Assign the network and IP on the subnet where your receiving devices reside
# Note: DLNA multicast traffic is limited to teh same subnet/VLAN, so the jail and media clients must be on teh same subnet
# Add the jail mount point for the database and logs
rw /mnt/data/tank/common -> /mnt/data/iocage/jails/streaming/root/mnt/common
# Add the jail mount point for the media library
# Note: the media directories will be mounted under /media in jail
ro /mnt/data/tank/family -> /mnt/data/iocage/jails/streaming/root/media/family
ro /mnt/my_media/tank/movies -> /mnt/data/iocage/jails/streaming/root/media/movies
ro /mnt/my_media/tank/shared -> /mnt/data/iocage/jails/streaming/root/media/shared
ro /mnt/my_media/tank/children -> /mnt/data/iocage/jails/streaming/root/media/children
# fstab result:
root@truenas:~ #
cat /mnt/data/iocage/jails/streaming/fstab
/mnt/data/tank/common /mnt/data/iocage/jails/streaming/root/mnt/common nullfs rw 0 0
/mnt/data/tank/family /mnt/data/iocage/jails/streaming/root/media/family nullfs ro 0 0
/mnt/my_media/tank/movies /mnt/data/iocage/jails/streaming/root/media/movies nullfs ro 0 0
/mnt/my_media/tank/shared /mnt/data/iocage/jails/streaming/root/media/shared nullfs ro 0 0
/mnt/my_media/tank/children /mnt/data/iocage/jails/streaming/root/media/children nullfs ro 0 0
# *************************************************************
# Jail: Add user/group permissions for the minidlna service
# *************************************************************
# In teh jail, we will add the group and user that will access the libraries
# Note: as stated above, this is not necessarily the same user running the mindlnad daemon
# - shell into the jail
root@truenas:~ #
iocage console streaming
# - notes about setting up the group and user
# + username must exist on both host and jail
# + username must have read rights on the media library IN THE HOST, either explicitely, or through a group membership (primary or auxiliary)
# + username must be added to the jail, with THE SAME UID as in the host
# + if username does not have an explicit read access to the media library on the host, but rather through a group membership:
# then, the group with read access must also be added on the jail, with the same gid as in the host
#
# NOTE: we can start minidlnad daemon as root and it will no more need the username setup in minidlna.conf or any host permissions
# However, I do not recommend this for security reasons
#
# - create group "smb_dlna" with gid 1019 : it must exist on TrueNAS host AND have read access to each share we want to stream
root@streaming:~ #
pw groupadd smb_dlna -g 1019
# - create user "minidlna" uid 1008 : it must exist on TrueNAS host.
# If user minidlna has no explicit read access in the host, the group "smb_dlna" must be either his primary or auxiliary group in the host
# In the jail, we must make "smb_dlna" the PRIMARY group of user "minidlna"
pw useradd minidlna -d /nonexistent -s /usr/sbin/nologin -u 1008 -g 1019 -c "MiniDLNA"
# *************************************************************
# Install minidlna using pkg install
# *************************************************************
# This is the recommended first step because it installs latest version with all dependencies
# Note: we cannot patch the source to use custom icons in this method, so we do it later in next section
#
root@streaming:~ #
pkg update
pkg install minidlna
# [Optional] Force update with patched version having a TrueNAS icon instead of the FreeBSD ugly bad guy icon !
# - copy my patched pkg file to the jail under for example /mnt/common
root@streaming:/mnt/common #
pkg add -f minidlna-1.3.0_2,1-custom-icon.pkg
# *************************************************************
# [Optional] Compile minidlna from FreeBSD ports collection
# *************************************************************
# If you want to compile yourself the patched minidlna pkg with a custom icon, follow this section, else skip it
# We will use this method to create a custom binary pkg from ports collection source files
# We will patch the ports collection sources to use a custom icon
# Then, we will create a binary pkg from these patched latest sources
# The created binary pkg can be used to update the currently installed minidlna version
# Also, use this method if the ports collection has a newer version than pkg install
# Download/Update the ports collection
# - If it is the first time or we deleted the collections to spare space:
root@streaming:~ #
portsnap fetch && portsnap extract && portsnap update
# - If it is already extracted and not removed, just update the collection:
portsnap fetch update
# Download and extract the minidlna latest port source files
cd /usr/ports/net/minidlna/
root@streaming:/usr/ports/net/minidlna #
make clean # if we previously installed without cleaning
make patch BATCH=yes
# Note: make patch will run automatically the below 3 commands:
make fetch # fetches the distfile tarball
make extract # extracts the distfile into the work directory
make patch # applies any specific FreeBSD patches
# The port source files should be now located under "/usr/ports/net/minidlna/work/minidlna-4f6a473/"
# Note: replace minidlna-4f6a473 directory with current version name
# Edit source files to support custom icons:
# - get the patched icons.c and icons_custom.c files from my git: https://github.com/PhilZ-cwm6/minidlna-bsd
# - copy teh patched files to /mnt/common in jail
# - we replace the modded icons.c and icons_custom.c files
cp /mnt/common/icons.c /mnt/common/icons_custom.c /usr/ports/net/minidlna/work/minidlna-4f6a473/
# - [OPTIONAL]: edit the icons_custom.c file if you want to select different custom icons
# Just uncomment only one line and comment the others. MINIDLNA_COL is for a default coloured minidlna icon
# As is, teh patched files will use a TrueNAS icon
#define TRUENAS
/* #define FREENAS */
/* #define FREENAS_3D */
/* #define MINIDLNA_COL */
# - [OPTIONAL]: edit the icons.c file to revert to default FreeBSD icon
/* #define USE_CUSTOM_ICON true */
# Compile and install the patched minidlna port:
# - to update an existing install:
root@streaming:/usr/ports/net/minidlna #
make reinstall BATCH=yes
# - to install for first time:
root@streaming:/usr/ports/net/minidlna #
make install BATCH=yes
# Create a pkg file for offline install on other jails
# - this creates a pkg binary file from our patched ports collection source with custom icons
root@streaming:/usr/ports/net/minidlna #
make package
# --> /usr/ports/net/minidlna/work/pkg/minidlna-1.3.0_2,1.pkg
# Copy the created patched "minidlna-1.3.0_2,1.pkg" file to the streaming jail
# [OPTIONAL] Remove and cleanup the ports files if needed
root@streaming:/usr/ports/net/minidlna #
make clean
rm -v /var/db/portsnap/tag
rm -rvf /var/db/portsnap/files
rm -rvf /usr/ports/*
# Now, update minidlna installation in streaming jail with the patched package
# Note: we should already have did "pkg install minidlna" like above to install stock version with dependencies
# -f: to force update existing package of same version
root@streaming:~ #
pkg add -f minidlna-1.3.0_2,1.pkg
# *************************************************************
# Setup minidlna config and service to auto start with jail
# *************************************************************
# Ensure that "dlna" user and group were added by installer
# User "dlna" is the user running the minidlnad service. Database files need to be writable by the dlna user
# It is not the same user we setup under minidlna.conf that is used to access the media libraries
#
# - user:group dlna:dlna (933:933) should be created by minidlna installer
root@streaming:~ #
cat /etc/passwd | grep dlna
dlna:*:933:933:DLNA Daemon:/nonexistent:/usr/sbin/nologin
minidlna:*:1008:1019:MiniDLNA:/nonexistent:/usr/sbin/nologin
cat /etc/group | grep dlna
dlna:*:933:
smb_dlna:*:1019:
# - [OPTIONAL]: if the user:group dlna:dlna were not created:
# The defaults for freeBSD port are dlna:dlna uid 933 and gid 933
root@streaming:~ #
pw groupadd dlna -g 933
pw useradd dlna -d /nonexistent -s /usr/sbin/nologin -u 933 -g 933 -c "DLNA Daemon"
# Edit minidlna service script
root@streaming:~ #
ee /usr/local/etc/rc.d/minidlna
# - Paste the code between the [start][end] tags
[CODE file start][minidlna]
#!/bin/sh
#
# $FreeBSD: head/net/minidlna/files/minidlna.in 323762 2013-07-26 23:25:40Z wg $
#
# PROVIDE: minidlna
# REQUIRE: LOGIN
# KEYWORD: shutdown
#
# Add the following line to /etc/rc.conf[.local] to enable minidlna:
#
# minidlna_enable="YES"
. /etc/rc.subr
name=minidlna
rcvar=minidlna_enable
load_rc_config $name
minidlna_enable=${minidlna_enable-"NO"}
# this is the user running the daemon, it doesn't need to exist on TrueNAS host
minidlna_uid=${minidlna_uid-"dlna"}
#minidlna_uid=${minidlna_uid-"root"}
# path to minidlnad binary
command=/usr/local/sbin/minidlnad
# file that holds the pid of the minidlna service when it is started
pidfile="/var/run/minidlna/minidlna.pid"
# config file defined in minidlna.conf
conf=/usr/local/etc/minidlna.conf
# database folder (only touched at startup. In all cases, the db folder set in minidlna.conf is used)
#dbfile=/var/db/minidlna
dbfile=/mnt/common/minidlna/db
# Add -r to do a non destructive scan on service start/restart
# Using -R would destroy all cached data and do a full scan again, which is very time consuming
command_args="-r -P $pidfile -u $minidlna_uid -f $conf"
# Create the $pidfile basedir and $dbfile folders (-d) with proper owner (-o)
# if folders exist, the owner is reset on every start of minidlna service
start_precmd="install -d -o $minidlna_uid ${pidfile%/*} $dbfile"
# On stopping the service, remove the pidfile
stop_postcmd="rm -f $pidfile"
extra_commands="rescan refresh"
# rescan command: destructive rescan (-R option) with rebuild of all the media library database
# a service restart is needed because minidlnad doesn't support -R without loading the daemon
rescan_cmd="rescan_minidlna"
rescan_minidlna() {
echo 'Scanning media library and rebuilding database...'
command_args="-R -P $pidfile -u $minidlna_uid -f $conf"
if [ -f "$pidfile" ]; then
run_rc_command restart
else
run_rc_command start
fi
}
# refresh command: non destructive rescan (-r option) of the media lib
# Actually same as restart
refresh_cmd="refresh_minidlna"
refresh_minidlna() {
echo 'Scanning media library for changes...'
command_args="-r -P $pidfile -u $minidlna_uid -f $conf"
if [ -f "$pidfile" ]; then
run_rc_command restart
else
run_rc_command start
fi
}
run_rc_command $1
[CODE file end][minidlna]
# - Set proper permissions
chmod 755 /usr/local/etc/rc.d/minidlna
chown root:wheel /usr/local/etc/rc.d/minidlna
# Edit minidlna config file
root@streaming:~ #
ee /usr/local/etc/minidlna.conf
# - Paste the code between the [start][end] tags
[CODE start minidlna.conf]
# port for HTTP (descriptions, SOAP, media transfer) traffic
port=8200
# network interfaces to serve, comma delimited (8 interfaces max)
#network_interface=eth0
# specify the user account name or uid to run as
user=minidlna
# set this to the directory you want scanned.
# * if you want multiple directories, you can have multiple media_dir= lines
# * if you want to restrict a media_dir to specific content types, you
# can prepend the types, followed by a comma, to the directory:
# + "A" for audio (eg. media_dir=A,/home/jmaggard/Music)
# + "V" for video (eg. media_dir=V,/home/jmaggard/Videos)
# + "P" for images (eg. media_dir=P,/home/jmaggard/Pictures)
# + "PV" for pictures and video (eg. media_dir=PV,/home/jmaggard/digital_camera)
media_dir=/media
# set this to merge all media_dir base contents into the root container
# note: the default is no
#merge_media_dirs=no
# set this if you want to customize the name that shows up on your clients
friendly_name=TrueNAS miniDLNA
# set this if you would like to specify the directory where you want MiniDLNA to store its database and album art cache
#db_dir=/var/db/minidlna
db_dir=/mnt/common/minidlna/db
# set this if you would like to specify the directory where you want MiniDLNA to store its log file
#log_dir=/var/log
log_dir=/mnt/common/minidlna/log
# set this to change the verbosity of the information that is logged
# each section can use a different level: off, fatal, error, warn, info, or debug
#log_level=general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn
# this should be a list of file names to check for when searching for album art
# note: names should be delimited with a forward slash ("/")
album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg
# set this to no to disable inotify monitoring to automatically discover new files
# note: the default is yes
inotify=yes
# set this to yes to enable support for streaming .jpg and .mp3 files to a TiVo supporting HMO
enable_tivo=no
# set this to beacon to use legacy broadcast discovery method
# defauts to bonjour if avahi is available
tivo_discovery=bonjour
# set this to strictly adhere to DLNA standards.
# * This will allow server-side downscaling of very large JPEG images,
# which may hurt JPEG serving performance on (at least) Sony DLNA products.
strict_dlna=no
# default presentation url is http address on port 80
#presentation_url=http://www.mylan/index.php
# notify interval in seconds. default is 895 seconds.
notify_interval=900
# serial and model number the daemon will report to clients
# in its XML description
serial=12345678
model_number=1
# Override the uuid to run multiple instances
# uuid=550e8400-e29b-41d4-a716-446655440000
# specify the path to the MiniSSDPd socket
#minissdpdsocket=/var/run/minissdpd.sock
# use different container as root of the tree
# possible values:
# + "." - use standard container (this is the default)
# + "B" - "Browse Directory"
# + "M" - "Music"
# + "V" - "Video"
# + "P" - "Pictures"
# + Or, you can specify the ObjectID of your desired root container (eg. 1$F for Music/Playlists)
# if you specify "B" and client device is audio-only then "Music/Folders" will be used as root
#root_container=.
# always force SortCriteria to this value, regardless of the SortCriteria passed by the client
# note: you can prepend the sort criteria with "!" to alter the titles of the objects so that they
# will be alphanumerically sorted in the order you specify here, to work around clients that do their
# own alphanumeric sorting.
force_sort_criteria=+upnp:class,+upnp:originalTrackNumber,+dc:title
# maximum number of simultaneous connections
# note: many clients open several simultaneous connections while streaming
#max_connections=50
# set this to yes to allow symlinks that point outside user-defined media_dirs.
#wide_links=no
# enable subtitle support by default on unknown clients.
# note: the default is yes
#enable_subtitles=yes
[CODE end minidlna.conf]
# - Set proper permissions
chmod 644 /usr/local/etc/minidlna.conf
chown root:wheel /usr/local/etc/minidlna.conf
# Start minidlna daemon:
root@streaming:~ #
service minidlna onestart
# Display version
minidlnad -V
# Test the daemon
# - with a conservative scan -r
service minidlna onestop
service minidlna onestart
service minidlna onerefresh
# - with a destructive -R rescan
service minidlna onestop
service minidlna onerescan
# Enable daemon on jail boot
sysrc minidlna_enable=yes
# - or
echo minidlna_enable="YES" >>/etc/rc.conf
# Start / stop / rescan (Destructive) / refresh (updates the library, non destructive)
service minidlna stop
service minidlna start
service minidlna restart
service minidlna rescan
service minidlna refresh
# If there are issues with permissions, delete these directories so that they are recreated with proper permissions:
# - recreate the mount points
# - delete minidlna database and log or manually chown/chmod them
service minidlna stop
rm -rvf /mnt/common/minidlna/db
rm -rvf /mnt/common/minidlna/log/minidlna.log
service minidlna start
## Fix file limit exceeded and additional files are not scanned by minidlna/Plex
# - display max files limits, globally and per process:
# sysctl -a : displays all readable variables
root@streaming:~ #
sysctl -a | grep kern.maxfiles
kern.maxfiles: 2084861
kern.maxfilesperproc: 1876374
# - to read a particular variable, specify its name:
sysctl kern.maxfiles
kern.maxfiles: 2084861
# - to set a particular variable, use the variable=value syntax:
sysctl kern.maxfiles=3000000
kern.maxfiles: 2084861 -> 3000000
sysctl kern.maxfilesperproc=3000000
kern.maxfilesperproc: 1876374 -> 3000000
# - to make the change stick on reboot, you must edit /etc/sysctl.conf
ee /etc/sysctl.conf
[sysctl.conf] {
# Set max readable files
kern.maxfiles=3000000
kern.maxfilesperproc=3000000
} [sysctl.conf]
# - if the variable is read-only and doesn't apply on reboot, modify/add it to /boot/loader.conf
ee /boot/loader.conf
[loader.conf] {
# Set max readable files
kern.maxfiles=3000000
kern.maxfilesperproc=3000000
} [loader.conf]