فهرست منبع

Merge pull request #180 from ThomasWaldmann/read-device

read special files as if they were regular files, update docs, closes #79
TW 9 سال پیش
والد
کامیت
70d97c4467
3فایلهای تغییر یافته به همراه23 افزوده شده و 6 حذف شده
  1. 10 4
      borg/archiver.py
  2. 3 2
      borg/cache.py
  3. 10 0
      docs/usage.rst

+ 10 - 4
borg/archiver.py

@@ -145,7 +145,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
                     continue
                     continue
             else:
             else:
                 restrict_dev = None
                 restrict_dev = None
-            self._process(archive, cache, args.excludes, args.exclude_caches, skip_inodes, path, restrict_dev)
+            self._process(archive, cache, args.excludes, args.exclude_caches, skip_inodes, path, restrict_dev,
+                          read_special=args.read_special)
         archive.save(timestamp=args.timestamp)
         archive.save(timestamp=args.timestamp)
         if args.progress:
         if args.progress:
             archive.stats.show_progress(final=True)
             archive.stats.show_progress(final=True)
@@ -163,7 +164,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
             print('-' * 78)
             print('-' * 78)
         return self.exit_code
         return self.exit_code
 
 
-    def _process(self, archive, cache, excludes, exclude_caches, skip_inodes, path, restrict_dev):
+    def _process(self, archive, cache, excludes, exclude_caches, skip_inodes, path, restrict_dev,
+                 read_special=False):
         if exclude_path(path, excludes):
         if exclude_path(path, excludes):
             return
             return
         try:
         try:
@@ -180,7 +182,8 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
         # Ignore if nodump flag is set
         # Ignore if nodump flag is set
         if has_lchflags and (st.st_flags & stat.UF_NODUMP):
         if has_lchflags and (st.st_flags & stat.UF_NODUMP):
             return
             return
-        if stat.S_ISREG(st.st_mode):
+        if (stat.S_ISREG(st.st_mode) or
+            read_special and not stat.S_ISDIR(st.st_mode)):
             try:
             try:
                 status = archive.process_file(path, st, cache)
                 status = archive.process_file(path, st, cache)
             except IOError as e:
             except IOError as e:
@@ -197,7 +200,7 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
                 for filename in sorted(entries):
                 for filename in sorted(entries):
                     entry_path = os.path.normpath(os.path.join(path, filename))
                     entry_path = os.path.normpath(os.path.join(path, filename))
                     self._process(archive, cache, excludes, exclude_caches, skip_inodes,
                     self._process(archive, cache, excludes, exclude_caches, skip_inodes,
-                                  entry_path, restrict_dev)
+                                  entry_path, restrict_dev, read_special=read_special)
         elif stat.S_ISLNK(st.st_mode):
         elif stat.S_ISLNK(st.st_mode):
             status = archive.process_symlink(path, st)
             status = archive.process_symlink(path, st)
         elif stat.S_ISFIFO(st.st_mode):
         elif stat.S_ISFIFO(st.st_mode):
@@ -688,6 +691,9 @@ Type "Yes I am sure" if you understand this and want to continue.\n""")
                                     'zlib,0 .. zlib,9 == zlib (with level 0..9), '
                                     'zlib,0 .. zlib,9 == zlib (with level 0..9), '
                                     'lzma == lzma (default level 6), '
                                     'lzma == lzma (default level 6), '
                                     'lzma,0 .. lzma,9 == lzma (with level 0..9).')
                                     'lzma,0 .. lzma,9 == lzma (with level 0..9).')
+        subparser.add_argument('--read-special', dest='read_special',
+                               action='store_true', default=False,
+                               help='open and read special files as if they were regular files')
         subparser.add_argument('archive', metavar='ARCHIVE',
         subparser.add_argument('archive', metavar='ARCHIVE',
                                type=location_validator(archive=True),
                                type=location_validator(archive=True),
                                help='archive to create')
                                help='archive to create')

+ 3 - 2
borg/cache.py

@@ -3,6 +3,7 @@ from .remote import cache_if_remote
 import errno
 import errno
 import msgpack
 import msgpack
 import os
 import os
+import stat
 import sys
 import sys
 from binascii import hexlify
 from binascii import hexlify
 import shutil
 import shutil
@@ -387,7 +388,7 @@ class Cache:
             stats.update(-size, -csize, False)
             stats.update(-size, -csize, False)
 
 
     def file_known_and_unchanged(self, path_hash, st):
     def file_known_and_unchanged(self, path_hash, st):
-        if not self.do_files:
+        if not (self.do_files and stat.S_ISREG(st.st_mode)):
             return None
             return None
         if self.files is None:
         if self.files is None:
             self._read_files()
             self._read_files()
@@ -404,7 +405,7 @@ class Cache:
             return None
             return None
 
 
     def memorize_file(self, path_hash, st, ids):
     def memorize_file(self, path_hash, st, ids):
-        if not self.do_files:
+        if not (self.do_files and stat.S_ISREG(st.st_mode)):
             return
             return
         # Entry: Age, inode, size, mtime, chunk ids
         # Entry: Age, inode, size, mtime, chunk ids
         mtime_ns = st_mtime_ns(st)
         mtime_ns = st_mtime_ns(st)

+ 10 - 0
docs/usage.rst

@@ -210,6 +210,11 @@ Examples
     # Even slower, even higher compression (N = 0..9)
     # Even slower, even higher compression (N = 0..9)
     $ borg create --compression lzma,N /mnt/backup::repo ~
     $ borg create --compression lzma,N /mnt/backup::repo ~
 
 
+    # Backup some LV snapshots (you have to create the snapshots before this
+    # and remove them afterwards). We also backup the output of lvdisplay so
+    # we can see the LV sizes at restore time. See also "borg extract" examples.
+    $ lvdisplay > lvdisplay.txt
+    $ borg create --read-special /mnt/backup::repo lvdisplay.txt /dev/vg0/*-snapshot
 
 
 .. include:: usage/extract.rst.inc
 .. include:: usage/extract.rst.inc
 
 
@@ -229,6 +234,11 @@ Examples
     # Extract the "src" directory but exclude object files
     # Extract the "src" directory but exclude object files
     $ borg extract /mnt/backup::my-files home/USERNAME/src --exclude '*.o'
     $ borg extract /mnt/backup::my-files home/USERNAME/src --exclude '*.o'
 
 
+    # Restore LV snapshots (the target LVs /dev/vg0/* of correct size have
+    # to be already available and will be overwritten by this command!)
+    $ borg extract --stdout /mnt/backup::repo dev/vg0/root-snapshot > /dev/vg0/root
+    $ borg extract --stdout /mnt/backup::repo dev/vg0/home-snapshot > /dev/vg0/home
+
 Note: currently, extract always writes into the current working directory ("."),
 Note: currently, extract always writes into the current working directory ("."),
       so make sure you ``cd`` to the right place before calling ``borg extract``.
       so make sure you ``cd`` to the right place before calling ``borg extract``.