Sysprog 12

22
C/C++ Linux System Programming Session 12 User-space System Programming – session 2

Transcript of Sysprog 12

Page 1: Sysprog 12

C/C++ Linux System Programming

Session 12User-space System Programming

– session 2

Page 2: Sysprog 12

Outline

● Signals● Job Control● Scheduling● IPC Intro

Page 3: Sysprog 12

Sending Signals

● int kill(pid_t pid, int sig);● int raise(int sig); // = kill(getpid(), sig);● int sigqueue(pid_t pid, int sig, const union sigval

value); // value is a payload (IPC w/data!!)

Page 4: Sysprog 12

Handling Signals – old school

● Handler

– typedef void (*sighandler_t)(int);

– sighandler_t signal(int signum, sighandler_t handler);

– SIG_IGN / SIG_DFL

– Example from sshd.c:

static voidmain_sigchld_handler(int sig){

int save_errno = errno;pid_t pid;int status;

while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR))

;

signal(SIGCHLD, main_sigchld_handler);errno = save_errno;

}

Page 5: Sysprog 12

Signal sets

– int sigemptyset(sigset_t *set); // Init

– int sigfillset(sigset_t *set); // Init with all

– int sigaddset(sigset_t *set, int signum);

– int sigdelset(sigset_t *set, int signum);

– int sigismember(const sigset_t *set, int signum);

– Non-POSIX:● int sigisemptyset (sigset_t *set);● int sigorset (sigset_t *dest, sigset_t *left, sigset_t *right);● int sigandset (sigset_t *dest, sigset_t *left, sigset_t *right);

Page 6: Sysprog 12

Masking

● Mask/Unmask– int sigprocmask(int how, const sigset_t *set, sigset_t

*oldset);

– how: SIG_BLOCK/SIG_UNBLOCK/SIG_SETMASK

● Check pending (temporarily masked)– int sigpending(sigset_t *set);

● Waiting for a signal– int pause(void);

– int sigsuspend(const sigset_t *mask);

Page 7: Sysprog 12

Masking Example -ssh/server_loop.c

/* block SIGCHLD while we check for dead children */ sigemptyset(&nset); sigaddset(&nset, SIGCHLD); sigprocmask(SIG_BLOCK, &nset, &oset); if (child_terminated) { debug("Received SIGCHLD."); while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) if (pid > 0) session_close_by_pid(pid, status); child_terminated = 0; } sigprocmask(SIG_SETMASK, &oset, NULL);}

Page 8: Sysprog 12

Versatile Signal Handling Interface

● int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

● Important sigaction fields:– void (*sa_handler)(int);

– void (*sa_sigaction)(int, siginfo_t *, void *);

– sigset_t sa_mask;

● Important siginfo_t:– si_signo , si_uid, si_value, si_addr

Page 9: Sysprog 12

Example - inetd memset(&sa, 0, sizeof(sa)); sigaddset(&sa.sa_mask, SIGALRM); sigaddset(&sa.sa_mask, SIGCHLD); sigaddset(&sa.sa_mask, SIGHUP); sa.sa_handler = retry_network_setup; sigaction_set(SIGALRM, &sa); sa.sa_handler = reread_config_file; sigaction_set(SIGHUP, &sa); sa.sa_handler = reap_child; sigaction_set(SIGCHLD, &sa); sa.sa_handler = clean_up_and_exit; sigaction_set(SIGTERM, &sa); sa.sa_handler = clean_up_and_exit; sigaction_set(SIGINT, &sa); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, &saved_pipe_handler);

static void clean_up_and_exit(int sig UNUSED_PARAM){,,,,

remove_pidfile(_PATH_INETDPID); exit(EXIT_SUCCESS);}

int FAST_FUNC sigaction_set(int signum, const struct sigaction *act){ return sigaction(signum, act, NULL);}

Page 10: Sysprog 12

Some Signal Notes

● Behavior in fork● Behavior in exec● Process Group relevance● System call interruptions● Intro to race conditions

– Critical region

– Reentrancy

– Minimal work

– Sigatomic_t

Page 11: Sysprog 12

system/popen

● fork/exec (/bin/sh)● Security hole● Signal blocking

Page 12: Sysprog 12

Scheduling

● Time-sharing (timeslices)● States● Process table● Context switch● Priorities● Preemptive vs Cooperative Multitasking● Idle process

Page 13: Sysprog 12

2.4 Scheduling● Nice values

– [-20,19], -20 is not nice, i.e. high priority

– Time slice length & run queue order

– Superuser to decrement

● int nice(int inc); // nice(0) is current● get/set priority

– int getpriority (int which, int who);

– int setpriority (int which, int who, int prio);

– Absolute

– PRIO_RPOCESS, PRIO_PGRP, PRIO_USER

Page 14: Sysprog 12

Relinquishing CPU

– int sched_yield ● why?● 2.4 vs 2.6 (RT vs non-RT)

– Sleep● unsigned int sleep(unsigned int seconds);● int nanosleep(const struct timespec *rqtp, struct timespec

*rmtp);● int usleep(useconds_t usec);

Page 15: Sysprog 12

Real-time Scheduling● Real-time - soft/hard

– determinism

● Priorities: 1-99, 0 non-RT

● Scheduling classes– Round-robin

– FIFO

● Chrt● Be “nice” !!!

struct sched_param { /* ... */ int sched_priority; /* ... */};

int sched_getparam (pid_t pid, struct sched_param *sp);

int sched_setparam (pid_t pid, const struct sched_param *sp);

Page 16: Sysprog 12

Processor Affinity

● SMP● Affinity: Which

processor?– By default, try the

same and hereditary

● Do I care? -- Cache coherency

● Do I really care?– http://www.linuxjournal.

com/article/6799

pid = atol(argv[1]); sscanf(argv[2], "%08lx", &new_mask); if (sched_getaffinity(pid, len, &cur_mask) < 0) { perror("sched_getaffinity"); return -1; } printf("pid %d's old affinity: %08lx\n", pid, cur_mask); if (sched_setaffinity(pid, len, &new_mask)) { perror("sched_setaffinity"); return -1; } if (sched_getaffinity(pid, len, &cur_mask) < 0) { perror("sched_getaffinity"); return -1; }

Page 17: Sysprog 12

Time

● Monotonic time / real time / process time● POSIX

– int clock_getres(clockid_t clk_id, struct timespec *res);

– int clock_gettime(clockid_t clk_id, struct timespec *tp);

– int clock_settime(clockid_t clk_id, const struct timespec *tp);

Page 18: Sysprog 12

System time● get/set

– int gettimeofday(struct timeval *tv, struct timezone *tz);

– int settimeofday(const struct timeval *tv, const struct timezone *tz);

– time_t time(time_t *t); // seconds

● Printable – char *ctime(const time_t *timep); //And family

● int adjtime(const struct timeval *delta, struct timeval *olddelta);

Page 19: Sysprog 12

Examples from NTP

gettimeofday(&tv, 0);epoch = tv.tv_sec;

...fprintf(stdout, "# %s\n# %s", filename, ctime(&epoch));

curtime = time(0);printf("Starting: %s", ctime(&curtime));

Page 20: Sysprog 12

Interval Timers● Set a timer● Signal when expired

int getitimer(int which, struct itimerval *value);int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);struct itimerval { struct timeval it_interval; /* next value */ struct timeval it_value; /* current value */};struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */};unsigned int alarm(unsigned int seconds);

Page 21: Sysprog 12

Example – ping.c

static void noresp(int ign UNUSED_PARAM){

printf("No response from %s\n", hostname);

exit(EXIT_FAILURE);}

main(){

...signal(SIGALRM, noresp);alarm(5); /* give the host 5000ms to respond */

...}

Page 22: Sysprog 12

IPC Intro

● Share data● Synchronize● Mutual Exclusion

– Critical region

– Semaphores