Skip to content

Commit

Permalink
support absolute paths as arguments for the mmap command line option …
Browse files Browse the repository at this point in the history
…when attaching

git-svn-id: https://xpra.org/svn/Xpra/trunk@12542 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed May 9, 2016
1 parent b6b9091 commit 0f24cb4
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 33 deletions.
6 changes: 4 additions & 2 deletions src/man/xpra.1
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ xpra \- viewer for remote, persistent X applications
\fBxpra\fP \fBattach\fP
[\fI:DISPLAY\fP | \fIssh:[USER@]HOST:DISPLAY\fP | \fItcp:[USER@]HOST:PORT[:DISPLAY]\fP]
[\fB\-zLEVEL | \-\-compress\fP=\fILEVEL\fP]
[\fB\-\-mmap\fP=\fIyes\fP|\fIno\fP]
[\fB\-\-mmap\fP=\fIyes\fP|\fIno\fP|ABSOLUTEFILENAME]
[\fB\-\-windows\fP=\fIyes\fP|\fIno\fP]
[\fB\-\-clipboard\fP=\fIyes\fP|\fIno\fP]
[\fB\-\-cursors\fP=\fIyes\fP|\fIno\fP]
Expand Down Expand Up @@ -427,12 +427,14 @@ Displays a summary of command line usage.
Enable debug logging. The special value \fBall\fP enables all
debugging.
.TP
\fB\-\-mmap\fP=\fIyes\fP|\fIno\fP
\fB\-\-mmap\fP=\fIyes\fP|\fIno\fP|\fIABSOLUTEFILENAME\fP
Enable or disable memory mapped pixel data transfer.
By default it is normally enabled automatically if the server and the
client reside on the same filesystem namespace.
This method of data transfer offers much lower overheads
and reduces both CPU consumption and local network traffic.
When attaching, you can also specify an absolute path where
the mmap file will be created.
.TP
\fB\-\-windows\fP=\fIyes\fP|\fIno\fP
Enable or disable the forwarding of windows. This is usually
Expand Down
17 changes: 11 additions & 6 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,13 @@ def init(self, opts):

self.dpi = int(opts.dpi)
self.xsettings_enabled = opts.xsettings
self.supports_mmap = MMAP_SUPPORTED and opts.mmap
self.mmap_group = opts.mmap_group
if MMAP_SUPPORTED:
self.mmap_group = opts.mmap_group
if os.path.isabs(opts.mmap):
self.mmap_filename = opts.mmap
self.supports_mmap = True
else:
self.supports_mmap = opts.mmap.lower() in TRUE_OPTIONS
self.shadow_fullscreen = opts.shadow_fullscreen

self.webcam_option = opts.webcam
Expand Down Expand Up @@ -464,7 +469,7 @@ def show_tray(*args):
def setup_connection(self, conn):
XpraClientBase.setup_connection(self, conn)
if self.supports_mmap:
self.init_mmap(self.mmap_group, conn.filename)
self.init_mmap(self.mmap_filename, self.mmap_group, conn.filename)


def parse_border(self, border_str, extra_args):
Expand Down Expand Up @@ -1084,8 +1089,8 @@ def window_bell(self, window, device, percent, pitch, duration, bell_class, bell
raise Exception("override me!")


def init_mmap(self, mmap_group, socket_filename):
log("init_mmap(%s, %s)", mmap_group, socket_filename)
def init_mmap(self, mmap_filename, mmap_group, socket_filename):
log("init_mmap(%s, %s, %s)", mmap_filename, mmap_group, socket_filename)
from xpra.os_util import get_int_uuid
from xpra.net.mmap_pipe import init_client_mmap
#calculate size:
Expand All @@ -1095,7 +1100,7 @@ def init_mmap(self, mmap_group, socket_filename):
mmap_size = min(1024*1024*1024, mmap_size)
self.mmap_token = get_int_uuid()
self.mmap_enabled, self.mmap, self.mmap_size, self.mmap_tempfile, self.mmap_filename = \
init_client_mmap(self.mmap_token, mmap_group, socket_filename, mmap_size)
init_client_mmap(self.mmap_token, mmap_group, socket_filename, mmap_size, self.mmap_filename)

def clean_mmap(self):
log("XpraClient.clean_mmap() mmap_filename=%s", self.mmap_filename)
Expand Down
61 changes: 39 additions & 22 deletions src/xpra/net/mmap_pipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,51 @@ def roundup(n, m):
return (n + m - 1) & ~(m - 1)


def init_client_mmap(token, mmap_group=None, socket_filename=None, size=128*1024*1024):
def init_client_mmap(token, mmap_group=None, socket_filename=None, size=128*1024*1024, filename=None):
"""
Initializes an mmap area, writes the token in it and returns:
(success flag, mmap_area, mmap_size, temp_file, mmap_filename)
The caller must keep hold of temp_file to ensure it does not get deleted!
This is used by the client.
"""
def rerr():
return False, None, 0, None, None
if not can_use_mmap():
log.error("cannot use mmap: python version is too old?")
return False, None, 0, None, None
log("init_mmap(%s, %s, %s)", token, mmap_group, socket_filename)
return rerr()
log("init_mmap%s", (token, mmap_group, socket_filename, size, filename))
try:
import mmap
import tempfile
from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP
mmap_dir = os.getenv("TMPDIR", "/tmp")
if not os.path.exists(mmap_dir):
raise Exception("TMPDIR %s does not exist!" % mmap_dir)
#create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures
#that the file is readable and writable only by the creating user ID
try:
temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir)
except OSError as e:
log.error("Error: cannot create mmap file:")
log.error(" %s", e)
return False, None, 0, None, None
#keep a reference to it so it does not disappear!
mmap_temp_file = temp
mmap_filename = temp.name
fd = temp.file.fileno()
if filename:
import errno
flags = os.O_CREAT | os.O_EXCL | os.O_RDWR
try:
fd = os.open(filename, flags)
mmap_temp_file = None #os.fdopen(fd, 'w')
mmap_filename = filename
except OSError as e:
if e.errno == errno.EEXIST:
log.error("Error: the mmap file '%s' already exists", filename)
return rerr()
raise
else:
import tempfile
from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP
mmap_dir = os.getenv("TMPDIR", "/tmp")
if not os.path.exists(mmap_dir):
raise Exception("TMPDIR %s does not exist!" % mmap_dir)
#create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures
#that the file is readable and writable only by the creating user ID
try:
temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir)
except OSError as e:
log.error("Error: cannot create mmap file:")
log.error(" %s", e)
return rerr()
#keep a reference to it so it does not disappear!
mmap_temp_file = temp
mmap_filename = temp.name
fd = temp.file.fileno()
#set the group permissions and gid if the mmap-group option is specified
if mmap_group and type(socket_filename)==str and os.path.exists(socket_filename):
s = os.stat(socket_filename)
Expand All @@ -69,9 +84,11 @@ def init_client_mmap(token, mmap_group=None, socket_filename=None, size=128*1024
write_mmap_token(mmap_area, token)
return True, mmap_area, mmap_size, mmap_temp_file, mmap_filename
except Exception as e:
log.error("failed to setup mmap: %s", e, exc_info=True)
log("failed to setup mmap: %s", e, exc_info=True)
log.error("Error: mmap setup failed:")
log.error(" %s", e)
clean_mmap(mmap_filename)
return False, None, 0, None, None
return rerr()

def clean_mmap(mmap_filename):
log("clean_mmap(%s)", mmap_filename)
Expand Down
4 changes: 2 additions & 2 deletions src/xpra/scripts/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ def read_xpra_defaults():
"ssh" : str,
"xvfb" : str,
"socket-dir" : str,
"mmap" : str,
"log-dir" : str,
"log-file" : str,
"border" : str,
Expand Down Expand Up @@ -341,7 +342,6 @@ def read_xpra_defaults():
"tray" : bool,
"pulseaudio" : bool,
"dbus-proxy" : bool,
"mmap" : bool,
"mmap-group" : bool,
"readonly" : bool,
"keyboard-sync" : bool,
Expand Down Expand Up @@ -517,7 +517,7 @@ def addtrailingslash(v):
"tray" : True,
"pulseaudio" : not OSX and not WIN32,
"dbus-proxy" : not OSX and not WIN32,
"mmap" : not OSX and not WIN32,
"mmap" : ["off", "on"][not OSX and not WIN32],
"mmap-group" : False,
"speaker" : ["disabled", "on"][has_sound_support],
"microphone" : ["disabled", "off"][has_sound_support],
Expand Down
2 changes: 1 addition & 1 deletion src/xpra/server/server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def init(self, opts):
self.init_options(opts)

def init_options(self, opts):
self.supports_mmap = opts.mmap
self.supports_mmap = opts.mmap.lower() in TRUE_OPTIONS
self.allowed_encodings = opts.encodings
self.init_encoding(opts.encoding)

Expand Down

0 comments on commit 0f24cb4

Please sign in to comment.