Practical Session 1 System Calls

Slides:



Advertisements
Similar presentations
1 CS345 Operating Systems Φροντιστήριο Άσκησης 1.
Advertisements

CSCC69: Operating Systems
Operating Systems, 142 Tas: Vadim Levit, Dan Brownstein, Ehud Barnea, Matan Drory and Yerry Sofer Practical Session 1, System Calls.
Operating Systems, 112 Practical Session 1, System Calls.
Today’s topic: –File operations –I/O redirection –Inter-process communication through pipes.
Process Control Hua LiSystems ProgrammingCS2690Process Control Page 1 of 41.
1 Processes Professor Jennifer Rexford
Process in Unix, Linux and Windows CS-3013 C-term Processes in Unix, Linux, and Windows CS-3013 Operating Systems (Slides include materials from.
CS-502 Fall 2006Processes in Unix, Linux, & Windows 1 Processes in Unix, Linux, and Windows CS502 Operating Systems.
Unix & Windows Processes 1 CS502 Spring 2006 Unix/Windows Processes.
CSE 451 Section 4 Project 2 Design Considerations.
Fork and Exec Unix Model Tutorial 3. Process Management Model The Unix process management model is split into two distinct operations : 1. The creation.
Processes in Unix, Linux, and Windows CS-502 Fall Processes in Unix, Linux, and Windows CS502 Operating Systems (Slides include materials from Operating.
Process. Process Concept Process – a program in execution Textbook uses the terms job and process almost interchangeably A process includes: – program.
Shell (Part 1). Process r A process is an instance of an application running r If there are two instances of an application running then there are two.
Process in Unix, Linux, and Windows CS-3013 A-term Processes in Unix, Linux, and Windows CS-3013 Operating Systems (Slides include materials from.
Fundamentals CIS 552. Fundamentals Low-level I/O (read/write using system calls)  Opening/Creating files  Reading & Writing files  Moving around in.
Cli/Serv.: procs/51 Client/Server Distributed Systems v Objectives –look at how to program UNIX processes , Semester 1, Processes.
Lecture 3 Process Concepts. What is a Process? A process is the dynamic execution context of an executing program. Several processes may run concurrently,
Creating and Executing Processes
Pipes A pipe is a simple, synchronized way of passing information between processes A pipe is a special file/buffer that stores a limited amount of data.
More on UART Interrupts; System Calls Reference on Interrupt Identification Register(IIR) slide 17 of
CS252: Systems Programming Ninghui Li Based on Slides by Prof. Gustavo Rodriguez-Rivera Topic 8: Opening Files and Starting Processes.
UNIX Files File organization and a few primitives.
System calls for Process management
Operating Systems Process Creation
What is a Process? u A process is an executable “cradle” in which a program may run u This “cradle” provides an environment in which the program can run,
Chapter 4 Process Abstraction Chien-Chung Shen CIS, UD
Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Tarek Abdelzaher Vikram Adve CS241 Systems Programming System Calls and I/O.
File I/O open close lseek read and write – unbuffered I/O dup and dup2.
System calls for Process management Process creation, termination, waiting.
1 Unix system calls fork( ) wait( ) exit( ). 2 How To Create New Processes? n Underlying mechanism -A process runs fork to create a child process -Parent.
Operating Systems 162 Practical Session 1 System Calls.
Using System Calls (Unix) Have to tell compiler (if C/C++) where to find the headers, etc. – i.e., the “include” files May have to tell compiler where.
S ALVATORE DI G IROLAMO (TA) Networks and Operating Systems: Exercise Session 1.
Virtualizing the CPU: Processes 1. How to provide the illusion of many CPUs? CPU virtualizing – The OS can promote the illusion that many virtual CPUs.
A process is a program in execution A running system consists of multiple processes – OS processes Processes started by the OS to do “system things” –
Error handling I/O Man pages
Practical Session 5.
CS 3305A Process – Part II Lecture 4 Sept 20, 2017.
Chapter 3: Process Concept
Protection of System Resources
Anton Burtsev February, 2017
ICS143A: Principles of Operating Systems Lecture 13: Context switching
Unix Process Management
Anton Burtsev February, 2017
Processes in Unix, Linux, and Windows
System Structure and Process Model
System Structure and Process Model
Processes in Unix, Linux, and Windows
Operating Systems for Computer Engineering 151
Lecture 5: Process Creation
More on UART Interrupts; System Calls
Fork and Exec Unix Model
System Structure B. Ramamurthy.
Practical Session 1 System Calls
Unix Directories unix etc home pro dev motd snt unix ... slide1 slide2
LINUX System Programming with Processes (additional)
Processes in Unix, Linux, and Windows
System Structure and Process Model
Process Programming Interface
Lecture 6: Multiprogramming and Context Switching
Processes in Unix, Linux, and Windows
Processes in Unix and Windows
EECE.4810/EECE.5730 Operating Systems
EECE.4810/EECE.5730 Operating Systems
Intro to the Shell with Fork, Exec, Wait
Practical Session 1 System Calls
Unix Directories unix etc home pro dev motd snt unix ... slide1 slide2
Presentation transcript:

Practical Session 1 System Calls Operating Systems Practical Session 1 System Calls

A few administrative notes… Course homepage: http://www.cs.bgu.ac.il/~os172/Main Assignments: Extending xv6 (a pedagogical OS) Submission in pairs. Frontal checking: Assume the grader may ask anything. Must register to exactly one checking session.

Operating System An operating system (OS) is system software that manages computer hardware and software resources and provides common services for computer programs.

Main Components for today Process Describes an execution of a program and all of its requirements Kernel The Heart of the OS, manages processes and other resources System Calls Means of communications between the process and the kernel

Process Process Kernel Space User Space Run Kernel code Has: Stack Heap System wide view Direct Hardware access Run user code System calls

System Calls A System Call is an interface between a user application and a service provided by the operating system (or kernel). These can be roughly grouped into five major categories: Process control (e.g. create/terminate process) File Management (e.g. read, write) Device Management (e.g. logically attach a device) Information Maintenance (e.g. set time or date) Communications (e.g. send messages)

System Calls - motivation A process is not supposed to have a direct access the hardware/kernel. It can’t access the kernel memory or functions. This is strictly enforced (‘protected mode’) for good reasons: Can jeopardize other processes running. Cause physical damage to devices. Alter system behavior. The system call mechanism provides a safe mechanism to request specific kernel operations.

Jumping from user space to kernel space A process running in user space cannot run code/access data structures in the kernel space In x86 arch, in order to jump to kernel space, it is common that the process will use interrupts When jumping to kernel space, the process (kernel) must store a “backup” for its current execution state (so that the kernel will be able to resume the execution later), this backup is referred to as a trapframe.

System Calls - interface Calls are usually made with C/C++ library functions: User Application C - Library Kernel System Call getpid() Load arguments, eax  _NR_getpid, kernel mode (int 80) Call Sys_Call_table[eax] sys_getpid() return syscall_exit _NR_getpid – the number of the system call getpid 0x80 – interrupt on Intel’s CPUs resume_userspace return User-Space Kernel-Space Remark: Invoking int 0x80 is common although newer techniques for “faster” control transfer (SYSCALL/SYSRET) are provided by both AMD’s and Intel’s architecture.

Xv6 code

System Calls - interface syscall.h // System call numbers #define SYS_fork 1 #define SYS_exit 2 #define SYS_wait 3 #define SYS_pipe 4 #define SYS_read 5 #define SYS_kill 6 #define SYS_exec 7 #define SYS_fstat 8 #define SYS_chdir 9 #define SYS_dup 10 #define SYS_getpid 11 #define SYS_sbrk 12 #define SYS_sleep 13 #define SYS_uptime 14 #define SYS_open 15 #define SYS_write 16 #define SYS_mknod 17 #define SYS_unlink 18 #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 Calls are usually made with C/C++ library functions: User Application C - Library Kernel System Call getpid() Load arguments, eax  _NR_getpid, kernel mode (int 80) Call Sys_Call_table[eax] sys_getpid() return syscall_exit _NR_getpid – the number of the system call getpid 0x80 – interrupt on Intel’s CPUs resume_userspace return User-Space Kernel-Space Remark: Invoking int 0x80 is common although newer techniques for “faster” control transfer are provided by both AMD’s and Intel’s architecture.

System Calls - interface usys.S #include "syscall.h" #include "traps.h" #define SYSCALL(name) \ .globl name; \ name: \ movl $SYS_ ## name, %eax; \ int $T_SYSCALL; \ ret SYSCALL(fork) SYSCALL(exit) SYSCALL(wait) SYSCALL(pipe) SYSCALL(read) SYSCALL(write) SYSCALL(close) SYSCALL(kill) SYSCALL(exec) SYSCALL(open) SYSCALL(mknod) SYSCALL(unlink) SYSCALL(fstat) SYSCALL(link) SYSCALL(mkdir) SYSCALL(chdir) SYSCALL(dup) SYSCALL(getpid) SYSCALL(sbrk) SYSCALL(sleep) SYSCALL(uptime) System Calls - interface .globl fork; \ fork : \ movl $SYS_fork, %eax; \ int $T_SYSCALL; \ ret Calls are usually made with C/C++ library functions: User Application C - Library Kernel System Call getpid() Load arguments, eax  _NR_getpid, kernel mode (int 80) Call Sys_Call_table[eax] .globl fork; \ fork : \ movl $1, %eax; \ int $64; \ ret sys_getpid() return syscall_exit _NR_getpid – the number of the system call getpid 0x80 – interrupt on Intel’s CPUs resume_userspace return User-Space Kernel-Space Remark: Invoking int 0x80 is common although newer techniques for “faster” control transfer are provided by both AMD’s and Intel’s architecture.

System Calls - interface trapasm.S .globl alltraps alltraps: # Build trap frame. pushl %ds pushl %es pushl %fs pushl %gs pushal . # Call trap(tf), where tf=%esp pushl %esp call trap Calls are usually made with C/C++ library functions: User Application C - Library Kernel System Call getpid() Load arguments, eax  _NR_getpid, kernel mode (int 80) Call Sys_Call_table[eax] sys_getpid() return syscall_exit _NR_getpid – the number of the system call getpid 0x80 – interrupt on Intel’s CPUs resume_userspace return User-Space Kernel-Space Remark: Invoking int 0x80 is common although newer techniques for “faster” control transfer are provided by both AMD’s and Intel’s architecture.

System Calls - interface syscall.c static int (*syscalls[])(void) = { [SYS_fork] sys_fork, [SYS_exit] sys_exit, . [SYS_close] sys_close, }; void syscall(void) { int num; num = proc->tf->eax; if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { proc->tf->eax = syscalls[num](); } else { cprintf("%d %s: unknown sys call %d\n", proc->pid, proc->name, num); proc->tf->eax = -1; } trap.c Void trap(struct trapframe* tf) { . if(tf->trapno == T_SYSCALL){ if(proc->killed) exit(); proc->tf = tf; syscall(); return; } Calls are usually made with C/C++ library functions: User Application C - Library Kernel System Call getpid() Load arguments, eax  _NR_getpid, kernel mode (int 80) Call Sys_Call_table[eax] sys_getpid() return syscall_exit _NR_getpid – the number of the system call getpid 0x80 – interrupt on Intel’s CPUs resume_userspace return User-Space Kernel-Space Remark: Invoking int 0x80 is common although newer techniques for “faster” control transfer are provided by both AMD’s and Intel’s architecture.

System Calls - interface Calls are usually made with C/C++ library functions: trapasm.S . addl $4, %esp # Return falls through to trapret... .globl trapret trapret: popal popl %gs popl %fs popl %es popl %ds addl $0x8, %esp # trapno and errcode iret User Application C - Library Kernel System Call getpid() Load arguments, eax  _NR_getpid, kernel mode (int 80) Call Sys_Call_table[eax] sys_getpid() return syscall_exit _NR_getpid – the number of the system call getpid 0x80 – interrupt on Intel’s CPUs resume_userspace return User-Space Kernel-Space Remark: Invoking int 0x80 is common although newer techniques for “faster” control transfer are provided by both AMD’s and Intel’s architecture.

System Calls – tips Kernel behavior can be enhanced by altering the system calls themselves: imagine we wish to write a message (or add a log entry) whenever a specific user is opening a file. We can re-write the system call open with our new open function and load it to the kernel (need administrative rights). Now all “open” requests are passed through our function. We can examine which system calls are made by a program by invoking strace<arguments>. Strace –c <cmd> will give a summary of all sys calls

Process Control Kernel Space Proc 1 (running) Proc 2 (sleep) Proc 3 (ready) Proc 4 (ready)

Process Control Block enum procstate { UNUSED, EMBRYO, SLEEPING, RUNNABLE, RUNNING, ZOMBIE }; // Per-process state struct proc { uint sz; // Size of process memory (bytes) pde_t* pgdir; // Page table char *kstack; // Bottom of kernel stack for this process enum procstate state; // Process state int pid; // Process ID struct proc *parent; // Parent process struct trapframe *tf; // Trap frame for current syscall struct context *context; // swtch() here to run process void *chan; // If non-zero, sleeping on chan int killed; // If non-zero, have been killed struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) };

The Kill SYSTEM CALL (XV6) /*** sysproc.c ***/ int sys_kill(void) { int pid; if(argint(0, &pid) < 0) return -1; return kill(pid); } /*** syscall.c ***/ static int (*syscalls[])(void) = { [SYS_chdir] sys_chdir, [SYS_close] sys_close, [SYS_dup] sys_dup, [SYS_exec] sys_exec, [SYS_exit] sys_exit, [SYS_fork] sys_fork, [SYS_fstat] sys_fstat, [SYS_getpid] sys_getpid, [SYS_kill] sys_kill, [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_mknod] sys_mknod, [SYS_open] sys_open, [SYS_pipe] sys_pipe, [SYS_read] sys_read, [SYS_sbrk] sys_sbrk, [SYS_sleep] sys_sleep, [SYS_unlink] sys_unlink, [SYS_wait] sys_wait, [SYS_write] sys_write, [SYS_uptime] sys_uptime, }; /*** proc.c ***/ // Kill the process with the given pid. // Process won't exit until it returns // to user space (see trap in trap.c). int kill(int pid) { struct proc *p; acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->pid == pid){ p->killed = 1; // Wake process from sleep if necessary. if(p->state == SLEEPING) p->state = RUNNABLE; release(&ptable.lock); return 0; } return -1; The collection of system calls that a kernel provides is the interface that user programs see. The xv6 kernel provides a subset of the services and system calls that Unix kernels traditionally offer.

Fork pid_t fork(void); Fork is used to create a new process. It creates a duplicate of the original process (including all file descriptors, registers, instruction pointer, etc’). Once the call is finished, the process and its copy go their separate ways. Subsequent changes to one should not effect the other. The fork call returns a different value to the original process (parent) and its copy (child): in the child process this value is zero, and in the parent process it is the PID of the child process. When fork is invoked the parent’s information should be copied to its child – however, this can be wasteful if the child will not need this information (see exec()…). To avoid such situations, Copy On Write (COW) is used for the data section. How do I find out the type of pid_t? Simple: Find out what’s needed: “man fork” The man page specifies ‘unistd.h’, Locate unistd by typing: “whereis unistd.h” Open the file: /usr/include/unistd.h pid_t is redefined with __pid_t Check out all of its included headers You will see that one of the included headers is ‘types.h’ --> sounds relevant ;) Locate ‘types.h’ (/usr/include/bits/types.h) and see that pid_t is simply an int

Copy On Write (COW) How does Linux manage COW? fork() Parent Process DATA STRUCTURE (task_struct) Child Process DATA STRUCTURE (task_struct) write information RW RW RO protection fault! Copying is expensive. The child process will point to the parent’s pages Well, no other choice but to allocate a new RW copy of each required page

Process control An example: Output: my process pid is 8864 int i = 3472; printf("my process pid is %d\n",getpid()); fork_id=fork(); if (fork_id==0){ i= 6794; printf(“child pid %d, i=%d\n",getpid(),i); } else printf(“parent pid %d, i=%d\n",getpid(),i); return 0; Output: my process pid is 8864 child pid 8865, i=6794 parent pid 8864, i=3472 Program flow: PID = 8864 i = 3472 fork () PID = 8865 Answer – expects exec, will show next fork_id=0 i = 6794 fork_id = 8865 i=3472

Process control Exit A process can terminate itself using the exit system call The call for the exit can be either explicit or implicit The exit system call receives a single integer argument that will be the exit status of the process If the child already changed state than the call is returned immediately

Process control - zombies When a process ends, the memory and resources associated with it are deallocated. However, the entry for that process is not removed from the process table. This allows the parent to collect the child’s exit status. When this data is not collected by the parent the child is called a “zombie”. Such a leak is usually not worrisome in itself, however, it is a good indicator for problems to come.

Process control Wait pid_t wait(int *status); pid_t waitpid(pid_t pid, int *status, int options); The wait command is used for waiting on child processes whose state changed (the process terminated, for example). The process calling wait will suspend execution until one of its children (or a specific one) terminates. Waiting can be done for a specific process, a group of processes or on any arbitrary child with waitpid. Once the status of a zombie process is collected that process is removed from the process table by the collecting process. If the child already changed state than the call is returned immediately

Process control exec* int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); exec…. The exec() family of function replaces current process image with a new process image (text, data, bss, stack, etc). Since no new process is created, PID remains the same. Exec functions do not return to the calling process unless an error occurred (in which case -1 is returned and errno is set with a special value). The system call is execve(…) With execv(), the first argument is a path to the executable. With execvp(), the first argument is a filename. It must be converted to a path before it can used. This involves looking for the filename in all of the directories in the PATH environment variable. Bss – all uninitialized data such as static and global variables

Process control – simple shell #define… … int main(int argc, char **argv){ while(true){ type_prompt(); read_command(command, params); pid=fork(); if (pid<0){ if (errno==EAGAIN) printf(“ERROR cannot allocate sufficient memory\n”); continue; } if (pid>0) wait(&status); else execvp(command,params);

Other system calls File Management: open close read write lseek etc…

File management In POSIX operating systems files are accessed via a file descriptor (Microsoft Windows uses a slightly different object: file handle). A file descriptor is an integer specifying the index of an entry in the file descriptor table held by each process. A file descriptor table is held by each process, and contains details of all open files. The following is an example of such a table: File descriptors can refer to files, directories, sockets and a few more data objects. FD Name Other information Standard Input (stdin) … 1 Standard Output (stdout) 2 Standard Error (stderr)

File management Open Close int open(const char *pathname, int flags, mode_t mode); Open returns a file descriptor for a given pathname. This file descriptor will be used in subsequent system calls (according to the flags and mode) Flags define the access mode: O_RDONLY (read only), O_WRONLY (write only), O_RDRW (read write). These can be bit-wised or’ed with more creation and status flags such as O_APPEND, O_TRUNC, O_CREAT. Close Int close(int fd); Closes a file descriptor so it no longer refers to a file. Returns 0 on success or -1 in case of failure (errno is set). Mode - the permissions in case a new file is created using the O_CREAT flag.

File management Read Write ssize_t read(int fd, void *buf, size_t count); Attempts to read up to count bytes from the file descriptor fd, into the buffer buf. Returns the number of bytes actually read (can be less than requested if read was interrupted by a signal, close to EOF, reading from pipe or terminal). On error -1 is returned (and errno is set). Note: The file position advances according to the number of bytes read. Write ssize_t write(int fd, const void *buf, size_t count); Writes up to count bytes to the file referenced to by fd, from the buffer positioned at buf. Returns the number of bytes actually wrote, or -1 (and errno) on error.

File management lseek off_t lseek(int fd, off_t offset, int whence); This function repositions the offset of the file position of the file associated with fd to the argument offset according to the directive whence. Whence can be set to SEEK_SET (directly to offset), SEEK_CUR (current+offset), SEEK_END (end+offset). Positioning the offset beyond file end is allowed. This does not change the size of the file. Writing to a file beyond its end results in a “hole” filled with ‘\0’ characters (null bytes). Returns the location as measured in bytes from the beginning of the file, or -1 in case of error (and set errno).

File management Dup int dup(int oldfd); int dup2(int oldfd, int newfd); The dup commands create a copy of the file descriptor oldfd. After a successful dup command is executed the old and new file descriptors may be used interchangeably. They refer to the same open file descriptions and thus share information such as offset and status. That means that using lseek on one will also affect the other! They do not share descriptor flags (FD_CLOEXEC). Dup uses the lowest numbered unused file descriptor, and dup2 uses newfd (closing current newfd if necessary). Returns the new file descriptor, or -1 in case of an error (and set errno). A dup3() command exists in kernel 3.0 Examples for dup: http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html

File management Consider the following example: fileFD= open(“file.txt”…); close(1); /* closes file handle 1, which is stdout.*/ fd =dup(fileFD); /* will create another file handle. File handle 1 is free, so it will be allocated. */ close(fileFD); /* don’t need this descriptor anymore.*/ printf(“this did not go to stdout”); As a result (abstract): stdin … 1 stdout 2 stderr 3 file.txt stdin … 1 file.txt 2 stderr

File management - example #define… … #define RW_BLOCK 10 int main(int argc, char **argv){ int fdsrc, fddst; ssize_t readBytes, wroteBytes; char *buf[RW_BLOCK]; char *source = argv[1]; char *dest = argv[2]; fdsrc=open(source,O_RDONLY); if (fdsrc<0){ perror("ERROR while trying to open source file:"); exit(-1); } fddst=open(dest,O_RDWR|O_CREAT|O_TRUNC, 0666); if (fddst<0){ perror("ERROR while trying to open destination file:"); exit(-2);

File management - example lseek(fddst,20,SEEK_SET); do{ readBytes=read(fdsrc, buf, RW_BLOCK); if (readBytes<0){ if (errno == EIO){ printf("I/O errors detected, aborting.\n"); exit(-10); } exit (-11); wroteBytes=write(fddst, buf, readBytes); if (wroteBytes<RW_BLOCK) if (errno == EDQUOT) printf("ERROR: out of quota.\n"); else if (errno == ENOSPC) printf("ERROR: not enough disk space.\n"); } while (readBytes>0); lseek(fddst,0,SEEK_SET); write(fddst,"\\*WRITE START*\\\n",16); close(fddst); close(fdsrc); return 0;

Fork – example (1) How many lines of “Hello” will be printed in the following example: int main(int argc, char **argv){ int i; for (i=0; i<10; i++){ fork(); printf(“Hello \n”); } return 0;

Fork – example (1) How many lines of “Hello” will be printed in the following example: int main(int argc, char **argv){ int i; for (i=0; i<10; i++){ fork(); printf(“Hello \n”); } return 0; Program flow: Total number of printf calls: i=0 i=1 i=2

Fork – example (2) How many lines of “Hello” will be printed in the following example: int main(int argc, char **argv){ int i; for (i=0; i<10; i++){ printf(“Hello \n”); fork(); } return 0;

Fork – example (2) How many lines of “Hello” will be printed in the following example: int main(int argc, char **argv){ int i; for (i=0; i<10; i++){ printf(“Hello \n”); fork(); } return 0; Program flow: Total number of printf calls: i=0 i=1 i=2

Fork – example (3) How many lines of “Hello” will be printed in the following example: int main(int argc, char **argv){ int i; for (i=0; i<10; i++) fork(); printf(“Hello \n”); return 0; }

Fork – example (3) How many lines of “Hello” will be printed in the following example: int main(int argc, char **argv){ int i; for (i=0; i<10; i++) fork(); printf(“Hello \n”); return 0; } Program flow: Total number of printf calls: i=0 i=1 i=2