YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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