Dev Docs Netatalk Configuration
- Netatalk Configuration System
- Parsing and source
- Sections and inheritance
- Loading flow
- Identity, authentication, and logging
- Network and session controls
- Caching and multi-protocol policy
- Volume options
- Homes and substitution
- Spotlight, afpstats, and FCE
- Compatibility names and removed options
- Command line and single-user mode
- 18. Configuration Reload
Netatalk Configuration System
Audited against Netatalk
d63155e13on 2026-10-10. This describes the current source checkout; older releases may differ.
Parsing and source
afp.conf is an INI file parsed through iniparser. Build-time selection can use a system dependency or a Meson subproject; it is not an in-tree libatalk/iniparser library.
| File | Responsibility |
|---|---|
| config/afp.conf.in | Installed configuration template |
| libatalk/util/netatalk_conf.c | Shared option parsing, validation, volume construction, substitution |
| include/atalk/netatalk_conf.h | Public configuration API |
| include/atalk/iniparser_util.h | Compatibility types/macros and section names |
| include/atalk/globals.h | AFPObj, afp_options, global flags/defaults |
| include/atalk/volume.h | Volume structure and flags |
| etc/afpd/afp_options.c | AFP command-line parsing |
| etc/afpd/afp_config.c | Listener, authentication, FCE setup |
| doc/manpages/man5/afp.conf.5.md | Maintained user-facing option reference |
Examples below use keys actually consumed by this checkout. Installation paths depend on Meson settings; source defaults containing _PATH_* are build substitutions.
Sections and inheritance
[Global]
server name = My Server
vol preset = defaults
[defaults]
ea = sys
unix priv = yes
[Shared Documents]
path = /srv/documents
valid users = @staff
[Homes]
basedir regex = /home
home name = $u's home
INISEC_GLOBAL and INISEC_HOMES are the special section names. Ordinary sections define volumes; preset sections supply common volume options.
Internal getoption_str(), getoption_strdup(), getoption_bool(), and getoption_int() try the volume section, then the selected preset, then a caller-supplied default. vdgoption_* variants additionally fall back to [Global]. Global inheritance therefore depends on the option’s lookup path; not every volume key placed under Global becomes a volume default.
Some fields use parsed global values as their defaults (for example charsets), and vol dbpath has special Global-path handling. Follow creatvol() for the actual precedence. INIPARSER_GETSTR() returns dictionary-owned strings; duplication helpers transfer a heap copy to the caller.
Loading flow
afp_config_parse() loads the dictionary, initializes logging early, parses Global options, validates numeric bounds/aliases, and sets up charsets and extension mappings. The controller and AFP parent each parse their own configuration; -F is passed to the child process.
load_afp_conf_vols() reads volume sections and builds struct vol through creatvol(). The public loader was formerly named load_volumes().
| Load flag | Purpose |
|---|---|
LV_DEFAULT |
Session-context loading with authorization filtering |
LV_ALL |
Load definitions without ordinary user access checks |
LV_FORCE |
Force reload despite the timestamp check |
creatvol() resolves presets, authorization, paths, storage, charsets, UUIDs, and flags. Duplicate/nested paths and initialization failures are logged and can cause volumes to be skipped.
Identity, authentication, and logging
| Global key | Field/behavior | Default |
|---|---|---|
hostname |
hostname |
System hostname |
server name |
servername |
Hostname fallback |
uam list |
uamlist |
uams_dhx2.so |
uam path |
uampath |
_PATH_AFPDUAMPATH |
guest account |
guest |
nobody |
valid shellcheck |
OPTION_VALID_SHELLCHECK |
yes |
passwd file |
passwdfile, legacy Randnum |
_PATH_AFPDPWFILE |
srp verifier path |
srpverifierpath, directory |
_PATH_AFPSRPVERIFIERPATH |
save password, set password |
passwdbits |
yes, no |
k5 service, k5 realm, k5 keytab, fqdn |
Kerberos/GSS setup | Unset |
login message |
loginmesg |
Unset |
log level |
logconfig |
default:note |
log file |
logfile |
Unset |
log microseconds |
log_us_timestamp |
yes |
admin group, force user, and force group are Global identity controls. Admin-group and forced-identity settings are rejected in single-user mode. LDAP keys configure ACL UUID lookup, not an AFP password-verification UAM. See Authentication.
Network and session controls
| Global key | Field | Default and units |
|---|---|---|
afp port |
port |
548 |
afp listen |
listen |
Unset; address list |
afp interfaces |
interfaces |
Unset; interface list |
max connections |
connections |
200 |
tickleval |
tickleval |
30 seconds, minimum 1 |
timeout |
timeout |
4 tickle intervals, minimum 1 |
sleep time |
sleep |
10 hours, converted to tickles |
disconnect time |
disconnected |
24 hours, converted to tickles |
tcpsndbuf, tcprcvbuf |
tcp_sndbuf, tcp_rcvbuf |
0; nonzero byte-size socket requests |
server quantum |
server_quantum |
1 MiB; 32,000 bytes–256 MiB |
dsireadbuf |
dsireadbuf |
32; incoming readahead multiplier |
recvfile |
OPTION_RECVFILE |
no; requires compiled splice support |
use sendfile |
Inverse OPTION_NOSENDFILE |
yes; requires an eligible compiled path |
splice size |
splice_size |
1 MiB; bounded 4 KiB–8 MiB and page-rounded |
configinit() in etc/afpd/afp_config.c creates DSI listeners. afp listen accepts addresses with optional ports (IPv6+port uses [address]:port); afp port supplies the default. Choose either address-based afp listen or afp interfaces, as documented in afp.conf(5). For example:
[Global]
afp listen = 192.168.1.100, ::1
afp port = 548
The configured DSI buffer product is capped at 1 GiB (NETATALK_READBUF_LIMIT), with address-space checks. A multiplier is first bounded to 6–1,024, then can be reduced below 6 to fit a large quantum. Per-session TCP MSS alignment can adjust the quantum within the growth/max bounds and re-clamp the buffer product. See Performance Tuning.
appletalk, ddp address, and ddp zone require an AppleTalk build. zeroconf defaults to yes and controls advertisements; it does not control authorization.
Caching and multi-protocol policy
| Global key | Field | Default |
|---|---|---|
dircache size |
dircachesize |
65,536 entries; runtime 1,024–1,048,576 |
dircache mode |
dircache_mode |
arc (1); lru is 0 |
dircache validation freq |
dircache_validation_freq |
100; accepted range 1–100 |
dircache rfork budget |
dircache_rfork_budget |
32,768 KiB; 0 disables |
dircache rfork maxsize |
dircache_rfork_maxentry |
1,024 KiB |
strict locking |
OPTION_STRICT_LOCKING |
no |
Resource-fork budget/max-entry hard caps are 10 GiB/10 MiB, with additional 32-bit overflow protection. Runtime resource-fork budget variables are in bytes, while configuration fields are in KiB.
Volume multi protocol = yes applies defaults through apply_multiprotocol_defaults(): process-wide strict locking becomes yes and validation becomes 1 unless explicitly configured. The volume is excluded from resource-fork caching unless the Global budget was explicitly set. Overrides remain effective and can emit warnings. ea = samba selects storage format separately; it does not enable this policy.
See Caching Architecture and Shared Volumes.
Volume options
| Key | Field/behavior |
|---|---|
path, volume name, vol preset |
Filesystem path, display name, inherited defaults |
valid users, invalid users, hosts allow, hosts deny |
Authorization filtering |
read only, rolist, rwlist |
Write policy |
password, veto files, delete veto files |
Volume password and veto policy |
cnid scheme |
v_cnidscheme; SQLite default, optional MySQL |
vol dbpath |
v_dbpath; volume directory or Global base path |
volume uuid |
v_uuid; generated registry value when unset/empty |
ea |
EA/storage selection: sys, samba, ad, none, or auto when unset |
multi protocol |
AFPVOL_MULTIPROTO; external-writer coherency defaults |
unix priv, acls, chmod request |
Unix/ACL behavior; chmod preserve default, ignore or simple |
umask, directory perm, file perm |
Octal creation-mode settings |
vol charset, mac charset, casefold, case sensitive, illegal seq |
Filename conversion and case handling |
time machine, vol size limit |
Backup capability and reported capacity limit in MiB |
spotlight, spotlight backend |
Search enablement and compiled backend selection |
legacy icon |
Virtual volume-root icon theme |
preexec, postexec, preexec close |
Lifecycle commands/policy |
follow symlinks, invisible dots, network ids, cnid dev |
Filesystem and advertised-identity policy |
A Global vol dbpath without variables gets the volume name appended. A volume/preset vol dbpath selects that directory directly; the default base is the configured state directory’s CNID/.
Volume UUIDs also identify CNID tables, rather than being exclusively Time Machine metadata. Changing format/path/UUID can affect persistent identity and requires appropriate migration; changing a config string does not perform that migration.
Homes and substitution
[Homes] requires basedir regex. home name defaults to $u's home and must include $u; optional path selects a home subdirectory.
volxlate() implements substitutions including $b (basename), $c (client address), $d (volume path), $f (GECOS), $g (group), $h (hostname), $i (client IP), $s (server name), $u (user), $v (volume name), and $$. Expansion depends on the available session/user/path context; do not use user-dependent values where the controller must resolve private state before login.
Spotlight, afpstats, and FCE
Spotlight defaults to enabled for volumes when compiled/available; spotlight backend defaults to cnid, with optional localsearch and xapian. spotlight results limit defaults to 10,000; 0 disables the limit, a nonzero limit has a minimum 100 and maximum 16,000,000. The field is spotlight_results_limit, and the control applies to every backend.
afpstats defaults to no and sets OPTION_AFPSTATS. It provides a Unix-domain socket served by the parent’s STATS_FD poll events, not a D-Bus statistics thread. afpstats group configures group access. See etc/afpd/afpstats.c and etc/afpd/afpstats.h.
FCE keys include fce listener, fce coalesce, fce events, fce version, fce ignore names, fce ignore directories, fce notify script, fce holdfmod, and fce sendwait. These configure external notifications through etc/afpd/afp_config.c and etc/afpd/fce_api.c, separate from internal cache hints.
Compatibility names and removed options
| Old key | Current handling |
|---|---|
dircachesize |
Deprecated alias for dircache size |
afp read locks |
Deprecated alias for strict locking |
sparql results limit |
Deprecated alias for spotlight results limit |
srp passwd file |
Deprecated alias for srp verifier path; value now names a directory |
zeroconf name |
Deprecated alias for server name |
cnid listen, cnid server, vol dbnest |
Removed; nonempty occurrences are logged and ignored |
For typed aliases, precedence can also depend on whether a value is valid/usable; do not assume a malformed canonical value must override a valid alias. See parser regression coverage in test/afpd/subtests_conf.c.
Command line and single-user mode
AFP options include -d (foreground/debug flag), -F (config file), -u/--single-user, -v, -V, and -h. -F is not a config-only validation operation.
The controller’s --single-user additionally requires -P with a private absolute PID-file path, private caller-owned config/credential state, SRP-only authentication, SQLite volumes, and at least one valid static volume. It rejects Homes, AppleTalk, afpstats, admin-group/forced identities, and non-CNID Spotlight backends. Details are in Controller Daemon.
18. Configuration Reload
In normal mode, SIGHUP to the controller reloads its volume list/advertisements and signals the AFP parent. The parent resets listeners, frees/reparses configuration, initializes listeners, and forwards SIGHUP to workers. Workers defer handling into their command loop and call load_afp_conf_vols().
creatvol() deliberately retains an existing matching volume’s options during reload. Volumes removed from configuration are handled according to their open/deleted state and close vol. Therefore changed options on an already-loaded volume do not automatically become effective in that session. Reconnect or restart when fresh volume construction is required.
Single-user mode ignores SIGHUP and requires a restart for configuration changes.
Footnotes
Generated from the Netatalk GitHub Wiki
Last updated 2026-10-21