%-------------------------------------------------------------------------------
% presentation.tex - presentation of the QCOW2 in-kernel project
%-------------------------------------------------------------------------------
% author   : Manuel Bentele
% date     : Aug 26, 2019
% copyright: (c) 2019 Manuel Bentele
%-------------------------------------------------------------------------------

\documentclass[english]{beamer}

%-------------------------------------------------------------------------------
% Presentation theme settings
%-------------------------------------------------------------------------------
\usetheme{Malmoe}
\usecolortheme{beaver}
\useinnertheme{rounded}

%-------------------------------------------------------------------------------
% Used packages
%-------------------------------------------------------------------------------
\usepackage{colortbl}
\usepackage{xcolor}
\usepackage{hyperref}
\usepackage{tikz}
\usetikzlibrary{positioning, calc, arrows}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat = newest}
\usepackage{pifont}

%-------------------------------------------------------------------------------
% Custom macros and definitions
%-------------------------------------------------------------------------------
\makeatletter\let\frametextheight\beamer@frametextheight\makeatother

\newcommand{\cmark}{\ding{51}}
\newcommand{\xmark}{\ding{55}}

\colorlet{hdr}{green!15}
\colorlet{ret}{yellow!15}
\colorlet{reb}{orange!15}
\colorlet{l1t}{red!15}
\colorlet{l2t}{violet!15}
\colorlet{dat}{cyan!15}

%-------------------------------------------------------------------------------
% General definitions
%-------------------------------------------------------------------------------
\title{QCOW2 in the Linux kernel}
\author[M. Bentele]{Manuel Bentele}
\institute{University of Freiburg}
\date{September 2, 2019}

\begin{document}

\begin{frame}
    \maketitle
\end{frame}

\section{Analysis}
\subsection{Requirements}
\begin{frame}{What has to be done?}
    \begin{block}{Implement the QCOW (QEMU Copy On Write) disk file format version~2 in the Linux kernel such that \dots}
        \vspace*{0.5cm}
        \begin{itemize}
            \item reading of the normal QCOW2 disk file format is possible
            \item compressed \& sparse QCOW2 disk files are supported as well
            \item the disk file format is exposed as block device
            \item the implementation compiles \& runs under Linux kernel 5 later
            \item the performance is better than using qemu-nbd
        \end{itemize} 
    \end{block}
\end{frame}

\subsection{Linux storage stack}
\begin{frame}{How does the Linux storage stack looks like?}
    \begin{center}
        \resizebox{!}{0.775\textheight}{
            \input{images/linux_storage_stack}
        }
    \end{center}
\end{frame}

\subsection{Implementation approaches}
\begin{frame}{How can the implementation be achieved?}
    \begin{block}{\xmark\ FUSE (Filesystem in Userspace) driver}
        \begin{itemize}
            \item implement reading of QCOW2 file format as user space driver
        \end{itemize}
    \end{block}
    \begin{block}{\xmark\ Device mapper target}
        \begin{itemize}
            \item implement reading of QCOW2 file format as mapped target
        \end{itemize}
    \end{block}
    \begin{block}{\xmark\ Custom block driver}
        \begin{itemize}
            \item create block driver \& configuration utility for reading QCOW2
        \end{itemize}
    \end{block}
    \begin{block}{\cmark\ Loop device module extension}
        \begin{itemize}
            \item extend the loop device module \& configuration utility by a file format subsystem to implement QCOW2 as additional file format driver
        \end{itemize}
    \end{block}
\end{frame}

\section{Implementation}
\subsection{Loop device module extension}
\begin{frame}{How is the file format subsystem integrated?}
    \resizebox{\textwidth}{!}{%
        \input{images/file_fmt_subsystem_integration}
    }
    \vfill
    \begin{itemize}
        \item file format subsystem abstracts the direct access to backing files to implement various file formats
        \item file formats are implemented as file format drivers
        \item drivers are registered at the subsystem
        \item subsystem supports (asynchronous) reads, (asynchronous) writes, flushes and virtual disk sizes
    \end{itemize}
\end{frame}

\begin{frame}[fragile, shrink=35]{How does a file format driver look like?}
\begin{verbatim}
#include "loop_file_fmt.h"

static int drv_file_fmt_read(struct loop_file_fmt *lo_fmt,
                             struct request *rq) {
    /* TODO: implement reading of file format */
    return -EIO;
}

static struct loop_file_fmt_ops drv_file_fmt_ops = {
    .read = drv_file_fmt_read
};
    
static struct loop_file_fmt_driver drv_file_fmt = {
    .name = "DRV",
    .file_fmt_type = LO_FILE_FMT_RAW,
    .ops = &drv_file_fmt_ops,
    .owner = THIS_MODULE
};

// register driver with loop_file_fmt_register_driver(&drv_file_fmt)
// unregister driver with loop_file_fmt_unregister_driver(&drv_file_fmt)
\end{verbatim}
\end{frame}

\subsection{QCOW2 file format driver}
\begin{frame}{How is the QCOW2 disk file format structured?}
    \begin{columns}
        \begin{column}[c]{0.25\textwidth}
            \resizebox{\textwidth}{!}{%
                \input{images/qcow2_structure}
            }
        \end{column}
        \begin{column}[c]{0.75\textwidth}
            \begin{itemize}
                \item data is saved in data clusters of equal size (512\,B -- 2\,MB)
                \item header provides offsets to 1st level tables
                \item two-level lookup of data clusters (L1 \& L2~tables)
                \item two-level reference count for copy on write (Refcount \& Refcount block tables)
                \item numbers are stored in big-endian order
                \item data clusters can be compressed or encrypted
                \item support of embedded snapshots by use of internal copy on write
            \end{itemize}
        \end{column}
    \end{columns}
\end{frame}

\begin{frame}{How does QCOW2 addresses data clusters?}
    \begin{itemize}
        \item QCOW2 header stores an offset in the file to the L1~table
        \item L1~table stores offsets in the file to L2 tables
        \item L2~tables stores offsets in the file to the data clusters
    \end{itemize}
    \begin{center}
        \resizebox{!}{0.55\textheight}{%
            \input{images/qcow2_addressing}
        }
    \end{center}
\end{frame}

\begin{frame}{How does the QCOW2 driver read data?}
    \begin{columns}
        \begin{column}[c]{0.4\textwidth}
            \resizebox{\textwidth}{!}{%
                \input{images/qcow2_reading}
            }
        \end{column}
        \begin{column}[c]{0.6\textwidth}
            Given a Linux IO read request with size $S$ and block device offset $O$:
            \begin{enumerate}
                \item calculate cluster $C$ and position $P$ for $O$ using cached L1 \& L2~tables
                \item decompress the data of $C$ if $C$ is compressed
                \item read data from $P$ into IO read request until $S$ bytes or the end of $C$ is reached
                \item repeat steps 1 -- 3 until IO read request is filled with $S$ bytes
            \end{enumerate}
        \end{column}
    \end{columns}
\end{frame}

\subsection{Performance of the driver}
\begin{frame}{How does the implementation perform compared to qemu-nbd?}
    \resizebox{\textwidth}{!}{
        \input{images/qcow2_performance}
    }
\end{frame}

\section{Outlook}
\subsection{Further work}
\begin{frame}{What can be done in the future?}
    \begin{block}{File format subsystem}
        \begin{itemize}
            \item implement other file formats, e.g. VDI, VMDK, \dots
            \item extend the API to support snapshots \& encryption
        \end{itemize}
    \end{block}
    \begin{block}{QCOW2 file format driver}
        \begin{itemize}
            \item implement write operations
            \item implement encryption \& snapshot support
            \item improve performance by hardware aligned cache allocation
            \item add a QCOW2 L2 cache clean interval
        \end{itemize}
    \end{block}
\end{frame}

\end{document}
