3
* Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
4
* Copyright © 2012 Canonical Ltd.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2, as
8
* published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License along
16
* with this program; if not, write to the Free Software Foundation, Inc.,
17
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
#include "../lxc/lxclock.h"
23
#include <sys/types.h>
27
#define mycontainername "lxctest.sem"
28
#define TIMEOUT_SECS 3
33
void timeouthandler(int sig)
37
kill(pid_to_kill, SIGTERM);
40
void starttimer(int secs)
43
signal(SIGALRM, timeouthandler);
49
signal(SIGALRM, NULL);
52
int test_one_lock(sem_t *lock)
55
starttimer(TIMEOUT_SECS);
56
ret = lxclock(lock, TIMEOUT_SECS*2);
63
fprintf(stderr, "%d: timed out waiting for lock\n", __LINE__);
65
fprintf(stderr, "%d: failed to get single lock\n", __LINE__);
70
* get one lock. Fork a second task to try to get a second lock,
71
* with infinite timeout. If our alarm hits, kill the second
72
* task. If second task does not
74
int test_two_locks(sem_t *lock)
79
ret = lxclock(lock, 1);
81
fprintf(stderr, "%d: Error getting first lock\n", __LINE__);
86
if (pid_to_kill < 0) {
87
fprintf(stderr, "%d: Failed to fork\n", __LINE__);
92
if (pid_to_kill == 0) { // child
93
ret = lxclock(lock, TIMEOUT_SECS*2);
98
fprintf(stderr, "%d: child, was not able to get lock\n", __LINE__);
101
starttimer(TIMEOUT_SECS);
102
waitpid(pid_to_kill, &status, 0);
104
if (WIFEXITED(status)) {
105
// child exited normally - timeout didn't kill it
106
if (WEXITSTATUS(status) == 0)
107
fprintf(stderr, "%d: child was able to get the lock\n", __LINE__);
109
fprintf(stderr, "%d: child timed out too early\n", __LINE__);
118
* get one lock. try to get second lock, but asking for timeout. If
119
* should return failure. If our own alarm, set at twice the lock
120
* request's timeout, hits, then lxclock() did not properly time out.
122
int test_with_timeout(sem_t *lock)
127
ret = lxclock(lock, 0);
129
fprintf(stderr, "%d: Error getting first lock\n", __LINE__);
132
pid_to_kill = fork();
133
if (pid_to_kill < 0) {
134
fprintf(stderr, "%d: Error on fork\n", __LINE__);
138
if (pid_to_kill == 0) {
139
ret = lxclock(lock, TIMEOUT_SECS);
146
starttimer(TIMEOUT_SECS * 2);
147
waitpid(pid_to_kill, &status, 0);
149
if (!WIFEXITED(status)) {
150
fprintf(stderr, "%d: lxclock did not honor its timeout\n", __LINE__);
154
if (WEXITSTATUS(status) == 0) {
155
fprintf(stderr, "%d: child was able to get lock, should have failed with timeout\n", __LINE__);
162
int main(int argc, char *argv[])
167
lock = lxc_newlock(NULL);
169
fprintf(stderr, "%d: failed to get unnamed lock\n", __LINE__);
172
ret = lxclock(lock, 0);
174
fprintf(stderr, "%d: failed to take unnamed lock (%d)\n", __LINE__, ret);
178
ret = lxcunlock(lock);
180
fprintf(stderr, "%d: failed to put unnamed lock (%d)\n", __LINE__, ret);
187
lock = lxc_newlock(mycontainername);
189
fprintf(stderr, "%d: failed to get lock\n", __LINE__);
192
r = sem_getvalue(lock, &sval);
194
fprintf(stderr, "%d: sem value at start is %d\n", __LINE__, sval);
196
fprintf(stderr, "%d: failed to get initial value\n", __LINE__);
199
ret = test_one_lock(lock);
201
fprintf(stderr, "%d: test failed\n", __LINE__);
204
r = sem_getvalue(lock, &sval);
206
fprintf(stderr, "%d: sem value is %d\n", __LINE__, sval);
208
fprintf(stderr, "%d: failed to get sem value\n", __LINE__);
211
ret = test_two_locks(lock);
213
fprintf(stderr, "%d: test failed\n", __LINE__);
216
r = sem_getvalue(lock, &sval);
218
fprintf(stderr, "%d: sem value is %d\n", __LINE__, sval);
220
fprintf(stderr, "%d: failed to get value\n", __LINE__);
223
ret = test_with_timeout(lock);
225
fprintf(stderr, "%d: test failed\n", __LINE__);
228
r = sem_getvalue(lock, &sval);
230
fprintf(stderr, "%d: sem value is %d\n", __LINE__, sval);
232
fprintf(stderr, "%d: failed to get value\n", __LINE__);
235
fprintf(stderr, "all tests passed\n");