I’m running Transmission and I need it to have access to files located in /DATA dir which is where I mount media harddrives. This works fine for the directories specified as complete/incomplete/watch in the config, but for others Transmission complains of readonly filesystem.
I found a clue here to add BindPaths
to the config, but I cannot find it as a option so where do I add this?
{pkgs, ...}: {
services.transmission = {
enable = true;
package = pkgs.transmission;
openFirewall = true;
openRPCPort = true;
settings = {
home = "/DATA/D1/TM";
download-dir = "/DATA/D1/TM/complete";
incomplete-dir = "/DATA/D1/TM/incomplete";
watch-dir = "/DATA/D1/TM/watch";
watch-dir-enabled = false;
rpc-bind-address = "0.0.0.0";
rpc-port = 9091;
rpc-host-whitelist = "192.168.1.245";
rpc-whitelist = "192.168.1.*";
};
};
}
aorith
April 11, 2023, 9:11am
2
You’ll need to start transmission with a combination of user/group (or group) that has access to that directory tree, and rw permissions on the final folders, example:
transmission = {
enable = true;
user = "media-user";
group = "media-group";
To bind paths you can use:
fileSystems."/target/path" = {
device = "/source/path";
options = ["bind" "rw"];
};
This is not sufficient. I’ve tried running the service under my user which can write, but Transmission still claims readonly. I did add the rw option to their mounts as well, just to be sure, but that made no difference either.
aorith
April 11, 2023, 11:55am
4
Then something in the way the module is configured is denying the access to those volumes…
You can experiment with systemd-run
for example:
# cd /tmp && systemd-run --shell --uid=1013 --gid=1013 --property=PrivateTmp=True
Replace 1013 with your own id (or transmission user id). You can play with the properties, probably one of them is denying the access to your volume.
Transmission module enables some security settings, see:
Personally I run some services together with transmission inside of a nixos container that isn’t always enabled: nixconf/default.nix at 56d488e94760f16ba88250333eb9b89852fe3f3a · aorith/nixconf · GitHub
Could you paste the error from the transmission service unit?
A systemctl cat transmission.service
would be helpful too.
aorith:
Then something in the way the module is configured is denying the access to those volumes…
You can experiment with systemd-run
for example:
# cd /tmp && systemd-run --shell --uid=1013 --gid=1013 --property=PrivateTmp=True
I’m not familiar with systemd, is this the entire command? It doesn’t seem to produce anything; just results in Main processes terminated with: code=exited/status=217
apr 11 14:19:21 helios transmission-daemon[12609]: [2023-04-11 14:19:21.278] Error while flushing completed pieces from cache (/build/source/libtransmission/session.c:571)
apr 11 14:19:21 helios transmission-daemon[12609]: [2023-04-11 14:19:21.278] Saved "/var/lib/transmission/.config/transmission-daemon/stats.json" (/build/source/libtransmission/>
apr 11 14:25:21 helios transmission-daemon[12609]: [2023-04-11 14:25:21.278] Couldn't create "/DATA/D2/MEDIA": Read-only file system (/build/source/libtransmission/file-posix.c:>
apr 11 14:25:21 helios transmission-daemon[12609]: [2023-04-11 14:25:21.278] Couldn't create "/DATA/D2/MEDIA/": Read-only file system (/build/source/libtransmission/>
apr 11 14:25:21 helios transmission-daemon[12609]: [2023-04-11 14:25:21.278] Kizuna no Allele - 02.mkv tr_fdFileCheckout failed for "/DATA/D2/MEDIA/>
apr 11 14:25:21 helios transmission-daemon[12609]: [2023-04-11 14:25:21.278] Error while flushing completed pieces from cache (/build/source/libtransmission/session.c:571)
apr 11 14:31:21 helios transmission-daemon[12609]: [2023-04-11 14:31:21.278] Couldn't create "/DATA/D2/MEDIA": Read-only file system (/build/source/libtransmission/file-posix.c:>
apr 11 14:31:21 helios transmission-daemon[12609]: [2023-04-11 14:31:21.278] Couldn't create "/DATA/D2/MEDIA/": Read-only file system (/build/source/libtransmission/>
apr 11 14:31:21 helios transmission-daemon[12609]: [2023-04-11 14:31:21.278] Kizuna no Allele - 02.mkv tr_fdFileCheckout failed for "/DATA/D2/MEDIA/>
[Unit]
After=network.target apparmor.service
Description=Transmission BitTorrent Service
Requires=apparmor.service
[Service]
Environment="CURL_CA_BUNDLE=/nix/store/7yrdb4cb3xqy8xlqmvdn5yalzcjz98r6-nss-cacert-3.86/etc/ssl/certs/ca-bundle.crt"
Environment="LOCALE_ARCHIVE=/nix/store/lj44nmfy9i3fhqxkawx107almiqd51a6-glibc-locales-2.35-224/lib/locale/locale-archive"
Environment="PATH=/nix/store/lyicmql3ws929d7azr65h25b2hyakmb6-coreutils-9.1/bin:/nix/store/hk8w4kray4jbc8bbpaxb0dfa95jm7syj-findutils-4.9.0/bin:/nix/store/kp1chfvl8bai7rd2g80lk3>
Environment="TZDIR=/nix/store/w2swil1dw4fxmvkggcik4l0jiywwp5vp-tzdata-2022g/share/zoneinfo"
AmbientCapabilities=
BindPaths=/var/lib/transmission/.config/transmission-daemon
BindPaths=/DATA/D1/TM/complete
BindPaths=/DATA/D1/TM/incomplete
BindReadOnlyPaths=/nix/store
BindReadOnlyPaths=/etc
BindReadOnlyPaths=/run
The option is systemd.services.transmission.serviceConfig.BindPaths
, here’s an example:
{
systemd.services.transmission.serviceConfig.BindPaths = [ "/DATA" ];
}
aorith
April 11, 2023, 12:50pm
7
I think that the cat
to the unit was truncated, but anyway you can try what Infinisil suggested and bind /DATA/D1/TM
too, not sure why it isn’t working with your config as it should be already binded, double check the permissions for all the paths used.
The systemd-run
command is complete (but it only has one property enabled as an example), it should drop you into a shell with the user pid defined in --uid
. It’s useful to test systemd units but maybe too cumbersome in this case.
Btw, you won’t find systemd.services.transmission.
directly in nixos options but you can search for systemd.services.<name>.
to see which options are available, the unit is created by services.transmission.enable = true;
Sorry, you’re correct. Full output:
[Unit]
After=network.target apparmor.service
Description=Transmission BitTorrent Service
Requires=apparmor.service
[Service]
Environment="CURL_CA_BUNDLE=/nix/store/7yrdb4cb3xqy8xlqmvdn5yalzcjz98r6-nss-cacert-3.86/etc/ssl/certs/ca-bundle.crt"
Environment="LOCALE_ARCHIVE=/nix/store/lj44nmfy9i3fhqxkawx107almiqd51a6-glibc-locales-2.35-224/lib/locale/locale-archive"
Environment="PATH=/nix/store/lyicmql3ws929d7azr65h25b2hyakmb6-coreutils-9.1/bin:/nix/store/hk8w4kray4jbc8bbpaxb0dfa95jm7syj-findutils-4.9.0/bin:/nix/store/kp1chfvl8bai7rd2g80lk3xjz4v76j1v-gnugrep-3.7/bin:/nix/store/hdq087rhq35fl5d5p6pw2m7hr2ib0f4h-gnused-4.9/bin:/nix/store/33pkg1f1ad2wh2rkl2c48hf8kfxcjgw5-systemd-253.1/bin:/nix/store/lyicmql3ws929d7azr65h25b2hyakmb6-coreutils-9.1/sbin:/nix/store/hk8w4kray4jbc8bbpaxb0dfa95jm7syj-findutils-4.9.0/sbin:/nix/store/kp1chfvl8bai7rd2g80lk3xjz4v76j1v-gnugrep-3.7/sbin:/nix/store/hdq087rhq35fl5d5p6pw2m7hr2ib0f4h-gnused-4.9/sbin:/nix/store/33pkg1f1ad2wh2rkl2c48hf8kfxcjgw5-systemd-253.1/sbin"
Environment="TZDIR=/nix/store/w2swil1dw4fxmvkggcik4l0jiywwp5vp-tzdata-2022g/share/zoneinfo"
AmbientCapabilities=
BindPaths=/var/lib/transmission/.config/transmission-daemon
BindPaths=/DATA/D1/TM/complete
BindPaths=/DATA/D1/TM/incomplete
BindReadOnlyPaths=/nix/store
BindReadOnlyPaths=/etc
BindReadOnlyPaths=/run
BindReadOnlyPaths=/DATA/D1/TM/watch
CapabilityBoundingSet=
DeviceAllow=
ExecReload=/nix/store/lyicmql3ws929d7azr65h25b2hyakmb6-coreutils-9.1/bin/kill -HUP $MAINPID
ExecStart=/nix/store/bgja8nzs5zx715chh66qh6h0v8c7m3k0-transmission-3.00/bin/transmission-daemon -f -g /var/lib/transmission/.config/transmission-daemon
ExecStartPre=+/nix/store/grs54fkp5dh92lj5jm5zx0p8q8504idf-transmission-prestart
Group=transmission
LockPersonality=true
MemoryDenyWriteExecute=true
MountAPIVFS=true
NoNewPrivileges=true
PrivateDevices=true
PrivateMounts=true
PrivateNetwork=false
PrivateTmp=true
PrivateUsers=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=read-only
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
RemoveIPC=true
RestrictAddressFamilies=AF_UNIX
RestrictAddressFamilies=AF_INET
RestrictAddressFamilies=AF_INET6
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
RootDirectory=/run/transmission
RootDirectoryStartOnly=true
RuntimeDirectory=transmission
RuntimeDirectoryMode=755
StateDirectory=transmission
StateDirectory=transmission/.config/transmission-daemon
StateDirectory=transmission/.incomplete
StateDirectory=transmission/Downloads
StateDirectory=transmission/watch-dir
StateDirectoryMode=750
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=~@aio
SystemCallFilter=~@chown
SystemCallFilter=~@keyring
SystemCallFilter=~@memlock
SystemCallFilter=~@resources
SystemCallFilter=~@setuid
SystemCallFilter=~@timer
SystemCallFilter=quotactl
UMask=0066
User=transmission
Thanks, will see if this helps.
aorith
April 11, 2023, 1:09pm
9
Btw, you can see in the unit logs that its complaining about /DATA/D2/MEDIA/
:
apr 11 14:25:21 helios transmission-daemon[12609]: [2023-04-11 14:25:21.278] Couldn't create "/DATA/D2/MEDIA/": Read-only file system (/build/source/libtransmission/>
But in your configuration you always reference /DATA/D1/TM
. Is it loading a leftover configuration?
I’ve had trouble in the past migrating to another storage or from docker to nixos-containers, that happens, permissions… wrong paths… try to bind that directory if it’s needed
aorith:
But in your configuration you always reference /DATA/D1/TM
. Is it loading a leftover configuration?
I’ve had trouble in the past migrating to another storage or from docker to nixos-containers, that happens, permissions… wrong paths… try to bind that directory if it’s needed
No, that was me attempting to see if placing Transmission on the same drive which it claimed was RO made a difference (it did not).
Anyways systemd.services.transmission.serviceConfig.BindPaths = [ "/DATA" ];
seems to have solved the RO problem, as TM now results in permission denied instead. I know the cat above shows it running as transmission uid, but even when I start it as my own user it results in permission denied.
ls -l shows drwxrwxrwx 3 nixuser10512 1000 4096
and I can create files there, but Transmission seemingly cannot.
aorith
April 11, 2023, 4:07pm
11
Did you manage to solve it?
Something is off here:
services.transmission = {
enable = true;
package = pkgs.transmission;
openFirewall = true;
openRPCPort = true;
settings = {
home = "/DATA/D1/TM";
As you can see you have “home” in services.transmission.settings.home
, but if you look at the nixos options it should be outside of the actual transmission settings, so: services.transmission.home
, that explains why in your unit the ExecStart
has transmission-daemon -f -g /var/lib/transmission/.config/transmission-daemon
(-g
is an alias por --config-dir
in transmission).
Maybe try to change that, then before starting anything or doing a nixos-rebuild switch
ensure that all the files are owned by the user that transmission will use, or at least belong to a group that transmission will have r/w permissions.
Unfortunately no. I removed the home section entirely so it would use the default, but that made no difference. I also made an entirely new group, ran chown -R on the entire drive and made sure the user:group combo Transmission runs under owns all of it, but it still claims permission denied.
aorith
April 12, 2023, 7:32am
13
Oh
I have tested this in a VM and it works (with an empty /DATA
volume):
users.groups.media = {gid = 1100;};
users.users.media = {
isNormalUser = true;
group = "media";
uid = 1100;
};
{pkgs, ...}: {
services.transmission = {
enable = true;
user = "media";
group "media";
openFirewall = true;
openRPCPort = true;
home = "/DATA/D1/TM";
settings = {
download-dir = "/DATA/D1/TM/complete";
incomplete-dir = "/DATA/D1/TM/incomplete";
watch-dir = "/DATA/D1/TM/watch";
watch-dir-enabled = false;
rpc-bind-address = "0.0.0.0";
rpc-port = 9091;
rpc-host-whitelist = "192.168.1.245";
rpc-whitelist = "192.168.1.*";
};
};
}
Ensure the directories and permissions:
$ mkdir -p /DATA/D1/TM/.config/transmission-daemon
$ mkdir -p /DATA/D1/TM/{complete,incomplete,watch}
$ chown media:media -R /DATA/D1/TM
$ systemctl restart transmission.service
If it’s a new user, ensure that you can cd
into all the folders, and maybe try to touch a dummy file:
$ sudo su - media
$ cd /DATA/D1/TM/.config/transmission-daemon
$ touch test.txt
$ rm test.txt
You should replace the user and group “media” with your own (check the command id
) if you want to test it with your current user or create one explicitly for transmission.
This is my last try, if it doesn’t work please paste the service unit logs again and maybe someone more knowledgeable than me will help
Thanks a lot for your help @aorith . I ran your example but unfortunately Transmission still claims permission denied when a path other than the default is specified. I’ll post an update here if I ever figure it out, until then, here are the latest logs should anyone else feel like taking a stab at it.
Config:
{pkgs, ...}: {
systemd.services.transmission.serviceConfig.BindPaths = [ "/DATA" ];
users.groups.media = {
gid = 1100;
};
users.users.media = {
isNormalUser = true;
group = "media";
uid = 1100;
};
services.transmission = {
enable = true;
user = "media";
group = "media";
openFirewall = true;
openRPCPort = true;
home = "/DATA/D1/TM";
settings = {
download-dir = "/DATA/D1/TM/complete";
incomplete-dir = "/DATA/D1/TM/incomplete";
watch-dir = "/DATA/D1/TM/watch";
watch-dir-enabled = false;
rpc-bind-address = "0.0.0.0";
rpc-port = 9091;
rpc-host-whitelist = "192.168.1.245";
rpc-whitelist = "192.168.1.*";
};
};
}
Log:
[Unit]
After=network.target apparmor.service
Description=Transmission BitTorrent Service
Requires=apparmor.service
[Service]
Environment="CURL_CA_BUNDLE=/nix/store/7yrdb4cb3xqy8xlqmvdn5yalzcjz98r6-nss-cacert-3.86/etc/ssl/certs/ca-bundle.crt"
Environment="LOCALE_ARCHIVE=/nix/store/lj44nmfy9i3fhqxkawx107almiqd51a6-glibc-locales-2.35-224/lib/locale/locale-archive"
Environment="PATH=/nix/store/lyicmql3ws929d7azr65h25b2hyakmb6-coreutils-9.1/bin:/nix/store/hk8w4kray4jbc8bbpaxb0dfa95jm7syj-findutils>
Environment="TZDIR=/nix/store/w2swil1dw4fxmvkggcik4l0jiywwp5vp-tzdata-2022g/share/zoneinfo"
AmbientCapabilities=
BindPaths=/DATA/D1/TM/.config/transmission-daemon
BindPaths=/DATA/D1/TM/complete
BindPaths=/DATA/D1/TM/incomplete
BindPaths=/DATA
BindReadOnlyPaths=/nix/store
BindReadOnlyPaths=/etc
BindReadOnlyPaths=/run
CapabilityBoundingSet=
DeviceAllow=
ExecReload=/nix/store/lyicmql3ws929d7azr65h25b2hyakmb6-coreutils-9.1/bin/kill -HUP $MAINPID
ExecStart=/nix/store/bgja8nzs5zx715chh66qh6h0v8c7m3k0-transmission-3.00/bin/transmission-daemon -f -g /DATA/D1/TM/.config/transmissio>
ExecStartPre=+/nix/store/jqq1wda7y7x5sfq7gz6dcsg2rx7bp5mq-transmission-prestart
Group=media
LockPersonality=true
MemoryDenyWriteExecute=true
MountAPIVFS=true
NoNewPrivileges=true
PrivateDevices=true
PrivateMounts=true
PrivateNetwork=false
PrivateTmp=true
PrivateUsers=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=read-only
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
RemoveIPC=true
RestrictAddressFamilies=AF_UNIX
RestrictAddressFamilies=AF_INET
RestrictAddressFamilies=AF_INET6
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
RootDirectory=/run/transmission
RootDirectoryStartOnly=true
RuntimeDirectory=transmission
RuntimeDirectoryMode=755
StateDirectory=transmission
StateDirectory=transmission/.config/transmission-daemon
StateDirectory=transmission/.incomplete
StateDirectory=transmission/Downloads
StateDirectory=transmission/watch-dir
StateDirectoryMode=750
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=~@aio
SystemCallFilter=~@chown
SystemCallFilter=~@keyring
SystemCallFilter=~@memlock
SystemCallFilter=~@resources
SystemCallFilter=~@setuid
SystemCallFilter=~@timer
SystemCallFilter=quotactl
UMask=0066
User=media
ls -l /DATA
drwxrwxrwx 8 media media 4096 12 apr 04.53 D1
drwxrwxrwx 4 media media 4096 12 apr 11.58 D2
drwxrwxrwx 3 media media 4096 22 mar 09.17 D3
drwxrwxrwx 3 media media 4096 30 mar 03.44 D4
drwxrwxrwx 3 media media 4096 10 nov 03.27 D5
drwxrwxrwx 2 media media 4096 9 apr 11.08 D6
Systemctl status
● transmission.service - Transmission BitTorrent Service
Loaded: loaded (/etc/systemd/system/transmission.service; enabled; preset: enabled)
Active: active (running) since Wed 2023-04-12 12:24:02 CEST; 9min ago
Process: 59945 ExecStartPre=/nix/store/jqq1wda7y7x5sfq7gz6dcsg2rx7bp5mq-transmission-prestart (code=exited, status=0/SUCCESS)
Main PID: 59949 (transmission-da)
IP: 6.6M in, 291.1K out
IO: 4.0K read, 48.0K written
Tasks: 4 (limit: 9418)
Memory: 27.6M
CPU: 1.035s
CGroup: /system.slice/transmission.service
└─59949 /nix/store/bgja8nzs5zx715chh66qh6h0v8c7m3k0-transmission-3.00/bin/transmission-daemon -f -g /DATA/D1/TM/.config/transmission-daemon
apr 12 12:24:59 helios transmission-daemon[59949]: [2023-04-12 12:24:59.336] [ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv tr_fdFileCheckout failed for "/DATA/D2//[ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv.part": Permission denied (/build/source/libtransmission/inout.c:95)
apr 12 12:24:59 helios transmission-daemon[59949]: [2023-04-12 12:24:59.336] [ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv Pausing (/build/source/libtransmission/torrent.c:2022)
apr 12 12:24:59 helios transmission-daemon[59949]: [2023-04-12 12:24:59.336] Couldn't open "/DATA/D2//[ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv.part": Permission denied (/build/source/libtransmission/fdlimit.c:195)
apr 12 12:24:59 helios transmission-daemon[59949]: [2023-04-12 12:24:59.336] [ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv tr_fdFileCheckout failed for "/DATA/D2//[ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv.part": Permission denied (/build/source/libtransmission/inout.c:95)
apr 12 12:24:59 helios transmission-daemon[59949]: [2023-04-12 12:24:59.336] Saved "/DATA/D1/TM/.config/transmission-daemon/resume/56137679de262d9cfb2de8f99eaf4c107f8c0445.resume" (/build/source/libtransmission/variant.c:1221)
apr 12 12:27:41 helios transmission-daemon[59949]: [2023-04-12 12:27:41.337] [ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv IPv4 DHT announce done (/build/source/libtransmission/tr-dht.c:683)
apr 12 12:30:03 helios transmission-daemon[59949]: [2023-04-12 12:30:03.336] Couldn't open "/DATA/D2//[ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv.part": Permission denied (/build/source/libtransmission/fdlimit.c:195)
apr 12 12:30:03 helios transmission-daemon[59949]: [2023-04-12 12:30:03.336] [ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv tr_fdFileCheckout failed for "/DATA/D2//[ASW] Skip to Loafer - 02 [1080p HEVC][9B3C66C4].mkv.part": Permission denied (/build/source/libtransmission/inout.c:95)
apr 12 12:30:03 helios transmission-daemon[59949]: [2023-04-12 12:30:03.336] Error while flushing completed pieces from cache (/build/source/libtransmission/session.c:571)
apr 12 12:30:03 helios transmission-daemon[59949]: [2023-04-12 12:30:03.336] Saved "/DATA/D1/TM/.config/transmission-daemon/stats.json" (/build/source/libtransmission/variant.c:1221)