Forráskód Böngészése

Merge branch 'master' into borg2

Thomas Waldmann 2 éve
szülő
commit
c7ed985ffd

+ 38 - 0
docs/faq.rst

@@ -1159,6 +1159,44 @@ It may be useful to set ``BORG_RELOCATED_REPO_ACCESS_IS_OK=yes`` to avoid the
 prompts when renaming multiple repositories or in a non-interactive context
 such as a script. See :doc:`deployment` for an example.
 
+The repository quota size is reached, what can I do?
+----------------------------------------------------
+
+The simplest solution is to increase or disable the quota and resume the backup:
+
+::
+
+    borg config /path/to/repo storage_quota 0
+
+If you are bound to the quota, you have to free repository space. The first to
+try is running :ref:`borg_compact` to free unused backup space (see also
+:ref:`separate_compaction`):
+
+::
+
+    borg compact /path/to/repo
+
+If your repository is already compacted, run :ref:`borg_prune` or
+:ref:`borg_delete` to delete archives that you do not need anymore, and then run
+``borg compact`` again.
+
+My backup disk is full, what can I do?
+--------------------------------------
+
+Borg cannot work if you really have zero free space on the backup disk, so the
+first thing you must do is deleting some files to regain free disk space. See
+:ref:`about_free_space` for further details.
+
+Some Borg commands that do not change the repository might work under disk-full
+conditions, but generally this should be avoided. If your backup disk is already
+full when Borg starts a write command like `borg create`, it will abort
+immediately and the repository will stay as-is.
+
+If you run a backup that stops due to a disk running full, Borg will roll back,
+delete the new new segment file and thus freeing disk space automatically. There
+may be a checkpoint archive left that has been saved before the disk got full.
+You can keep it to speed up the next backup or delete it to get back more disk
+space.
 
 Miscellaneous
 #############

+ 4 - 2
docs/internals/frontends.rst

@@ -90,12 +90,14 @@ progress_percent
         can have this property set to *true*.
     message
         A formatted progress message, this will include the percentage and perhaps other information
+        (absent for finished == true)
     current
-        Current value (always less-or-equal to *total*)
+        Current value (always less-or-equal to *total*, absent for finished == true)
     info
         Array that describes the current item, may be *null*, contents depend on *msgid*
+        (absent for finished == true)
     total
-        Total value
+        Total value (absent for finished == true)
     time
         Unix timestamp (float)
 

+ 2 - 0
docs/quickstart.rst

@@ -26,6 +26,8 @@ repositories contain data blocks and a manifest tracking which blocks are in eac
 archive. If some data hasn't changed from one backup to another, Borg can simply
 reference an already uploaded data chunk (deduplication).
 
+.. _about_free_space:
+
 Important note about free space
 -------------------------------
 

+ 3 - 3
src/borg/_hashindex.c

@@ -664,11 +664,11 @@ hashindex_compact(HashIndex *index)
     while(idx < index->num_buckets) {
         /* Phase 1: Find some empty slots */
         start_idx = idx;
-        while((BUCKET_IS_EMPTY(index, idx) || BUCKET_IS_DELETED(index, idx)) && idx < index->num_buckets) {
+        while((idx < index->num_buckets) && (BUCKET_IS_EMPTY(index, idx) || BUCKET_IS_DELETED(index, idx))) {
             idx++;
         }
 
-        /* everything from start_idx to idx is empty or deleted */
+        /* everything from start_idx to idx-1 (inclusive) is empty or deleted */
         count = empty_slot_count = idx - start_idx;
         begin_used_idx = idx;
 
@@ -682,7 +682,7 @@ hashindex_compact(HashIndex *index)
 
         /* Phase 2: Find some non-empty/non-deleted slots we can move to the compact tail */
 
-        while(!(BUCKET_IS_EMPTY(index, idx) || BUCKET_IS_DELETED(index, idx)) && empty_slot_count && idx < index->num_buckets) {
+        while(empty_slot_count && (idx < index->num_buckets) && !(BUCKET_IS_EMPTY(index, idx) || BUCKET_IS_DELETED(index, idx))) {
             idx++;
             empty_slot_count--;
         }

+ 7 - 4
src/borg/archiver.py

@@ -3147,10 +3147,13 @@ class Archiver:
 
         # borg mount
         mount_epilog = process_epilog("""
-        This command mounts an archive as a FUSE filesystem. This can be useful for
-        browsing an archive or restoring individual files. Unless the ``--foreground``
-        option is given the command will run in the background until the filesystem
-        is ``umounted``.
+        This command mounts an archive as a FUSE filesystem. This can be useful
+        for browsing an archive or restoring individual files. When restoring,
+        take into account that the current FUSE implementation does not support
+        special fs flags and ACLs.
+
+        Unless the ``--foreground`` option is given the command will run in the
+        background until the filesystem is ``umounted``.
 
         The command ``borgfs`` provides a wrapper for ``borg mount``. This can also be
         used in fstab entries:

+ 12 - 7
src/borg/platform/base.py

@@ -239,13 +239,18 @@ class SaveFile:
             safe_unlink(self.tmp_fname)  # with-body has failed, clean up tmp file
             return  # continue processing the exception normally
 
-        # tempfile.mkstemp always uses owner-only file permissions for the temp file,
-        # but as we'll rename it to the non-temp permanent file now, we need to respect
-        # the umask and change the file mode to what a normally created file would have.
-        # thanks to the crappy os.umask api, we can't query the umask without setting it. :-(
-        umask = os.umask(UMASK_DEFAULT)
-        os.umask(umask)
-        os.chmod(self.tmp_fname, mode=0o666 & ~ umask)
+        try:
+            # tempfile.mkstemp always uses owner-only file permissions for the temp file,
+            # but as we'll rename it to the non-temp permanent file now, we need to respect
+            # the umask and change the file mode to what a normally created file would have.
+            # thanks to the crappy os.umask api, we can't query the umask without setting it. :-(
+            umask = os.umask(UMASK_DEFAULT)
+            os.umask(umask)
+            os.chmod(self.tmp_fname, mode=0o666 & ~ umask)
+        except OSError:
+            # chmod might fail if the fs does not support it.
+            # this is not harmful, the file will still have permissions for the owner.
+            pass
 
         try:
             os.replace(self.tmp_fname, self.path)  # POSIX: atomic rename