Hi all - just wanted to post this here in case anyone else runs into the same problem since I spent hours shaking my fists at it.
For the past few days I’ve been attempting to upgrade my Plex setup to use it as a DVR - I signed up for Plex Pass, got my tuner card set up and working correctly, and everything appeared to be working well except that I could not record anything. I was getting the dreaded “No write access to destination” error, and DVR:Grabber: No write permission in the logs. I thoroughly searched for solutions to this and found that while it seems pretty widespread, it is usually caused by attempting to write to a improperly configured Samba share or some other remote file system type.
My Plex setup on the other hand is all local disk - a 6 disk ZFS raid Z2 pool. I have a TV library set up at /media/tv and it attempts to write to /media/tv/.grab/<guid>. I have the permissions set up correctly on this folder (everything in /media/ is owned by a group that the “plex” user is a member of, permissions are set at 775 and the .grab folder is owned by plex:plex). I doubled checked everything, and even tried just setting the whole tree to 777, but I was still getting the same access denied errors. I couldn’t figure out what it was getting hung up on.
So I broke out strace (using the “-f” option to capture the short lived subprocess that the main service process spawned): strace -f -e trace=file -p <pid> -o <log file>, and saw this: statfs("/media/tv/.grab", { ... f_flags=ST_VALID|ST_RDONLY} (shortened for brevity). The file system was reporting a read only mount! A few lines below that: mkdir("/media/tv/.grab/<guid>", 0777) = -1 EROFS (Read-only file system). Not quite the same as “access denied” (hint hint Plex devs: return the damn error code in the log message!)
Anyway, the problem is apparently that Plex ends up running in a unique mount namespace and you need to explicitly grant it write access (cat /proc/<plex pid>/mounts is revealing here). You do this by editing the systemd service file and adding a line like ReadWritePaths=<your local path> under the [Service] section. Problem solved!
Hope this helps someone…