• 沒有找到結果。

系統程式

N/A
N/A
Protected

Academic year: 2021

Share "系統程式"

Copied!
62
0
0

加載中.... (立即查看全文)

全文

(1)

系統程式

系統程式

朱浩華教授

朱浩華教授

/

/

施吉昇教

施吉昇教

(2)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Contents

Contents

1.

1.

Preface/Introduction

Preface/Introduction

2.

2.

Standardization and Implementation

Standardization and Implementation

3.

3.

File I/O

File I/O

4.

4.

Standard I/O Library

Standard I/O Library

5.

5.

Files and Directories

Files and Directories

6.

6.

System Data Files and Information

System Data Files and Information

7.

7.

Environment of a Unix Process

Environment of a Unix Process

8.

8.

Process Control

Process Control

9.

9.

Signals

Signals

10.

(3)

Multi-processes in modern

Multi-processes in modern

systems

systems

Image that you are now a system architect to

Image that you are now a system architect to

design a new multi-process systems.

design a new multi-process systems.

Q1: How does the systems create a new process and

Q1: How does the systems create a new process and

terminate a process?

terminate a process?

Q2: What processes you need when the system

Q2: What processes you need when the system

starts?

starts?

Q2: Should you impose a communist or democratic

Q2: Should you impose a communist or democratic

system on your system?

(4)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Process Control

Process Control

Special Processes

Special Processes

PID 0 –

PID 0 –

Swapper

Swapper

(I.e., the scheduler)

(I.e., the scheduler)

Kernel process

Kernel process

No program on disks correspond to this proce

No program on disks correspond to this proce

ss

ss

PID 1 –

PID 1 –

init

init

responsible for bringing up a Unix sy

responsible for bringing up a Unix sy

stem after the kernel has been bootstrapped. (/et

stem after the kernel has been bootstrapped. (/et

c/rc* & init or /sbin/rc* & init)

c/rc* & init or /sbin/rc* & init)

User process with superuser privileges

User process with superuser privileges

PID 2 - pagedaemon responsible for paging

PID 2 - pagedaemon responsible for paging

Kernel process

(5)

Memory Management

Memory Management

Virtual Memory – Demand paging

Virtual Memory – Demand paging

File System

Swap Space

Run

Swap-Out/In

Logical Memory

Memory Map

(Page Table)

Physical Memory

(6)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Memory Management

Memory Management

Virtual Memory – Demand paging

Virtual Memory – Demand paging

File System

Swap Space

Run

Swap-Out

Swap-In

CPU

MMU

Page

Table

TLB

Logical

Address

Memory

Physical

Address

(7)

Memory Management

Memory Management

Demand Paging

Demand Paging

Page fault -> disk I/O -> modify the page

Page fault -> disk I/O -> modify the page

table -> rerun the instruction!

table -> rerun the instruction!

F

P

D

P

F

D

page fault

disk I/O

File System /

Memory

Logical Address

Physical Address

Page

Table

(8)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Process Control

Process Control

#include <sys/types.h>

#include <sys/types.h>

#include <unistd.h>

#include <unistd.h>

pid_t getpid(void);

pid_t getpid(void);

pid_t getppid(void);

pid_t getppid(void);

uid_t getuid(void);

uid_t getuid(void);

uid_t geteuid(void);

uid_t geteuid(void);

gid_t getgid(void);

gid_t getgid(void);

gid_t getegid(void);

gid_t getegid(void);

None of them has an error return.

(9)

Discussion

Discussion

How can your systems have multiple

How can your systems have multiple

processes?

processes?

(10)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

If ((pid=fork()) == 0){

{

}

else {

}

exit(0);

if ((pid=fork() == 0){

{

}

else {

}

exit(0);

Parent

Child

fork()

What’s a

What’s a

Fork()

Fork()

Child is an exact copy of the parent process.

Child is an exact copy of the parent process.

They have their own memory space.

(11)

fork

fork

#include <sys/types.h>

#include <sys/types.h>

#include <unistd.h>

#include <unistd.h>

pid_t fork(void);

pid_t fork(void);

The only way beside the bootstrap process to

The only way beside the bootstrap process to

create a new process.

create a new process.

Call once but return twice

Call once but return twice

0 for the child process (getppid)

0 for the child process (getppid)

Child pid for the parent (1:n)

Child pid for the parent (1:n)

Copies of almost everything but no sharing of

Copies of almost everything but no sharing of

memory, except text

memory, except text

Copy-on-write (fork() – exec())

(12)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

fork

fork

Program 8.1 – Page 212

Program 8.1 – Page 212

fork(), race conditions, write vs standard I/O

fork(), race conditions, write vs standard I/O

functions

functions

File sharing

File sharing

Sharing of file offesets (including stdin, stdo

Sharing of file offesets (including stdin, stdo

ut, stderr)

ut, stderr)

Tables of

Opened Files

(per process)

System

Open File

Table

In-core

i-node

list

(13)

fork

fork

Normal cases in fork:

Normal cases in fork:

The parent waits for the child to complete.

The parent waits for the child to complete.

The parent and child each go their own way (e.g., ne

The parent and child each go their own way (e.g., ne

twork servers).

twork servers).

Inherited properties:

Inherited properties:

Real/effective [ug]id, supplementary gid, process group ID, ses

Real/effective [ug]id, supplementary gid, process group ID, ses

sion ID, controlling terminal, set[ug]id flag, current working dir, r

sion ID, controlling terminal, set[ug]id flag, current working dir, r

oot dir, file-mode creation mask, signal mask & dispositions, FD

oot dir, file-mode creation mask, signal mask & dispositions, FD

_CLOEXEC flags, environment, attached shared memory segm

_CLOEXEC flags, environment, attached shared memory segm

ents, resource limits

ents, resource limits

Differences on properties:

Differences on properties:

Returned value from fork, process ID, parent pid, tms_[us]time,

Returned value from fork, process ID, parent pid, tms_[us]time,

tms_c[us]time, file locks, pending alarms, pending signals

(14)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

fork

fork

Reasons for fork to fail

Reasons for fork to fail

Too many processes in the system

Too many processes in the system

The total number of processes for the real uid exceed

The total number of processes for the real uid exceed

s the limit

s the limit

CHILD_MAX

CHILD_MAX

Usages of fork

Usages of fork

Duplicate a process to run different sections of code

Duplicate a process to run different sections of code

Network servers

Network servers

Want to run a different program

Want to run a different program

shells (spawn = fork+exec)

(15)

vfork

vfork

Design Objective

Design Objective

An optimization on performance

An optimization on performance

Execute exec right after returns from fork.

Execute exec right after returns from fork.

Mechanism – SVR4 & 4.3+BSD

Mechanism – SVR4 & 4.3+BSD

Since 4BSD

Since 4BSD

<vfork.h> in some systems

<vfork.h> in some systems

No fully copying of the parent’s address space i

No fully copying of the parent’s address space i

nto the child.

nto the child.

Sharing of address space

(16)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

vfork

vfork

vfork() is as the same as fork() except

vfork() is as the same as fork() except

The child runs in the address space of its parent.

The child runs in the address space of its parent.

The parent waits until the child calls exit or exec.

The parent waits until the child calls exit or exec.

Child process always executes first.

Child process always executes first.

A possibility of deadlock if the child waits for the par

A possibility of deadlock if the child waits for the par

ent to do something before calling exec().

ent to do something before calling exec().

Program 8.2 – Page 217

Program 8.2 – Page 217

vfork,

vfork,

_exit vs exit (flushing/closing of stdout)

_exit vs exit (flushing/closing of stdout)

exit() may close the file descriptors, causing printf() to f

exit() may close the file descriptors, causing printf() to f

ail.

(17)

Deadlock – One Example

(18)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Process Termination

Process Termination

Eight ways to terminate:

Eight ways to terminate:

Normal termination

Normal termination

Return from main()

Return from main()

exit(main(argc, argv));

exit(main(argc, argv));

Call

Call exit()

Call

Call _exit()

or _Exit()

or

Return of the last thread from its start routine

Return of the last thread from its start routine

Calling

Calling

pthread_exit

pthread_exit

from the last thread.

from the last thread.

Abnormal termination (Chapter 10)

Abnormal termination (Chapter 10)

Call abort()

Call abort()

Be terminated by a signal

Be terminated by a signal

Response of the last thread to a cancellation request.

(19)

exit

exit

Termination

Termination

The same code in the kernel is finally execute

The same code in the kernel is finally execute

d.

d.

Close all open descriptors, release memory

Close all open descriptors, release memory

, and the like.

, and the like.

Exit status vs. termination status

Exit status vs. termination status

Exit status (arg from exit, _exit, or return)

Exit status (arg from exit, _exit, or return)

termination status

termination status

In abnormal case, the kernel generates it.

In abnormal case, the kernel generates it.

wait & waitpid to retrieve the termination sta

wait & waitpid to retrieve the termination sta

tus.

(20)

Tei-Wei Kuo, Chi-Sheng Shih, and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

(21)

Annoucements

Annoucements

Midterm exam scores are out

Midterm exam scores are out

Average: 68.1

Average: 68.1

Std. Dev: 20.35

Std. Dev: 20.35

MP3 is out today

MP3 is out today

(22)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Fun project #1

Fun project #1

Hyperdragging (1999)

Hyperdragging (1999)

Dragging into the physical space

Dragging into the physical space

(23)

Fun project #2

Fun project #2

Diamond touch (2005)

Diamond touch (2005)

Lay display flat on the table, and interactions g

Lay display flat on the table, and interactions g

et interesting …

et interesting …

(24)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Discussion

Discussion

wait() and waitpid() are called by the par

wait() and waitpid() are called by the par

ent process to retrieve the termination s

ent process to retrieve the termination s

tatus of its child process.

tatus of its child process.

Questions:

Questions:

How to use these functions?

How to use these functions?

What if the child processes terminate before w

What if the child processes terminate before w

ait() and waitpid() are called?

ait() and waitpid() are called?

(25)

wait & waitpid

wait & waitpid

#include <sys/types.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <sys/wait.h>

pid_t wait(int *statloc);

pid_t wait(int *statloc);

pid_t waitpid(pid_t pid, int *statloc, int op);

pid_t waitpid(pid_t pid, int *statloc, int op);

wait will block until one child terminates or an error c

wait will block until one child terminates or an error c

ould be returned.

ould be returned.

waitpid could wait for a specific one and has an optio

waitpid could wait for a specific one and has an optio

n not to be blocked.

n not to be blocked.

SIGCHILD from the kernel if a child terminat

SIGCHILD from the kernel if a child terminat

es

es

Default action is ignoring.

(26)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

wait & waitpid

wait & waitpid

Three situations in calling wait/waitpid

Three situations in calling wait/waitpid

Block

Block

Return with the termination status of a child

Return with the termination status of a child

Return with an error.

Return with an error.

Termination Status <sys/wait.h> – Figure 8.4

Termination Status <sys/wait.h> – Figure 8.4

Access termination status through the following MACROs

Access termination status through the following MACROs

Exit status (WIFEXITED, WEXITSTATUS)

Exit status (WIFEXITED, WEXITSTATUS)

WIFEXITED(status): if successfully exited (true/false)

WIFEXITED(status): if successfully exited (true/false)

WEXITSTATUS(status): exit code

WEXITSTATUS(status): exit code

Signal # (WIFSIGNALED, WTERMSIG)

Signal # (WIFSIGNALED, WTERMSIG)

Core dump (WCOREDUMP)

Core dump (WCOREDUMP)

Others (WIFSTOPPED, WSTOPSIG)

(27)

Program 8.5 – Page 222

Program 8.5 – Page 222

void

pr_exit(int status)

{

if (WIFEXITED(status))

printf("normal termination, exit status = %d\n",

WEXITSTATUS(status));

else if (WIFSIGNALED(status))

printf("abnormal termination, signal number = %

d%s\n",

WTERMSIG(status),

#ifdef WCOREDUMP

WCOREDUMP(status) ? " (core file g

enerated)" : "");

#else

"");

#endif

else if (WIFSTOPPED(status))

printf("child stopped, signal number = %d\n",

WSTOPSIG(status));

}

linux1:~/sys_prog_06/test> fig.8.6.exe

normal termination, exit status = 7

abnormal termination, signal number = 6

abnormal termination, signal number = 8

if ((pid = fork()) < 0)

if ((pid = fork()) < 0)

err_sys("fork error");

err_sys("fork error");

else if (pid == 0) /* child */

else if (pid == 0) /* child */

exit(7);

exit(7);

if (wait(&status) != pid) /* wait for child */

if (wait(&status) != pid) /* wait for child */

err_sys("wait error");

err_sys("wait error");

pr_exit(status); /* and print its status */

pr_exit(status); /* and print its status */

if ((pid = fork()) < 0)

if ((pid = fork()) < 0)

err_sys("fork error");

err_sys("fork error");

else if (pid == 0) /* child */

else if (pid == 0) /* child */

abort(); /* generates SIGABRT *

abort(); /* generates SIGABRT *

/

/

if (wait(&status) != pid) /* wait for child */

if (wait(&status) != pid) /* wait for child */

err_sys("wait error");

err_sys("wait error");

pr_exit(status); /* and print its status */

pr_exit(status); /* and print its status */

if ((pid = fork()) < 0)

if ((pid = fork()) < 0)

err_sys("fork error");

err_sys("fork error");

else if (pid == 0) /* child */

else if (pid == 0) /* child */

status /= 0; /* divide by 0 generates SI

status /= 0; /* divide by 0 generates SI

GFPE */

GFPE */

if (wait(&status) != pid) /* wait for child */

if (wait(&status) != pid) /* wait for child */

(28)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Zombie process

Zombie process

zombie

zombie

The process has terminated, but its parent

The process has terminated, but its parent

has not yet waited for it.

has not yet waited for it.

It keeps the minimal information for the

It keeps the minimal information for the

parent process.

parent process.

(29)

If (pid=fork() == 0){

{

exit(0);

}

else {

// parent’s code

}

Parent

Child

fork()

How is a Zombie process created?

How is a Zombie process created?

If (pid=fork() == 0){

{

exit(0);

}

else {

// parent’s code

}

(30)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Cleaning up Zombies

Cleaning up Zombies

What if the parent process terminates

What if the parent process terminates

before the child process?

before the child process?

Inherited by init

Inherited by init

When a parent terminates, it is done by

When a parent terminates, it is done by

the kernel.

the kernel.

Clean up of the zombies by the init – wait

Clean up of the zombies by the init – wait

whenever needed!

whenever needed!

(31)

Discussion: why do we

Discussion: why do we

need zombie?

need zombie?

A parent process can end up with two

A parent process can end up with two

different children that share the same PID.

different children that share the same PID.

A parent process can end up trying to wait

A parent process can end up trying to wait

for the return code of another process’s

for the return code of another process’s

child.

child.

If child process completely disappear, its parent

If child process completely disappear, its parent

process won’t be able to wait on & fetch its

process won’t be able to wait on & fetch its

termination status.

termination status.

(32)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

wait & waitpid

wait & waitpid

pid_t waitpid(pid_t pid, int *statloc, int op);

pid_t waitpid(pid_t pid, int *statloc, int op);

pid

pid

pid == -1

pid == -1

wait for any child

wait for any child

pid > 0

pid > 0

wait for the child with pid

wait for the child with pid

pid == 0

pid == 0

wait for any child with the same group id

wait for any child with the same group id

pid < -1

pid < -1

wait for any child with the group ID = |pid|

wait for any child with the group ID = |pid|

return

return

pid of the child

pid of the child

0 if WNOHANG flag is set & the specified pid does not

0 if WNOHANG flag is set & the specified pid does not

exit

exit

-1 an error is returned -> how can an error occur?

(33)

wait & waitpid

wait & waitpid

Errors

Errors

No such child or wrong parent

No such child or wrong parent

Option for waitpid

Option for waitpid

WNOHANG, WUNTRACED

WNOHANG, WUNTRACED

WNOWAIT, WCONTINUED (SVR4)

WNOWAIT, WCONTINUED (SVR4)

(34)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Troubles from Zombie

Troubles from Zombie

Although Zombie processes do not occupy

Although Zombie processes do not occupy

any memory space in the system, it consumes

any memory space in the system, it consumes

process IDs

process IDs

, which are limited resources too.

, which are limited resources too.

You may not be able to fork new child

You may not be able to fork new child

processes when there are too many zombie

processes when there are too many zombie

processes in the systems.

processes in the systems.

CHILD_MAX: max number of simultaneous processes

CHILD_MAX: max number of simultaneous processes

per real user ID

per real user ID

How to fork a new child process but

How to fork a new child process but

not asking the parent process to wait for the child AND

not asking the parent process to wait for the child AND

not generating zombie process?

(35)

if (pid1=fork() == 0){

{

if (pid2=fork() == 0) {

}

else

exit(0);

}

else

waitpid(pid1, NULL, 0)

exit(0);

Parent

How to create a background process

How to create a background process

without making a zombie?

without making a zombie?

Child

if (pid1=fork() == 0){

{

if (pid2=fork() == 0) {

}

else

exit(0);

}

else

exit(0);

Grandchild

if (pid1=fork() == 0){

{

if (pid2=fork() == 0) {

sleep(2);

// grandchild exec

}

else

exit(0);

}

else

exit(0);

(36)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

waitid

waitid

#include <sys/wait.h>

#include <sys/wait.h>

pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

pid_t waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

Defined in XSI extension

Defined in XSI extension

Similar to waitpid() but provide extra info.

Similar to waitpid() but provide extra info.

idtype:

idtype:

P_PID: wait for a particular process

P_PID: wait for a particular process

P_PGID: wait for a group of process

P_PGID: wait for a group of process

P_ALL: wait for any child process

P_ALL: wait for any child process

options:

options:

WCONTINUED

WCONTINUED

WNOHANG

WNOHANG

WSTOPPED

WSTOPPED

WNOWAIT: the exit status will be kept for other wait() functions.

WNOWAIT: the exit status will be kept for other wait() functions.

WEXITED

(37)

wait3 & wait4 – resource

wait3 & wait4 – resource

usage info

usage info

#include <sys/types.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <sys/wait.h>

#include <sys/time.h>

#include <sys/time.h>

#include <sys/resource.h>

#include <sys/resource.h>

pid_t wait3(int *statloc, int op, struct rusage *rusage);

pid_t wait3(int *statloc, int op, struct rusage *rusage);

pid_t wait4(pid_t pid, int *statloc, int op, struct rusage

pid_t wait4(pid_t pid, int *statloc, int op, struct rusage

*rusage);

*rusage);

4.3+BSD – Figure 8.4, Page 203

4.3+BSD – Figure 8.4, Page 203

User/system CPU time, # of page faults, # of signal

User/system CPU time, # of page faults, # of signal

s received, the like.

(38)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Race Conditions

Race Conditions

Def: When multiple processes are

Def: When multiple processes are

trying to do something with shared

trying to do something with shared

data, the final outcome depends on the

data, the final outcome depends on the

order in which the processes run.

order in which the processes run.

(39)

Race condition example

Race condition example

A is the number of available copies

A is the number of available copies

of a book = 1.

of a book = 1.

Two processes (transactions)

Two processes (transactions)

running concurrently.

running concurrently.

Race between T1 & T2!

Race between T1 & T2!

T1 wants to buy one copy.

T1 wants to buy one copy.

T2 wants to buy one copy.

T2 wants to buy one copy.

T1 gets an error.

T1 gets an error.

The result is different from any serial

The result is different from any serial

schedule T1,T2 or T2,T1

schedule T1,T2 or T2,T1

How to solve this?

How to solve this?

Locking mechanism

Locking mechanism

T1

T1

T2

T2

R(A=1)

R(A=1)

Check if

Check if

(A>0)

(A>0)

R(A=1)

R(A=1)

Check if

Check if

(A>0)

(A>0)

W(A=0)

W(A=0)

W(A=0)

W(A=0)

Error!

Error!

(40)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Another race condition

Another race condition

example

example

Situation: T2 reads an object that has b

Situation: T2 reads an object that has b

een modified by T1, but T1 has not com

een modified by T1, but T1 has not com

mitted.

mitted.

T1 transfers $100 from A to B. T2 adds

T1 transfers $100 from A to B. T2 adds

6% interests to A and B. A non-serializ

6% interests to A and B. A non-serializ

able schedule is:

able schedule is:

Step 1: deduct $100 from A.

Step 1: deduct $100 from A.

Step 2: add 6% interest to A & B.

Step 2: add 6% interest to A & B.

Step 3: credit $100 in B.

Step 3: credit $100 in B.

Why is the problem?

Why is the problem?

The result differs based on different order of

The result differs based on different order of

execution

execution

The result differs from any serial schedule

The result differs from any serial schedule

-> Bank adds $6 less interest.

> Bank adds $6 less interest.

T1

T1

T2

T2

R(A)

R(A)

W(A-100)

W(A-100)

R(A)

R(A)

W(A+6%)

W(A+6%)

R(B)

R(B)

W(B+6%)

W(B+6%)

Commit

Commit

R(B)

R(B)

W(B+100

W(B+100

)

)

Commit

Commit

(41)

Race Conditions

Race Conditions

Example: Program 8.8 – Page 225

Example: Program 8.8 – Page 225

Who is the parent of the 2

Who is the parent of the 2

nd

nd

child?

child?

Program 8.12 – Page 229

Program 8.12 – Page 229

Mixture of output by putc + setting of unbuffer

Mixture of output by putc + setting of unbuffer

ing for stdout

ing for stdout

(42)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Can you spot the potential race

Can you spot the potential race

condition?

condition?

(avoid zombie processes by calling fork

(avoid zombie processes by calling fork

twice)

twice)

int

int

main(void)

main(void)

{

{

pid_t pid;

pid_t pid;

if ((pid = fork()) < 0) {

if ((pid = fork()) < 0) {

err_sys("fork error");

err_sys("fork error");

} else if (pid == 0) { /* first child */

} else if (pid == 0) { /* first child */

if ((pid = fork()) < 0)

if ((pid = fork()) < 0)

err_sys("fork error");

err_sys("fork error");

else if (pid > 0)

else if (pid > 0)

exit(0); /* parent from second fork == first child */

exit(0); /* parent from second fork == first child */

/*

/*

* We're the second child; our parent becomes init as soon

* We're the second child; our parent becomes init as soon

* as our real parent calls exit() in the statement above.

* as our real parent calls exit() in the statement above.

* Here's where we'd continue executing, knowing that when

* Here's where we'd continue executing, knowing that when

* we're done, init will reap our status.

* we're done, init will reap our status.

*/

*/

sleep(2);

sleep(2);

printf("second child, parent pid = %d\n", getppid());

printf("second child, parent pid = %d\n", getppid());

exit(0);

exit(0);

}

}

if (waitpid(pid, NULL, 0) != pid)

if (waitpid(pid, NULL, 0) != pid)

/* wait for first child */

/* wait for first child */

err_sys("waitpid error");

err_sys("waitpid error");

/*

/*

* We're the parent (the original pr

* We're the parent (the original pr

ocess); we continue executing,

ocess); we continue executing,

* knowing that we're not the pare

* knowing that we're not the pare

nt of the second child.

nt of the second child.

*/

*/

exit(0);

exit(0);

}

}

What if the 2nd child exit

What if the 2nd child exit

before the 1st child calle

before the 1st child calle

d exit(0)?

d exit(0)?

- parent of 2nd child is n

- parent of 2nd child is n

ot init by the 1st child.

ot init by the 1st child.

What if the 2nd child exit

What if the 2nd child exit

before the 1st child calle

before the 1st child calle

d exit(0)?

d exit(0)?

- parent of 2nd child is n

- parent of 2nd child is n

ot init by the 1st child.

(43)

Race Conditions

Race Conditions

How to synchronize parent and child proce

How to synchronize parent and child proce

sses?

sses?

Busy wait?

Busy wait?

Waste CPU time, other means possible: Inter-Proce

Waste CPU time, other means possible: Inter-Proce

ss Communication facility, such as pipe fifo, semaph

ss Communication facility, such as pipe fifo, semaph

ore, shared memory, etc.

ore, shared memory, etc.

Program 8.13 on Page 206

Program 8.13 on Page 206

WAIT_PARENT(), TELL_CHILD(), WAIT_CHILD(),

WAIT_PARENT(), TELL_CHILD(), WAIT_CHILD(),

TELL_PARENT()

TELL_PARENT()

while (getppid() != 1)

sleep(1);

(44)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Can you spot the potential race

Can you spot the potential race

condition?

condition?

(avoid zombie processes by calling fork

(avoid zombie processes by calling fork

twice)

twice)

int

int

main(void)

main(void)

{

{

pid_t pid;

pid_t pid;

if ((pid = fork()) < 0) {

if ((pid = fork()) < 0) {

err_sys("fork error");

err_sys("fork error");

} else if (pid == 0) { /* first child */

} else if (pid == 0) { /* first child */

if ((pid = fork()) < 0)

if ((pid = fork()) < 0)

err_sys("fork error");

err_sys("fork error");

else if (pid > 0)

else if (pid > 0)

exit(0); /* parent from second fork == first child */

exit(0); /* parent from second fork == first child */

/*

/*

* We're the second child; our parent becomes init as soon

* We're the second child; our parent becomes init as soon

* as our real parent calls exit() in the statement above.

* as our real parent calls exit() in the statement above.

* Here's where we'd continue executing, knowing that when

* Here's where we'd continue executing, knowing that when

* we're done, init will reap our status.

* we're done, init will reap our status.

*/

*/

sleep(2);

sleep(2);

printf("second child, parent pid = %d\n", getppid());

printf("second child, parent pid = %d\n", getppid());

while (getppid() != 1)

sleep(1);

exit(0);

exit(0);

}

}

if (waitpid(pid, NULL, 0) != pid)

if (waitpid(pid, NULL, 0) != pid)

/* wait for first child */

/* wait for first child */

err_sys("waitpid error");

err_sys("waitpid error");

/*

/*

* We're the parent (the original pr

* We're the parent (the original pr

ocess); we continue executing,

ocess); we continue executing,

* knowing that we're not the pare

* knowing that we're not the pare

nt of the second child.

nt of the second child.

*/

*/

exit(0);

exit(0);

}

}

What if the 2nd child exit

What if the 2nd child exit

before the 1st child calle

before the 1st child calle

d exit(0)?

d exit(0)?

- parent of 2nd child is n

- parent of 2nd child is n

ot init by the 1st child.

ot init by the 1st child.

What if the 2nd child exit

What if the 2nd child exit

before the 1st child calle

before the 1st child calle

d exit(0)?

d exit(0)?

- parent of 2nd child is n

- parent of 2nd child is n

ot init by the 1st child.

(45)

Can you spot the potential race

Can you spot the potential race

condition?

condition?

Program 8.12 on page 229

Program 8.12 on page 229

static void charatatime(char *);

static void charatatime(char *);

int main(void)

int main(void)

{

{

pid_t pid;

pid_t pid;

if ((pid = fork()) < 0) {

if ((pid = fork()) < 0) {

err_sys("fork error");

err_sys("fork error");

} else if (pid == 0) {

} else if (pid == 0) {

charatatime("output from child\n");

charatatime("output from child\n");

} else {

} else {

charatatime("output from parent\n");

charatatime("output from parent\n");

}

}

exit(0);

exit(0);

}

}

static void charatatime(char *str)

static void charatatime(char *str)

{

{

char *ptr;

char *ptr;

int c;

int c;

setbuf(stdout, NULL); /* set unbuffered */

setbuf(stdout, NULL); /* set unbuffered */

for (ptr = str; (c = *ptr++) != 0; )

for (ptr = str; (c = *ptr++) != 0; )

$ ./a.out

$ ./a.out

ooutput from child

ooutput from child

utput from parent

utput from parent

$ ./a.out

$ ./a.out

output from child

output from child

output from parent

output from parent

(46)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Avoid race condition

Avoid race condition

#include <sys/types.h>

#include <sys/types.h>

#include "ourhdr.h"

#include "ourhdr.h"

static

static

void

void

charatatime(

charatatime(

char

char

*);

*);

int

int

main(

main(

void

void

)

)

{

{

pid_t pid;

pid_t pid;

if

if

( (pid = fork()) < 0)

( (pid = fork()) < 0)

err_sys("fork error");

err_sys("fork error");

else

else

if

if

(pid == 0)

(pid == 0)

{

{

charatatime("output from child\n");

charatatime("output from child\n");

}

}

else

else

{

{

charatatime("output from parent\n");

charatatime("output from parent\n");

}

}

exit(0);

exit(0);

}

}

static

static

void

void

charatatime(

charatatime(

char

char

*str)

*str)

{

{

… …

… …

}

}

TELL_WAIT();

TELL_WAIT();

WAIT_PARENT(); // parent goes first

WAIT_PARENT(); // parent goes first

TELL_CHILD(pid);

(47)

exec (6 variations)

exec (6 variations)

Replace the text, data, heap, and stack segments of a proc

Replace the text, data, heap, and stack segments of a proc

ess with a program!

ess with a program!

Specify: new program, command line args, environment

Specify: new program, command line args, environment

#include <unistd.h>

#include <unistd.h>

int execl(const char *pathname, const char *arg0, … /* (char *)

int execl(const char *pathname, const char *arg0, … /* (char *)

0 */);

0 */);

int execv(const char *pathname, char *const argv[]);

int execv(const char *pathname, char *const argv[]);

int execle(const char *pathname, const char *arg0, … /* (char

int execle(const char *pathname, const char *arg0, … /* (char

*) 0, char *const envp[] */);

*) 0, char *const envp[] */);

int execve(const char *pathname, char *const argv[], char *co

int execve(const char *pathname, char *const argv[], char *co

nst envp[]);

nst envp[]);

int execlp(const char *filename, const char *arg0, … /* (char *)

int execlp(const char *filename, const char *arg0, … /* (char *)

0 */);

0 */);

int execvp(const char *filename, char *const argv[]);

(48)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

exec

exec

l

l

,

,

v

v

, and

, and

e

e

stands for list, vector, and environment, r

stands for list, vector, and environment, r

espectively.

espectively.

command-line arg must end with null pointer

command-line arg must end with null pointer

Limit on # of command line args: ARG_MAX

Limit on # of command line args: ARG_MAX

With

With

p

p

, a filename is specified unless it contains ‘/’.

, a filename is specified unless it contains ‘/’.

PATH=/bin:/usr/bin:.

PATH=/bin:/usr/bin:.

/bin/sh is invoked with “filename” if the file is not

/bin/sh is invoked with “filename” if the file is not

a machine executable.

a machine executable.

When do you want to change environ parameters?

When do you want to change environ parameters?

login process

login process

(49)

exec

exec

Inherited from the calling process:

Inherited from the calling process:

pid, ppid, real [ug]id, supplementary gid, proc gid, se

pid, ppid, real [ug]id, supplementary gid, proc gid, se

ssion id, controlling terminal, time left until alarm clo

ssion id, controlling terminal, time left until alarm clo

ck, current working dir, root dir, file mode creation m

ck, current working dir, root dir, file mode creation m

ask, file locks, proc signal mask, pending signals, re

ask, file locks, proc signal mask, pending signals, re

source limits, tms_[us]time, tms_cutime, tms_ustime

source limits, tms_[us]time, tms_cutime, tms_ustime

FD_CLOEXEC flag

FD_CLOEXEC flag

Requirement

Requirement

Closing of open dir streams

Closing of open dir streams

May change:

May change:

effective user/group ID if new program has set-uid-I

effective user/group ID if new program has set-uid-I

D bit set

(50)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

exec

exec

In many Unix implementations, execve() is a

In many Unix implementations, execve() is a

system call, other exec are library functions

system call, other exec are library functions

calling execve().

calling execve().

Program 8.8 – Page 235

Program 8.8 – Page 235

Program 8.9 – Page 236

Program 8.9 – Page 236

The prompt bet the printing of argv[0] and argv[1].

The prompt bet the printing of argv[0] and argv[1].

execvp

execlp

execv

execl

execve

execle

build argv

build argv

build argv

try each

PATH prefix

use

environ

(51)

exec example

exec example

char *env_init[] = { "USER=unknown", "PATH=/t

char *env_init[] = { "USER=unknown", "PATH=/t

mp", NULL };

mp", NULL };

int int main(void) main(void) { {

pid_t pid;pid_t pid;

if ((pid = fork()) < 0) {if ((pid = fork()) < 0) {

err_sys("fork error");err_sys("fork error");

} else if (pid == 0) { /* specify pathname, specify environment */} else if (pid == 0) { /* specify pathname, specify environment */

if if

(execle("/mnt/professor/hchu/sys_pro

(execle("/mnt/professor/hchu/sys_pro

g_06/test/fig8.17.exe", "echoall", "myar

g_06/test/fig8.17.exe", "echoall", "myar

g1", "MY ARG2", (char *)0, env_init) < 0)

g1", "MY ARG2", (char *)0, env_init) < 0)

err_sys("execle error");

err_sys("execle error");

}

}

if (waitpid(pid, NULL, 0) < 0)if (waitpid(pid, NULL, 0) < 0)

err_sys("wait error");err_sys("wait error");

if ((pid = fork()) < 0) {if ((pid = fork()) < 0) {

err_sys("fork error");err_sys("fork error");

} else if (pid == 0) { /* specify filename, inherit environment */} else if (pid == 0) { /* specify filename, inherit environment */

if (execlp("fig8.17.exe", "echoall",

if (execlp("fig8.17.exe", "echoall",

"only 1 arg", (char *)0) < 0)

"only 1 arg", (char *)0) < 0)

err_sys("execlp error");

err_sys("execlp error");

}

}

exit(0);

exit(0);

linux1:~/sys_prog_06/test> fig8.16.exe

linux1:~/sys_prog_06/test> fig8.16.exe

argv[0]: echoall

argv[0]: echoall

argv[1]: myarg1

argv[1]: myarg1

argv[2]: MY ARG2

argv[2]: MY ARG2

USER=unknown

USER=unknown

PATH=/tmp

PATH=/tmp

linux1:~/sys_prog_06/test> argv[0]: echoall

linux1:~/sys_prog_06/test> argv[0]: echoall

argv[1]: only 1 arg

argv[1]: only 1 arg

USER=hchu

USER=hchu

LOGNAME=hchu

LOGNAME=hchu

HOME=/home/professor/hchu

HOME=/home/professor/hchu

PATH=/usr/bin:/bin:/usr/X11R6/bin:/opt/kde/bin:.

PATH=/usr/bin:/bin:/usr/X11R6/bin:/opt/kde/bin:.

MAIL=/var/mail/hchu

MAIL=/var/mail/hchu

SHELL=/bin/tcsh

SHELL=/bin/tcsh

SSH_CLIENT=140.112.30.82 46314 22

SSH_CLIENT=140.112.30.82 46314 22

SSH_CONNECTION=140.112.30.82 46314 140.112

SSH_CONNECTION=140.112.30.82 46314 140.112

.30.32 22

.30.32 22

SSH_TTY=/dev/pts/5

SSH_TTY=/dev/pts/5

TERM=xterm

TERM=xterm

DISPLAY=localhost:10.0

DISPLAY=localhost:10.0

LANG=zh_TW.Big5

LANG=zh_TW.Big5

HOSTTYPE=i486-linux

HOSTTYPE=i486-linux

VENDOR=intel

VENDOR=intel

OSTYPE=linux

OSTYPE=linux

MACHTYPE=i486

MACHTYPE=i486

SHLVL=1

SHLVL=1

PWD=/home/professor/hchu/sys_prog_06/test

PWD=/home/professor/hchu/sys_prog_06/test

GROUP=users

GROUP=users

HOST=linux1

HOST=linux1

(52)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

program 8.17

program 8.17

#include "apue.h"

#include "apue.h"

int

int

main(int argc, char *argv[])

main(int argc, char *argv[])

{

{

int i;

int i;

char **ptr;

char **ptr;

extern char **environ;

extern char **environ;

for (i = 0; i < argc; i++) /* echo all command-line args */

for (i = 0; i < argc; i++) /* echo all command-line args */

printf("argv[%d]: %s\n", i, argv[i]);

printf("argv[%d]: %s\n", i, argv[i]);

for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */

for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */

printf("%s\n", *ptr);

printf("%s\n", *ptr);

exit(0);

exit(0);

}

}

(53)

Changing User/Group ID’s

Changing User/Group ID’s

This part is confusing … (when I read it)

This part is confusing … (when I read it)

Why changes user id in the middle of a

Why changes user id in the middle of a

program execution?

program execution?

Least-privilege model: a program should use the least

Least-privilege model: a program should use the least

privilege necessary to accomplish any task.

privilege necessary to accomplish any task.

Reduce window of security vulnerability

Reduce window of security vulnerability

Example: a process needs to gain a privilege to

Example: a process needs to gain a privilege to

access a privileged file

(54)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

Recall …

Recall …

A

A

process

process

can have more than one ID.

can have more than one ID.

Real user/group ID: who you really are

Real user/group ID: who you really are

Effective user/group ID: determine file access

Effective user/group ID: determine file access

permission

permission

Supplementary group IDs

Supplementary group IDs

Saved set-user/group-ID = owner of the

Saved set-user/group-ID = owner of the

program with set-user-id bit set

program with set-user-id bit set

Why do you need saved set-user-id?

Why do you need saved set-user-id?

cannot give up privilege temporarily (and get it back)

(55)

Recall …

Recall …

#include <sys/types.h>

#include <sys/types.h>

#include <unistd.h>

#include <unistd.h>

int setuid(uid_t uid);

int setuid(uid_t uid);

The process == superuser

The process == superuser

set real/effective/saved-suid =

set real/effective/saved-suid =

uid

uid

Otherwise, euid=

Otherwise, euid=

uid

uid

if

if

uid

uid

== ruid or

== ruid or

uid

uid

== saved-suid (suid = se

== saved-suid (suid = se

t-uid)

t-uid)

Return 0 upon success

Return 0 upon success

Return -1 otherwise, errno=EPERM (_POSIX_SAVED_IDS)

Return -1 otherwise, errno=EPERM (_POSIX_SAVED_IDS)

int setgid(gid_t gid);

int setgid(gid_t gid);

The same as setuid

(56)

Tei-Wei Kuo, Chi-Sheng Shih and Hao-Hua Chu©2006 Department of Computer Science and Information Engineering

User/Group ID’s

User/Group ID’s

Only superuser process can change the real

Only superuser process can change the real

uid – normally done by the login program.

uid – normally done by the login program.

The euid is set by exec only if the setuid bit is

The euid is set by exec only if the setuid bit is

set for the program file. euid can only be set

set for the program file. euid can only be set

as its saved-suid or ruid.

as its saved-suid or ruid.

exec copies the euid to the saved-suid (after t

exec copies the euid to the saved-suid (after t

he setting of euid if setuid bit is on).

數據

table -&gt; rerun the instruction!

參考文獻

相關文件

Department of Computer Science and Information

Department of Computer Science and Information

Department of Computer Science and Information

Professor of Computer Science and Information Engineering National Chung Cheng University. Chair

2 Department of Materials Science and Engineering, National Chung Hsing University, Taichung, Taiwan.. 3 Department of Materials Science and Engineering, National Tsing Hua

Department of Computer Science and Information Engineering, Chaoyang University of

The probability of loss increases rapidly with burst size so senders talking to old-style receivers saw three times the loss rate (1.8% vs. The higher loss rate meant more time spent

* All rights reserved, Tei-Wei Kuo, National Taiwan University,