1/*-
2 * Copyright (c) 2011, 2012, 2013, 2014 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 zfsd.h
37 *
38 * Class definitions and supporting data strutures for the ZFS fault
39 * management daemon.
40 *
41 * Header requirements:
42 *
43 *    #include <sys/fs/zfs.h>
44 *
45 *    #include <libzfs.h>
46 *
47 *    #include <list>
48 *    #include <map>
49 *    #include <string>
50 *
51 *    #include <devdctl/guid.h>
52 *    #include <devdctl/event.h>
53 *    #include <devdctl/event_factory.h>
54 *    #include <devdctl/consumer.h>
55 *
56 *    #include "vdev_iterator.h"
57 */
58#ifndef	_ZFSD_H_
59#define	_ZFSD_H_
60
61/*=========================== Forward Declarations ===========================*/
62struct pidfh;
63
64struct zpool_handle;
65typedef struct zpool_handle zpool_handle_t;
66
67struct zfs_handle;
68typedef struct libzfs_handle libzfs_handle_t;
69
70struct nvlist;
71typedef struct nvlist nvlist_t;
72
73typedef int LeafIterFunc(zpool_handle_t *, nvlist_t *, void *);
74
75/*================================ Global Data ===============================*/
76extern int              g_debug;
77extern libzfs_handle_t *g_zfsHandle;
78
79/*============================= Class Definitions ============================*/
80/*--------------------------------- ZfsDaemon --------------------------------*/
81/**
82 * Static singleton orchestrating the operations of the ZFS daemon program.
83 */
84class ZfsDaemon : public DevdCtl::Consumer
85{
86public:
87	/** Return the ZfsDaemon singleton. */
88	static ZfsDaemon &Get();
89
90	/**
91	 * Used by signal handlers to ensure, in a race free way, that
92	 * the event loop will perform at least one more full loop
93	 * before sleeping again.
94	 */
95	static void WakeEventLoop();
96
97	/**
98	 * Schedules a rescan of devices in the system for potential
99	 * candidates to replace a missing vdev.  The scan is performed
100	 * during the next run of the event loop.
101	 */
102	static void RequestSystemRescan();
103
104	/** Daemonize and perform all functions of the ZFS daemon. */
105	static void Run();
106
107private:
108	ZfsDaemon();
109	~ZfsDaemon();
110
111	static VdevCallback_t VdevAddCaseFile;
112
113	/** Purge our cache of outstanding ZFS issues in the system. */
114	void PurgeCaseFiles();
115
116	/** Build a cache of outstanding ZFS issues in the system. */
117	void BuildCaseFiles();
118
119	/**
120	 * Iterate over all known issues and attempt to solve them
121	 * given resources currently available in the system.
122	 */
123	void RescanSystem();
124
125	/**
126	 * Interrogate the system looking for previously unknown
127	 * faults that occurred either before ZFSD was started,
128	 * or during a period of lost communication with Devd.
129	 */
130	void DetectMissedEvents();
131
132	/**
133	 * Wait for and process event source activity.
134	 */
135	void EventLoop();
136
137	/**
138	 * Signal handler for which our response is to
139	 * log the current state of the daemon.
140	 *
141	 * \param sigNum  The signal caught.
142	 */
143	static void InfoSignalHandler(int sigNum);
144
145	/**
146	 * Signal handler for which our response is to
147	 * request a case rescan.
148	 *
149	 * \param sigNum  The signal caught.
150	 */
151	static void RescanSignalHandler(int sigNum);
152
153	/**
154	 * Signal handler for which our response is to
155	 * gracefully terminate.
156	 *
157	 * \param sigNum  The signal caught.
158	 */
159	static void QuitSignalHandler(int sigNum);
160
161	/**
162	 * Open and lock our PID file.
163	 */
164	static void OpenPIDFile();
165
166	/**
167	 * Update our PID file with our PID.
168	 */
169	static void UpdatePIDFile();
170
171	/**
172	 * Close and release the lock on our PID file.
173	 */
174	static void ClosePIDFile();
175
176	/**
177	 * Perform syslog configuration.
178	 */
179	static void InitializeSyslog();
180
181	static ZfsDaemon		       *s_theZfsDaemon;
182
183	/**
184	 * Set to true when our program is signaled to
185	 * gracefully exit.
186	 */
187	static bool				s_logCaseFiles;
188
189	/**
190	 * Set to true when our program is signaled to
191	 * gracefully exit.
192	 */
193	static bool				s_terminateEventLoop;
194
195	/**
196	 * The canonical path and file name of zfsd's PID file.
197	 */
198	static char				s_pidFilePath[];
199
200	/**
201	 * Control structure for PIDFILE(3) API.
202	 */
203	static pidfh			       *s_pidFH;
204
205	/**
206	 * Pipe file descriptors used to close races with our
207	 * signal handlers.
208	 */
209	static int				s_signalPipeFD[2];
210
211	/**
212	 * Flag controlling a rescan from ZFSD's event loop of all
213	 * GEOM providers in the system to find candidates for solving
214	 * cases.
215	 */
216	static bool				s_systemRescanRequested;
217
218	/**
219	 * Flag controlling whether events can be queued.  This boolean
220	 * is set during event replay to ensure that events for pools or
221	 * devices no longer in the system are not retained forever.
222	 */
223	static bool				s_consumingEvents;
224
225	static DevdCtl::EventFactory::Record	s_registryEntries[];
226};
227
228#endif	/* _ZFSD_H_ */
229