17a0c41d5SAlan Somers /*- 27a0c41d5SAlan Somers * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Spectra Logic Corporation 37a0c41d5SAlan Somers * All rights reserved. 47a0c41d5SAlan Somers * 57a0c41d5SAlan Somers * Redistribution and use in source and binary forms, with or without 67a0c41d5SAlan Somers * modification, are permitted provided that the following conditions 77a0c41d5SAlan Somers * are met: 87a0c41d5SAlan Somers * 1. Redistributions of source code must retain the above copyright 97a0c41d5SAlan Somers * notice, this list of conditions, and the following disclaimer, 107a0c41d5SAlan Somers * without modification. 117a0c41d5SAlan Somers * 2. Redistributions in binary form must reproduce at minimum a disclaimer 127a0c41d5SAlan Somers * substantially similar to the "NO WARRANTY" disclaimer below 137a0c41d5SAlan Somers * ("Disclaimer") and any redistribution must be conditioned upon 147a0c41d5SAlan Somers * including a substantially similar Disclaimer requirement for further 157a0c41d5SAlan Somers * binary redistribution. 167a0c41d5SAlan Somers * 177a0c41d5SAlan Somers * NO WARRANTY 187a0c41d5SAlan Somers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 197a0c41d5SAlan Somers * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 207a0c41d5SAlan Somers * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 217a0c41d5SAlan Somers * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 227a0c41d5SAlan Somers * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 237a0c41d5SAlan Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 247a0c41d5SAlan Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 257a0c41d5SAlan Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 267a0c41d5SAlan Somers * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 277a0c41d5SAlan Somers * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 287a0c41d5SAlan Somers * POSSIBILITY OF SUCH DAMAGES. 297a0c41d5SAlan Somers * 307a0c41d5SAlan Somers * Authors: Justin T. Gibbs (Spectra Logic Corporation) 317a0c41d5SAlan Somers */ 327a0c41d5SAlan Somers 337a0c41d5SAlan Somers /** 347a0c41d5SAlan Somers * \file zfsd.cc 357a0c41d5SAlan Somers * 367a0c41d5SAlan Somers * The ZFS daemon consumes kernel devdctl(4) event data via devd(8)'s 377a0c41d5SAlan Somers * unix domain socket in order to react to system changes that impact 387a0c41d5SAlan Somers * the function of ZFS storage pools. The goal of this daemon is to 397a0c41d5SAlan Somers * provide similar functionality to the Solaris ZFS Diagnostic Engine 407a0c41d5SAlan Somers * (zfs-diagnosis), the Solaris ZFS fault handler (zfs-retire), and 417a0c41d5SAlan Somers * the Solaris ZFS vdev insertion agent (zfs-mod sysevent handler). 427a0c41d5SAlan Somers */ 437a0c41d5SAlan Somers 447a0c41d5SAlan Somers #include <sys/cdefs.h> 45*9e5787d2SMatt Macy #include <sys/byteorder.h> 467a0c41d5SAlan Somers #include <sys/param.h> 477a0c41d5SAlan Somers #include <sys/fs/zfs.h> 487a0c41d5SAlan Somers 497a0c41d5SAlan Somers #include <err.h> 50*9e5787d2SMatt Macy #include <fcntl.h> 517a0c41d5SAlan Somers #include <libgeom.h> 527a0c41d5SAlan Somers #include <libutil.h> 537a0c41d5SAlan Somers #include <poll.h> 547a0c41d5SAlan Somers #include <syslog.h> 557a0c41d5SAlan Somers 567a0c41d5SAlan Somers #include <libzfs.h> 577a0c41d5SAlan Somers 587a0c41d5SAlan Somers #include <list> 597a0c41d5SAlan Somers #include <map> 607a0c41d5SAlan Somers #include <string> 617a0c41d5SAlan Somers 627a0c41d5SAlan Somers #include <devdctl/guid.h> 637a0c41d5SAlan Somers #include <devdctl/event.h> 647a0c41d5SAlan Somers #include <devdctl/event_factory.h> 657a0c41d5SAlan Somers #include <devdctl/exception.h> 667a0c41d5SAlan Somers #include <devdctl/consumer.h> 677a0c41d5SAlan Somers 687a0c41d5SAlan Somers #include "callout.h" 697a0c41d5SAlan Somers #include "vdev_iterator.h" 707a0c41d5SAlan Somers #include "zfsd_event.h" 717a0c41d5SAlan Somers #include "case_file.h" 727a0c41d5SAlan Somers #include "vdev.h" 737a0c41d5SAlan Somers #include "vdev_iterator.h" 747a0c41d5SAlan Somers #include "zfsd.h" 757a0c41d5SAlan Somers #include "zfsd_exception.h" 767a0c41d5SAlan Somers #include "zpool_list.h" 777a0c41d5SAlan Somers 787a0c41d5SAlan Somers __FBSDID("$FreeBSD$"); 797a0c41d5SAlan Somers 807a0c41d5SAlan Somers /*================================== Macros ==================================*/ 817a0c41d5SAlan Somers #define NUM_ELEMENTS(x) (sizeof(x) / sizeof(*x)) 827a0c41d5SAlan Somers 837a0c41d5SAlan Somers /*============================ Namespace Control =============================*/ 847a0c41d5SAlan Somers using DevdCtl::Event; 857a0c41d5SAlan Somers using DevdCtl::EventFactory; 867a0c41d5SAlan Somers using DevdCtl::EventList; 877a0c41d5SAlan Somers 887a0c41d5SAlan Somers /*================================ Global Data ===============================*/ 897a0c41d5SAlan Somers int g_debug = 0; 907a0c41d5SAlan Somers libzfs_handle_t *g_zfsHandle; 917a0c41d5SAlan Somers 927a0c41d5SAlan Somers /*--------------------------------- ZfsDaemon --------------------------------*/ 937a0c41d5SAlan Somers //- ZfsDaemon Static Private Data ---------------------------------------------- 947a0c41d5SAlan Somers ZfsDaemon *ZfsDaemon::s_theZfsDaemon; 957a0c41d5SAlan Somers bool ZfsDaemon::s_logCaseFiles; 967a0c41d5SAlan Somers bool ZfsDaemon::s_terminateEventLoop; 977a0c41d5SAlan Somers char ZfsDaemon::s_pidFilePath[] = "/var/run/zfsd.pid"; 987a0c41d5SAlan Somers pidfh *ZfsDaemon::s_pidFH; 997a0c41d5SAlan Somers int ZfsDaemon::s_signalPipeFD[2]; 1007a0c41d5SAlan Somers bool ZfsDaemon::s_systemRescanRequested(false); 1017a0c41d5SAlan Somers EventFactory::Record ZfsDaemon::s_registryEntries[] = 1027a0c41d5SAlan Somers { 1037a0c41d5SAlan Somers { Event::NOTIFY, "GEOM", &GeomEvent::Builder }, 1047a0c41d5SAlan Somers { Event::NOTIFY, "ZFS", &ZfsEvent::Builder } 1057a0c41d5SAlan Somers }; 1067a0c41d5SAlan Somers 1077a0c41d5SAlan Somers //- ZfsDaemon Static Public Methods -------------------------------------------- 1087a0c41d5SAlan Somers ZfsDaemon & 1097a0c41d5SAlan Somers ZfsDaemon::Get() 1107a0c41d5SAlan Somers { 1117a0c41d5SAlan Somers return (*s_theZfsDaemon); 1127a0c41d5SAlan Somers } 1137a0c41d5SAlan Somers 1147a0c41d5SAlan Somers void 1157a0c41d5SAlan Somers ZfsDaemon::WakeEventLoop() 1167a0c41d5SAlan Somers { 1177a0c41d5SAlan Somers write(s_signalPipeFD[1], "+", 1); 1187a0c41d5SAlan Somers } 1197a0c41d5SAlan Somers 1207a0c41d5SAlan Somers void 1217a0c41d5SAlan Somers ZfsDaemon::RequestSystemRescan() 1227a0c41d5SAlan Somers { 1237a0c41d5SAlan Somers s_systemRescanRequested = true; 1247a0c41d5SAlan Somers ZfsDaemon::WakeEventLoop(); 1257a0c41d5SAlan Somers } 1267a0c41d5SAlan Somers 1277a0c41d5SAlan Somers void 1287a0c41d5SAlan Somers ZfsDaemon::Run() 1297a0c41d5SAlan Somers { 1307a0c41d5SAlan Somers ZfsDaemon daemon; 1317a0c41d5SAlan Somers 1327a0c41d5SAlan Somers while (s_terminateEventLoop == false) { 1337a0c41d5SAlan Somers 1347a0c41d5SAlan Somers try { 1357a0c41d5SAlan Somers daemon.DisconnectFromDevd(); 1367a0c41d5SAlan Somers 1377a0c41d5SAlan Somers if (daemon.ConnectToDevd() == false) { 1387a0c41d5SAlan Somers sleep(30); 1397a0c41d5SAlan Somers continue; 1407a0c41d5SAlan Somers } 1417a0c41d5SAlan Somers 1427a0c41d5SAlan Somers daemon.DetectMissedEvents(); 1437a0c41d5SAlan Somers 1447a0c41d5SAlan Somers daemon.EventLoop(); 1457a0c41d5SAlan Somers 1467a0c41d5SAlan Somers } catch (const DevdCtl::Exception &exp) { 1477a0c41d5SAlan Somers exp.Log(); 1487a0c41d5SAlan Somers } 1497a0c41d5SAlan Somers } 1507a0c41d5SAlan Somers 1517a0c41d5SAlan Somers daemon.DisconnectFromDevd(); 1527a0c41d5SAlan Somers } 1537a0c41d5SAlan Somers 1547a0c41d5SAlan Somers //- ZfsDaemon Private Methods -------------------------------------------------- 1557a0c41d5SAlan Somers ZfsDaemon::ZfsDaemon() 1567a0c41d5SAlan Somers : Consumer(/*defBuilder*/NULL, s_registryEntries, 1577a0c41d5SAlan Somers NUM_ELEMENTS(s_registryEntries)) 1587a0c41d5SAlan Somers { 1597a0c41d5SAlan Somers if (s_theZfsDaemon != NULL) 1607a0c41d5SAlan Somers errx(1, "Multiple ZfsDaemon instances created. Exiting"); 1617a0c41d5SAlan Somers 1627a0c41d5SAlan Somers s_theZfsDaemon = this; 1637a0c41d5SAlan Somers 1647a0c41d5SAlan Somers if (pipe(s_signalPipeFD) != 0) 1657a0c41d5SAlan Somers errx(1, "Unable to allocate signal pipe. Exiting"); 1667a0c41d5SAlan Somers 1677a0c41d5SAlan Somers if (fcntl(s_signalPipeFD[0], F_SETFL, O_NONBLOCK) == -1) 1687a0c41d5SAlan Somers errx(1, "Unable to set pipe as non-blocking. Exiting"); 1697a0c41d5SAlan Somers 1707a0c41d5SAlan Somers if (fcntl(s_signalPipeFD[1], F_SETFL, O_NONBLOCK) == -1) 1717a0c41d5SAlan Somers errx(1, "Unable to set pipe as non-blocking. Exiting"); 1727a0c41d5SAlan Somers 1737a0c41d5SAlan Somers signal(SIGHUP, ZfsDaemon::RescanSignalHandler); 1747a0c41d5SAlan Somers signal(SIGINFO, ZfsDaemon::InfoSignalHandler); 1757a0c41d5SAlan Somers signal(SIGINT, ZfsDaemon::QuitSignalHandler); 1767a0c41d5SAlan Somers signal(SIGTERM, ZfsDaemon::QuitSignalHandler); 1777a0c41d5SAlan Somers signal(SIGUSR1, ZfsDaemon::RescanSignalHandler); 1787a0c41d5SAlan Somers 1797a0c41d5SAlan Somers g_zfsHandle = libzfs_init(); 1807a0c41d5SAlan Somers if (g_zfsHandle == NULL) 1817a0c41d5SAlan Somers errx(1, "Unable to initialize ZFS library. Exiting"); 1827a0c41d5SAlan Somers 1837a0c41d5SAlan Somers Callout::Init(); 1847a0c41d5SAlan Somers InitializeSyslog(); 1857a0c41d5SAlan Somers OpenPIDFile(); 1867a0c41d5SAlan Somers 1877a0c41d5SAlan Somers if (g_debug == 0) 1887a0c41d5SAlan Somers daemon(0, 0); 1897a0c41d5SAlan Somers 1907a0c41d5SAlan Somers UpdatePIDFile(); 1917a0c41d5SAlan Somers } 1927a0c41d5SAlan Somers 1937a0c41d5SAlan Somers ZfsDaemon::~ZfsDaemon() 1947a0c41d5SAlan Somers { 1957a0c41d5SAlan Somers PurgeCaseFiles(); 1967a0c41d5SAlan Somers ClosePIDFile(); 1977a0c41d5SAlan Somers } 1987a0c41d5SAlan Somers 1997a0c41d5SAlan Somers void 2007a0c41d5SAlan Somers ZfsDaemon::PurgeCaseFiles() 2017a0c41d5SAlan Somers { 2027a0c41d5SAlan Somers CaseFile::PurgeAll(); 2037a0c41d5SAlan Somers } 2047a0c41d5SAlan Somers 2057a0c41d5SAlan Somers bool 2067a0c41d5SAlan Somers ZfsDaemon::VdevAddCaseFile(Vdev &vdev, void *cbArg) 2077a0c41d5SAlan Somers { 2087a0c41d5SAlan Somers if (vdev.State() != VDEV_STATE_HEALTHY) 2097a0c41d5SAlan Somers CaseFile::Create(vdev); 2107a0c41d5SAlan Somers 2117a0c41d5SAlan Somers return (/*break early*/false); 2127a0c41d5SAlan Somers } 2137a0c41d5SAlan Somers 2147a0c41d5SAlan Somers void 2157a0c41d5SAlan Somers ZfsDaemon::BuildCaseFiles() 2167a0c41d5SAlan Somers { 2177a0c41d5SAlan Somers ZpoolList zpl; 2187a0c41d5SAlan Somers ZpoolList::iterator pool; 2197a0c41d5SAlan Somers 2207a0c41d5SAlan Somers /* Add CaseFiles for vdevs with issues. */ 2217a0c41d5SAlan Somers for (pool = zpl.begin(); pool != zpl.end(); pool++) 2227a0c41d5SAlan Somers VdevIterator(*pool).Each(VdevAddCaseFile, NULL); 2237a0c41d5SAlan Somers 2247a0c41d5SAlan Somers /* De-serialize any saved cases. */ 2257a0c41d5SAlan Somers CaseFile::DeSerialize(); 2267a0c41d5SAlan Somers 2277a0c41d5SAlan Somers /* Simulate config_sync events to force CaseFile reevaluation */ 2287a0c41d5SAlan Somers for (pool = zpl.begin(); pool != zpl.end(); pool++) { 2297a0c41d5SAlan Somers char evString[160]; 2307a0c41d5SAlan Somers Event *event; 2317a0c41d5SAlan Somers nvlist_t *config; 2327a0c41d5SAlan Somers uint64_t poolGUID; 2337a0c41d5SAlan Somers const char *poolname; 2347a0c41d5SAlan Somers 2357a0c41d5SAlan Somers poolname = zpool_get_name(*pool); 2367a0c41d5SAlan Somers config = zpool_get_config(*pool, NULL); 2377a0c41d5SAlan Somers if (config == NULL) { 2387a0c41d5SAlan Somers syslog(LOG_ERR, "ZFSDaemon::BuildCaseFiles: Could not " 2397a0c41d5SAlan Somers "find pool config for pool %s", poolname); 2407a0c41d5SAlan Somers continue; 2417a0c41d5SAlan Somers } 2427a0c41d5SAlan Somers if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 2437a0c41d5SAlan Somers &poolGUID) != 0) { 2447a0c41d5SAlan Somers syslog(LOG_ERR, "ZFSDaemon::BuildCaseFiles: Could not " 2457a0c41d5SAlan Somers "find pool guid for pool %s", poolname); 2467a0c41d5SAlan Somers continue; 2477a0c41d5SAlan Somers } 2487a0c41d5SAlan Somers 2497a0c41d5SAlan Somers 2507a0c41d5SAlan Somers snprintf(evString, 160, "!system=ZFS subsystem=ZFS " 2517a0c41d5SAlan Somers "type=misc.fs.zfs.config_sync sub_type=synthesized " 2527a0c41d5SAlan Somers "pool_name=%s pool_guid=%" PRIu64 "\n", poolname, poolGUID); 2537a0c41d5SAlan Somers event = Event::CreateEvent(GetFactory(), string(evString)); 2547a0c41d5SAlan Somers if (event != NULL) { 2557a0c41d5SAlan Somers event->Process(); 2567a0c41d5SAlan Somers delete event; 2577a0c41d5SAlan Somers } 2587a0c41d5SAlan Somers } 2597a0c41d5SAlan Somers } 2607a0c41d5SAlan Somers 2617a0c41d5SAlan Somers void 2627a0c41d5SAlan Somers ZfsDaemon::RescanSystem() 2637a0c41d5SAlan Somers { 2647a0c41d5SAlan Somers struct gmesh mesh; 2657a0c41d5SAlan Somers struct gclass *mp; 2667a0c41d5SAlan Somers struct ggeom *gp; 2677a0c41d5SAlan Somers struct gprovider *pp; 2687a0c41d5SAlan Somers int result; 2697a0c41d5SAlan Somers 2707a0c41d5SAlan Somers /* 2717a0c41d5SAlan Somers * The devdctl system doesn't replay events for new consumers 2727a0c41d5SAlan Somers * of the interface. Emit manufactured DEVFS arrival events 2737a0c41d5SAlan Somers * for any devices that already before we started or during 2747a0c41d5SAlan Somers * periods where we've lost our connection to devd. 2757a0c41d5SAlan Somers */ 2767a0c41d5SAlan Somers result = geom_gettree(&mesh); 2777a0c41d5SAlan Somers if (result != 0) { 2787a0c41d5SAlan Somers syslog(LOG_ERR, "ZfsDaemon::RescanSystem: " 2797a0c41d5SAlan Somers "geom_gettree faild with error %d\n", result); 2807a0c41d5SAlan Somers return; 2817a0c41d5SAlan Somers } 2827a0c41d5SAlan Somers 2837a0c41d5SAlan Somers const string evStart("!system=DEVFS subsystem=CDEV type=CREATE " 2847a0c41d5SAlan Somers "sub_type=synthesized cdev="); 2857a0c41d5SAlan Somers LIST_FOREACH(mp, &mesh.lg_class, lg_class) { 2867a0c41d5SAlan Somers LIST_FOREACH(gp, &mp->lg_geom, lg_geom) { 2877a0c41d5SAlan Somers LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { 2887a0c41d5SAlan Somers Event *event; 2897a0c41d5SAlan Somers 2907a0c41d5SAlan Somers string evString(evStart + pp->lg_name + "\n"); 2917a0c41d5SAlan Somers event = Event::CreateEvent(GetFactory(), 2927a0c41d5SAlan Somers evString); 2937a0c41d5SAlan Somers if (event != NULL) { 2947a0c41d5SAlan Somers if (event->Process()) 2957a0c41d5SAlan Somers SaveEvent(*event); 2967a0c41d5SAlan Somers delete event; 2977a0c41d5SAlan Somers } 2987a0c41d5SAlan Somers } 2997a0c41d5SAlan Somers } 3007a0c41d5SAlan Somers } 3017a0c41d5SAlan Somers geom_deletetree(&mesh); 3027a0c41d5SAlan Somers } 3037a0c41d5SAlan Somers 3047a0c41d5SAlan Somers void 3057a0c41d5SAlan Somers ZfsDaemon::DetectMissedEvents() 3067a0c41d5SAlan Somers { 3077a0c41d5SAlan Somers do { 3087a0c41d5SAlan Somers PurgeCaseFiles(); 3097a0c41d5SAlan Somers 3107a0c41d5SAlan Somers /* 3117a0c41d5SAlan Somers * Discard any events waiting for us. We don't know 3127a0c41d5SAlan Somers * if they still apply to the current state of the 3137a0c41d5SAlan Somers * system. 3147a0c41d5SAlan Somers */ 3157a0c41d5SAlan Somers FlushEvents(); 3167a0c41d5SAlan Somers 3177a0c41d5SAlan Somers BuildCaseFiles(); 3187a0c41d5SAlan Somers 3197a0c41d5SAlan Somers /* 3207a0c41d5SAlan Somers * If the system state has changed during our 3217a0c41d5SAlan Somers * interrogation, start over. 3227a0c41d5SAlan Somers */ 3237a0c41d5SAlan Somers } while (s_terminateEventLoop == false && EventsPending()); 3247a0c41d5SAlan Somers 3257a0c41d5SAlan Somers RescanSystem(); 3267a0c41d5SAlan Somers } 3277a0c41d5SAlan Somers 3287a0c41d5SAlan Somers void 3297a0c41d5SAlan Somers ZfsDaemon::EventLoop() 3307a0c41d5SAlan Somers { 3317a0c41d5SAlan Somers while (s_terminateEventLoop == false) { 3327a0c41d5SAlan Somers struct pollfd fds[2]; 3337a0c41d5SAlan Somers int result; 3347a0c41d5SAlan Somers 3357a0c41d5SAlan Somers if (s_logCaseFiles == true) { 3367a0c41d5SAlan Somers EventList::iterator event(m_unconsumedEvents.begin()); 3377a0c41d5SAlan Somers s_logCaseFiles = false; 3387a0c41d5SAlan Somers CaseFile::LogAll(); 3397a0c41d5SAlan Somers while (event != m_unconsumedEvents.end()) 3407a0c41d5SAlan Somers (*event++)->Log(LOG_INFO); 3417a0c41d5SAlan Somers } 3427a0c41d5SAlan Somers 3437a0c41d5SAlan Somers Callout::ExpireCallouts(); 3447a0c41d5SAlan Somers 3457a0c41d5SAlan Somers /* Wait for data. */ 3467a0c41d5SAlan Somers fds[0].fd = m_devdSockFD; 3477a0c41d5SAlan Somers fds[0].events = POLLIN; 3487a0c41d5SAlan Somers fds[0].revents = 0; 3497a0c41d5SAlan Somers fds[1].fd = s_signalPipeFD[0]; 3507a0c41d5SAlan Somers fds[1].events = POLLIN; 3517a0c41d5SAlan Somers fds[1].revents = 0; 3527a0c41d5SAlan Somers result = poll(fds, NUM_ELEMENTS(fds), /*timeout*/INFTIM); 3537a0c41d5SAlan Somers if (result == -1) { 3547a0c41d5SAlan Somers if (errno == EINTR) 3557a0c41d5SAlan Somers continue; 3567a0c41d5SAlan Somers else 3577a0c41d5SAlan Somers err(1, "Polling for devd events failed"); 3587a0c41d5SAlan Somers } else if (result == 0) { 3597a0c41d5SAlan Somers errx(1, "Unexpected result of 0 from poll. Exiting"); 3607a0c41d5SAlan Somers } 3617a0c41d5SAlan Somers 3627a0c41d5SAlan Somers if ((fds[0].revents & POLLIN) != 0) 3637a0c41d5SAlan Somers ProcessEvents(); 3647a0c41d5SAlan Somers 3657a0c41d5SAlan Somers if ((fds[1].revents & POLLIN) != 0) { 3667a0c41d5SAlan Somers static char discardBuf[128]; 3677a0c41d5SAlan Somers 3687a0c41d5SAlan Somers /* 3697a0c41d5SAlan Somers * This pipe exists just to close the signal 3707a0c41d5SAlan Somers * race. Its contents are of no interest to 3717a0c41d5SAlan Somers * us, but we must ensure that future signals 3727a0c41d5SAlan Somers * have space in the pipe to write. 3737a0c41d5SAlan Somers */ 3747a0c41d5SAlan Somers while (read(s_signalPipeFD[0], discardBuf, 3757a0c41d5SAlan Somers sizeof(discardBuf)) > 0) 3767a0c41d5SAlan Somers ; 3777a0c41d5SAlan Somers } 3787a0c41d5SAlan Somers 3797a0c41d5SAlan Somers if (s_systemRescanRequested == true) { 3807a0c41d5SAlan Somers s_systemRescanRequested = false; 3817a0c41d5SAlan Somers syslog(LOG_INFO, "System Rescan request processed."); 3827a0c41d5SAlan Somers RescanSystem(); 3837a0c41d5SAlan Somers } 3847a0c41d5SAlan Somers 3857a0c41d5SAlan Somers if ((fds[0].revents & POLLERR) != 0) { 3867a0c41d5SAlan Somers syslog(LOG_INFO, "POLLERROR detected on devd socket."); 3877a0c41d5SAlan Somers break; 3887a0c41d5SAlan Somers } 3897a0c41d5SAlan Somers 3907a0c41d5SAlan Somers if ((fds[0].revents & POLLHUP) != 0) { 3917a0c41d5SAlan Somers syslog(LOG_INFO, "POLLHUP detected on devd socket."); 3927a0c41d5SAlan Somers break; 3937a0c41d5SAlan Somers } 3947a0c41d5SAlan Somers } 3957a0c41d5SAlan Somers } 3967a0c41d5SAlan Somers //- ZfsDaemon staic Private Methods -------------------------------------------- 3977a0c41d5SAlan Somers void 3987a0c41d5SAlan Somers ZfsDaemon::InfoSignalHandler(int) 3997a0c41d5SAlan Somers { 4007a0c41d5SAlan Somers s_logCaseFiles = true; 4017a0c41d5SAlan Somers ZfsDaemon::WakeEventLoop(); 4027a0c41d5SAlan Somers } 4037a0c41d5SAlan Somers 4047a0c41d5SAlan Somers void 4057a0c41d5SAlan Somers ZfsDaemon::RescanSignalHandler(int) 4067a0c41d5SAlan Somers { 4077a0c41d5SAlan Somers RequestSystemRescan(); 4087a0c41d5SAlan Somers } 4097a0c41d5SAlan Somers 4107a0c41d5SAlan Somers void 4117a0c41d5SAlan Somers ZfsDaemon::QuitSignalHandler(int) 4127a0c41d5SAlan Somers { 4137a0c41d5SAlan Somers s_terminateEventLoop = true; 4147a0c41d5SAlan Somers ZfsDaemon::WakeEventLoop(); 4157a0c41d5SAlan Somers } 4167a0c41d5SAlan Somers 4177a0c41d5SAlan Somers void 4187a0c41d5SAlan Somers ZfsDaemon::OpenPIDFile() 4197a0c41d5SAlan Somers { 4207a0c41d5SAlan Somers pid_t otherPID; 4217a0c41d5SAlan Somers 4227a0c41d5SAlan Somers s_pidFH = pidfile_open(s_pidFilePath, 0600, &otherPID); 4237a0c41d5SAlan Somers if (s_pidFH == NULL) { 4247a0c41d5SAlan Somers if (errno == EEXIST) 4257a0c41d5SAlan Somers errx(1, "already running as PID %d. Exiting", otherPID); 4267a0c41d5SAlan Somers warn("cannot open PID file"); 4277a0c41d5SAlan Somers } 4287a0c41d5SAlan Somers } 4297a0c41d5SAlan Somers 4307a0c41d5SAlan Somers void 4317a0c41d5SAlan Somers ZfsDaemon::UpdatePIDFile() 4327a0c41d5SAlan Somers { 4337a0c41d5SAlan Somers if (s_pidFH != NULL) 4347a0c41d5SAlan Somers pidfile_write(s_pidFH); 4357a0c41d5SAlan Somers } 4367a0c41d5SAlan Somers 4377a0c41d5SAlan Somers void 4387a0c41d5SAlan Somers ZfsDaemon::ClosePIDFile() 4397a0c41d5SAlan Somers { 4407a0c41d5SAlan Somers if (s_pidFH != NULL) 44119d04786SAlan Somers pidfile_remove(s_pidFH); 4427a0c41d5SAlan Somers } 4437a0c41d5SAlan Somers 4447a0c41d5SAlan Somers void 4457a0c41d5SAlan Somers ZfsDaemon::InitializeSyslog() 4467a0c41d5SAlan Somers { 4477a0c41d5SAlan Somers openlog("zfsd", LOG_NDELAY, LOG_DAEMON); 4487a0c41d5SAlan Somers } 4497a0c41d5SAlan Somers 450