1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * dservd -- daemon for dserv 28 */ 29 30 #include <nfs/nfs4.h> 31 #include <libdserv.h> 32 #include <libintl.h> 33 #include <stdio.h> 34 #include <errno.h> 35 #include <string.h> 36 #include <stdlib.h> 37 #include <fcntl.h> 38 #include <signal.h> 39 #include <dservd.h> 40 41 #ifndef TEXT_DOMAIN 42 #define TEXT_DOMAIN "SUNW_OST_OSCMD" 43 #endif /* TEXT_DOMAIN */ 44 45 static void 46 daemonize() 47 { 48 int frc; 49 50 (void) chdir("/"); 51 closefrom(0); 52 (void) open("/dev/null", O_RDONLY); 53 (void) open("/dev/null", O_WRONLY); 54 (void) dup(1); 55 (void) setsid(); 56 57 frc = fork(); 58 if (frc < 0) { 59 dserv_log(NULL, LOG_ERR, 60 gettext("fork() system call failed: %m\n")); 61 exit(1); 62 } else if (frc > 0) { 63 exit(0); 64 } 65 } 66 67 static void 68 instance_shutdown(void) 69 { 70 dserv_handle_t *handle; 71 int error = 0; 72 73 handle = dserv_handle_create(); 74 if (handle == NULL) { 75 dserv_log(NULL, LOG_ERR, 76 gettext("shutdown: cannot create libdserv handle: %m")); 77 exit(1); 78 } 79 if (dserv_myinstance(handle) != 0) { 80 dserv_log(handle, LOG_ERR, NULL); 81 exit(1); 82 } 83 error = dserv_kmod_instance_shutdown(handle); 84 if (error) { 85 dserv_log(handle, LOG_ERR, 86 gettext("ERROR on dserv_kmod_instance_shutdown")); 87 } 88 89 dserv_handle_destroy(handle); 90 exit(0); 91 } 92 93 int 94 main(int argc, char *argv[]) 95 { 96 dserv_setmds_args_t setmds; 97 dserv_handle_t *handle; 98 char *poolname, *mdsaddr; 99 struct sigaction act; 100 101 (void) sigfillset(&act.sa_mask); 102 act.sa_handler = instance_shutdown; 103 act.sa_flags = 0; 104 105 (void) sigaction(SIGTERM, &act, NULL); 106 107 daemonize(); 108 109 /* no need for _create_daemon_lock; we use SMF(5). */ 110 svcsetprio(); 111 112 handle = dserv_handle_create(); 113 if (handle == NULL) 114 dserv_log(NULL, LOG_ERR, 115 gettext("cannot create libdserv handle: %m")); 116 if (dserv_myinstance(handle) != 0) { 117 dserv_log(handle, LOG_ERR, NULL); 118 exit(1); 119 } 120 121 for (poolname = dserv_firstpool(handle); 122 poolname != NULL; 123 poolname = dserv_nextpool(handle)) { 124 if (dserv_error(handle) != DSERV_ERR_NONE) 125 break; 126 127 dserv_log(handle, LOG_INFO, "dataset: %s\n", poolname); 128 if (dserv_kmod_regpool(handle, poolname) != 0) 129 break; 130 } 131 if (dserv_error(handle) != DSERV_ERR_NONE) { 132 dserv_log(handle, LOG_ERR, NULL); 133 exit(1); 134 } 135 136 mdsaddr = dserv_getmds(handle); 137 if (mdsaddr == NULL) { 138 if (dserv_error(handle) != DSERV_ERR_NONE) 139 dserv_log(handle, LOG_ERR, NULL); 140 else 141 dserv_log(handle, LOG_ERR, 142 gettext("MDS not set; aborting")); 143 exit(1); 144 } 145 if (strlcpy(setmds.dsm_mds_uaddr, mdsaddr, 146 sizeof (setmds.dsm_mds_uaddr)) >= sizeof (setmds.dsm_mds_uaddr)) { 147 dserv_log(handle, LOG_ERR, 148 gettext("MDS address too long; aborting")); 149 exit(1); 150 } 151 /* XXX need a way to have non-tcp addresses */ 152 (void) strcpy(setmds.dsm_mds_netid, "tcp"); 153 dserv_kmod_setmds(handle, &setmds); 154 155 dserv_daemon(handle); 156 157 dserv_handle_destroy(handle); 158 159 return (0); 160 } 161