/Users/deen/code/yugabyte-db/src/yb/util/path_util.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. 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 | | // The following only applies to changes made to this file as part of YugaByte development. |
19 | | // |
20 | | // Portions Copyright (c) YugaByte, Inc. |
21 | | // |
22 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
23 | | // in compliance with the License. You may obtain a copy of the License at |
24 | | // |
25 | | // http://www.apache.org/licenses/LICENSE-2.0 |
26 | | // |
27 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
28 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
29 | | // or implied. See the License for the specific language governing permissions and limitations |
30 | | // under the License. |
31 | | // |
32 | | |
33 | | #include "yb/util/path_util.h" |
34 | | |
35 | | // Use the POSIX version of dirname(3). |
36 | | #include <libgen.h> |
37 | | #include <fcntl.h> |
38 | | |
39 | | #include <string> |
40 | | #if defined(__APPLE__) |
41 | | #include <sys/param.h> |
42 | | #endif // defined(__APPLE__) |
43 | | |
44 | | #if defined(__linux__) |
45 | | #include <linux/falloc.h> |
46 | | #include <sys/sysinfo.h> |
47 | | #endif |
48 | | |
49 | | #include <glog/logging.h> |
50 | | |
51 | | #include "yb/util/env_util.h" |
52 | | #include "yb/util/errno.h" |
53 | | #include "yb/util/logging.h" |
54 | | #include "yb/util/malloc.h" |
55 | | #include "yb/util/thread_restrictions.h" |
56 | | |
57 | | using std::string; |
58 | | |
59 | | namespace yb { |
60 | | |
61 | | static const char* const kTmpTemplateSuffix = ".tmp.XXXXXX"; |
62 | | |
63 | 11.0M | void AppendPathSegments(std::string* out, const std::string &b) { |
64 | 936 | CHECK(!out->empty()) << "empty first component: " << *out; |
65 | 18.4E | CHECK(!b.empty() && b[0] != '/') |
66 | 18.4E | << "second path component must be non-empty and relative: " |
67 | 18.4E | << b; |
68 | 11.0M | if ((*out)[out->size() - 1] != '/') { |
69 | 11.0M | *out += '/'; |
70 | 11.0M | } |
71 | 11.0M | *out += b; |
72 | 11.0M | } |
73 | | |
74 | 0 | Status FileCreationError(const std::string& path_dir, int err_number) { |
75 | 0 | switch (err_number) { |
76 | 0 | case EACCES: FALLTHROUGH_INTENDED; |
77 | 0 | case EPERM: FALLTHROUGH_INTENDED; |
78 | 0 | case EINVAL: |
79 | 0 | return STATUS(NotSupported, path_dir, Errno(err_number)); |
80 | 0 | } |
81 | 0 | return Status::OK(); |
82 | 0 | } |
83 | | |
84 | 3.91M | string DirName(const string& path) { |
85 | 3.91M | #if defined(__APPLE__) |
86 | 3.91M | char buffer[MAXPATHLEN]; |
87 | 3.91M | return dirname_r(path.c_str(), buffer); |
88 | | #else |
89 | | std::unique_ptr<char[], FreeDeleter> path_copy(strdup(path.c_str())); |
90 | | return dirname(path_copy.get()); |
91 | | #endif // defined(__APPLE__) |
92 | 3.91M | } |
93 | | |
94 | 377k | string BaseName(const string& path) { |
95 | 377k | #if defined(__APPLE__) |
96 | 377k | char buffer[MAXPATHLEN]; |
97 | 377k | return basename_r(path.c_str(), buffer); |
98 | | #else |
99 | | std::unique_ptr<char[], FreeDeleter> path_copy(strdup(path.c_str())); |
100 | | return basename(path_copy.get()); |
101 | | #endif |
102 | 377k | } |
103 | | |
104 | 2.63M | std::string GetYbDataPath(const std::string& root) { |
105 | 2.63M | return JoinPathSegments(root, "yb-data"); |
106 | 2.63M | } |
107 | | |
108 | | std::string GetServerTypeDataPath( |
109 | 2.61M | const std::string& root, const std::string& server_type) { |
110 | 2.61M | return JoinPathSegments(GetYbDataPath(root), server_type); |
111 | 2.61M | } |
112 | | |
113 | | Status SetupRootDir( |
114 | | Env* env, const std::string& root, const std::string& server_type, std::string* out_dir, |
115 | 13.1k | bool* created) { |
116 | 13.1k | RETURN_NOT_OK_PREPEND(env_util::CreateDirIfMissing(env, root, created), |
117 | 13.1k | "Unable to create FS path component " + root); |
118 | 13.1k | *out_dir = GetYbDataPath(root); |
119 | 13.1k | RETURN_NOT_OK_PREPEND(env_util::CreateDirIfMissing(env, *out_dir, created), |
120 | 13.1k | "Unable to create FS path component " + *out_dir); |
121 | 13.1k | *out_dir = GetServerTypeDataPath(root, server_type); |
122 | 13.1k | RETURN_NOT_OK_PREPEND(env_util::CreateDirIfMissing(env, *out_dir, created), |
123 | 13.1k | "Unable to create FS path component " + *out_dir); |
124 | 13.1k | return Status::OK(); |
125 | 13.1k | } |
126 | | |
127 | | Status CheckODirectTempFileCreationInDir(Env* env, |
128 | 123 | const std::string& dir_path) { |
129 | 123 | std::string name_template; |
130 | 123 | if (!dir_path.empty() && dir_path.back() == '/') { |
131 | 0 | name_template = dir_path + kTmpTemplateSuffix; |
132 | 123 | } else { |
133 | 123 | name_template = dir_path + '/' + kTmpTemplateSuffix; |
134 | 123 | } |
135 | 123 | ThreadRestrictions::AssertIOAllowed(); |
136 | 123 | std::unique_ptr<char[]> fname(new char[name_template.size() + 1]); |
137 | 123 | ::snprintf(fname.get(), name_template.size() + 1, "%s", name_template.c_str()); |
138 | | #if defined(__linux__) |
139 | | int fd = -1; |
140 | | fd = ::mkostemp(fname.get(), O_DIRECT); |
141 | | |
142 | | if (fd < 0) { |
143 | | return FileCreationError(dir_path, errno); |
144 | | } |
145 | | |
146 | | if (unlink(fname.get()) != 0) { |
147 | | return FileCreationError(dir_path, errno); |
148 | | } |
149 | | #endif |
150 | 123 | return Status::OK(); |
151 | 123 | } |
152 | | } // namespace yb |