\section{Related work}
\label{sec:related-work}
\noindent FGFT draws inspiration from past projects on
driver reliability, program partitioning and software fault isolation 
systems.

\paragraph{Device driver recovery.}
Prior driver-recovery systems, including Nooks~\cite{swift03}, Shadow
drivers~\cite{smb+04}, SafeDrive~\cite{zca+06} and Minix
3~\cite{herder:driver-resilience:dsn:2007} all unload and restart a
failed driver. In contrast, \toolshort\ takes a checkpoint prior to invoking
the driver, and then rolls back to the most recent checkpoint, which
is much faster.  CuriOS provides transparent recovery and further
ensures that client session state can be
recovered~\cite{david08curios}. However, CuriOS is a new operating
system and requires specially written code to take advantage of its
recovery system, while \toolshort\ works with existing driver code in
existing operating systems.
ReViveI/O~\cite{nakano2006revivei}, and similar systems ~\cite{ramachandran2011detecting} 
provide whole-system checkpoint/restore by buffering I/O and only letting it
reach the device after the next memory checkpoint. However, this
approach does not work with polling, where I/O operations cannot be
buffered and applied later.

\paragraph{Driver isolation systems.}

Driver isolation systems rely on hardware protection
(Nooks~\cite{swift03} and Xen~\cite{fhn+04}) or strong in-situ
detection mechanisms (BGI~\cite{Castro:2009}, LXFI~\cite{mczsfi11}, Mondrix~\cite{wra05} and
XFI~\cite{erlingsson:xfi:osdi:2006}) to detect failures in driver
execution. However, in latter systems if the failure is detected {\em
  after} any state shared with the kernel has been modified then these
systems cannot rollback to a last good state.  Other driver isolation
systems such as SUD~\cite{Boyd-Wickizer:2010} and Linux user-mode
drivers~\cite{lcf+05}, require writing
class-specific wrappers in the kernel that are hard to maintain as the
kernel evolves. \toolshort\ differs from existing isolation systems by
providing transactional semantics and limits the runtime
overheads only to suspect code. %Prior work on fast software fault
%isolation, such as BGI~\cite{Castro:2009}, would benefit \toolshort\ by
%improving its performance on I/O-intensive workloads.

\paragraph{Software fault tolerance.}
Existing SFI techniques use programmer annotations
(SafeDrive~\cite{zca+06}) or API contracts (LXFI~\cite{mczsfi11}) to
provide type safety.  XFI~\cite{erlingsson:xfi:osdi:2006} transforms
code binaries to provide inline software guards and stack
protection. In contrast, \toolshort\ operates on source code and allows
drivers to operate on a copy of shared data. \toolshort\ marshals the minimum
required data and uses a range hash to provide spatial safety.


\paragraph{Transactional kernels.}
\noindent 
\toolshort\ executes drivers as a transaction by buffering their state
changes until they complete. VINO~\cite{seltzer1996dealing} similarly
encapsulated extensions with SFI and used a compensation log to undo
kernel changes. However, VINO applied to an entire extension and did
not address recovering device state. In addition, it terminated faulty
extensions, while most users want to continue using devices following
a failure. \toolshort\ is complementary to other transactional systems, such
as TxOS~\cite{porter:txos:sosp:2009}, that provide
transactional semantics for system calls. These techniques could be
applied to driver calls into the kernel instead of using a kernel undo
log of compensation records. Currently, these systems do not perform device I/O 
transactionally and either rely on higher-level atomicity techniques 
(TxOS~\cite{porter:txos:sosp:2009} and xCalls~\cite{volos2009xcalls}) or serialize transactions with a 
lock (TxLinux~\cite{rossbach:tx-linux:sosp:2007}).

\paragraph{Program Partitioning}
\noindent 
Program partitioning has been used for security ~\cite{bs04,clm+07}
and remote code execution~\cite{chun2009augmented}.  Existing program
partitioning tools statically partition user mode code or move driver
code to user mode~\cite{grb08}. \toolshort\ is the first system to partition
programs within the kernel and is hence able to provide partitioning
benefits to kernel specific components such as interrupt delivery and
critical I/O path code. Furthermore, instead of partitioning code in
any one domain, \toolshort\ replicates its entry points and decides on a
runtime basis whether a particular thread should run in isolation.

