File: daemon.c

package info (click to toggle)
bpfilter 0.5.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,076 kB
  • sloc: ansic: 30,397; sh: 1,383; cpp: 959; python: 495; yacc: 385; lex: 194; makefile: 9
file content (107 lines) | stat: -rw-r--r-- 2,759 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
 */

#include "harness/daemon.h"

#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include "core/helper.h"
#include "core/logger.h"
#include "harness/process.h"

#define _BF_DAEMON_START_TIMEOUT 5
#define _BF_DAEMON_START_SLEEP 100000

int bf_test_daemon_init(struct bf_test_daemon *daemon, const char *path,
                        uint32_t options)
{
    char *args[__builtin_ctz(_BF_TEST_DAEMON_LAST) + 1] = {};
    size_t nargs = 0;

    bf_assert(daemon);

    if (options & BF_TEST_DAEMON_TRANSIENT)
        args[nargs++] = "--transient";
    if (options & BF_TEST_DAEMON_NO_CLI)
        args[nargs++] = "--no-cli";
    if (options & BF_TEST_DAEMON_NO_IPTABLES)
        args[nargs++] = "--no-iptables";
    if (options & BF_TEST_DAEMON_NO_NFTABLES)
        args[nargs++] = "--no-nftables";

    return bf_test_process_init(&daemon->process, path, args, nargs);
}

void bf_test_daemon_clean(struct bf_test_daemon *daemon)
{
    bf_assert(daemon);

    bf_test_process_clean(&daemon->process);
}

int bf_test_daemon_start(struct bf_test_daemon *daemon)
{
    clock_t begin;
    int r;

    bf_assert(daemon);

    r = bf_test_process_start(&daemon->process);
    if (r < 0)
        return bf_err_r(r, "failed to start bpfilter daemon");

    begin = clock();
    while (true) {
        _cleanup_free_ const char *err_buf = NULL;
        int status;

        r = waitpid(daemon->process.pid, &status, WNOHANG);
        if (r < 0)
            return bf_err_r(r, "waitpid() failed on bpfilter process");
        if (r != 0) {
            err_buf = bf_test_process_stderr(&daemon->process);
            return bf_err_r(-ENOENT, "bpfilter process seems to be dead:\n%s\n",
                            err_buf);
        }

        err_buf = bf_test_process_stderr(&daemon->process);
        if (err_buf && strstr(err_buf, "waiting for requests..."))
            break;

        if ((clock() - begin) / CLOCKS_PER_SEC > _BF_DAEMON_START_TIMEOUT) {
            kill(daemon->process.pid, SIGKILL);
            return bf_err_r(
                -EIO, "daemon is not showing up after %d seconds, aborting",
                _BF_DAEMON_START_TIMEOUT);
        }

        // Wait a bit for the daemon to be ready
        usleep(_BF_DAEMON_START_SLEEP);
    }

    return 0;
}

int bf_test_daemon_stop(struct bf_test_daemon *daemon)
{
    int r;

    bf_assert(daemon);

    r = bf_test_process_stop(&daemon->process);
    if (r < 0)
        return bf_err_r(r, "failed to stop bpfilter daemon");

    return r;
}