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 ===========================*/ 62 struct pidfh; 63 64 struct zpool_handle; 65 typedef struct zpool_handle zpool_handle_t; 66 67 struct zfs_handle; 68 typedef struct libzfs_handle libzfs_handle_t; 69 70 struct nvlist; 71 typedef struct nvlist nvlist_t; 72 73 typedef int LeafIterFunc(zpool_handle_t *, nvlist_t *, void *); 74 75 /*================================ Global Data ===============================*/ 76 extern int g_debug; 77 extern libzfs_handle_t *g_zfsHandle; 78 79 /*============================= Class Definitions ============================*/ 80 /*--------------------------------- ZfsDaemon --------------------------------*/ 81 /** 82 * Static singleton orchestrating the operations of the ZFS daemon program. 83 */ 84 class ZfsDaemon : public DevdCtl::Consumer 85 { 86 public: 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 107 private: 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