[X2Go-Commits] [x2goserver] 01/01: x2goserver-printing/bin/x2goprint: work around atomicity problems with newer FUSE versions, create .ready file as .notready, move/copy to target file system and only then rename it in a hopefully atomic fashion.

git-admin at x2go.org git-admin at x2go.org
Sun Jul 22 00:00:06 CEST 2018


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository x2goserver.

commit aaa5b2236d03e5101618603087885a3667746b9d
Author: Mihai Moldovan <ionic at ionic.de>
Date:   Sat Jul 21 23:58:25 2018 +0200

    x2goserver-printing/bin/x2goprint: work around atomicity problems with newer FUSE versions, create .ready file as .notready, move/copy to target file system and only then rename it in a hopefully atomic fashion.
---
 debian/changelog                  |  4 ++++
 x2goserver-printing/bin/x2goprint | 32 ++++++++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index b852eeb..cc5df9c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -118,6 +118,10 @@ x2goserver (4.1.0.1-0x2go1) UNRELEASED; urgency=medium
       nxagent. Fixes: #1266.
     - x2goserver/bin/x2gostartagent: fix calculation syntax errors, drop
       useless subshells, don't use -o operator in plain test calls.
+    - x2goserver-printing/bin/x2goprint: work around atomicity problems with
+      newer FUSE versions, create .ready file as .notready, move/copy to
+      target file system and only then rename it in a hopefully atomic
+      fashion.
   * debian/{control,compat}:
     + Bump DH compat level to 9.
   * debian/:
diff --git a/x2goserver-printing/bin/x2goprint b/x2goserver-printing/bin/x2goprint
index d436a6b..c1ea0b6 100755
--- a/x2goserver-printing/bin/x2goprint
+++ b/x2goserver-printing/bin/x2goprint
@@ -119,14 +119,38 @@ if ( $mounts=~m/$spooldir/)
 	system("su", "$user", "-c", "mv $spooltmp/$pdfFile $spooldir");
 	syslog('debug', "x2goprint moved file $pdfFile to X2Go client's spool dir");
 
-	open (RFILE,">$spooltmp/$pdfFile.ready");
+	# Different fuse versions seem to handle cross-boundary moves differently.
+	# Older fuse versions seem to move files atomically (which is what we expect), i.e.,
+	# the file turns up on the remote file system fully populated.
+	# Newer fuse versions first create the file and then populate it, leading to a race
+	# condition with X2Go Client:
+	#   - X2Go Client sees the .ready file
+	#   - immediately tries to read its content
+	#   - deletes the file
+	#
+	# To further understand what is happening, consider that an mv operation is only
+	# (somewhat) guaranteed to be atomic for moves within a file system. In this case,
+	# mv uses the rename(2) system call, which, according to POSIX/SUS shall be atomic
+	# in certain cases (though it seems to only hold when the target file already
+	# exists). Then again, the C standard itself, which POSIX is also referencing,
+	# does not make any guarantees when it comes to atomicity, rather it says that the
+	# behavior is "implementation-defined" when the target file already exists. When
+	# crossing boundaries, all bets are off. Such an operation might be atomic, but
+	# might also be implemented as the equivalent of cp && rm.
+	#
+	# We'll handle this by generating a temporary file on the local server file system
+	# (suffixed .notready), copying that to the fuse mount and then issuing a fs-local
+	# mv/rename operation that we really, really, really hope will be atomic.
+	open (RFILE,">$spooltmp/$pdfFile.notready");
 	print RFILE "$pdfFile\n$title";
 	close (RFILE);
 
-	chown $uid, $gid, "$spooltmp/$pdfFile.ready";
-	system ("su", "$user", "-c", "mv $spooltmp/$pdfFile.ready $spooldir");
-	syslog('debug', "x2goprint moved file $pdfFile.ready to X2Go client's spool dir, X2Go client should start the print dialog very soon");
+	chown $uid, $gid, "$spooltmp/$pdfFile.notready";
+	system ("su", "$user", "-c", "mv $spooltmp/$pdfFile.notready $spooldir");
+
+	system ("su", "$user", "-c", "mv $spooldir/$pdfFile.notready $spooldir/$pdfFile.ready");
 
+	syslog('debug', "x2goprint moved file $pdfFile.ready to X2Go client's spool dir, X2Go client should start the print dialog very soon");
 } else {
 
 	# if the client-side spool dir is not mounted via SSHFS, we will simply drop the

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2goserver.git


More information about the x2go-commits mailing list