]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libdevdctl/event.h
MFV: zlib 1.3
[FreeBSD/FreeBSD.git] / lib / libdevdctl / event.h
1 /*-
2  * Copyright (c) 2011, 2012, 2013, 2016 Spectra Logic Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions, and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    substantially similar to the "NO WARRANTY" disclaimer below
13  *    ("Disclaimer") and any redistribution must be conditioned upon
14  *    including a substantially similar Disclaimer requirement for further
15  *    binary redistribution.
16  *
17  * NO WARRANTY
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGES.
29  *
30  * Authors: Justin T. Gibbs     (Spectra Logic Corporation)
31  */
32
33 /**
34  * \file devdctl_event.h
35  *
36  * \brief Class hierarchy used to express events received via
37  *        the devdctl API.
38  */
39
40 #ifndef _DEVDCTL_EVENT_H_
41 #define _DEVDCTL_EVENT_H_
42
43 /*============================ Namespace Control =============================*/
44 namespace DevdCtl
45 {
46
47 /*=========================== Forward Declarations ===========================*/
48 class EventFactory;
49
50 /*============================= Class Definitions ============================*/
51 /*-------------------------------- NVPairMap ---------------------------------*/
52 /**
53  * NVPairMap is a specialization of the standard map STL container.
54  */
55 typedef std::map<std::string, std::string> NVPairMap;
56
57 /*----------------------------------- Event ----------------------------------*/
58 /**
59  * \brief Container for the name => value pairs that comprise the content of
60  *        a device control event.
61  *
62  * All name => value data for events can be accessed via the Contains()
63  * and Value() methods.  name => value pairs for data not explicitly
64  * received as a name => value pair are synthesized during parsing.  For
65  * example, ATTACH and DETACH events have "device-name" and "parent"
66  * name => value pairs added.
67  */
68 class Event
69 {
70         friend class EventFactory;
71
72 public:
73         /** Event type */
74         enum Type {
75                 /** Generic event notification. */
76                 NOTIFY  = '!',
77
78                 /** A driver was not found for this device. */
79                 NOMATCH = '?',
80
81                 /** A bus device instance has been added. */
82                 ATTACH  = '+',
83
84                 /** A bus device instance has been removed. */
85                 DETACH  = '-'
86         };
87
88         /**
89          * Factory method type to construct an Event given
90          * the type of event and an NVPairMap populated from
91          * the event string received from devd.
92          */
93         typedef Event* (BuildMethod)(Type, NVPairMap &, const std::string &);
94
95         /** Generic Event object factory. */
96         static BuildMethod Builder;
97
98         static Event *CreateEvent(const EventFactory &factory,
99                                   const std::string &eventString);
100
101         /**
102          * Returns the devname, if any, associated with the event
103          *
104          * \param name  Devname, returned by reference
105          * \return      True iff the event contained a devname
106          */
107         virtual bool DevName(std::string &name) const;
108
109         /**
110          * Returns the absolute pathname of the device associated with this
111          * event.
112          *
113          * \param name  Devname, returned by reference
114          * \return      True iff the event contained a devname
115          */
116         bool DevPath(std::string &path)         const;
117
118         /**
119          * Returns true iff this event refers to a disk device
120          */
121         bool IsDiskDev()                        const;
122
123         /** Returns the physical path of the device, if any
124          *
125          * \param path  Physical path, returned by reference
126          * \return      True iff the event contains a device with a physical
127          *              path
128          */
129         bool PhysicalPath(std::string &path)    const;
130
131         /**
132          * Provide a user friendly string representation of an
133          * event type.
134          *
135          * \param type  The type of event to map to a string.
136          *
137          * \return  A user friendly string representing the input type.
138          */
139         static const char  *TypeToString(Type type);
140
141         /**
142          * Determine the availability of a name => value pair by name.
143          *
144          * \param name  The key name to search for in this event instance.
145          *
146          * \return  true if the specified key is available in this
147          *          event, otherwise false.
148          */
149         bool Contains(const std::string &name)           const;
150
151         /**
152          * \param key  The name of the key for which to retrieve its
153          *             associated value.
154          *
155          * \return  A const reference to the string representing the
156          *          value associated with key.
157          *
158          * \note  For key's with no registered value, the empty string
159          *        is returned.
160          */
161         const std::string &Value(const std::string &key) const;
162
163         /**
164          * Get the type of this event instance.
165          *
166          * \return  The type of this event instance.
167          */
168         Type GetType()                                   const;
169
170         /**
171          * Get the original DevdCtl event string for this event.
172          *
173          * \return  The DevdCtl event string.
174          */
175         const std::string &GetEventString()              const;
176
177         /**
178          * Convert the event instance into a string suitable for
179          * printing to the console or emitting to syslog.
180          *
181          * \return  A string of formatted event data.
182          */
183         std::string ToString()                           const;
184
185         /**
186          * Pretty-print this event instance to cout.
187          */
188         void Print()                                     const;
189
190         /**
191          * Pretty-print this event instance to syslog.
192          *
193          * \param priority  The logging priority/facility.
194          *                  See syslog(3).
195          */
196         void Log(int priority)                           const;
197
198         /**
199          * Create and return a fully independent clone
200          * of this event.
201          */
202         virtual Event *DeepCopy()                        const;
203
204         /** Destructor */
205         virtual ~Event();
206
207         /**
208          * Interpret and perform any actions necessary to
209          * consume the event.
210          *
211          * \return True if this event should be queued for later reevaluation
212          */
213         virtual bool Process()                           const;
214
215         /**
216          * Get the time that the event was created
217          */
218         timeval GetTimestamp()                           const;
219
220         /**
221          * Add a timestamp to the event string, if one does not already exist
222          * TODO: make this an instance method that operates on the std::map
223          * instead of the string.  We must fix zfsd's CaseFile serialization
224          * routines first, so that they don't need the raw event string.
225          *
226          * \param[in,out] eventString The devd event string to modify
227          */
228         static void TimestampEventString(std::string &eventString);
229
230         /**
231          * Access all parsed key => value pairs.
232          */
233         const NVPairMap &GetMap()                        const;
234
235 protected:
236         /** Table entries used to map a type to a user friendly string. */
237         struct EventTypeRecord
238         {
239                 Type         m_type;
240                 const char  *m_typeName;
241         };
242
243         /**
244          * Constructor
245          *
246          * \param type  The type of event to create.
247          */
248         Event(Type type, NVPairMap &map, const std::string &eventString);
249
250         /** Deep copy constructor. */
251         Event(const Event &src);
252
253         /** Always empty string returned when NVPairMap lookups fail. */
254         static const std::string    s_theEmptyString;
255
256         /** Unsorted table of event types. */
257         static EventTypeRecord      s_typeTable[];
258
259         /** The type of this event. */
260         const Type                  m_type;
261
262         /**
263          * Event attribute storage.
264          *
265          * \note Although stored by reference (since m_nvPairs can
266          *       never be NULL), the NVPairMap referenced by this field
267          *       is dynamically allocated and owned by this event object.
268          *       m_nvPairs must be deleted at event destruction.
269          */
270         NVPairMap                  &m_nvPairs;
271
272         /**
273          * The unaltered event string, as received from devd, used to
274          * create this event object.
275          */
276         std::string                 m_eventString;
277
278 private:
279         /**
280          * Ingest event data from the supplied string.
281          *
282          * \param[in] eventString  The string of devd event data to parse.
283          * \param[out] nvpairs     Returns the parsed data
284          */
285         static void ParseEventString(Type type, const std::string &eventString,
286                                      NVPairMap &nvpairs);
287 };
288
289 inline Event::Type
290 Event::GetType() const
291 {
292         return (m_type);
293 }
294
295 inline const std::string &
296 Event::GetEventString() const
297 {
298         return (m_eventString);
299 }
300
301 inline const NVPairMap &
302 Event::GetMap() const
303 {
304         return (m_nvPairs);
305 }
306
307 /*--------------------------------- EventList --------------------------------*/
308 /**
309  * EventList is a specialization of the standard list STL container.
310  */
311 typedef std::list<Event *> EventList;
312
313 /*-------------------------------- DevfsEvent --------------------------------*/
314 class DevfsEvent : public Event
315 {
316 public:
317         /** Specialized Event object factory for Devfs events. */
318         static BuildMethod Builder;
319
320         virtual Event *DeepCopy()               const;
321
322         /**
323          * Interpret and perform any actions necessary to
324          * consume the event.
325          * \return True if this event should be queued for later reevaluation
326          */
327         virtual bool Process()                  const;
328
329         bool IsWholeDev()                       const;
330         virtual bool DevName(std::string &name) const;
331
332 protected:
333         /**
334          * Given the device name of a disk, determine if the device
335          * represents the whole device, not just a partition.
336          *
337          * \param devName  Device name of disk device to test.
338          *
339          * \return  True if the device name represents the whole device.
340          *          Otherwise false.
341          */
342         static bool IsWholeDev(const std::string &devName);
343
344         /** DeepCopy Constructor. */
345         DevfsEvent(const DevfsEvent &src);
346
347         /** Constructor */
348         DevfsEvent(Type, NVPairMap &, const std::string &);
349 };
350
351 /*--------------------------------- GeomEvent --------------------------------*/
352 class GeomEvent : public Event
353 {
354 public:
355         /** Specialized Event object factory for GEOM events. */
356         static BuildMethod Builder;
357
358         virtual Event *DeepCopy()       const;
359
360         virtual bool DevName(std::string &name) const;
361
362         const std::string &DeviceName() const;
363
364 protected:
365         /** Constructor */
366         GeomEvent(Type, NVPairMap &, const std::string &);
367
368         /** Deep copy constructor. */
369         GeomEvent(const GeomEvent &src);
370
371         std::string m_devname;
372 };
373
374 /*--------------------------------- ZfsEvent ---------------------------------*/
375 class ZfsEvent : public Event
376 {
377 public:
378         /** Specialized Event object factory for ZFS events. */
379         static BuildMethod Builder;
380
381         virtual Event *DeepCopy()       const;
382
383         virtual bool DevName(std::string &name) const;
384
385         const std::string &PoolName()   const;
386         Guid               PoolGUID()   const;
387         Guid               VdevGUID()   const;
388
389 protected:
390         /** Constructor */
391         ZfsEvent(Type, NVPairMap &, const std::string &);
392
393         /** Deep copy constructor. */
394         ZfsEvent(const ZfsEvent &src);
395
396         Guid    m_poolGUID;
397         Guid    m_vdevGUID;
398 };
399
400 //- ZfsEvent Inline Public Methods --------------------------------------------
401 inline const std::string&
402 ZfsEvent::PoolName() const
403 {
404         /* The pool name is reported as the subsystem of ZFS events. */
405         return (Value("subsystem"));
406 }
407
408 inline Guid
409 ZfsEvent::PoolGUID() const
410 {
411         return (m_poolGUID);
412 }
413
414 inline Guid
415 ZfsEvent::VdevGUID() const
416 {
417         return (m_vdevGUID);
418 }
419
420 } // namespace DevdCtl
421 #endif /*_DEVDCTL_EVENT_H_ */