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