2010$BG/(B12$B7n(B14$BF|(B
$B>pJs2J3XN`(B $B%*%Z%l!<%F%#%s%0%7%9%F%`(B II
$BC^GHBg3X(B $B%7%9%F%`>pJs9)3X8&5f2J(B
$B%3%s%T%e!<%?%5%$%(%s%9@l96(B, $BEE;R!&>pJs9)3X7O(B
$B?7>k(B $BLw(B
<yas@is.tsukuba.ac.jp>
$B$3$N%Z!<%8$O!"
http://www.coins.tsukuba.ac.jp/~yas/coins/os2-2010/2010-12-14
$B$"$k$$$O!"
http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/
$B%7%9%F%`!&%3!<%k$N=hM}$G$O!"FC8"L?Na$rI,MW$H$9$k!#%i%$%V%i%j4X?t$G$O!"(B $BIaDL$OFC8"L?Na$r;H$($J$$(B($BI,MW$J;~$K$O%7%9%F%`!&%3!<%k$rMxMQ$9$k(B)$B!#(B
| $B>uBV(B | $B@bL@(B |
|---|---|
| Ready | CPU$B$,$"$l$P |
| Running | CPU$B$, |
| Blocked (waiting) | I/O$B40N;BT$A!"%M%C%H%o!<%/$d%f!<%6$+$i$NF~NOBT$A!#(B |
$B?^(B? $B%W%m%;%9$N#3>uBV(B
$B%9%l%C%I$H$O!"#1$D$N%W%m%;%9!J$N%"%I%l%96u4V!K$NFbIt$K$U$/$^$l$F$$$kO@(B $BM}E*$JJBNs=hM}$NC10L!#(B
$ ps l
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
0 1013 20591 20590 15 0 9224 2696 rt_sig Ss pts/1 0:00 -tcsh
0 1013 20761 20591 16 0 3724 904 finish T pts/1 0:00 nm /usr/lib/l
0 1013 20762 20591 16 0 2720 624 finish T pts/1 0:00 lv
0 1013 20795 20591 16 0 4256 628 - R+ pts/1 0:00 ps l
$
/proc $B$N2<$K!"%+!<%M%kFb$N%G!<%?$rPID $B$N%W%m%;%9$N>pJs$,8=$l$k!#>\$7$/$O!"(Bman proc$B$r8+(B
$B$J$5$$!#(B
$ echo $$
23069
$ ls /proc/$$
attr cpuset fd maps numa_maps schedstat status
auxv cwd io mem oom_adj smaps task
cmdline environ limits mounts oom_score stat wchan
coredump_filter exe loginuid mountstats root statm
$ head -11 /proc/$$/status
Name: bash
State: S (sleeping)
SleepAVG: 98%
Tgid: 23069
Pid: 23069
PPid: 23068
TracerPid: 0
Uid: 1013 1013 1013 1013
Gid: 510 510 510 510
FDSize: 256
Groups: 20 510 1020 1065 1150
$
1: /*
2: fork-pid.c -- fork() $B$7$F2hLL$K(B pid $B$rI=<($9$k%W%m%0%i%`(B
3: ~yas/syspro/proc/fork-pid.c
4: Created on: 2010/12/13 21:19:17
5: */
6:
7: #include <sys/types.h> /* getpid(), getppid() */
8: #include <unistd.h> /* getpid(), getppid() */
9: #include <stdio.h>
10:
11: main()
12: {
13: pid_t pid;
14: fork();
15: pid = getpid();
16: printf("pid=%d\n", pid );
17: }
$ make fork-pid
cc fork-pid.c -o fork-pid
$ ./fork-pid
pid=11041
pid=11040
$ ./fork-pid
pid=11042
pid=11043
$
1: /*
2: proc-pid-ppid.c -- $B2hLL$K(B pid $B$H(B ppid $B$rI=<($9$k%W%m%0%i%`(B
3: ~yas/syspro/proc/proc-pid-ppid.c
4: Created on: 2010/12/13 21:00:48
5: */
6:
7: #include <sys/types.h> /* getpid(), getppid() */
8: #include <unistd.h> /* getpid(), getppid() */
9: #include <stdio.h>
10:
11: main()
12: {
13: pid_t pid, ppid;
14: pid = getpid();
15: ppid = getppid();
16: printf("pid=%d, ppid=%d\n", pid, ppid );
17: }
$ make proc-pid-ppid
cc proc-pid-ppid.c -o proc-pid-ppid
$ echo $$
10771
$ ./proc-pid-ppid
pid=10873, ppid=10771
$ ./proc-pid-ppid
pid=10874, ppid=10771
$ ./proc-pid-ppid
pid=10875, ppid=10771
$
1: /*
2: fork-hello.c -- $B2hLL$KJ8;zNs$rI=<($9$k%W%m%0%i%`(B
3: ~yas/syspro/proc/fork-hello.c
4: Start: 2001/05/13 23:19:01
5: */
6:
7: #include <stdio.h>
8:
9: main()
10: {
11: fork();
12: fork();
13: fork();
14: printf("hello\n");
15: }
$ make fork-hello
cc fork-hello.c -o fork-hello
$ ./fork-hello
hello
hello
hello
hello
hello
hello
hello
hello
$
$B?^(B? fork()$B%7%9%F%`!&%3!<%k$K$h$k%W%m%;%9$N%3%T!<(B
Unix$B$G$O!"A4$F$N%U%!%$%k$d%W%m%;%9$O!"$"$k%f!<%6$N=jM-J*$G$"$k!#(B $B%U%!%$%k$H%W%m%;%9$K$O!"(BUID $B$,IU2C$5$l$F$$$k!#(B
$B#1?M$N%f!<%6$,J#?t$N%0%k!<%W$KB0$9$k$3$H$,$G$-$k!#(B
$ id
uid=1013(yas) gid=510(prof) groups=20(games),510(prof),1020(c-admin),1065(c-spec),1150(tebiki)
$
1:
2: /*
3: id-simple.c -- a simple id command
4: Created on: 2009/12/07 22:16:23
5: */
6:
7: #include <unistd.h> /* getuid(), getgid(), getgroups() */
8: #include <sys/types.h> /* getuid(), getgid(), getgroups() */
9: #include <stdio.h> /* printf() */
10:
11: #define MAXNGROUPS 100
12:
13: main( int argc, char *argv[], char *envp[] )
14: {
15: uid_t uid ;
16: gid_t gid ;
17: gid_t groups[MAXNGROUPS];
18: int len, i;
19: uid = getuid();
20: gid = getgid();
21: len = getgroups(MAXNGROUPS,&groups[0]);
22: printf("uid=%d gid=%d groups=", uid, gid );
23: for( i=0; i<len; i++ )
24: printf("%d,", groups[i]);
25: printf("\n");
26: }
$ cc id-simple.c -o id-simple
$ ./id-simple
uid=1013 gid=510 groups=20,510,1020,1065,1150,
$
http://www.coins.tsukuba.ac.jp/~yas/coins/literacy-2010/2010-05-11/
Linux $B$NFC
$B"!(Btask_struct$B9=B$BN(B
linux-2.6.36/include/linux/sched.h
1163: struct task_struct {
1164: volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
...
1224: int exit_state;
...
1251: struct task_struct *real_parent; /* real parent process */
1252: struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */
1253: /*
1254: * children/sibling forms the list of my natural children
1255: */
1256: struct list_head children; /* list of my children */
1257: struct list_head sibling; /* linkage in my parent's children list */
1258: struct task_struct *group_leader; /* threadgroup leader */
...
1268: /* PID/PID hash table linkage. */
1269: struct pid_link pids[PIDTYPE_MAX];
1270: struct list_head thread_group;
...
1290: /* process credentials */
1291: const struct cred *real_cred; /* objective and real subjective task
1292: * credentials (COW) */
1293: const struct cred *cred; /* effective (overridable) subjective task
1294: * credentials (COW) */
...
1300: char comm[TASK_COMM_LEN]; /* executable name excluding path
1301: - access with [gs]et_task_comm (which lock
1302: it with task_lock())
1303: - initialized normally by setup_new_exec */
...
1497: };
STAT $B$NItJ,$K8=$l$k!#(B
$B0lHLE*$K!"%W%m%;%9$O!"(B
$B#3$D$N>uBV$r;}$D(B$B!#(B
Linux $B$N%W%m%;%9$N>uBV$O$b$&>/$7B?$$!#include/linux/sched.h 182: #define TASK_RUNNING 0 183: #define TASK_INTERRUPTIBLE 1 184: #define TASK_UNINTERRUPTIBLE 2 185: #define __TASK_STOPPED 4 186: #define __TASK_TRACED 8 187: /* in tsk->exit_state */ 188: #define EXIT_ZOMBIE 16 189: #define EXIT_DEAD 32 190: /* in tsk->state again */ 191: #define TASK_DEAD 64 192: #define TASK_WAKEKILL 128 193: #define TASK_WAKING 256 194: #define TASK_STATE_MAX 512
| $B0lHLE*$J>uBV(B | Linux$B$N>uBV(B | ps$BI=<((B | $B@bL@(B |
| Ready | TASK_RUNNING | R | $B |
| Running | TASK_RUNNING | ||
| Blocked | TASK_INTERRUPTIBLE | S | $B%-!<%\!<%I$dB>$N%W%m%;%9$+$i$NF~NO$rBT$C$F$$$k!#(B |
| TASK_UNINTERRUPTIBLE | D | $B%G%#%9%/F~=PNO$J$I$N40N;$rBT$C$F$$$k!#3d$j9~$_IT2D!#(B | |
| __TASK_STOPPED, __TASK_TRACED | T | $B0l;~E*$KDd;_$7$F$$$k$+!"%G%P%C%0$NBP>]$K$J$C$F$$$k!#(B | |
| TASK_DEAD | Z | $B4{$K=*N;$7$F$$$F!"=*N;=hM}$N40N;$rBT$C$F$k!#(B |
pids[] $B$O!"%W%m%;%9<1JL;R$rJ];}$9$k$?$a$NG[Ns!#$$$/$D$+$Npids[PIDTYPE_PID]$B!#(B
pids[PIDTYPE_PID] $B$O!"(Bpid_link $B7?$G!"FbIt$K(Bstruct pid $B$r;}$D!#(Bstruct pid $B$NCf$K$O!"(Bstruct upid $B$,$"$j!"$=$NCf$K$O(B getpid() $BEy$GMQ$$$k(B pid $B$r(B $BJ];}$9$k%U%#!<%k%I(B nr $B$,$"$k!#(B
include/linux/pid.h
50: struct upid {
...
52: int nr;
...
55: };
57: struct pid
58: {
...
64: struct upid numbers[1];
65: };
...
69: struct pid_link
70: {
...
72: struct pid *pid;
73: };
$B?^(B? $B%W%m%;%9$NLZ9=B$(B
$B?^(B? UID$B$NJ]B8J}K!(B
include/linux/cred.h
25: /*
26: * COW Supplementary groups list
27: */
28: #define NGROUPS_SMALL 32
29: #define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(gid_t)))
30:
31: struct group_info {
32: atomic_t usage;
33: int ngroups;
34: int nblocks;
35: gid_t small_block[NGROUPS_SMALL];
36: gid_t *blocks[0];
37: };
...
116: struct cred {
117: atomic_t usage;
118: #ifdef CONFIG_DEBUG_CREDENTIALS
119: atomic_t subscribers; /* number of processes subscribed */
120: void *put_addr;
121: unsigned magic;
122: #define CRED_MAGIC 0x43736564
123: #define CRED_MAGIC_DEAD 0x44656144
124: #endif
125: uid_t uid; /* real UID of the task */
126: gid_t gid; /* real GID of the task */
127: uid_t suid; /* saved UID of the task */
128: gid_t sgid; /* saved GID of the task */
129: uid_t euid; /* effective UID of the task */
130: gid_t egid; /* effective GID of the task */
...
148: struct user_struct *user; /* real user ID subscription */
149: struct group_info *group_info; /* supplementary groups for euid/fsgid */
...
151: };
Unix $B$K$O!"(Bset-uid $B$N%W%m%0%i%`$,$"$k!#(Bls -l $B$G(B user $B$N(B x $B$N=j$,(B s $B$K$J$C(B $B$F$$$k!#(B
$ ls -l /usr/bin | egrep '^...s'
...
-rwsr-xr-x 1 root root 49392 Jan 27 2010 at
...
-rwsr-sr-x 1 root root 315432 Jan 6 2010 crontab
-rwsr-xr-x 1 root root 51576 Mar 31 2010 gpasswd
...
---s--x--x 2 root root 180448 Oct 19 22:11 sudo
...
$
$B$3$N$h$&$J%W%m%0%i%`$r
kernel/timer.c
1351: SYSCALL_DEFINE0(getpid)
1352: {
1353: return task_tgid_vnr(current);
1354: }
include/linux/sched.h
1600: static inline pid_t task_tgid_vnr(struct task_struct *tsk)
1601: {
1602: return pid_vnr(task_tgid(tsk));
1603: }
1538: static inline struct pid *task_tgid(struct task_struct *task)
1539: {
1540: return task->group_leader->pids[PIDTYPE_PID].pid;
1541: }
kernel/pid.c
474: pid_t pid_vnr(struct pid *pid)
475: {
476: return pid_nr_ns(pid, $B>JN,(B);
477: }
...
461: pid_t pid_nr_ns(struct pid *pid, $B>JN,(B)
462: {
463: struct upid *upid;
464: pid_t nr = 0;
...
467: upid = &pid->numbers[$B>JN,(B];
...
469: nr = upid->nr;
471: return nr;
472: }
kernel/timer.c
1362: SYSCALL_DEFINE0(getppid)
1363: {
1364: int pid;
...
1367: pid = task_tgid_vnr(current->real_parent);
...
1370: return pid;
1371: }
current$B$N(Breal_parent$B$r0z?t$K$7$F(B task_tgid_vnr() $B$H$$$&4X?t$r8F$V!#(B
$B0J9_!"(Bgetpid() $B$HF1$8!#(B
kernel/timer.c
1373: SYSCALL_DEFINE0(getuid)
1374: {
1375: /* Only we change this so SMP safe */
1376: return current_uid();
1377: }
current_uid() $B$H$$$&4X?t(B($B%^%/%m(B)$B$r8F$S=P$9!#(B
include/linux/cred.h
342: #define current_cred_xxx(xxx) \
343: ({ \
344: current->cred->xxx; \
345: })
346:
347: #define current_uid() (current_cred_xxx(uid))
current$B$+$i(Bcred$B$r0z$-!"$=$NCf$N(B uid $B$H$$$&%U%#!<%k%I$rJV$9!#(B
$ echo $$
1001
$ ./fork-printf
hello: (pid=$B6uMs#A(B,ppid=$B6uMs#B(B)
hello: (pid=$B6uMs#C(B,ppid=$B6uMs#D(B)
$
$B$?$@$7!"(BPID $B$H$7$F$O!"(B1001,1002,1003,1004 $B$NCf$+$iA*$S$J$5$$!#(B
$B$J$*!"Ez$($O#1DL$j$G$O$J$$!#(B
$B%R%s%H(B: current $B$+$i=PH/$9$k!#(Bcurrent_cred_xxx() $B%^%/%m$r;H$C$F$b;H$o$J(B $B$/$F$b$h$$!#(B