int retval;
int i;
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
long long int last_key_time = 0;
int repeat_count = 0;
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
/*
- * Copyright (c) 2008, 2009 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <limits.h>
#include <stdlib.h>
#include "util.h"
-#include "vlog.h"
/* Given the GNU-style long options in 'options', returns a string that may be
* passed to getopt() with the corresponding short options. The caller is
ovs_fatal(0, "unknown command '%s'; use --help for help", argv[0]);
}
+\f
+/* Process title. */
+
+#ifdef __linux__
+static char *argv_start; /* Start of command-line arguments in memory. */
+static size_t argv_size; /* Number of bytes of command-line arguments. */
+static char *saved_proctitle; /* Saved command-line arguments. */
+
+/* Prepares the process so that proctitle_set() can later succeed.
+ *
+ * This modifies the argv[] array so that it no longer points into the memory
+ * that it originally does. Later, proctitle_set() might overwrite that
+ * memory. That means that this function should be called before anything else
+ * that accesses the process's argv[] array. Ideally, it should be called
+ * before anything else, period, at the very beginning of program
+ * execution. */
+void
+proctitle_init(int argc, char **argv)
+{
+ int i;
+
+ if (!argc || !argv[0]) {
+ /* This situation should never occur, but... */
+ return;
+ }
+
+ /* Specialized version of first loop iteration below. */
+ argv_start = argv[0];
+ argv_size = strlen(argv[0]) + 1;
+ argv[0] = xstrdup(argv[0]);
+
+ for (i = 1; i < argc; i++) {
+ size_t size = strlen(argv[i]) + 1;
+
+ /* Add (argv[i], strlen(argv[i])+1) to (argv_start, argv_size). */
+ if (argv[i] + size == argv_start) {
+ /* Arguments grow downward in memory. */
+ argv_start -= size;
+ argv_size += size;
+ } else if (argv[i] == argv_start + argv_size) {
+ /* Arguments grow upward in memory. */
+ argv_size += size;
+ } else {
+ /* Arguments not contiguous. (Is this really Linux?) */
+ }
+
+ /* Copy out the old argument so we can reuse the space. */
+ argv[i] = xstrdup(argv[i]);
+ }
+}
+
+/* Changes the name of the process, as shown by "ps", to 'format', which is
+ * formatted as if by printf(). */
+void
+proctitle_set(const char *format, ...)
+{
+ va_list args;
+ int n;
+
+ if (!argv_start || argv_size < 8) {
+ return;
+ }
+
+ if (!saved_proctitle) {
+ saved_proctitle = xmemdup(argv_start, argv_size);
+ }
+
+ va_start(args, format);
+ n = vsnprintf(argv_start, argv_size, format, args);
+ if (n >= argv_size) {
+ /* The name is too long, so add an ellipsis at the end. */
+ strcpy(&argv_start[argv_size - 4], "...");
+ } else {
+ /* Fill the extra space with null bytes, so that trailing bytes don't
+ * show up in the command line. */
+ memset(&argv_start[n], '\0', argv_size - n);
+ }
+ va_end(args);
+}
+
+/* Restores the process's original command line, as seen by "ps". */
+void
+proctitle_restore(void)
+{
+ if (saved_proctitle) {
+ memcpy(argv_start, saved_proctitle, argv_size);
+ free(saved_proctitle);
+ saved_proctitle = NULL;
+ }
+}
+#else /* !__linux__ */
+/* Stubs that don't do anything on non-Linux systems. */
+
+void
+proctitle_init(int argc UNUSED, char **argv UNUSED)
+{
+}
+
+void
+proctitle_set(const char *format UNUSED, ...)
+{
+}
+
+void
+proctitle_restore(void)
+{
+}
+#endif /* !__linux__ */
/*
- * Copyright (c) 2008, 2009 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
char *long_options_to_short_options(const struct option *options);
void run_command(int argc, char *argv[], const struct command[]);
+void proctitle_init(int argc, char **argv);
+void proctitle_set(const char *, ...)
+ PRINTF_FORMAT(1, 2);
+void proctitle_restore(void);
+
#endif /* command-line.h */
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
+#include "command-line.h"
#include "fatal-signal.h"
#include "dirs.h"
#include "lockfile.h"
/* XXX Should limit the rate at which we restart the daemon. */
/* XXX Should log daemon's stderr output at startup time. */
const char *saved_program_name;
+ char *status_msg;
saved_program_name = program_name;
program_name = xasprintf("monitor(%s)", program_name);
+ status_msg = xstrdup("healthy");
for (;;) {
int retval;
int status;
+ proctitle_set("%s: monitoring pid %lu (%s)",
+ saved_program_name, (unsigned long int) daemon_pid,
+ status_msg);
+
do {
retval = waitpid(daemon_pid, &status, 0);
} while (retval == -1 && errno == EINTR);
if (retval == -1) {
ovs_fatal(errno, "waitpid failed");
} else if (retval == daemon_pid) {
- char *status_msg = process_status_msg(status);
- if (should_restart(status)) {
- VLOG_ERR("%s daemon died unexpectedly (%s), restarting",
- saved_program_name, status_msg);
- free(status_msg);
+ char *s = process_status_msg(status);
+ free(status_msg);
+ status_msg = xasprintf("pid %lu died, %s",
+ (unsigned long int) daemon_pid, s);
+ free(s);
+ if (should_restart(status)) {
+ VLOG_ERR("%s, restarting", status_msg);
daemon_pid = fork_and_wait_for_startup(&daemonize_fd);
if (!daemon_pid) {
break;
}
} else {
- VLOG_INFO("%s daemon exited normally (%s), exiting",
- saved_program_name, status_msg);
+ VLOG_INFO("%s, exiting", status_msg);
exit(0);
}
}
}
/* Running in new daemon process. */
+ proctitle_restore();
free((char *) program_name);
program_name = saved_program_name;
}
int
main(int argc, char *argv[])
{
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
bool exiting;
int retval;
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
/*
- * Copyright (c) 2009 Nicira Networks.
+ * Copyright (c) 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
int
main(int argc, char *argv[])
{
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
#include <sys/types.h>
#include <unistd.h>
+#include "command-line.h"
#include "daemon.h"
#include "util.h"
int
main(int argc, char *argv[])
{
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
int retval;
int i;
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
int retval;
int i;
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
int error;
struct netflow_options nf_options;
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
struct ovsdb_idl *idl;
int retval;
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();
unsigned int idl_seqno;
int retval;
+ proctitle_init(argc, argv);
set_program_name(argv[0]);
time_init();
vlog_init();