def start(options)
      begin
        setup_traps
        @state_serializer = Serializer.new(:json)

        # Retrieve instance agent configuration options
        @agent = AgentConfig.agent_options('instance')
        error("No instance agent configured", nil, abort = true) if @agent.empty?

        # Apply agent's ping interval if needed and adjust options to make them consistent
        @options = options
        unless @options[:time_limit]
          if @agent[:ping_interval]
            @options[:time_limit] = @agent[:ping_interval] * PING_INTERVAL_MULTIPLIER
          else
            @options[:time_limit] = DEFAULT_TIME_LIMIT
          end
        end
        @options[:retry_interval] = [@options[:retry_interval], @options[:time_limit]].min
        @options[:max_attempts] = [@options[:max_attempts], @options[:time_limit] / @options[:retry_interval]].min
        @options[:log_path] ||= RightScale::Platform.filesystem.log_dir

        # Attach to log used by instance agent
        Log.program_name = 'RightLink'
        Log.facility = 'user'
        Log.log_to_file_only(@agent[:log_to_file_only])
        Log.init(@agent[:identity], @options[:log_path], :print => true)
        Log.level = :debug if @options[:verbose]
        @logging_enabled = true

        # Catch any egregious eventmachine failures, especially failure to connect to agent with CommandIO
        # Exit even if running as daemon since no longer can trust EM and should get restarted automatically
        EM.error_handler do |e|
          if e.class == RuntimeError && e.message =~ /no connection/
            error("Failed to connect to agent for communication check", nil, abort = false)
            @command_io_failures = (@command_io_failures || 0) + 1
            reenroll! if @command_io_failures > @options[:max_attempts]
          else
            error("Internal checker failure", e, abort = true)
          end
        end

        # note that our Windows service monitors rnac and rchk processes
        # externally and restarts them if they die, so no need to roll our
        # own cross-monitoring on that platform.
        use_agent_watcher = !RightScale::Platform.windows?
        EM.run do
          check
          setup_agent_watcher if use_agent_watcher
        end
        stop_agent_watcher if use_agent_watcher

      rescue SystemExit => e
        raise e
      rescue Exception => e
        error("Failed to run", e, abort = true)
      end
      true
    end
def start(options)
      begin
        setup_traps
        @state_serializer = Serializer.new(:json)

        # Retrieve instance agent configuration options
        @agent = AgentConfig.agent_options('instance')
        error("No instance agent configured", nil, abort = true) if @agent.empty?

        # Apply agent's ping interval if needed and adjust options to make them consistent
        @options = options
        unless @options[:time_limit]
          if @agent[:ping_interval]
            @options[:time_limit] = @agent[:ping_interval] * PING_INTERVAL_MULTIPLIER
          else
            @options[:time_limit] = DEFAULT_TIME_LIMIT
          end
        end
        @options[:retry_interval] = [@options[:retry_interval], @options[:time_limit]].min
        @options[:max_attempts] = [@options[:max_attempts], @options[:time_limit] / @options[:retry_interval]].min
        @options[:log_path] ||= RightScale::Platform.filesystem.log_dir

        # Attach to log used by instance agent
        Log.program_name = 'RightLink'
        Log.facility = 'user'
        Log.log_to_file_only(@agent[:log_to_file_only])
        Log.init(@agent[:identity], @options[:log_path], :print => true)
        Log.level = :debug if @options[:verbose]
        @logging_enabled = true

        # Catch any egregious eventmachine failures, especially failure to connect to agent with CommandIO
        # Exit even if running as daemon since no longer can trust EM and should get restarted automatically
        EM.error_handler do |e|
          if e.class == RuntimeError && e.message =~ /no connection/
            error("Failed to connect to agent for communication check", nil, abort = false)
            @command_io_failures = (@command_io_failures || 0) + 1
            reenroll! if @command_io_failures > @options[:max_attempts]
          else
            error("Internal checker failure", e, abort = true)
          end
        end

        # note that our Windows service monitors rnac and rchk processes
        # externally and restarts them if they die, so no need to roll our
        # own cross-monitoring on that platform.
        use_agent_watcher = !RightScale::Platform.windows?
        EM.run do
          check
          setup_agent_watcher if use_agent_watcher
        end
        stop_agent_watcher if use_agent_watcher

      rescue SystemExit => e
        raise e
      rescue Exception => e
        error("Failed to run", e, abort = true)
      end
      true
    end
Run daemon or run one agent communication check
 If running as a daemon, store pid in same location as agent except suffix the
 agent identity with '-rchk'.

 === Parameters
 options(Hash):: Run options
   :time_limit(Integer):: Time limit for last communication and interval for daemon checks,
     defaults to PING_INTERVAL_MULTIPLIER times agent's ping interval or to DEFAULT_TIME_LIMIT
   :max_attempts(Integer):: Maximum number of communication check attempts,
     defaults to DEFAULT_MAX_ATTEMPTS
   :retry_interval(Integer):: Number of seconds to wait before retrying communication check,
     defaults to DEFAULT_RETRY_INTERVAL, reset to :time_limit if exceeds it
   :daemon(Boolean):: Whether to run as a daemon rather than do a one-time communication check
   :log_path(String):: Log file directory, defaults to one used by agent
   :stop(Boolean):: Whether to stop the currently running daemon and then exit
   :ping(Boolean):: Try communicating now regardless of whether have communicated within
     the configured time limit, ignored if :daemon true
   :verbose(Boolean):: Whether to display debug information

 === Return
 true:: Always return true