Файлова система союзу з назвою назви файлів?


5

Чи знаєте ви, чи є об'єднаний fs для GNU / Linux, який показує також "тіньові" файли з трохи іншими іменами? IE, якщо у мене є два фС на кшталт:

root1
+dir1
+dir2
 +file1
 +file2
 +file3

root2
+dir1
+dir2
 +file1
 +file2
 +file4

Отримані в результаті "об'єднані" ФС повинні:

unioned
+dir1
+dir2
 +file1
 +file1.1
 +file2
 +file2.1
 +file3

Щоб можна було швидко перевірити відмінності між "об'єднаними" ФС

Схоже, що UnionFS та Aufs не пропонують такий варіант

Дякую


Ну, я б сказав, що це підірве основну концепцію цих файлових систем. Якщо ви хочете відрізняти дерева директорій, чому б просто не використовувати diff?
Даніель Б

тому що мені потрібно об'єднати резервні копії географічного розповсюдження (створені за допомогою декількох rsync), швидко перевіривши відмінності з diff / meld / тощо. було б дуже багато часу, щоб розрізняти кожну фс-пару, у мене є як мінімум 5 різних резервних копій)
atrent

Якщо ви зможете їх змонтувати, можете використовувати diff. Я не бачу проблеми, вибачте.
Даніель Б

витрачає багато часу (300 к. файлів за фс), а під час об'єднання я міг накладати їх і використовувати такі інструменти, як rdfind (дублікат пошуку) на основі каталогу
atrent

також майте на увазі, що я не зацікавлений у виборі наймолодшого або пріоритетного файлу кожного шару, мені також потрібно перевірити, чи вони здорові
atrent

Відповіді:


1

Альтернатива з використанням git-annex:

Спочатку ми встановимо тестові файли:

#!/bin/bash 
# faster than /dev/urandom
randfile='openssl enc -aes-256-ctr -pass pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" -nosalt < /dev/zero'
dd='dd bs=1M count=5 iflag=fullblock'

for I in 1 2
do
  mkdir root$I
  cd root$I
  for J in 1 2
  do
    mkdir dir$J
    if [ -e dir2 ]
    then
      cd dir2
      eval $randfile | eval $dd of=file1
      eval $randfile | eval $dd of=file2
      if [ `pwd | grep root1` ]; then
        eval $randfile | eval $dd of=file3
      elif [ `pwd | grep root2` ]; then
        eval $randfile | eval $dd of=file4
      fi
      cd ..
    fi
  done
  cd ..
done

При цьому створюються каталоги з бінарними файлами, що містять випадкові дані. У цей момент файли:

user@host$ find root? -path '*/.git*' -prune -o -print | sort -n 
root1
root1/dir1
root1/dir2
root1/dir2/file1
root1/dir2/file2
root1/dir2/file3
root2
root2/dir1
root2/dir2
root2/dir2/file1
root2/dir2/file2
root2/dir2/file4

Тепер ми ініціалізуємо репост і виконуємо синхронізацію:

cd root1
  git init
  git annex init 'root1'
  git remote add root2 ../root2
  #git annex direct
  git annex add .
  git commit -a -m 'Files added.'
cd ..
cd root2
  git init
  git annex init 'root1'
  git remote add root1 ../root1
  #git annex direct
  git annex add .
  git commit -a -m 'Files added.'
cd ..
mkdir unioned
cd unioned
  git init
  git annex init 'unioned'
  git remote add root1 ../root1
  git remote add root2 ../root2
  git annex add . 
  git commit -a -m 'Files added.'
  git annex sync
cd ..

На даний момент вміст unioned/:

user@host$ find root? unioned -path '*/.git*' -prune -o -print | sort -n
root1
root1/dir1
root1/dir2
root1/dir2/file1
root1/dir2/file2
root1/dir2/file3
root2
root2/dir1
root2/dir2
root2/dir2/file1
root2/dir2/file2
root2/dir2/file4
unioned
unioned/dir2
unioned/dir2/file1
unioned/dir2/file1.variant-065a
unioned/dir2/file1.variant-a33e
unioned/dir2/file2
unioned/dir2/file2.variant-08f3
unioned/dir2/file2.variant-75c4
unioned/dir2/file3
unioned/dir2/file4

Де *.variant-*посилання повертається до різних файлів у різних сховищах. Крім того, unionedдосі не містить даних, поки ми не проведемо git annex get. На даний момент git annex listпоказує, де файли знаходяться та / або отримуються з:

user@host$ cd unioned; git annex list
here
|root1
||root2
|||web
||||
__X_ dir2/file1.variant-065a
_X__ dir2/file1.variant-a33e
__X_ dir2/file2.variant-08f3
_X__ dir2/file2.variant-75c4
_X__ dir2/file3
__X_ dir2/file4

Альтернатива в більш тривалій формі є git annex whereis. Нарешті, для вирішення конфліктів та розповсюдження злиття зсередини unioned/dir2:

cd unioned/dir2
git annex get # retrieve the actual content
git annex unlock # unlock the files - replace the symlinks with the actual repofiles
rm file1
git mv file1.variant-065a file1
git rm -f file1.variant-a33e
rm file2
git mv file2.variant-75c4 file2
git rm -f file2.variant-08f3
git annex add . # "commits" the changes, converts files back into symlinks
git annex sync  # propagates the changes back to the other repos

Який урожай:

git annex sync
commit  ok
pull root2 
ok
pull root1 
ok
push root2 
Counting objects: 61, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (26/26), done.
Writing objects: 100% (37/37), 2.67 KiB | 0 bytes/s, done.
Total 37 (delta 14), reused 0 (delta 0)
To ../root2
   e5df80f..720b34b  git-annex -> synced/git-annex
   b055385..ad8c5c2  master -> synced/master
ok
push root1 
Counting objects: 61, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (26/26), done.
Writing objects: 100% (37/37), 2.67 KiB | 0 bytes/s, done.
Total 37 (delta 14), reused 0 (delta 0)
To ../root1
   e5df80f..720b34b  git-annex -> synced/git-annex
   b055385..ad8c5c2  master -> synced/master
ok

Нарешті, git annex listпоказується, де розташовані ці файли після синхронізації: у unioned/каталозі є копії всіх файлів, вибраних з різних серверів, як зазначено вище.


git-annexтакож є прямий режим, який працює безпосередньо у файловій системі без використання символьних посилань.

Налаштування цього для використання на віддалених комп'ютерах - це питання налаштування віддалених файлів через ssh за допомогою стандартного git, однак його поведінка описана тут: http://git-annex.branchable.com/walkthrough/using_ssh_remotes/

Загальна інформація про додаток до git розміщена тут: http://git-annex.branchable.com/walkthrough/


0

Відповідь на оригінальне запитання, здається, "не на даний момент".

Запропоновано обхідні шляхи, в основі яких:

  • на сумнозвісному інструменті (rsync, із активованою опцією резервного копіювання)
  • на спеціальних файлових системах (таких як ZFS або btrfs), що пропонують "знімок"

Обидві пропозиції передбачають великі введення-виведення, оскільки вони створюють нову файлову систему замість відображення існуючих у віртуальну файлову систему.


0

Замість того, щоб дивитися на рівень файлової системи, оскільки вам потрібно бачити / підтримувати відмінності між версіями. Якщо це текстові файли - тоді git http://git-scm.com/ забезпечить хороше рішення. gitце система управління версіями, яка використовується для вихідного коду, і обробляє як порівняння декількох каталогів файлів (ака сховищ), але розгалуження, розходження та злиття.

Якщо ви не можете використовувати git, тоді rsync запропонує рішення, але вам потрібно буде вручну розробити рішення, щоб вивчити файли, які ви хочете порівняти або об'єднати. За допомогою git ці відмінності відстежуються автоматично.

Якщо вони здебільшого двійкові файли - можливо, ви захочете щось зробити з rsync. Наприклад, із наступним сценарієм: Щоб встановити тест:

set -x
for DIR in a b c ; do mkdir $DIR ; done
for DIR in `ls -d ?`; do
  echo "TESTMSG1-$DIR" >> $DIR/A;
  echo "TESTMSG2-$DIR" >> $DIR/B;
  echo "TESTMSG3-$DIR" >> $DIR/C;
  done
ls
ls -R
grep -r $ ?

І виконати тест, -avза допомогою багатослівної копії архіву, та -cпорівняти файли з контрольною сумою, а -b --suffix=також створити резервні копії файлів із позначкою часу для подальшого порівняння:

rsync -avc -b --suffix=-$(date +%s.bk) a/ b
ls -R
grep -r $ ?
find . -name "*.bk"

Ми показуємо, що файли скопійовані, .bkдодається суфікс із позначенням часу , тоді ви можете знайти резервні файли для подальшого аналізу:find . -name "*.bk"

$ sh test.sh
...output deleted for brevity...
+ ls
a  b  c  test.sh
+ ls -R
a  b  c  test.sh

./a:
A  B  C
./b:
A  B  C
./c:
A  B  C
+ grep -r $ a b c
a/A:TESTMSG1-a
a/B:TESTMSG2-a
a/C:TESTMSG3-a
b/A:TESTMSG1-b
b/B:TESTMSG2-b
b/C:TESTMSG3-b
c/A:TESTMSG1-c
c/B:TESTMSG2-c
c/C:TESTMSG3-c

+ date +%s.bk
+ rsync -avc -b --suffix=-1403746846.bk a/ b
sending incremental file list
A
B
C
sent 300 bytes  received 73 bytes  746.00 bytes/sec
total size is 33  speedup is 0.09
+ ls -R
a  b  c  test.sh

./a:
A  B  C
./b:
A  A-1403746846.bk  B  B-1403746846.bk  C  C-1403746846.bk
./c:
A  B  C
+ grep -r $ a b c
a/A:TESTMSG1-a
a/B:TESTMSG2-a
a/C:TESTMSG3-a
b/A:TESTMSG1-a
b/A-1403746846.bk:TESTMSG1-b
b/B:TESTMSG2-a
b/B-1403746846.bk:TESTMSG2-b
b/C:TESTMSG3-a
b/C-1403746846.bk:TESTMSG3-b
c/A:TESTMSG1-c
c/B:TESTMSG2-c
c/C:TESTMSG3-c

+find . -name "*.bk"
./b/B-1403746846.bk
./b/C-1403746846.bk
./b/A-1403746846.bk

Іншою альтернативою є використання знімків ZFS для «відображення» каталогів у тому ж «просторі імен». Псевдо-код для цих кроків (оскільки я не маю zfs перед собою) буде чимось таким:

for X in (a b c); do 
  zfs snapshot zfs-destination@baseline
  rsync -avc /src-$X/ zfs-destination
  zfs snapshot zfs-destination@$X
  diff -r zfs-destination/ zfs-destination/.zfs/snapshot/$X/
  # analyze diff files and validate changes to commit
  # restore files to not change from .zfs/snapshot/baseline
done

Не те, що ви можете "циркулювати" як сценарій, через вимогу вручну проаналізувати виправлення, але повторення вищезазначених кроків для кожного dir-джерела дасть вам можливість як об'єднатись, так і повну історію за допомогою знімків. Замініть "abc" чимось на зразок date -Isтимчасового позначення знімків.

Я не помітив zfs diffкоманду. Лінія різниці вище повинна бути:

zfs diff -FH zfs-destination/ zfs-destination@baseline | \
  awk '/^[+MR]\tF/ {print $3}' > list

Де awk вибирає (+) для доданих файлів (M) для модифікованих (R) для перейменованих. Це набагато швидше, ніж рекурсивна різниця в каталогах.


Дякую! Перша примітка: я знаю про git (я використовую його щодня), але моя потреба не передбачає (лише) текстових файлів, більш того, їх багато (півмільйона), і вони походять із розкиданих (географічно розповсюджених) резервних копій, які я періодично (постійно) ) запустити за допомогою rsync. Тоді іноді (не часто, на щастя) у мене відбувається збій диска, і мені потрібно об'єднати резервні копії (оскільки вони знаходяться в дещо інших станах. На даний момент я використовую rdfind (для очищення дублікатів) та meld / diff / тощо, щоб перевірити залишки файли (я не можу покластися на часові позначки, тому що моя остання проблема з диском була на головному диску, і я помітив це занадто пізно)
atrent

Друга примітка: ще раз дякую! Я не пам’ятав про параметр резервного копіювання rsync, я думаю, що це вирішує (хоча і з більшою кількістю дискових вводу-виводу) мою проблему.
atrent

@atrent також є "unison" cis.upenn.edu/~bcpierce/unison Я не дуже його використовував, але він більше налаштований на злиття, а не новіший замінює старий, як rsync, і це може бути корисно.
glallen

@atrent також, якщо це вирішило ваше питання, будь-ласка, позначте відповідь відповідним чином. Дякую.
glallen

Unison - одна з найгірших програм, яку я коли-небудь бачив ... непридатна в кращому випадку. Параметр rsync не є повним рішенням, тому я залишаю це питання відкритим.
atrent
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.