2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * are met:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <errno.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <signal.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <libgen.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <libscf.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <libintl.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/wait.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <zone.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <tsol/label.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <dlfcn.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd_common.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/* zfs library handle & mutex */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarlibzfs_handle_t *zlibh;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarmutex_t zlib_mtx;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarvoid *mod_plp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void ndmpd_sig_handler(int sig);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct ndmpd {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int s_shutdown_flag; /* Fields for shutdown control */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int s_sigval;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar} ndmpd_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_t ndmpd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Load and initialize the plug-in module
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarmod_init()
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *plname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_plugin_t *(*plugin_init)(int);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_pl = NULL;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl plname = ndmpd_get_prop(NDMP_PLUGIN_PATH);
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if (plname == NULL || *plname == '\0')
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((mod_plp = dlopen(plname, RTLD_LOCAL | RTLD_NOW)) == NULL) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl NDMP_LOG(LOG_ERR, "Error loading the plug-in %s: %s",
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl plname, dlerror());
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar plugin_init = (ndmp_plugin_t *(*)(int))dlsym(mod_plp, "_ndmp_init");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (plugin_init == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) dlclose(mod_plp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((ndmp_pl = plugin_init(NDMP_PLUGIN_VERSION)) == NULL) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl NDMP_LOG(LOG_ERR, "Error loading the plug-in %s", plname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Unload
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarmod_fini()
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_pl == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar void (*plugin_fini)(ndmp_plugin_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar plugin_fini = (void (*)(ndmp_plugin_t *))dlsym(mod_plp, "_ndmp_fini");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (plugin_fini == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) dlclose(mod_plp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar plugin_fini(ndmp_pl);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) dlclose(mod_plp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
faac71c002f7c7a98741f991b25937b24f309df0Jan Krylset_privileges(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik priv_set_t *pset = priv_allocset();
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set effective sets privileges to 'least' required. If fails, send
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * error messages to log file and proceed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik if (pset != NULL) {
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik priv_basicset(pset);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_PROC_AUDIT);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_PROC_SETID);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_PROC_OWNER);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_FILE_CHOWN);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_FILE_CHOWN_SELF);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_FILE_DAC_READ);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_FILE_DAC_SEARCH);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_FILE_DAC_WRITE);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_FILE_OWNER);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_FILE_SETID);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_SYS_LINKDIR);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_SYS_DEVICES);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_SYS_MOUNT);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(pset, PRIV_SYS_CONFIG);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik }
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik if (pset == NULL || setppriv(PRIV_SET, PRIV_EFFECTIVE, pset) != 0) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr,
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl "Failed to set least required privileges to the service\n");
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik }
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik priv_freeset(pset);
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl}
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
faac71c002f7c7a98741f991b25937b24f309df0Jan Krylstatic void
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryldaemonize_init(void)
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl{
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl sigset_t set, oset;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl pid_t pid;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Block all signals prior to the fork and leave them blocked in the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * parent so we don't get in a situation where the parent gets SIGINT
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and returns non-zero exit status and the child is actually running.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In the child, restore the signal mask once we've done our setsid().
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigfillset(&set);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigdelset(&set, SIGABRT);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigprocmask(SIG_BLOCK, &set, &oset);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((pid = fork()) == -1) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr,
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl "Failed to start process in background.\n");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar exit(SMF_EXIT_ERR_CONFIG);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* If we're the parent process, exit. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (pid != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar _exit(0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) setsid();
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigprocmask(SIG_SETMASK, &oset, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) chdir("/");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * main
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The main NDMP daemon function
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Parameters:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * argc (input) - the argument count
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * argv (input) - command line options
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarmain(int argc, char *argv[])
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct sigaction act;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sigset_t set;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl char c;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl void *arg = NULL;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl boolean_t run_in_foreground = B_FALSE;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl boolean_t override_debug = B_FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check for existing ndmpd door server (make sure ndmpd is not already
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * running)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_door_check()) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* ndmpd is already running, exit. */
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr, "ndmpd is already running.\n");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Global zone check */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (getzoneid() != GLOBAL_ZONEID) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr, "Non-global zone not supported.\n");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar exit(SMF_EXIT_ERR_FATAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Trusted Solaris check */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_system_labeled()) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr, "Trusted Solaris not supported.\n");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar exit(SMF_EXIT_ERR_FATAL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl /* load SMF configuration */
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if (ndmpd_load_prop()) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr,
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl "SMF properties initialization failed.\n");
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl exit(SMF_EXIT_ERR_CONFIG);
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl }
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar opterr = 0;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl while ((c = getopt(argc, argv, "df")) != -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (c) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case 'd':
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl override_debug = B_TRUE;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl break;
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl case 'f':
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl run_in_foreground = B_TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr, "%s: Invalid option -%c.\n",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar argv[0], optopt);
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) fprintf(stderr, "Usage: %s [-df]\n", argv[0]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar exit(SMF_EXIT_ERR_CONFIG);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* set up signal handler */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigfillset(&set);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigdelset(&set, SIGABRT); /* always unblocked for ASSERT() */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigfillset(&act.sa_mask);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar act.sa_handler = ndmpd_sig_handler;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar act.sa_flags = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigaction(SIGTERM, &act, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigaction(SIGHUP, &act, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigaction(SIGINT, &act, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigaction(SIGUSR1, &act, NULL);
c211fc479225fa54805cf480633bf6689ca9a2dbReza Sabdar (void) sigaction(SIGPIPE, &act, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigdelset(&set, SIGTERM);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigdelset(&set, SIGHUP);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigdelset(&set, SIGINT);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigdelset(&set, SIGUSR1);
c211fc479225fa54805cf480633bf6689ca9a2dbReza Sabdar (void) sigdelset(&set, SIGPIPE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl set_privileges();
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl (void) umask(077);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar openlog(argv[0], LOG_PID | LOG_NDELAY, LOG_DAEMON);
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl /*
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl * Open log file before we detach from terminal in case that open
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl * fails and error message is printed to stderr.
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl */
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if (ndmp_log_open_file(run_in_foreground, override_debug) != 0)
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl exit(SMF_EXIT_ERR_FATAL);
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl if (!run_in_foreground)
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl daemonize_init();
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang (void) mutex_init(&ndmpd_zfs_fd_lock, 0, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (mod_init() != 0) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl NDMP_LOG(LOG_ERR, "Failed to load the plugin module.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar exit(SMF_EXIT_ERR_CONFIG);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* libzfs init */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((zlibh = libzfs_init()) == NULL) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl NDMP_LOG(LOG_ERR, "Failed to initialize ZFS library.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar exit(SMF_EXIT_ERR_CONFIG);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* initialize and start the door server */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_door_init()) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl NDMP_LOG(LOG_ERR, "Can not start ndmpd door server.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar exit(SMF_EXIT_ERR_CONFIG);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
1e05b03fa76ee89d509f0c461b36cb865f1e6794Janice Chang if (tlm_init() == -1) {
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl NDMP_LOG(LOG_ERR, "Failed to initialize tape manager.");
1e05b03fa76ee89d509f0c461b36cb865f1e6794Janice Chang exit(SMF_EXIT_ERR_CONFIG);
1e05b03fa76ee89d509f0c461b36cb865f1e6794Janice Chang }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Prior to this point, we are single-threaded. We will be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * multi-threaded from this point on.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) pthread_create(NULL, NULL, (funct_t)ndmpd_main,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void *)&arg);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (!ndmpd.s_shutdown_flag) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sigsuspend(&set);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (ndmpd.s_sigval) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case 0:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
c211fc479225fa54805cf480633bf6689ca9a2dbReza Sabdar case SIGPIPE:
c211fc479225fa54805cf480633bf6689ca9a2dbReza Sabdar break;
c211fc479225fa54805cf480633bf6689ca9a2dbReza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case SIGHUP:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Refresh SMF properties */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmpd_load_prop())
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Service properties initialization "
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "failed.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Typically SIGINT or SIGTERM.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd.s_shutdown_flag = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd.s_sigval = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
8c4f9701439555b41fbfe7848508f53b52166007Janice Chang (void) mutex_destroy(&ndmpd_zfs_fd_lock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar libzfs_fini(zlibh);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mod_fini();
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_door_fini();
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl ndmp_log_close_file();
faac71c002f7c7a98741f991b25937b24f309df0Jan Kryl
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (SMF_EXIT_OK);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_sig_handler(int sig)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmpd.s_sigval == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmpd.s_sigval = sig;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Enable libumem debugging by default on DEBUG builds.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#ifdef DEBUG
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarconst char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar_umem_debug_init(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return ("default,verbose"); /* $UMEM_DEBUG setting */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarconst char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar_umem_logging_init(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return ("fail,contents"); /* $UMEM_LOGGING setting */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#endif