1f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// Copyright (C) 2011 The Android Open Source Project
2f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner//
3f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// This software is licensed under the terms of the GNU General Public
4f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// License version 2, as published by the Free Software Foundation, and
5f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// may be copied, distributed, and modified under those terms.
6f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner//
7f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// This program is distributed in the hope that it will be useful,
8f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// but WITHOUT ANY WARRANTY; without even the implied warranty of
9f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// GNU General Public License for more details.
11f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
12f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#include "android/log-rotate.h"
13f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#include "net/net.h"
14f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#include "slirp-android/libslirp.h"
15f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#include "sysemu/sysemu.h"
16f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
17f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#include <stdio.h>
18f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
19f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#ifdef _WIN32
20f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
21f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turnervoid qemu_log_rotation_init(void) {
22f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    // Nothing to do on Win32 for now.
23f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner}
24f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
25f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turnervoid qemu_log_rotation_poll(void) {
26f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    // Nothing to do on Win32 for now.
27f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner}
28f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
29f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#else // !_WIN32
30f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
31f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#include <sys/signal.h>
32f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
33f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turnerstatic int rotate_logs_requested = 0;
34f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
35f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turnerstatic void rotate_qemu_logs_handler(int signum) {
36f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  rotate_logs_requested = 1;
37f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner}
38f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
39f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turnervoid qemu_log_rotation_init(void) {
40f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  // Install SIGUSR1 signal handler.
41f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  struct sigaction act;
42f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  sigfillset(&act.sa_mask);
43f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  act.sa_flags = 0;
44f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  act.sa_handler = rotate_qemu_logs_handler;
45f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  if (sigaction(SIGUSR1, &act, NULL) == -1) {
46f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    fprintf(stderr, "Failed to setup SIGUSR1 handler to clear Qemu logs\n");
47f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    exit(-1);
48f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  }
49f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner}
50f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
51f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
52f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// Clears the passed qemu log when the rotate_logs_requested
53f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// is set. We need to clear the logs between the tasks that do not
54f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner// require restarting Qemu.
55f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turnerstatic FILE* rotate_log(FILE* old_log_fd, const char* filename) {
56f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  FILE* new_log_fd = NULL;
57f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  if (old_log_fd) {
58f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    if (fclose(old_log_fd) == -1) {
59f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner      fprintf(stderr, "Cannot close old_log fd\n");
60f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner      exit(errno);
61f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    }
62f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  }
63f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
64f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  if (!filename) {
65f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    fprintf(stderr, "The log filename to be rotated is not provided");
66f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    exit(-1);
67f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  }
68f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
69f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  new_log_fd = fopen(filename , "wb+");
70f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  if (new_log_fd == NULL) {
71f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    fprintf(stderr, "Cannot open the log file: %s for write.\n",
72f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner            filename);
73f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    exit(1);
74f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  }
75f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
76f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner  return new_log_fd;
77f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner}
78f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
79f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
80f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turnervoid qemu_log_rotation_poll(void) {
81f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    if (!rotate_logs_requested)
82f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner        return;
83c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner
84f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    FILE* new_dns_log_fd = rotate_log(get_slirp_dns_log_fd(),
85f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner                                      dns_log_filename);
86f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    FILE* new_drop_log_fd = rotate_log(get_slirp_drop_log_fd(),
87f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner                                       drop_log_filename);
88f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    slirp_dns_log_fd(new_dns_log_fd);
89f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    slirp_drop_log_fd(new_drop_log_fd);
90f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner    rotate_logs_requested = 0;
91f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner}
92f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner
93f9077a88a0b9edca081b0810dde73d108db087a6David 'Digit' Turner#endif  // !_WIN32
94