Xapian Search Engine
The Xapian build system (based on autoconf) works out of the box with Solaris 11. We have built Xapian using both GCC 4.7.3 and Oracle Solaris Studio 12.3 compiler suites. SPT in general uses Solaris Studio 12.3 to compile applications, since in our experience they tend to be more efficient and stable on Solaris.
Under certain operating conditions (heavily threaded environments), the file related system calls return a
errno
of 150
(symbolic name EINPROGRESS
). Oracle documentation explains this status as follows: An operation that takes a long time to complete (such as a connect) was attempted on a non-blocking object.
Xapian uses the
stat
system call to verify the status of the database directory and files before opening them. While testing our Xapian based applications we run into this issue quite frequently. We decided to modify the Xapian source code to try and ignore EINPROGRESS
status, which in our testing has not lead to any problems (no database corruption or invalid search results).The following modifications were applied to the Xapian sources. Note that these modifications and line numbers relate to version 1.2.13 of the xapian-core source distribution.
dbfactory.cc
The
WritableDatabase
constructor invokes stat
on the database directory specified. The check for the errno
associated with the stat
invocation is performed in backends/dbfactory.cc
on line 424 which was modified as follows:424 if (errno != ENOENT) 425 throw DatabaseOpeningError("Couldn't stat '" + path + "'", errno);
to
424 if (errno != ENOENT && errno != EINPROGRESS) 425 throw DatabaseOpeningError("Couldn't stat '" + path + "'", errno);
ioutils.cc
The
io_unlink
utility function used to delete files, uses the unlink
system call to delete the file. This also at times returns the EINPROGRESS
status, which we continue to ignore. The check for the return from the unlink
system call is performed on line 47 in common/io_utils.cc
, which was modified as follows:47 if (errno != ENOENT) { 48 throw Xapian::DatabaseError(filename + ": delete failed", errno); 49 }
to
47 if (errno != ENOENT && errno != EINPROGRESS) { 48 throw Xapian::DatabaseError(filename + ": delete failed", errno); 49 }
chert_database.cc
The
ChertDatabase
constructor uses stat
to verify the database directory, which again may fail with the EINPROGRESS
error code. The check is performed on line 135 of the backends/chert/chert_database.cc
implementation file, which was modified as follows:135 } else if (errno != ENOENT || mkdir(db_dir, 0755) == -1) { 136 fail = true; 137 }
to
135 } else if (mkdir(db_dir, 0755) == -1) { 136 fail = true; 137 }
chert_table.cc
The
ChertTable::do_open_to_write
method uses the open
system call to open the database file for read/write. The open
system call also returns the EINPROGRESS
error status. We modified the backends/chert/chert_table.cc
implementation file at line 1505 as follows to ignore this status:1505 if (lazy && !create_db && errno == ENOENT) { 1506 revision_number = revision_; 1507 RETURN(true); 1508 }
to
1505 if (lazy && !create_db && (errno == ENOENT || errno == EINPROGRESS)) { 1506 revision_number = revision_; 1507 RETURN(true); 1508 }
libtool
The
libtool
script generated by the configure script also needs a small modification to build Xapian. The autoconf
system properly determines that it needs the Apache stdcxx
library to compile, while the libtool
attempts to link against the default Cstd
library. We removed the specification of the Cstd
library from the libtool
script for the build to succeed.10219 postdeps="-library=Cstd -library=Crun"
to
10219 postdeps="-library=Crun"
Notes
We have so far been using only the default chert backend with Xapian. If you use the other backends such as brass or flint, you will need to apply modifications similar to the modifications we applied to the chert backend.
The following shell script may be used to build and install Xapian
#!/bin/ksh ./configure --prefix=/opt/xapian \ CC=cc CXX=CC CFLAGS="-m64" CXXFLAGS="-O -m64" \ LIBS="-lsocket -lnsl -lpthread" LDFLAGS="-m64" sed -e 's;postdeps="-library Cstd -library=Crun";postdeps="-library=Crun";g' libtool > /tmp/libtool \mv /tmp/libtool . gmake -j8 gmake check pfexec gmake install