Gentoo Archives: gentoo-commits

From: William Hubbs <williamh@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/openrc:master commit in: src/librc/
Date: Thu, 30 Nov 2017 19:58:16
Message-Id: 1512071814.a7c99506d9de81b9a2a7547bd11715073de1ce95.williamh@OpenRC
1 commit: a7c99506d9de81b9a2a7547bd11715073de1ce95
2 Author: Will Miles <wmiles <AT> sgl <DOT> com>
3 AuthorDate: Thu Aug 24 01:53:16 2017 +0000
4 Commit: William Hubbs <williamh <AT> gentoo <DOT> org>
5 CommitDate: Thu Nov 30 19:56:54 2017 +0000
6 URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=a7c99506
7
8 Fix repeated dependency cache rebuild if clock skewed
9
10 rc_deptree_update_needed would return early as soon as it found
11 any file newer than the existing dependency cache. Unfortunately,
12 the first file found may not be the newest one there; so the
13 clock skew workaround in rc-misc:_rc_deptree_load would be given
14 a timestamp that was still too old.
15
16 This fix forces a full scan of all relevant files, so as to
17 ensure that we return a timestamp that will allow the clock skew
18 fix to operate. The runtime cost is no worse than the case where
19 the cache is up to date (ie. we must check every possible file).
20
21 This fixes #161.
22
23 src/librc/librc-depend.c | 123 +++++++++++++++++++++++++++--------------------
24 1 file changed, 71 insertions(+), 52 deletions(-)
25
26 diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c
27 index 1c993998..37f0b60d 100644
28 --- a/src/librc/librc-depend.c
29 +++ b/src/librc/librc-depend.c
30 @@ -542,52 +542,41 @@ rc_deptree_order(const RC_DEPTREE *deptree, const char *runlevel, int options)
31 }
32 librc_hidden_def(rc_deptree_order)
33
34 +
35 +/* Given a time, recurse the target path to find out if there are
36 + any older (or newer) files. If false, sets the time to the
37 + oldest (or newest) found.
38 +*/
39 static bool
40 -mtime_check(const char *source, const char *target, bool newer,
41 +deep_mtime_check(const char *target, bool newer,
42 time_t *rel, char *file)
43 {
44 struct stat buf;
45 - time_t mtime;
46 bool retval = true;
47 DIR *dp;
48 struct dirent *d;
49 char path[PATH_MAX];
50 int serrno = errno;
51
52 - /* We have to exist */
53 - if (stat(source, &buf) != 0)
54 - return false;
55 - mtime = buf.st_mtime;
56 -
57 /* If target does not exist, return true to mimic shell test */
58 if (stat(target, &buf) != 0)
59 return true;
60
61 if (newer) {
62 - if (mtime < buf.st_mtime) {
63 - if (rel == NULL)
64 - return false;
65 + if (*rel < buf.st_mtime) {
66 retval = false;
67 - }
68 - if (rel != NULL) {
69 - if (*rel < buf.st_mtime) {
70 - if (file)
71 - strlcpy(file, target, PATH_MAX);
72 - *rel = buf.st_mtime;
73 - }
74 +
75 + if (file)
76 + strlcpy(file, target, PATH_MAX);
77 + *rel = buf.st_mtime;
78 }
79 } else {
80 - if (mtime > buf.st_mtime) {
81 - if (rel == NULL)
82 - return false;
83 + if (*rel > buf.st_mtime) {
84 retval = false;
85 - }
86 - if (rel != NULL) {
87 - if (*rel > buf.st_mtime) {
88 - if (file)
89 - strlcpy(file, target, PATH_MAX);
90 - *rel = buf.st_mtime;
91 - }
92 +
93 + if (file)
94 + strlcpy(file, target, PATH_MAX);
95 + *rel = buf.st_mtime;
96 }
97 }
98
99 @@ -602,16 +591,38 @@ mtime_check(const char *source, const char *target, bool newer,
100 if (d->d_name[0] == '.')
101 continue;
102 snprintf(path, sizeof(path), "%s/%s", target, d->d_name);
103 - if (!mtime_check(source, path, newer, rel, file)) {
104 + if (!deep_mtime_check(path, newer, rel, file)) {
105 retval = false;
106 - if (rel == NULL)
107 - break;
108 }
109 }
110 closedir(dp);
111 return retval;
112 }
113
114 +/* Recursively check if target is older/newer than source.
115 + * If false, return the filename and most different time (if
116 + * the return value arguments are non-null).
117 + */
118 +static bool
119 +mtime_check(const char *source, const char *target, bool newer,
120 + time_t *rel, char *file)
121 +{
122 + struct stat buf;
123 + time_t mtime;
124 + bool retval = true;
125 +
126 + /* We have to exist */
127 + if (stat(source, &buf) != 0)
128 + return false;
129 + mtime = buf.st_mtime;
130 +
131 + retval = deep_mtime_check(target,newer,&mtime,file);
132 + if (rel) {
133 + *rel = mtime;
134 + }
135 + return retval;
136 +}
137 +
138 bool
139 rc_newer_than(const char *source, const char *target,
140 time_t *newest, char *file)
141 @@ -670,6 +681,8 @@ rc_deptree_update_needed(time_t *newest, char *file)
142 RC_STRINGLIST *config;
143 RC_STRING *s;
144 int i;
145 + struct stat buf;
146 + time_t mtime;
147
148 /* Create base directories if needed */
149 for (i = 0; depdirs[i]; i++)
150 @@ -677,42 +690,48 @@ rc_deptree_update_needed(time_t *newest, char *file)
151 fprintf(stderr, "mkdir `%s': %s\n", depdirs[i], strerror(errno));
152
153 /* Quick test to see if anything we use has changed and we have
154 - * data in our deptree */
155 - if (!existss(RC_DEPTREE_CACHE))
156 - return true;
157 - if (!rc_newer_than(RC_DEPTREE_CACHE, RC_INITDIR, newest, file))
158 - return true;
159 - if (!rc_newer_than(RC_DEPTREE_CACHE, RC_CONFDIR, newest, file))
160 - return true;
161 + * data in our deptree. */
162 +
163 + if (stat(RC_DEPTREE_CACHE, &buf) == 0) {
164 + mtime = buf.st_mtime;
165 + } else {
166 + /* No previous cache found.
167 + * We still run the scan, in case of clock skew; we still need to return
168 + * the newest time.
169 + */
170 + newer = true;
171 + mtime = time(NULL);
172 + }
173 +
174 + newer |= !deep_mtime_check(RC_INITDIR,true,&mtime,file);
175 + newer |= !deep_mtime_check(RC_CONFDIR,true,&mtime,file);
176 #ifdef RC_PKG_INITDIR
177 - if (!rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_INITDIR, newest, file))
178 - return true;
179 + newer |= !deep_mtime_check(RC_PKG_INITDIR,true,&mtime,file);
180 #endif
181 #ifdef RC_PKG_CONFDIR
182 - if (!rc_newer_than(RC_DEPTREE_CACHE, RC_PKG_CONFDIR, newest, file))
183 - return true;
184 + newer |= !deep_mtime_check(RC_PKG_CONFDIR,true,&mtime,file);
185 #endif
186 -#ifdef RC_LOCAL_INITDIR
187 - if (!rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_INITDIR, newest, file))
188 - return true;
189 +#ifdef RC_LOCAL_INITDIRs
190 + newer |= !deep_mtime_check(RC_LOCAL_INITDIR,true,&mtime,file);
191 #endif
192 #ifdef RC_LOCAL_CONFDIR
193 - if (!rc_newer_than(RC_DEPTREE_CACHE, RC_LOCAL_CONFDIR, newest, file))
194 - return true;
195 + newer |= !deep_mtime_check(RC_LOCAL_CONFDIR,true,&mtime,file);
196 #endif
197 - if (!rc_newer_than(RC_DEPTREE_CACHE, RC_CONF, newest, file))
198 - return true;
199 + newer |= !deep_mtime_check(RC_CONF,true,&mtime,file);
200
201 /* Some init scripts dependencies change depending on config files
202 * outside of baselayout, like syslog-ng, so we check those too. */
203 config = rc_config_list(RC_DEPCONFIG);
204 TAILQ_FOREACH(s, config, entries) {
205 - if (!rc_newer_than(RC_DEPTREE_CACHE, s->value, newest, file)) {
206 - newer = true;
207 - break;
208 - }
209 + newer |= !deep_mtime_check(s->value, true, &mtime, file);
210 }
211 rc_stringlist_free(config);
212 +
213 + /* Return newest file time, if requested */
214 + if ((newer) && (newest != NULL)) {
215 + *newest = mtime;
216 + }
217 +
218 return newer;
219 }
220 librc_hidden_def(rc_deptree_update_needed)