1*7a0c41d5SAlan Somers /*- 2*7a0c41d5SAlan Somers * Copyright (c) 2011, 2012, 2013, 2014 Spectra Logic Corporation 3*7a0c41d5SAlan Somers * All rights reserved. 4*7a0c41d5SAlan Somers * 5*7a0c41d5SAlan Somers * Redistribution and use in source and binary forms, with or without 6*7a0c41d5SAlan Somers * modification, are permitted provided that the following conditions 7*7a0c41d5SAlan Somers * are met: 8*7a0c41d5SAlan Somers * 1. Redistributions of source code must retain the above copyright 9*7a0c41d5SAlan Somers * notice, this list of conditions, and the following disclaimer, 10*7a0c41d5SAlan Somers * without modification. 11*7a0c41d5SAlan Somers * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12*7a0c41d5SAlan Somers * substantially similar to the "NO WARRANTY" disclaimer below 13*7a0c41d5SAlan Somers * ("Disclaimer") and any redistribution must be conditioned upon 14*7a0c41d5SAlan Somers * including a substantially similar Disclaimer requirement for further 15*7a0c41d5SAlan Somers * binary redistribution. 16*7a0c41d5SAlan Somers * 17*7a0c41d5SAlan Somers * NO WARRANTY 18*7a0c41d5SAlan Somers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19*7a0c41d5SAlan Somers * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20*7a0c41d5SAlan Somers * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21*7a0c41d5SAlan Somers * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22*7a0c41d5SAlan Somers * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23*7a0c41d5SAlan Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24*7a0c41d5SAlan Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25*7a0c41d5SAlan Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26*7a0c41d5SAlan Somers * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27*7a0c41d5SAlan Somers * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*7a0c41d5SAlan Somers * POSSIBILITY OF SUCH DAMAGES. 29*7a0c41d5SAlan Somers * 30*7a0c41d5SAlan Somers * Authors: Justin T. Gibbs (Spectra Logic Corporation) 31*7a0c41d5SAlan Somers */ 32*7a0c41d5SAlan Somers 33*7a0c41d5SAlan Somers /** 34*7a0c41d5SAlan Somers * \file zfsd.h 35*7a0c41d5SAlan Somers * 36*7a0c41d5SAlan Somers * Class definitions and supporting data strutures for the ZFS fault 37*7a0c41d5SAlan Somers * management daemon. 38*7a0c41d5SAlan Somers * 39*7a0c41d5SAlan Somers * Header requirements: 40*7a0c41d5SAlan Somers * 41*7a0c41d5SAlan Somers * #include <sys/fs/zfs.h> 42*7a0c41d5SAlan Somers * 43*7a0c41d5SAlan Somers * #include <libzfs.h> 44*7a0c41d5SAlan Somers * 45*7a0c41d5SAlan Somers * #include <list> 46*7a0c41d5SAlan Somers * #include <map> 47*7a0c41d5SAlan Somers * #include <string> 48*7a0c41d5SAlan Somers * 49*7a0c41d5SAlan Somers * #include <devdctl/guid.h> 50*7a0c41d5SAlan Somers * #include <devdctl/event.h> 51*7a0c41d5SAlan Somers * #include <devdctl/event_factory.h> 52*7a0c41d5SAlan Somers * #include <devdctl/consumer.h> 53*7a0c41d5SAlan Somers * 54*7a0c41d5SAlan Somers * #include "vdev_iterator.h" 55*7a0c41d5SAlan Somers */ 56*7a0c41d5SAlan Somers #ifndef _ZFSD_H_ 57*7a0c41d5SAlan Somers #define _ZFSD_H_ 58*7a0c41d5SAlan Somers 59*7a0c41d5SAlan Somers /*=========================== Forward Declarations ===========================*/ 60*7a0c41d5SAlan Somers struct pidfh; 61*7a0c41d5SAlan Somers 62*7a0c41d5SAlan Somers struct zpool_handle; 63*7a0c41d5SAlan Somers typedef struct zpool_handle zpool_handle_t; 64*7a0c41d5SAlan Somers 65*7a0c41d5SAlan Somers struct zfs_handle; 66*7a0c41d5SAlan Somers typedef struct libzfs_handle libzfs_handle_t; 67*7a0c41d5SAlan Somers 68*7a0c41d5SAlan Somers struct nvlist; 69*7a0c41d5SAlan Somers typedef struct nvlist nvlist_t; 70*7a0c41d5SAlan Somers 71*7a0c41d5SAlan Somers typedef int LeafIterFunc(zpool_handle_t *, nvlist_t *, void *); 72*7a0c41d5SAlan Somers 73*7a0c41d5SAlan Somers /*================================ Global Data ===============================*/ 74*7a0c41d5SAlan Somers extern int g_debug; 75*7a0c41d5SAlan Somers extern libzfs_handle_t *g_zfsHandle; 76*7a0c41d5SAlan Somers 77*7a0c41d5SAlan Somers /*============================= Class Definitions ============================*/ 78*7a0c41d5SAlan Somers /*--------------------------------- ZfsDaemon --------------------------------*/ 79*7a0c41d5SAlan Somers /** 80*7a0c41d5SAlan Somers * Static singleton orchestrating the operations of the ZFS daemon program. 81*7a0c41d5SAlan Somers */ 82*7a0c41d5SAlan Somers class ZfsDaemon : public DevdCtl::Consumer 83*7a0c41d5SAlan Somers { 84*7a0c41d5SAlan Somers public: 85*7a0c41d5SAlan Somers /** Return the ZfsDaemon singleton. */ 86*7a0c41d5SAlan Somers static ZfsDaemon &Get(); 87*7a0c41d5SAlan Somers 88*7a0c41d5SAlan Somers /** 89*7a0c41d5SAlan Somers * Used by signal handlers to ensure, in a race free way, that 90*7a0c41d5SAlan Somers * the event loop will perform at least one more full loop 91*7a0c41d5SAlan Somers * before sleeping again. 92*7a0c41d5SAlan Somers */ 93*7a0c41d5SAlan Somers static void WakeEventLoop(); 94*7a0c41d5SAlan Somers 95*7a0c41d5SAlan Somers /** 96*7a0c41d5SAlan Somers * Schedules a rescan of devices in the system for potential 97*7a0c41d5SAlan Somers * candidates to replace a missing vdev. The scan is performed 98*7a0c41d5SAlan Somers * during the next run of the event loop. 99*7a0c41d5SAlan Somers */ 100*7a0c41d5SAlan Somers static void RequestSystemRescan(); 101*7a0c41d5SAlan Somers 102*7a0c41d5SAlan Somers /** Daemonize and perform all functions of the ZFS daemon. */ 103*7a0c41d5SAlan Somers static void Run(); 104*7a0c41d5SAlan Somers 105*7a0c41d5SAlan Somers private: 106*7a0c41d5SAlan Somers ZfsDaemon(); 107*7a0c41d5SAlan Somers ~ZfsDaemon(); 108*7a0c41d5SAlan Somers 109*7a0c41d5SAlan Somers static VdevCallback_t VdevAddCaseFile; 110*7a0c41d5SAlan Somers 111*7a0c41d5SAlan Somers /** Purge our cache of outstanding ZFS issues in the system. */ 112*7a0c41d5SAlan Somers void PurgeCaseFiles(); 113*7a0c41d5SAlan Somers 114*7a0c41d5SAlan Somers /** Build a cache of outstanding ZFS issues in the system. */ 115*7a0c41d5SAlan Somers void BuildCaseFiles(); 116*7a0c41d5SAlan Somers 117*7a0c41d5SAlan Somers /** 118*7a0c41d5SAlan Somers * Iterate over all known issues and attempt to solve them 119*7a0c41d5SAlan Somers * given resources currently available in the system. 120*7a0c41d5SAlan Somers */ 121*7a0c41d5SAlan Somers void RescanSystem(); 122*7a0c41d5SAlan Somers 123*7a0c41d5SAlan Somers /** 124*7a0c41d5SAlan Somers * Interrogate the system looking for previously unknown 125*7a0c41d5SAlan Somers * faults that occurred either before ZFSD was started, 126*7a0c41d5SAlan Somers * or during a period of lost communication with Devd. 127*7a0c41d5SAlan Somers */ 128*7a0c41d5SAlan Somers void DetectMissedEvents(); 129*7a0c41d5SAlan Somers 130*7a0c41d5SAlan Somers /** 131*7a0c41d5SAlan Somers * Wait for and process event source activity. 132*7a0c41d5SAlan Somers */ 133*7a0c41d5SAlan Somers void EventLoop(); 134*7a0c41d5SAlan Somers 135*7a0c41d5SAlan Somers /** 136*7a0c41d5SAlan Somers * Signal handler for which our response is to 137*7a0c41d5SAlan Somers * log the current state of the daemon. 138*7a0c41d5SAlan Somers * 139*7a0c41d5SAlan Somers * \param sigNum The signal caught. 140*7a0c41d5SAlan Somers */ 141*7a0c41d5SAlan Somers static void InfoSignalHandler(int sigNum); 142*7a0c41d5SAlan Somers 143*7a0c41d5SAlan Somers /** 144*7a0c41d5SAlan Somers * Signal handler for which our response is to 145*7a0c41d5SAlan Somers * request a case rescan. 146*7a0c41d5SAlan Somers * 147*7a0c41d5SAlan Somers * \param sigNum The signal caught. 148*7a0c41d5SAlan Somers */ 149*7a0c41d5SAlan Somers static void RescanSignalHandler(int sigNum); 150*7a0c41d5SAlan Somers 151*7a0c41d5SAlan Somers /** 152*7a0c41d5SAlan Somers * Signal handler for which our response is to 153*7a0c41d5SAlan Somers * gracefully terminate. 154*7a0c41d5SAlan Somers * 155*7a0c41d5SAlan Somers * \param sigNum The signal caught. 156*7a0c41d5SAlan Somers */ 157*7a0c41d5SAlan Somers static void QuitSignalHandler(int sigNum); 158*7a0c41d5SAlan Somers 159*7a0c41d5SAlan Somers /** 160*7a0c41d5SAlan Somers * Open and lock our PID file. 161*7a0c41d5SAlan Somers */ 162*7a0c41d5SAlan Somers static void OpenPIDFile(); 163*7a0c41d5SAlan Somers 164*7a0c41d5SAlan Somers /** 165*7a0c41d5SAlan Somers * Update our PID file with our PID. 166*7a0c41d5SAlan Somers */ 167*7a0c41d5SAlan Somers static void UpdatePIDFile(); 168*7a0c41d5SAlan Somers 169*7a0c41d5SAlan Somers /** 170*7a0c41d5SAlan Somers * Close and release the lock on our PID file. 171*7a0c41d5SAlan Somers */ 172*7a0c41d5SAlan Somers static void ClosePIDFile(); 173*7a0c41d5SAlan Somers 174*7a0c41d5SAlan Somers /** 175*7a0c41d5SAlan Somers * Perform syslog configuration. 176*7a0c41d5SAlan Somers */ 177*7a0c41d5SAlan Somers static void InitializeSyslog(); 178*7a0c41d5SAlan Somers 179*7a0c41d5SAlan Somers static ZfsDaemon *s_theZfsDaemon; 180*7a0c41d5SAlan Somers 181*7a0c41d5SAlan Somers /** 182*7a0c41d5SAlan Somers * Set to true when our program is signaled to 183*7a0c41d5SAlan Somers * gracefully exit. 184*7a0c41d5SAlan Somers */ 185*7a0c41d5SAlan Somers static bool s_logCaseFiles; 186*7a0c41d5SAlan Somers 187*7a0c41d5SAlan Somers /** 188*7a0c41d5SAlan Somers * Set to true when our program is signaled to 189*7a0c41d5SAlan Somers * gracefully exit. 190*7a0c41d5SAlan Somers */ 191*7a0c41d5SAlan Somers static bool s_terminateEventLoop; 192*7a0c41d5SAlan Somers 193*7a0c41d5SAlan Somers /** 194*7a0c41d5SAlan Somers * The canonical path and file name of zfsd's PID file. 195*7a0c41d5SAlan Somers */ 196*7a0c41d5SAlan Somers static char s_pidFilePath[]; 197*7a0c41d5SAlan Somers 198*7a0c41d5SAlan Somers /** 199*7a0c41d5SAlan Somers * Control structure for PIDFILE(3) API. 200*7a0c41d5SAlan Somers */ 201*7a0c41d5SAlan Somers static pidfh *s_pidFH; 202*7a0c41d5SAlan Somers 203*7a0c41d5SAlan Somers /** 204*7a0c41d5SAlan Somers * Pipe file descriptors used to close races with our 205*7a0c41d5SAlan Somers * signal handlers. 206*7a0c41d5SAlan Somers */ 207*7a0c41d5SAlan Somers static int s_signalPipeFD[2]; 208*7a0c41d5SAlan Somers 209*7a0c41d5SAlan Somers /** 210*7a0c41d5SAlan Somers * Flag controlling a rescan from ZFSD's event loop of all 211*7a0c41d5SAlan Somers * GEOM providers in the system to find candidates for solving 212*7a0c41d5SAlan Somers * cases. 213*7a0c41d5SAlan Somers */ 214*7a0c41d5SAlan Somers static bool s_systemRescanRequested; 215*7a0c41d5SAlan Somers 216*7a0c41d5SAlan Somers /** 217*7a0c41d5SAlan Somers * Flag controlling whether events can be queued. This boolean 218*7a0c41d5SAlan Somers * is set during event replay to ensure that events for pools or 219*7a0c41d5SAlan Somers * devices no longer in the system are not retained forever. 220*7a0c41d5SAlan Somers */ 221*7a0c41d5SAlan Somers static bool s_consumingEvents; 222*7a0c41d5SAlan Somers 223*7a0c41d5SAlan Somers static DevdCtl::EventFactory::Record s_registryEntries[]; 224*7a0c41d5SAlan Somers }; 225*7a0c41d5SAlan Somers 226*7a0c41d5SAlan Somers #endif /* _ZFSD_H_ */ 227