aboutsummaryrefslogtreecommitdiff
path: root/lib/libdevdctl/event.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libdevdctl/event.h')
-rw-r--r--lib/libdevdctl/event.h421
1 files changed, 421 insertions, 0 deletions
diff --git a/lib/libdevdctl/event.h b/lib/libdevdctl/event.h
new file mode 100644
index 000000000000..162878bd6a65
--- /dev/null
+++ b/lib/libdevdctl/event.h
@@ -0,0 +1,421 @@
+/*-
+ * Copyright (c) 2011, 2012, 2013, 2016 Spectra Logic Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * Authors: Justin T. Gibbs (Spectra Logic Corporation)
+ */
+
+/**
+ * \file devdctl_event.h
+ *
+ * \brief Class hierarchy used to express events received via
+ * the devdctl API.
+ */
+
+#ifndef _DEVDCTL_EVENT_H_
+#define _DEVDCTL_EVENT_H_
+
+/*============================ Namespace Control =============================*/
+namespace DevdCtl
+{
+
+/*=========================== Forward Declarations ===========================*/
+class EventFactory;
+
+/*============================= Class Definitions ============================*/
+/*-------------------------------- NVPairMap ---------------------------------*/
+/**
+ * NVPairMap is a specialization of the standard map STL container.
+ */
+typedef std::map<std::string, std::string> NVPairMap;
+
+/*----------------------------------- Event ----------------------------------*/
+/**
+ * \brief Container for the name => value pairs that comprise the content of
+ * a device control event.
+ *
+ * All name => value data for events can be accessed via the Contains()
+ * and Value() methods. name => value pairs for data not explicitly
+ * received as a name => value pair are synthesized during parsing. For
+ * example, ATTACH and DETACH events have "device-name" and "parent"
+ * name => value pairs added.
+ */
+class Event
+{
+ friend class EventFactory;
+
+public:
+ /** Event type */
+ enum Type {
+ /** Generic event notification. */
+ NOTIFY = '!',
+
+ /** A driver was not found for this device. */
+ NOMATCH = '?',
+
+ /** A bus device instance has been added. */
+ ATTACH = '+',
+
+ /** A bus device instance has been removed. */
+ DETACH = '-'
+ };
+
+ /**
+ * Factory method type to construct an Event given
+ * the type of event and an NVPairMap populated from
+ * the event string received from devd.
+ */
+ typedef Event* (BuildMethod)(Type, NVPairMap &, const std::string &);
+
+ /** Generic Event object factory. */
+ static BuildMethod Builder;
+
+ static Event *CreateEvent(const EventFactory &factory,
+ const std::string &eventString);
+
+ /**
+ * Returns the devname, if any, associated with the event
+ *
+ * \param name Devname, returned by reference
+ * \return True iff the event contained a devname
+ */
+ virtual bool DevName(std::string &name) const;
+
+ /**
+ * Returns the absolute pathname of the device associated with this
+ * event.
+ *
+ * \param name Devname, returned by reference
+ * \return True iff the event contained a devname
+ */
+ bool DevPath(std::string &path) const;
+
+ /**
+ * Returns true iff this event refers to a disk device
+ */
+ bool IsDiskDev() const;
+
+ /** Returns the physical path of the device, if any
+ *
+ * \param path Physical path, returned by reference
+ * \return True iff the event contains a device with a physical
+ * path
+ */
+ bool PhysicalPath(std::string &path) const;
+
+ /**
+ * Provide a user friendly string representation of an
+ * event type.
+ *
+ * \param type The type of event to map to a string.
+ *
+ * \return A user friendly string representing the input type.
+ */
+ static const char *TypeToString(Type type);
+
+ /**
+ * Determine the availability of a name => value pair by name.
+ *
+ * \param name The key name to search for in this event instance.
+ *
+ * \return true if the specified key is available in this
+ * event, otherwise false.
+ */
+ bool Contains(const std::string &name) const;
+
+ /**
+ * \param key The name of the key for which to retrieve its
+ * associated value.
+ *
+ * \return A const reference to the string representing the
+ * value associated with key.
+ *
+ * \note For key's with no registered value, the empty string
+ * is returned.
+ */
+ const std::string &Value(const std::string &key) const;
+
+ /**
+ * Get the type of this event instance.
+ *
+ * \return The type of this event instance.
+ */
+ Type GetType() const;
+
+ /**
+ * Get the original DevdCtl event string for this event.
+ *
+ * \return The DevdCtl event string.
+ */
+ const std::string &GetEventString() const;
+
+ /**
+ * Convert the event instance into a string suitable for
+ * printing to the console or emitting to syslog.
+ *
+ * \return A string of formatted event data.
+ */
+ std::string ToString() const;
+
+ /**
+ * Pretty-print this event instance to cout.
+ */
+ void Print() const;
+
+ /**
+ * Pretty-print this event instance to syslog.
+ *
+ * \param priority The logging priority/facility.
+ * See syslog(3).
+ */
+ void Log(int priority) const;
+
+ /**
+ * Create and return a fully independent clone
+ * of this event.
+ */
+ virtual Event *DeepCopy() const;
+
+ /** Destructor */
+ virtual ~Event();
+
+ /**
+ * Interpret and perform any actions necessary to
+ * consume the event.
+ *
+ * \return True if this event should be queued for later reevaluation
+ */
+ virtual bool Process() const;
+
+ /**
+ * Get the time that the event was created
+ */
+ timeval GetTimestamp() const;
+
+ /**
+ * Add a timestamp to the event string, if one does not already exist
+ * TODO: make this an instance method that operates on the std::map
+ * instead of the string. We must fix zfsd's CaseFile serialization
+ * routines first, so that they don't need the raw event string.
+ *
+ * \param[in,out] eventString The devd event string to modify
+ */
+ static void TimestampEventString(std::string &eventString);
+
+ /**
+ * Access all parsed key => value pairs.
+ */
+ const NVPairMap &GetMap() const;
+
+protected:
+ /** Table entries used to map a type to a user friendly string. */
+ struct EventTypeRecord
+ {
+ Type m_type;
+ const char *m_typeName;
+ };
+
+ /**
+ * Constructor
+ *
+ * \param type The type of event to create.
+ */
+ Event(Type type, NVPairMap &map, const std::string &eventString);
+
+ /** Deep copy constructor. */
+ Event(const Event &src);
+
+ /** Always empty string returned when NVPairMap lookups fail. */
+ static const std::string s_theEmptyString;
+
+ /** Unsorted table of event types. */
+ static EventTypeRecord s_typeTable[];
+
+ /** The type of this event. */
+ const Type m_type;
+
+ /**
+ * Event attribute storage.
+ *
+ * \note Although stored by reference (since m_nvPairs can
+ * never be NULL), the NVPairMap referenced by this field
+ * is dynamically allocated and owned by this event object.
+ * m_nvPairs must be deleted at event destruction.
+ */
+ NVPairMap &m_nvPairs;
+
+ /**
+ * The unaltered event string, as received from devd, used to
+ * create this event object.
+ */
+ std::string m_eventString;
+
+private:
+ /**
+ * Ingest event data from the supplied string.
+ *
+ * \param[in] eventString The string of devd event data to parse.
+ * \param[out] nvpairs Returns the parsed data
+ */
+ static void ParseEventString(Type type, const std::string &eventString,
+ NVPairMap &nvpairs);
+};
+
+inline Event::Type
+Event::GetType() const
+{
+ return (m_type);
+}
+
+inline const std::string &
+Event::GetEventString() const
+{
+ return (m_eventString);
+}
+
+inline const NVPairMap &
+Event::GetMap() const
+{
+ return (m_nvPairs);
+}
+
+/*--------------------------------- EventList --------------------------------*/
+/**
+ * EventList is a specialization of the standard list STL container.
+ */
+typedef std::list<Event *> EventList;
+
+/*-------------------------------- DevfsEvent --------------------------------*/
+class DevfsEvent : public Event
+{
+public:
+ /** Specialized Event object factory for Devfs events. */
+ static BuildMethod Builder;
+
+ virtual Event *DeepCopy() const;
+
+ /**
+ * Interpret and perform any actions necessary to
+ * consume the event.
+ * \return True if this event should be queued for later reevaluation
+ */
+ virtual bool Process() const;
+
+ bool IsWholeDev() const;
+ virtual bool DevName(std::string &name) const;
+
+protected:
+ /**
+ * Given the device name of a disk, determine if the device
+ * represents the whole device, not just a partition.
+ *
+ * \param devName Device name of disk device to test.
+ *
+ * \return True if the device name represents the whole device.
+ * Otherwise false.
+ */
+ static bool IsWholeDev(const std::string &devName);
+
+ /** DeepCopy Constructor. */
+ DevfsEvent(const DevfsEvent &src);
+
+ /** Constructor */
+ DevfsEvent(Type, NVPairMap &, const std::string &);
+};
+
+/*--------------------------------- GeomEvent --------------------------------*/
+class GeomEvent : public Event
+{
+public:
+ /** Specialized Event object factory for GEOM events. */
+ static BuildMethod Builder;
+
+ virtual Event *DeepCopy() const;
+
+ virtual bool DevName(std::string &name) const;
+
+ const std::string &DeviceName() const;
+
+protected:
+ /** Constructor */
+ GeomEvent(Type, NVPairMap &, const std::string &);
+
+ /** Deep copy constructor. */
+ GeomEvent(const GeomEvent &src);
+
+ std::string m_devname;
+};
+
+/*--------------------------------- ZfsEvent ---------------------------------*/
+class ZfsEvent : public Event
+{
+public:
+ /** Specialized Event object factory for ZFS events. */
+ static BuildMethod Builder;
+
+ virtual Event *DeepCopy() const;
+
+ virtual bool DevName(std::string &name) const;
+
+ const std::string &PoolName() const;
+ Guid PoolGUID() const;
+ Guid VdevGUID() const;
+
+protected:
+ /** Constructor */
+ ZfsEvent(Type, NVPairMap &, const std::string &);
+
+ /** Deep copy constructor. */
+ ZfsEvent(const ZfsEvent &src);
+
+ Guid m_poolGUID;
+ Guid m_vdevGUID;
+};
+
+//- ZfsEvent Inline Public Methods --------------------------------------------
+inline const std::string&
+ZfsEvent::PoolName() const
+{
+ /* The pool name is reported as the subsystem of ZFS events. */
+ return (Value("subsystem"));
+}
+
+inline Guid
+ZfsEvent::PoolGUID() const
+{
+ return (m_poolGUID);
+}
+
+inline Guid
+ZfsEvent::VdevGUID() const
+{
+ return (m_vdevGUID);
+}
+
+} // namespace DevdCtl
+#endif /*_DEVDCTL_EVENT_H_ */