Advanced I/O

advertisement
Daemon Processes



Long lived utility processes
Often started at system boot and ended
when system shuts down
Run in the background with no
controlling terminal
Daemon Processes

Coding rules (see page 425)





Call umask and set the file mode creation
mask to 0
Call fork and let the parent die
Call setsid
Change current working directory to root
directory
Close unneeded file descriptors
Advanced I/O


Nonblocking I/O
I/O Multiplexing




The poll() function call
The select() function call
File record locking
Memory mapped I/O
“Slow” I/O



Reads of certain file types that can block
forever if data is not ready (pipes, terminal
devices, network devices)
Writes on those same file types where data
can’t be accepted immediately (pipe full,
network flow control, etc)
Opens of certain file types that block until
some condition becomes true (terminal
device that waits on a modem, open of a
FIFO for writing only when no other process
has it open for reading)
“Slow” I/O



Reads and writes of files with
mandatory record locking enabled
Some ioctl operations
Some IPC functions
Nonblocking I/O


We can specify nonblocking I/O when
we open a file by providing the
O_NONBLOCK flag
open(file,O_RDONLY | O_NONBLOCK);
If the file is already open, we can use
fcntl to set the O_NONBLOCK flag
Nonblocking I/O
flags = fcntl(fd, F_GETFL, 0);
flags = flags | O_NONBLOCK;
fcntl(fd, F_SETFL, flags);




F_GETFL – get flags
F_SETFL – set flags
Check if file has nonblocking I/O enabled
if(flags & O_NONBLOCK)
Turn off nonblocking I/O
flags = flags & ~O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
I/O Multiplexing


Avoids the busy waiting loop common
with simple nonblocking I/O
Using multiplexing we can block on
multiple file descriptors simultaneously
poll function
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
int fd;
/* file descriptor */
short events;
/* requested events */
short revents; /* returned events */
};



fds is an array of pollfd elements
nfds is the number of elements in the array
timeout specifies how long the function should block



timeout = 0 – don’t block
timeout = -1 - wait forever
timeout > 0 - wait timeout miliseconds
select function
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds, struct timeval *timeout);
struct timeval {
long tv_sec;
/* seconds */
long tv_usec;
/* microseconds */
};

timeout specifies how long to block



NULL – wait forever, or until a signal is caught
tv_sec = 0 and tv_usec = 0 – don’t block
tv_sec != 0 or tv_usec != 0 – block until a
descriptor is ready or the timeout is reached. Can
also be interrupted by a signal
select function

readfds, writefds, exceptfds are pointers to descriptor sets

telling the system which file descriptors we are interested in for
reading, writing and exceptions
The type for descriptor sets is fd_set. This type can not be
directly manipulated
Use the following functions with fd_set
 void FD_CLR(int fd, fd_set *set);
 int FD_ISSET(int fd, fd_set *set);
 void FD_SET(int fd, fd_set *set);
 void FD_ZERO(fd_set *set);

nfds is the number of file descriptors (usually the

highest number plus one)
Scatter Read and Gather Write
ssize_t readv(int fd, const struct iovec *vector, int count);
ssize_t writev(int fd, const struct iovec *vector, int count);
struct iovec {
void *iov_base; /* Starting address */
size_t iov_len; /* Number of bytes */
};




readv and writev allows us to read or write to
multiple non contiguous buffers at the same time
fd is the file descriptor to read from or write to
vector is a pointer to an array of iovec structures
count is the number of elements in the array
Memory Mapped I/O


Reading/Writing a memory address
actually causes I/O to another device
Functions are provided to memory map
an open file
Memory Mapped I/O
void *mmap(void *start, size_t length, int prot,
int flags, int fd, off_t offset);



Maps an open file to an area of memory
start lets us request a given starting
point in memory.
length is the number of bytes to read
from the file
Memory Mapped I/O



offset is the location within the file to begin
fd is the file descriptor to be mapped
prot specifies the protection of the mapped
region





PROT_READ - region can be read
PROT_WRITE – region can be written
PROT_EXEC – region can be executed
PROT_NONE – region cannot be accessed
flags – sets attributes of the mapped region.
See page 488 for values and descriptions
Memory Mapped I/O
int munmap(void *start, size_t length);
 A mapped region is automatically unmapped
when the process terminates
 munmap can be used to unmap a region
earlier



start – beginning address of mapped region
length – number of bytes in region
Note: closing the file descriptors does not
unmap a region.
File (Record) Locking


Allows a process to lock a portion of a file to
prevent access by another process
Advisory Locking


A convention that all processes accessing the file
must follow
Mandatory Locking


Enforced by the Kernel. Other processes
suspended if they try to read/write the locked
section
Mandatory Locking enabled by turning on the Set
Group ID bit and turning off the group execute bit
File (Record) Locking

Locking Functions



lockf - System V
flock – BSD
fcntl - POSIX
fcntl Record Locking
int fcntl(int fd, int cmd, struct flock *lock);
struct flock {
short l_type;
short l_whence;
off_t l_start;
off_t l_len;
pid_t l_pid;
};

fd an open file descriptor
fcntl Record Locking

lock – a pointer to a flock struct





l_type – F_RDLCK, F_WRLCK or F_UNLCK
l_start – starting byte offset of locked
region
l_whence – same as for lseek: SEEK_SET,
SEEK_CUR, SEEK_END
l_len – length in bytes to lock. 0 means
lock until EOF
l_pid – used to return a pid with F_GETLK
fcntl Record Locking

cmd



F_GETLK – checks to see if we can acquire
the requested lock. If another process has
a conflicting lock the information about
that lock is passed back through lock
F_SETLK – set a lock
F_SETLKW – set a lock, but wait if there is
a conflict. May be interrupted by a signal
fcntl Record Locking

Lock type must be consistent with the
opened mode of the file


F_RDLCK for O_RDONLY or O_RDWR
F_WRLCK for O_WRONLY or O_RDWR
Lock Compatibility




Any number of processes may have
shared read locks on a region of a file
Only one processes at a time can have
an exclusive write lock on a region
We can not obtain a write lock on a
region that already has a read lock
We can not obtain a read lock on a
region that already has a write lock
Lock Combining


If a process attempts to acquire a lock on a
region it already has a lock on the old lock is
replaced by the new lock
The system will split and combine locks
automatically



Lock acquired from byte 100 to 200
Lock released for bytes 125 to 150
We now have 2 locks for bytes 100 to 125 and
150 to 200
Implied Inheritance and
Release of Locks





Locks are associated with a process and a file
If the process terminates, its locks are
released
When a file is closed, any locks on it for that
process are released
Locks are not inherited across a fork
Locks are inherited across an exec unless the
close-on-exec flag is set
Download