\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://ictlab.tyict.vtc.edu.hk/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: