mirror of
https://github.com/systemd/systemd.git
synced 2025-01-26 14:04:03 +03:00
update-done: Create using a temporary file (#5789)
'/etc/.updated' is created without using a temporary file, this can be problematic with filesystems that cache writes. Modify so that the timestamp is written to a temporary file and then use an atomic move to move it to its correct place.
This commit is contained in:
parent
6385cb31ef
commit
5a1d67639d
@ -17,8 +17,10 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "io-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "util.h"
|
||||
@ -36,6 +38,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int fd = -1;
|
||||
int r;
|
||||
_cleanup_(unlink_and_freep) char *tmp = NULL;
|
||||
|
||||
assert(path);
|
||||
assert(ts);
|
||||
@ -50,20 +53,20 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);
|
||||
|
||||
fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
|
||||
fd = open_tmpfile_linkable(path, O_WRONLY|O_CLOEXEC, &tmp);
|
||||
mac_selinux_create_file_clear();
|
||||
|
||||
if (fd < 0) {
|
||||
if (errno == EROFS)
|
||||
return log_debug("Can't create timestamp file %s, file system is read-only.", path);
|
||||
return log_debug("Can't create temporary timestamp file %s, file system is read-only.", tmp);
|
||||
|
||||
return log_error_errno(errno, "Failed to create/open timestamp file %s: %m", path);
|
||||
return log_error_errno(errno, "Failed to create/open temporary timestamp file %s: %m", tmp);
|
||||
}
|
||||
|
||||
f = fdopen(fd, "we");
|
||||
if (!f) {
|
||||
safe_close(fd);
|
||||
return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", path);
|
||||
return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", tmp);
|
||||
}
|
||||
|
||||
(void) fprintf(f,
|
||||
@ -76,7 +79,15 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
|
||||
return log_error_errno(r, "Failed to write timestamp file: %m");
|
||||
|
||||
if (futimens(fd, twice) < 0)
|
||||
return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
|
||||
return log_error_errno(errno, "Failed to update timestamp on %s: %m", tmp);
|
||||
|
||||
/* fix permissions */
|
||||
(void) fchmod(fd, 0644);
|
||||
r = link_tmpfile(fd, tmp, path);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to move \"%s\" to \"%s\": %m", tmp, path);
|
||||
|
||||
tmp = mfree(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user