@cryptotaxi247 / netdata-1 / commits / dee923850

Support falling back to buffered I/O when direct I/O is unavailable (#6174)

Markos Fountoulakis committed Jun 3, 2019 at 15:26 UTC dee923850b3ff9b921ed657fe5f8736732b06645
4 files changed +47 -36
database/engine/datafile.c
+2 -18
@@ -100,18 +100,10 @@ int create_data_file(struct rrdengine_datafile *datafile)
100 char path[1024];
101
102 generate_datafilepath(datafile, path, sizeof(path));
103 - fd = uv_fs_open(NULL, &req, path, O_DIRECT | O_CREAT | O_RDWR | O_TRUNC,
104 - S_IRUSR | S_IWUSR, NULL);
103 + fd = open_file_direct_io(path, O_CREAT | O_RDWR | O_TRUNC, &file);
104 if (fd < 0) {
105 fatal("uv_fs_fsopen: %s", uv_strerror(fd));
106 }
108 - assert(req.result >= 0);
109 - file = req.result;
110 - uv_fs_req_cleanup(&req);
111 -#ifdef __APPLE__
112 - info("Disabling OS X caching for file \"%s\".", path);
113 - fcntl(fd, F_NOCACHE, 1);
114 -#endif
107
108 ret = posix_memalign((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
109 if (unlikely(ret)) {
@@ -187,20 +179,12 @@ static int load_data_file(struct rrdengine_datafile *datafile)
179 char path[1024];
180
181 generate_datafilepath(datafile, path, sizeof(path));
190 - fd = uv_fs_open(NULL, &req, path, O_DIRECT | O_RDWR, S_IRUSR | S_IWUSR, NULL);
182 + fd = open_file_direct_io(path, O_RDWR, &file);
183 if (fd < 0) {
184 /* if (UV_ENOENT != fd) */
185 error("uv_fs_fsopen: %s", uv_strerror(fd));
194 - uv_fs_req_cleanup(&req);
186 return fd;
187 }
197 - assert(req.result >= 0);
198 - file = req.result;
199 - uv_fs_req_cleanup(&req);
200 -#ifdef __APPLE__
201 - info("Disabling OS X caching for file \"%s\".", path);
202 - fcntl(fd, F_NOCACHE, 1);
203 -#endif
188 info("Initializing data file \"%s\".", path);
189
190 ret = check_file_properties(file, &file_size, sizeof(struct rrdeng_df_sb));
database/engine/journalfile.c
+2 -18
@@ -146,18 +146,10 @@ int create_journal_file(struct rrdengine_journalfile *journalfile, struct rrdeng
146 char path[1024];
147
148 generate_journalfilepath(datafile, path, sizeof(path));
149 - fd = uv_fs_open(NULL, &req, path, O_DIRECT | O_CREAT | O_RDWR | O_TRUNC,
150 - S_IRUSR | S_IWUSR, NULL);
149 + fd = open_file_direct_io(path, O_CREAT | O_RDWR | O_TRUNC, &file);
150 if (fd < 0) {
151 fatal("uv_fs_fsopen: %s", uv_strerror(fd));
152 }
154 - assert(req.result >= 0);
155 - file = req.result;
156 - uv_fs_req_cleanup(&req);
157 -#ifdef __APPLE__
158 - info("Disabling OS X caching for file \"%s\".", path);
159 - fcntl(fd, F_NOCACHE, 1);
160 -#endif
153
154 ret = posix_memalign((void *)&superblock, RRDFILE_ALIGNMENT, sizeof(*superblock));
155 if (unlikely(ret)) {
@@ -411,20 +403,12 @@ int load_journal_file(struct rrdengine_instance *ctx, struct rrdengine_journalfi
403 char path[1024];
404
405 generate_journalfilepath(datafile, path, sizeof(path));
414 - fd = uv_fs_open(NULL, &req, path, O_DIRECT | O_RDWR, S_IRUSR | S_IWUSR, NULL);
406 + fd = open_file_direct_io(path, O_RDWR, &file);
407 if (fd < 0) {
408 /* if (UV_ENOENT != fd) */
409 error("uv_fs_fsopen: %s", uv_strerror(fd));
418 - uv_fs_req_cleanup(&req);
410 return fd;
411 }
421 - assert(req.result >= 0);
422 - file = req.result;
423 - uv_fs_req_cleanup(&req);
424 -#ifdef __APPLE__
425 - info("Disabling OS X caching for file \"%s\".", path);
426 - fcntl(fd, F_NOCACHE, 1);
427 -#endif
412 info("Loading journal file \"%s\".", path);
413
414 ret = check_file_properties(file, &file_size, sizeof(struct rrdeng_df_sb));
database/engine/rrdenginelib.c
+42
@@ -78,6 +78,48 @@ int check_file_properties(uv_file file, uint64_t *file_size, size_t min_size)
78 return 0;
79 }
80
81 +/*
82 + * Tries to open a file in direct I/O mode, falls back to buffered mode if not possible.
83 + * Returns UV error number that is < 0 on failure.
84 + * On success sets (*file) to be the uv_file that was opened.
85 + */
86 +int open_file_direct_io(char *path, int flags, uv_file *file)
87 +{
88 + uv_fs_t req;
89 + int fd, current_flags, direct;
90 +
91 + for (direct = 1 ; direct >= 0 ; --direct) {
92 +#ifdef __APPLE__
93 + /* Apple OS does not support O_DIRECT */
94 + direct = 0;
95 +#endif
96 + current_flags = flags;
97 + if (direct) {
98 + current_flags |= O_DIRECT;
99 + }
100 + fd = uv_fs_open(NULL, &req, path, current_flags, S_IRUSR | S_IWUSR, NULL);
101 + if (fd < 0) {
102 + if ((direct) && (UV_EINVAL == fd)) {
103 + error("File \"%s\" does not support direct I/O, falling back to buffered I/O.", path);
104 + } else {
105 + error("Failed to open file \"%s\".", path);
106 + return fd;
107 + }
108 + } else {
109 + assert(req.result >= 0);
110 + *file = req.result;
111 +#ifdef __APPLE__
112 + info("Disabling OS X caching for file \"%s\".", path);
113 + fcntl(fd, F_NOCACHE, 1);
114 +#endif
115 + --direct; /* break the loop */
116 + }
117 + uv_fs_req_cleanup(&req);
118 + }
119 +
120 + return fd;
121 +}
122 +
123 char *get_rrdeng_statistics(struct rrdengine_instance *ctx, char *str, size_t size)
124 {
125 struct page_cache *pg_cache;
database/engine/rrdenginelib.h
+1
@@ -93,6 +93,7 @@ static inline void crc32set(void *crcp, uLong crc)
93 extern void print_page_cache_descr(struct rrdeng_page_descr *page_cache_descr);
94 extern void print_page_descr(struct rrdeng_page_descr *descr);
95 extern int check_file_properties(uv_file file, uint64_t *file_size, size_t min_size);
96 +extern int open_file_direct_io(char *path, int flags, uv_file *file);
97 extern char *get_rrdeng_statistics(struct rrdengine_instance *ctx, char *str, size_t size);
98
99 #endif /* NETDATA_RRDENGINELIB_H */
\ No newline at end of file