\subsection{Funktionsweise} \hfill \includegraphics{ori/ori.pdf} \hspace*{\fill} Wie aus dem Systemdiagramm ersichtlich ist, besteht Ori aus den Teilprogrammen \emph{ori}, \emph{orisync} und \emph{orifs}, die auf \emph{libori} aufgebaut sind. \begin{description} \item[\emph{ori}] stellt die Schnittstelle zum Nutzer dar. Hier werden Repositorien erstellt, gelöscht und manuelle Operationen ausgeführt. Folgende Befehle sind laut Hilfe u.a. implementiert: \begin{description} \item[\emph{newfs [name]}] erstellt ein neues Repo namens \emph{name}. \item[\emph{removefs [name]}] löscht das Repo \emph{name}. \item[\emph{list}] listet alle lokalen Repositorien auf. \item[\emph{status}] gibt eine Liste modifizierter Dateien aus. \item[\emph{diff}] zeigt alle Änderungen seit dem letzten Snapshot an. \item[\emph{snapshot [description]}] erstellt einen Snapshot mit einer optionalen \emph{description}. Zugleich wird das Repo eingecheckt. \item[\emph{purgesnapshot [commitid]}] löscht den Snapshot zu \emph{commitid} und gibt Speicher frei. \item[\emph{snapshots}] gibt eine Liste aller für das Repo vorhandennen Snapshots aus. \item[\emph{log}] zeigt die History des Repos an. \item[\emph{filelog [file]}] zeigt die History der Datei \emph{file} an. \item[\emph{replicate [node:repo]}] repliziert das Repo \emph{repo} von Node \emph{node}. \item[\emph{pull}] synchronisiert manuell das Repo. \item[\emph{merge [commitid]}] vereinigt manuell das vorhandene Repo mit dem von \emph{commitid}. \item[\emph{checkout [commitid]}] checkt das Repo mit \emph{commitid} lokal aus. \item[\emph{tip}] gibt die letzte Commit-ID des Repos aus. \item[\emph{show}] zeigt Informationen zum Repo (Verzeichnis, UUID und HEAD des Repos, sowie aktuelle Version von Ori) an. \end{description} \item[\emph{orisync}] entdeckt andere Kopien eines Repos und synchronisiert diese automatisch. \begin{description} \item[\emph{init}] startet die interaktive Konfiguration von \emph{orisync}, in der ein neues Cluster erstellt oder der genutzte Node einem bestehendem Cluster hinzugefügt werden kann. \item[\emph{add [repo]}] fügt \emph{repo} zu den verwaltenden Repositorien hinzu. \item[\emph{remove [repo]}] entfernt \emph{repo} aus der automatischen Synchronisation. \item[\emph{list}] listet alle Repositorien auf, die \emph{orisync} verwaltet. \item[\emph{hostadd [host]}] fügt einen statischen Host \emph{host} hinzu. \item[\emph{hostremove [host]}] entfernt den Host \emph{host}. \item[\emph{hosts}] listet alle eingetragenen Hosts auf. \end{description} \item[orifs] nutzt \emph{libFUSE}, um Repositorien als FUSE-Dateisysteme einzubinden. Desweiteren produziert \emph{orifs} automatisch in periodischen Abständen (Tag, Woche, Monat und Jahr) Snapshots. \begin{description} \item[\emph{[OPTIONS] mountpoint}] bindet ein Repo in \emph{mountpoint} ein. Das Verzeichnis \emph{mountpoint} muss vorhanden sein. \emph{OPTIONS} sind u.a.: \begin{description} \item[\emph{-- --repo=[REPO PATH]}] für abweichenden Pfad zum Repo \emph{REPO PATH} \item[\emph{-- --shallow}] erzeugt Kopie mit Hintergrundtransfer \item[\emph{-- --nocache}] erzeugt Kopie ohne Caching \item[\emph{-- --journal-none}] deaktiviert das Wiederherstellungs-Journal \item[\emph{-- --journal-async}] für asynchrones Wiederherstellungs-Journal \item[\emph{-- --journal-sync}] für synchrones Wiederherstellungs-Journal \end{description} \end{description} \pagebreak \item[\emph{libori}] verwaltet die Repositorien bestehend aus Index, Objekt-Speicher und Objekt-Metadaten. Die Repositorien werden lokal unter \emph{.ori} im Home-Verzeichnis gespeichert. \end{description} Beispielverzeichnis mit einem replizierten Repo \emph{repo}: \\ \begin{tikzpicture} \treeroot{.ori/} \altentry{repo.ori/}{1} \altentry{objs/}{2} \altentry{pack0.pak}{3} \altentry{refs/}{2} \altentry{heads/}{3} \altentry{default}{4} \altentry{remotes/}{3} \altentry{origin}{4} \altentry{tmp/}{2} \altentry{fuse/}{3} \altentry{journal}{4} \altentry{trusted/}{2} \altentry{HEAD}{2} \altentry{id}{2} \altentry{index}{2} \altentry{metadata}{2} \altentry{ori.log}{2} \altentry{README}{2} \altentry{snapshots}{2} \altentry{uds}{2} \altentry{version}{2} \altentry{oricli.log}{1} \altentry{orisync.log}{1} \altentry{orisyncrc}{1} \end{tikzpicture} Das Verzeichnis \emph{.ori} enthält neben dem Repo \emph{repo.ori} die beiden Logs für den Ori-Client und Orisync, sowie die Konfigurationsdatei für Orisync. Im Repo befindet sich neben einer \emph{id}, einem \emph{index} (Speicheradressierung durch Hash-Summen), dem Log und der Version von Ori, sowie den Metadaten und Snapshots, noch der Unix Domain Socket, ein Verweis auf den \emph{HEAD} des Repos und der Objektspeicher \emph{objs} mit den verschlüsselten \emph{*.pak}-Archiven, das Verzeichnis \emph{ref} bestehend aus den Unterverzeichnissen \emph{heads} (Commit-ID des Repo-Heads) und \emph{remotes} (URL des Quell-Repos). \\ Ori's Datenmodell besteht aus Commit-Objekte (Snapshots und History-Kontext), Bäume (Verzeichnisse), Blobs und LargeBlobs (Dateien). Alle Snapshots sind aufgebaut aus den Quell-Baum-Hash, den Eltern-Commit-Hash(es), einem Zeitstempel und dem Nutzernamen. Optional kann der Nutzer eine Beschreibung anhängen. Bäume vereinen den Verzeichniseintrag und die I-Node-Felder in sich. Blobs speichern Daten von weniger als 1MB, LargeBlobs teilen größere Dateien in kleinere Blobs, indem sie eine Liste von Blob-Hashes von Dateiteilen speichern. Dadurch können Blobs dedupliziert werden. Alle Objekte werden durch SHA-256-Hashes eindeutig adressiert. \pagebreak