/Users/deen/code/yugabyte-db/src/yb/util/env.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
4 | | // |
5 | | // The following only applies to changes made to this file as part of YugaByte development. |
6 | | // |
7 | | // Portions Copyright (c) YugaByte, Inc. |
8 | | // |
9 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
10 | | // in compliance with the License. You may obtain a copy of the License at |
11 | | // |
12 | | // http://www.apache.org/licenses/LICENSE-2.0 |
13 | | // |
14 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
15 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
16 | | // or implied. See the License for the specific language governing permissions and limitations |
17 | | // under the License. |
18 | | // |
19 | | // An Env is an interface used by the yb implementation to access |
20 | | // operating system functionality like the filesystem etc. Callers |
21 | | // may wish to provide a custom Env object when opening a database to |
22 | | // get fine gain control; e.g., to rate limit file system operations. |
23 | | // |
24 | | // All Env implementations are safe for concurrent access from |
25 | | // multiple threads without any external synchronization. |
26 | | |
27 | | #ifndef YB_UTIL_ENV_H |
28 | | #define YB_UTIL_ENV_H |
29 | | |
30 | | #include <stdint.h> |
31 | | |
32 | | #include <functional> |
33 | | #include <string> |
34 | | #include <vector> |
35 | | |
36 | | #include "yb/gutil/callback_forward.h" |
37 | | |
38 | | #include "yb/util/status_fwd.h" |
39 | | #include "yb/util/file_system.h" |
40 | | #include "yb/util/strongly_typed_bool.h" |
41 | | #include "yb/util/ulimit.h" |
42 | | |
43 | | namespace yb { |
44 | | |
45 | | class FileLock; |
46 | | class RandomAccessFile; |
47 | | class RWFile; |
48 | | class Slice; |
49 | | class WritableFile; |
50 | | |
51 | | struct RWFileOptions; |
52 | | struct WritableFileOptions; |
53 | | |
54 | | YB_STRONGLY_TYPED_BOOL(ExcludeDots); |
55 | | |
56 | | // FileFactory is the implementation of all NewxxxFile Env methods as well as any methods that |
57 | | // are used to create new files. This class is created to allow easy definition of how we create |
58 | | // new files without inheriting the whole env. |
59 | | class FileFactory { |
60 | | public: |
61 | 21.8k | FileFactory() {} |
62 | 112 | virtual ~FileFactory() {} |
63 | | // Create a brand new sequentially-readable file with the specified name. |
64 | | // On success, stores a pointer to the new file in *result and returns OK. |
65 | | // On failure stores NULL in *result and returns non-OK. If the file does |
66 | | // not exist, returns a non-OK status. |
67 | | // |
68 | | // The returned file will only be accessed by one thread at a time. |
69 | | virtual CHECKED_STATUS NewSequentialFile(const std::string& fname, |
70 | | std::unique_ptr<SequentialFile>* result) = 0; |
71 | | |
72 | | // Create a brand new random access read-only file with the |
73 | | // specified name. On success, stores a pointer to the new file in |
74 | | // *result and returns OK. On failure stores NULL in *result and |
75 | | // returns non-OK. If the file does not exist, returns a non-OK |
76 | | // status. |
77 | | // |
78 | | // The returned file may be concurrently accessed by multiple threads. |
79 | | virtual CHECKED_STATUS NewRandomAccessFile(const std::string& fname, |
80 | | std::unique_ptr<RandomAccessFile>* result) = 0; |
81 | | |
82 | | // Create an object that writes to a new file with the specified |
83 | | // name. Deletes any existing file with the same name and creates a |
84 | | // new file. On success, stores a pointer to the new file in |
85 | | // *result and returns OK. On failure stores NULL in *result and |
86 | | // returns non-OK. |
87 | | // |
88 | | // The returned file will only be accessed by one thread at a time. |
89 | | virtual CHECKED_STATUS NewWritableFile(const std::string& fname, |
90 | | std::unique_ptr<WritableFile>* result) = 0; |
91 | | |
92 | | |
93 | | // Like the previous NewWritableFile, but allows options to be |
94 | | // specified. |
95 | | virtual CHECKED_STATUS NewWritableFile(const WritableFileOptions& opts, |
96 | | const std::string& fname, |
97 | | std::unique_ptr<WritableFile>* result) = 0; |
98 | | |
99 | | // Creates a new WritableFile provided the name_template parameter. |
100 | | // The last six characters of name_template must be "XXXXXX" and these are |
101 | | // replaced with a string that makes the filename unique. |
102 | | // The resulting created filename, if successful, will be stored in the |
103 | | // created_filename out parameter. |
104 | | // The file is created with permissions 0600, that is, read plus write for |
105 | | // owner only. The implementation will create the file in a secure manner, |
106 | | // and will return an error Status if it is unable to open the file. |
107 | | virtual CHECKED_STATUS NewTempWritableFile(const WritableFileOptions& opts, |
108 | | const std::string& name_template, |
109 | | std::string* created_filename, |
110 | | std::unique_ptr<WritableFile>* result) = 0; |
111 | | |
112 | | // Creates a new readable and writable file. If a file with the same name |
113 | | // already exists on disk, it is deleted. |
114 | | // |
115 | | // Some of the methods of the new file may be accessed concurrently, |
116 | | // while others are only safe for access by one thread at a time. |
117 | | virtual CHECKED_STATUS NewRWFile(const std::string& fname, |
118 | | std::unique_ptr<RWFile>* result) = 0; |
119 | | |
120 | | // Like the previous NewRWFile, but allows options to be specified. |
121 | | virtual CHECKED_STATUS NewRWFile(const RWFileOptions& opts, |
122 | | const std::string& fname, |
123 | | std::unique_ptr<RWFile>* result) = 0; |
124 | | |
125 | | virtual Result<uint64_t> GetFileSize(const std::string& fname) = 0; |
126 | | |
127 | | virtual bool IsEncrypted() const = 0; |
128 | | }; |
129 | | |
130 | | class FileFactoryWrapper : public FileFactory { |
131 | | public: |
132 | 6.10k | explicit FileFactoryWrapper(FileFactory* t) : target_(t) {} |
133 | 112 | virtual ~FileFactoryWrapper() {} |
134 | | |
135 | | CHECKED_STATUS NewSequentialFile(const std::string& fname, |
136 | | std::unique_ptr<SequentialFile>* result) override; |
137 | | |
138 | | CHECKED_STATUS NewRandomAccessFile(const std::string& fname, |
139 | | std::unique_ptr<RandomAccessFile>* result) override; |
140 | | |
141 | | CHECKED_STATUS NewWritableFile(const std::string& fname, |
142 | | std::unique_ptr<WritableFile>* result) override; |
143 | | |
144 | | CHECKED_STATUS NewWritableFile(const WritableFileOptions& opts, |
145 | | const std::string& fname, |
146 | | std::unique_ptr<WritableFile>* result) override; |
147 | | |
148 | | CHECKED_STATUS NewTempWritableFile(const WritableFileOptions& opts, |
149 | | const std::string& name_template, |
150 | | std::string* created_filename, |
151 | | std::unique_ptr<WritableFile>* result) override; |
152 | | |
153 | | CHECKED_STATUS NewRWFile(const std::string& fname, |
154 | | std::unique_ptr<RWFile>* result) override; |
155 | | |
156 | | // Like the previous NewRWFile, but allows options to be specified. |
157 | | CHECKED_STATUS NewRWFile(const RWFileOptions& opts, |
158 | | const std::string& fname, |
159 | | std::unique_ptr<RWFile>* result) override; |
160 | | |
161 | | Result<uint64_t> GetFileSize(const std::string& fname) override; |
162 | | |
163 | 0 | bool IsEncrypted() const override { |
164 | 0 | return target_->IsEncrypted(); |
165 | 0 | } |
166 | | |
167 | | protected: |
168 | | FileFactory* target_; |
169 | | }; |
170 | | |
171 | | class Env { |
172 | | public: |
173 | | // Governs if/how the file is created. |
174 | | // |
175 | | // enum value | file exists | file does not exist |
176 | | // --------------------------------+-------------------+-------------------- |
177 | | // CREATE_IF_NON_EXISTING_TRUNCATE | opens + truncates | creates |
178 | | // CREATE_NON_EXISTING | fails | creates |
179 | | // OPEN_EXISTING | opens | fails |
180 | | enum CreateMode { |
181 | | CREATE_IF_NON_EXISTING_TRUNCATE, |
182 | | CREATE_NON_EXISTING, |
183 | | OPEN_EXISTING |
184 | | }; |
185 | | |
186 | 23.2k | Env() { } |
187 | | virtual ~Env(); |
188 | | |
189 | | // Return a default environment suitable for the current operating |
190 | | // system. Sophisticated users may wish to provide their own Env |
191 | | // implementation instead of relying on this default environment. |
192 | | // |
193 | | // The result of Default() belongs to yb and must never be deleted. |
194 | | static Env* Default(); |
195 | | |
196 | | static FileFactory* DefaultFileFactory(); |
197 | | |
198 | | static std::unique_ptr<Env> NewDefaultEnv(std::unique_ptr<FileFactory> file_factory); |
199 | | |
200 | | // Create a brand new sequentially-readable file with the specified name. |
201 | | // On success, stores a pointer to the new file in *result and returns OK. |
202 | | // On failure stores NULL in *result and returns non-OK. If the file does |
203 | | // not exist, returns a non-OK status. |
204 | | // |
205 | | // The returned file will only be accessed by one thread at a time. |
206 | | virtual CHECKED_STATUS NewSequentialFile(const std::string& fname, |
207 | | std::unique_ptr<SequentialFile>* result) = 0; |
208 | | |
209 | | // Create a brand new random access read-only file with the |
210 | | // specified name. On success, stores a pointer to the new file in |
211 | | // *result and returns OK. On failure stores NULL in *result and |
212 | | // returns non-OK. If the file does not exist, returns a non-OK |
213 | | // status. |
214 | | // |
215 | | // The returned file may be concurrently accessed by multiple threads. |
216 | | virtual CHECKED_STATUS NewRandomAccessFile(const std::string& fname, |
217 | | std::unique_ptr<RandomAccessFile>* result) = 0; |
218 | | |
219 | | // Create an object that writes to a new file with the specified |
220 | | // name. Deletes any existing file with the same name and creates a |
221 | | // new file. On success, stores a pointer to the new file in |
222 | | // *result and returns OK. On failure stores NULL in *result and |
223 | | // returns non-OK. |
224 | | // |
225 | | // The returned file will only be accessed by one thread at a time. |
226 | | virtual CHECKED_STATUS NewWritableFile(const std::string& fname, |
227 | | std::unique_ptr<WritableFile>* result) = 0; |
228 | | |
229 | | |
230 | | // Like the previous NewWritableFile, but allows options to be |
231 | | // specified. |
232 | | virtual CHECKED_STATUS NewWritableFile(const WritableFileOptions& opts, |
233 | | const std::string& fname, |
234 | | std::unique_ptr<WritableFile>* result) = 0; |
235 | | |
236 | | // Creates a new WritableFile provided the name_template parameter. |
237 | | // The last six characters of name_template must be "XXXXXX" and these are |
238 | | // replaced with a string that makes the filename unique. |
239 | | // The resulting created filename, if successful, will be stored in the |
240 | | // created_filename out parameter. |
241 | | // The file is created with permissions 0600, that is, read plus write for |
242 | | // owner only. The implementation will create the file in a secure manner, |
243 | | // and will return an error Status if it is unable to open the file. |
244 | | virtual CHECKED_STATUS NewTempWritableFile(const WritableFileOptions& opts, |
245 | | const std::string& name_template, |
246 | | std::string* created_filename, |
247 | | std::unique_ptr<WritableFile>* result) = 0; |
248 | | |
249 | | // Creates a new readable and writable file. If a file with the same name |
250 | | // already exists on disk, it is deleted. |
251 | | // |
252 | | // Some of the methods of the new file may be accessed concurrently, |
253 | | // while others are only safe for access by one thread at a time. |
254 | | virtual CHECKED_STATUS NewRWFile(const std::string& fname, |
255 | | std::unique_ptr<RWFile>* result) = 0; |
256 | | |
257 | | // Like the previous NewRWFile, but allows options to be specified. |
258 | | virtual CHECKED_STATUS NewRWFile(const RWFileOptions& opts, |
259 | | const std::string& fname, |
260 | | std::unique_ptr<RWFile>* result) = 0; |
261 | | |
262 | | // Returns true iff the named file exists. |
263 | | virtual bool FileExists(const std::string& fname) = 0; |
264 | | |
265 | | // Returns true if the named directory exists and is a directory. |
266 | | virtual bool DirExists(const std::string& dname) = 0; |
267 | | |
268 | | // Store in *result the names of the children of the specified directory. |
269 | | // The names are relative to "dir". |
270 | | // Original contents of *results are dropped. |
271 | | CHECKED_STATUS GetChildren(const std::string& dir, std::vector<std::string>* result); |
272 | | |
273 | | Result<std::vector<std::string>> GetChildren( |
274 | | const std::string& dir, ExcludeDots exclude_dots = ExcludeDots::kFalse); |
275 | | |
276 | | virtual CHECKED_STATUS GetChildren(const std::string& dir, ExcludeDots exclude_dots, |
277 | | std::vector<std::string>* result) = 0; |
278 | | |
279 | | // Delete the named file. |
280 | | virtual CHECKED_STATUS DeleteFile(const std::string& fname) = 0; |
281 | | |
282 | | // Create the specified directory. |
283 | | virtual CHECKED_STATUS CreateDir(const std::string& dirname) = 0; |
284 | | |
285 | | CHECKED_STATUS CreateDirs(const std::string& dirname); |
286 | | |
287 | | // Delete the specified directory. |
288 | | virtual CHECKED_STATUS DeleteDir(const std::string& dirname) = 0; |
289 | | |
290 | | // Synchronize the entry for a specific directory. |
291 | | virtual CHECKED_STATUS SyncDir(const std::string& dirname) = 0; |
292 | | |
293 | | // Recursively delete the specified directory. |
294 | | // This should operate safely, not following any symlinks, etc. |
295 | | virtual CHECKED_STATUS DeleteRecursively(const std::string &dirname) = 0; |
296 | | |
297 | | // Store the logical size of fname in *file_size. |
298 | | virtual Result<uint64_t> GetFileSize(const std::string& fname) = 0; |
299 | | |
300 | | virtual Result<uint64_t> GetFileINode(const std::string& fname) = 0; |
301 | | |
302 | | virtual CHECKED_STATUS LinkFile(const std::string& src, |
303 | | const std::string& target) = 0; |
304 | | |
305 | | // Read link's actual target |
306 | | virtual Result<std::string> ReadLink(const std::string& link) = 0; |
307 | | |
308 | | // Returns the physical size of fname. |
309 | | // |
310 | | // This differs from GetFileSize() in that it returns the actual amount |
311 | | // of space consumed by the file, not the user-facing file size. |
312 | | virtual Result<uint64_t> GetFileSizeOnDisk(const std::string& fname) = 0; |
313 | | |
314 | | // Returns the block size of the filesystem where fname resides. |
315 | | // fname must exist but it may be a file or a directory. |
316 | | virtual Result<uint64_t> GetBlockSize(const std::string& fname) = 0; |
317 | | |
318 | | // Rename file src to target. |
319 | | virtual CHECKED_STATUS RenameFile(const std::string& src, |
320 | | const std::string& target) = 0; |
321 | | |
322 | | // Lock the specified file. Used to prevent concurrent access to |
323 | | // the same db by multiple processes. On failure, stores NULL in |
324 | | // *lock and returns non-OK. |
325 | | // |
326 | | // On success, stores a pointer to the object that represents the |
327 | | // acquired lock in *lock and returns OK. The caller should call |
328 | | // UnlockFile(*lock) to release the lock. If the process exits, |
329 | | // the lock will be automatically released. |
330 | | // |
331 | | // If somebody else already holds the lock, finishes immediately |
332 | | // with a failure. I.e., this call does not wait for existing locks |
333 | | // to go away. |
334 | | // |
335 | | // If 'recursive_lock_ok' is true, then the existing process is allowed |
336 | | // to grab the lock on the same file multiple times. Note that a count of |
337 | | // how many times the lock is repeatedly grabbed on the same file is |
338 | | // NOT maintained. A single unlock will release the lock. |
339 | | // |
340 | | // May create the named file if it does not already exist. |
341 | | virtual CHECKED_STATUS LockFile(const std::string& fname, |
342 | | FileLock** lock, |
343 | | bool recursive_lock_ok) = 0; |
344 | | |
345 | | // Release the lock acquired by a previous successful call to LockFile. |
346 | | // REQUIRES: lock was returned by a successful LockFile() call |
347 | | // REQUIRES: lock has not already been unlocked. |
348 | | virtual CHECKED_STATUS UnlockFile(FileLock* lock) = 0; |
349 | | |
350 | | // *path is set to a temporary directory that can be used for testing. It may |
351 | | // or many not have just been created. The directory may or may not differ |
352 | | // between runs of the same process, but subsequent calls will return the |
353 | | // same directory. |
354 | | virtual CHECKED_STATUS GetTestDirectory(std::string* path) = 0; |
355 | | |
356 | | Result<std::string> GetTestDirectory(); |
357 | | |
358 | | // Returns the number of micro-seconds since some fixed point in time. Only |
359 | | // useful for computing deltas of time. |
360 | | virtual uint64_t NowMicros() = 0; |
361 | | |
362 | | // Returns the number of nano-seconds since some fixed point in time. Only |
363 | | // useful for computing deltas of time in one run. |
364 | | virtual uint64_t NowNanos() = 0; |
365 | | |
366 | | // Sleep/delay the thread for the perscribed number of micro-seconds. |
367 | | virtual void SleepForMicroseconds(int micros) = 0; |
368 | | |
369 | | // Get caller's thread id. |
370 | | virtual uint64_t gettid() = 0; |
371 | | |
372 | | // Return the full path of the currently running executable. |
373 | | virtual CHECKED_STATUS GetExecutablePath(std::string* path) = 0; |
374 | | |
375 | | // Checks if the file is a directory. Returns an error if it doesn't |
376 | | // exist, otherwise writes true or false into 'is_dir' appropriately. |
377 | | virtual CHECKED_STATUS IsDirectory(const std::string& path, bool* is_dir) = 0; |
378 | | |
379 | | Result<bool> IsDirectory(const std::string& path); |
380 | | |
381 | | // Like IsDirectory, but non-existence of the given path is not considered an error. |
382 | | Result<bool> DoesDirectoryExist(const std::string& path); |
383 | | |
384 | | // Checks if the given path is an executable file. If the file does not exist |
385 | | // we simply return false rather than consider that an error. |
386 | | virtual Result<bool> IsExecutableFile(const std::string& path) = 0; |
387 | | |
388 | | // The kind of file found during a walk. Note that symbolic links are |
389 | | // reported as FILE_TYPE. |
390 | | enum FileType { |
391 | | DIRECTORY_TYPE, |
392 | | FILE_TYPE, |
393 | | }; |
394 | | |
395 | | // Called for each file/directory in the walk. |
396 | | // |
397 | | // The first argument is the type of file. |
398 | | // The second is the dirname of the file. |
399 | | // The third is the basename of the file. |
400 | | // |
401 | | // Returning an error won't halt the walk, but it will cause it to return |
402 | | // with an error status when it's done. |
403 | | using WalkCallback = std::function<Status(FileType, const std::string&, const std::string&)>; |
404 | | |
405 | | // Whether to walk directories in pre-order or post-order. |
406 | | enum DirectoryOrder { |
407 | | PRE_ORDER, |
408 | | POST_ORDER, |
409 | | }; |
410 | | |
411 | | // Walk the filesystem subtree from 'root' down, invoking 'cb' for each |
412 | | // file or directory found, including 'root'. |
413 | | // |
414 | | // The walk will not cross filesystem boundaries. It won't change the |
415 | | // working directory, nor will it follow symbolic links. |
416 | | virtual CHECKED_STATUS Walk(const std::string& root, |
417 | | DirectoryOrder order, |
418 | | const WalkCallback& cb) = 0; |
419 | | |
420 | | // Canonicalize 'path' by applying the following conversions: |
421 | | // - Converts a relative path into an absolute one using the cwd. |
422 | | // - Converts '.' and '..' references. |
423 | | // - Resolves all symbolic links. |
424 | | // |
425 | | // All directory entries in 'path' must exist on the filesystem. |
426 | | virtual CHECKED_STATUS Canonicalize(const std::string& path, std::string* result) = 0; |
427 | | |
428 | | Result<std::string> Canonicalize(const std::string& path); |
429 | | |
430 | | // Get the total amount of RAM installed on this machine. |
431 | | virtual CHECKED_STATUS GetTotalRAMBytes(int64_t* ram) = 0; |
432 | | |
433 | | // Get free space available on the path's filesystem. |
434 | | virtual Result<uint64_t> GetFreeSpaceBytes(const std::string& path) = 0; |
435 | | |
436 | | struct FilesystemStats { |
437 | | uint64_t free_space; |
438 | | uint64_t used_space; |
439 | | uint64_t total_space; |
440 | | }; |
441 | | |
442 | | // Returns the stats of the filesystem where fname resides in bytes. |
443 | | virtual Result<FilesystemStats> GetFilesystemStatsBytes(const std::string& fname) = 0; |
444 | | |
445 | | // Get ulimit |
446 | | virtual Result<ResourceLimits> GetUlimit(int resource) = 0; |
447 | | |
448 | | // Set ulimit |
449 | | // Note that if running on macOS, the semantics of this API are a bit inconsistent across |
450 | | // versions. Namely, setrlimit in some versions for some resources will return success even if |
451 | | // the call did not change the resource limit to the desired value. This is specifically observed |
452 | | // on at least RLIM_NPROC, where constraints around number of processes are a bit more restrictive |
453 | | // than other POSIX systems. |
454 | | // See: https://apple.stackexchange.com/questions/373063/why-is-macos-limited-to-1064-processes |
455 | | virtual CHECKED_STATUS SetUlimit(int resource, ResourceLimit value) = 0; |
456 | | virtual CHECKED_STATUS SetUlimit( |
457 | | int resource, ResourceLimit value, const std::string& resource_name) = 0; |
458 | | |
459 | | virtual bool IsEncrypted() const = 0; |
460 | | |
461 | | private: |
462 | | // No copying allowed |
463 | | Env(const Env&); |
464 | | void operator=(const Env&); |
465 | | }; |
466 | | |
467 | | // Creation-time options for WritableFile |
468 | | struct WritableFileOptions { |
469 | | // Call Sync() during Close(). |
470 | | bool sync_on_close; |
471 | | |
472 | | bool o_direct; |
473 | | |
474 | | // See CreateMode for details. |
475 | | Env::CreateMode mode; |
476 | | |
477 | | WritableFileOptions() |
478 | | : sync_on_close(false), |
479 | | o_direct(false), |
480 | 1.23M | mode(Env::CREATE_IF_NON_EXISTING_TRUNCATE) { } |
481 | | }; |
482 | | |
483 | | // A file abstraction for sequential writing. The implementation |
484 | | // must provide buffering since callers may append small fragments |
485 | | // at a time to the file. |
486 | | class WritableFile { |
487 | | public: |
488 | | enum FlushMode { |
489 | | FLUSH_SYNC, |
490 | | FLUSH_ASYNC |
491 | | }; |
492 | | |
493 | 1.23M | WritableFile() { } |
494 | | virtual ~WritableFile(); |
495 | | |
496 | | // Pre-allocates 'size' bytes for the file in the underlying filesystem. |
497 | | // size bytes are added to the current pre-allocated size or to the current |
498 | | // offset, whichever is bigger. In no case is the file truncated by this |
499 | | // operation. |
500 | | virtual CHECKED_STATUS PreAllocate(uint64_t size) = 0; |
501 | | |
502 | | virtual CHECKED_STATUS Append(const Slice& data) = 0; |
503 | | |
504 | | // If possible, uses scatter-gather I/O to efficiently append |
505 | | // multiple buffers to a file. Otherwise, falls back to regular I/O. |
506 | | // |
507 | | // For implementation specific quirks and details, see comments in |
508 | | // implementation source code (e.g., env_posix.cc) |
509 | | CHECKED_STATUS AppendVector(const std::vector<Slice>& data_vector); |
510 | | |
511 | | virtual CHECKED_STATUS AppendSlices(const Slice* slices, size_t num) = 0; |
512 | | |
513 | | CHECKED_STATUS AppendSlices(const Slice* begin, const Slice* end); |
514 | | |
515 | | virtual CHECKED_STATUS Close() = 0; |
516 | | |
517 | | // Flush all dirty data (not metadata) to disk. |
518 | | // |
519 | | // If the flush mode is synchronous, will wait for flush to finish and |
520 | | // return a meaningful status. |
521 | | virtual CHECKED_STATUS Flush(FlushMode mode) = 0; |
522 | | |
523 | | virtual CHECKED_STATUS Sync() = 0; |
524 | | |
525 | | virtual uint64_t Size() const = 0; |
526 | | |
527 | | // Returns the filename provided when the WritableFile was constructed. |
528 | | virtual const std::string& filename() const = 0; |
529 | | |
530 | | private: |
531 | | // No copying allowed |
532 | | WritableFile(const WritableFile&); |
533 | | void operator=(const WritableFile&); |
534 | | }; |
535 | | |
536 | | // An implementation of WritableFile that forwards all calls to another |
537 | | // WritableFile. May be useful to clients who wish to override just part of the |
538 | | // functionality of another WritableFile. |
539 | | // It's declared as friend of WritableFile to allow forwarding calls to |
540 | | // protected virtual methods. |
541 | | class WritableFileWrapper : public WritableFile { |
542 | | public: |
543 | 1 | explicit WritableFileWrapper(std::unique_ptr<WritableFile> t) : target_(std::move(t)) { } |
544 | 1 | virtual ~WritableFileWrapper() { } |
545 | | |
546 | | // Return the target to which this WritableFile forwards all calls. |
547 | 0 | WritableFile* target() const { return target_.get(); } |
548 | | |
549 | | CHECKED_STATUS PreAllocate(uint64_t size) override; |
550 | | CHECKED_STATUS Append(const Slice& data) override; |
551 | | CHECKED_STATUS AppendSlices(const Slice* slices, size_t num) override; |
552 | | CHECKED_STATUS Close() override; |
553 | | CHECKED_STATUS Flush(FlushMode mode) override; |
554 | | CHECKED_STATUS Sync() override; |
555 | 11 | uint64_t Size() const override { return target_->Size(); } |
556 | 0 | const std::string& filename() const override { return target_->filename(); } |
557 | | |
558 | | private: |
559 | | std::unique_ptr<WritableFile> target_; |
560 | | }; |
561 | | |
562 | | // Creation-time options for RWFile |
563 | | struct RWFileOptions { |
564 | | // Call Sync() during Close(). |
565 | | bool sync_on_close; |
566 | | |
567 | | // See CreateMode for details. |
568 | | Env::CreateMode mode; |
569 | | |
570 | | RWFileOptions() |
571 | | : sync_on_close(false), |
572 | 4 | mode(Env::CREATE_IF_NON_EXISTING_TRUNCATE) { } |
573 | | }; |
574 | | |
575 | | // A file abstraction for both reading and writing. No notion of a built-in |
576 | | // file offset is ever used; instead, all operations must provide an |
577 | | // explicit offset. |
578 | | // |
579 | | // All "read" operations are safe for concurrent use by multiple threads, |
580 | | // but "write" operations must be externally synchronized. |
581 | | class RWFile { |
582 | | public: |
583 | | enum FlushMode { |
584 | | FLUSH_SYNC, |
585 | | FLUSH_ASYNC |
586 | | }; |
587 | | |
588 | 4 | RWFile() { |
589 | 4 | } |
590 | | |
591 | | virtual ~RWFile(); |
592 | | |
593 | | // Read exactly 'length' bytes from the file starting at 'offset'. |
594 | | // 'scratch[0..length-1]' may be written by this routine. Sets '*result' |
595 | | // to the data that was read. May set '*result' to point at data in |
596 | | // 'scratch[0..length-1]', which must be live when '*result' is used. |
597 | | // If an error was encountered, returns a non-OK status. |
598 | | // |
599 | | // In the event of a "short read" (fewer bytes read than were requested), |
600 | | // an IOError is returned. |
601 | | // |
602 | | // Safe for concurrent use by multiple threads. |
603 | | virtual CHECKED_STATUS Read(uint64_t offset, size_t length, |
604 | | Slice* result, uint8_t* scratch) const = 0; |
605 | | |
606 | | // Writes 'data' to the file position given by 'offset'. |
607 | | virtual CHECKED_STATUS Write(uint64_t offset, const Slice& data) = 0; |
608 | | |
609 | | // Preallocates 'length' bytes for the file in the underlying filesystem |
610 | | // beginning at 'offset'. It is safe to preallocate the same range |
611 | | // repeatedly; this is an idempotent operation. |
612 | | // |
613 | | // In no case is the file truncated by this operation. |
614 | | virtual CHECKED_STATUS PreAllocate(uint64_t offset, size_t length) = 0; |
615 | | |
616 | | // Deallocates space given by 'offset' and length' from the file, |
617 | | // effectively "punching a hole" in it. The space will be reclaimed by |
618 | | // the filesystem and reads to that range will return zeroes. Useful |
619 | | // for making whole files sparse. |
620 | | // |
621 | | // Filesystems that don't implement this will return an error. |
622 | | virtual CHECKED_STATUS PunchHole(uint64_t offset, size_t length) = 0; |
623 | | |
624 | | // Flushes the range of dirty data (not metadata) given by 'offset' and |
625 | | // 'length' to disk. If length is 0, all bytes from 'offset' to the end |
626 | | // of the file are flushed. |
627 | | // |
628 | | // If the flush mode is synchronous, will wait for flush to finish and |
629 | | // return a meaningful status. |
630 | | virtual CHECKED_STATUS Flush(FlushMode mode, uint64_t offset, size_t length) = 0; |
631 | | |
632 | | // Synchronously flushes all dirty file data and metadata to disk. Upon |
633 | | // returning successfully, all previously issued file changes have been |
634 | | // made durable. |
635 | | virtual CHECKED_STATUS Sync() = 0; |
636 | | |
637 | | // Closes the file, optionally calling Sync() on it if the file was |
638 | | // created with the sync_on_close option enabled. |
639 | | virtual CHECKED_STATUS Close() = 0; |
640 | | |
641 | | // Retrieves the file's size. |
642 | | virtual CHECKED_STATUS Size(uint64_t* size) const = 0; |
643 | | |
644 | | // Returns the filename provided when the RWFile was constructed. |
645 | | virtual const std::string& filename() const = 0; |
646 | | |
647 | | private: |
648 | | DISALLOW_COPY_AND_ASSIGN(RWFile); |
649 | | }; |
650 | | |
651 | | // Identifies a locked file. |
652 | | class FileLock { |
653 | | public: |
654 | 8.45k | FileLock() { } |
655 | | virtual ~FileLock(); |
656 | | private: |
657 | | // No copying allowed |
658 | | FileLock(const FileLock&); |
659 | | void operator=(const FileLock&); |
660 | | }; |
661 | | |
662 | | // A utility routine: write "data" to the named file. |
663 | | extern CHECKED_STATUS WriteStringToFile(Env* env, const Slice& data, const std::string& fname); |
664 | | |
665 | | extern CHECKED_STATUS WriteStringToFileSync(Env* env, const Slice& data, const std::string& fname); |
666 | | |
667 | | |
668 | | // A utility routine: read contents of named file into *data |
669 | | extern CHECKED_STATUS ReadFileToString(Env* env, const std::string& fname, |
670 | | faststring* data); |
671 | | |
672 | | // An implementation of Env that forwards all calls to another Env. |
673 | | // May be useful to clients who wish to override just part of the |
674 | | // functionality of another Env. |
675 | | class EnvWrapper : public Env { |
676 | | public: |
677 | | // Initialize an EnvWrapper that delegates all calls to *t |
678 | 1.31k | explicit EnvWrapper(Env* t) : target_(t) { } |
679 | | virtual ~EnvWrapper(); |
680 | | |
681 | | // Return the target to which this Env forwards all calls |
682 | 0 | Env* target() const { return target_; } |
683 | | |
684 | | // The following text is boilerplate that forwards all methods to target() |
685 | | CHECKED_STATUS NewSequentialFile(const std::string& f, |
686 | | std::unique_ptr<SequentialFile>* r) override; |
687 | | CHECKED_STATUS NewRandomAccessFile(const std::string& f, |
688 | | std::unique_ptr<RandomAccessFile>* r) override; |
689 | | CHECKED_STATUS NewWritableFile(const std::string& f, std::unique_ptr<WritableFile>* r) override; |
690 | | CHECKED_STATUS NewWritableFile(const WritableFileOptions& o, |
691 | | const std::string& f, |
692 | | std::unique_ptr<WritableFile>* r) override; |
693 | | CHECKED_STATUS NewTempWritableFile(const WritableFileOptions& o, const std::string& t, |
694 | | std::string* f, std::unique_ptr<WritableFile>* r) override; |
695 | | CHECKED_STATUS NewRWFile(const std::string& f, std::unique_ptr<RWFile>* r) override; |
696 | | CHECKED_STATUS NewRWFile(const RWFileOptions& o, |
697 | | const std::string& f, |
698 | | std::unique_ptr<RWFile>* r) override; |
699 | 4.06k | bool FileExists(const std::string& f) override { return target_->FileExists(f); } |
700 | 6 | bool DirExists(const std::string& d) override { return target_->DirExists(d); } |
701 | | CHECKED_STATUS GetChildren( |
702 | | const std::string& dir, ExcludeDots exclude_dots, std::vector<std::string>* r) override; |
703 | | CHECKED_STATUS DeleteFile(const std::string& f) override; |
704 | | CHECKED_STATUS CreateDir(const std::string& d) override; |
705 | | CHECKED_STATUS SyncDir(const std::string& d) override; |
706 | | CHECKED_STATUS DeleteDir(const std::string& d) override; |
707 | | CHECKED_STATUS DeleteRecursively(const std::string& d) override; |
708 | | Result<uint64_t> GetFileSize(const std::string& f) override; |
709 | | Result<uint64_t> GetFileINode(const std::string& f) override; |
710 | | Result<uint64_t> GetFileSizeOnDisk(const std::string& f) override; |
711 | | Result<uint64_t> GetBlockSize(const std::string& f) override; |
712 | | Result<FilesystemStats> GetFilesystemStatsBytes(const std::string& f) override; |
713 | | CHECKED_STATUS LinkFile(const std::string& s, const std::string& t) override; |
714 | | Result<std::string> ReadLink(const std::string& s) override; |
715 | | CHECKED_STATUS RenameFile(const std::string& s, const std::string& t) override; |
716 | | CHECKED_STATUS LockFile(const std::string& f, FileLock** l, bool r) override; |
717 | | CHECKED_STATUS UnlockFile(FileLock* l) override; |
718 | | virtual CHECKED_STATUS GetTestDirectory(std::string* path) override; |
719 | | |
720 | 0 | uint64_t NowMicros() override { |
721 | 0 | return target_->NowMicros(); |
722 | 0 | } |
723 | | |
724 | 0 | uint64_t NowNanos() override { |
725 | 0 | return target_->NowNanos(); |
726 | 0 | } |
727 | | |
728 | 0 | void SleepForMicroseconds(int micros) override { |
729 | 0 | target_->SleepForMicroseconds(micros); |
730 | 0 | } |
731 | | |
732 | 0 | uint64_t gettid() override { |
733 | 0 | return target_->gettid(); |
734 | 0 | } |
735 | | |
736 | | CHECKED_STATUS GetExecutablePath(std::string* path) override; |
737 | | CHECKED_STATUS IsDirectory(const std::string& path, bool* is_dir) override; |
738 | | Result<bool> IsExecutableFile(const std::string& path) override; |
739 | | CHECKED_STATUS Walk(const std::string& root, |
740 | | DirectoryOrder order, |
741 | | const WalkCallback& cb) override; |
742 | | CHECKED_STATUS Canonicalize(const std::string& path, std::string* result) override; |
743 | | CHECKED_STATUS GetTotalRAMBytes(int64_t* ram) override; |
744 | | Result<uint64_t> GetFreeSpaceBytes(const std::string& path) override; |
745 | | Result<ResourceLimits> GetUlimit(int resource) override; |
746 | | CHECKED_STATUS SetUlimit(int resource, ResourceLimit value) override; |
747 | | CHECKED_STATUS SetUlimit( |
748 | | int resource, ResourceLimit value, const std::string& resource_name) override; |
749 | | |
750 | 0 | bool IsEncrypted() const override { |
751 | 0 | return target_->IsEncrypted(); |
752 | 0 | } |
753 | | |
754 | | private: |
755 | | Env* target_; |
756 | | }; |
757 | | |
758 | | CHECKED_STATUS DeleteIfExists(const std::string& path, Env* env); |
759 | | |
760 | | } // namespace yb |
761 | | |
762 | | #endif // YB_UTIL_ENV_H |