\chapter{Basic Filesystem}
\label{cha:basicfilesystem}
{\mns 

\subsection{Objectives}

\begin{itemize}
  \item After completing this section, you will be able to:
  \begin{itemize}
    \item Understand a typical Linux filesystem
    \item Navigate the file hierarchy
    \item Manipulate files and directories
    \item Handle access control
    \item Deal with `special files' and {\kwd links}
  \end{itemize}
\end{itemize}



\section{Filesystem Overview}
\label{sec:filesystem-basic-filesystem-overview}

\begin{itemize}
\item Linux uses {\kwd ext3}, \emph{reiserfs} and {\kwd ext2} as its
  {\em native} filesystems
\begin{itemize}
  \item Also supports many other types
\end{itemize}
\item All data stored on a Linux system is a file
\item Ext2/3 file names can be 1 to 255 characters long
\begin{itemize}
  \item Only {\kwd /} and {\kwd nul} are disallowed
\end{itemize}
\item Non-native filesystems have different features
\item Ext2/3 sees only two basic types of files:
  \begin{itemize}
    \item {\kwd directories}
    \item {\kwd files}
  \end{itemize}
\item Other specialised types exist (\FIFO{}s, and `special files'),
  these are covered later
\end{itemize}



\section{Files}
\label{sec:filesystem-basic-files}

\begin{itemize}
  \item Linux imposes no structure on files
  \item All files are accessible at the byte level
  \item Individual files used to have a maximum size of around 2GB ({\em in an
      ext2 filesystem with an older kernel, 2.2.x})
  \item Modern kernels (2.4.x) have a maximum file size of about 8TB
  \item They have a minimum size of 0 bytes
  \item Files can be extended after creation
  \item Filename extensions such as {\kwd .exe} and {\kwd .bat} are unnecessary
  \item Executable files are simply marked as such using file permissions ({\em see later})
\end{itemize}



\section{Directories}
\label{sec:filesystem-basic-directories}

\begin{itemize}
  \item {\kwd Directories} are files that list other files
  \begin{itemize}
    \item Can be normal files or directories
    \item Enables a hierarchy to be built
  \end{itemize}
  \item Each directory entry consists of two parts: a file name and an
        {\kwd inode number} \\{\myss (An inode is roughly a {\em pointer to a file}, see below)} \\ \bigskip
%% {\myss  \begin{tabular}{|p{150pt}|p{150pt}|} \hline
%% Filename & Inode number \\ \hline \hline
%% . & 512\\ \hline
%% .. & 500\\ \hline
%% bin & 17324\\ \hline
%% basic\_linux.tex & 24567 \\ \hline
%% \end{tabular}}
{\myss
\begin{tabular}{>{\ttfamily}p{150pt}p{150pt}}
  \toprule%
  \textnormal{Filename} & Inode number \\
  \midrule%
  . & 512\\
  .. & 500\\
  bin & 17324\\
  basic\_linux.tex & 24567 \\
  \bottomrule
\end{tabular}}
\par\smallskip\par
  \item The topmost directory is always called {\fn /}
  \begin{itemize}
    \item Called the fileystem `root'
  \end{itemize}
  \item Directory information can only be changed by Linux itself
  \begin{itemize}
    \item Ensures a proper structure is maintained
  \end{itemize}
\end{itemize}



\section{Directory Hierarchy}
\label{sec:filesystem-basic-directory-hierarchy}

\begin{itemize}
\item By the \emph{Linux Filesystem Hierarchy Standard} \url{http://www.pathname.com/fhs/}, many directories have specialised r\^oles \bigskip

{\myss 
%% \begin{tabularx}{\linewidth}{|l|Y|} \hline
%%   {\sco /bin} & essential executable commands, available when no other
%%   filesystems are mounted \\ \hline
%%   {\sco /sbin} & essential system administrator commands, needed for
%%   repairing filesystems, when no other filesystems are mounted \\
%%   \hline
%%   {\sco /boot} & static files of the boot loader \\ \hline
%%   {\sco /etc} & system configuration files \\ \hline
%%   {\sco /lib} & essential shared libraries and kernel modules \\ \hline
%%   {\sco /dev} & device files which control peripheral devices \\ \hline
%%   {\sco /tmp} & temporary files \\ \hline 
%%   {\sco /mnt} & to mount external devices \\ \hline
%%   {\sco /var} & variable data files, e.g. logs, status and lock files,
%%   spooling files---let {\sco /usr} be mounted read only \\ \hline
%%   {\sco /proc} & system information, dynamically generated by kernel \\ \hline
%%   {\sco /usr} & shareable, read-only data \\ \hline
%%   {\sco /usr/bin} & most user commands \\ \hline
%%   {\sco /usr/sbin} & further system administration commands \\ \hline
%%   {\sco /usr/lib} & further libraries for programming and shared
%%   libraries used by software packages \\ \hline
%%   {\sco /usr/share} & architecture independent data, including man
%%   pages and documentation \\ \hline 
%% \end{tabularx}
\begin{tabularx}{\linewidth}{>{\ttfamily}lY}
  {\sco /bin} & essential executable commands, available when no other
  filesystems are mounted \\
  {\sco /sbin} & essential system administrator commands, needed for
  repairing filesystems, when no other filesystems are mounted \\
 
  {\sco /boot} & static files of the boot loader \\
  {\sco /etc} & system configuration files \\
  {\sco /lib} & essential shared libraries and kernel modules \\
  {\sco /dev} & device files which control peripheral devices \\
  {\sco /tmp} & temporary files \\ 
  {\sco /mnt} & to mount external devices \\
  {\sco /var} & variable data files, e.g. logs, status and lock files,
  spooling files---let {\sco /usr} be mounted read only \\
  {\sco /proc} & system information, dynamically generated by kernel \\
  {\sco /usr} & shareable, read-only data \\
  {\sco /usr/bin} & most user commands \\
  {\sco /usr/sbin} & further system administration commands \\
  {\sco /usr/lib} & further libraries for programming and shared
  libraries used by software packages \\
  {\sco /usr/share} & architecture independent data, including man
  pages and documentation
\end{tabularx}
}
\bigskip
\item User-installed programs typically go under the {\sco /usr/local} hierachy
\item {\fn /mnt} is a convenience to place all `mounted'
      devices under one place
\end{itemize}



\section{Pathnames}
\label{sec:filesystem-basic-pathnames}

{
\unitlength=1pt
\begin{picture}(200,200)
\put(65,60){\line(1,1){23.5}}
\put(40,30){\framebox(50,30){\normalsize File1}}
\put(110.5,83){\line(1,-1){22.5}}
\put(110,30){\framebox(50,30){\normalsize File2}}
\put(100,100){\circle{40}}
\put(94,98){\makebox{\normalsize lee}}
\put(114.5,114.5){\line(1,1){21.5}}
\put(200,100){\circle{40}}
\put(190,98){\makebox{\normalsize mike}}
\put(163.2,135){\line(1,-1){21.5}}
\put(150,150){\circle{40}}
\put(138,148){\makebox{\normalsize home}}
\put(164.3,164.3){\line(1,1){21.5}}
\put(200,200){\circle{40}}
\put(198,195){\makebox{/}}
\end{picture}
}

\vspace{-30pt}

\begin{itemize}
  \item Files can be referred to by {\kwd relative} or {\kwd absolute} pathnames
  \item Absolute pathnames begin with {\cmdn /}
  \begin{verbatim}
/usr/sbin/httpd
/usr/local/bin/safe-mysqld
  \end{verbatim}
  \vspace{-25pt}
  \item The {\kwd absolute} pathname refers to one file only
  \item A \emph{relative pathname} does not begin with {\fn /} and
    describes the path from the current directory to find a file, e.g.
  \begin{verbatim}
sbin/httpd
bin/safe-mysqld
  \end{verbatim}
\end{itemize}



\section{Current Directory, Home Directory}
\label{sec:filesystem-basic-current-dir}

\begin{itemize}
\item Every process has a \texttt{current directory}
\item When you log in your shell's current directory is your {\kwd
    home directory}
  \begin{itemize}
  \item Typically {\cmdn /home/username}
  \item Superuser usually has {\fn /root} for a home directory
  \end{itemize}
\item {\pgn pwd} tells you the current directory
\end{itemize}
% \item {\fn \verb|~|} is a synonym for {\fn /home/username}
\begin{description}
\item[$\sim$\ \ \ ] the shell expands this to name of your home
  directory
  \begin{itemize}
  \item The ``$\sim$'' character is called ``tilde''
  \end{itemize}
\item [$\sim$\meta{user}\ \ \ ] the shell expands this to the name of
  the home directory of the user with user name \meta{user}
\end{description}
  
\subsection{The \texttt{cd} Command}
\label{sec:filesystem-basic-cd-command}

\begin{itemize}
\item {\pgn cd} changes your current directory
  \begin{itemize}
  \item Typing {\cmdn cd \meta{path}} changes your current directory
    to \meta{path}
  \end{itemize}
\item {\pgn path} can be {\kwd absolute} or {\kwd relative}
\item Without arguments {\pgn cd} changes to your home directory
\end{itemize}



\section{Dot (.) and DotDot(..)}
\label{sec:filesystem-basic-dot-dotdot}

\begin{itemize}
\item Directories always contain two entries ``\texttt{.}'' and ``\texttt{..}''
\\ \bigskip
%% \begin{tabular}{|p{50pt}|>{\PBS\rr}p{203pt}|} \hline
%% {\cmdn .} & Current directory \\ \hline
%% {\cmdn ..} & Parent directory \\ \hline
%% \end{tabular}
\begin{tabular}{p{50pt}>{\PBS\rr}p{203pt}}
{\cmdn .} & Current directory \\
{\cmdn ..} & Parent directory \\
\end{tabular}
\vspace{16pt}
\item Used for relative pathnames and navigation
\item Example:

{\myss \vspace{10pt}
%% \begin{tabular}{|p{90pt}|>{\PBS\rr}p{243pt}|} \hline
%% {\cmdn \$ mv file ..} & Move {\fn file} to the parent directory \\ \hline
%% {\cmdn \$ du .} & Display space used by files in current directory and below \\ \hline
%% {\cmdn \$ du ..} & Display space used by files in parent directory and below \\ \hline
%% {\cmdn \$ ./a.out} & Execute the file {\fn a.out} in the current directory \\ \hline
%% \end{tabular}
\noindent
\begin{tabularx}{\linewidth}{lY}
\texttt{\$ \textbf{cd ..}} & Change to the parent directory \\
{\cmdn \$ \textbf{mv file ..}} & Move {\fn file} to the parent directory \\
{\cmdn \$ \textbf{du .}} & Display space used by files in current directory and below \\
{\cmdn \$ \textbf{du ..}} & Display space used by files in parent directory and below \\
{\cmdn \$ \textbf{./a.out}} & Execute the file {\fn a.out} in the current directory \\
\end{tabularx}
\vspace{10pt}}

  \item This last row above shows execution of the particular
    file that is in the current directory
    \begin{itemize}
    \item If we had simply typed {\cmdn a.out} then our \texttt{PATH}
      environment variable would be used to search for the file
    \item It may execute another {\fn a.out} instead of the one we
      {\em actually} want
    \end{itemize}
\end{itemize}



\section{Moving and Copying Files}
\label{sec:filesystem-basic-moving-and-copying-files}

\begin{itemize}
  \item The {\pgn mv} command is used to move files:
\begin{alltt}
mv [\meta{options}] \meta{source file} \meta{dest file}
mv [\meta{options}] \meta{source file}... \meta{target directory}
\end{alltt}
  e.g.
\begin{alltt}
$ \textbf{mv oldname newname}
$ \textbf{mv somefile ..}
\end{alltt}
  \item The {\pgn cp} command is used to copy files:
\begin{alltt}
cp [\meta{options}] \meta{source file} \meta{dest file}
cp [\meta{options}] \meta{source file}... \meta{target directory}
\end{alltt}
  e.g.
\begin{alltt}
$ \textbf{cp -a thisfile newfile}
$ \textbf{cp file1 file2 file3 /tmp}
\end{alltt}
    \begin{itemize}
    \item A \emph{very important option} is {\cmdn -a}, which preserves
      permissions and symbolic links (see
      slide~\S\vref{sec:filesystem-basic-soft-links} for more about
      symbolic links).
    \item Can even use {\cmdn cp -ax} to clone a hard disk partition.
    \end{itemize}
    
  \item See \texttt{man cp} and \texttt{man mv}
\end{itemize}




\section{Removing Files}
\label{sec:filesystem-basic-removing-files}

\begin{itemize}
  \item Files are removed using the {\cmdn rm} command:
\begin{alltt}
rm [\meta{options}] \meta{file}...
\end{alltt}
  e.g.
\begin{alltt}
$ \textbf{rm -i thisfile thatfile}
rm: remove `thisfile'?  \textbf{y}
rm: remove `thatfile'?  \textbf{y}
$
\end{alltt}
  \item Most useful options are:
  \bigskip \\
%% \begin{tabular}{|p{50pt}|>{\PBS\rr}p{283pt}|} \hline
%% {\cmdn rm -f} & Force removal and say nothing if cannot remove \\ \hline
%% {\cmdn rm -r} & Recursively delete files \\ \hline
%%   \end{tabular}
\begin{tabularx}{\linewidth}{lY}
{\cmdn rm -f} & Force removal and say nothing if cannot remove \\
{\cmdn rm -r} & Recursively delete files
\end{tabularx}

\vspace{10pt}
  e.g.
\begin{alltt}
$ \textbf{rm -rf somedir}
\end{alltt}%$
will delete all files and subdirectories in directory \texttt{somedir}
and below
  \item See {\cmdn man rm}
  \item Removing a file is {\em not} considered an operation on the file
  \begin{itemize}
    \item It is an operation on the directory
    \item Filenames are merely {\kwd links} {\myss (Explained below)}
  \end{itemize}
\end{itemize}



\section{Operations on Directories}
\label{sec:filesystem-basic-directory-operations}

%% \begin{tabular}{|p{80pt}|>{\PBS\rr}p{253pt}|} \hline
%% {\pgn mkdir} & Create a new directory \\ \hline
%% {\pgn rmdir} & Remove a directory \\ \hline
%% {\pgn ls} & List the contents of a directory \\ \hline
%% \end{tabular}
\begin{tabularx}{\linewidth}{lY}
{\pgn mkdir} & Create a new directory \\
{\pgn rmdir} & Remove a directory \\
{\pgn ls} & List the contents of a directory \\
\end{tabularx}
\bigskip
\begin{itemize}
  \item These commands can take many arguments
  \item {\pgn mkdir} can be told to create the whole pathname of directories if they don't exist, e.g.
\begin{alltt}
$ \textbf{mkdir -p \(\sim\)/new1/test/directory}
\end{alltt}%$
Will create the directories \texttt{$\sim$/new1} and
\texttt{$\sim$/new1/test} as well as
\texttt{$\sim$/new1/test/directory} if they don't already exist
  \item {\pgn ls} arguments control what information is shown and how it's sorted
  \begin{itemize}
    \item Some are explained later, consult {\cmdn man ls} for full
    details.  Also see figure~\vref{fig:ls-l-output} for meaning of
    output of \texttt{ls~-l}.
  \end{itemize}
\end{itemize}

\section{Inodes}
\label{sec:filesystem-basic-inodes}

\begin{itemize}
  \item Each file is represented by an inode\footnote{The term {\kwd inode} was invented
        by Dennis Ritchie of AT\&T. He admits to forgetting why he chose that name.}
  \item An {\kwd inode} contains information about:
  \begin{itemize}
    \item File type (ordinary, directory, FIFO, block device etc.)
    \item Owner ID (user the file belongs to)
    \item Size (in bytes)
    \item Access, creation, and modification times
    \item Group ID (group the file belongs to)
    \item File permissions
    \item Mapping of the file contents (data sectors)
  \end{itemize}
  \item Inode layout and location varies with filesystem type
\end{itemize}



\section{Inodes: \texttt{ls -i} and \texttt{stat}}
\label{sec:filesystem-basic-inodes-ls-i-stat}

\begin{itemize}
\item {\pgn ls -i} displays inode numbers of entries, e.g.
\begin{alltt}\myss
$ \textbf{ls -i}
200808 Ext2fs-0.1-14.html   542726 include
200795 Ext2fs-0.1-2.html    188447 info
200797 Ext2fs-0.1-4.html    333831 ldap
200802 Ext2fs-0.1-8.html    329729 man
200803 Ext2fs-0.1-9.html    278533 misc
200793 Ext2fs-0.1.html      428042 nsmail
204802 systemprogramming
\end{alltt}%$
\item {\pgn stat} prints the inode contents for files inc. permissions, size, links, access times etc.
\begin{alltt}\myss
$ \textbf{stat /home/lee}
File: "/home/lee"
Size: 4096         Filetype: Directory
Mode: (0755/drwxr-xr-x) Uid:(504/lee) Gid:(502/lee)
Device:  3,0   Inode: 200705    Links: 30   
Access: Thu May 27 10:54:55 1999(00000.00:01:43)
Modify: Thu May 27 10:44:41 1999(00000.00:11:57)
Change: Thu May 27 10:44:41 1999(00000.00:11:57)
\end{alltt}%$
\end{itemize}



\section{Links}
\label{sec:filesystem-basic-links}

\begin{itemize}
  \item More than one filename can refer to an inode
  \begin{itemize}
    \item These file names are {\em links} to the file
  \end{itemize}
  \item {\pgn ln} creates links to files
  \begin{itemize}
    \item Creates {\kwd hard links} by default
    \item {\pgn ln -s} creates {\kwd symbolic} or {\kwd soft links}
  \end{itemize}
  \item Erasing a file just removes its directory entry
  \begin{itemize}
    \item The file is only lost when all entries for it have been removed
  \end{itemize}
  \item Important: A filename is {\em not} the file
  \begin{itemize}
    \item The inode {\em is} the file
    \item All names are simply links (references) to the inode
    \item A bit like a Windows' `shortcut'
  \end{itemize}
\end{itemize}



\section{Hard links}
\label{sec:filesystem-basic-hard-links}

\begin{itemize}
\item A {\kwd hard link} is merely a directory entry with the relevant
  {\kwd inode} number
  \item Consider the following
  \begin{itemize}
  \item  Start with:
\begin{alltt}\myss
$ \textbf{ls -li}
428175 -rw-rw-r-- ... 4 May 26 13:18 test
\end{alltt}%$
\item We create a {\kwd hard link}:
\begin{alltt}\myss
$ \textbf{ln test hl}
$ \textbf{ls -li}
428175 -rw-rw-r-- ... 4 May 26 13:18 hl
428175 -rw-rw-r-- ... 4 May 26 13:18 test
\end{alltt}
  \end{itemize}
  \item N.B. {\kwd Hard links} cannot cross filesystems
  \item {\kwd Inode} numbers are filesystem specific
\end{itemize}
\begin{center}
  \includegraphics[width=\linewidth]{../images/basic_filesystem_hard_links}
\end{center}



\section{Symbolic Links (Soft Links)}
\label{sec:filesystem-basic-soft-links}

\begin{itemize}
\item \emph{Symbolic} (or {\kwd Soft}) \emph{links} store the pathname
  of the linked file
  \item This means they can cross filesystems.
  \item Adding a {\kwd symbolic link}:
\begin{alltt}\myss
$ \textbf{ln -s test sl}
$ \textbf{ls -li}
428175 -rw-rw-r-- ... 4 May 26 13:18 hl
428176 lrwxrwxrwx ... 4 May 26 13:19 sl -> test
428175 -rw-rw-r-- ... 4 May 26 13:18 test
\end{alltt}
\end{itemize}
\begin{center}
  \includegraphics[width=\linewidth]{../images/basic_filesystem_soft_links-1}
\end{center}

\section{Symbolic (or Soft) Links (continued)}
\label{sec:filesystem-basic-soft-links-cntd}

\begin{itemize}
\item If we replace the {\fn test} file with another then the symbolic
  link still works, but the hard one still points to the old file!
\begin{alltt}\myss
$ \textbf{mv ../test2 test}
$ \textbf{ls -li}
428175 -rw-rw-r-- ...  5 May 26 13:45 hl
428176 lrwxrwxrwx ...  4 May 26 13:19 sl -> test
428178 -rw-rw-r-- ... 15 May 26 13:47 test
\end{alltt}
\end{itemize}
\begin{center}
  \includegraphics[width=\linewidth]{../images/basic_filesystem_soft_links-2}
\end{center}



\section{File Ownership, Users and Groups}
\label{sec:filesystem-basic-users-and-groups}

\begin{itemize}
\item Every user has a unique user \ID and a unique primary group
\item When a user starts a process, the process is owned by the user
  \ID and primary group of the user
\item Every file has a user that owns the file, and a group that owns
  the file.
\item When a process creates a file, the file is owned by the same
  user and group as the process
\item E.g., if user \texttt{nicku} with primary group \texttt{staff}
  creates a file, then the file will be owned by user \texttt{nicku}
  and group \texttt{staff}.
\item Figure~\vref{fig:ls-l-output} shows how \texttt{ls~-l} shows
  file ownership.
\end{itemize}
\begin{figure}[htb]
  \centering%
  \includegraphics[width=\textwidth]{../images/ls-l-output}
  \caption{The output of \texttt{ls -l}: what each field is.}
  \label{fig:ls-l-output}
\end{figure}

\section{Access Control, Users and Groups}
\label{sec:filesystem-basic-Access-Control-and-UID}

\begin{itemize}
  \item File access can be limited to specific users
  \item {\em Super} user(s) can override access control
  \item Access control is set by user and group ID
  \item Each user has a user-id ({\kwd UID}) and one or more group-ids
    {\kwd GIDs})
  \item Processes have an associated UID and GID
  \begin{itemize}
    \item Inherited from the user who created the process
  \end{itemize}
  \item They can however can be changed:
  \begin{itemize}
    \item Processes are known as set-user ID (\SUID) if they set
      their own user ID equal to the user that owns the executable file,
    \item or set-group ID (\SGID) if they set their own group ID
      equal to the group owner of the file
  \end{itemize}
\item There are three special modes that we will examine in the next
  module: ``set user ID'', ``set group ID'' and the ``restriction
  deletion flag''.
  You can read about them in \texttt{info}:
\begin{alltt}
$ \textbf{info '(coreutils)Mode Structure'}
$ \textbf{info '(coreutils)Numeric Modes'}
\end{alltt}
\end{itemize}



\section{Categories of Access Control}
\label{sec:filesystem-basic-categories-of-access-control}

\begin{itemize}
\item There are three categories of access, and three categories of
  user:
  \par\bigskip\par
%%     \begin{tabular}{|p{180pt}|p{40pt}|} \hline
%% read           &  {\sco r} \\ \hline
%% write          &  {\sco w} \\ \hline
%% execute        &  {\sco x} \\ \hline
%%     \end{tabular}
%%     \begin{tabular}{p{180pt}p{40pt}}
%%       read           &  {\sco r} \\
%%       write          &  {\sco w} \\
%%       execute        &  {\sco x} \\
%%     \end{tabular}
  \begin{tabularx}{\linewidth}{Yp{40pt}cY>{\ttfamily}p{40pt}}
    %\begin{tabularx}{\linewidth}{Yp{40pt}@{\hspace*{1em}}Y>{\ttfamily}p{40pt}}
    \toprule%
    \multicolumn{2}{c}{\textbf{Category of Access}} &&
    \multicolumn{2}{c}{\textbf{Set of Users}}\\
    \cmidrule(r{0.75em}){1-2} \cmidrule(l{0.25em}){4-5}%
    \textbf{r}ead           &  {\sco r}& & \textbf{u}ser & u \\
    \textbf{w}rite          &  {\sco w}& & \textbf{g}roup & g \\
    e\textbf{x}ecute        &  {\sco x}& & \textbf{o}thers & o \\
    \bottomrule
  \end{tabularx}
  \par\bigskip\par
\end{itemize}
%% \begin{description}
%% \item[read:]
%%   \begin{description}
%%   \item[For files:] the permission to open the file for reading
%%   \item[For directories:] the permission to list the file names
%%   \end{description}
%% \item[write:]
%%   \begin{description}
%%   \item[For files:] the permission to open the file for writing
%%   \item[For directories:] the permission to create and delete files in
%%     the directory
%%   \end{description}
%% \item[execute:] 
%%   \begin{description}
%%   \item[For files:] the permission to execute the file; scripts need
%%     the read permission also.
%%   \item[For directories:] the permission to change into the directory
%%   \end{description}
%% \end{description}
\begin{tabularx}{\linewidth}{@{}>{\ttfamily\bfseries}lYY@{}}
\toprule%
\textnormal{\textbf{Permission}}& \textbf{For Files} & \textbf{For Directories}\\
\midrule%
read & permission to open the file for reading & permission to list the file names\\
write & permission to open the file for writing & permission
to create and delete files in the directory \\
execute & permission to execute the file; scripts also need
read permission. & permission to change into the directory\\
\bottomrule
\end{tabularx}
  \par\bigskip\par
\begin{itemize}
\item There are three sets of access control, one for each of the
  three sets of users:
  \begin{itemize}
  \item[user:] the user that owns the file
  \item[group:] members of the group that owns the file, except for
    the user that owns the file
  \item[others:] all users who are not the owner of the file, and who
    are not members of the group that owns the file.
  \end{itemize}
\end{itemize}


\section{Access Control --- Example}
\label{sec:filesystem-basic-example}

\begin{itemize}
  \item {\cmdn ls -l} shows the access permissions, e.g.
\begin{alltt}\myss
$ \textbf{ls -l}
-rw-rw-r-- 1 www    www    x_windows.tex
lrwxrwxrwx 1 lee    lee    img -> ../linux/img/
-rw-rw-r-- 1 lee    lee    test.log
\end{alltt}%$

%  \input{../permissions.latex}
\item There are three sets of permissions, each of which applies to
  one set of users
  
\item To find permissions that apply to a user, determine what set of
  users the user belongs to, and then those permissions apply to that
  user.
\begin{center}
   \includegraphics[height=0.8\linewidth]{../images/perms}
\end{center}
\end{itemize}

\section{Examples of minimum file permission requirements}
\label{sec:filesystem-basic-minimum-file-permissions}

\begin{itemize}
\item This table shows examples of minimum file permission
  requirements 
\item It is based on table 2-2 on page 37 of the book \emph{Essential
    System Administration} by \AE leen Frisch, O'Reilly 2002.
  
\item I recommend this excellent book.

  {\myfs
  \begin{tabular}[t]{@{}>{\ttfamily}lcc@{}}
    \toprule%
    \textnormal{Command} & \multicolumn{2}{c@{}}{minimum access required}\\
    \cmidrule(l){2-3}%
    & on the file & on the directory\\
    \midrule%
    cd /var/project & no file & \texttt{--x}\\
    ls /var/project & \texttt{---} & \texttt{r--}\\
    ls -l /var/project & \texttt{---} & \texttt{r-x} \\
    cat /var/project/user1.txt & \texttt{r--} & \texttt{--x} \\
    echo "hello" >> /var/project/user1.txt & \texttt{-w-} &
    \texttt{--x} \\
    /var/project/binary-program & \texttt{--x} & \texttt{--x} \\
    /var/project/script-program & \texttt{r-x} & \texttt{--x} \\
    rm /var/project/user1.txt & \texttt{---} & \texttt{-wx} \\
    \bottomrule
  \end{tabular}}
\end{itemize}




\section{Changing Access Permission: \texttt{chmod}}
\label{sec:filesystem-basic-chmod-1}

\begin{itemize}
  \item Only the owner of a file (or the super-user) may alter its access permissions
  \item {\pgn chmod} (change mode) changes access permissions
  \begin{itemize}
    \item Works in two ways, symbolically or numerically
    \item Symbolically is easier to remember (for most)
  \end{itemize}
\end{itemize}

% Nick: TODO:  Add some exercises here.



\section{\texttt{chmod} symbolically}
\label{sec:filesystem-basic-chmod-symbolically}

\begin{itemize}
  \item Select who you want to change permissions for {\sco (u=user, g=group, o=others, a=all)}
  \item Decide whether you want to {\sco grant a permission(+), remove(-), or set(=)} it
  \item Take the permission that you want to change {\sco (r=read, w=write, x=execute)}
  \item Example:
\begin{alltt}
$ \textbf{chmod gu+w filename}
\end{alltt}%$
        Adds write permission for user and group
  \item You can make several changes by separating the settings with commas, e.g.
\begin{alltt}
$ \textbf{chmod a-w,gu=rw filename}
\end{alltt}%$
Removes write permission for all, then grants it for the user and
group
\end{itemize}



\section{\texttt{chmod} numerically}
\label{sec:filesystem-basic-numerically}

\begin{itemize}
\item Once you know this it is often quicker
\item An octal digit represents each permission type
  \par\bigskip\par
%%{\myss
%% \begin{tabular}{|p{40pt}|p{153pt}|} \hline
%% 4 & read permission \\ \hline
%% 2 & write permission \\ \hline
%% 1 & execute permission \\ \hline
%%\end{tabular}}
\begin{tabular}{p{40pt}p{153pt}}
4 & read permission \\
2 & write permission \\
1 & execute permission
\end{tabular}
\par\medskip\par
\item Add up the permission numbers you want for each user group (owner, group, all)
      and supply these to {\pgn chmod}
\item Example:
\begin{alltt}
$ \textbf{chmod 755 filename}
\end{alltt}%$
grants all permissions to the owner (4+2+1), and read and execute
(4+1) to group and all others
\begin{itemize}
\item \texttt{chmod 755 filename} is equivalent to
  \texttt{chmod~u=rwx,go=rx~filename}
\end{itemize}
\end{itemize}

\section{Special Permissions: SUID, SGID}
\label{sec:filesystem-basic-special-perms-suid-sgid}

\begin{itemize}
\item When the \SUID permission applies to an \emph{executable file},
  then, when it is executed, the file will execute with the \acro{UID}
  of the \textcolor{red}{owner of the file}, instead of the \acro{UID}
  of the \textcolor{blue}{person executing the program}.
\item When the \SGID permission applies to an \emph{executable file},
  then, when it is executed, the file will execute with the \acro{GID}
  of the \textcolor{red}{group owner of the file}, instead of the
  \acro{GID} of the \textcolor{blue}{person executing the program}.
\item When the \SGID permission applies to a directory, then all files
  created there have the same group owner as the directory, instead of
  the group owner of the process that created the file, as would be
  the case otherwise.
\item When the \emph{restricted deletion flag} (``sticky bit'') is
  enabled on a directory, then only the owner of a file (and
  \texttt{root}) may delete or modify the file.  Normally, \emph{if
    other permissions allow it}, anyone may delete or modify a file
  that they do not own.
\end{itemize}


\section{\texttt{chmod}: Symbolic Permissions}
\label{sec:filesystem-basic-chmod-symbolic-suid-sgid}

\begin{itemize}
\item To apply the \SUID permission to \texttt{file}:
\begin{alltt}
$ \textbf{chmod u+s file}
\end{alltt}%$
\item To apply the \SGID permission to \texttt{file}:
\begin{alltt}
$ \textbf{chmod g+s file}
\end{alltt}%$
\item The \emph{restricted deletion flag} (``sticky bit'') permission
  applies only to the ``others'' part of the file permissions, but it
  behaves as I described above.  To apply the ``restricted deletion
  flag'' permission to \texttt{directory}:
\begin{alltt}
$ \textbf{chmod o+t directory}
\end{alltt}%$
\end{itemize}


\section{\texttt{chmod}: SUID, SGID}
\label{sec:filesystem-basic-chmod-suid-sgid}

\begin{itemize}
\item The permissions for \SUID and  \SGID are specified numerically
  like this:
  \par\smallskip\par
  \begin{tabular}[t]{@{}ll@{}}
    \toprule%
    \textbf{numeric mode} & \textbf{changes:}\\
    \midrule%
    2000 & set group \ID \\
    4000 & set user \ID \\
    1000 & restricted deletion flag (``Sticky bit'')\\
    \bottomrule
  \end{tabular}
  \par\smallskip\par
\item Example:
\begin{alltt}\myss
# make the program executable file \texttt{/tmp/ash} \SUID:
$ \textbf{sudo chmod 4755 /tmp/ash}
# make the program executable file \texttt{/tmp/ash} both \SUID \emph{and} \SGID:
$ \textbf{sudo chmod 6755 /tmp/ash}
# remove the \SUID and \SGID permissions from \texttt{/tmp/ash}:
$ \textbf{sudo chmod 755 /tmp/ash}
\end{alltt}%$

\item The permission for \SUID and  \SGID is specified symbolically
  with `\texttt{s}', and can be added or removed from user or group
  permissions.
\item Example:
\begin{alltt}\myss
# make the program executable file \texttt{/tmp/ash} \SUID:
$ \textbf{sudo chmod u+s /tmp/ash}
# make the program executable file \texttt{/tmp/ash} both \SUID \emph{and} \SGID:
$ \textbf{sudo chmod ug+s /tmp/ash}
# remove the \SUID and \SGID permissions from \texttt{/tmp/ash}:
$ \textbf{sudo chmod ug-s /tmp/ash}
\end{alltt}%$
\end{itemize}

% Nick: TODO:  Add some exercises here, compare with those from last
% section.

\section{Set Group ID Directory}
\label{sec:filesystem-basic-setgid-dir}

\begin{itemize}
\item If the ``set group id'' (\SGID) permission is set on a directory, then:
  \begin{itemize}
  \item if a user makes a change to a file or creates a file in that
    directory, the file will have group owner the same as the
    directory.
    
  \item If a user creates a directory in that directory, it too will
    have the Set Group \ID bit set.  As with the file, it will have a
    group owner the same as the group owner of its parent \SGID
    directory.
  \end{itemize}
\end{itemize}

\section{Set Group ID Directory --- Example}
\label{sec:filesystem-basic-setgid-dir-example}

\begin{itemize}
\item Let's see the result of creating a file in {\fn /var/project}
  both before and after adding this permission:
{\myfs
\begin{alltt}
$ \textbf{ls -ld /var/project}
drwxrwx---    2 root     admin        4096 Jan  2 13:48 project
$ \textbf{touch /var/project/test1}
$ \textbf{ls -l /var/project}
-rw-rw-r--    1 nicku    nicku           0 Jan  2 13:53 test1
\end{alltt}}%$
  Now we add the set group \ID bit to the directory permissions, and
  see the effect:
{\myfs
\begin{alltt}
$ \textbf{sudo chmod g+s /var/project}
$ \textbf{ls -ld /var/project}
drwxrws---    2 root     admin        4096 Jan  2 13:48 project
$ \textbf{touch /var/project/test2}
$ \textbf{ls -l /var/project}
-rw-rw-r--    1 nicku    nicku           0 Jan  2 13:53 test1
-rw-rw-r--    1 nicku    admin           0 Jan  2 13:54 test2
\end{alltt}}
\begin{itemize}
\item Note that the user \texttt{nicku} has primary group
  \texttt{nicku}, and is also a member of the \texttt{admin} group.
\end{itemize}

\item when the directory is not \SGID, files I create
  have my primary group ID.

\item when the directory \emph{is} \SGID, files I create
  have the group \ID of the directory.  This allows others in the group
  to read, write and change the files created by any group member.
\end{itemize}


\section{Restricted Deletion Flag (``Sticky Bit'') on Directories}
\label{sec:filesystem-basic-sticky-bit-on-directories}

\begin{itemize}
\item When a directory has the \emph{restricted deletion flag}
  (``sticky~bit'') set:
  \begin{itemize}
  \item Files cannot be overwritten or deleted by any user except the
    user that created the file
  \item Normally, \emph{if other permissions on the directory allow},
    anyone may delete a file they do not own.
  \end{itemize}
\item Use in \texttt{/tmp} to protect users' files from being altered
  by other users
\end{itemize}
\begin{alltt}
$ \textbf{ls -ld /tmp}\myss
drwxrwxrwt  397 root     root        12288 Feb  5 13:07 /tmp
         \(\uparrow\)
\end{alltt}%$
\begin{itemize}
\item Notice that instead of ``\texttt{x}'' for others, there is a
  ``\texttt{t}''
\item Anyone can create a new file in \texttt{/tmp}, but only the
  \texttt{root} user can overwrite or delete files they do not own.
\item Useful for many applications besides protecting files in the
  \texttt{/tmp} directory.
\item Add to a directory with this command:
\begin{alltt}
$ \textbf{sudo chmod o+t \meta{directory}}
\end{alltt}%$
\end{itemize}

\section{\texttt{umask}}
\label{sec:filesystem-basic-umask}

\begin{itemize}
\item Files begin with a default access setting; files with
  \texttt{-rw-rw-rw-}, or 0666, and directories with \texttt{drwxrwxrwx}
  (0777)
  \begin{itemize}
    \item Specified by a user's {\kwd umask} setting
  \end{itemize}
  \item This only works numerically
  \item Unlike {\pgn chmod}, specified permissions are turned {\em
  off}
\begin{itemize}
\item umask specifies permissions which are \emph{absent}
\end{itemize}
  \item With a umask setting of 000 files are created with permissions {\sco rw-rw-rw-} (666)
  \item Default umask (on Red Hat systems) is 002 which means files
    are typically created {\sco rw-rw-r--} (664)~\footnote {This is
      the case on Redhat systems where users typically belong to a
      group of their own; other distributions will probably use a
      default umask of 022.}  e.g.,
\begin{alltt}\myss
$ \textbf{umask 002}
$ \textbf{touch foo}
$ \textbf{ls -l foo}
-rw-rw-r-- 1 lee lee 0 Feb 10 17:17 foo
$ \textbf{umask 222}
$ \textbf{touch foo2}
$ \textbf{ls -l foo2}
-r--r--r-- 1 lee lee 0 Feb 10 17:17 foo2
\end{alltt}

\item The default access setting is bitwise ANDed with the complement
  of the umask.  For example, with a umask of 027, and a default
  setting of 666, we have:
  \par\smallskip\par
  {\myfs
  \begin{tabular}[t]{@{}rrcrcrcr@{}}
    & octal & & \multicolumn{1}{c}{binary} & & AND & &
    \multicolumn{1}{l}{octal}\\
    default & 0666 & & 110\,110\,110 & &
    110\,110\,110\makebox[0pt][l]{\,\,\&}\\
    umask & $\sim$0027 & $\to$ & $\sim$000\,010\,111 & $\to$
    & 111\,101\,000\\
    \cline{6-6}
    & & & & & 110\,100\,000 & $\to$ & 0640 $\to$ \texttt{rw-r-----}
  \end{tabular}}
\end{itemize}



\section{Special Files --- \texttt{/dev}}
\label{sec:filesystem-basic-dev}

\begin{itemize}
\item Files under {\fn /dev} typically represent devices attached to your computer
\item Programs can open and close them and read from and write to them --- as with regular files
\item Kernel code handles exactly how these work
\item Two types
  \begin{itemize}
  \item Block --- Disk drives, \RAID devices, \SCSI devices, \CDROM{}s 
  \item Character --- Printers, modems, tape drives, mice, sound
    devices, \USB devices, etc.
  \end{itemize}
\end{itemize}

% Nick: TODO: exercises:
% See if can find devices for mouse, cdrom.  What type of file are
% they?  (symbolic link).   Why?
% Also identify devices for the hard disks and floppy disk.



\section{Special Files --- \texttt{/proc}}
\label{sec:filesystem-basic-proc}

\begin{itemize}
  \item The section of the filesystem called {\fn /proc} doesn't contain {\em real} files
  \item It contains system status information
  \item It is built dynamically by the Linux kernel
  \item For example:
\begin{table}[htbp]
\vspace{10pt}
{\myss%
  \setlength{\extrarowheight}{0pt}%
  \begin{center}
%\begin{tabular}{|p{110pt}|>{\PBS\rr}p{240pt}|} \hline
\begin{tabularx}{\linewidth}{@{}>{\ttfamily}lY@{}}
\toprule%
\textnormal{Location}      &  Information \\
\midrule%
/proc/\meta{number} &  On specific running processes. See
                   {\cmdn man proc} for details \\
/proc/meminfo & How much memory is in your system and how much is being used \\
/proc/cpuinfo & What \CPU{}(s) you are  currently using \\
/proc/filesystems & Filesystems your kernel supports \\
/proc/mounts & The definitive list of what is actually mounted on your
computer \\
/proc/uptime & The uptime of the system \\
/proc/kcore & An image of your physical memory \\
/proc/net & Network status of your machine \\
/proc/pci & \PCI devices found at initialization \\
/proc/sys & Details on kernel variables, e.g.
\begin{itemize*}
\item Maximum number of files we can open (\texttt{fs/file-max})
\item Number of files currently open (\texttt{fs/file-nr})
  
\item Whether \IP is forwarded between network interfaces
  (\texttt{net/ipv4/ip\_forward})
\end{itemize*}
Set the values ``permanently'' in \path{/etc/sysctl.conf}.  See \texttt{man
  sysctl.conf} and \texttt{man sysctl}\\
\bottomrule%
\end{tabularx}
    
  \end{center}
}
    \caption{System Information from \texttt{/proc}}
    \label{tab:filesystem-basic-sysinfo-from-proc}
\end{table}
\end{itemize}
% Nick: TODO: exercises to see what type of CPU and clock speed from
% /proc/cpuinfo.

\section{Filesystem Structure and \texttt{/etc/fstab}}
\label{sec:filesystem-basic-filesystem-structure}

Multi-Volume Filesystems

\begin{itemize}
\item The filesystem can be held on several devices
\item Large disks can be divided into partitions
\begin{itemize}
  \item This creates several {\em logical} devices
\end{itemize}
\item A basic Linux system must be present on {\fn /}
\item Other parts of the fs may be mounted at any time
\item The main ones are mounted at boot time
\item This is controlled by the important {\fn /etc/fstab} file which
  says which file system is mounted where:
  \begin{itemize}
  \item while the computer starts up, and 
  \item when you type \texttt{mount~\meta{mount point}} or
  \texttt{mount~/dev/\meta{device name}}
  \end{itemize}

\end{itemize}



\section{\texttt{/etc/fstab} --- Example}
\label{sec:filesystem-basic-fstab-example}

% {\myts \begin{tabular}{|p{85pt}|p{100pt}|p{40pt}|p{50pt}|p{24pt}|p{30pt}|} \hline
% Logical Volume&Mount Point&FS type&Options&Dump&Check order \\ \hline \hline
% /dev/hda1&/&ext3&defaults&1&1 \\ \hline
% /dev/hda5&/home&ext3&defaults&1&2\\ \hline
% /dev/hda7&/tmp&ext3&defaults&1&2\\ \hline
% /dev/hda6&/usr&ext3&defaults&1&2\\ \hline
% /dev/hda8&swap&swap&defaults&0&0\\ \hline
% /dev/fd0&/mnt/floppy&ext3&noauto&0&0\\ \hline
% /dev/cdrom&/mnt/cdrom&iso9660&noauto,ro&0&0\\ \hline
% \verb|\\|kashmir\verb|\|c&/mnt/kashmir&smbfs&guest&0&0\\ \hline
% landlord:/var/admin&/var/admin&nfs&defaults&0&0 \\ \hline
% landlord:/home/lee&/home/lee/LANDLORD&nfs&defaults&0&0 \\ \hline
% \end{tabular}}

{\myts%
  \ttfamily%
  \begin{tabular}% {\linewidth}%
{@{}p{95pt}p{90pt}p{35pt}p{105pt}p{24pt}p{30pt}@{}}
\#~Logical~Volume\hspace{3em} \# & Mount Point & FS~type & Options & Dump & Check order \\
/dev/hda1 & / & ext3 & defaults & 1 & 1 \\
/dev/hda5 & /home & ext3 & defaults & 1 & 2\\
/dev/hda7 & /tmp & ext3 & defaults & 1 & 2\\
/dev/hda6 & /usr & ext3 & defaults & 1 & 2\\
/dev/hda8 & swap & swap & defaults & 0 & 0\\
/dev/fd0 & /mnt/floppy & ext3 & noauto & 0 & 0\\
/dev/cdrom & /mnt/cdrom & iso9660 & noauto,ro & 0 & 0\\
\bs\bs{}kashmir\bs{}c & /mnt/kashmir & smbfs & guest & 0 & 0\\
landlord:/var/admin & /var/admin & nfs & defaults & 0 & 0 \\
landlord:/home/lee & /home/lee/LANDLORD & nfs & defaults & 0 & 0\\
/dev/hda5 & /mnt/winas & ntfs & default,ro,umask=0000 & 0 & 0
\end{tabular}%
}

{\myss
\begin{itemize}
\item See \texttt{man fstab}
\item The first field is a device
\item The second field is a directory, the \emph{mount point}, that
  must exist;
\item The third field is the type of the file system (see \texttt{man
    mount} and also \texttt{cat /proc/filesystems})
\item The fourth field is options to \texttt{mount}.  See \texttt{man mount}
\item The second last field says whether the program \texttt{dump}
  should backup this filesystem
\item The last field is:
  \begin{itemize*}
  \item[0] if the program \texttt{fsck} (file system
  check) should check the file system on boot,
\item[1] if it should be
  checked first (should be just the root filesystem ``\texttt{/}''),
\item[2] if it should be checked later in boot sequence.
\end{itemize*}
\item Currently (2004) Red Hat are not putting the \NTFS module into
  the 2.4.x kernel---get the module \RPM from
  \url{http://linux-ntfs.sourceforge.net/rpm/fedora1.html}
\end{itemize}%
}

\section{Mounting Additional Volumes}
\label{sec:filesystem-basic-mount-fs}

\begin{itemize}
  \item To mount a filesystem use {\pgn mount}, e.g.
\begin{alltt}
$ \textbf{mount /dev/cdrom /mnt/cdrom}
\end{alltt}%$
\item Mounts the filesystem {\fn /dev/cdrom} in the directory {\fn /mnt/cdrom}
\item {\cmdn cd /mnt/cdrom} changes directory to the root of
  the \CDROM's filesystem
  \item To unmount use {\cmdn umount name} where {\kwd name} is either the filesystem name or the mount point:
\begin{alltt}
$ \textbf{umount /dev/cdrom}
$ \textbf{umount /mnt/cdrom}
\end{alltt}
\item \emph{Note} --- A filesystem can only be unmounted when it is no
  longer in use.  {\em `In use'} includes:
  \begin{itemize}
    \item Having any file on that filesystem open
    \item Having a shell in a directory on that filesystem
  \end{itemize}

\item Use the {\pgn lsof} (``list open files'') program to identify
  and kill processes that prevent unmounting a file.
\end{itemize}



\section{Mounting shared filesystems}
\label{sec:filesystem-basic-mounting-shared-directories}

\begin{itemize}
  \item {\kwd NFS} filesystems can be mounted with
\begin{alltt}
$ \textbf{mount -t nfs \meta{hostname}:\meta{path} \meta{mount-point}}
\end{alltt}%$
\meta{mount-point} is a directory which must already exist.
\meta{path} is a directory on the \NFS server that it \emph{exports}
to the client.
  \item Example:
\begin{alltt}
$ \textbf{mount -t nfs landlord:/backup /mnt/backup}
\end{alltt}%$
\item The \texttt{mount} program is smart enough to determine that
  the type of the filesystem is \texttt{nfs}, so you do not need to
  specify it:\begin{alltt}
$ \textbf{mount ictlab:/var/ftp/pub /mnt/nfs}
\end{alltt}%$


  \item Share files from MS-Windows machines using {\kwd Samba}
  \item This is a free implementation of the Windows file-sharing
    protocols, e.g.
\begin{alltt}
$ \textbf{mount -t smbfs '\bs\bs{}ntbox\bs{}c' /mnt/ntbox}
\end{alltt}%$
% Nick: Verify the above once kernel and samba people agree on smb or
% smbfs.  Note, 15 Jan 2004: Current kernel in Fedora Core 1
% 2.4.22-1.2149.nptl uses smbfs.
    
  \item {\em N.B.} Linux does not use the `drive letter' concept at
    all
  \begin{itemize}
  \item {\kwd Drives} and {\kwd shares} integrate seamlessly into the
    filename tree
  \end{itemize}
\end{itemize}



\section{Summary}
\label{sec:filesystem-basic-summary}

\begin{itemize}
\item The primary Linux filesystems are Ext3, Reiserfs and Ext2
\item It has a tree-like hierarchy of directories
\item Directories merely contain pointers to files ({\kwd inodes})
\item {\kwd inodes} contain all the information about a file
\item Can have multiple links to the same file
\item Read/Write access is controlled per file
\item Creation/Deletion of files is controlled by permissions of the directory
\item Several filesystems can be mounted to create the directory hierarchy
\end{itemize}





\section{Filesystem Exercises}
\label{sec:filesystem-basic-exercises}
{\normalsize

\begin{enumerate}
\item {\em Basic navigation}
  

  \begin{enumerate}
  \item Log in and use {\pgn pwd} to discover what the full path of
    your home directory is.
  \item Change directory to {\fn /bin} and then {\fn /tmp}. Use {\pgn
      pwd} to check you got there each time.
  \item When in {\fn /tmp} type {\cmdn cd ..} and use {\pgn pwd} to
    find out where you end up.  See
    section~\S\vref{sec:filesystem-basic-dot-dotdot}
  \item What is the parent directory of the root of the filesystem?
    Why is this so?
  \item Move back to your home directory. Think of three ways you can
    do this.  See section~\S\vref{sec:filesystem-basic-current-dir}.
  \end{enumerate}


\item {\em Directories}


  \begin{enumerate}
  \item Start in your home directory and create a directory called
    {\fn new}
  \item Change to the {\fn new} directory and create a directory
    called {\fn newer}
  \item Go to your home directory. Now create a directory under {\fn
      newer} called {\fn newerstill} There are two ways to do this
    what are they? (Hint: You don't {\em have} to change directories
    to solve this.)
  \item Remove all the directories that you've just created, there are
    several ways to do this.  See
    section~\S\vref{sec:filesystem-basic-directory-operations}.
  \item Create the same directory structure with one command.  See
    section~\S\vref{sec:filesystem-basic-directory-operations}.
\end{enumerate}







\item{\em Links}

You may wish to see the handout:
\url{http://nicku.org/ossi/lab/sym-link/sym-link.pdf}
for more details about links.
  \begin{enumerate}
  \item Create a file called {\fn test} in your home directory (Typing
    {\cmdn echo abc > test} should do this). Now create a hard link to
    {\fn test} called {\fn h\_test} and a symbolic link to test called
    {\fn s\_test}
  \item Find out the inode number of the files. Check you understand
    why they are what they are.
  \item Remove the original file called {\fn test}. Can you still get
    at the contents of the original file?
  \item What happens if you try {\cmdn cat s\_test}?  Make sure you
    understand the distinction between {\fn h\_test}, and {\fn
      s\_test}
  \item Try to make a {\kwd hard link} to your home directory. Why
    does this fail?
  \item From your home directory, try to make a hard link from a file
    in the \texttt{/boot} directory to your home directory.  In other
    words, the link should be in your home directory, and when you
    examine it, you should see the contents of the file in the
    \texttt{/boot} directory.  Does it
    work?
    
  \item From your home directory, try to make a \emph{symbolic} link
    from a file in the \texttt{/boot} directory to your home
    directory.  The link should be in your home directory.  Does it
    work?  How do you know whether it works properly or not?
    (\emph{Hint}: look at the \texttt{-L} option to \texttt{ls}).
    
  \item Change to the \texttt{/boot} directory.  Make a symbolic link
    from a file in that directory to your home directory.  The link
    should be in your home directory. Make sure that your result is
    correct.  How to check?
    
  \item Make a symbolic link from a file in the \texttt{/boot}
    directory to your home directory that is a \emph{relative symbolic
      link}.  A relative symbolic link is one where the \emph{target}
    does not start with a \texttt{/}.  Here is an example, in my home
    directory:
\begin{alltt}
$ \textbf{ls -l kernel.h}
lrwxrwxrwx    1 nicku    nicku          19 Feb  4 08:22 kernel.h -> ../../boot/kernel.h
\end{alltt}%$
The target file is the one shown to the right of the arrow
``\texttt{->}''.  The link is absolute if it starts with a slash
``\texttt{/}''; it is relative if it does not start with a slash.
\end{enumerate}


\item{\em {\fn /proc} --- See section\vref{sec:filesystem-basic-proc}}
  \begin{enumerate}
  \item Use the files in {\fn /proc} to find out how much memory your
    system has and what processor it is running on.
  \item Find out what PCI devices are attached to your machine.
  \item Find out what environment variables are set for your currently
    running shell using the information in {\fn /proc}. {\em Hint} you
    can get the process-id of your shell using \$\$
  \item A router does \emph{IP forwarding}; it allows \IP traffic
    entering one network interface to travel though the machine to
    another network interface, even if the destination \IP address is
    not on the router itself.  Whether or not your machine is doing
    \IP forwarding is stored in the file {\fn
      /proc/sys/net/ipv4/ip\_forward}.  You can {\fn cat} this file: a
    value of 1 means that \IP forwarding is turned on. Find out
    whether or not your machine will forward \IP.
    
    Note: the file \path{/etc/sysctl.conf} will change the values of
    files under \path{/proc/sys} while the computer is starting up.
    See man \texttt{sysctl.conf} and \texttt{man sysctl}.
  \item Find out how many files are currently open on your system.
    Hint: do
\begin{alltt}
$ \textbf{cat /proc/sys/fs/file-nr}
2812    70      52416
$ \textbf{man proc}
\end{alltt}
and then search the manual page for the string ``\texttt{file-nr}''.
  \end{enumerate}


\item \emph{\texttt{/etc/fstab}}
  \begin{enumerate}
  \item Add an entry to your \texttt{/etc/fstab} file to automatically
    mount the \NFS filesystem \texttt{/var/ftp/pub} from
    \texttt{ictlab} on a directory \texttt{/mnt/nfs} whenever the
    computer starts up.  See
    section~\vref{sec:filesystem-basic-fstab-example}.  See also
    section~\vref{sec:filesystem-basic-mounting-shared-directories}.
   \end{enumerate}
 \end{enumerate}



\section{Filesystem Solutions}
\label{fs-sols}

\includeversion{Solutions}%
\excludeversion{noSolutions}%
                                                                                \begin{Solutions}
\begin{enumerate}
\item {\em Basic Navigation}
  
  \begin{enumerate}
  \item You will probably see
\begin{alltt}
$ \textbf{pwd}
/home/\meta{username}
\end{alltt}%$
    where \meta{username} is the name you log in with.
  \item Check that the output of {\pgn pwd} is {\sco /bin} and {\sco
      /tmp}
  \item You should end up in {\fn /} This is the root of the filesystem.
  \item The parent of {\fn /} is itself. You can use {\cmdn ls -lia} to
    show that the inode numbers for {\fn .} and {\fn ..} are the same
    when you are in {\fn /}:
\begin{alltt}
$ \textbf{cd /}
$ \textbf{ls -id / ..}
      2 /        2 ..
\end{alltt}
  You can see here that `\texttt{/}' and `\texttt{/..}' both have an
  inode number of 2, so both are the same file, since both are in the
  same file system.
  \item You can move back to your home directory by using any of the
    following:
    \begin{enumerate}
    \item
\begin{alltt}
$ \textbf{cd}        
\end{alltt}%$
\item 
\begin{alltt}
$ \textbf{cd \(\sim\)}        
\end{alltt}%$
   \item
\begin{alltt}
$ \textbf{cd \(\sim\)\meta{username}}        
\end{alltt}%$
   \item
\begin{alltt}
$ \textbf{cd $HOME}
\end{alltt}
   \item
\begin{alltt}
$ \textbf{cd /home/\meta{username}}        
\end{alltt}%$
if your home directory is under \texttt{/home}.
   \end{enumerate}
 \end{enumerate}

\item {\em Directories}
  \begin{enumerate}
  \item
\begin{alltt}
$ \textbf{cd}
$ \textbf{mkdir new}
\end{alltt}
   \item
\begin{alltt}
$ \textbf{cd new}
$ \textbf{mkdir newer}
\end{alltt}
   \item
\begin{alltt}
$ \textbf{cd}
\end{alltt}%$
 then either: 
 \begin{enumerate}
   \item
\begin{alltt}
$ \textbf{cd new/newer}
$ \textbf{mkdir newerstill}
\end{alltt}
   \item or
\begin{alltt}
$ \textbf{mkdir new/newer/newerstill}
\end{alltt}%$
   \end{enumerate}
   \item Any of the following will work:
   \begin{enumerate}
     \item
\begin{alltt}
$ \textbf{cd}
$ \textbf{cd new/newer}
$ \textbf{rmdir newerstill}
$ \textbf{cd ..}
$ \textbf{rmdir newer}
$ \textbf{cd ..}
$ \textbf{rmdir new}
\end{alltt}%$
   \item
\begin{alltt}
$ \textbf{cd}
$ \textbf{rmdir -p new/newer/newerstill}
\end{alltt}
   \item
\begin{alltt}
$ \textbf{cd}
$ \textbf{rm -rf new/}
\end{alltt}
   \end{enumerate}
   \item
\begin{alltt}
$ \textbf{cd}
$ \textbf{mkdir -p new/newer/newerstill}
\end{alltt}
 \end{enumerate}

 \item {\em Links}

 \begin{enumerate}
   \item This is achieved as follows:
\begin{alltt}
$ \textbf{ln test h_test}
$ \textbf{ln -s test s_test}
\end{alltt}
   \item {\cmdn ls -li} should show that the inode number of the
     original file and {\fn h\_test} are identical {\fn h\_test} is
     another name for the original file. The inode number for {\fn
       s\_test} will be different. It is a separate file that contains
     information about the location of the file it is a link to.
   \item After you created the hard link the original file had two
     names {\fn test} and {\fn h\_test}.  You have removed {\fn test}
     but until all names for a file have been removed it is still
     accessible.  In this case you can do {\cmdn cat h\_test} to see
     the contents of the file.
   \item This should fail with a {\sco No such file or directory}
     message. {\fn s\_test} contained a pointer to the file {\fn test}
     not the inode number. There is no longer a file named {\fn test}
     so this cannot work. {\kwd Hard links} reference a file by its
     inode number, {\kwd symbolic links} reference it by its name
   \item This is not allowed, as it could stop the filesystem being
     strictly hierarchical.  It would cause problems with all software
     that searches the filesystem, since loops could be created.  If
     this were the case, all software would need extra code to check
     for loops, making the software bigger, slower, more complex and
     hence more likely to have bugs.
   \item
\begin{alltt}
$ \textbf{cd}
$ \textbf{ln /boot/kernel.h .}
ln: creating hard link `./kernel.h' to `/boot/kernel.h': Invalid cross-device link
\end{alltt}%$
    The reason that it is not possible to create a hard link from one
    partition to another is that a hard link is specified by an inode
    number.  An inode number is only unique within one partition or
    filesystem.
   \item 
\begin{alltt}
$ \textbf{cd}
$ \textbf{ln -s /boot/kernel.h .}
$ \textbf{ls -l kernel.h}
lrwxrwxrwx    1 nicku    nicku          14 Feb 28 05:50 kernel.h -> /boot/kernel.h
$ \textbf{ls -Ll kernel.h}
-rw-r--r--    1 root     root          473 May  8  2002 kernel.h
\end{alltt}%$
  So it is clear that this symbolic link works fine.  We can examine
  the file through the link with
\begin{alltt}
$ \textbf{less kernel.h}
\end{alltt}%$
 and verify that we can see the same content as when we view
 \texttt{/boot/kernel.h}.
   \item 
\begin{alltt}
$ \textbf{rm \(\sim\)/kernel.h}
$ \textbf{cd /boot}
$ \textbf{ln -s /boot/kernel.h \(\sim\)}
$ \textbf{ls -l kernel.h}
lrwxrwxrwx    1 nicku    nicku          14 Feb 28 05:50 kernel.h -> /boot/kernel.h
$ \textbf{ls -Ll kernel.h}
-rw-r--r--    1 root     root          473 May  8  2002 kernel.h
\end{alltt}%$
\item
\begin{alltt}
$ \textbf{cd}
$ \textbf{ln -s ../../boot/kernel.h .}
$ \textbf{ls -l kernel.h}
lrwxrwxrwx    1 nicku    nicku          19 Feb 28 05:55 kernel.h -> ../../boot/kernel.h
\end{alltt}%$
Note that the command
\begin{alltt}
$ \textbf{ln -s ../../boot/kernel.h \(\sim\)}
\end{alltt}%$
will work no matter where your current directory is.
\end{enumerate}

 \item {\em {\fn /proc}}


 \begin{enumerate}
   \item {\cmdn cat /proc/meminfo} should show you memory usage.
   \item {\cmdn cat /proc/pci} gives a list of all PCI devices.
   \item {\cmdn cat /proc/\$\$/environ} will give a list of the
     environment of your current shell. Each variable is delimited
     with the nul character (decimal 0). The following will show the
     output with one variable per line:
\begin{alltt}
$ \textbf{cat /proc/$$/environ | tr '\bs{}000' '\bs{}n'}
\end{alltt}
  \item In this example machine (a router), ip forwarding is on:
\begin{alltt}
$ \textbf{cat /proc/sys/net/ipv4/ip_forward}
1
\end{alltt}%$
However, on a workstation, ip forwarding is normally off.  It is
controlled conveniently by an entry in the file {\fn
  /etc/sysctl.conf}; for example, in the example router, the file
contains these lines:
\begin{alltt}
net.ipv4.ip_forward = 1
fs.file-max = 16384
\end{alltt}
which ensure that {\fn /proc/sys/net/ipv4/ip\_forward} will contain
`\texttt{1}' and that {\fn /proc/sys/fs/file-max} will contain
`\texttt{16384}'.  See \texttt{man sysctl.conf} and \texttt{man
  sysctl}.
  \item
\begin{alltt}
$\textbf{cat /proc/sys/fs/file-nr}
16384   13018   16384
$ \textbf{man proc}
\end{alltt}
And in this document, we see:
\begin{quote}
  The (read-only) file \texttt{file-nr} gives the number of files
  presently opened.  It contains three numbers: The number of
  allocated file handles, the number of free file handles and the
  maximum number of file handles.  The kernel allocates file handles
  dynamically, but it doesn't free them again.  If the number of
  allocated files is close to the maximum, you should consider
  increasing the maximum.  When the number of free file handles is
  large, you've encountered a peak in your usage of file handles and
  you probably don't need to increase the maximum.
\end{quote}
we see that $n_{\text{alloc}} = 16384, n_{\text{free}} = 13018,
n_{\text{max}} = 16384$.  So to answer the question, $n_{\text{open}}=
n_{\text{alloc}} - n_{\text{free}} = 16384 - 13018 = 3366$.  However,
at one stage since it was booted, this system ran out of open file
handles, so it may be a good idea to increase the value in this line
of {\fn /etc/sysctl.conf}:
\begin{alltt}
fs.file-max = 16384
\end{alltt}
\end{enumerate}

\item Add a line like this to \texttt{/etc/fstab}:
\begin{alltt}
ictlab:/var/ftp/pub /mnt/nfs nfs defaults 0 0
\end{alltt}
The file system table \texttt{/etc/fstab} is critical for successful
startup of a Linux system; it is important to understand the basics of
how filesystems are mounted at system startup.
\end{enumerate}
\end{Solutions}
\begin{noSolutions}
  We will provide solutions soon.
\end{noSolutions}

} % end of \normalsize                   
} % end \mns from chapter start
\label{endofchapter-filesystem}

\excludeversion{Solutions}%
\includeversion{noSolutions}%
 
%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 
