Seastar
High performance C++ framework for concurrent servers
fsnotify.hh
1 /*
2  * This file is open source software, licensed to you under the terms
3  * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4  * distributed with this work for additional information regarding copyright
5  * ownership. You may not use this file except in compliance with the License.
6  *
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an
13  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14  * KIND, either express or implied. See the License for the
15  * specific language governing permissions and limitations
16  * under the License.
17  */
18 /*
19  * Copyright 2020 ScyllaDB Ltd.
20  */
21 
22 #pragma once
23 
24 #ifndef SEASTAR_MODULE
25 #include <memory>
26 #include <sys/inotify.h>
27 
28 #include <seastar/core/future.hh>
29 #include <seastar/core/sstring.hh>
30 #include <seastar/core/shared_ptr.hh>
31 #include <seastar/util/modules.hh>
32 #endif
33 
34 namespace seastar::experimental {
35 
36 SEASTAR_MODULE_EXPORT_BEGIN
37 
44 
58 class fsnotifier {
59  class impl;
60  shared_ptr<impl> _impl;
61 public:
62  class watch;
63  friend class watch;
64 
71  enum class flags : uint32_t {
72  access = IN_ACCESS, // File was accessed (e.g., read(2), execve(2)).
73  attrib = IN_ATTRIB, // Metadata changed—for example, permissions, timestamps, extended attributes
74  close_write = IN_CLOSE_WRITE, // File opened for writing was closed.
75  close_nowrite = IN_CLOSE_NOWRITE,// File or directory not opened for writing was closed.
76  create_child = IN_CREATE, // File/directory created in watched directory
77  delete_child = IN_DELETE, // File/directory deleted from watched directory.
78  delete_self = IN_DELETE_SELF, // Watched file/directory was itself deleted. (This event
79  // also occurs if an object is moved to another filesystem)
80  modify = IN_MODIFY, // File was modified (e.g., write(2), truncate(2)).
81  move_self = IN_MOVE_SELF, // Watched file/directory was itself moved.
82  move_from = IN_MOVED_FROM, // Generated for the directory containing the old filename
83  // when a file is renamed.
84  move_to = IN_MOVED_TO, // Generated for the directory containing the new filename
85  // when a file is renamed.
86  open = IN_OPEN, // File was opened
87  close = IN_CLOSE, // close_write|close_nowrite
88  move = IN_MOVE, // move_from|move_to
89  oneshot = IN_ONESHOT, // listen for only a single notification, after which the
90  // token will be invalid
91  ignored = IN_IGNORED, // generated when a token or the file being watched is deleted
92  onlydir = IN_ONLYDIR, // Watch pathname only if it is a directory; the error ENOT‐
93  // DIR results if pathname is not a directory. Using this
94  // flag provides an application with a race-free way of
95  // ensuring that the monitored object is a directory.
96  };
97 
99  using watch_token = int32_t;
105  using sequence_no = uint32_t;
106 
111  class watch {
112  public:
113  ~watch();
114  watch(watch&&) noexcept;
115  watch& operator=(watch&&) noexcept;
116 
122 
124  operator watch_token() const {
125  return _token;
126  }
127 
129  watch_token token() const {
130  return _token;
131  }
132 
133  private:
134  friend class fsnotifier;
136  watch_token _token;
137  shared_ptr<impl> _impl;
138  };
139 
140  fsnotifier();
141  ~fsnotifier();
142 
144  fsnotifier& operator=(fsnotifier&&);
145 
152  future<watch> create_watch(const sstring& path, flags mask);
153 
155  struct event {
156  // matches source watch
157  watch_token id;
158  // event(s) generated
159  flags mask;
160  sequence_no seq; // event correlation -> move_from+move_to
161  sstring name; // optional file name, in case of move_from/to
162  };
163 
168 
173  void shutdown();
174 
176  bool active() const;
177 
179  operator bool() const {
180  return active();
181  }
182 };
183 
186  return fsnotifier::flags(std::underlying_type_t<fsnotifier::flags>(a) | std::underlying_type_t<fsnotifier::flags>(b));
187 }
188 
190 inline void operator|=(fsnotifier::flags& a, fsnotifier::flags b) {
191  a = (a | b);
192 }
193 
196  return fsnotifier::flags(std::underlying_type_t<fsnotifier::flags>(a) & std::underlying_type_t<fsnotifier::flags>(b));
197 }
198 
200 inline void operator&=(fsnotifier::flags& a, fsnotifier::flags b) {
201  a = (a & b);
202 }
203 
205 
206 SEASTAR_MODULE_EXPORT_END
207 
208 }
Simple RAII wrapper around a fsnotifier::watch_token.
Definition: fsnotify.hh:111
watch_token token() const
Get the token of this watch point.
Definition: fsnotify.hh:129
Filesystem modification notifier.
Definition: fsnotify.hh:58
bool active() const
Check if the notifier is activated.
int32_t watch_token
Token of a watch point.
Definition: fsnotify.hh:99
uint32_t sequence_no
Unique sequence number of associating related events.
Definition: fsnotify.hh:105
future< watch > create_watch(const sstring &path, flags mask)
Monitor events specified in mask for the give path.
future< std::vector< event > > wait() const
flags
Flags of events supported by FileSystem Notifier.
Definition: fsnotify.hh:71
A wrapper around inotify_event.
Definition: fsnotify.hh:155
A representation of a possibly not-yet-computed value.
Definition: future.hh:1238
holds the implementation parts of the metrics layer, do not use directly.