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