Skip to content

Rotated sync-run log .OpenCloudSync.log.1 is not excluded from sync, causing unresolvable conflicts on client-internal files #1129

Description

@Hegghammer

Summary

The desktop client writes its sync-run log .OpenCloudSync.log into the sync folder root (src/gui/syncrunfilelog.cpp). When the log exceeds 10 MiB, SyncRunFileLog::restartLogging() renames it to .OpenCloudSync.log.1. The bundled exclude list only excludes the exact name ].OpenCloudSync.log, so the rotated file .OpenCloudSync.log.1 is treated as a normal user file and synced to the server — even though it is a client-internal artifact with no user value.

This leads to conflicts on a file users never asked to sync, and the client offers no way to resolve them.

Why the exclusion fails

  • syncrunfilelog.cpp contains the comment "Note; this name is ignored in csync_exclude.c", but no such hard-coded exclusion exists in csync_exclude.cpp — exclusion happens only via exclude lists.
  • The bundled sync-exclude.lst (src/resources/theme/universal/sync-exclude.lst) has only ].OpenCloudSync.log (exact match, anchored). .OpenCloudSync.log.1 matches nothing.
  • Result: the rotated log syncs across machines, and any divergence produces a conflict copy.

Observed behavior

Client 4.0.0.3642, OpenCloud server 8.0.1, Linux (Debian 13).

After the log had rotated, a sync reset on a second event caused the client to treat the server's .OpenCloudSync.log.1 as new while a local copy existed → a conflict copy .OpenCloudSync.log (conflicted copy …).1 was created and a record written to the journal's conflicts table.

Consequences, verified against the source:

  • The server does not advertise the uploadConflictFiles capability, so SyncEngine sets setExcludeConflictFiles(true). Every discovery run classifies the conflict copy as CSYNC_FILE_EXCLUDE_CONFLICT, which yields an item with status Conflict / instruction IGNORE (discovery.cpp). This re-raises the conflict counter on every sync run, so the folder permanently shows "There are unresolved conflicts."
  • Because the item's instruction is IGNORE, it is also skipped by the sync-run file log, so the conflict is invisible there.
  • The conflict file is a dotfile, so it is invisible in file managers by default.
  • The client has no conflict-resolution UI; the only guidance is "Please check the conflict file!".

Net effect: a conflict on a client-internal file persists indefinitely with no visible location and no recourse.

Reproduction

  1. Let .OpenCloudSync.log grow past 10 MiB on one client so it rotates to .1 (or copy a large log into the sync root and sync twice).
  2. Sync so that .1 is uploaded.
  3. On the same or another client, trigger a state where local and server .1 diverge (e.g. wipe folder state / fresh journal while the local rotated file remains).
  4. Observe: conflict copy created, journal conflicts table populated, permanent "unresolved conflicts" warning.

Suggested fix

Change the bundled exclude pattern from ].OpenCloudSync.log to ].OpenCloudSync.log* — the wildcard matches within the basename, covering .1 rotations and conflict-copy variants alike. Alternatively, write the sync-run log outside the sync folder entirely.

Workaround (verified end-to-end)

  1. Delete or move the conflict copy and the .OpenCloudSync.log.1 file from the sync root. The deletion propagates to the server and the stale journal conflict record is removed automatically on the next sync run, clearing the warning.
  2. Create ~/.config/OpenCloud/sync-exclude.lst containing:
    ].OpenCloudSync.log*
    
  3. Restart the client — the user exclude list is only registered at startup (ConfigFile::setupDefaultExcludeFilePaths() adds the user file only if it exists).

Verified on 4.0.0.3642: after restart, a test file .OpenCloudSync.log.99 placed in the sync root was silently excluded while a control file synced normally, and the journal conflicts table remained empty.


Related: #802 reports the missing user-facing notification side of conflicts; this issue is about the conflict being created on a client-internal file in the first place.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions