631ae0f11f
Sometimes there are situations when `connection` map is filled with dead sessions. We don't want to deal with those dead ones. Change-Id: I00dda77c39b5adbba69421eace0be0159e02505c Reviewed-on: https://gerrit.libreoffice.org/22207 Reviewed-by: Ashod Nakashian <ashnakash@gmail.com> Tested-by: Ashod Nakashian <ashnakash@gmail.com> |
||
---|---|---|
.. | ||
bundled/include/LibreOfficeKit | ||
debian | ||
test | ||
.gitignore | ||
Admin.hpp | ||
Auth.hpp | ||
AUTHORS | ||
Capabilities.hpp | ||
ChangeLog | ||
ChildProcessSession.cpp | ||
ChildProcessSession.hpp | ||
Common.hpp | ||
configure.ac | ||
Connect.cpp | ||
COPYING | ||
INSTALL | ||
LoadTest.cpp | ||
LoadTest.hpp | ||
LOKitClient.cpp | ||
LOKitHelper.hpp | ||
LOOLBroker.cpp | ||
LOOLKit.cpp | ||
loolmap.c | ||
LOOLProtocol.cpp | ||
LOOLProtocol.hpp | ||
LOOLSession.cpp | ||
LOOLSession.hpp | ||
loolstat | ||
loolwsd-systemplate-setup | ||
LOOLWSD.cpp | ||
LOOLWSD.hpp | ||
loolwsd.service | ||
loolwsd.spec.in | ||
Makefile.am | ||
MasterProcessSession.cpp | ||
MasterProcessSession.hpp | ||
MessageQueue.cpp | ||
MessageQueue.hpp | ||
NEWS | ||
Png.hpp | ||
protocol.txt | ||
QueueHandler.hpp | ||
README | ||
Rectangle.hpp | ||
reference.txt | ||
Storage.hpp | ||
sysconfig.loolwsd | ||
TileCache.cpp | ||
TileCache.hpp | ||
TODO | ||
Util.cpp | ||
Util.hpp |
LibreOffice On-Line WebSocket server ==================================== Dependencies ------------ LibreOffice On-Line WebSocket server has the following dependencies: * libpng * Poco library: http://pocoproject.org/index.html. * libcap-progs Poco can be built with ./configure --prefix=/opt/poco && make install, but distro packages exist too. On openSUSE, you can use: zypper ar http://download.opensuse.org/repositories/devel:/libraries:/c_c++/openSUSE_13.2/devel:libraries:c_c++.repo zypper in poco-devel libcap-progs Building -------- loolwsd uses autoconf/automake, so build using the usual: MASTER=/path/to/built/core.git # configure for your system autoreconf automake --add-missing ./configure --enable-silent-rules --with-lokit-path=${MASTER}/include make where ${MASTER} is the location of the LibreOffice source tree. Run 'make check' after each commit. Requires loolwsd to be running. Note that the loolwsd program needs the CAP_SYS_CHROOT capability, thus you will be asked the root password when running make as it invokes sudo to run /sbin/setcap. If you have self-built Poco, add the following to ./configure: --with-poco-includes=<POCOINST>/include --with-poco-libs=<POCOINST>/lib where <POCOINST> means the Poco installation location. If you have the Poco debugging libraries (eg. you have a self-built Poco), you can add --enable-debug to the configure options for additional debugging. For Windows, a proper VS2013 project is needed. There is still unconditional debugging output etc. This is a work in progress. Running ------- First create the directory used for caching tiles. It is set as "${localstatedir}/cache/${PACKAGE}" in the configure.ac, so if you did not pass any switch to the configure script that affects "localstatedir, it will be /usr/local/var/cache/loolwsd . If you did pass such a switch, like --prefix, check config.h for the exact value. If you're using the defaults you'll need to: sudo mkdir -p /usr/local/var/cache/loolwsd sudo chown `whoami` /usr/local/var/cache/loolwsd Now you need to set up a minimal chroot system, and directory for the jails: SYSTEMPLATE=`pwd`/systemplate # or tweak for your system ROOTFORJAILS=`pwd`/jails # or tweak for your system rm -Rf ${SYSTEMPLATE} # clean ./loolwsd-systemplate-setup ${SYSTEMPLATE} ${MASTER}/instdir # build template mkdir -p ${ROOTFORJAILS} # create location for transient jails. To run loolwsd the way it is supposed to eventually be run "for real", you can now do: ./loolwsd --systemplate=${SYSTEMPLATE} --lotemplate=${MASTER}/instdir --childroot=${ROOTFORJAILS} and connect loleaflet to that (see loleaflet/README for more info). Again, ${MASTER} is location of the LibreOffice source tree with a built LibreOffice. This is work in progress, and consequently needs the latest LibreOffice master. The ${SYSTEMPLATE} is a directory tree set up using the loolwsd-systemplate-setup script here. (It should not exist before running the script.) It will contain the runtime environment needed by the LibreOffice dynamic libraries used through LibreOfficeKit. Improvements to that script are very likely needed on various distros. The ${ROOTFORJAILS} directory above is a presumably initially empty directory under which loolwsd will create chroot jails for editing each specific document. As loolwsd uses hardlinks to "copy" the contents of both ${SYSTEMPLATE} and the ${MASTER}/instdir directories into each chroot jail, ${SYSTEMPLATE} and ${MASTER}/instdir need to be on the same file system as ${ROOTFORJAILS}. If you plan to hack on loolwsd, you probably want to familiarize yourself with loolwsd's --test and --numprespawns switches, and the 'connect' test program. For interactive testing, you can use the loolwsd --test switch, or you can use the 'connect' program. Both accept "commands" from the protocol on standard input. You can either used them tuly interactively, or edit input lines into a file, or use shell scripting, etc. For instance: (echo load /some/where/foo.odt; echo tile part=0 width=500 height=500 tileposx=0 tileposy=0 tilewidth=10000 tileheight=10000; sleep 10) | ./loolwsd --test --systemplate=/home/tml/lo/master/lool-sys-template --lotemplate=/home/tml/lo/master/instdir --childroot=/home/tml/lo/master/lool-child-root Debugging --------- When debugging, you want to add --numprespawns=1 to the loolwsd parameters to limit the amount of concurrently running processes. When the crash happens too early, you also want to export SLEEPFORDEBUGGER=<number of seconds> so that you have time to attach to the process. Then run loolwsd, and attach your debugger to the process you are interested in. Note that as the loolwsd executable file has capabilities set, you need to run the debugger with super-user privilege. Also, note that as the child processes run in a chroot environment, they see the LibreOffice shared libraries as being in a directory tree /lo , but your debugger does not. So in order to be able to effectively debug the LibreOffice code as used through LibreOfficeKit by a child loolwsd process, you need to symlink the "lo" subdirectory of a running child loolwsd process's chroot jail as /lo. Something like: sudo ln -s ~/libreoffice/master/lool-child-roots/1046829984599121011/lo /lo Use the ps command to find out exactly the path to use. Set LOOL_DEBUG=1 to trap SIGSEGV and SEGBUS and prompt for debugger. Protocol description -------------------- See protocol.txt for a description of the protocol to be used over the websocket. Architecture ------------ There are three processes: LoolWSD, LoolBroker, and LoolKit. WSD is the top-level server and is intended to run as a service. It is responsible for spawning Broker and listening on public port for Client connections. The Broker is only responsible for spawning (or forking) Kit instances. There is only one Broker per WSD instance and there is one Kit instance per document. WSD listens on a public port and using internal pipes requests the Broker to fire a child (Kit) instance to host documents. The Broker then has to find an existing Kit that hosts that document, based on the public URI as unique key, and forward the request to this existing Kit, which then loads a new view to the document. Whether a document is loaded for the first time, or this is a new view on an existing one, the Kit connects via a socket to WSD on an internal port. WSD acts as a bridge between the Client and Kit by tunnelling the traffic between the two sockets (that which is between the Client and WSD and the one between WSD and Kit). File System ----------- WSD is given childroot argument on the command line. This is the root directory of jailed FS. This path can be anywhere, but here we'll designate it as: /childroot Before spawning a Broker instance, WSD needs to generate a random Jail-ID to use as the jail directory name. This JailID is then passed to Broker as argument jailid. Note: for security reasons, this directory name is randomly generated and should not be given out to the Client. Since there is only one Broker per WSD instance, there is also one JailID between them. The Broker creates a chroot in this directory (the jail directory): /childroot/jailid/ Broker copies the LO instdir (essentially installs LO in the chroot), then copies the Kit binary into the jail directory upon startup. Once done, it chroot-s and drops caps. Broker then waits on a read pipe to which WSD writes when a new request from a Client is received. Broker is responsible for spawning (or forking) Kit instances. For our purposes, it doesn't matter whether Kit is spawned or forked. Every document is hosted by a Kit instance. Each document is stored in a dedicated directory within the jail directory. The document root within the jail is /user/docs. The absolute path on the system (which isn't accessible to the Kit process as it's jailed) is: /childroot/jailid/user/docs Within this path, each document gets its own sub-directory based on another random Child-ID (which could be the Process ID of the Kit). This ChildId will be given out to Clients to facilitate the insertion and downloading of documents. (Although strictly speaking the Client can use the main document URI as key, this is the current design.) /childroot/jailid/user/docs/childid A request from a Client to load a document will trigger the following chain of events. - WSD public socket will receive the connection request followed by a "load" command. - WSD creates MasterProcessSession (ToClient) to handle the client traffic. - MasterProcessSession requests Broker to find or spawn Kit for the given URI. - Broker sends Kit request to host URI via pipe. - Kit connects to WSD on an internal port. - WSD creates another MasterProcessSession (ToPrisoner) to service Kit. - MasterProcessSession (ToClient) is linked to the ToPrisoner instance, copies the document into jail (first load only) and sends (via ToPrisoner) the load request to Kit. - Kit loads the document and sets up callbacks with LOKit. - MasterProcessSession (ToClient) and MasterProcessSession (ToPrisoner) tunnel the traffic between Client and Kit both ways. Coding style ------------ There is not really any serious rationale why the code ended up being written in the style it is... but unless you plan to change some style detail completely and consistenly all over, please keep to the style of the existing code when editing. The style is roughly as follows, in rough order of importance: - As in LO, no hard TABs in source files. Only spaces. Indentation step is four columns. - As in LO, the braces { and } of the block of if, switch, and while statements go on separate lines. - Following Poco conventions, non-static member variables are prefixed with an underscore. Static members have a CamelCase name. - Do use C++11. I admit in some places (out of laziness or ignorance) I use Poco API even if there probably is an equivalent std:: API. (Like for threads.) Feel free to change those, if the std:: API is not much more verbose or ugly, and you are sure it is equivalent. - Always prefer the C++ wrapped version of a C library API. I.e. include <cstring> instead of <string.h>, use std::memcpy() instead of memcpy(), etc. - Use std:: prefix for all std API, i.e. don't ever do "using std;". But it's OK to use "using Poco::Foo;" all over. Maybe that is not a good idea? But please no "using" in headers. - Be as portable as possible, i.e. don't intentionally write Unix-only code if there is a choice. Obviously some parts of the code currently use Unix-only things like chroot() and link() though. - Member functions use camelCaseWithInitialLowerCase. I don't like CamelCaseWithInitialUpperCase. - [ No kind of Hungarian prefixes. ] This rule seems to have been totally ignored lately. So now the codebase is inconsistent in naming conventions. Oh well.