1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /* 30*0Sstevel@tonic-gate * Service Management Facility (SMF) interfaces. 31*0Sstevel@tonic-gate */ 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include <stdio.h> 34*0Sstevel@tonic-gate #include <libscf.h> 35*0Sstevel@tonic-gate #include <meta.h> 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate static void enable(char *svc_names[], md_error_t *ep); 38*0Sstevel@tonic-gate static void disable(char *svc_names[], md_error_t *ep); 39*0Sstevel@tonic-gate static int enabled(char *svc_name); 40*0Sstevel@tonic-gate static int online(char *svc_names[], char **names); 41*0Sstevel@tonic-gate static void wait_online(char *svc_names[]); 42*0Sstevel@tonic-gate static int is_online(char *svc_name); 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate static char 45*0Sstevel@tonic-gate *svm_core_svcs[] = { 46*0Sstevel@tonic-gate "system/metainit:default", 47*0Sstevel@tonic-gate "system/mdmonitor:default", 48*0Sstevel@tonic-gate "network/rpc/meta:default", 49*0Sstevel@tonic-gate NULL 50*0Sstevel@tonic-gate }; 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate static char 53*0Sstevel@tonic-gate *svm_diskset_svcs[] = { 54*0Sstevel@tonic-gate "network/rpc/metamed:default", 55*0Sstevel@tonic-gate "network/rpc/metamh:default", 56*0Sstevel@tonic-gate NULL 57*0Sstevel@tonic-gate }; 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate static char 60*0Sstevel@tonic-gate *svm_mn_diskset_svcs[] = { 61*0Sstevel@tonic-gate "network/rpc/mdcomm:default", 62*0Sstevel@tonic-gate NULL 63*0Sstevel@tonic-gate }; 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate /* 66*0Sstevel@tonic-gate * Enable the specified SVM services through the SMF. 67*0Sstevel@tonic-gate */ 68*0Sstevel@tonic-gate int 69*0Sstevel@tonic-gate meta_smf_enable(uint_t flags, md_error_t *ep) 70*0Sstevel@tonic-gate { 71*0Sstevel@tonic-gate if (flags & META_SMF_CORE) { 72*0Sstevel@tonic-gate enable(svm_core_svcs, ep); 73*0Sstevel@tonic-gate wait_online(svm_core_svcs); 74*0Sstevel@tonic-gate } 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gate if (flags & META_SMF_DISKSET) { 77*0Sstevel@tonic-gate enable(svm_diskset_svcs, ep); 78*0Sstevel@tonic-gate wait_online(svm_diskset_svcs); 79*0Sstevel@tonic-gate } 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate if (flags & META_SMF_MN_DISKSET) { 82*0Sstevel@tonic-gate enable(svm_mn_diskset_svcs, ep); 83*0Sstevel@tonic-gate wait_online(svm_mn_diskset_svcs); 84*0Sstevel@tonic-gate } 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate if (ep != NULL) 87*0Sstevel@tonic-gate return ((mdisok(ep)) ? 0 : -1); 88*0Sstevel@tonic-gate else 89*0Sstevel@tonic-gate return (0); 90*0Sstevel@tonic-gate } 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate /* 93*0Sstevel@tonic-gate * Disable the specified SVM services through the SMF. 94*0Sstevel@tonic-gate */ 95*0Sstevel@tonic-gate int 96*0Sstevel@tonic-gate meta_smf_disable(uint_t flags, md_error_t *ep) 97*0Sstevel@tonic-gate { 98*0Sstevel@tonic-gate if (flags & META_SMF_CORE) { 99*0Sstevel@tonic-gate disable(svm_core_svcs, ep); 100*0Sstevel@tonic-gate } 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate if (flags & META_SMF_DISKSET) { 103*0Sstevel@tonic-gate disable(svm_diskset_svcs, ep); 104*0Sstevel@tonic-gate } 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate if (flags & META_SMF_MN_DISKSET) { 107*0Sstevel@tonic-gate disable(svm_mn_diskset_svcs, ep); 108*0Sstevel@tonic-gate } 109*0Sstevel@tonic-gate 110*0Sstevel@tonic-gate if (ep != NULL) 111*0Sstevel@tonic-gate return ((mdisok(ep)) ? 0 : -1); 112*0Sstevel@tonic-gate else 113*0Sstevel@tonic-gate return (0); 114*0Sstevel@tonic-gate } 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate /* 117*0Sstevel@tonic-gate * Determine if desired services are online. If all services in the 118*0Sstevel@tonic-gate * classes specified by flags are online, 1 is returned. Otherwise 119*0Sstevel@tonic-gate * 0 is returned. 120*0Sstevel@tonic-gate */ 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate int 123*0Sstevel@tonic-gate meta_smf_isonline(uint_t flags, md_error_t *ep) 124*0Sstevel@tonic-gate { 125*0Sstevel@tonic-gate int ret = 1; 126*0Sstevel@tonic-gate char *names = NULL; 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate if (flags & META_SMF_CORE) { 129*0Sstevel@tonic-gate if (online(svm_core_svcs, &names) == 0) 130*0Sstevel@tonic-gate ret = 0; 131*0Sstevel@tonic-gate } 132*0Sstevel@tonic-gate if (flags & META_SMF_DISKSET) { 133*0Sstevel@tonic-gate if (online(svm_diskset_svcs, &names) == 0) 134*0Sstevel@tonic-gate ret = 0; 135*0Sstevel@tonic-gate } 136*0Sstevel@tonic-gate if (flags & META_SMF_MN_DISKSET) { 137*0Sstevel@tonic-gate if (online(svm_mn_diskset_svcs, &names) == 0) 138*0Sstevel@tonic-gate ret = 0; 139*0Sstevel@tonic-gate } 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate if (ret == 0) { 142*0Sstevel@tonic-gate (void) mderror(ep, MDE_SMF_NO_SERVICE, names); 143*0Sstevel@tonic-gate Free(names); 144*0Sstevel@tonic-gate } 145*0Sstevel@tonic-gate 146*0Sstevel@tonic-gate return (ret); 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate /* 150*0Sstevel@tonic-gate * Return a bitmask of the META_SMF_* flags indicating which services should be 151*0Sstevel@tonic-gate * online given the current SVM configuration. 152*0Sstevel@tonic-gate */ 153*0Sstevel@tonic-gate int 154*0Sstevel@tonic-gate meta_smf_getmask() 155*0Sstevel@tonic-gate { 156*0Sstevel@tonic-gate int mask = 0; 157*0Sstevel@tonic-gate mdsetname_t *sp = NULL; 158*0Sstevel@tonic-gate mddb_config_t c; 159*0Sstevel@tonic-gate md_error_t status = mdnullerror; 160*0Sstevel@tonic-gate md_error_t *ep = &status; 161*0Sstevel@tonic-gate int max_sets; 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate /* 164*0Sstevel@tonic-gate * If there are any local metadbs configured then the core services 165*0Sstevel@tonic-gate * are needed. 166*0Sstevel@tonic-gate */ 167*0Sstevel@tonic-gate (void) memset(&c, 0, sizeof (c)); 168*0Sstevel@tonic-gate c.c_setno = MD_LOCAL_SET; 169*0Sstevel@tonic-gate if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0 || c.c_dbcnt == 0) 170*0Sstevel@tonic-gate return (mask); 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate mask |= META_SMF_CORE; 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate /* 175*0Sstevel@tonic-gate * If any disksets configured then the diskset services are needed. 176*0Sstevel@tonic-gate * Also check for multi-node sets. 177*0Sstevel@tonic-gate */ 178*0Sstevel@tonic-gate if ((max_sets = get_max_sets(ep)) > 0) { 179*0Sstevel@tonic-gate int i; 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate mdclrerror(ep); 182*0Sstevel@tonic-gate for (i = 1; i < max_sets; i++) { 183*0Sstevel@tonic-gate md_set_desc *sd; 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate if ((sp = metasetnosetname(i, ep)) == NULL) { 186*0Sstevel@tonic-gate if (!mdisok(ep) && !mdiserror(ep, MDE_NO_SET) && 187*0Sstevel@tonic-gate !mdismddberror(ep, MDE_NOTENOUGH_DB) && 188*0Sstevel@tonic-gate !mdiserror(ep, MDE_SMF_NO_SERVICE) && 189*0Sstevel@tonic-gate ep->info.errclass != MDEC_RPC) { 190*0Sstevel@tonic-gate /* 191*0Sstevel@tonic-gate * metad rpc program not registered 192*0Sstevel@tonic-gate * can't get diskset info 193*0Sstevel@tonic-gate */ 194*0Sstevel@tonic-gate break; 195*0Sstevel@tonic-gate } 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate } else { 198*0Sstevel@tonic-gate mask |= META_SMF_DISKSET; 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate if ((sd = metaget_setdesc(sp, ep)) != NULL) { 201*0Sstevel@tonic-gate if (MD_MNSET_DESC(sd)) { 202*0Sstevel@tonic-gate mask |= META_SMF_MN_DISKSET; 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate /* 205*0Sstevel@tonic-gate * we don't have to check the 206*0Sstevel@tonic-gate * rest of the disksets at this 207*0Sstevel@tonic-gate * point 208*0Sstevel@tonic-gate */ 209*0Sstevel@tonic-gate break; 210*0Sstevel@tonic-gate } 211*0Sstevel@tonic-gate } 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate mdclrerror(ep); 215*0Sstevel@tonic-gate } 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate return (mask); 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate static void 222*0Sstevel@tonic-gate enable(char *svc_names[], md_error_t *ep) 223*0Sstevel@tonic-gate { 224*0Sstevel@tonic-gate int i; 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate for (i = 0; svc_names[i]; i++) { 227*0Sstevel@tonic-gate if (!enabled(svc_names[i])) 228*0Sstevel@tonic-gate if (smf_enable_instance(svc_names[i], 0) != 0) { 229*0Sstevel@tonic-gate if (ep != NULL) { 230*0Sstevel@tonic-gate (void) mderror(ep, MDE_SMF_FAIL, 231*0Sstevel@tonic-gate svc_names[i]); 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate } 234*0Sstevel@tonic-gate } 235*0Sstevel@tonic-gate } 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate static void 238*0Sstevel@tonic-gate disable(char *svc_names[], md_error_t *ep) 239*0Sstevel@tonic-gate { 240*0Sstevel@tonic-gate int i; 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate for (i = 0; svc_names[i]; i++) { 243*0Sstevel@tonic-gate if (enabled(svc_names[i])) 244*0Sstevel@tonic-gate if (smf_disable_instance(svc_names[i], 0) != 0) { 245*0Sstevel@tonic-gate if (ep != NULL) { 246*0Sstevel@tonic-gate (void) mderror(ep, MDE_SMF_FAIL, 247*0Sstevel@tonic-gate svc_names[i]); 248*0Sstevel@tonic-gate } 249*0Sstevel@tonic-gate } 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate static int 254*0Sstevel@tonic-gate enabled(char *svc_name) 255*0Sstevel@tonic-gate { 256*0Sstevel@tonic-gate scf_simple_prop_t *prop; 257*0Sstevel@tonic-gate int rval = 0; 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate prop = scf_simple_prop_get(NULL, svc_name, SCF_PG_GENERAL, 260*0Sstevel@tonic-gate SCF_PROPERTY_ENABLED); 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate if (scf_simple_prop_numvalues(prop) == 1) { 263*0Sstevel@tonic-gate if (*scf_simple_prop_next_boolean(prop) != 0) 264*0Sstevel@tonic-gate rval = 1; 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate scf_simple_prop_free(prop); 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate return (rval); 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate /* 273*0Sstevel@tonic-gate * There can be a delay while the RPC services get going. Try to 274*0Sstevel@tonic-gate * make sure the RPC daemons are ready to run before we return. 275*0Sstevel@tonic-gate * Check 15 times (15 seconds total wait time) and then just 276*0Sstevel@tonic-gate * return. 277*0Sstevel@tonic-gate */ 278*0Sstevel@tonic-gate static void 279*0Sstevel@tonic-gate wait_online(char *svc_names[]) 280*0Sstevel@tonic-gate { 281*0Sstevel@tonic-gate int i; 282*0Sstevel@tonic-gate char *names = NULL; 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate for (i = 0; i < 15; i++) { 285*0Sstevel@tonic-gate if (online(svc_names, &names)) 286*0Sstevel@tonic-gate break; 287*0Sstevel@tonic-gate (void) sleep(1); 288*0Sstevel@tonic-gate } 289*0Sstevel@tonic-gate 290*0Sstevel@tonic-gate if (names != NULL) 291*0Sstevel@tonic-gate Free(names); 292*0Sstevel@tonic-gate } 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate /* 295*0Sstevel@tonic-gate * Check to see if all services in the svc_names are online. If they are 296*0Sstevel@tonic-gate * all online 1 is returned, otherwise 0 is returned. 297*0Sstevel@tonic-gate */ 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate static int 300*0Sstevel@tonic-gate online(char *svc_names[], char **names) 301*0Sstevel@tonic-gate { 302*0Sstevel@tonic-gate int i; 303*0Sstevel@tonic-gate int rv = 1; 304*0Sstevel@tonic-gate 305*0Sstevel@tonic-gate for (i = 0; svc_names[i]; i++) { 306*0Sstevel@tonic-gate if (is_online(svc_names[i]) == 0) { 307*0Sstevel@tonic-gate int sz; 308*0Sstevel@tonic-gate char *p; 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate /* 311*0Sstevel@tonic-gate * Need space for the name, the new line, the 312*0Sstevel@tonic-gate * tab and the null terminator. 313*0Sstevel@tonic-gate */ 314*0Sstevel@tonic-gate sz = strlen(svc_names[i]) + 3; 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gate if (*names == NULL) { 317*0Sstevel@tonic-gate p = Malloc(sz); 318*0Sstevel@tonic-gate (void) snprintf(p, sz, "\n\t%s", svc_names[i]); 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate } else { 321*0Sstevel@tonic-gate /* Add space for existing names */ 322*0Sstevel@tonic-gate sz += strlen(*names); 323*0Sstevel@tonic-gate p = Malloc(sz); 324*0Sstevel@tonic-gate (void) snprintf(p, sz, "%s\n\t%s", *names, 325*0Sstevel@tonic-gate svc_names[i]); 326*0Sstevel@tonic-gate Free(names); 327*0Sstevel@tonic-gate } 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate *names = p; 330*0Sstevel@tonic-gate rv = 0; 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate } 333*0Sstevel@tonic-gate return (rv); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate /* 337*0Sstevel@tonic-gate * Return 1 if the specified service is online. Otherwise, return 0. 338*0Sstevel@tonic-gate */ 339*0Sstevel@tonic-gate static int 340*0Sstevel@tonic-gate is_online(char *svc_name) 341*0Sstevel@tonic-gate { 342*0Sstevel@tonic-gate int rval = 0; 343*0Sstevel@tonic-gate char *s; 344*0Sstevel@tonic-gate 345*0Sstevel@tonic-gate if ((s = smf_get_state(svc_name)) != NULL) { 346*0Sstevel@tonic-gate if (strcmp(s, "online") == 0) 347*0Sstevel@tonic-gate rval = 1; 348*0Sstevel@tonic-gate free(s); 349*0Sstevel@tonic-gate } 350*0Sstevel@tonic-gate return (rval); 351*0Sstevel@tonic-gate } 352