master
c 78 lines 2.27 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2 #include "rrdengine.h"
3
4 int check_file_properties(uv_file file, uint64_t *file_size, size_t min_size)
5 {
6 int ret;
7 uv_fs_t req;
8 uv_stat_t* s;
9
10 ret = uv_fs_fstat(NULL, &req, file, NULL);
11 if (ret < 0) {
12 fatal("uv_fs_fstat: %s\n", uv_strerror(ret));
13 }
14 fatal_assert(req.result == 0);
15 s = req.ptr;
16 if (!(s->st_mode & S_IFREG)) {
17 netdata_log_error("Not a regular file.\n");
18 uv_fs_req_cleanup(&req);
19 return UV_EINVAL;
20 }
21 if (s->st_size < min_size) {
22 netdata_log_error("File length is too short.\n");
23 uv_fs_req_cleanup(&req);
24 return UV_EINVAL;
25 }
26 *file_size = s->st_size;
27 uv_fs_req_cleanup(&req);
28
29 return 0;
30 }
31
32 /**
33 * Open file for I/O.
34 *
35 * @param path The full path of the file.
36 * @param flags Same flags as the open() system call uses.
37 * @param file On success sets (*file) to be the uv_file that was opened.
38 * @param direct Tries to open a file in direct I/O mode when direct=1, falls back to buffered mode if not possible.
39 * @return Returns UV error number that is < 0 on failure. 0 on success.
40 */
41 int open_file_for_io(char *path, int flags, uv_file *file, int direct)
42 {
43 uv_fs_t req;
44 int fd = -1, current_flags;
45
46 fatal_assert(0 == direct || 1 == direct);
47 for ( ; direct >= 0 ; --direct) {
48 #ifdef __APPLE__
49 /* Apple OS does not support O_DIRECT */
50 direct = 0;
51 #endif
52 current_flags = flags;
53 if (direct) {
54 current_flags |= O_DIRECT;
55 }
56 fd = uv_fs_open(NULL, &req, path, current_flags, S_IRUSR | S_IWUSR, NULL);
57 if (fd < 0) {
58 if ((direct) && (UV_EINVAL == fd)) {
59 netdata_log_error("File \"%s\" does not support direct I/O, falling back to buffered I/O.", path);
60 } else {
61 netdata_log_error("Failed to open file \"%s\".", path);
62 --direct; /* break the loop */
63 }
64 } else {
65 fatal_assert(req.result >= 0);
66 *file = req.result;
67 #ifdef __APPLE__
68 netdata_log_info("Disabling OS X caching for file \"%s\".", path);
69 fcntl(fd, F_NOCACHE, 1);
70 #endif
71 --direct; /* break the loop */
72 }
73 uv_fs_req_cleanup(&req);
74 }
75
76 return fd;
77 }
78