3d84582f38
files. This allows deja-dup to proceed by back-ups without filling up /tmp -- from RH Bugzilla.
146 lines
4.7 KiB
Plaintext
146 lines
4.7 KiB
Plaintext
$OpenBSD: patch-common_CommonUtils_vala,v 1.1 2013/01/21 08:23:30 ajacoutot Exp $
|
|
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=892063
|
|
|
|
--- common/CommonUtils.vala.orig Tue Aug 21 17:08:23 2012
|
|
+++ common/CommonUtils.vala Mon Jan 21 08:43:45 2013
|
|
@@ -444,6 +444,9 @@ public bool initialize(out string header, out string m
|
|
var unused_backend = DejaDup.Backend.get_default();
|
|
unused_backend = null;
|
|
|
|
+ // And cleanup from any previous runs
|
|
+ clean_tempdirs.begin();
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -580,6 +583,128 @@ public Date get_full_backup_threshold_date()
|
|
date.subtract_days(days);
|
|
|
|
return date;
|
|
+}
|
|
+
|
|
+public bool ensure_directory_exists(string path)
|
|
+{
|
|
+ var gfile = File.new_for_path(path);
|
|
+ try {
|
|
+ if (gfile.make_directory_with_parents())
|
|
+ return true;
|
|
+ }
|
|
+ catch (IOError.EXISTS e) {
|
|
+ return true; // ignore
|
|
+ }
|
|
+ catch (Error e) {
|
|
+ warning("%s\n", e.message);
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
+// By default, duplicity uses normal tmp folders like /tmp to store its
|
|
+// in-process files. These can get quite large, especially when restoring.
|
|
+// You may need up to twice the size of the largest source file.
|
|
+// Because /tmp may not be super large, especially on systems that use
|
|
+// tmpfs by default (e.g. Fedora 18), we try to use a tempdir that is on
|
|
+// the same partition as the source files.
|
|
+public async string get_tempdir()
|
|
+{
|
|
+ var tempdirs = get_tempdirs();
|
|
+
|
|
+ // First, decide the "main include". Assume that if $HOME
|
|
+ // is present, that is it. Else, the first include we find decides it.
|
|
+ // This is admittedly fast and loose, but our primary concern is just
|
|
+ // avoiding silly choices like tmpfs or tiny special /tmp partitions.
|
|
+ var settings = get_settings();
|
|
+ var include_val = settings.get_value(INCLUDE_LIST_KEY);
|
|
+ var include_list = parse_dir_list(include_val.get_strv());
|
|
+ File main_include = null;
|
|
+ var home = File.new_for_path(Environment.get_home_dir());
|
|
+ foreach (var include in include_list) {
|
|
+ if (include.equal(home)) {
|
|
+ main_include = include;
|
|
+ break;
|
|
+ }
|
|
+ else if (main_include == null)
|
|
+ main_include = include;
|
|
+ }
|
|
+ if (main_include == null)
|
|
+ return tempdirs[0];
|
|
+
|
|
+ // Grab that include's fs ID
|
|
+ string filesystem_id;
|
|
+ try {
|
|
+ var info = yield main_include.query_info_async(FileAttribute.ID_FILESYSTEM,
|
|
+ FileQueryInfoFlags.NONE);
|
|
+ filesystem_id = info.get_attribute_string(FileAttribute.ID_FILESYSTEM);
|
|
+ }
|
|
+ catch (Error e) {
|
|
+ return tempdirs[0];
|
|
+ }
|
|
+
|
|
+ // Then, see which of our possible tempdirs matches that partition.
|
|
+ foreach (var tempdir in tempdirs) {
|
|
+ string temp_id;
|
|
+ ensure_directory_exists(tempdir);
|
|
+ try {
|
|
+ var gfile = File.new_for_path(tempdir);
|
|
+ var info = yield gfile.query_info_async(FileAttribute.ID_FILESYSTEM,
|
|
+ FileQueryInfoFlags.NONE);
|
|
+ temp_id = info.get_attribute_string(FileAttribute.ID_FILESYSTEM);
|
|
+ }
|
|
+ catch (Error e) {
|
|
+ continue;
|
|
+ }
|
|
+ if (temp_id == filesystem_id)
|
|
+ return tempdir;
|
|
+ }
|
|
+
|
|
+ // Fallback to simply using the highest preferred tempdir
|
|
+ return tempdirs[0];
|
|
+}
|
|
+
|
|
+public string[] get_tempdirs()
|
|
+{
|
|
+ var tempdir = Environment.get_variable("DEJA_DUP_TEMPDIR");
|
|
+ if (tempdir != null && tempdir != "")
|
|
+ return {tempdir};
|
|
+ // Prefer directories that have their own cleanup logic in case ours isn't
|
|
+ // run for a while. (e.g. /tmp every boot, /var/tmp every now and then)
|
|
+ return {Environment.get_tmp_dir(), "/var/tmp",
|
|
+ Path.build_filename(Environment.get_user_cache_dir(), Config.PACKAGE,
|
|
+ "tmp")};
|
|
+}
|
|
+
|
|
+public async void clean_tempdirs()
|
|
+{
|
|
+ var tempdirs = get_tempdirs();
|
|
+ const int NUM_ENUMERATED = 16;
|
|
+ foreach (var tempdir in tempdirs) {
|
|
+ var gfile = File.new_for_path(tempdir);
|
|
+
|
|
+ // Now try to find and delete all files that start with "duplicity-"
|
|
+ try {
|
|
+ var enumerator = yield gfile.enumerate_children_async(
|
|
+ FileAttribute.STANDARD_NAME,
|
|
+ FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
|
|
+ Priority.DEFAULT, null);
|
|
+ while (true) {
|
|
+ var infos = yield enumerator.next_files_async(NUM_ENUMERATED,
|
|
+ Priority.DEFAULT, null);
|
|
+ foreach (FileInfo info in infos) {
|
|
+ if (info.get_name().has_prefix("duplicity-")) {
|
|
+ var child = gfile.get_child(info.get_name());
|
|
+ yield new DejaDup.RecursiveDelete(child).start_async();
|
|
+ }
|
|
+ }
|
|
+ if (infos.length() != NUM_ENUMERATED)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ catch (Error e) {
|
|
+ // No worries
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
} // end namespace
|