diff --git a/lib/fluent/command/fluentd.rb b/lib/fluent/command/fluentd.rb index afa26553e5..9c96d8b5e0 100644 --- a/lib/fluent/command/fluentd.rb +++ b/lib/fluent/command/fluentd.rb @@ -20,6 +20,7 @@ require 'fluent/log' require 'fluent/env' require 'fluent/version' +require 'fluent/process' $fluentdargv = Marshal.load(Marshal.dump(ARGV)) @@ -340,6 +341,22 @@ early_exit = true end +begin + running_fluentd_conf = Fluent::ProcessDetector.running_fluentd_conf + puts "DEBUG: config_path: #{opts[:config_path]} running fluent conf: #{running_fluentd_conf}" + if opts[:config_path] and opts[:config_path] == running_fluentd_conf + puts "Error: can't start duplicate Fluentd instance with same #{opts[:config_path]}" + exit 2 + elsif Fluent::DEFAULT_CONFIG_PATH == running_fluentd_conf + puts "Error: can't start duplicate Fluentd instance with default #{Fluent::DEFAULT_CONFIG_PATH}" + exit 2 + end +rescue => e + # e.g. unprivileged access error + puts "Error: already running unprivileged fluentd process exist #{e}" + exit 2 +end + if start_service Service.start(opts[:winsvc_name]) end diff --git a/lib/fluent/process.rb b/lib/fluent/process.rb index f9d40fb41a..a24df250b7 100644 --- a/lib/fluent/process.rb +++ b/lib/fluent/process.rb @@ -15,8 +15,32 @@ # require 'fluent/compat/detach_process_mixin' +require 'fluent/env' module Fluent DetachProcessMixin = Fluent::Compat::DetachProcessMixin DetachMultiProcessMixin = Fluent::Compat::DetachMultiProcessMixin + + class ProcessDetector + def self.running_fluentd_conf + # Detect if same configuration is used + unless Fluent.windows? + IO.popen(["/usr/bin/ps", "-e", "-o", "uid,pid,ppid,cmd"]) do |_io| + _io.readlines.each do |line| + uid, pid, ppid, cmd = line.split(' ', 4) + # skip self and supervisor process + next if Process.pid == pid.to_i or Process.pid == ppid.to_i + if cmd and cmd.chomp.include?("fluentd") and ppid.to_i == 1 + # under systemd control + File.open("/proc/#{pid.to_i}/environ") do |file| + conf = file.read.split("\u0000").select { |entry| entry.include?("FLUENT_CONF") } + return conf.first.split('=').last if conf + end + end + end + end + end + return nil + end + end end