1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 """Asynchronous pyinotify implementation"""
23
24
25 import asyncore
26 import logging
27
28 try:
29
30 from pyinotify import pyinotify
31 except ImportError:
32 import pyinotify
33
34 from ganeti import daemon
35 from ganeti import errors
36
37
38
39
41 """An asyncore dispatcher for inotify events.
42
43 """
44
45 - def __init__(self, watch_manager, default_proc_fun=None, map=None):
46 """Initializes this class.
47
48 This is a a special asyncore file_dispatcher that actually wraps a
49 pyinotify Notifier, making it asyncronous.
50
51 """
52 if default_proc_fun is None:
53 default_proc_fun = pyinotify.ProcessEvent()
54
55 self.notifier = pyinotify.Notifier(watch_manager, default_proc_fun)
56
57
58
59
60
61 self.fd = self.notifier._fd
62 asyncore.file_dispatcher.__init__(self, self.fd, map)
63
65 self.notifier.read_events()
66 self.notifier.process_events()
67
68
71 """An asyncnotifier that can survive errors in the callbacks.
72
73 We define this as a separate class, since we don't want to make AsyncNotifier
74 diverge from what we contributed upstream.
75
76 """
77
78
80 """Handle modify events for a single file.
81
82 """
83
84 - def __init__(self, watch_manager, callback, filename):
85 """Constructor for SingleFileEventHandler
86
87 @type watch_manager: pyinotify.WatchManager
88 @param watch_manager: inotify watch manager
89 @type callback: function accepting a boolean
90 @param callback: function to call when an inotify event happens
91 @type filename: string
92 @param filename: config file to watch
93
94 """
95
96
97 self.watch_manager = watch_manager
98 self.callback = callback
99 self.mask = pyinotify.EventsCodes.ALL_FLAGS["IN_IGNORED"] | \
100 pyinotify.EventsCodes.ALL_FLAGS["IN_MODIFY"]
101 self.file = filename
102 self.watch_handle = None
103
105 """Watch the given file
106
107 """
108 if self.watch_handle is None:
109 result = self.watch_manager.add_watch(self.file, self.mask)
110 if not self.file in result or result[self.file] <= 0:
111 raise errors.InotifyError("Could not add inotify watcher")
112 else:
113 self.watch_handle = result[self.file]
114
116 """Stop watching the given file
117
118 """
119 if self.watch_handle is not None:
120 result = self.watch_manager.rm_watch(self.watch_handle)
121 if result[self.watch_handle]:
122 self.watch_handle = None
123
124
125
127
128
129
130
131
132
133
134 logging.debug("Received 'ignored' inotify event for %s", event.path)
135 self.watch_handle = None
136 self.callback(False)
137
138
139
141
142
143
144
145 logging.debug("Received 'modify' inotify event for %s", event.path)
146 self.callback(True)
147
149 logging.error("Received unhandled inotify event: %s", event)
150