-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsnowid_checkpoint.c
104 lines (81 loc) · 2.88 KB
/
snowid_checkpoint.c
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/**
*
* MIT License
*
* Copyright (c) 2022 beyonddream
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "snowid_checkpoint.h"
#include "snowid_util.h"
#define CHECKPOINT_PERIOD_SECS 2
static void snow_checkpoint_periodic(char *timestamp_path);
static void snow_checkpoint_periodic(char *timestamp_path)
{
int fd;
uint64_t buf[1];
if ((fd = open(timestamp_path, O_WRONLY)) == -1) {
_exit(1);
}
uint64_t checkpoint;
for(;;) {
/* check if child is reparented to init(1), if so then exit. */
/* XXX - may not guarenteed to work if reparent is not pid == 1 */
if (getppid() == 1) {
_exit(0);
}
if (get_current_ts(&checkpoint) == false) {
continue;
}
buf[0] = checkpoint;
/* XXX - ignore lseek() errors - it may recover during next try (: */
if (lseek(fd, 0, SEEK_SET) == -1) {
continue;
}
/* XXX - ignore write() errors - it may recover during next try (: */
if (write(fd, buf, 1) != -1) {
/* XXX - ignore fsync() errors - it may recover during next try (: */
fsync(fd);
}
sleep(CHECKPOINT_PERIOD_SECS);
}
_exit(1);
}
bool snow_checkpoint_start(char *timestamp_path)
{
if (timestamp_path == NULL) {
fprintf(stderr, "snow_checkpoint_start():timestamp_path is NULL.");
return false;
}
if (access(timestamp_path, W_OK) != 0) {
perror("snow_checkpoint_start():error while checking access to `timestamp_path`.");
return false;
}
int pid = fork();
if (pid < 0) {
perror("snow_checkpoint_start():Call to fork failed.");
return false;
}
/* child */
if (pid == 0) {
snow_checkpoint_periodic(timestamp_path);
}
return true;
}