CS 105 “Tour of the Black Holes of Computing”

Slides:



Advertisements
Similar presentations
© Original by Donald Acton; Changes by George Tsiknis Unix I/O Related Text Sections: 2nd Ed: and st Ed: and
Advertisements

1. I/O. I/O Unix I/O RIO (robust I/O) package Metadata, sharing, and redirection Standard I/O Conclusions and examples.
Carnegie Mellon 1 System-Level I/O : Introduction to Computer Systems 14 th Lecture, Oct. 12, 2010 Instructors: Randy Bryant and Dave O’Hallaron.
System-Level I/O November 4, 2003 Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O “The.
System-Level I/O Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O.
System-Level I/O October 8, 2008 Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O class14.ppt.
System-Level I/O May 28, 2008 Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O.
System-Level I/O November 11, 2004 Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O “The.
System-Level I/O Nov 14, 2002 Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O class24.ppt
System-Level I/O Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O.
I/O April 16, 2002 Topics Files Unix I/O Standard I/O Reading: (Beta) or (New) Problems: 12.9 (Beta) or 12.4 (New) class24.ppt
System-Level I/O May 22, 2006 Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O.
Recitation 11: I/O Problems Andrew Faulring Section A 18 November 2002.
Introduction to Operating Systems File I/O Most of the following slides are adapted from slides of Gregory Kesden and Markus Püschel of Carnegie Mellon.
System-level I/O Alan L. Cox Some slides adapted from CMU slides.
Chapter 39 Virtsualization of Storage: File and Directory Chien-Chung Shen CIS, UD
Input and Output Topics I/O hardware Unix file abstraction Robust I/O File sharing io.ppt CS 105 “Tour of the Black Holes of Computing”
System-Level I/O Topics Unix I/O Robust reading and writing
Carnegie Mellon 1 System-Level I/O / : Introduction to Computer Systems 15 th Lecture, Oct. 18, 2012 Instructors: Dave O’Hallaron, Greg Ganger,
1 System-Level I/O Andrew Case Slides adapted from Jinyang Li, Randy Bryant and Dave O’Hallaron.
Week 12 - Friday.  What did we talk about last time?  Exam 2 post mortem  Low level file I/O.
Recitation 11: 11/18/02 Outline Robust I/O Chapter 11 Practice Problems Annie Luo Office Hours: Thursday 6:00 – 7:00 Wean.
UNIX Files File organization and a few primitives.
Carnegie Mellon 1 System-Level I/O / : Introduction to Computer Systems 15 th Lecture, Oct. 16, 2014 Instructors: Greg Ganger, Greg Kesden,
Carnegie Mellon 1 System-Level I/O / : Introduction to Computer Systems 15 th Lecture, June 25, 2013 Instructors: Gregory Kesden.
System-Level I/O March 25, 2004 Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O “The.
Lee CSCE 312 TAMU 1 System Level I/O Instructor: Dr. Hyunyoung Lee Based on slides provided by Randy Bryant and Dave O’Hallaron.
Input and Output Topics I/O hardware Unix file abstraction Robust I/O File sharing CS 105 “Tour of the Black Holes of Computing”
System-Level I/O.
Input and Output Topics I/O hardware Unix file abstraction Robust I/O File sharing CS 105 “Tour of the Black Holes of Computing”
Laface 2007 File system 2.1 Operating System Design Filesystem system calls buffer allocation algorithms getblk brelse bread breada bwrite iget iput bmap.
CS 105 “Tour of the Black Holes of Computing”
GAME203 – C Files stdio.h C standard Input/Output “getchar()”
CSE333 SECTION 3. Important Dates Jan 27 th – Homework 1 Due Feb 6 th – Midterm.
1 System-Level I/O. 2 Outline Unix I/O Reading File Metadata Sharing Files & I/O redirection Robust I/O Standard I/O Suggested Reading –10.1~10.3, 10.5~10.7,
Carnegie Mellon 1 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition System-Level I/O : Introduction to Computer.
Carnegie Mellon /18-243: Introduction to Computer Systems Instructors: Bill Nace and Gregory Kesden (c) All Rights Reserved. All work.
System-Level I/O Topics Unix I/O Robust reading and writing Reading file metadata Sharing files I/O redirection Standard I/O.
Real Numbers Device driver process within the operating system that interacts with I/O controller logical record 1 logical record 2 logical record 3.
Carnegie Mellon 1 System-Level I/O / : Introduction to Computer Systems 15 th Lecture, June 24, 2014 Instructors: Gregory Kesden.
Week 12 - Thursday CS222.
Error handling I/O Man pages
CS/COE 0449 (term 2174) Jarrett Billingsley
Robust I/O package Chapter 11 practice problems
System-Level I/O.
Supplementary Material on Unix System Calls and Standard I/O
System-Level I/O : Introduction to Computer Systems
Introduction to Operating Systems File I/O
Files CMSC 15400: Introduction to Computer Systems Chapter 10
UNIX System Overview.
File I/O.
CS111 Computer Programming
System-Level I/O Topics Unix I/O Robust reading and writing
System-Level I/O October 9, 2008
“The course that gives CMU its Zip!”
“The course that gives CMU its Zip!”
Virtual Memory CSCI 380: Operating Systems Lecture #7 -- Review and Lab Suggestions William Killian.
File Input and Output.
File I/O (1) Prof. Ikjun Yeom TA – Mugyo
Reference: Advanced Programming in the UNIX Environment, Third Edition, W. Richard Stevens and Stephen A. Rago, Addison-Wesley Professional Computing Series,
Accessing Files in C Professor Hugh C. Lauer CS-2303, System Programming Concepts (Slides include materials from The C Programming Language, 2nd edition,
File I/O (1) Prof. Ikjun Yeom TA – Hoyoun
IPC Prof. Ikjun Yeom TA – Hoyoun
System-Level I/O.
System-Level I/O CSCI 380: Operating Systems
CSCI 380: Operating Systems William Killian
CS 105 “Tour of the Black Holes of Computing”
Instructors: David Trammell
Lecture 26: File Systems CS April 29, 2019.
Presentation transcript:

CS 105 “Tour of the Black Holes of Computing” Input and Output Topics I/O hardware Unix file abstraction Robust I/O File sharing

I/O: A Typical Hardware System CPU chip register file ALU system bus memory bus main memory bus interface I/O bridge I/O bus Expansion slots for other devices such as network adapters. USB controller graphics adapter disk controller mouse keyboard monitor disk

Abstracting I/O Low level requires complex device commands Vary from device to device Device models can be very different Tape: read or write sequentially, or rewind Disk: “random” access at block level Terminal: sequential, no rewind, must echo and allow editing Video: write-only, with 2-dimensional structure Operating system should hide these differences “Read” and “write” should work regardless of device Sometimes impossible to generalize (e.g., video) Still need access to full power of hardware

Unix Files A Unix file is a sequence of m bytes: B0, B1, .... , Bk , .... , Bm-1 Cool fact: All I/O devices are represented as files: /dev/sda1 (/boot disk partition) /dev/tty2 (terminal) Even the kernel is represented as files: /dev/kmem (access to kernel memory) /proc (kernel data structures) /sys (device discovery and control)

Current file position = k Unix I/O Overview Elegant mapping of files to devices allows kernel to export a simple interface called Unix I/O Key Unix idea: All input and output is handled in a consistent and uniform way Basic Unix I/O operations (system calls): Opening and closing files: open()and close() Reading and writing a file: read() and write() Changing the current file position (seek): lseek (not discussed) B0 B1 • • • Bk-1 Bk Bk+1 Current file position = k

File Types Each file has a type indicating its role in the system Regular file: Contains arbitrary data Directory: Index for a related group of files Socket: For communicating with a process on same or another machine Other file types beyond our scope Named pipes (FIFOs) Symbolic links Character and block devices

Regular Files A regular file contains arbitrary data Applications often distinguish between text files and binary files Text files are regular files with only ASCII or Unicode characters Binary files are everything else e.g., object files, JPEG images Kernel doesn’t know the difference! Text file is sequence of text lines Text line is sequence of chars terminated by newline character (‘\n’) Newline is 0xa, same as ASCII line feed character (LF) End of line (EOL) indicators in other systems Linux and Mac OS: '\n' (0xa) line feed (LF) Windows and Internet protocols: '\r' '\n' (0xd 0xa) Carriage return (CR) followed by line feed (LF)

Directories Directory consists of an array of links Each link maps a filename to a file Each directory contains at least two entries . (dot) is a link to itself .. (dot dot) is a link to the parent directory in the directory hierarchy (next slide) Commands for manipulating directories mkdir: create empty directory ls: view directory contents rmdir: delete empty directory

Directory Hierarchy All files are organized as a hierarchy anchored by root directory named / (slash) Kernel maintains current working directory (cwd) for each process Modified using the cd command / bin/ dev/ etc/ home/ usr/ bash tty1 group passwd geoff/ z/ include/ stdio.h emacs sys/ unistd.h foo.c

Pathnames Locations of files in the hierarchy denoted by pathnames Absolute pathname starts with ‘/’ and denotes path from root /home/geoff/foo.c Relative pathname denotes path from current working directory ../geoff/foo.c / bin/ dev/ etc/ home/ usr/ bash tty1 group passwd geoff/ z/ include/ stdio.h emacs sys/ unistd.h foo.c cwd: /home/z

Opening Files #include <errno.h> int fd; /* file descriptor */ if ((fd = open("/etc/hosts", O_RDONLY)) == -1) { fprintf(stderr, "Couldn’t open /etc/hosts: %s", strerror(errno)); exit(1); } Opening a file tells kernel you are getting ready to access it Returns small identifying integer file descriptor fd == -1 indicates that an error occurred; errno has reason strerror converts to English (Note: use strerror_r for thread safety) Each process created by a Unix shell begins life with three open files (normally connected to terminal): 0: standard input 1: standard output 2: standard error

Redirecting Files One of the most powerful ideas in Unix You can easily redirect stdin/stdout/stderr ./echoclient < /etc/passwd redirects input grep knuth /etc/hosts > ~/knuthip redirects output ls –Rl /proc 2> /dev/null redirects error You can even hook programs together (“piping”): find / -name core | wc -l find / -name core –print0 | xargs -0 rm –f You’re not true Unix expert until you’re good with pipes Two-command pipes: advanced learner Three commands: excellent competence Six or more: scary ninja cat foo | bar is always incorrect (and sign of ignorance) Use bar < foo instead Don’t let stackoverflow fool you!

Closing Files Closing a file tells kernel that you’re finished with it int fd; /* file descriptor */ int retval; /* return value */ if ((retval = close(fd)) == -1) { perror("close"); exit(1); } Closing a file tells kernel that you’re finished with it Closing an already closed file is recipe for disaster in threaded programs (more on this later) Some error reports are delayed until close! Moral: Always check return codes, even for seemingly benign functions such as close() perror is simplified strerror/fprintf; see man page

Reading Files char buf[4096]; int fd; /* file descriptor */ unsigned int nbytes; /* number of bytes read */ /* Open file fd ... */ /* Then read up to 4096 bytes from file fd */ if ((nbytes = read(fd, buf, sizeof buf)) == -1) { perror("read"); exit(1); } Reading a file copies bytes from current file position into memory, then updates file position You must provide the memory (buffer) Returns number of bytes read from file fd into buf nbytes == -1 indicates error occurred nbytes == 0 indicates end of file (EOF) Short counts (nbytes < sizeof buf) are possible and are not errors!

Writing Files char buf[4096]; int fd; /* file descriptor */ unsigned int nbytes; /* number of bytes read */ /* Open the file fd ... */ /* Then write up to 4096 bytes from buf to file fd */ if ((nbytes = write(fd, buf, sizeof buf) == -1) { perror("write"); exit(1); } Writing a file copies bytes from memory to current file position, then updates current file position Returns number of bytes written from buf to file fd nbytes == -1 indicates that an error occurred As with reads, short counts are possible and are not errors! Here, transfers up to 4096 bytes from address buf to file fd

Simple Unix I/O Example #include "csapp.h" int main(void) { char c; while(Read(STDIN_FILENO, &c, 1) > 0) Write(STDOUT_FILENO, &c, 1); exit(0); } Copies standard input to standard output one byte at a time (basically, this is cat) Note the use of error-handling wrappers for read and write (Appendix B in text)

Dealing with Short Counts Short counts can occur in these situations: Encountering (end-of-file) EOF on reads Reading text lines from a terminal Reading and writing network sockets or Unix pipes Short counts never occur in these situations: Reading from disk files, except for EOF Writing to disk files How should you deal with short counts in your code? Use the RIO (Robust I/O) package from your textbook’s csapp.c file (Appendix B) (But note that it handles EOF wrong on terminal) Use C stdio or C++ streams (also sometimes blows EOF!) Write your code very, very carefully Ignore the problem and accept that your code is fragile

“Foolproof” I/O Low-level I/O is difficult because of short counts and other possible errors Textbook provides RIO package, a (fairly) good example of how to encapsulate low-level I/O RIO is set of wrappers that provide efficient and robust I/O in applications (e.g., network programs) that are subject to short counts. Download from csapp.cs.cmu.edu/public/ics2/code/src/csapp.c csapp.cs.cmu.edu/public/ics2/code/include/csapp.h

Implementation of rio_readn /* * rio_readn - robustly read n bytes (unbuffered) */ ssize_t rio_readn(int fd, void *usrbuf, size_t n) { size_t nleft = n; ssize_t nread; char *bufp = usrbuf; while (nleft > 0) { if ((nread = read(fd, bufp, nleft)) == -1) { if (errno == EINTR) /* interrupted by signal handler return */ nread = 0; /* so call read() again */ else return -1; /* errno set by read() */ } else if (nread == 0) break; /* EOF */ nleft -= nread; bufp += nread; return (n - nleft); /* return >= 0 */

Where’s the Bug? Suppose 5 bytes remain in input, 10 requested: 5 bytes will be read (short count) Loop will try to read more, get 0 (EOF) Function will return 5 bytes that were read On next call, forgets that EOF was hit and tries to read again OK on files; EOF will be issued over again On terminal, means you have to type Control-D twice Cure: need rio_t to describe file, and flag in rio_t that remembers EOF was hit

Unbuffered I/O RIO provides buffered and unbuffered routines Especially useful for transferring data on network sockets Same interface as Unix read and write rio_readn returns short count only if it encounters EOF Usually incorrect if reading from terminal rio_writen never returns a short count Calls to rio_readn and rio_writen can be interleaved arbitrarily on the same descriptor Small unbuffered I/Os are horribly inefficient

Buffered I/O: Motivation Applications often read/write one character at a time getc, putc, ungetc gets, fgets Read line of text one character at a time, stopping at newline Implementing as Unix I/O calls expensive read and write require Unix kernel calls > 10,000 clock cycles Solution: Buffered read Use Unix read to grab block of bytes User input functions take one byte at a time from buffer Refill buffer when empty Buffer already read unread

Buffered Input Buffered: Efficiently read text lines and binary data from file partially cached in an internal memory buffer rio_readlineb reads text line of up to maxlen bytes from file fd and stores it in usrbuf. Especially useful for reading lines from network sockets rio_readnb reads up to n bytes from file fd Calls to rio_readlineb and rio_readnb can be interleaved arbitrarily on same descriptor Warning: Don’t interleave calls to rio_readn with calls to *b versions

Buffered I/O: Implementation For reading from file File has associated buffer to hold bytes that have been read from file but not yet read by user code Layered on Unix file: rio_cnt Buffer already read unread rio_buf rio_bufptr Buffered Portion not in buffer already read unread unseen Current File Position

Buffered I/O: Declaration All information contained in struct rio_cnt Buffer already read unread rio_buf rio_bufptr typedef struct { int rio_fd; /* descriptor for this internal buf */ int rio_cnt; /* unread bytes in internal buf */ char *rio_bufptr; /* next unread byte in internal buf */ char rio_buf[RIO_BUFSIZE]; /* internal buffer */ } rio_t;

Buffered RIO Example Copying the lines of a text file from standard input to standard output #include "csapp.h" int main(int argc, char **argv) { int n; rio_t rio; char buf[MAXLINE]; Rio_readinitb(&rio, STDIN_FILENO); while(1) { n = Rio_readlineb(&rio, buf, sizeof buf); if (n == 0) break; Rio_writen(STDOUT_FILENO, buf, n); exit(0); }

How the Unix Kernel Represents Open Files Two descriptors referencing two distinct open files Descriptor 1 (stdout) points to terminal, and descriptor 4 points to open disk file Descriptor table [one table per process] Open file table [shared by all processes] v-node table [shared by all processes] File A (terminal) stdin fd 0 File access stdout fd 1 Info in stat struct File pos File size stderr fd 2 refcnt=1 File type fd 3 fd 4 ... ... File B (disk) File access File size File pos File type refcnt=1 ... ...

File Sharing Two distinct descriptors sharing the same disk file through two distinct open file table entries E.g., Calling open twice with the same filename argument Descriptor table (one table per process) Open file table (shared by all processes) v-node table (shared by all processes) File A fd 0 File access fd 1 File pos File size fd 2 refcnt=1 File type fd 3 fd 4 ... ... File B File pos refcnt=1 ...

How Processes Share Files: fork A child process inherits its parent’s open files Note: situation unchanged by exec functions (use fcntl to change) Before fork call: Descriptor table [one table per process] Open file table [shared by all processes] v-node table [shared by all processes] File A (terminal) stdin fd 0 File access stdout fd 1 File pos File size stderr fd 2 refcnt=1 File type fd 3 fd 4 ... ... File B (disk) File access File size File pos File type refcnt=1 ... ...

How Processes Share Files: fork A child process inherits its parent’s open files After fork call: Child’s table same as parent’s; add +1 to each refcnt Descriptor table [one table per process] Open file table [shared by all processes] v-node table [shared by all processes] Parent File A (terminal) fd 0 File access fd 1 File pos File size fd 2 refcnt=2 File type fd 3 fd 4 ... ... File B (disk) Child File access fd 0 File size fd 1 File pos fd 2 File type refcnt=2 fd 3 ... ... fd 4

I/O Redirection Question: How does a shell implement I/O redirection? bash$ ls > foo.txt Answer: By calling the dup2(oldfd, newfd) function Copies (per-process) descriptor table entry oldfd to entry newfd Descriptor table before dup2(4,1) Descriptor table after dup2(4,1) fd 0 fd 0 fd 1 a fd 1 b fd 2 fd 2 fd 3 fd 3 fd 4 b fd 4 b

I/O Redirection Example Step #1: open file to which stdout should be redirected Happens in child executing shell code, before exec Descriptor table [one table per process] Open file table [shared by all processes] v-node table [shared by all processes] File A stdin fd 0 File access stdout fd 1 File pos File size stderr fd 2 refcnt=1 File type fd 3 fd 4 ... ... File pos refcnt=1 ... File access File size File type File B

I/O Redirection Example (cont.) Step #2: call dup2(4,1) cause fd=1 (stdout) to refer to disk file pointed at by fd=4 Descriptor table [one table per process] Open file table [shared by all processes] v-node table [shared by all processes] File A stdin fd 0 File access stdout fd 1 File pos File size stderr fd 2 refcnt=0 File type fd 3 fd 4 ... ... File B File access File size File pos File type refcnt=2 ... ...

File Metadata Metadata is data about data, in this case file data. Maintained by kernel, accessed by users with the stat and fstat functions. /* Metadata returned by the stat and fstat functions */ struct stat { dev_t st_dev; /* device */ ino_t st_ino; /* inode */ mode_t st_mode; /* protection and file type */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device type (if inode device) */ off_t st_size; /* total size, in bytes */ unsigned long st_blksize; /* blocksize for filesystem I/O */ unsigned long st_blocks; /* number of blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last change */ };

Standard I/O Functions The C standard library (libc.so) contains a collection of higher-level standard I/O functions Documented in Appendix B of K&R Examples of standard I/O functions: Opening and closing files (fopen and fclose) Reading and writing bytes (fread and fwrite) Reading and writing text lines (fgets and fputs) Formatted reading and writing (fscanf and fprintf)

Standard I/O Streams Standard I/O models open files as streams Abstraction for a file descriptor and a buffer in memory C programs begin life with three open streams (defined in stdio.h) stdin (standard input) stdout (standard output) stderr (standard error) #include <stdio.h> extern FILE *stdin; /* standard input (descriptor 0) */ extern FILE *stdout; /* standard output (descriptor 1) */ extern FILE *stderr; /* standard error (descriptor 2) */ int main() { fprintf(stdout, "Hello, world\n"); }

Buffering in Standard I/O Standard I/O functions use buffered I/O Buffer flushed to output fd on '\n‘ (if terminal), call to fflush or exit, or return from main. printf("h"); printf("e"); printf("l"); printf("l"); printf("o"); buf printf("\n"); h e l l o \n . . fflush(stdout); write(1, buf, 6);

Standard I/O Buffering in Action You can see this buffering in action for yourself, using the always fascinating Linux strace program: #include <stdio.h> int main() { printf("h"); printf("e"); printf("l"); printf("o"); printf("\n"); fflush(stdout); exit(0); } linux> strace ./hello execve("./hello", ["hello"], [/* ... */]). ... write(1, "hello\n", 6) = 6 exit_group(0) = ?

Aside: Working with Binary Files Functions you should never use on binary files Text-oriented I/O such as fgets, scanf, rio_readlineb Interpret EOL characters. Use functions like rio_readn or rio_readnb instead String functions strlen, strcpy, strcat Interprets byte value 0 (end of string) as special