<command>kea-lfc</command>
<arg><option>-4|-6</option></arg>
<arg><option>-c <replaceable class="parameter">config-file</replaceable></option></arg>
- <arg><option>-p <replaceable class="parameter">previous-file</replaceable></option></arg>
+ <arg><option>-p <replaceable class="parameter">pid-file</replaceable></option></arg>
+ <arg><option>-x <replaceable class="parameter">previous-file</replaceable></option></arg>
<arg><option>-i <replaceable class="parameter">copy-file</replaceable></option></arg>
<arg><option>-o <replaceable class="parameter">output-file</replaceable></option></arg>
<arg><option>-f <replaceable class="parameter">finish-file</replaceable></option></arg>
Configuration file including the configuration for
<command>kea-lfc</command> process. It may also
contain configuration entries for other Kea services.
- Currently <command>kea-lfc</command> gets all of its arguments from
+ Currently <command>kea-lfc</command> gets all of its arguments from
the comamnd line, in the future it will be extended to get some arguments
from the config file.
</para></listitem>
<varlistentry>
<term><option>-p</option></term>
<listitem><para>
- Previous lease file - When <command>kea-lfc</command> starts this
+ PID file - When the <command>kea-lfc</command> process starts
+ it attempts to determine if another instance of the process is
+ already running by examining the pid file. If one is running
+ it aborts the new process. If one isn't running it writes its
+ pid into the pid file.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x</option></term>
+ <listitem><para>
+ Previous or ex lease file - When <command>kea-lfc</command> starts this
is the result of any previous run of <command>kea-lfc</command>.
When <command>kea-lfc</command> finishes it is the result of this run.
If <command>kea-lfc</command> is interrupted before compelting
// PERFORMANCE OF THIS SOFTWARE.
#include <lfc/lfc_controller.h>
+#include <util/pid_file.h>
#include <exceptions/exceptions.h>
#include <config.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
+using namespace isc::util;
namespace isc {
namespace lfc {
void
LFCController::launch(int argc, char* argv[]) {
- try {
- parseArgs(argc, argv);
- } catch (const InvalidUsage& ex) {
- usage(ex.what());
- throw; // rethrow it
- }
+ try {
+ parseArgs(argc, argv);
+ } catch (const InvalidUsage& ex) {
+ usage(ex.what());
+ throw; // rethrow it
+ }
+
+ std::cerr << "Starting lease file cleanup" << std::endl;
+
+ // verify we are the only instance
+ PIDFile pid_file(pid_file_);
+ if (pid_file.check() == true) {
+ // Already running instance, bail out
+ std::cerr << "LFC instance already running" << std::endl;
+ return;
+ }
+
+ // create the pid file for this instance
+ try {
+ pid_file.write();
+ } catch (const PIDFileError& pid_ex) {
+ std::cerr << pid_ex.what() << std::endl;
+ return;
+ }
+
+ // do other work (TBD)
+ std::cerr << "Add code to perform lease cleanup" << std::endl;
+
+ // delete the pid file for this instance
+ pid_file.deleteFile();
+
+ std::cerr << "LFC complete" << std::endl;
}
void
opterr = 0;
optind = 1;
- while ((ch = getopt(argc, argv, ":46dvVp:i:o:c:f:")) != -1) {
+ while ((ch = getopt(argc, argv, ":46dvVp:x:i:o:c:f:")) != -1) {
switch (ch) {
case '4':
// Process DHCPv4 lease files.
break;
case 'p':
- // Previous file name.
+ // PID file name.
+ if (optarg == NULL) {
+ isc_throw(InvalidUsage, "PID file name missing");
+ }
+ pid_file_ = optarg;
+ break;
+
+ case 'x':
+ // Previous (or ex) file name.
if (optarg == NULL) {
- isc_throw(InvalidUsage, "Previous file name missing");
+ isc_throw(InvalidUsage, "Previous (ex) file name missing");
}
previous_file_ = optarg;
break;
break;
case 'f':
- // Output file name.
+ // Finish file name.
if (optarg == NULL) {
isc_throw(InvalidUsage, "Finish file name missing");
}
break;
case 'c':
- // Previous file name.
+ // Configuration file name
if (optarg == NULL) {
isc_throw(InvalidUsage, "Configuration file name missing");
}
isc_throw(InvalidUsage, "DHCP version required");
}
+ if (pid_file_.empty()) {
+ isc_throw(InvalidUsage, "PID file not specified");
+ }
+
if (previous_file_.empty()) {
isc_throw(InvalidUsage, "Previous file not specified");
}
// If verbose is set echo the input information
if (verbose_ == true) {
std::cerr << "Protocol version: DHCPv" << protocol_version_ << std::endl
- << "Previous lease file: " << previous_file_ << std::endl
- << "Copy lease file: " << copy_file_ << std::endl
- << "Output lease file: " << output_file_ << std::endl
- << "Finishn file: " << finish_file_ << std::endl
- << "Config file: " << config_file_ << std::endl
- << "PID file: " << pid_file_ << std::endl;
+ << "Previous or ex lease file: " << previous_file_ << std::endl
+ << "Copy lease file: " << copy_file_ << std::endl
+ << "Output lease file: " << output_file_ << std::endl
+ << "Finishn file: " << finish_file_ << std::endl
+ << "Config file: " << config_file_ << std::endl
+ << "PID file: " << pid_file_ << std::endl;
}
}
}
std::cerr << "Usage: " << lfc_bin_name_ << std::endl
- << " [-4|-6] -p file -i file -o file -f file -c file" << std::endl
+ << " [-4|-6] -p file -x file -i file -o file -f file -c file" << std::endl
<< " -4 or -6 clean a set of v4 or v6 lease files" << std::endl
- << " -p <file>: previous lease file" << std::endl
+ << " -p <file>: PID file" << std::endl
+ << " -x <file>: previous or ex lease file" << std::endl
<< " -i <file>: copy of lease file" << std::endl
<< " -o <file>: output lease file" << std::endl
<< " -f <file>: finish file" << std::endl
/// of the process. Provides the control logic:
///
/// -# parse command line arguments
- /// -# verifies that it is the only instance
- /// -# creates pid file (TBD)
+ /// -# verify that it is the only instance
+ /// -# create pid file
/// -# .... TBD
- /// -# remove pid file (TBD)
+ /// -# remove pid file
/// -# exit to the caller
///
/// @param argc Number of strings in the @c argv array.
return (config_file_);
}
- /// @brief Gets the prevous file name
+ /// @brief Gets the previous file name
///
/// @return Returns the path to the previous file
std::string getPreviousFile() const {
// Verify that standard options can be parsed without error
char* argv[] = { const_cast<char*>("progName"),
const_cast<char*>("-4"),
- const_cast<char*>("-p"),
+ const_cast<char*>("-x"),
const_cast<char*>("previous"),
const_cast<char*>("-i"),
const_cast<char*>("copy"),
const_cast<char*>("-c"),
const_cast<char*>("config"),
const_cast<char*>("-f"),
- const_cast<char*>("finish") };
- int argc = 12;
+ const_cast<char*>("finish"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("pid") };
+ int argc = 14;
ASSERT_NO_THROW(lfc_controller.parseArgs(argc, argv));
EXPECT_EQ(lfc_controller.getCopyFile(), "copy");
EXPECT_EQ(lfc_controller.getOutputFile(), "output");
EXPECT_EQ(lfc_controller.getFinishFile(), "finish");
+ EXPECT_EQ(lfc_controller.getPidFile(), "pid");
}
/// @brief Verify that parsing a correct but incomplete line fails.
// to the parse routine via the argc variable.
char* argv[] = { const_cast<char*>("progName"),
const_cast<char*>("-4"),
- const_cast<char*>("-p"),
+ const_cast<char*>("-x"),
const_cast<char*>("previous"),
const_cast<char*>("-i"),
const_cast<char*>("copy"),
const_cast<char*>("-c"),
const_cast<char*>("config"),
const_cast<char*>("-f"),
- const_cast<char*>("finish") };
+ const_cast<char*>("finish"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("pid") };
int argc = 1;
- for (; argc < 12; ++argc) {
+ for (; argc < 14; ++argc) {
EXPECT_THROW(lfc_controller.parseArgs(argc, argv), InvalidUsage)
<< "test failed for argc = " << argc;
}
char* argv[] = { const_cast<char*>("progName"),
const_cast<char*>("-4"),
- const_cast<char*>("-p"),
+ const_cast<char*>("-x"),
const_cast<char*>("previous"),
const_cast<char*>("-i"),
const_cast<char*>("copy"),
const_cast<char*>("config"),
const_cast<char*>("-f"),
const_cast<char*>("finish"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("pid"),
const_cast<char*>("some"),
const_cast<char*>("other"),
const_cast<char*>("args"),
};
- int argc = 15;
+ int argc = 17;
// We expect an error as we have arguments that aren't valid
EXPECT_THROW(lfc_controller.parseArgs(argc, argv), InvalidUsage);