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 #include <memory>
25 #include <sys/inotify.h>
26 
27 #include <seastar/core/future.hh>
28 #include <seastar/core/sstring.hh>
29 #include <seastar/core/shared_ptr.hh>
30 
31 namespace seastar::experimental {
32 
39 
53 class fsnotifier {
54  class impl;
55  shared_ptr<impl> _impl;
56 public:
57  class watch;
58  friend class watch;
59 
66  enum class flags : uint32_t {
67  access = IN_ACCESS, // File was accessed (e.g., read(2), execve(2)).
68  attrib = IN_ATTRIB, // Metadata changed—for example, permissions, timestamps, extended attributes
69  close_write = IN_CLOSE_WRITE, // File opened for writing was closed.
70  close_nowrite = IN_CLOSE_NOWRITE,// File or directory not opened for writing was closed.
71  create_child = IN_CREATE, // File/directory created in watched directory
72  delete_child = IN_DELETE, // File/directory deleted from watched directory.
73  delete_self = IN_DELETE_SELF, // Watched file/directory was itself deleted. (This event
74  // also occurs if an object is moved to another filesystem)
75  modify = IN_MODIFY, // File was modified (e.g., write(2), truncate(2)).
76  move_self = IN_MOVE_SELF, // Watched file/directory was itself moved.
77  move_from = IN_MOVED_FROM, // Generated for the directory containing the old filename
78  // when a file is renamed.
79  move_to = IN_MOVED_TO, // Generated for the directory containing the new filename
80  // when a file is renamed.
81  open = IN_OPEN, // File was opened
82  close = IN_CLOSE, // close_write|close_nowrite
83  move = IN_MOVE, // move_from|move_to
84  oneshot = IN_ONESHOT, // listen for only a single notification, after which the
85  // token will be invalid
86  ignored = IN_IGNORED, // generated when a token or the file being watched is deleted
87  onlydir = IN_ONLYDIR, // Watch pathname only if it is a directory; the error ENOT‐
88  // DIR results if pathname is not a directory. Using this
89  // flag provides an application with a race-free way of
90  // ensuring that the monitored object is a directory.
91  };
92 
94  using watch_token = int32_t;
100  using sequence_no = uint32_t;
101 
106  class watch {
107  public:
108  ~watch();
109  watch(watch&&) noexcept;
110  watch& operator=(watch&&) noexcept;
111 
117 
119  operator watch_token() const {
120  return _token;
121  }
122 
124  watch_token token() const {
125  return _token;
126  }
127 
128  private:
129  friend class fsnotifier;
131  watch_token _token;
132  shared_ptr<impl> _impl;
133  };
134 
135  fsnotifier();
136  ~fsnotifier();
137 
139  fsnotifier& operator=(fsnotifier&&);
140 
147  future<watch> create_watch(const sstring& path, flags mask);
148 
150  struct event {
151  // matches source watch
152  watch_token id;
153  // event(s) generated
154  flags mask;
155  sequence_no seq; // event correlation -> move_from+move_to
156  sstring name; // optional file name, in case of move_from/to
157  };
158 
163 
168  void shutdown();
169 
171  bool active() const;
172 
174  operator bool() const {
175  return active();
176  }
177 };
178 
181  return fsnotifier::flags(std::underlying_type_t<fsnotifier::flags>(a) | std::underlying_type_t<fsnotifier::flags>(b));
182 }
183 
185 inline void operator|=(fsnotifier::flags& a, fsnotifier::flags b) {
186  a = (a | b);
187 }
188 
191  return fsnotifier::flags(std::underlying_type_t<fsnotifier::flags>(a) & std::underlying_type_t<fsnotifier::flags>(b));
192 }
193 
195 inline void operator&=(fsnotifier::flags& a, fsnotifier::flags b) {
196  a = (a & b);
197 }
198 
200 
201 }
Simple RAII wrapper around a fsnotifier::watch_token.
Definition: fsnotify.hh:106
watch_token token() const
Get the token of this watch point.
Definition: fsnotify.hh:124
Filesystem modification notifier.
Definition: fsnotify.hh:53
bool active() const
Check if the notifier is activated.
int32_t watch_token
Token of a watch point.
Definition: fsnotify.hh:94
uint32_t sequence_no
Unique sequence number of associating related events.
Definition: fsnotify.hh:100
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:66
A wrapper around inotify_event.
Definition: fsnotify.hh:150
A representation of a possibly not-yet-computed value.
Definition: future.hh:1349
holds the implementation parts of the metrics layer, do not use directly.