Merge lp:~rye/ubuntuone-client/ignore-in-close-write-in-dirs into lp:ubuntuone-client

Proposed by Roman Yepishev
Status: Merged
Approved by: Manuel de la Peña
Approved revision: 1247
Merged at revision: 1253
Proposed branch: lp:~rye/ubuntuone-client/ignore-in-close-write-in-dirs
Merge into: lp:ubuntuone-client
Diff against target: 75 lines (+51/-0)
2 files modified
tests/platform/filesystem_notifications/test_linux.py (+41/-0)
ubuntuone/platform/filesystem_notifications/linux.py (+10/-0)
To merge this branch: bzr merge lp:~rye/ubuntuone-client/ignore-in-close-write-in-dirs
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve
dobey (community) Approve
Review via email: mp+106612@code.launchpad.net

Commit message

Ignore IN_CLOSE_WRITE for directories

Description of the change

If you approve this then please also approve https://code.launchpad.net/~rye/ubuntuone-client/ignore-in-close-write-in-dirs-stable-3-0/+merge/106613 which is the same code but for stable-3-0 release (Precise)

This branch adds the same types of filters as are already in place to make sure that events IN_OPEN and IN_CLOSE_NOWRITE work only on files.

eCryptFS layer used in Ubuntu for Private directories can send IN_CLOSE_WRITE on directories breaking syncdaemon and preventing the users from running Ubuntu One with ~/.Private directory.

To test:
0. Before patching:
1. Create a private ecryptfs directory: ecryptfs-setup-private and follow all the prompts including relogin.
2. After relogin add underlying ~/.Private folder to Ubuntu One: u1sdtool --create-folder=~/.Private
3. Notice that files do upload
4. Open this directory and put another file in it.

At this point no files will be uploaded for any Ubuntu One directory due to the unexpected event from INotify subsystem. The log will show:
exceptions.KeyError: "Unhandled Event in INotify: <Event dir=True mask=0x40000008 maskname=IN_CLOSE_WRITE|IN_ISDIR name='' path=/home/rtg/.Private pathname=/home/rtg/.Private wd=8 >"

5. Apply the patch and restart syncdaemon.
6. Add another file to the directory. Notice that the amount of entries in https://one.ubuntu.com/files/ in ~/.Private UDF corresponds to the number of files locally (filenames are encrypted).

To post a comment you must log in.
Revision history for this message
dobey (dobey) :
review: Approve
Revision history for this message
Manuel de la Peña (mandel) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/platform/filesystem_notifications/test_linux.py'
2--- tests/platform/filesystem_notifications/test_linux.py 2012-04-30 15:19:03 +0000
3+++ tests/platform/filesystem_notifications/test_linux.py 2012-05-23 13:09:19 +0000
4@@ -34,6 +34,7 @@
5 import os
6
7 from twisted.internet import defer, reactor
8+from twisted.trial.unittest import TestCase as PlainTestCase
9
10 from ubuntuone.syncdaemon import (
11 event_queue,
12@@ -436,3 +437,43 @@
13 self.monitor.rm_watch(path_ancestor)
14 self.assertEqual(self.monitor._general_watchs, {})
15 self.assertEqual(self.monitor._ancestors_watchs, {})
16+
17+
18+class FakeEvent(object):
19+ """A fake event."""
20+
21+ mask = 0
22+ name = ""
23+
24+
25+class ECryptFsTestCase(PlainTestCase):
26+ """Tests for the eCryptFS weirdness."""
27+
28+ def test_close_write_on_folders_is_ignored(self):
29+ """When eCryptFS sends CLOSE_WRITE on folders, ignore it"""
30+ result = []
31+ monitor = None
32+ processor = filesystem_notifications._GeneralINotifyProcessor(monitor)
33+ self.patch(processor.general_processor, "push_event", result.append)
34+
35+ fake_event = FakeEvent()
36+ fake_event.mask = filesystem_notifications.pyinotify.IN_ISDIR
37+ fake_event.name = "/fake/directory/path"
38+ processor.process_IN_CLOSE_WRITE(fake_event)
39+
40+ self.assertNotIn(fake_event, result)
41+
42+
43+ def test_close_write_on_files_is_handled(self):
44+ """When anything sends CLOSE_WRITE on files, handle it."""
45+ result = []
46+ monitor = None
47+ processor = filesystem_notifications._GeneralINotifyProcessor(monitor)
48+ self.patch(processor.general_processor, "push_event", result.append)
49+
50+ fake_event = FakeEvent()
51+ fake_event.mask = filesystem_notifications.pyinotify.IN_CLOSE_WRITE
52+ fake_event.name = "/fake/directory/path"
53+ processor.process_IN_CLOSE_WRITE(fake_event)
54+
55+ self.assertIn(fake_event, result)
56
57=== modified file 'ubuntuone/platform/filesystem_notifications/linux.py'
58--- ubuntuone/platform/filesystem_notifications/linux.py 2012-05-14 21:24:24 +0000
59+++ ubuntuone/platform/filesystem_notifications/linux.py 2012-05-23 13:09:19 +0000
60@@ -212,6 +212,16 @@
61 if not (event.mask & pyinotify.IN_ISDIR):
62 self.general_processor.push_event(event)
63
64+ @validate_filename
65+ def process_IN_CLOSE_WRITE(self, event):
66+ """Filter IN_CLOSE_WRITE to make it happen only in files.
67+
68+ eCryptFS sends IN_CLOSE_WRITE event for lower directories.
69+
70+ """
71+ if not (event.mask & pyinotify.IN_ISDIR):
72+ self.general_processor.push_event(event)
73+
74 def process_IN_MOVE_SELF(self, event):
75 """Don't do anything here.
76

Subscribers

People subscribed via source and target branches