networkd-wait-online.c revision b6b8adbff4b1a67a2fffc2c225f1b083d9e4a69e
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen/***
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen This file is part of systemd.
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen Copyright 2013 Tom Gundersen <teg@jklm.no>
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen systemd is free software; you can redistribute it and/or modify it
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen under the terms of the GNU Lesser General Public License as published by
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen (at your option) any later version.
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen systemd is distributed in the hope that it will be useful, but
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen Lesser General Public License for more details.
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen You should have received a copy of the GNU Lesser General Public License
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen***/
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen#include "sd-event.h"
e1528e085cefce20e93d930a45fce792e32db29aThomas Hindoe Paaboel Andersen#include "event-util.h"
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen#include "sd-daemon.h"
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen#include "sd-network.h"
e1528e085cefce20e93d930a45fce792e32db29aThomas Hindoe Paaboel Andersen#include "network-util.h"
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen#include "util.h"
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersenstatic bool all_configured(void) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen _cleanup_free_ unsigned *indices = NULL;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen bool one_ready = false;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen int r, n, i;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen n = sd_network_get_ifindices(&indices);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (n <= 0)
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen return false;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen for (i = 0; i < n; i++) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen _cleanup_free_ char *state = NULL;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen r = sd_network_get_link_state(indices[i], &state);
cb6fa44cb5411ed574f14109ee862ff663ab0a36Tom Gundersen if (r == -EUNATCH)
cb6fa44cb5411ed574f14109ee862ff663ab0a36Tom Gundersen continue;
cb6fa44cb5411ed574f14109ee862ff663ab0a36Tom Gundersen if (r < 0 || !streq(state, "configured"))
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen return false;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
cb6fa44cb5411ed574f14109ee862ff663ab0a36Tom Gundersen one_ready = true;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
cb6fa44cb5411ed574f14109ee862ff663ab0a36Tom Gundersen return one_ready;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen}
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersenstatic int event_handler(sd_event_source *s, int fd, uint32_t revents,
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen void *userdata) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen sd_event *event = userdata;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen assert(event);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (all_configured())
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen sd_event_exit(event, 0);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen return 1;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen}
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersenint main(int argc, char *argv[]) {
e1528e085cefce20e93d930a45fce792e32db29aThomas Hindoe Paaboel Andersen _cleanup_event_unref_ sd_event *event = NULL;
e1528e085cefce20e93d930a45fce792e32db29aThomas Hindoe Paaboel Andersen _cleanup_event_source_unref_ sd_event_source *event_source = NULL;
e1528e085cefce20e93d930a45fce792e32db29aThomas Hindoe Paaboel Andersen _cleanup_network_monitor_unref_ sd_network_monitor *monitor = NULL;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen int r, fd, events;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_set_target(LOG_TARGET_AUTO);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_parse_environment();
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_open();
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen umask(0022);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (argc != 1) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_error("This program takes no arguments.");
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen r = -EINVAL;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen goto out;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen r = sd_network_monitor_new(NULL, &monitor);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (r < 0) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_error("Could not create monitor: %s", strerror(-r));
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen goto out;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen r = sd_event_new(&event);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (r < 0) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_error("Could not create event: %s", strerror(-r));
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen goto out;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen fd = sd_network_monitor_get_fd(monitor);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (fd < 0) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_error("Could not get monitor fd: %s", strerror(-r));
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen goto out;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen events = sd_network_monitor_get_events(monitor);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (events < 0) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_error("Could not get monitor events: %s", strerror(-r));
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen goto out;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen r = sd_event_add_io(event, &event_source, fd, events, &event_handler,
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen event);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (r < 0) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_error("Could not add io event source: %s", strerror(-r));
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen goto out;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (all_configured()) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen r = 0;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen goto out;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen sd_notify(false,
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen "READY=1\n"
b6b8adbff4b1a67a2fffc2c225f1b083d9e4a69eTom Gundersen "STATUS=Waiting for network connections...");
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen r = sd_event_loop(event);
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen if (r < 0) {
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen log_error("Event loop failed: %s", strerror(-r));
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen goto out;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen }
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersenout:
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen sd_notify(false,
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen "STATUS=All interfaces configured...");
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
020d59000f86b3d98be763eaee6a2671f0427e46Tom Gundersen}