72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber/* liblxcapi
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber *
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * Copyright © 2012 Serge Hallyn <serge.hallyn@ubuntu.com>.
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * Copyright © 2012 Canonical Ltd.
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber *
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * This program is free software; you can redistribute it and/or modify
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * it under the terms of the GNU General Public License version 2, as
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * published by the Free Software Foundation.
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber *
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * This program is distributed in the hope that it will be useful,
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * but WITHOUT ANY WARRANTY; without even the implied warranty of
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * GNU General Public License for more details.
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber *
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * You should have received a copy of the GNU General Public License along
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * with this program; if not, write to the Free Software Foundation, Inc.,
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber */
f2363e38d07db2ad4796b5580b95e3665ed34a88S.Çağlar Onur#include "lxc/lxclock.h"
061ba5d071e4c2b4bfe76c84875bc29cc5334c27Stéphane Graber#include "config.h"
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber#include <unistd.h>
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber#include <signal.h>
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber#include <stdio.h>
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber#include <sys/types.h>
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber#include <sys/wait.h>
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber#include <stdlib.h>
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber#define mycontainername "lxctest.sem"
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber#define TIMEOUT_SECS 3
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
0b98289ef95e83fcd493ba6688e57aa8b4fb53f7Andrey Mazostatic void test_two_locks(void)
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber{
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn struct lxc_lock *l;
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn pid_t pid;
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn int ret, status;
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn int p[2];
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn char c;
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (pipe(p) < 0)
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if ((pid = fork()) < 0)
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (pid == 0) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (read(p[0], &c, 1) < 0) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn perror("read");
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn l = lxc_newlock("/tmp", "lxctest-sem");
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (!l) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn fprintf(stderr, "%d: child: failed to create lock\n", __LINE__);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (lxclock(l, 0) < 0) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn fprintf(stderr, "%d: child: failed to grab lock\n", __LINE__);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn fprintf(stderr, "%d: child: grabbed lock\n", __LINE__);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(0);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn l = lxc_newlock("/tmp", "lxctest-sem");
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (!l) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn fprintf(stderr, "%d: failed to create lock\n", __LINE__);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (lxclock(l, 0) < 0) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn fprintf(stderr, "%d; failed to get lock\n", __LINE__);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber exit(1);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber }
9f3d75a0ca34c78f94227a59905fbd7b59355826Stéphane Graber if (write(p[1], "a", 1) < 0) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn perror("write");
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn sleep(3);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn ret = waitpid(pid, &status, WNOHANG);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (ret == pid) { // task exited
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (WIFEXITED(status)) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn printf("%d exited normally with exit code %d\n", pid,
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn WEXITSTATUS(status));
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (WEXITSTATUS(status) == 0)
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn } else
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn printf("%d did not exit normally\n", pid);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn return;
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn } else if (ret < 0) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn perror("waitpid");
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn kill(pid, SIGKILL);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn wait(&status);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn close(p[1]);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn close(p[0]);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn lxcunlock(l);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn lxc_putlock(l);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber}
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graberint main(int argc, char *argv[])
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber{
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn int ret;
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn struct lxc_lock *lock;
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn lock = lxc_newlock(NULL, NULL);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (!lock) {
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber fprintf(stderr, "%d: failed to get unnamed lock\n", __LINE__);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn ret = lxclock(lock, 0);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (ret) {
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber fprintf(stderr, "%d: failed to take unnamed lock (%d)\n", __LINE__, ret);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn }
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn ret = lxcunlock(lock);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (ret) {
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber fprintf(stderr, "%d: failed to put unnamed lock (%d)\n", __LINE__, ret);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber exit(1);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn lxc_putlock(lock);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn lock = lxc_newlock("/var/lib/lxc", mycontainername);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber if (!lock) {
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber fprintf(stderr, "%d: failed to get lock\n", __LINE__);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber exit(1);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn struct stat sb;
72cf81f6a3404e35028567db2c99a90406e9c6e6Serge Hallyn char *pathname = RUNTIME_PATH "/lxc/lock/var/lib/lxc/";
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn ret = stat(pathname, &sb);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn if (ret != 0) {
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn fprintf(stderr, "%d: filename %s not created\n", __LINE__,
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn pathname);
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn exit(1);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber }
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn lxc_putlock(lock);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn test_two_locks();
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
df271a59cbfcfbe98fa4bd7af3ae595633539a12Serge Hallyn fprintf(stderr, "all tests passed\n");
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber exit(ret);
72d0e1cb2facaa4b8ba2f15e311d6bb9491badb7Stéphane Graber}