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