Commit graph

5313 commits

Author SHA1 Message Date
Patrick Ohly
c3fdf439da SyncConfig: implement "id" handling for reading and writing credentials
save/checkPassword both know how to handle the "id" provider now.
2013-08-02 13:15:26 +02:00
Patrick Ohly
d2a4164668 SyncConfig: allow sharing file config tree between configs
A SHARED_LAYOUT config tree caches config nodes. Allow a second config
to use those same nodes as an already existing config. This will be
useful in combination with indirect password lookup, because then the
credentials can be stored as temporary property values and be reused
when used multiple times in a process (for example, by CardDAV and by
CalDAV).
2013-08-02 13:15:20 +02:00
Patrick Ohly
d9f87251c0 SyncConfig: simplify password API
In practice, the methods are always called for a specific SyncConfig.
Passing that allows removing several other parameters and, more
importantly, also grants access to the config and through that other
configs. This will be needed for the indirect credential lookup.
2013-08-02 13:15:14 +02:00
Patrick Ohly
1131379cc5 SyncConfig: allow access to ConfigTree
This will be needed to access other configs in the indirect password
lookup.
2013-08-02 13:15:13 +02:00
Patrick Ohly
059bb0bd6f SyncSourceConfig: remove obsolete password methods
Not used, the per-source password operations are done via the
ConfigProperty interface.
2013-08-02 13:15:13 +02:00
Patrick Ohly
5ff97dea44 config: user name -> identity
"username", "proxyUsername" and "databaseUser" used to be simply a
string containing the name of the respective user or (in the case of
the ActiveSync backend) the account ID in gconf.

Now it is also possible to provide credentials (username + password)
indirectly: when any of these properties is set to "id:<config name>",
then the "username/password" properties in that config are used
instead. This is useful in particular with WebDAV, where credentials
had to be repeated several times (target config, in each database when
used as part of SyncML) or when using a service which requires several
configs (Google via SyncML and CalDAV).

For user names which contain colons, the new "user:<user name>" format
must be used. Strings without colons are assumed to be normal user
names.

This commit changes the SyncConfig APIs for this extension. More work
is needed to make the indirect lookup via "id" functional.
2013-08-02 13:15:13 +02:00
Patrick Ohly
56ac0812a4 SyncConfig: remove obsolete caching of passwords
Passwords are cached after the initial check as temporary property
values. The explicit string members are obsolete and can be removed
together with the code using them.
2013-08-02 13:15:13 +02:00
Patrick Ohly
193ef1e534 glib: SYNCEVO_GLIB_CALL_SYNC() must use GRunWhile()
Like everything else that waits for a certain event on the main loop,
SYNCEVO_GLIB_CALL_SYNC() should also better use GRunWhile(). This is
necessary to be usable in threads.
2013-08-02 13:15:13 +02:00
Patrick Ohly
0a8b3f1f48 D-Bus server: password not stored in GNOME keyring or KWallet (FDO #66110)
When clients like the GTK sync-ui stored a password, it was always
stored as plain text in the config.ini file by the
syncevo-dbus-server. The necessary code for redirecting the password
storage in a keyring (GNOME or KWallet) simply wasn't called in that
case.

The command line tool, even when using the D-Bus server to run the
operation, had the necessary code active and thus was not affected.
2013-08-02 13:15:13 +02:00
Patrick Ohly
8bc48fd7d8 PBAP: compile fix for "PBAP: transfer data inside ReadItemAsKey"
uint16 happened to work when compiling with a recent GNOME stack, but
without that uint16 is not defined. The right approach is to use
stdint.h and uint16_t.
2013-07-25 11:19:03 +02:00
Patrick Ohly
94ab0a279a NEWS, autotools: SyncEvolution 1.3.99.4 2013-07-12 16:19:53 +02:00
Guido Günther
85fca61913 build: use top_builddir instead of builddir
when building syncevo-local-sync. Maemo's old automake doesn't now
about builddir.

This only fixes the one occurence relevant to Maemo.
2013-07-12 16:18:12 +02:00
Guido Günther
f65d91e132 build: Split autoreconf options
maemo's Scratchbox autoreconf chokes on the combined ones
2013-07-12 16:18:12 +02:00
Patrick Ohly
8694f06fb2 D-Bus testing: fix race in TestCmdline.testSyncFailure2
We used to kill it when it showed the first sign of life via D-Bus log output
- any output! Depending on timing, it may or may not have been able to send
the "target side ready" INFO message. If it did, our strict output check
failed.

Fix that by waiting for that message, which should be the only INFO message
and thus the only one which will appear in the output text, before killing the
process.
2013-07-12 11:44:39 +02:00
Patrick Ohly
924a8a7dd3 D-Bus testing: fix TestLocalCache.testPropertyRemovalIncremental100 name 2013-07-12 11:44:39 +02:00
Patrick Ohly
c16f1b0756 sync: avoid maintaining suspend/resume meta data during ephemeral sync
Both maintaining the map items inside the Synthesis engine and storing
them in .ini hash config nodes inside SyncEvolution are fairly heavy
operations which are not needed at all during an ephemeral sync (= no
meta data stored, done by the PIM Manager when triggering a pure PBAP
sync).

Using the new Synthesis CA_ResumeSupported DB capability it is
possible to suppress these operations without having to fiddle with
the Synthesis DB API that SyncEvolution provides. To make it possible
at the DB layer to detect that the meta data is not needed, the
ConfigNode passed to it must be marked as volatile.

This change sped up a sync with 10000 unmodified, known items from 38s
to 23s.
2013-07-12 11:44:39 +02:00
Patrick Ohly
5aec08d12c SyncSourceConfig: cache synthesisID
The synthesisID value is required for each Synthesis source progress
event, which can be fairly frequent (more than one per item). Instead
of going down to the underlying .ini config node each time, cache the
value in the SyncSourceConfig layer.
2013-07-12 11:44:39 +02:00
Patrick Ohly
a05197891f sync: reduce D-Bus traffic
Syncing was slowed down by fowarding all log messages from the local
sync helper to its parent and from the D-Bus helper to
syncevo-dbus-server. Quite often, the log messages then were simply
discarded by the recipient. To speed up syncing, better filter at the
source.

The syncevo-dbus-helper is told which messages are relevant by
forwarding the syncevo-dbus-server "D-Bus log level" command line
setting to the helper process as part of its argv parameters.

The synevo-local-sync helper applies its own log level now also to the
messages sent to the parent. This ensures that messages stored in the
client log also show up in the parent log (unless the parent has more
restrictive settints, which is uncommon) and that INFO/SHOW messages
still reach the user.
2013-07-12 11:44:39 +02:00
Patrick Ohly
b34d56482e sync: less verbose output, shorter runtime
For each incoming change, one INFO line with "received x[/out of y]"
was printed, immediately followed by another line with total counts
"added x, updated y, removed z". For each outgoing change, a "sent
x[/out of y]" was printed.

In addition, these changes were forwarded to the D-Bus server where a
"percent complete" was calculated and broadcasted to clients. All of
that caused a very high overhead for every single change, even if the
actual logging was off. The syncevo-dbus-server was constantly
consuming CPU time during a sync when it should have been mostly idle.

To avoid this overhead, the updated received/sent numbers that come
from the Synthesis engine are now cached and only processed when done
with a SyncML message or some other event happens (whatever happens
first).

To keep the implementation simple, the "added x, updated y, removed z"
information is ignored completely and no longer appears in the output.

As a result, syncevo-dbus-server is now almost completely idle during
a running sync with no log output. Such a sync involving 10000 contacts
was sped up from 37s to 26s total runtime.
2013-07-12 11:43:40 +02:00
Patrick Ohly
f2378b7909 ForkExec: allow passing arguments to helper
The optional args array will be used when executing the helper
executable.
2013-07-11 11:40:51 +02:00
Patrick Ohly
a69018e6da D-Bus testing: don't depend on server output during startup, truely quiet TEST_DBUS_QUIET
When asked to run quietly via a non-empty TEST_DBUS_QUIET,
test-dbus.py still enabled INFO messages to determine that the server
is ready. Waiting for bus name (as already done when starting with a
debugger) avoids that and allows us to disable all LogOutput signals.
2013-07-10 15:37:37 +02:00
Patrick Ohly
0a3ec71e92 PIM testing: include testcase from FDO #66618
Ordering of 鳥 = niǎo before 女性 = nǚ xìng depends on the right
env variables. It works in this test.
2013-07-10 13:08:02 +02:00
Patrick Ohly
4577c27fda HTTP server: handle message resends
If a client gave up waiting for the server's response and resent its message
while the server was still processing the message, syncing failed with
"protocol error: already processing a message" raised by the
syncevo-dbus-server because it wasn't prepared to handle that situation.

The right place to handle this is inside the syncevo-http-server, because it
depends on the protocol (HTTP in this case) whether resending is valid or
not. It handles that now by tracking the message that is currently in
processing and matching it against each new message. If it matches, the new
request replaces the obsolete one without sending the message again to
syncevo-dbus-server. When syncevo-dbus-server replies to the old message, the
reply is used to finish the newer request.

This situation is covered by
Client::Sync::eds_event_eds_contact::testManyDeletes with 100 items and
client and server running under valgrind. The test failed earlier and works
now.
2013-07-10 13:08:02 +02:00
Patrick Ohly
dc35d87dec D-Bus: better logging of server stub transport exceptions
Use SE_THROW() instead of "throw" because we want the error being
logged in the current sync log.
2013-07-10 13:08:02 +02:00
Patrick Ohly
7059459768 D-Bus: allow catching syncevo-dbus-helper in valgrind debugger
Set SYNCEVOLUTION_DBUS_HELPER_VGDB=1, add --vgdb-error=1 --vgdb=yes
to VALGRIND_ARGS, run test, wait for vgdb message in valgrind*.out files,
attach as instructed.

With --vgdb-error=0, all processes block during startup, waiting for
the debugger to attach.
2013-07-10 13:08:02 +02:00
Patrick Ohly
1538b89b36 PBAP: transfer data inside ReadItemAsKey
The previous attempt with concurrent reading while listing IDs did not
work, that listing must complete before the SyncML client contacts the
server. What works is transfering and parsing after the engine starts
to ask for the actual data.

For that we need to list IDs in advance. We use GetSize() for that.

If contacts get deleted while we read, getting the data for the
contacts at the end of the range will fail with 404, which is
understood by the Synthesis engine and leads to ignoring the ID, as
intended.

If contacts get added while we read, we will ignore them even if they
happen to be in the result of PullAll. The next sync will include
them.
2013-07-10 13:08:02 +02:00
Patrick Ohly
19aeba2029 PIM: use incremental sync for PBAP by default (FDO #59551)
When doing a PBAP sync, PIM manager asks the D-Bus sync helper to set
its SYNCEVOLUTION_PBAP_SYNC to "incremental". If the env variable
is already set, it does not get overwritten, which allows overriding
this default.
2013-07-10 13:08:02 +02:00
Patrick Ohly
7bd8a187d2 PIM testing: more flexible exclusion of empty vcard
Don't depend on order of properties, something else was seen.
2013-07-10 13:08:02 +02:00
Patrick Ohly
ddc1e53b0c PBAP: incremental sync (FDO #59551)
Depending on the SYNCEVOLUTION_PBAP_SYNC env variable, syncing reads
all properties as configured ("all"), excludes photos ("text") or
first text, then all ("incremental").

When excluding photos, only known properties get requested. This
avoids issues with phones which reject the request when enabling
properties via the bit flags. This also helps with
"databaseFormat=^PHOTO".

When excluding photos, the vcard merge script as used by EDS ensures
that existing photo data is preserved. This only works during a slow
sync (merge script not called otherwise, okay for PBAP because it
always syncs in slow sync) and EDS (other backends do not use the
merge script, okay at the moment because PIM Manager is hard-coded to
use EDS).

The PBAP backend must be aware of the PBAP sync mode and request a
second cycle, which again must be a slow sync. This only works because
the sync engine is aware of the special mode and sets a new session
variable "keepPhotoData". It would be better to have the PBAP backend
send CTCap with PHOTO marked as not supported for text-only syncs and
enabled when sending PHOTO data, but that is considerably harder to
implement (CTCap cannot be adjusted at runtime).

beginSync() may only ask for a slow sync when not already called
for one. That's what the command line tool does when accessing
items. It fails when getting the 508 status.

The original goal of overlapping syncing with download has not been
achieved yet. It turned out that all item IDs get requested before
syncing starts, which thus depends on downloading all items in the current
implementation. Can be fixed by making up IDs based on the number of
existing items (see GetSize() in PBAP) and then downloading later when
the data is needed.
2013-07-10 13:08:02 +02:00
Patrick Ohly
309bed01e1 SyncSource: avoid ERROR logging for 508 status code
Returning a 508 status from beginSync() via a StatusException is
valid, this should only be logged by the originator if it deems that
an error.
2013-07-10 13:08:02 +02:00
Patrick Ohly
6d3b1cf64b EDS: update PHOTO+GEO during slow sync, avoid rewriting PHOTO file
If PHOTO and/or GEO were the only modified properties during a slow
sync, the updated item was not written into local storage because
they were marked as compare="never" = "not relevant".

For PHOTO this was intentional in the sample config, with the
rationale that local storages often don't store the data exactly as
requested. When that happens, comparing the data would lead to
unnecessary writes. But EDS and probably all other local SyncEvolution
storages (KDE, file) store the photo exactly as requested, so not
considering changes had the undesirable effect of not always writing
new photo data.

For GEO, ignoring it was accidental.

A special merge script handles EDS file:// photo URIs. When the
loosing item has the data in a file and the winning item has binary
data, the data in the file may still be up-to-date, so before allowing
MERGEFIELDS() to overwrite the file reference with binary data and
thus forcing EDS to write a new file, check the content. If it
matches, use the file reference in both items.
2013-07-10 13:08:02 +02:00
Patrick Ohly
50c06bbe61 EDS contacts: read-ahead cache
Performance is improved by requesting multiple contacts at once and
overlapping reading with processing. On a fast system (SSD, CPU fast
enough to not be the limiting factor), testpim.py's testSync takes 8
seconds for a "match" sync where 1000 contacts get loaded and compared
against the same set of contacts. Read-ahead with only 1 contact per
query speeds that up to 6.7s due to overlapping IO and
processing. Read-ahead with the default 50 contacts per query takes
5.5s. It does not get much faster with larger queries.

While returning items from one cache populated with a single
e_book_client_get_contacts() call, another query is started to overlap
processing and loading.

To achieve efficient read-ahead, the backend relies on the hint given
to it via setReadAheadOrder(). As soon as it detects that a contact is
not the next one according to that order, it switches back to reading
one contact at a time. This happens during the write phase of a sync
where the Synthesis engine needs to read, update, and write back
changes based on updates sent by the peer.

Cache statistics show that this works well for --print-items, --export
and slow syncs.

Writing into the database must invalidate the corresponding cached
contact. Otherwise the backup operation after a sync may end up
reading stale data.
2013-07-10 13:07:53 +02:00
Patrick Ohly
7d12c0a586 read-ahead: tell SyncSource about the upcoming read accesses
Trying to predict in the SyncSource which items will be needed is
hard. It depends what the item is retrieved for (sync or
backup/printing) and on the sync mode (during a sync).

Instead of guessing, better have the user of the source tell the
source in advance what it will read. In most cases this is cheap
because it does not involve copying of items luids ("read all items",
"read new or modified items"). The source then can use its own internal
mechanisms to figure out what that means.

Only extracting specific items specified on the command line and the
backup operation must explicitly pass an ordered list of luids. For
the sake of simplicity, do that in a std::vector even though it
involves copying.
2013-07-10 13:07:44 +02:00
Patrick Ohly
81fdf67437 glib: allow other threads to check something after each main loop iteration
The
  while (<something>) g_main_context_iterate(NULL, true);
pattern only works in the main thread. As soon as multiple
threads are allowed to process events, race conditions occur,
as described before.

But the pattern is useful, so support it in all threads by
shifting the check into the main thread, which will then notify
other threads via a condition variable when something changes.
2013-07-10 13:07:35 +02:00
Patrick Ohly
ce1809d811 Threading: add Cond class
A thin wrapper around GMutex, initializes the condition variable
automatically.
2013-07-05 17:44:20 +02:00
Patrick Ohly
8ba5b42b92 Threading: fix Dyn*Mutex
gcc complained about the "protected" m_mutex access. Apparently
it did not realize that the access was to a base class. An explicit
get() solves that. Another way to get the pointer is a type cast.
2013-07-05 17:44:20 +02:00
Patrick Ohly
a5fd9df29d PBAP: refactor PbapSyncSource, asyncronous transfer, report items immediately
Derive from SyncSource and SyncSourceSession directly instead of going
through TrackingSyncSource. This allows removing several dummy methods
that we have to implement for TrackingSyncSource and allows
reporting existing items incrementally, instead of having to load all
of them at once for the old listAllItems().

Contacts are now already reported to the engine while their transfer
still runs. That depends on monitoring the temporary file, remapping
the larger file and continuing parsing where the previous parsing
stopped.

This only works with obexd 0.47 and obexd from Bluez 5, because it
depends on the temporary file interface. The older PullAll did not
return any data until it had downloaded everything.

Because it isn't known when the contact data will be needed, the backend
still maintains the mapping from ID to vCard data for all contacts seen
in the current session. Because that memory is backed by a temporary file
system, unused memory can be swapped out (and in) well by the OS.

If the file is in a ram-based temp file system, then it may also not
matter at all that the file gets mapped multiple times.
2013-07-05 17:44:20 +02:00
Patrick Ohly
37c29253cf GErrorCXX: add take()
The other methods always make a copy of the GError. The new take()
method takes over ownership. Use in combination with g_error_new().
2013-07-05 17:44:20 +02:00
Patrick Ohly
55c0806800 command line: execute --export and --print-items while the source is still reading
Instead of reading all item IDs, then iterating over them, process
each new ID as soon as it is available. With sources that support
incremental reading (only the PBAP source at the moment) that provides
output sooner and is a bit more memory efficient.
2013-07-05 17:44:20 +02:00
Patrick Ohly
e6c07b32b9 TmpFile: add moreData() and remove()
remove() is useful when want to continue using the file but also want
to ensure that it gets deleted when we crash.

moreData() can be used to determine if the file has grown since the
last time that map() was called. In other words, it supports
processing data while obexd still writes into the file.
2013-07-05 17:44:20 +02:00
Patrick Ohly
d0626ea46c GDBus GIO: support int64_t and uint64_t
The dbus_traits for them were simply missing.
2013-07-05 17:44:20 +02:00
Patrick Ohly
4bf2adbe25 GDBus GIO: avoid unnecessary case-insentive type comparison.
The type is already lower-case on both sides, so there's no
need for the case-insensitive comparison.
2013-07-05 17:44:20 +02:00
Patrick Ohly
25f24387c3 PBAP: fix support for obexd == 0.47, break 0.48
The previous commit "PBAP: fix support for obexd >= 0.47 and < Bluez 5"
made the backend work with obexd 0.48 and broke it with 0.47. That's because
there was another API change between 0.47 and 0.48, which wasn't known
at the time of that commit.

SyncEvolution now works with 0.47 and does not work with 0.48. This choice
was made because 0.47 supports the file-based data transfer (same as in Bluez 5
and thus useful for testing when Bluez 5 is not available) and 0.47 still
compiles against older Bluez versions (which makes it easier to use than 0.48).
2013-07-05 17:44:10 +02:00
Patrick Ohly
eca4dcb4b5 SuspendFlags: make it thread-safe
A new internal recursive mutex protects data that may get accessed
from different threads. It's recursive because callbacks may need to
lock it again.
2013-07-05 17:44:10 +02:00
Patrick Ohly
aa961d85f6 testing: run local sync tests with more items
Several of the recent changes are meant for exchanging many items.
Tests that when running syncs locally, that way we also cover
both sides (client and server).
2013-07-05 17:44:10 +02:00
Patrick Ohly
0c63a4f7f0 D-Bus testing: support git glib/gobject bindings
More recent GNOME Python bindings are provided by gobject
introspection. The traditional gobject/glib modules no
longer exist.

The API is similar enough that we just need to adapt importing: if
importing the normal modules fails, try importing from gi.repository
instead.
2013-07-05 17:44:10 +02:00
Patrick Ohly
9c6022bd13 testing: better logging of synccompare invocation
In testExtension, the local environment variables matter when invoking
synccompare. Include them in the debug output.
2013-07-05 17:44:10 +02:00
Patrick Ohly
dfd0bc29af EDS contacts: avoid unnecessary DB writes during slow sync due to FILE-AS
EDS 3.8 sets X-EVOLUTION-FILE-AS to "last, first" when a contact is
created without it. This leads again to unnecessary DB updates because
the incoming item that the engine works with doesn't have that field
set.

To mitigate that issue, set FILE_AS (renamed to make the field name
valid in a script) like EDS would do during writing.

The downside is that all incoming items now have FILE_AS set, which
will overwrite a locally stored copy of that property even if the peer
did not store X-EVOLUTION-FILE-AS. Previously, as tested by
testExtension, the local value was preserved. There is no good solution
that works for both use cases, so allow X-EVOLUTION-FILE-AS to get lost
and relax the test.
2013-07-05 17:44:10 +02:00
Patrick Ohly
d2a43b1e50 EDS contacts: avoid unnecessary DB writes during slow sync
Traditionally, contacts were modified shortly before writing into EDS
to match with Evolution expectations (must have N, only one CELL TEL,
VOICE flag must be set). During a slow sync, the engine compare the
modified contacts with the unmodified, incoming one. This led to
mismatches and/or merge operations which end up not changing anything
in the DB because the only difference would be removed again before
writing.

To avoid this, define datatypes which include the EDS modifications in
its <incomingscript>. Then the engine works with an item as it would
be written to EDS and correctly determines that the incoming and DB
items are identical.

Found in testpim.py's testSync when applied to the test cases
generated by the Openismus test case generator.
2013-07-05 17:44:10 +02:00
Patrick Ohly
634e5e4e90 EDS: avoid retrieving REV/LAST-MODIFIED if not needed
If the sources are used in a mode which doesn't need revision strings,
then skip the retrieval of items from the EDS daemons when we would
normally do it to get the revision string.
2013-07-05 17:44:10 +02:00