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