Merge lp:~xnox/upstart/cgroup-states into lp:~jamesodhunt/upstart/cgroups
- cgroup-states
- Merge into cgroups
Status: | Work in progress |
---|---|
Proposed branch: | lp:~xnox/upstart/cgroup-states |
Merge into: | lp:~jamesodhunt/upstart/cgroups |
Diff against target: |
1234 lines (+343/-197) 10 files modified
init/job.c (+1/-11) init/job_process.c (+17/-82) init/tests/test_event.c (+6/-6) init/tests/test_job.c (+72/-34) scripts/Makefile.am (+9/-9) scripts/pyupstart.py (+102/-4) scripts/tests/test_pyupstart_cgmanager.py (+63/-0) scripts/tests/test_pyupstart_session_init.py (+0/-26) scripts/tests/test_pyupstart_system_cgroups.py (+73/-0) scripts/tests/test_pyupstart_system_init.py (+0/-25) |
To merge this branch: | bzr merge lp:~xnox/upstart/cgroup-states |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Hunt | Pending | ||
Review via email: mp+214514@code.launchpad.net |
Commit message
Description of the change
- 1605. By Dimitri John Ledkov
-
Actually, it looks like the tests might be broken.
- 1606. By Dimitri John Ledkov
-
Extend asserts to setup stages
Dimitri John Ledkov (xnox) wrote : | # |
so running under cgmanager in a container i notice that jobs do not progress from *_SETUP -> * states.
Also process tracking with e.g. expect stop did not work it seems (well, i've kill -s CONT a few processes to get the container booting)
I am now leaning to believe that stats in job_process.c (e.g. PROCESS_PRE_STOP) should assert state JOB_PRE_STOP. And that it's buggy behavior for jobs to get stuck in _SETUP state and not transition to the full one. (when cgroups stanza is specified that is)
Dimitri John Ledkov (xnox) wrote : | # |
I've tested all but "security" and "pre-stop" processes and they all get cgroups containment now.
- 1607. By Dimitri John Ledkov
-
We need to both SIGCONT & switch to next state for 'expect stop' and setup states.
Dimitri John Ledkov (xnox) wrote : | # |
With -r1607 i get correct transitions from *_SETUP -> * states.
However, expect stop jobs are still stuck in "setup" and do not transition to running. Investigating.
- 1608. By Dimitri John Ledkov
-
SIGCONT in setup as well.
Dimitri John Ledkov (xnox) wrote : | # |
Now the states progress to quickly, e.g. we jump to spawning the main process and running, ahead of pre-start process completing, if and only if cgroups stanza is specified in the job.
- 1609. By Dimitri John Ledkov
-
Merge pythonic CGManager
- 1610. By Dimitri John Ledkov
-
Add pyupstart CGManager tests
- 1611. By Dimitri John Ledkov
-
And kaboom!
Unmerged revisions
- 1611. By Dimitri John Ledkov
-
And kaboom!
- 1610. By Dimitri John Ledkov
-
Add pyupstart CGManager tests
- 1609. By Dimitri John Ledkov
-
Merge pythonic CGManager
- 1608. By Dimitri John Ledkov
-
SIGCONT in setup as well.
- 1607. By Dimitri John Ledkov
-
We need to both SIGCONT & switch to next state for 'expect stop' and setup states.
- 1606. By Dimitri John Ledkov
-
Extend asserts to setup stages
- 1605. By Dimitri John Ledkov
-
Actually, it looks like the tests might be broken.
- 1604. By Dimitri John Ledkov
-
Fix up cgroup-states.
- 1603. By Dimitri John Ledkov
-
Remove debug
Preview Diff
1 | === modified file 'init/job.c' | |||
2 | --- init/job.c 2014-04-04 18:42:18 +0000 | |||
3 | +++ init/job.c 2014-04-08 20:51:56 +0000 | |||
4 | @@ -278,8 +278,6 @@ | |||
5 | 278 | { | 278 | { |
6 | 279 | nih_assert (job != NULL); | 279 | nih_assert (job != NULL); |
7 | 280 | 280 | ||
8 | 281 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
9 | 282 | |||
10 | 283 | if (job->goal == goal) | 281 | if (job->goal == goal) |
11 | 284 | return; | 282 | return; |
12 | 285 | 283 | ||
13 | @@ -348,9 +346,6 @@ | |||
14 | 348 | { | 346 | { |
15 | 349 | nih_assert (job != NULL); | 347 | nih_assert (job != NULL); |
16 | 350 | 348 | ||
17 | 351 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, new state=%s", __func__, __LINE__, | ||
18 | 352 | job_name (job), job_goal_name (job->goal), job_state_name (job->state), job_state_name (state)); | ||
19 | 353 | |||
20 | 354 | while (job->state != state) { | 349 | while (job->state != state) { |
21 | 355 | JobState old_state; | 350 | JobState old_state; |
22 | 356 | int unused; | 351 | int unused; |
23 | @@ -363,9 +358,6 @@ | |||
24 | 363 | old_state = job->state; | 358 | old_state = job->state; |
25 | 364 | job->state = state; | 359 | job->state = state; |
26 | 365 | 360 | ||
27 | 366 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, old state=%s", __func__, __LINE__, | ||
28 | 367 | job_name (job), job_goal_name (job->goal), job_state_name (job->state), job_state_name (old_state)); | ||
29 | 368 | |||
30 | 369 | NIH_LIST_FOREACH (control_conns, iter) { | 361 | NIH_LIST_FOREACH (control_conns, iter) { |
31 | 370 | NihListEntry *entry = (NihListEntry *)iter; | 362 | NihListEntry *entry = (NihListEntry *)iter; |
32 | 371 | DBusConnection *conn = (DBusConnection *)entry->data; | 363 | DBusConnection *conn = (DBusConnection *)entry->data; |
33 | @@ -673,8 +665,6 @@ | |||
34 | 673 | { | 665 | { |
35 | 674 | nih_assert (job != NULL); | 666 | nih_assert (job != NULL); |
36 | 675 | 667 | ||
37 | 676 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
38 | 677 | |||
39 | 678 | switch (job->state) { | 668 | switch (job->state) { |
40 | 679 | case JOB_WAITING: | 669 | case JOB_WAITING: |
41 | 680 | switch (job->goal) { | 670 | switch (job->goal) { |
42 | @@ -789,7 +779,7 @@ | |||
43 | 789 | case JOB_PRE_STOP_SETUP: | 779 | case JOB_PRE_STOP_SETUP: |
44 | 790 | switch (job->goal) { | 780 | switch (job->goal) { |
45 | 791 | case JOB_STOP: | 781 | case JOB_STOP: |
47 | 792 | return JOB_STOPPING; | 782 | return JOB_PRE_STOP; |
48 | 793 | case JOB_START: | 783 | case JOB_START: |
49 | 794 | return JOB_PRE_STOP; | 784 | return JOB_PRE_STOP; |
50 | 795 | case JOB_RESPAWN: | 785 | case JOB_RESPAWN: |
51 | 796 | 786 | ||
52 | === modified file 'init/job_process.c' | |||
53 | --- init/job_process.c 2014-04-04 18:42:18 +0000 | |||
54 | +++ init/job_process.c 2014-04-08 20:51:56 +0000 | |||
55 | @@ -199,8 +199,6 @@ | |||
56 | 199 | 199 | ||
57 | 200 | nih_assert (job != NULL); | 200 | nih_assert (job != NULL); |
58 | 201 | 201 | ||
59 | 202 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
60 | 203 | |||
61 | 204 | proc = job->class->process[process]; | 202 | proc = job->class->process[process]; |
62 | 205 | nih_assert (proc != NULL); | 203 | nih_assert (proc != NULL); |
63 | 206 | nih_assert (proc->command != NULL); | 204 | nih_assert (proc->command != NULL); |
64 | @@ -449,8 +447,6 @@ | |||
65 | 449 | int cgroups_needed = FALSE; | 447 | int cgroups_needed = FALSE; |
66 | 450 | #endif /* ENABLE_CGROUPS */ | 448 | #endif /* ENABLE_CGROUPS */ |
67 | 451 | 449 | ||
68 | 452 | //nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
69 | 453 | |||
70 | 454 | nih_assert (job != NULL); | 450 | nih_assert (job != NULL); |
71 | 455 | nih_assert (job->class != NULL); | 451 | nih_assert (job->class != NULL); |
72 | 456 | nih_assert (job->log != NULL); | 452 | nih_assert (job->log != NULL); |
73 | @@ -950,11 +946,8 @@ | |||
74 | 950 | /* Signal to parent that the (final) setup phase | 946 | /* Signal to parent that the (final) setup phase |
75 | 951 | * is complete. | 947 | * is complete. |
76 | 952 | */ | 948 | */ |
77 | 953 | nih_message ("XXX:%s:%d: raising SIGSTOP to %s process %s pid %d (state=%s)", __func__, __LINE__, | ||
78 | 954 | job_name (job), process_name (process), getpid(), job_state_name (job->state));fflush (NULL); | ||
79 | 955 | raise (SIGSTOP); | 949 | raise (SIGSTOP); |
80 | 956 | } | 950 | } |
81 | 957 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
82 | 958 | 951 | ||
83 | 959 | #endif /* ENABLE_CGROUPS */ | 952 | #endif /* ENABLE_CGROUPS */ |
84 | 960 | 953 | ||
85 | @@ -964,14 +957,11 @@ | |||
86 | 964 | job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETGID, 0); | 957 | job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETGID, 0); |
87 | 965 | } | 958 | } |
88 | 966 | 959 | ||
89 | 967 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
90 | 968 | if (job_setuid != (uid_t)-1 && setuid (job_setuid) < 0) { | 960 | if (job_setuid != (uid_t)-1 && setuid (job_setuid) < 0) { |
91 | 969 | nih_error_raise_system (); | 961 | nih_error_raise_system (); |
92 | 970 | job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETUID, 0); | 962 | job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETUID, 0); |
93 | 971 | } | 963 | } |
94 | 972 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
95 | 973 | } | 964 | } |
96 | 974 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
97 | 975 | 965 | ||
98 | 976 | /* Reset all the signal handlers back to their default handling so | 966 | /* Reset all the signal handlers back to their default handling so |
99 | 977 | * the child isn't unexpectedly ignoring any, and so we won't | 967 | * the child isn't unexpectedly ignoring any, and so we won't |
100 | @@ -980,7 +970,6 @@ | |||
101 | 980 | nih_signal_reset (); | 970 | nih_signal_reset (); |
102 | 981 | sigprocmask (SIG_SETMASK, &orig_set, NULL); | 971 | sigprocmask (SIG_SETMASK, &orig_set, NULL); |
103 | 982 | 972 | ||
104 | 983 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
105 | 984 | /* Notes: | 973 | /* Notes: |
106 | 985 | * | 974 | * |
107 | 986 | * - we can't use pause() here since there would then be no way to | 975 | * - we can't use pause() here since there would then be no way to |
108 | @@ -1003,7 +992,6 @@ | |||
109 | 1003 | close (fds[1]); | 992 | close (fds[1]); |
110 | 1004 | raise (SIGSTOP); | 993 | raise (SIGSTOP); |
111 | 1005 | } | 994 | } |
112 | 1006 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
113 | 1007 | 995 | ||
114 | 1008 | #ifdef ENABLE_CGROUPS | 996 | #ifdef ENABLE_CGROUPS |
115 | 1009 | /* Move the pid into the appropriate cgroups now that | 997 | /* Move the pid into the appropriate cgroups now that |
116 | @@ -1022,17 +1010,14 @@ | |||
117 | 1022 | } | 1010 | } |
118 | 1023 | #endif /* ENABLE_CGROUPS */ | 1011 | #endif /* ENABLE_CGROUPS */ |
119 | 1024 | 1012 | ||
120 | 1025 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
121 | 1026 | /* Set up a process trace if we need to trace forks */ | 1013 | /* Set up a process trace if we need to trace forks */ |
122 | 1027 | if (trace) { | 1014 | if (trace) { |
123 | 1028 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
124 | 1029 | if (ptrace (PTRACE_TRACEME, 0, NULL, 0) < 0) { | 1015 | if (ptrace (PTRACE_TRACEME, 0, NULL, 0) < 0) { |
125 | 1030 | nih_error_raise_system(); | 1016 | nih_error_raise_system(); |
126 | 1031 | job_process_error_abort (fds[1], | 1017 | job_process_error_abort (fds[1], |
127 | 1032 | JOB_PROCESS_ERROR_PTRACE, 0); | 1018 | JOB_PROCESS_ERROR_PTRACE, 0); |
128 | 1033 | } | 1019 | } |
129 | 1034 | } | 1020 | } |
130 | 1035 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
131 | 1036 | 1021 | ||
132 | 1037 | /* Execute the process, if we escape from here it failed */ | 1022 | /* Execute the process, if we escape from here it failed */ |
133 | 1038 | if (execvp (argv[0], argv) < 0) { | 1023 | if (execvp (argv[0], argv) < 0) { |
134 | @@ -1526,9 +1511,6 @@ | |||
135 | 1526 | 1511 | ||
136 | 1527 | nih_assert (pid > 0); | 1512 | nih_assert (pid > 0); |
137 | 1528 | 1513 | ||
138 | 1529 | nih_message ("XXX:%s:%d:pid=%d, event=%x, status=%d", __func__, __LINE__, | ||
139 | 1530 | pid, event, status); | ||
140 | 1531 | |||
141 | 1532 | /* Find the job that an event ocurred for, and identify which of the | 1514 | /* Find the job that an event ocurred for, and identify which of the |
142 | 1533 | * job's process it was. If we don't know about it, then we simply | 1515 | * job's process it was. If we don't know about it, then we simply |
143 | 1534 | * ignore the event. | 1516 | * ignore the event. |
144 | @@ -1537,9 +1519,6 @@ | |||
145 | 1537 | if (! job) | 1519 | if (! job) |
146 | 1538 | return; | 1520 | return; |
147 | 1539 | 1521 | ||
148 | 1540 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s", __func__, __LINE__, | ||
149 | 1541 | job_name (job), job_goal_name (job->goal), job_state_name (job->state)); | ||
150 | 1542 | |||
151 | 1543 | /* Check the job's normal exit clauses to see whether this is a failure | 1522 | /* Check the job's normal exit clauses to see whether this is a failure |
152 | 1544 | * worth warning about. | 1523 | * worth warning about. |
153 | 1545 | */ | 1524 | */ |
154 | @@ -1553,7 +1532,6 @@ | |||
155 | 1553 | 1532 | ||
156 | 1554 | switch (event) { | 1533 | switch (event) { |
157 | 1555 | case NIH_CHILD_EXITED: | 1534 | case NIH_CHILD_EXITED: |
158 | 1556 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
159 | 1557 | /* Child exited; check status to see whether it exited | 1535 | /* Child exited; check status to see whether it exited |
160 | 1558 | * normally (zero) or with a non-zero status. | 1536 | * normally (zero) or with a non-zero status. |
161 | 1559 | */ | 1537 | */ |
162 | @@ -1571,7 +1549,6 @@ | |||
163 | 1571 | break; | 1549 | break; |
164 | 1572 | case NIH_CHILD_KILLED: | 1550 | case NIH_CHILD_KILLED: |
165 | 1573 | case NIH_CHILD_DUMPED: | 1551 | case NIH_CHILD_DUMPED: |
166 | 1574 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
167 | 1575 | /* Child was killed by a signal, and maybe dumped core. We | 1552 | /* Child was killed by a signal, and maybe dumped core. We |
168 | 1576 | * store the signal value in the higher byte of status (it's | 1553 | * store the signal value in the higher byte of status (it's |
169 | 1577 | * safe to do that) to distinguish it from a normal exit | 1554 | * safe to do that) to distinguish it from a normal exit |
170 | @@ -1592,7 +1569,6 @@ | |||
171 | 1592 | job_process_terminated (job, process, status); | 1569 | job_process_terminated (job, process, status); |
172 | 1593 | break; | 1570 | break; |
173 | 1594 | case NIH_CHILD_STOPPED: | 1571 | case NIH_CHILD_STOPPED: |
174 | 1595 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
175 | 1596 | /* Child was stopped by a signal, make sure it was SIGSTOP | 1572 | /* Child was stopped by a signal, make sure it was SIGSTOP |
176 | 1597 | * and not a tty-related signal. | 1573 | * and not a tty-related signal. |
177 | 1598 | */ | 1574 | */ |
178 | @@ -1608,13 +1584,11 @@ | |||
179 | 1608 | } | 1584 | } |
180 | 1609 | 1585 | ||
181 | 1610 | if (status == SIGSTOP) { | 1586 | if (status == SIGSTOP) { |
182 | 1611 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
183 | 1612 | job_process_stopped (job, process); | 1587 | job_process_stopped (job, process); |
184 | 1613 | } | 1588 | } |
185 | 1614 | 1589 | ||
186 | 1615 | break; | 1590 | break; |
187 | 1616 | case NIH_CHILD_CONTINUED: | 1591 | case NIH_CHILD_CONTINUED: |
188 | 1617 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
189 | 1618 | /* Child was continued by a signal. | 1592 | /* Child was continued by a signal. |
190 | 1619 | */ | 1593 | */ |
191 | 1620 | sig = nih_signal_to_name (status); | 1594 | sig = nih_signal_to_name (status); |
192 | @@ -1629,7 +1603,6 @@ | |||
193 | 1629 | } | 1603 | } |
194 | 1630 | break; | 1604 | break; |
195 | 1631 | case NIH_CHILD_TRAPPED: | 1605 | case NIH_CHILD_TRAPPED: |
196 | 1632 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
197 | 1633 | /* Child received a signal while we were tracing it. This | 1606 | /* Child received a signal while we were tracing it. This |
198 | 1634 | * can be a signal raised inside the kernel as a side-effect | 1607 | * can be a signal raised inside the kernel as a side-effect |
199 | 1635 | * of the trace because the child called fork() or exec(); | 1608 | * of the trace because the child called fork() or exec(); |
200 | @@ -1637,29 +1610,23 @@ | |||
201 | 1637 | */ | 1610 | */ |
202 | 1638 | if ((job->trace_state == TRACE_NEW) | 1611 | if ((job->trace_state == TRACE_NEW) |
203 | 1639 | && (status == SIGTRAP)) { | 1612 | && (status == SIGTRAP)) { |
204 | 1640 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
205 | 1641 | job_process_trace_new (job, process); | 1613 | job_process_trace_new (job, process); |
206 | 1642 | } else if ((job->trace_state == TRACE_NEW_CHILD) | 1614 | } else if ((job->trace_state == TRACE_NEW_CHILD) |
207 | 1643 | && (status == SIGSTOP)) { | 1615 | && (status == SIGSTOP)) { |
208 | 1644 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
209 | 1645 | job_process_trace_new_child (job, process); | 1616 | job_process_trace_new_child (job, process); |
210 | 1646 | } else { | 1617 | } else { |
211 | 1647 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
212 | 1648 | job_process_trace_signal (job, process, status); | 1618 | job_process_trace_signal (job, process, status); |
213 | 1649 | } | 1619 | } |
214 | 1650 | break; | 1620 | break; |
215 | 1651 | case NIH_CHILD_PTRACE: | 1621 | case NIH_CHILD_PTRACE: |
216 | 1652 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
217 | 1653 | /* Child called an important syscall that can modify the | 1622 | /* Child called an important syscall that can modify the |
218 | 1654 | * state of the process trace we hold. | 1623 | * state of the process trace we hold. |
219 | 1655 | */ | 1624 | */ |
220 | 1656 | switch (status) { | 1625 | switch (status) { |
221 | 1657 | case PTRACE_EVENT_FORK: | 1626 | case PTRACE_EVENT_FORK: |
222 | 1658 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
223 | 1659 | job_process_trace_fork (job, process); | 1627 | job_process_trace_fork (job, process); |
224 | 1660 | break; | 1628 | break; |
225 | 1661 | case PTRACE_EVENT_EXEC: | 1629 | case PTRACE_EVENT_EXEC: |
226 | 1662 | nih_message ("XXX:%s:%d:", __func__, __LINE__); | ||
227 | 1663 | job_process_trace_exec (job, process); | 1630 | job_process_trace_exec (job, process); |
228 | 1664 | break; | 1631 | break; |
229 | 1665 | default: | 1632 | default: |
230 | @@ -1697,10 +1664,6 @@ | |||
231 | 1697 | 1664 | ||
232 | 1698 | nih_assert (job != NULL); | 1665 | nih_assert (job != NULL); |
233 | 1699 | 1666 | ||
234 | 1700 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s, status=%d", __func__, __LINE__, | ||
235 | 1701 | job_name (job), job_goal_name (job->goal), job_state_name (job->state), | ||
236 | 1702 | process_name (process), status); | ||
237 | 1703 | |||
238 | 1704 | switch (process) { | 1667 | switch (process) { |
239 | 1705 | case PROCESS_MAIN: | 1668 | case PROCESS_MAIN: |
240 | 1706 | nih_assert ((job->state == JOB_RUNNING) | 1669 | nih_assert ((job->state == JOB_RUNNING) |
241 | @@ -1708,7 +1671,9 @@ | |||
242 | 1708 | || (job->state == JOB_KILLED) | 1671 | || (job->state == JOB_KILLED) |
243 | 1709 | || (job->state == JOB_STOPPING) | 1672 | || (job->state == JOB_STOPPING) |
244 | 1710 | || (job->state == JOB_POST_START) | 1673 | || (job->state == JOB_POST_START) |
245 | 1674 | || (job->state == JOB_POST_START_SETUP) | ||
246 | 1711 | || (job->state == JOB_PRE_STOP) | 1675 | || (job->state == JOB_PRE_STOP) |
247 | 1676 | || (job->state == JOB_PRE_STOP_SETUP) | ||
248 | 1712 | || (job->state == JOB_SETUP)); | 1677 | || (job->state == JOB_SETUP)); |
249 | 1713 | 1678 | ||
250 | 1714 | /* We don't change the state if we're in post-start and there's | 1679 | /* We don't change the state if we're in post-start and there's |
251 | @@ -1800,7 +1765,8 @@ | |||
252 | 1800 | stop = TRUE; | 1765 | stop = TRUE; |
253 | 1801 | break; | 1766 | break; |
254 | 1802 | case PROCESS_SECURITY: | 1767 | case PROCESS_SECURITY: |
256 | 1803 | nih_assert (job->state == JOB_SECURITY_SETUP); | 1768 | nih_assert ((job->state == JOB_SECURITY) |
257 | 1769 | || (job->state == JOB_SECURITY_SETUP)); | ||
258 | 1804 | 1770 | ||
259 | 1805 | /* We should always fail the job if the security profile | 1771 | /* We should always fail the job if the security profile |
260 | 1806 | * failed to load | 1772 | * failed to load |
261 | @@ -1811,7 +1777,8 @@ | |||
262 | 1811 | } | 1777 | } |
263 | 1812 | break; | 1778 | break; |
264 | 1813 | case PROCESS_PRE_START: | 1779 | case PROCESS_PRE_START: |
266 | 1814 | nih_assert (job->state == JOB_PRE_START_SETUP); | 1780 | nih_assert ((job->state == JOB_PRE_START) |
267 | 1781 | || (job->state == JOB_PRE_START_SETUP)); | ||
268 | 1815 | 1782 | ||
269 | 1816 | /* If the pre-start script is killed or exits with a status | 1783 | /* If the pre-start script is killed or exits with a status |
270 | 1817 | * other than zero, it's always considered a failure since | 1784 | * other than zero, it's always considered a failure since |
271 | @@ -1823,7 +1790,8 @@ | |||
272 | 1823 | } | 1790 | } |
273 | 1824 | break; | 1791 | break; |
274 | 1825 | case PROCESS_POST_START: | 1792 | case PROCESS_POST_START: |
276 | 1826 | nih_assert (job->state == JOB_POST_START_SETUP); | 1793 | nih_assert ((job->state == JOB_POST_START) |
277 | 1794 | || (job->state == JOB_POST_START_SETUP)); | ||
278 | 1827 | 1795 | ||
279 | 1828 | /* We always want to change the state when the post-start | 1796 | /* We always want to change the state when the post-start |
280 | 1829 | * script terminates; if the main process is running, we'll | 1797 | * script terminates; if the main process is running, we'll |
281 | @@ -1834,7 +1802,8 @@ | |||
282 | 1834 | */ | 1802 | */ |
283 | 1835 | break; | 1803 | break; |
284 | 1836 | case PROCESS_PRE_STOP: | 1804 | case PROCESS_PRE_STOP: |
286 | 1837 | nih_assert (job->state == JOB_PRE_STOP_SETUP); | 1805 | nih_assert ((job->state == JOB_PRE_STOP) |
287 | 1806 | || (job->state == JOB_PRE_STOP_SETUP)); | ||
288 | 1838 | 1807 | ||
289 | 1839 | /* We always want to change the state when the pre-stop | 1808 | /* We always want to change the state when the pre-stop |
290 | 1840 | * script terminates, we either want to go back into running | 1809 | * script terminates, we either want to go back into running |
291 | @@ -1845,7 +1814,8 @@ | |||
292 | 1845 | */ | 1814 | */ |
293 | 1846 | break; | 1815 | break; |
294 | 1847 | case PROCESS_POST_STOP: | 1816 | case PROCESS_POST_STOP: |
296 | 1848 | nih_assert (job->state == JOB_POST_STOP_SETUP); | 1817 | nih_assert ((job->state == JOB_POST_STOP) |
297 | 1818 | || (job->state == JOB_POST_STOP_SETUP)); | ||
298 | 1849 | 1819 | ||
299 | 1850 | /* If the post-stop script is killed or exits with a status | 1820 | /* If the post-stop script is killed or exits with a status |
300 | 1851 | * other than zero, it's always considered a failure since | 1821 | * other than zero, it's always considered a failure since |
301 | @@ -2022,34 +1992,19 @@ | |||
302 | 2022 | break; | 1992 | break; |
303 | 2023 | } | 1993 | } |
304 | 2024 | 1994 | ||
305 | 2025 | nih_message ("XXX:%s:%d: job=%s, process=%s, pid %d (state=%s, goal=%s)", __func__, __LINE__, | ||
306 | 2026 | job_name (job), process_name (process), job->pid[process], job_state_name (job->state), job_goal_name (job->goal)); | ||
307 | 2027 | |||
308 | 2028 | /* Any process can stop on a signal, but we only care about the | 1995 | /* Any process can stop on a signal, but we only care about the |
309 | 2029 | * main process when the state is still spawned and any jobs | 1996 | * main process when the state is still spawned and any jobs |
310 | 2030 | * which require (cgroup) setup. | 1997 | * which require (cgroup) setup. |
316 | 2031 | */ | 1998 | * |
317 | 2032 | if (! ((process == PROCESS_MAIN && job->state == JOB_SPAWNED) || setup)) | 1999 | * Send SIGCONT back and change the state to the next one for |
313 | 2033 | return; | ||
314 | 2034 | |||
315 | 2035 | /* Send SIGCONT back and change the state to the next one for | ||
318 | 2036 | * 'expect stop' jobs and those that require cgroup setup. | 2000 | * 'expect stop' jobs and those that require cgroup setup. |
319 | 2037 | */ | 2001 | */ |
324 | 2038 | if (job->class->expect == EXPECT_STOP || (job_needs_cgroups (job) && setup)) { | 2002 | if (job->class->expect == EXPECT_STOP && process == PROCESS_MAIN |
325 | 2039 | nih_message ("XXX:%s:%d: sending SIGCONT to %s process %s pid %d (state=%s)", __func__, __LINE__, | 2003 | && (job->state == JOB_SETUP || job->state == JOB_SPAWNED) |
326 | 2040 | job_name (job), process_name (process), job->pid[process], job_state_name (job->state)); | 2004 | || (job_needs_cgroups (job) && setup)) { |
323 | 2041 | |||
327 | 2042 | kill (job->pid[process], SIGCONT); | 2005 | kill (job->pid[process], SIGCONT); |
328 | 2043 | } | ||
329 | 2044 | |||
330 | 2045 | if (job->class->expect == EXPECT_STOP && process == PROCESS_MAIN && job->state == JOB_SPAWNED) { | ||
331 | 2046 | nih_message ("XXX:%s:%d: changing state for job %s process %s pid %d (state=%s)", __func__, __LINE__, | ||
332 | 2047 | job_name (job), process_name (process), job->pid[process], job_state_name (job->state)); | ||
333 | 2048 | |||
334 | 2049 | job_change_state (job, job_next_state (job)); | 2006 | job_change_state (job, job_next_state (job)); |
335 | 2050 | } | 2007 | } |
336 | 2051 | |||
337 | 2052 | nih_message ("XXX:%s:%d: ", __func__, __LINE__); | ||
338 | 2053 | } | 2008 | } |
339 | 2054 | 2009 | ||
340 | 2055 | 2010 | ||
341 | @@ -2072,10 +2027,6 @@ | |||
342 | 2072 | nih_assert ((job->trace_state == TRACE_NEW) | 2027 | nih_assert ((job->trace_state == TRACE_NEW) |
343 | 2073 | || (job->trace_state == TRACE_NEW_CHILD)); | 2028 | || (job->trace_state == TRACE_NEW_CHILD)); |
344 | 2074 | 2029 | ||
345 | 2075 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s", __func__, __LINE__, | ||
346 | 2076 | job_name (job), job_goal_name (job->goal), job_state_name (job->state), | ||
347 | 2077 | process_name (process)); | ||
348 | 2078 | |||
349 | 2079 | /* Any process can get us to trace them, but we only care about the | 2030 | /* Any process can get us to trace them, but we only care about the |
350 | 2080 | * main process when the state is still spawned. | 2031 | * main process when the state is still spawned. |
351 | 2081 | */ | 2032 | */ |
352 | @@ -2127,10 +2078,6 @@ | |||
353 | 2127 | nih_assert (job != NULL); | 2078 | nih_assert (job != NULL); |
354 | 2128 | nih_assert (job->trace_state == TRACE_NEW_CHILD); | 2079 | nih_assert (job->trace_state == TRACE_NEW_CHILD); |
355 | 2129 | 2080 | ||
356 | 2130 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s", __func__, __LINE__, | ||
357 | 2131 | job_name (job), job_goal_name (job->goal), job_state_name (job->state), | ||
358 | 2132 | process_name (process)); | ||
359 | 2133 | |||
360 | 2134 | /* Any process can get us to trace them, but we only care about the | 2081 | /* Any process can get us to trace them, but we only care about the |
361 | 2135 | * main process when the state is still spawned. | 2082 | * main process when the state is still spawned. |
362 | 2136 | */ | 2083 | */ |
363 | @@ -2176,10 +2123,6 @@ | |||
364 | 2176 | { | 2123 | { |
365 | 2177 | nih_assert (job != NULL); | 2124 | nih_assert (job != NULL); |
366 | 2178 | 2125 | ||
367 | 2179 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s, signum=%d", __func__, __LINE__, | ||
368 | 2180 | job_name (job), job_goal_name (job->goal), job_state_name (job->state), | ||
369 | 2181 | process_name (process), signum); | ||
370 | 2182 | |||
371 | 2183 | /* Any process can get us to trace them, but we only care about the | 2126 | /* Any process can get us to trace them, but we only care about the |
372 | 2184 | * main process when the state is still spawned. | 2127 | * main process when the state is still spawned. |
373 | 2185 | */ | 2128 | */ |
374 | @@ -2215,10 +2158,6 @@ | |||
375 | 2215 | 2158 | ||
376 | 2216 | nih_assert (job != NULL); | 2159 | nih_assert (job != NULL); |
377 | 2217 | 2160 | ||
378 | 2218 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s", __func__, __LINE__, | ||
379 | 2219 | job_name (job), job_goal_name (job->goal), job_state_name (job->state), | ||
380 | 2220 | process_name (process)); | ||
381 | 2221 | |||
382 | 2222 | /* Any process can get us to trace them, but we only care about the | 2161 | /* Any process can get us to trace them, but we only care about the |
383 | 2223 | * main process when the state is still spawned. | 2162 | * main process when the state is still spawned. |
384 | 2224 | */ | 2163 | */ |
385 | @@ -2287,10 +2226,6 @@ | |||
386 | 2287 | { | 2226 | { |
387 | 2288 | nih_assert (job != NULL); | 2227 | nih_assert (job != NULL); |
388 | 2289 | 2228 | ||
389 | 2290 | nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s", __func__, __LINE__, | ||
390 | 2291 | job_name (job), job_goal_name (job->goal), job_state_name (job->state), | ||
391 | 2292 | process_name (process)); | ||
392 | 2293 | |||
393 | 2294 | /* Any process can get us to trace them, but we only care about the | 2229 | /* Any process can get us to trace them, but we only care about the |
394 | 2295 | * main process when the state is still spawned and we're tracing it. | 2230 | * main process when the state is still spawned and we're tracing it. |
395 | 2296 | */ | 2231 | */ |
396 | 2297 | 2232 | ||
397 | === modified file 'init/tests/test_event.c' | |||
398 | --- init/tests/test_event.c 2013-01-31 17:23:55 +0000 | |||
399 | +++ init/tests/test_event.c 2014-04-08 20:51:56 +0000 | |||
400 | @@ -1259,7 +1259,7 @@ | |||
401 | 1259 | job = (Job *)nih_hash_lookup (class->instances, ""); | 1259 | job = (Job *)nih_hash_lookup (class->instances, ""); |
402 | 1260 | 1260 | ||
403 | 1261 | TEST_EQ (job->goal, JOB_STOP); | 1261 | TEST_EQ (job->goal, JOB_STOP); |
405 | 1262 | TEST_EQ (job->state, JOB_POST_STOP); | 1262 | TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
406 | 1263 | 1263 | ||
407 | 1264 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); | 1264 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
408 | 1265 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); | 1265 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); |
409 | @@ -1335,7 +1335,7 @@ | |||
410 | 1335 | job = (Job *)nih_hash_lookup (class->instances, ""); | 1335 | job = (Job *)nih_hash_lookup (class->instances, ""); |
411 | 1336 | 1336 | ||
412 | 1337 | TEST_EQ (job->goal, JOB_STOP); | 1337 | TEST_EQ (job->goal, JOB_STOP); |
414 | 1338 | TEST_EQ (job->state, JOB_POST_STOP); | 1338 | TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
415 | 1339 | 1339 | ||
416 | 1340 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); | 1340 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
417 | 1341 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); | 1341 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); |
418 | @@ -1439,7 +1439,7 @@ | |||
419 | 1439 | job = (Job *)nih_hash_lookup (class->instances, ""); | 1439 | job = (Job *)nih_hash_lookup (class->instances, ""); |
420 | 1440 | 1440 | ||
421 | 1441 | TEST_EQ (job->goal, JOB_STOP); | 1441 | TEST_EQ (job->goal, JOB_STOP); |
423 | 1442 | TEST_EQ (job->state, JOB_POST_STOP); | 1442 | TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
424 | 1443 | 1443 | ||
425 | 1444 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); | 1444 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
426 | 1445 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); | 1445 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); |
427 | @@ -1621,7 +1621,7 @@ | |||
428 | 1621 | job = (Job *)nih_hash_lookup (class->instances, ""); | 1621 | job = (Job *)nih_hash_lookup (class->instances, ""); |
429 | 1622 | 1622 | ||
430 | 1623 | TEST_EQ (job->goal, JOB_STOP); | 1623 | TEST_EQ (job->goal, JOB_STOP); |
432 | 1624 | TEST_EQ (job->state, JOB_POST_STOP); | 1624 | TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
433 | 1625 | 1625 | ||
434 | 1626 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); | 1626 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
435 | 1627 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); | 1627 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); |
436 | @@ -1980,7 +1980,7 @@ | |||
437 | 1980 | event_poll (); | 1980 | event_poll (); |
438 | 1981 | 1981 | ||
439 | 1982 | TEST_EQ (job->goal, JOB_STOP); | 1982 | TEST_EQ (job->goal, JOB_STOP); |
441 | 1983 | TEST_EQ (job->state, JOB_POST_STOP); | 1983 | TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
442 | 1984 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); | 1984 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
443 | 1985 | TEST_EQ_P (job->blocker, NULL); | 1985 | TEST_EQ_P (job->blocker, NULL); |
444 | 1986 | 1986 | ||
445 | @@ -2026,7 +2026,7 @@ | |||
446 | 2026 | event_poll (); | 2026 | event_poll (); |
447 | 2027 | 2027 | ||
448 | 2028 | TEST_EQ (job->goal, JOB_START); | 2028 | TEST_EQ (job->goal, JOB_START); |
450 | 2029 | TEST_EQ (job->state, JOB_PRE_START); | 2029 | TEST_EQ (job->state, JOB_PRE_START_SETUP); |
451 | 2030 | TEST_GT (job->pid[PROCESS_PRE_START], 0); | 2030 | TEST_GT (job->pid[PROCESS_PRE_START], 0); |
452 | 2031 | TEST_EQ_P (job->blocker, NULL); | 2031 | TEST_EQ_P (job->blocker, NULL); |
453 | 2032 | 2032 | ||
454 | 2033 | 2033 | ||
455 | === modified file 'init/tests/test_job.c' | |||
456 | --- init/tests/test_job.c 2013-11-18 16:38:32 +0000 | |||
457 | +++ init/tests/test_job.c 2014-04-08 20:51:56 +0000 | |||
458 | @@ -1059,10 +1059,10 @@ | |||
459 | 1059 | job->failed_process = PROCESS_INVALID; | 1059 | job->failed_process = PROCESS_INVALID; |
460 | 1060 | job->exit_status = 0; | 1060 | job->exit_status = 0; |
461 | 1061 | 1061 | ||
463 | 1062 | job_change_state (job, JOB_PRE_START); | 1062 | job_change_state (job, JOB_PRE_START_SETUP); |
464 | 1063 | 1063 | ||
465 | 1064 | TEST_EQ (job->goal, JOB_START); | 1064 | TEST_EQ (job->goal, JOB_START); |
467 | 1065 | TEST_EQ (job->state, JOB_PRE_START); | 1065 | TEST_EQ (job->state, JOB_PRE_START_SETUP); |
468 | 1066 | TEST_NE (job->pid[PROCESS_PRE_START], 0); | 1066 | TEST_NE (job->pid[PROCESS_PRE_START], 0); |
469 | 1067 | 1067 | ||
470 | 1068 | waitpid (job->pid[PROCESS_PRE_START], &status, 0); | 1068 | waitpid (job->pid[PROCESS_PRE_START], &status, 0); |
471 | @@ -1125,7 +1125,7 @@ | |||
472 | 1125 | job->failed_process = PROCESS_INVALID; | 1125 | job->failed_process = PROCESS_INVALID; |
473 | 1126 | job->exit_status = 0; | 1126 | job->exit_status = 0; |
474 | 1127 | 1127 | ||
476 | 1128 | job_change_state (job, JOB_PRE_START); | 1128 | job_change_state (job, JOB_PRE_START_SETUP); |
477 | 1129 | 1129 | ||
478 | 1130 | TEST_EQ (job->goal, JOB_START); | 1130 | TEST_EQ (job->goal, JOB_START); |
479 | 1131 | TEST_EQ (job->state, JOB_RUNNING); | 1131 | TEST_EQ (job->state, JOB_RUNNING); |
480 | @@ -1200,7 +1200,7 @@ | |||
481 | 1200 | job->exit_status = 0; | 1200 | job->exit_status = 0; |
482 | 1201 | 1201 | ||
483 | 1202 | TEST_DIVERT_STDERR (output) { | 1202 | TEST_DIVERT_STDERR (output) { |
485 | 1203 | job_change_state (job, JOB_PRE_START); | 1203 | job_change_state (job, JOB_PRE_START_SETUP); |
486 | 1204 | } | 1204 | } |
487 | 1205 | rewind (output); | 1205 | rewind (output); |
488 | 1206 | 1206 | ||
489 | @@ -1284,7 +1284,7 @@ | |||
490 | 1284 | job->failed_process = PROCESS_INVALID; | 1284 | job->failed_process = PROCESS_INVALID; |
491 | 1285 | job->exit_status = 0; | 1285 | job->exit_status = 0; |
492 | 1286 | 1286 | ||
494 | 1287 | job_change_state (job, JOB_SPAWNED); | 1287 | job_change_state (job, JOB_SETUP); |
495 | 1288 | 1288 | ||
496 | 1289 | TEST_EQ (job->goal, JOB_START); | 1289 | TEST_EQ (job->goal, JOB_START); |
497 | 1290 | TEST_EQ (job->state, JOB_RUNNING); | 1290 | TEST_EQ (job->state, JOB_RUNNING); |
498 | @@ -1352,7 +1352,7 @@ | |||
499 | 1352 | job->failed_process = PROCESS_INVALID; | 1352 | job->failed_process = PROCESS_INVALID; |
500 | 1353 | job->exit_status = 0; | 1353 | job->exit_status = 0; |
501 | 1354 | 1354 | ||
503 | 1355 | job_change_state (job, JOB_SPAWNED); | 1355 | job_change_state (job, JOB_SETUP); |
504 | 1356 | 1356 | ||
505 | 1357 | TEST_EQ (job->goal, JOB_START); | 1357 | TEST_EQ (job->goal, JOB_START); |
506 | 1358 | TEST_EQ (job->state, JOB_RUNNING); | 1358 | TEST_EQ (job->state, JOB_RUNNING); |
507 | @@ -1432,7 +1432,7 @@ | |||
508 | 1432 | job->failed_process = PROCESS_INVALID; | 1432 | job->failed_process = PROCESS_INVALID; |
509 | 1433 | job->exit_status = 0; | 1433 | job->exit_status = 0; |
510 | 1434 | 1434 | ||
512 | 1435 | job_change_state (job, JOB_SPAWNED); | 1435 | job_change_state (job, JOB_SETUP); |
513 | 1436 | 1436 | ||
514 | 1437 | TEST_EQ (job->goal, JOB_START); | 1437 | TEST_EQ (job->goal, JOB_START); |
515 | 1438 | TEST_EQ (job->state, JOB_RUNNING); | 1438 | TEST_EQ (job->state, JOB_RUNNING); |
516 | @@ -1507,7 +1507,7 @@ | |||
517 | 1507 | job->failed_process = PROCESS_INVALID; | 1507 | job->failed_process = PROCESS_INVALID; |
518 | 1508 | job->exit_status = 0; | 1508 | job->exit_status = 0; |
519 | 1509 | 1509 | ||
521 | 1510 | job_change_state (job, JOB_SPAWNED); | 1510 | job_change_state (job, JOB_SETUP); |
522 | 1511 | 1511 | ||
523 | 1512 | TEST_EQ (job->goal, JOB_START); | 1512 | TEST_EQ (job->goal, JOB_START); |
524 | 1513 | TEST_EQ (job->state, JOB_RUNNING); | 1513 | TEST_EQ (job->state, JOB_RUNNING); |
525 | @@ -1572,7 +1572,7 @@ | |||
526 | 1572 | job->exit_status = 0; | 1572 | job->exit_status = 0; |
527 | 1573 | 1573 | ||
528 | 1574 | TEST_DIVERT_STDERR (output) { | 1574 | TEST_DIVERT_STDERR (output) { |
530 | 1575 | job_change_state (job, JOB_SPAWNED); | 1575 | job_change_state (job, JOB_SETUP); |
531 | 1576 | } | 1576 | } |
532 | 1577 | rewind (output); | 1577 | rewind (output); |
533 | 1578 | 1578 | ||
534 | @@ -1658,10 +1658,10 @@ | |||
535 | 1658 | job->failed_process = PROCESS_INVALID; | 1658 | job->failed_process = PROCESS_INVALID; |
536 | 1659 | job->exit_status = 0; | 1659 | job->exit_status = 0; |
537 | 1660 | 1660 | ||
539 | 1661 | job_change_state (job, JOB_SPAWNED); | 1661 | job_change_state (job, JOB_SETUP); |
540 | 1662 | 1662 | ||
541 | 1663 | TEST_EQ (job->goal, JOB_START); | 1663 | TEST_EQ (job->goal, JOB_START); |
543 | 1664 | TEST_EQ (job->state, JOB_SPAWNED); | 1664 | TEST_EQ (job->state, JOB_SETUP); |
544 | 1665 | TEST_NE (job->pid[PROCESS_MAIN], 0); | 1665 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
545 | 1666 | 1666 | ||
546 | 1667 | waitpid (job->pid[PROCESS_MAIN], &status, 0); | 1667 | waitpid (job->pid[PROCESS_MAIN], &status, 0); |
547 | @@ -1727,10 +1727,10 @@ | |||
548 | 1727 | job->failed_process = PROCESS_INVALID; | 1727 | job->failed_process = PROCESS_INVALID; |
549 | 1728 | job->exit_status = 0; | 1728 | job->exit_status = 0; |
550 | 1729 | 1729 | ||
552 | 1730 | job_change_state (job, JOB_POST_START); | 1730 | job_change_state (job, JOB_POST_START_SETUP); |
553 | 1731 | 1731 | ||
554 | 1732 | TEST_EQ (job->goal, JOB_START); | 1732 | TEST_EQ (job->goal, JOB_START); |
556 | 1733 | TEST_EQ (job->state, JOB_POST_START); | 1733 | TEST_EQ (job->state, JOB_POST_START_SETUP); |
557 | 1734 | TEST_EQ (job->pid[PROCESS_MAIN], 1); | 1734 | TEST_EQ (job->pid[PROCESS_MAIN], 1); |
558 | 1735 | TEST_NE (job->pid[PROCESS_POST_START], 0); | 1735 | TEST_NE (job->pid[PROCESS_POST_START], 0); |
559 | 1736 | 1736 | ||
560 | @@ -1794,7 +1794,7 @@ | |||
561 | 1794 | job->failed_process = PROCESS_INVALID; | 1794 | job->failed_process = PROCESS_INVALID; |
562 | 1795 | job->exit_status = 0; | 1795 | job->exit_status = 0; |
563 | 1796 | 1796 | ||
565 | 1797 | job_change_state (job, JOB_POST_START); | 1797 | job_change_state (job, JOB_POST_START_SETUP); |
566 | 1798 | 1798 | ||
567 | 1799 | TEST_EQ (job->goal, JOB_START); | 1799 | TEST_EQ (job->goal, JOB_START); |
568 | 1800 | TEST_EQ (job->state, JOB_RUNNING); | 1800 | TEST_EQ (job->state, JOB_RUNNING); |
569 | @@ -1858,7 +1858,7 @@ | |||
570 | 1858 | job->exit_status = 0; | 1858 | job->exit_status = 0; |
571 | 1859 | 1859 | ||
572 | 1860 | TEST_DIVERT_STDERR (output) { | 1860 | TEST_DIVERT_STDERR (output) { |
574 | 1861 | job_change_state (job, JOB_POST_START); | 1861 | job_change_state (job, JOB_POST_START_SETUP); |
575 | 1862 | } | 1862 | } |
576 | 1863 | rewind (output); | 1863 | rewind (output); |
577 | 1864 | 1864 | ||
578 | @@ -2058,10 +2058,10 @@ | |||
579 | 2058 | job->failed_process = PROCESS_INVALID; | 2058 | job->failed_process = PROCESS_INVALID; |
580 | 2059 | job->exit_status = 0; | 2059 | job->exit_status = 0; |
581 | 2060 | 2060 | ||
583 | 2061 | job_change_state (job, JOB_PRE_STOP); | 2061 | job_change_state (job, JOB_PRE_STOP_SETUP); |
584 | 2062 | 2062 | ||
585 | 2063 | TEST_EQ (job->goal, JOB_STOP); | 2063 | TEST_EQ (job->goal, JOB_STOP); |
587 | 2064 | TEST_EQ (job->state, JOB_PRE_STOP); | 2064 | TEST_EQ (job->state, JOB_PRE_STOP_SETUP); |
588 | 2065 | TEST_EQ (job->pid[PROCESS_MAIN], 1); | 2065 | TEST_EQ (job->pid[PROCESS_MAIN], 1); |
589 | 2066 | TEST_NE (job->pid[PROCESS_PRE_STOP], 0); | 2066 | TEST_NE (job->pid[PROCESS_PRE_STOP], 0); |
590 | 2067 | 2067 | ||
591 | @@ -2125,7 +2125,7 @@ | |||
592 | 2125 | job->failed_process = PROCESS_INVALID; | 2125 | job->failed_process = PROCESS_INVALID; |
593 | 2126 | job->exit_status = 0; | 2126 | job->exit_status = 0; |
594 | 2127 | 2127 | ||
596 | 2128 | job_change_state (job, JOB_PRE_STOP); | 2128 | job_change_state (job, JOB_PRE_STOP_SETUP); |
597 | 2129 | 2129 | ||
598 | 2130 | TEST_EQ (job->goal, JOB_STOP); | 2130 | TEST_EQ (job->goal, JOB_STOP); |
599 | 2131 | TEST_EQ (job->state, JOB_STOPPING); | 2131 | TEST_EQ (job->state, JOB_STOPPING); |
600 | @@ -2198,7 +2198,7 @@ | |||
601 | 2198 | job->failed_process = PROCESS_INVALID; | 2198 | job->failed_process = PROCESS_INVALID; |
602 | 2199 | job->exit_status = 0; | 2199 | job->exit_status = 0; |
603 | 2200 | 2200 | ||
605 | 2201 | job_change_state (job, JOB_PRE_STOP); | 2201 | job_change_state (job, JOB_PRE_STOP_SETUP); |
606 | 2202 | 2202 | ||
607 | 2203 | TEST_EQ (job->goal, JOB_STOP); | 2203 | TEST_EQ (job->goal, JOB_STOP); |
608 | 2204 | TEST_EQ (job->state, JOB_STOPPING); | 2204 | TEST_EQ (job->state, JOB_STOPPING); |
609 | @@ -2283,7 +2283,7 @@ | |||
610 | 2283 | job->failed_process = PROCESS_INVALID; | 2283 | job->failed_process = PROCESS_INVALID; |
611 | 2284 | job->exit_status = 0; | 2284 | job->exit_status = 0; |
612 | 2285 | 2285 | ||
614 | 2286 | job_change_state (job, JOB_PRE_STOP); | 2286 | job_change_state (job, JOB_PRE_STOP_SETUP); |
615 | 2287 | 2287 | ||
616 | 2288 | TEST_EQ (job->goal, JOB_STOP); | 2288 | TEST_EQ (job->goal, JOB_STOP); |
617 | 2289 | TEST_EQ (job->state, JOB_STOPPING); | 2289 | TEST_EQ (job->state, JOB_STOPPING); |
618 | @@ -2364,7 +2364,7 @@ | |||
619 | 2364 | job->exit_status = 0; | 2364 | job->exit_status = 0; |
620 | 2365 | 2365 | ||
621 | 2366 | TEST_DIVERT_STDERR (output) { | 2366 | TEST_DIVERT_STDERR (output) { |
623 | 2367 | job_change_state (job, JOB_PRE_STOP); | 2367 | job_change_state (job, JOB_PRE_STOP_SETUP); |
624 | 2368 | } | 2368 | } |
625 | 2369 | rewind (output); | 2369 | rewind (output); |
626 | 2370 | 2370 | ||
627 | @@ -3039,7 +3039,7 @@ | |||
628 | 3039 | job_change_state (job, JOB_KILLED); | 3039 | job_change_state (job, JOB_KILLED); |
629 | 3040 | 3040 | ||
630 | 3041 | TEST_EQ (job->goal, JOB_STOP); | 3041 | TEST_EQ (job->goal, JOB_STOP); |
632 | 3042 | TEST_EQ (job->state, JOB_POST_STOP); | 3042 | TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
633 | 3043 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); | 3043 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); |
634 | 3044 | 3044 | ||
635 | 3045 | waitpid (job->pid[PROCESS_POST_STOP], &status, 0); | 3045 | waitpid (job->pid[PROCESS_POST_STOP], &status, 0); |
636 | @@ -3100,10 +3100,10 @@ | |||
637 | 3100 | job->failed_process = PROCESS_INVALID; | 3100 | job->failed_process = PROCESS_INVALID; |
638 | 3101 | job->exit_status = 0; | 3101 | job->exit_status = 0; |
639 | 3102 | 3102 | ||
641 | 3103 | job_change_state (job, JOB_POST_STOP); | 3103 | job_change_state (job, JOB_POST_STOP_SETUP); |
642 | 3104 | 3104 | ||
643 | 3105 | TEST_EQ (job->goal, JOB_STOP); | 3105 | TEST_EQ (job->goal, JOB_STOP); |
645 | 3106 | TEST_EQ (job->state, JOB_POST_STOP); | 3106 | TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
646 | 3107 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); | 3107 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); |
647 | 3108 | 3108 | ||
648 | 3109 | waitpid (job->pid[PROCESS_POST_STOP], &status, 0); | 3109 | waitpid (job->pid[PROCESS_POST_STOP], &status, 0); |
649 | @@ -3168,7 +3168,7 @@ | |||
650 | 3168 | 3168 | ||
651 | 3169 | TEST_FREE_TAG (job); | 3169 | TEST_FREE_TAG (job); |
652 | 3170 | 3170 | ||
654 | 3171 | job_change_state (job, JOB_POST_STOP); | 3171 | job_change_state (job, JOB_POST_STOP_SETUP); |
655 | 3172 | 3172 | ||
656 | 3173 | TEST_FREE (job); | 3173 | TEST_FREE (job); |
657 | 3174 | 3174 | ||
658 | @@ -3228,7 +3228,7 @@ | |||
659 | 3228 | TEST_FREE_TAG (job); | 3228 | TEST_FREE_TAG (job); |
660 | 3229 | 3229 | ||
661 | 3230 | TEST_DIVERT_STDERR (output) { | 3230 | TEST_DIVERT_STDERR (output) { |
663 | 3231 | job_change_state (job, JOB_POST_STOP); | 3231 | job_change_state (job, JOB_POST_STOP_SETUP); |
664 | 3232 | } | 3232 | } |
665 | 3233 | rewind (output); | 3233 | rewind (output); |
666 | 3234 | 3234 | ||
667 | @@ -4000,11 +4000,20 @@ | |||
668 | 4000 | 4000 | ||
669 | 4001 | 4001 | ||
670 | 4002 | /* Check that the next state if we're starting a starting job is | 4002 | /* Check that the next state if we're starting a starting job is |
671 | 4003 | * security setup. | ||
672 | 4004 | */ | ||
673 | 4005 | TEST_FEATURE ("with starting job and a goal of start"); | ||
674 | 4006 | job->goal = JOB_START; | ||
675 | 4007 | job->state = JOB_STARTING; | ||
676 | 4008 | |||
677 | 4009 | TEST_EQ (job_next_state (job), JOB_SECURITY_SETUP); | ||
678 | 4010 | |||
679 | 4011 | /* Check that the next state if we're starting a security job is | ||
680 | 4003 | * security. | 4012 | * security. |
681 | 4004 | */ | 4013 | */ |
683 | 4005 | TEST_FEATURE ("with starting job and a goal of start"); | 4014 | TEST_FEATURE ("with security job and a goal of start"); |
684 | 4006 | job->goal = JOB_START; | 4015 | job->goal = JOB_START; |
686 | 4007 | job->state = JOB_STARTING; | 4016 | job->state = JOB_SECURITY_SETUP; |
687 | 4008 | 4017 | ||
688 | 4009 | TEST_EQ (job_next_state (job), JOB_SECURITY); | 4018 | TEST_EQ (job_next_state (job), JOB_SECURITY); |
689 | 4010 | 4019 | ||
690 | @@ -4015,7 +4024,7 @@ | |||
691 | 4015 | job->goal = JOB_START; | 4024 | job->goal = JOB_START; |
692 | 4016 | job->state = JOB_SECURITY; | 4025 | job->state = JOB_SECURITY; |
693 | 4017 | 4026 | ||
695 | 4018 | TEST_EQ (job_next_state (job), JOB_PRE_START); | 4027 | TEST_EQ (job_next_state (job), JOB_PRE_START_SETUP); |
696 | 4019 | 4028 | ||
697 | 4020 | /* Check that the next state if we're stopping an security job is | 4029 | /* Check that the next state if we're stopping an security job is |
698 | 4021 | * stopping. | 4030 | * stopping. |
699 | @@ -4037,11 +4046,20 @@ | |||
700 | 4037 | 4046 | ||
701 | 4038 | 4047 | ||
702 | 4039 | /* Check that the next state if we're starting a pre-start job is | 4048 | /* Check that the next state if we're starting a pre-start job is |
703 | 4049 | * setup. | ||
704 | 4050 | */ | ||
705 | 4051 | TEST_FEATURE ("with pre-start job and a goal of start"); | ||
706 | 4052 | job->goal = JOB_START; | ||
707 | 4053 | job->state = JOB_PRE_START; | ||
708 | 4054 | |||
709 | 4055 | TEST_EQ (job_next_state (job), JOB_SETUP); | ||
710 | 4056 | |||
711 | 4057 | /* Check that the next state if we're starting a pre-start job is | ||
712 | 4040 | * spawned. | 4058 | * spawned. |
713 | 4041 | */ | 4059 | */ |
714 | 4042 | TEST_FEATURE ("with pre-start job and a goal of start"); | 4060 | TEST_FEATURE ("with pre-start job and a goal of start"); |
715 | 4043 | job->goal = JOB_START; | 4061 | job->goal = JOB_START; |
717 | 4044 | job->state = JOB_PRE_START; | 4062 | job->state = JOB_SETUP; |
718 | 4045 | 4063 | ||
719 | 4046 | TEST_EQ (job_next_state (job), JOB_SPAWNED); | 4064 | TEST_EQ (job_next_state (job), JOB_SPAWNED); |
720 | 4047 | 4065 | ||
721 | @@ -4057,11 +4075,20 @@ | |||
722 | 4057 | 4075 | ||
723 | 4058 | 4076 | ||
724 | 4059 | /* Check that the next state if we're starting a spawned job is | 4077 | /* Check that the next state if we're starting a spawned job is |
725 | 4078 | * post-start setup. | ||
726 | 4079 | */ | ||
727 | 4080 | TEST_FEATURE ("with spawned job and a goal of start"); | ||
728 | 4081 | job->goal = JOB_START; | ||
729 | 4082 | job->state = JOB_SPAWNED; | ||
730 | 4083 | |||
731 | 4084 | TEST_EQ (job_next_state (job), JOB_POST_START_SETUP); | ||
732 | 4085 | |||
733 | 4086 | /* Check that the next state if we're starting a spawned job is | ||
734 | 4060 | * post-start. | 4087 | * post-start. |
735 | 4061 | */ | 4088 | */ |
736 | 4062 | TEST_FEATURE ("with spawned job and a goal of start"); | 4089 | TEST_FEATURE ("with spawned job and a goal of start"); |
737 | 4063 | job->goal = JOB_START; | 4090 | job->goal = JOB_START; |
739 | 4064 | job->state = JOB_SPAWNED; | 4091 | job->state = JOB_POST_START_SETUP; |
740 | 4065 | 4092 | ||
741 | 4066 | TEST_EQ (job_next_state (job), JOB_POST_START); | 4093 | TEST_EQ (job_next_state (job), JOB_POST_START); |
742 | 4067 | 4094 | ||
743 | @@ -4098,7 +4125,7 @@ | |||
744 | 4098 | 4125 | ||
745 | 4099 | 4126 | ||
746 | 4100 | /* Check that the next state if we're stopping a running job is | 4127 | /* Check that the next state if we're stopping a running job is |
748 | 4101 | * pre-stop. This is the "normal" stop process, as called from the | 4128 | * pre-stop setup. This is the "normal" stop process, as called from the |
749 | 4102 | * goal change event. | 4129 | * goal change event. |
750 | 4103 | */ | 4130 | */ |
751 | 4104 | TEST_FEATURE ("with running job and a goal of stop"); | 4131 | TEST_FEATURE ("with running job and a goal of stop"); |
752 | @@ -4106,6 +4133,17 @@ | |||
753 | 4106 | job->state = JOB_RUNNING; | 4133 | job->state = JOB_RUNNING; |
754 | 4107 | job->pid[PROCESS_MAIN] = 1; | 4134 | job->pid[PROCESS_MAIN] = 1; |
755 | 4108 | 4135 | ||
756 | 4136 | TEST_EQ (job_next_state (job), JOB_PRE_STOP_SETUP); | ||
757 | 4137 | |||
758 | 4138 | /* Check that the next state if we're stopping a running job is | ||
759 | 4139 | * pre-stop. | ||
760 | 4140 | */ | ||
761 | 4141 | TEST_FEATURE ("with running job and a goal of stop"); | ||
762 | 4142 | job->goal = JOB_STOP; | ||
763 | 4143 | job->state = JOB_PRE_STOP_SETUP; | ||
764 | 4144 | job->pid[PROCESS_MAIN] = 1; | ||
765 | 4145 | job->pid[PROCESS_PRE_STOP] = 2; | ||
766 | 4146 | |||
767 | 4109 | TEST_EQ (job_next_state (job), JOB_PRE_STOP); | 4147 | TEST_EQ (job_next_state (job), JOB_PRE_STOP); |
768 | 4110 | 4148 | ||
769 | 4111 | 4149 | ||
770 | @@ -4193,7 +4231,7 @@ | |||
771 | 4193 | job->goal = JOB_START; | 4231 | job->goal = JOB_START; |
772 | 4194 | job->state = JOB_KILLED; | 4232 | job->state = JOB_KILLED; |
773 | 4195 | 4233 | ||
775 | 4196 | TEST_EQ (job_next_state (job), JOB_POST_STOP); | 4234 | TEST_EQ (job_next_state (job), JOB_POST_STOP_SETUP); |
776 | 4197 | 4235 | ||
777 | 4198 | 4236 | ||
778 | 4199 | /* Check that the next state if we're stopping a killed job is | 4237 | /* Check that the next state if we're stopping a killed job is |
779 | @@ -4203,7 +4241,7 @@ | |||
780 | 4203 | job->goal = JOB_STOP; | 4241 | job->goal = JOB_STOP; |
781 | 4204 | job->state = JOB_KILLED; | 4242 | job->state = JOB_KILLED; |
782 | 4205 | 4243 | ||
784 | 4206 | TEST_EQ (job_next_state (job), JOB_POST_STOP); | 4244 | TEST_EQ (job_next_state (job), JOB_POST_STOP_SETUP); |
785 | 4207 | 4245 | ||
786 | 4208 | 4246 | ||
787 | 4209 | /* Check that the next state if we're starting a post-stop job is | 4247 | /* Check that the next state if we're starting a post-stop job is |
788 | 4210 | 4248 | ||
789 | === modified file 'scripts/Makefile.am' | |||
790 | --- scripts/Makefile.am 2013-11-14 11:42:05 +0000 | |||
791 | +++ scripts/Makefile.am 2014-04-08 20:51:56 +0000 | |||
792 | @@ -12,24 +12,24 @@ | |||
793 | 12 | upstart-monitor.py | 12 | upstart-monitor.py |
794 | 13 | 13 | ||
795 | 14 | noinst_SCRIPTS = \ | 14 | noinst_SCRIPTS = \ |
797 | 15 | pyupstart.py | 15 | pyupstart.py \ |
798 | 16 | pyupstartvars.py | ||
799 | 16 | 17 | ||
800 | 17 | CLEANFILES = \ | 18 | CLEANFILES = \ |
802 | 18 | pyupstart.py | 19 | pyupstartvars.py pyupstartvars.py.tmp |
803 | 19 | 20 | ||
804 | 20 | EXTRA_DIST = \ | 21 | EXTRA_DIST = \ |
805 | 21 | $(install_scripts) \ | 22 | $(install_scripts) \ |
807 | 22 | pyupstart.py.in \ | 23 | pyupstart.py \ |
808 | 23 | tests/__init__.py \ | 24 | tests/__init__.py \ |
809 | 24 | tests/test_pyupstart_session_init.py \ | 25 | tests/test_pyupstart_session_init.py \ |
810 | 25 | tests/test_pyupstart_system_init.py | 26 | tests/test_pyupstart_system_init.py |
811 | 26 | 27 | ||
818 | 27 | pyupstart.py: pyupstart.py.in Makefile | 28 | pyupstartvars.py: Makefile |
819 | 28 | sed -e 's|[@]built_init_binary[@]|$(UPSTART_BINARY)|g' \ | 29 | echo "BUILT_UPSTART = '$(UPSTART_BINARY)'" > pyupstartvars.py.tmp |
820 | 29 | -e 's|[@]built_initctl_binary[@]|$(INITCTL_BINARY)|g' \ | 30 | echo "BUILT_INITCTL = '$(INITCTL_BINARY)'" >> pyupstartvars.py.tmp |
821 | 30 | -e 's|[@]built_file_bridge_binary[@]|$(FILE_BRIDGE_BINARY)|g' \ | 31 | echo "BUILT_FILE_BRIDGE = '$(FILE_BRIDGE_BINARY)'" >> pyupstartvars.py.tmp |
822 | 31 | $< > $@ | 32 | mv pyupstartvars.py.tmp pyupstartvars.py |
817 | 32 | chmod +x $@ | ||
823 | 33 | 33 | ||
824 | 34 | dist_man_MANS = \ | 34 | dist_man_MANS = \ |
825 | 35 | man/initctl2dot.8 \ | 35 | man/initctl2dot.8 \ |
826 | 36 | 36 | ||
827 | === renamed file 'scripts/pyupstart.py.in' => 'scripts/pyupstart.py' | |||
828 | --- scripts/pyupstart.py.in 2014-03-05 10:41:18 +0000 | |||
829 | +++ scripts/pyupstart.py 2014-04-08 20:51:56 +0000 | |||
830 | @@ -20,6 +20,8 @@ | |||
831 | 20 | import pyinotify | 20 | import pyinotify |
832 | 21 | import subprocess | 21 | import subprocess |
833 | 22 | import shutil | 22 | import shutil |
834 | 23 | import sys | ||
835 | 24 | import unittest | ||
836 | 23 | import dbus | 25 | import dbus |
837 | 24 | import dbus.service | 26 | import dbus.service |
838 | 25 | import dbus.mainloop.glib | 27 | import dbus.mainloop.glib |
839 | @@ -28,6 +30,11 @@ | |||
840 | 28 | from datetime import datetime, timedelta | 30 | from datetime import datetime, timedelta |
841 | 29 | from gi.repository import GLib | 31 | from gi.repository import GLib |
842 | 30 | 32 | ||
843 | 33 | try: | ||
844 | 34 | from pyupstartvars import * | ||
845 | 35 | except: | ||
846 | 36 | pass | ||
847 | 37 | |||
848 | 31 | VERSION = '0.1' | 38 | VERSION = '0.1' |
849 | 32 | NAME = 'TestUpstart' | 39 | NAME = 'TestUpstart' |
850 | 33 | 40 | ||
851 | @@ -36,10 +43,6 @@ | |||
852 | 36 | SYSTEM_INITCTL = '/sbin/initctl' | 43 | SYSTEM_INITCTL = '/sbin/initctl' |
853 | 37 | SYSTEM_FILE_BRIDGE = '/sbin/upstart-file-bridge' | 44 | SYSTEM_FILE_BRIDGE = '/sbin/upstart-file-bridge' |
854 | 38 | 45 | ||
855 | 39 | BUILT_UPSTART = '@built_init_binary@' | ||
856 | 40 | BUILT_INITCTL = '@built_initctl_binary@' | ||
857 | 41 | BUILT_FILE_BRIDGE = '@built_file_bridge_binary@' | ||
858 | 42 | |||
859 | 43 | UPSTART_SESSION_ENV = 'UPSTART_SESSION' | 46 | UPSTART_SESSION_ENV = 'UPSTART_SESSION' |
860 | 44 | USE_SYSTEM_BINARIES_ENV = 'UPSTART_TEST_USE_SYSTEM_BINARIES' | 47 | USE_SYSTEM_BINARIES_ENV = 'UPSTART_TEST_USE_SYSTEM_BINARIES' |
861 | 45 | 48 | ||
862 | @@ -64,6 +67,10 @@ | |||
863 | 64 | OBJECT_PATH = '/com/ubuntu/Upstart' | 67 | OBJECT_PATH = '/com/ubuntu/Upstart' |
864 | 65 | FREEDESKTOP_PROPERTIES = 'org.freedesktop.DBus.Properties' | 68 | FREEDESKTOP_PROPERTIES = 'org.freedesktop.DBus.Properties' |
865 | 66 | 69 | ||
866 | 70 | CGM_SOCKET = 'unix:path=/sys/fs/cgroup/cgmanager/sock' | ||
867 | 71 | CGM_INTERFACE_NAME = 'org.linuxcontainers.cgmanager0_0' | ||
868 | 72 | CGM_OBJECT_PATH = '/org/linuxcontainers/cgmanager' | ||
869 | 73 | |||
870 | 67 | # Maximum number of seconds to wait for Upstart to detect a new job | 74 | # Maximum number of seconds to wait for Upstart to detect a new job |
871 | 68 | # has been created | 75 | # has been created |
872 | 69 | JOB_WAIT_SECS = 5 | 76 | JOB_WAIT_SECS = 5 |
873 | @@ -83,6 +90,7 @@ | |||
874 | 83 | 90 | ||
875 | 84 | #--------------------------------------------------------------------- | 91 | #--------------------------------------------------------------------- |
876 | 85 | 92 | ||
877 | 93 | |||
878 | 86 | def get_init(): | 94 | def get_init(): |
879 | 87 | """ | 95 | """ |
880 | 88 | Return full path to an appropriate init daemon binary. | 96 | Return full path to an appropriate init daemon binary. |
881 | @@ -95,6 +103,7 @@ | |||
882 | 95 | assert (os.path.exists(binary)) | 103 | assert (os.path.exists(binary)) |
883 | 96 | return binary | 104 | return binary |
884 | 97 | 105 | ||
885 | 106 | |||
886 | 98 | def get_initctl(): | 107 | def get_initctl(): |
887 | 99 | """ | 108 | """ |
888 | 100 | Return full path to an appropriate initctl binary. | 109 | Return full path to an appropriate initctl binary. |
889 | @@ -107,6 +116,7 @@ | |||
890 | 107 | assert (os.path.exists(binary)) | 116 | assert (os.path.exists(binary)) |
891 | 108 | return binary | 117 | return binary |
892 | 109 | 118 | ||
893 | 119 | |||
894 | 110 | def get_file_bridge(): | 120 | def get_file_bridge(): |
895 | 111 | """ | 121 | """ |
896 | 112 | Return full path to an appropriate upstart-file-bridge binary. | 122 | Return full path to an appropriate upstart-file-bridge binary. |
897 | @@ -119,6 +129,7 @@ | |||
898 | 119 | assert (os.path.exists(binary)) | 129 | assert (os.path.exists(binary)) |
899 | 120 | return binary | 130 | return binary |
900 | 121 | 131 | ||
901 | 132 | |||
902 | 122 | def dbus_encode(str): | 133 | def dbus_encode(str): |
903 | 123 | """ | 134 | """ |
904 | 124 | Simulate nih_dbus_path() which Upstart uses to convert | 135 | Simulate nih_dbus_path() which Upstart uses to convert |
905 | @@ -195,6 +206,13 @@ | |||
906 | 195 | pass | 206 | pass |
907 | 196 | 207 | ||
908 | 197 | 208 | ||
909 | 209 | class CGMException(Exception): | ||
910 | 210 | """ | ||
911 | 211 | An Upstart Exception. | ||
912 | 212 | """ | ||
913 | 213 | pass | ||
914 | 214 | |||
915 | 215 | |||
916 | 198 | class Upstart: | 216 | class Upstart: |
917 | 199 | """ | 217 | """ |
918 | 200 | Upstart Class. | 218 | Upstart Class. |
919 | @@ -972,6 +990,7 @@ | |||
920 | 972 | self.stop() | 990 | self.stop() |
921 | 973 | self.logfile.destroy() | 991 | self.logfile.destroy() |
922 | 974 | 992 | ||
923 | 993 | |||
924 | 975 | class SystemInit(Upstart): | 994 | class SystemInit(Upstart): |
925 | 976 | 995 | ||
926 | 977 | def __init__(self): | 996 | def __init__(self): |
927 | @@ -991,6 +1010,59 @@ | |||
928 | 991 | os.system('telinit u') | 1010 | os.system('telinit u') |
929 | 992 | 1011 | ||
930 | 993 | 1012 | ||
931 | 1013 | class CGManager(): | ||
932 | 1014 | |||
933 | 1015 | def __init__(self, socket=CGM_SOCKET): | ||
934 | 1016 | self.socket = socket | ||
935 | 1017 | self.connection = None | ||
936 | 1018 | self.remote_object = None | ||
937 | 1019 | self.proxy = None | ||
938 | 1020 | self.connect() | ||
939 | 1021 | with open('/proc/cgroups') as f: | ||
940 | 1022 | self.all_cgroups = [l.split('\t')[0] for l in | ||
941 | 1023 | f.readlines() if not l.startswith('#')] | ||
942 | 1024 | |||
943 | 1025 | def connect(self, force=False): | ||
944 | 1026 | """ | ||
945 | 1027 | Connect to CGManager. | ||
946 | 1028 | |||
947 | 1029 | @force: if True, connect regardless of whether already | ||
948 | 1030 | connected. | ||
949 | 1031 | |||
950 | 1032 | Notes: | ||
951 | 1033 | - Raises an CGMException() if already connected. | ||
952 | 1034 | """ | ||
953 | 1035 | if self.connection and not force: | ||
954 | 1036 | raise CGMException('Already connected') | ||
955 | 1037 | |||
956 | 1038 | # Create appropriate D-Bus connection | ||
957 | 1039 | self.connection = dbus.connection.Connection(self.socket) | ||
958 | 1040 | self.remote_object = self.connection.get_object( | ||
959 | 1041 | object_path=CGM_OBJECT_PATH) | ||
960 | 1042 | self.proxy = dbus.Interface(self.remote_object, CGM_INTERFACE_NAME) | ||
961 | 1043 | self.Ping(0) | ||
962 | 1044 | |||
963 | 1045 | def api_version(self): | ||
964 | 1046 | """ | ||
965 | 1047 | Determine api-version of running CGManager. | ||
966 | 1048 | |||
967 | 1049 | Returns: API Version as a string. | ||
968 | 1050 | |||
969 | 1051 | """ | ||
970 | 1052 | properties = dbus.Interface(self.remote_object, FREEDESKTOP_PROPERTIES) | ||
971 | 1053 | return int(properties.Get(CGM_INTERFACE_NAME, 'api_version')) | ||
972 | 1054 | |||
973 | 1055 | def setup_sandbox(self, sandbox, pid): | ||
974 | 1056 | for controller in self.all_cgroups: | ||
975 | 1057 | if sandbox: | ||
976 | 1058 | self.Create(controller, sandbox) | ||
977 | 1059 | self.RemoveOnEmpty(controller, sandbox) | ||
978 | 1060 | self.MovePid(controller, sandbox, pid) | ||
979 | 1061 | |||
980 | 1062 | def __getattr__(self, name): | ||
981 | 1063 | return getattr(self.proxy, name) | ||
982 | 1064 | |||
983 | 1065 | |||
984 | 994 | class SessionInit(Upstart): | 1066 | class SessionInit(Upstart): |
985 | 995 | """ | 1067 | """ |
986 | 996 | Create a new Upstart Session or join an existing one. | 1068 | Create a new Upstart Session or join an existing one. |
987 | @@ -1164,3 +1236,29 @@ | |||
988 | 1164 | 1236 | ||
989 | 1165 | self.logger.debug("Restarting Session Init") | 1237 | self.logger.debug("Restarting Session Init") |
990 | 1166 | self.proxy.Restart() | 1238 | self.proxy.Restart() |
991 | 1239 | |||
992 | 1240 | def main(): | ||
993 | 1241 | kwargs = {} | ||
994 | 1242 | format = \ | ||
995 | 1243 | '%(asctime)s:' \ | ||
996 | 1244 | '%(filename)s:' \ | ||
997 | 1245 | '%(name)s:' \ | ||
998 | 1246 | '%(funcName)s:' \ | ||
999 | 1247 | '%(levelname)s:' \ | ||
1000 | 1248 | '%(message)s' | ||
1001 | 1249 | |||
1002 | 1250 | kwargs['format'] = format | ||
1003 | 1251 | |||
1004 | 1252 | # We want to see what's happening | ||
1005 | 1253 | kwargs['level'] = logging.DEBUG | ||
1006 | 1254 | |||
1007 | 1255 | logging.basicConfig(**kwargs) | ||
1008 | 1256 | |||
1009 | 1257 | unittest.main( | ||
1010 | 1258 | testRunner=unittest.TextTestRunner( | ||
1011 | 1259 | stream=sys.stdout, | ||
1012 | 1260 | verbosity=2 | ||
1013 | 1261 | ) | ||
1014 | 1262 | ) | ||
1015 | 1263 | |||
1016 | 1264 | sys.exit(0) | ||
1017 | 1167 | 1265 | ||
1018 | === added file 'scripts/tests/test_pyupstart_cgmanager.py' | |||
1019 | --- scripts/tests/test_pyupstart_cgmanager.py 1970-01-01 00:00:00 +0000 | |||
1020 | +++ scripts/tests/test_pyupstart_cgmanager.py 2014-04-08 20:51:56 +0000 | |||
1021 | @@ -0,0 +1,63 @@ | |||
1022 | 1 | #!/usr/bin/python3 | ||
1023 | 2 | # -*- coding: utf-8 -*- | ||
1024 | 3 | #--------------------------------------------------------------------- | ||
1025 | 4 | # Copyright © 2014 Canonical Ltd. | ||
1026 | 5 | # | ||
1027 | 6 | # Author: Dimitri John Ledkov <xnox@ubuntu.com> | ||
1028 | 7 | # | ||
1029 | 8 | # This program is free software; you can redistribute it and/or modify | ||
1030 | 9 | # it under the terms of the GNU General Public License version 2, as | ||
1031 | 10 | # published by the Free Software Foundation. | ||
1032 | 11 | # | ||
1033 | 12 | # This program is distributed in the hope that it will be useful, | ||
1034 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1035 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1036 | 15 | # GNU General Public License for more details. | ||
1037 | 16 | # | ||
1038 | 17 | # You should have received a copy of the GNU General Public License along | ||
1039 | 18 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
1040 | 19 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
1041 | 20 | #--------------------------------------------------------------------- | ||
1042 | 21 | |||
1043 | 22 | #--------------------------------------------------------------------- | ||
1044 | 23 | # Description: unit-tests for the CGManager() object | ||
1045 | 24 | # | ||
1046 | 25 | #--------------------------------------------------------------------- | ||
1047 | 26 | |||
1048 | 27 | import os | ||
1049 | 28 | import sys | ||
1050 | 29 | import tempfile | ||
1051 | 30 | import unittest | ||
1052 | 31 | |||
1053 | 32 | base_dir = os.path.abspath(os.path.dirname(__file__)) | ||
1054 | 33 | module_dir = os.path.normpath(os.path.realpath(base_dir + os.sep + '..')) | ||
1055 | 34 | |||
1056 | 35 | # top-level unpacked source directory | ||
1057 | 36 | top_srcdir = os.path.normpath(os.path.realpath(module_dir + os.sep + '..')) | ||
1058 | 37 | |||
1059 | 38 | # Tell Python where the uninstalled module lives in the source tree | ||
1060 | 39 | sys.path.append(module_dir) | ||
1061 | 40 | from pyupstart import * | ||
1062 | 41 | |||
1063 | 42 | class TestCGManager(unittest.TestCase): | ||
1064 | 43 | def setUp(self): | ||
1065 | 44 | self.cg = CGManager() | ||
1066 | 45 | self.tempfile = tempfile.NamedTemporaryFile(prefix='TestCGManager') | ||
1067 | 46 | self.tempname = os.path.split(self.tempfile.name)[-1] | ||
1068 | 47 | |||
1069 | 48 | def test_init(self): | ||
1070 | 49 | self.assertRaises(CGMException, self.cg.connect, ()) | ||
1071 | 50 | |||
1072 | 51 | def test_api_version(self): | ||
1073 | 52 | self.assertEqual(self.cg.api_version(), 2) | ||
1074 | 53 | |||
1075 | 54 | def test_setup_sandbox(self): | ||
1076 | 55 | pid = os.getpid() | ||
1077 | 56 | self.cg.setup_sandbox(self.tempname, pid) | ||
1078 | 57 | with open('/proc/self/cgroup') as f: | ||
1079 | 58 | missing = [l for l in f.readlines() if self.tempname not in l] | ||
1080 | 59 | self.assertEqual(len(missing), 1) | ||
1081 | 60 | self.assertTrue("name=systemd" in missing[0]) | ||
1082 | 61 | |||
1083 | 62 | if __name__ == '__main__': | ||
1084 | 63 | main() | ||
1085 | 0 | 64 | ||
1086 | === modified file 'scripts/tests/test_pyupstart_session_init.py' | |||
1087 | --- scripts/tests/test_pyupstart_session_init.py 2014-03-05 10:41:18 +0000 | |||
1088 | +++ scripts/tests/test_pyupstart_session_init.py 2014-04-08 20:51:56 +0000 | |||
1089 | @@ -539,31 +539,5 @@ | |||
1090 | 539 | self.assertEqual(path, full_job_path) | 539 | self.assertEqual(path, full_job_path) |
1091 | 540 | self.stop_session_init() | 540 | self.stop_session_init() |
1092 | 541 | 541 | ||
1093 | 542 | def main(): | ||
1094 | 543 | kwargs = {} | ||
1095 | 544 | format = \ | ||
1096 | 545 | '%(asctime)s:' \ | ||
1097 | 546 | '%(filename)s:' \ | ||
1098 | 547 | '%(name)s:' \ | ||
1099 | 548 | '%(funcName)s:' \ | ||
1100 | 549 | '%(levelname)s:' \ | ||
1101 | 550 | '%(message)s' | ||
1102 | 551 | |||
1103 | 552 | kwargs['format'] = format | ||
1104 | 553 | |||
1105 | 554 | # We want to see what's happening | ||
1106 | 555 | kwargs['level'] = logging.DEBUG | ||
1107 | 556 | |||
1108 | 557 | logging.basicConfig(**kwargs) | ||
1109 | 558 | |||
1110 | 559 | unittest.main( | ||
1111 | 560 | testRunner=unittest.TextTestRunner( | ||
1112 | 561 | stream=sys.stdout, | ||
1113 | 562 | verbosity=2 | ||
1114 | 563 | ) | ||
1115 | 564 | ) | ||
1116 | 565 | |||
1117 | 566 | sys.exit(0) | ||
1118 | 567 | |||
1119 | 568 | if __name__ == '__main__': | 542 | if __name__ == '__main__': |
1120 | 569 | main() | 543 | main() |
1121 | 570 | 544 | ||
1122 | === added file 'scripts/tests/test_pyupstart_system_cgroups.py' | |||
1123 | --- scripts/tests/test_pyupstart_system_cgroups.py 1970-01-01 00:00:00 +0000 | |||
1124 | +++ scripts/tests/test_pyupstart_system_cgroups.py 2014-04-08 20:51:56 +0000 | |||
1125 | @@ -0,0 +1,73 @@ | |||
1126 | 1 | #!/usr/bin/python3 | ||
1127 | 2 | # -*- coding: utf-8 -*- | ||
1128 | 3 | #--------------------------------------------------------------------- | ||
1129 | 4 | # Copyright © 2014 Canonical Ltd. | ||
1130 | 5 | # | ||
1131 | 6 | # Author: Dimitri John Ledkov <xnox@ubuntu.com> | ||
1132 | 7 | # | ||
1133 | 8 | # This program is free software; you can redistribute it and/or modify | ||
1134 | 9 | # it under the terms of the GNU General Public License version 2, as | ||
1135 | 10 | # published by the Free Software Foundation. | ||
1136 | 11 | # | ||
1137 | 12 | # This program is distributed in the hope that it will be useful, | ||
1138 | 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1139 | 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1140 | 15 | # GNU General Public License for more details. | ||
1141 | 16 | # | ||
1142 | 17 | # You should have received a copy of the GNU General Public License along | ||
1143 | 18 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
1144 | 19 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
1145 | 20 | #--------------------------------------------------------------------- | ||
1146 | 21 | |||
1147 | 22 | #--------------------------------------------------------------------- | ||
1148 | 23 | # Description: unit-tests for the CGManager() object | ||
1149 | 24 | # | ||
1150 | 25 | #--------------------------------------------------------------------- | ||
1151 | 26 | |||
1152 | 27 | import os | ||
1153 | 28 | import sys | ||
1154 | 29 | import tempfile | ||
1155 | 30 | import unittest | ||
1156 | 31 | |||
1157 | 32 | base_dir = os.path.abspath(os.path.dirname(__file__)) | ||
1158 | 33 | module_dir = os.path.normpath(os.path.realpath(base_dir + os.sep + '..')) | ||
1159 | 34 | |||
1160 | 35 | # top-level unpacked source directory | ||
1161 | 36 | top_srcdir = os.path.normpath(os.path.realpath(module_dir + os.sep + '..')) | ||
1162 | 37 | |||
1163 | 38 | # Tell Python where the uninstalled module lives in the source tree | ||
1164 | 39 | sys.path.append(module_dir) | ||
1165 | 40 | from pyupstart import * | ||
1166 | 41 | from tests.test_pyupstart_system_init import TestSystemUpstart | ||
1167 | 42 | |||
1168 | 43 | class TestSystemCGManager(TestSystemUpstart): | ||
1169 | 44 | def setUp(self): | ||
1170 | 45 | self.cg = CGManager() | ||
1171 | 46 | self.tempfile = tempfile.NamedTemporaryFile(prefix='TestSystemCGManager') | ||
1172 | 47 | self.tempname = os.path.split(self.tempfile.name)[-1] | ||
1173 | 48 | self.cg.setup_sandbox(self.tempname, 1) | ||
1174 | 49 | self.sample_job = [ "cgroup {} {}".format(cgroup, self.tempname) | ||
1175 | 50 | for cgroup in self.cg.all_cgroups ] | ||
1176 | 51 | self.sample_job.append('exec upstart-udev-bridge') | ||
1177 | 52 | super().setUp() | ||
1178 | 53 | |||
1179 | 54 | def test_main(self): | ||
1180 | 55 | job = self.upstart.job_create('main', self.sample_job) | ||
1181 | 56 | job.start(wait=True) | ||
1182 | 57 | self._assert_all_match(job.pids()['main']) | ||
1183 | 58 | |||
1184 | 59 | def test_pre_start(self): | ||
1185 | 60 | self.sample_job.append('pre-start exec cat /proc/self/cgroup') | ||
1186 | 61 | job = self.upstart.job_create('pre-start', self.sample_job) | ||
1187 | 62 | job.start() | ||
1188 | 63 | print(job.logfile_name()) | ||
1189 | 64 | # Kaboom! | ||
1190 | 65 | |||
1191 | 66 | def _assert_all_match(self, pid): | ||
1192 | 67 | for c in self.cg.all_cgroups: | ||
1193 | 68 | self.assertEqual( | ||
1194 | 69 | self.cg.GetPidCgroup(c, pid), | ||
1195 | 70 | self.tempname) | ||
1196 | 71 | |||
1197 | 72 | if __name__ == '__main__': | ||
1198 | 73 | main() | ||
1199 | 0 | 74 | ||
1200 | === modified file 'scripts/tests/test_pyupstart_system_init.py' | |||
1201 | --- scripts/tests/test_pyupstart_system_init.py 2014-03-10 13:43:50 +0000 | |||
1202 | +++ scripts/tests/test_pyupstart_system_init.py 2014-04-08 20:51:56 +0000 | |||
1203 | @@ -167,31 +167,6 @@ | |||
1204 | 167 | self.upstart.polling_connect(force=True) | 167 | self.upstart.polling_connect(force=True) |
1205 | 168 | self.assertTrue(self.upstart.version()) | 168 | self.assertTrue(self.upstart.version()) |
1206 | 169 | 169 | ||
1207 | 170 | def main(): | ||
1208 | 171 | kwargs = {} | ||
1209 | 172 | format = \ | ||
1210 | 173 | '%(asctime)s:' \ | ||
1211 | 174 | '%(filename)s:' \ | ||
1212 | 175 | '%(name)s:' \ | ||
1213 | 176 | '%(funcName)s:' \ | ||
1214 | 177 | '%(levelname)s:' \ | ||
1215 | 178 | '%(message)s' | ||
1216 | 179 | |||
1217 | 180 | kwargs['format'] = format | ||
1218 | 181 | |||
1219 | 182 | # We want to see what's happening | ||
1220 | 183 | kwargs['level'] = logging.DEBUG | ||
1221 | 184 | |||
1222 | 185 | logging.basicConfig(**kwargs) | ||
1223 | 186 | |||
1224 | 187 | unittest.main( | ||
1225 | 188 | testRunner=unittest.TextTestRunner( | ||
1226 | 189 | stream=sys.stdout, | ||
1227 | 190 | verbosity=2 | ||
1228 | 191 | ) | ||
1229 | 192 | ) | ||
1230 | 193 | |||
1231 | 194 | sys.exit(0) | ||
1232 | 195 | 170 | ||
1233 | 196 | if __name__ == '__main__': | 171 | if __name__ == '__main__': |
1234 | 197 | main() | 172 | main() |
This fixes a bunch of test_job and test_job_process test suite failures. Mostly it's adjusting state expectations in the test-suite, but also fixes JOB_PRE_STOP_SETUP -> JOB_PRE_STOP transition and updates the asserts in the job_process (once we are in the process failure handler, the relevant process has completed the setup and thus is in the "full" state, as far as I understand it)