1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +03:00

Merge pull request #212 from poettering/gc-machine-snapshots

automatically remove old machine shapshots at boot
This commit is contained in:
Lennart Poettering 2015-06-15 20:33:35 +02:00
commit 78ed65ac8d
19 changed files with 109 additions and 40 deletions

View File

@ -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 += \

View File

@ -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;

View File

@ -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++) {

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View 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.*

View File

@ -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 - - -