Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libdevdctl/event.h
39475 views
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_ */
422
423