xpra icon
Bug tracker and wiki

Ticket #88: share-mmap-v2.patch

File share-mmap-v2.patch, 12.6 KB (added by Antoine Martin, 9 years ago)

updated patch with small changes

  • xpra/server.py

     
    798798            log.error("too many connections (%s), ignoring new one", len(self._potential_protocols))
    799799            listener.close()
    800800            return  True
    801         sock, _ = listener.accept()
    802         protocol = Protocol(SocketConnection(sock), self.process_packet)
     801        sock, address = listener.accept()
     802        protocol = Protocol(SocketConnection(sock, address), self.process_packet)
    803803        self._potential_protocols.append(protocol)
    804804        def verify_connection_accepted(protocol):
    805805            if not protocol._closed and protocol in self._potential_protocols and protocol!=self._protocol:
  • xpra/client.py

     
    434434                import tempfile
    435435                import uuid
    436436                import ctypes
    437                 from stat import S_IRUSR,S_IWUSR
     437                from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP
    438438                mmap_dir = os.getenv("TMPDIR", "/tmp")
    439439                if not os.path.exists(mmap_dir):
    440440                    raise Exception("TMPDIR %s does not exist!" % mmap_dir)
     
    442442                #keep a reference to it so it does not disappear!
    443443                self._mmap_temp_file = temp
    444444                self.mmap_file = temp.name
    445                 #ensure that the permissions are strict:
    446                 os.chmod(self.mmap_file, S_IRUSR|S_IWUSR)
     445                fd = temp.file.fileno()
     446                #ensure that the permissions are strict or set mmap-group option:
     447                if opts.mmap_group and type(conn.target)==str and os.path.exists(conn.target):
     448                    s = os.stat(conn.target)
     449                    os.fchown(fd, -1, s.st_gid)
     450                    os.fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
     451                else:
     452                    os.fchmod(fd, S_IRUSR|S_IWUSR)
    447453                self.mmap_size = max(4096, mmap.PAGESIZE)*32*1024   #generally 128MB
    448                 fd = temp.file.fileno()
    449454                log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd, self.mmap_size)
    450455                os.lseek(fd, self.mmap_size-1, os.SEEK_SET)
    451456                assert os.write(fd, '\x00')
  • xpra/dotxpra.py

     
    1515    pass
    1616
    1717class DotXpra(object):
    18     def __init__(self, dir=None):
     18    def __init__(self, sockdir=None, confdir=None):
    1919        assert XPRA_LOCAL_SERVERS_SUPPORTED
    20         if dir is None:
    21             dir = os.path.expanduser("~/.xpra")
    22         self._dir = dir
    23         if not os.path.exists(self._dir):
    24             os.mkdir(dir, 0700)
     20        self._confdir = os.path.expanduser(confdir or "~/.xpra")
     21        self._sockdir = os.path.expanduser(sockdir or "~/.xpra")
     22        if not os.path.exists(self._confdir):
     23            os.mkdir(self._confdir, 0700)
     24        if not os.path.exists(self._sockdir):
     25            os.mkdir(self._sockdir, 0700)
    2526        self._prefix = "%s-" % (socket.gethostname(),)
    2627
    27     def dir(self):
    28         return self._dir
     28    def confdir(self):
     29        return self._confdir
    2930
    3031    def _normalize_local_display_name(self, local_display_name):
    3132        if not local_display_name.startswith(":"):
     
    3738            assert char in "0123456789"
    3839        return local_display_name
    3940
    40     def socket_path(self, local_display_name):
     41    def make_path(self, local_display_name, dirpath ):
    4142        local_display_name = self._normalize_local_display_name(local_display_name)
    42         return os.path.join(self._dir, self._prefix + local_display_name[1:])
     43        return os.path.join( dirpath , self._prefix + local_display_name[1:])
    4344
     45    def socket_path(self, local_display_name):
     46        return self.make_path(local_display_name, self._sockdir)
     47
     48    def conf_path(self, local_display_name):
     49        return self.make_path(local_display_name, self._confdir)
     50
    4451    LIVE = "LIVE"
    4552    DEAD = "DEAD"
    4653    UNKNOWN = "UNKNOWN"
     
    7481
    7582    def sockets(self):
    7683        results = []
    77         base = os.path.join(self._dir, self._prefix)
     84        base = os.path.join(self._sockdir, self._prefix)
    7885        potential_sockets = glob.glob(base + "*")
    7986        for path in potential_sockets:
    8087            if stat.S_ISSOCK(os.stat(path).st_mode):
  • xpra/scripts/main.py

     
    163163    parser.add_option("--ssh", action="store",
    164164                      dest="ssh", default=DEFAULT_SSH_CMD, metavar="CMD",
    165165                      help="How to run ssh (default: '%default')")
     166    parser.add_option("--socket-dir", action="store",
     167                      dest="sockdir", default="~/.xpra",
     168                      help="Directory to place socket file in (default: '%default')")
     169    parser.add_option("--mmap-group", action="store_true",
     170                      dest="mmap_group", default=False,
     171                      help="Set the group permission on the mmap file to the same value as the owner of the server socket file we connect to when creating the mmap file with the client (default: '%default')")
    166172    parser.add_option("--remote-xpra", action="store",
    167173                      dest="remote_xpra", default=".xpra/run-xpra",
    168174                      metavar="CMD",
     
    263269            "type": "unix-domain",
    264270            "local": True,
    265271            "display": display_name,
     272            "sockdir": opts.sockdir,
    266273            }
    267274        return desc
    268275    elif display_name.startswith("tcp:"):
     
    284291        if not XPRA_LOCAL_SERVERS_SUPPORTED:
    285292            parser.error("need to specify a display")
    286293        # Pick a default server
    287         sockdir = DotXpra()
     294        sockdir = DotXpra(opts.sockdir)
    288295        servers = sockdir.sockets()
    289296        live_servers = [display
    290297                        for (state, display) in servers
     
    305312        sock.connect(target)
    306313    except socket.error, e:
    307314        sys.exit("Connection failed: %s" % (e,))
    308     return SocketConnection(sock)
     315    return SocketConnection(sock, target)
    309316
    310317def connect_or_fail(display_desc):
    311318    if display_desc["type"] == "ssh":
     
    324331                from wimpiggy.util import gtk_main_quit_really
    325332                gtk_main_quit_really()
    326333                raise IOError(error_message)
    327         return TwoFileConnection(child.stdin, child.stdout, abort_test)
     334        return TwoFileConnection(child.stdin, child.stdout, abort_test, target=cmd)
    328335
    329336    elif XPRA_LOCAL_SERVERS_SUPPORTED and display_desc["type"] == "unix-domain":
    330         sockdir = DotXpra()
     337        sockdir = DotXpra(display_desc["sockdir"])
    331338        sock = socket.socket(socket.AF_UNIX)
    332         return _socket_connect(sock,
    333                                sockdir.socket_path(display_desc["display"]))
     339        sockfile = sockdir.socket_path(display_desc["display"])
     340        return _socket_connect(sock, sockfile)
    334341
    335342    elif display_desc["type"] == "tcp":
    336343        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    337         return _socket_connect(sock,
    338                                (display_desc["host"], display_desc["port"]))
     344        tcp_endpoint = (display_desc["host"], display_desc["port"])
     345        return _socket_connect(sock, tcp_endpoint)
    339346
    340347    else:
    341348        assert False, "unsupported display type in connect"
     
    405412    while conn.read(4096):
    406413        pass
    407414    if display_desc["local"]:
    408         sockdir = DotXpra()
     415        sockdir = DotXpra(opts.sockdir)
    409416        for _ in xrange(6):
    410417            final_state = sockdir.server_state(display_desc["display"])
    411418            if final_state is DotXpra.LIVE:
    412                 time.sleep(0.5)
    413             else:
    414419                break
     420            time.sleep(0.5)
    415421        if final_state is DotXpra.DEAD:
    416422            print("xpra at %s has exited." % display_desc["display"])
    417423            sys.exit(0)
     
    423429            print("Failed to shutdown xpra at %s" % display_desc["display"])
    424430            sys.exit(1)
    425431        else:
    426             assert False
     432            assert False, "invalid state: %s" % final_state
    427433    else:
    428434        print("Sent shutdown command")
    429435
     
    431437    assert "gtk" not in sys.modules
    432438    if extra_args:
    433439        parser.error("too many arguments for mode")
    434     sockdir = DotXpra()
     440    sockdir = DotXpra(opts.sockdir)
    435441    results = sockdir.sockets()
    436442    if not results:
    437443        sys.stdout.write("No xpra sessions found\n")
  • xpra/scripts/server.py

     
    1515import atexit
    1616import signal
    1717import socket
     18import os
    1819
    1920from xpra.wait_for_x_server import wait_for_x_server        #@UnresolvedImport
    2021from xpra.dotxpra import DotXpra, ServerSockInUse
    2122
     23from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP
     24
    2225_cleanups = []
    2326def run_cleanups():
    2427    for c in _cleanups:
     
    137140    listener = socket.socket(socket.AF_UNIX)
    138141    listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    139142    listener.bind(sockpath)
     143    os.chmod(sockpath, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
    140144    return listener
    141145
    142146def create_tcp_socket(parser, spec):
     
    181185    assert mode in ("start", "upgrade")
    182186    upgrading = (mode == "upgrade")
    183187
    184     dotxpra = DotXpra()
     188    dotxpra = DotXpra(opts.sockdir)
    185189
    186190    # This used to be given a display-specific name, but now we give it a
    187191    # single fixed name and if multiple servers are started then the last one
     
    191195    # is running on the remote host.  Might need to revisit this later if
    192196    # people run into problems or autodiscovery turns out to be less useful
    193197    # than expected.
    194     scriptpath = os.path.join(dotxpra.dir(), "run-xpra")
     198    scriptpath = os.path.join(dotxpra.confdir(), "run-xpra")
    195199
    196200    # Save the starting dir now, because we'll lose track of it when we
    197201    # daemonize:
    198202    starting_dir = os.getcwd()
    199203
    200204    clobber = upgrading or opts.use_display
     205    try:
     206        sockpath = dotxpra.server_socket_path(display_name, clobber)
     207    except ServerSockInUse:
     208        parser.error("You already have an xpra server running at %s\n"
     209                     "  (did you want 'xpra upgrade'?)"
     210                     % (display_name,))
    201211    # Daemonize:
    202212    if opts.daemon:
    203         try:
    204             logpath = dotxpra.server_socket_path(display_name, clobber) + ".log"
    205         except ServerSockInUse:
    206             parser.error("You already have an xpra server running at %s\n"
    207                          "  (did you want 'xpra upgrade'?)"
    208                          % (display_name,))
     213        logpath = dotxpra.conf_path(display_name) + ".log"
    209214        sys.stderr.write("Entering daemon mode; "
    210215                         + "any further errors will be reported to:\n"
    211216                         + ("  %s\n" % logpath))
     
    299304        save_pid(xvfb_pid)
    300305
    301306    sockets = []
    302     sockpath = dotxpra.server_socket_path(display_name, clobber)
    303307    #print("creating server socket %s" % sockpath)
    304308    sockets.append(create_unix_domain_socket(sockpath))
    305309    def cleanup_socket():
  • xpra/protocol.py

     
    2727# (os.read/os.write-style interface) two-way byte stream:
    2828
    2929class TwoFileConnection(object):
    30     def __init__(self, writeable, readable, abort_test=None):
     30    def __init__(self, writeable, readable, abort_test=None, target=None):
    3131        self._writeable = writeable
    3232        self._readable = readable
    3333        self._abort_test = abort_test
     34        self.target = target
    3435
    3536    def may_abort(self, action):
    3637        """ if abort_test is defined, run it """
     
    4950        self._writeable.close()
    5051        self._readable.close()
    5152
     53    def __str__(self):
     54        return "TwoFileConnection(%s)" % str(self.target)
     55
    5256class SocketConnection(object):
    53     def __init__(self, s):
     57    def __init__(self, s, target):
    5458        self._s = s
     59        self.target = target
    5560
    5661    def read(self, n):
    5762        return self._s.recv(n)
     
    6166
    6267    def close(self):
    6368        return self._s.close()
    64        
     69
     70    def __str__(self):
     71        return "SocketConnection(%s)" % str(self.target)
     72
    6573def repr_ellipsized(obj, limit=100):
    6674    if isinstance(obj, str) and len(obj) > limit:
    6775        return repr(obj[:limit]) + "..."