mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
Merge pull request #212 from poettering/gc-machine-snapshots
automatically remove old machine shapshots at boot
This commit is contained in:
commit
78ed65ac8d
@ -2188,7 +2188,8 @@ dist_tmpfiles_DATA = \
|
||||
tmpfiles.d/tmp.conf \
|
||||
tmpfiles.d/x11.conf \
|
||||
tmpfiles.d/var.conf \
|
||||
tmpfiles.d/home.conf
|
||||
tmpfiles.d/home.conf \
|
||||
tmpfiles.d/systemd-nspawn.conf
|
||||
|
||||
if HAVE_SYSV_COMPAT
|
||||
dist_tmpfiles_DATA += \
|
||||
|
@ -396,7 +396,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
|
||||
assert(from);
|
||||
assert(to);
|
||||
|
||||
r = tempfn_random(to, &t);
|
||||
r = tempfn_random(to, NULL, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -2521,7 +2521,7 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
|
||||
assert(_f);
|
||||
assert(_temp_path);
|
||||
|
||||
r = tempfn_xxxxxx(path, &t);
|
||||
r = tempfn_xxxxxx(path, NULL, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2551,7 +2551,7 @@ int symlink_atomic(const char *from, const char *to) {
|
||||
assert(from);
|
||||
assert(to);
|
||||
|
||||
r = tempfn_random(to, &t);
|
||||
r = tempfn_random(to, NULL, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2594,7 +2594,7 @@ int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
|
||||
|
||||
assert(path);
|
||||
|
||||
r = tempfn_random(path, &t);
|
||||
r = tempfn_random(path, NULL, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2615,7 +2615,7 @@ int mkfifo_atomic(const char *path, mode_t mode) {
|
||||
|
||||
assert(path);
|
||||
|
||||
r = tempfn_random(path, &t);
|
||||
r = tempfn_random(path, NULL, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -4969,7 +4969,7 @@ int fflush_and_check(FILE *f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tempfn_xxxxxx(const char *p, char **ret) {
|
||||
int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
|
||||
const char *fn;
|
||||
char *t;
|
||||
|
||||
@ -4981,24 +4981,27 @@ int tempfn_xxxxxx(const char *p, char **ret) {
|
||||
* /foo/bar/waldo
|
||||
*
|
||||
* Into this:
|
||||
* /foo/bar/.#waldoXXXXXX
|
||||
* /foo/bar/.#<extra>waldoXXXXXX
|
||||
*/
|
||||
|
||||
fn = basename(p);
|
||||
if (!filename_is_valid(fn))
|
||||
return -EINVAL;
|
||||
|
||||
t = new(char, strlen(p) + 2 + 6 + 1);
|
||||
if (extra == NULL)
|
||||
extra = "";
|
||||
|
||||
t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
strcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn), "XXXXXX");
|
||||
strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
|
||||
|
||||
*ret = path_kill_slashes(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tempfn_random(const char *p, char **ret) {
|
||||
int tempfn_random(const char *p, const char *extra, char **ret) {
|
||||
const char *fn;
|
||||
char *t, *x;
|
||||
uint64_t u;
|
||||
@ -5012,18 +5015,21 @@ int tempfn_random(const char *p, char **ret) {
|
||||
* /foo/bar/waldo
|
||||
*
|
||||
* Into this:
|
||||
* /foo/bar/.#waldobaa2a261115984a9
|
||||
* /foo/bar/.#<extra>waldobaa2a261115984a9
|
||||
*/
|
||||
|
||||
fn = basename(p);
|
||||
if (!filename_is_valid(fn))
|
||||
return -EINVAL;
|
||||
|
||||
t = new(char, strlen(p) + 2 + 16 + 1);
|
||||
if (!extra)
|
||||
extra = "";
|
||||
|
||||
t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
x = stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn);
|
||||
x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
|
||||
|
||||
u = random_u64();
|
||||
for (i = 0; i < 16; i++) {
|
||||
@ -5037,7 +5043,7 @@ int tempfn_random(const char *p, char **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tempfn_random_child(const char *p, char **ret) {
|
||||
int tempfn_random_child(const char *p, const char *extra, char **ret) {
|
||||
char *t, *x;
|
||||
uint64_t u;
|
||||
unsigned i;
|
||||
@ -5048,14 +5054,17 @@ int tempfn_random_child(const char *p, char **ret) {
|
||||
/* Turns this:
|
||||
* /foo/bar/waldo
|
||||
* Into this:
|
||||
* /foo/bar/waldo/.#3c2b6219aa75d7d0
|
||||
* /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
|
||||
*/
|
||||
|
||||
t = new(char, strlen(p) + 3 + 16 + 1);
|
||||
if (!extra)
|
||||
extra = "";
|
||||
|
||||
t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
x = stpcpy(stpcpy(t, p), "/.#");
|
||||
x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
|
||||
|
||||
u = random_u64();
|
||||
for (i = 0; i < 16; i++) {
|
||||
|
@ -828,9 +828,9 @@ int bind_remount_recursive(const char *prefix, bool ro);
|
||||
|
||||
int fflush_and_check(FILE *f);
|
||||
|
||||
int tempfn_xxxxxx(const char *p, char **ret);
|
||||
int tempfn_random(const char *p, char **ret);
|
||||
int tempfn_random_child(const char *p, char **ret);
|
||||
int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
|
||||
int tempfn_random(const char *p, const char *extra, char **ret);
|
||||
int tempfn_random_child(const char *p, const char *extra, char **ret);
|
||||
|
||||
int take_password_lock(const char *root);
|
||||
|
||||
|
@ -265,7 +265,7 @@ static int reflink_snapshot(int fd, const char *path) {
|
||||
if (new_fd < 0) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
r = tempfn_random(path, &t);
|
||||
r = tempfn_random(path, NULL, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -290,7 +290,7 @@ int tar_export_start(TarExport *e, const char *path, int fd, ImportCompressType
|
||||
free(e->temp_path);
|
||||
e->temp_path = NULL;
|
||||
|
||||
r = tempfn_random(path, &e->temp_path);
|
||||
r = tempfn_random(path, NULL, &e->temp_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -180,7 +180,7 @@ static int raw_import_maybe_convert_qcow2(RawImport *i) {
|
||||
return 0;
|
||||
|
||||
/* This is a QCOW2 image, let's convert it */
|
||||
r = tempfn_random(i->final_path, &t);
|
||||
r = tempfn_random(i->final_path, NULL, &t);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -267,7 +267,7 @@ static int raw_import_open_disk(RawImport *i) {
|
||||
if (!i->final_path)
|
||||
return log_oom();
|
||||
|
||||
r = tempfn_random(i->final_path, &i->temp_path);
|
||||
r = tempfn_random(i->final_path, NULL, &i->temp_path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
|
@ -223,7 +223,7 @@ static int tar_import_fork_tar(TarImport *i) {
|
||||
if (!i->final_path)
|
||||
return log_oom();
|
||||
|
||||
r = tempfn_random(i->final_path, &i->temp_path);
|
||||
r = tempfn_random(i->final_path, NULL, &i->temp_path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
|
@ -520,7 +520,7 @@ static int dkr_pull_job_on_open_disk(PullJob *j) {
|
||||
assert(!i->temp_path);
|
||||
assert(i->tar_pid <= 0);
|
||||
|
||||
r = tempfn_random(i->final_path, &i->temp_path);
|
||||
r = tempfn_random(i->final_path, NULL, &i->temp_path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
|
@ -208,7 +208,7 @@ static int raw_pull_maybe_convert_qcow2(RawPull *i) {
|
||||
return 0;
|
||||
|
||||
/* This is a QCOW2 image, let's convert it */
|
||||
r = tempfn_random(i->final_path, &t);
|
||||
r = tempfn_random(i->final_path, NULL, &t);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -280,7 +280,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
|
||||
if (i->force_local)
|
||||
(void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
|
||||
|
||||
r = tempfn_random(p, &tp);
|
||||
r = tempfn_random(p, NULL, &tp);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -424,7 +424,7 @@ static int raw_pull_job_on_open_disk(PullJob *j) {
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = tempfn_random(i->final_path, &i->temp_path);
|
||||
r = tempfn_random(i->final_path, NULL, &i->temp_path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
|
@ -324,7 +324,7 @@ static int tar_pull_job_on_open_disk(PullJob *j) {
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = tempfn_random(i->final_path, &i->temp_path);
|
||||
r = tempfn_random(i->final_path, NULL, &i->temp_path);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
|
@ -301,7 +301,7 @@ static int save_external_coredump(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine coredump file name: %m");
|
||||
|
||||
r = tempfn_random(fn, &tmp);
|
||||
r = tempfn_random(fn, NULL, &tmp);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine temporary file name: %m");
|
||||
|
||||
@ -347,7 +347,7 @@ static int save_external_coredump(
|
||||
goto uncompressed;
|
||||
}
|
||||
|
||||
r = tempfn_random(fn_compressed, &tmp_compressed);
|
||||
r = tempfn_random(fn_compressed, NULL, &tmp_compressed);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to determine temporary file name for %s: %m", fn_compressed);
|
||||
goto uncompressed;
|
||||
|
@ -350,7 +350,7 @@ static int custom_mounts_prepare(void) {
|
||||
if (m->read_only)
|
||||
continue;
|
||||
|
||||
r = tempfn_random(m->source, &m->work_dir);
|
||||
r = tempfn_random(m->source, NULL, &m->work_dir);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate work directory from %s: %m", m->source);
|
||||
}
|
||||
@ -4522,9 +4522,9 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
if (r > 0)
|
||||
r = tempfn_random_child(arg_directory, &np);
|
||||
r = tempfn_random_child(arg_directory, "machine.", &np);
|
||||
else
|
||||
r = tempfn_random(arg_directory, &np);
|
||||
r = tempfn_random(arg_directory, "machine.", &np);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to generate name for snapshot: %m");
|
||||
goto finish;
|
||||
|
@ -75,7 +75,7 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) {
|
||||
if (errno != ENOENT)
|
||||
return sd_bus_error_set_errnof(error, errno, "Failed to open /var/lib/machines.raw: %m");
|
||||
|
||||
r = tempfn_xxxxxx("/var/lib/machines.raw", &tmp);
|
||||
r = tempfn_xxxxxx("/var/lib/machines.raw", NULL, &tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -5687,7 +5687,7 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
|
||||
assert(original_path);
|
||||
assert(ret_tmp_fn);
|
||||
|
||||
r = tempfn_random(new_path, &t);
|
||||
r = tempfn_random(new_path, NULL, &t);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
|
||||
|
||||
|
@ -1507,6 +1507,42 @@ static void test_parse_mode(void) {
|
||||
assert_se(parse_mode("0", &m) >= 0 && m == 0);
|
||||
}
|
||||
|
||||
static void test_tempfn(void) {
|
||||
char *ret = NULL, *p;
|
||||
|
||||
assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
|
||||
assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
|
||||
free(ret);
|
||||
|
||||
assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
|
||||
assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
|
||||
free(ret);
|
||||
|
||||
assert_se(tempfn_random("/foo/bar/waldo", NULL, &ret) >= 0);
|
||||
assert_se(p = startswith(ret, "/foo/bar/.#waldo"));
|
||||
assert_se(strlen(p) == 16);
|
||||
assert_se(in_charset(p, "0123456789abcdef"));
|
||||
free(ret);
|
||||
|
||||
assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret) >= 0);
|
||||
assert_se(p = startswith(ret, "/foo/bar/.#[wuff]waldo"));
|
||||
assert_se(strlen(p) == 16);
|
||||
assert_se(in_charset(p, "0123456789abcdef"));
|
||||
free(ret);
|
||||
|
||||
assert_se(tempfn_random_child("/foo/bar/waldo", NULL, &ret) >= 0);
|
||||
assert_se(p = startswith(ret, "/foo/bar/waldo/.#"));
|
||||
assert_se(strlen(p) == 16);
|
||||
assert_se(in_charset(p, "0123456789abcdef"));
|
||||
free(ret);
|
||||
|
||||
assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret) >= 0);
|
||||
assert_se(p = startswith(ret, "/foo/bar/waldo/.#[kikiriki]"));
|
||||
assert_se(strlen(p) == 16);
|
||||
assert_se(in_charset(p, "0123456789abcdef"));
|
||||
free(ret);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
@ -1582,6 +1618,7 @@ int main(int argc, char *argv[]) {
|
||||
test_sparse_write();
|
||||
test_shell_maybe_quote();
|
||||
test_parse_mode();
|
||||
test_tempfn();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1465,7 +1465,7 @@ static int remove_item_instance(Item *i, const char *instance) {
|
||||
/* FIXME: we probably should use dir_cleanup() here
|
||||
* instead of rm_rf() so that 'x' is honoured. */
|
||||
log_debug("rm -rf \"%s\"", instance);
|
||||
r = rm_rf(instance, (i->type == RECURSIVE_REMOVE_PATH ? REMOVE_ROOT : 0) | REMOVE_PHYSICAL);
|
||||
r = rm_rf(instance, (i->type == RECURSIVE_REMOVE_PATH ? REMOVE_ROOT|REMOVE_SUBVOLUME : 0) | REMOVE_PHYSICAL);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return log_error_errno(r, "rm_rf(%s): %m", instance);
|
||||
|
||||
|
23
tmpfiles.d/systemd-nspawn.conf
Normal file
23
tmpfiles.d/systemd-nspawn.conf
Normal file
@ -0,0 +1,23 @@
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# See tmpfiles.d(5) for details
|
||||
|
||||
v /var/lib/machines 0700 - - -
|
||||
|
||||
# Remove old temporary snapshots, but only at boot. Ideally we'd have
|
||||
# "self-destroying" btrfs snapshots that go away if the last last
|
||||
# reference to it does. To mimic a scheme like this at least remove
|
||||
# the old snapshots on fresh boots, where we know they cannot be
|
||||
# referenced anymore. Note that we actually remove all temporary files
|
||||
# in /var/lib/machines/ at boot, which should be safe since the
|
||||
# directory has defined semantics. In the root directory (where
|
||||
# systemd-nspawn --ephemeral places snapshots) we are more strict, to
|
||||
# avoid removing unrelated temporary files.
|
||||
|
||||
R! /var/lib/machines/.#*
|
||||
R! /.#machine.*
|
@ -18,6 +18,5 @@ f /var/log/btmp 0600 root utmp -
|
||||
d /var/cache 0755 - - -
|
||||
|
||||
d /var/lib 0755 - - -
|
||||
v /var/lib/machines 0700 - - -
|
||||
|
||||
d /var/spool 0755 - - -
|
||||
|
Loading…
Reference in New Issue
Block a user