17836SJohn.Forte@Sun.COM /* 27836SJohn.Forte@Sun.COM * CDDL HEADER START 37836SJohn.Forte@Sun.COM * 47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 77836SJohn.Forte@Sun.COM * 87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 117836SJohn.Forte@Sun.COM * and limitations under the License. 127836SJohn.Forte@Sun.COM * 137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 187836SJohn.Forte@Sun.COM * 197836SJohn.Forte@Sun.COM * CDDL HEADER END 207836SJohn.Forte@Sun.COM */ 217836SJohn.Forte@Sun.COM /* 22*11909SPeter.Gill@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237836SJohn.Forte@Sun.COM * Use is subject to license terms. 247836SJohn.Forte@Sun.COM */ 257836SJohn.Forte@Sun.COM 267836SJohn.Forte@Sun.COM #include <stdlib.h> 277836SJohn.Forte@Sun.COM #include <stdio.h> 287836SJohn.Forte@Sun.COM #include <strings.h> 297836SJohn.Forte@Sun.COM #include <sys/types.h> 307836SJohn.Forte@Sun.COM #include <unistd.h> 317836SJohn.Forte@Sun.COM #include <libintl.h> 327836SJohn.Forte@Sun.COM #include <errno.h> 337836SJohn.Forte@Sun.COM #include <time.h> 347836SJohn.Forte@Sun.COM #include <string.h> 357836SJohn.Forte@Sun.COM #include <assert.h> 367836SJohn.Forte@Sun.COM #include <getopt.h> 377836SJohn.Forte@Sun.COM #include <cmdparse.h> 387836SJohn.Forte@Sun.COM #include <libstmf.h> 397836SJohn.Forte@Sun.COM #include <signal.h> 407836SJohn.Forte@Sun.COM #include <pthread.h> 417836SJohn.Forte@Sun.COM #include <locale.h> 427836SJohn.Forte@Sun.COM 437836SJohn.Forte@Sun.COM static int svcStart(int, char **, cmdOptions_t *, void *); 447836SJohn.Forte@Sun.COM static int svcStop(int, char **, cmdOptions_t *, void *); 457836SJohn.Forte@Sun.COM static int online(); 467836SJohn.Forte@Sun.COM 477836SJohn.Forte@Sun.COM /* 487836SJohn.Forte@Sun.COM * MAJOR - This should only change when there is an incompatible change made 497836SJohn.Forte@Sun.COM * to the interfaces or the output. 507836SJohn.Forte@Sun.COM * 517836SJohn.Forte@Sun.COM * MINOR - This should change whenever there is a new command or new feature 527836SJohn.Forte@Sun.COM * with no incompatible change. 537836SJohn.Forte@Sun.COM */ 547836SJohn.Forte@Sun.COM #define VERSION_STRING_MAJOR "1" 557836SJohn.Forte@Sun.COM #define VERSION_STRING_MINOR "0" 567836SJohn.Forte@Sun.COM #define VERSION_STRING_MAX_LEN 10 577836SJohn.Forte@Sun.COM 587836SJohn.Forte@Sun.COM /* 10 ms sleep in nanoseconds */ 597836SJohn.Forte@Sun.COM #define TEN_MS_NANOSLEEP 10000000 607836SJohn.Forte@Sun.COM 617836SJohn.Forte@Sun.COM /* tables set up based on cmdparse instructions */ 627836SJohn.Forte@Sun.COM 637836SJohn.Forte@Sun.COM /* add new options here */ 647836SJohn.Forte@Sun.COM optionTbl_t longOptions[] = { 657836SJohn.Forte@Sun.COM {NULL, 0, 0, 0} 667836SJohn.Forte@Sun.COM }; 677836SJohn.Forte@Sun.COM 687836SJohn.Forte@Sun.COM /* 697836SJohn.Forte@Sun.COM * Add new subcommands here 707836SJohn.Forte@Sun.COM */ 717836SJohn.Forte@Sun.COM subCommandProps_t subcommands[] = { 727836SJohn.Forte@Sun.COM {"start", svcStart, NULL, NULL, NULL, OPERAND_NONE, NULL}, 737836SJohn.Forte@Sun.COM {"stop", svcStop, NULL, NULL, NULL, OPERAND_NONE, NULL}, 747836SJohn.Forte@Sun.COM {NULL, 0, NULL, NULL, 0, NULL, 0, NULL} 757836SJohn.Forte@Sun.COM }; 767836SJohn.Forte@Sun.COM 777836SJohn.Forte@Sun.COM /* globals */ 787836SJohn.Forte@Sun.COM char *cmdName; 797836SJohn.Forte@Sun.COM 807836SJohn.Forte@Sun.COM /* 817836SJohn.Forte@Sun.COM * svcStop 827836SJohn.Forte@Sun.COM * 837836SJohn.Forte@Sun.COM * Offlines the stmf service 847836SJohn.Forte@Sun.COM * 857836SJohn.Forte@Sun.COM */ 867836SJohn.Forte@Sun.COM /*ARGSUSED*/ 877836SJohn.Forte@Sun.COM static int 887836SJohn.Forte@Sun.COM svcStop(int operandLen, char *operands[], cmdOptions_t *options, 897836SJohn.Forte@Sun.COM void *args) 907836SJohn.Forte@Sun.COM { 917836SJohn.Forte@Sun.COM int stmfRet; 927836SJohn.Forte@Sun.COM int ret = 0; 937836SJohn.Forte@Sun.COM stmfState state; 947836SJohn.Forte@Sun.COM boolean_t serviceOffline = B_FALSE; 957836SJohn.Forte@Sun.COM struct timespec rqtp; 967836SJohn.Forte@Sun.COM 977836SJohn.Forte@Sun.COM bzero(&rqtp, sizeof (rqtp)); 987836SJohn.Forte@Sun.COM 997836SJohn.Forte@Sun.COM rqtp.tv_nsec = TEN_MS_NANOSLEEP; 1007836SJohn.Forte@Sun.COM 1017836SJohn.Forte@Sun.COM if ((stmfRet = stmfOffline()) != STMF_STATUS_SUCCESS) { 1027836SJohn.Forte@Sun.COM switch (stmfRet) { 1037836SJohn.Forte@Sun.COM case STMF_ERROR_PERM: 1047836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 1057836SJohn.Forte@Sun.COM gettext("permission denied")); 1067836SJohn.Forte@Sun.COM break; 1077836SJohn.Forte@Sun.COM case STMF_ERROR_SERVICE_NOT_FOUND: 1087836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 1097836SJohn.Forte@Sun.COM gettext("STMF service not found")); 1107836SJohn.Forte@Sun.COM break; 1117836SJohn.Forte@Sun.COM case STMF_ERROR_SERVICE_OFFLINE: 1127836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 1137836SJohn.Forte@Sun.COM gettext("STMF service already offline")); 1147836SJohn.Forte@Sun.COM break; 1157836SJohn.Forte@Sun.COM default: 1167836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 1177836SJohn.Forte@Sun.COM gettext("unable to offline service")); 1187836SJohn.Forte@Sun.COM break; 1197836SJohn.Forte@Sun.COM } 1207836SJohn.Forte@Sun.COM return (1); 1217836SJohn.Forte@Sun.COM } 1227836SJohn.Forte@Sun.COM 1237836SJohn.Forte@Sun.COM /* wait for service offline */ 1247836SJohn.Forte@Sun.COM while (!serviceOffline) { 1257836SJohn.Forte@Sun.COM stmfRet = stmfGetState(&state); 1267836SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 1277836SJohn.Forte@Sun.COM ret = 1; 1287836SJohn.Forte@Sun.COM break; 1297836SJohn.Forte@Sun.COM } 1307836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) { 1317836SJohn.Forte@Sun.COM serviceOffline = B_TRUE; 1327836SJohn.Forte@Sun.COM } else { 1337836SJohn.Forte@Sun.COM (void) nanosleep(&rqtp, NULL); 1347836SJohn.Forte@Sun.COM } 1357836SJohn.Forte@Sun.COM } 1367836SJohn.Forte@Sun.COM 1377836SJohn.Forte@Sun.COM return (ret); 1387836SJohn.Forte@Sun.COM } 1397836SJohn.Forte@Sun.COM 1407836SJohn.Forte@Sun.COM /* 1417836SJohn.Forte@Sun.COM * loadConfig 1427836SJohn.Forte@Sun.COM * 1437836SJohn.Forte@Sun.COM * Loads the stmf config from the SMF repository 1447836SJohn.Forte@Sun.COM * 1457836SJohn.Forte@Sun.COM */ 1467836SJohn.Forte@Sun.COM /*ARGSUSED*/ 1477836SJohn.Forte@Sun.COM static int 1487836SJohn.Forte@Sun.COM svcStart(int operandLen, char *operands[], cmdOptions_t *options, 1497836SJohn.Forte@Sun.COM void *args) 1507836SJohn.Forte@Sun.COM { 1517836SJohn.Forte@Sun.COM int stmfRet; 1527836SJohn.Forte@Sun.COM int ret = 0; 1537836SJohn.Forte@Sun.COM if ((stmfRet = stmfLoadConfig()) != STMF_STATUS_SUCCESS) { 1547836SJohn.Forte@Sun.COM switch (stmfRet) { 1557836SJohn.Forte@Sun.COM case STMF_ERROR_PERM: 1567836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 1577836SJohn.Forte@Sun.COM gettext("permission denied")); 1587836SJohn.Forte@Sun.COM break; 1597836SJohn.Forte@Sun.COM case STMF_ERROR_SERVICE_NOT_FOUND: 1607836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 1617836SJohn.Forte@Sun.COM gettext("STMF service not found")); 1627836SJohn.Forte@Sun.COM break; 1637836SJohn.Forte@Sun.COM case STMF_ERROR_SERVICE_ONLINE: 1647836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 1657836SJohn.Forte@Sun.COM gettext("STMF service must be offline")); 1667836SJohn.Forte@Sun.COM break; 1677836SJohn.Forte@Sun.COM default: 1687836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 169*11909SPeter.Gill@Sun.COM gettext("Unable to load the configuration. " 170*11909SPeter.Gill@Sun.COM "See /var/adm/messages for details")); 171*11909SPeter.Gill@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 172*11909SPeter.Gill@Sun.COM gettext("For information on reverting the " 173*11909SPeter.Gill@Sun.COM "stmf:default instance to a previously " 174*11909SPeter.Gill@Sun.COM "running configuration see the man page " 175*11909SPeter.Gill@Sun.COM "for svccfg(1M)")); 176*11909SPeter.Gill@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 177*11909SPeter.Gill@Sun.COM gettext("After reverting the instance " 178*11909SPeter.Gill@Sun.COM "you must clear the service maintenance " 179*11909SPeter.Gill@Sun.COM "state. See the man page for svcadm(1M)")); 1807836SJohn.Forte@Sun.COM break; 1817836SJohn.Forte@Sun.COM } 1827836SJohn.Forte@Sun.COM return (1); 1837836SJohn.Forte@Sun.COM } 1847836SJohn.Forte@Sun.COM ret = online(); 1857836SJohn.Forte@Sun.COM return (ret); 1867836SJohn.Forte@Sun.COM 1877836SJohn.Forte@Sun.COM } 1887836SJohn.Forte@Sun.COM 1897836SJohn.Forte@Sun.COM /* 1907836SJohn.Forte@Sun.COM * online 1917836SJohn.Forte@Sun.COM * 1927836SJohn.Forte@Sun.COM * Onlines the stmf service 1937836SJohn.Forte@Sun.COM * 1947836SJohn.Forte@Sun.COM */ 1957836SJohn.Forte@Sun.COM /*ARGSUSED*/ 1967836SJohn.Forte@Sun.COM static int 1977836SJohn.Forte@Sun.COM online() 1987836SJohn.Forte@Sun.COM { 1997836SJohn.Forte@Sun.COM int stmfRet; 2007836SJohn.Forte@Sun.COM int ret = 0; 2017836SJohn.Forte@Sun.COM stmfState state; 2027836SJohn.Forte@Sun.COM boolean_t serviceOnline = B_FALSE; 2037836SJohn.Forte@Sun.COM struct timespec rqtp; 2047836SJohn.Forte@Sun.COM 2057836SJohn.Forte@Sun.COM bzero(&rqtp, sizeof (rqtp)); 2067836SJohn.Forte@Sun.COM 2077836SJohn.Forte@Sun.COM rqtp.tv_nsec = TEN_MS_NANOSLEEP; 2087836SJohn.Forte@Sun.COM 2097836SJohn.Forte@Sun.COM if ((stmfRet = stmfOnline()) != STMF_STATUS_SUCCESS) { 2107836SJohn.Forte@Sun.COM switch (stmfRet) { 2117836SJohn.Forte@Sun.COM case STMF_ERROR_PERM: 2127836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 2137836SJohn.Forte@Sun.COM gettext("permission denied")); 2147836SJohn.Forte@Sun.COM break; 2157836SJohn.Forte@Sun.COM case STMF_ERROR_SERVICE_NOT_FOUND: 2167836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 2177836SJohn.Forte@Sun.COM gettext("STMF service not found")); 2187836SJohn.Forte@Sun.COM break; 2197836SJohn.Forte@Sun.COM case STMF_ERROR_SERVICE_ONLINE: 2207836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 2217836SJohn.Forte@Sun.COM gettext("STMF service already online")); 2227836SJohn.Forte@Sun.COM break; 2237836SJohn.Forte@Sun.COM default: 2247836SJohn.Forte@Sun.COM (void) fprintf(stderr, "%s: %s\n", cmdName, 2257836SJohn.Forte@Sun.COM gettext("unable to online service")); 2267836SJohn.Forte@Sun.COM break; 2277836SJohn.Forte@Sun.COM } 2287836SJohn.Forte@Sun.COM return (1); 2297836SJohn.Forte@Sun.COM } 2307836SJohn.Forte@Sun.COM 2317836SJohn.Forte@Sun.COM /* wait for service online */ 2327836SJohn.Forte@Sun.COM while (!serviceOnline) { 2337836SJohn.Forte@Sun.COM stmfRet = stmfGetState(&state); 2347836SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 2357836SJohn.Forte@Sun.COM ret = 1; 2367836SJohn.Forte@Sun.COM break; 2377836SJohn.Forte@Sun.COM } 2387836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_ONLINE) { 2397836SJohn.Forte@Sun.COM serviceOnline = B_TRUE; 2407836SJohn.Forte@Sun.COM } else { 2417836SJohn.Forte@Sun.COM (void) nanosleep(&rqtp, NULL); 2427836SJohn.Forte@Sun.COM } 2437836SJohn.Forte@Sun.COM } 2447836SJohn.Forte@Sun.COM 2457836SJohn.Forte@Sun.COM return (ret); 2467836SJohn.Forte@Sun.COM } 2477836SJohn.Forte@Sun.COM 2487836SJohn.Forte@Sun.COM 2497836SJohn.Forte@Sun.COM /* 2507836SJohn.Forte@Sun.COM * input: 2517836SJohn.Forte@Sun.COM * execFullName - exec name of program (argv[0]) 2527836SJohn.Forte@Sun.COM * 2537836SJohn.Forte@Sun.COM * copied from usr/src/cmd/zoneadm/zoneadm.c in OS/Net 2547836SJohn.Forte@Sun.COM * (changed name to lowerCamelCase to keep consistent with this file) 2557836SJohn.Forte@Sun.COM * 2567836SJohn.Forte@Sun.COM * Returns: 2577836SJohn.Forte@Sun.COM * command name portion of execFullName 2587836SJohn.Forte@Sun.COM */ 2597836SJohn.Forte@Sun.COM static char * 2607836SJohn.Forte@Sun.COM getExecBasename(char *execFullname) 2617836SJohn.Forte@Sun.COM { 2627836SJohn.Forte@Sun.COM char *lastSlash, *execBasename; 2637836SJohn.Forte@Sun.COM 2647836SJohn.Forte@Sun.COM /* guard against '/' at end of command invocation */ 2657836SJohn.Forte@Sun.COM for (;;) { 2667836SJohn.Forte@Sun.COM lastSlash = strrchr(execFullname, '/'); 2677836SJohn.Forte@Sun.COM if (lastSlash == NULL) { 2687836SJohn.Forte@Sun.COM execBasename = execFullname; 2697836SJohn.Forte@Sun.COM break; 2707836SJohn.Forte@Sun.COM } else { 2717836SJohn.Forte@Sun.COM execBasename = lastSlash + 1; 2727836SJohn.Forte@Sun.COM if (*execBasename == '\0') { 2737836SJohn.Forte@Sun.COM *lastSlash = '\0'; 2747836SJohn.Forte@Sun.COM continue; 2757836SJohn.Forte@Sun.COM } 2767836SJohn.Forte@Sun.COM break; 2777836SJohn.Forte@Sun.COM } 2787836SJohn.Forte@Sun.COM } 2797836SJohn.Forte@Sun.COM return (execBasename); 2807836SJohn.Forte@Sun.COM } 2817836SJohn.Forte@Sun.COM 2827836SJohn.Forte@Sun.COM int 2837836SJohn.Forte@Sun.COM main(int argc, char *argv[]) 2847836SJohn.Forte@Sun.COM { 2857836SJohn.Forte@Sun.COM synTables_t synTables; 2867836SJohn.Forte@Sun.COM char versionString[VERSION_STRING_MAX_LEN]; 2877836SJohn.Forte@Sun.COM int ret; 2887836SJohn.Forte@Sun.COM int funcRet; 2897836SJohn.Forte@Sun.COM void *subcommandArgs = NULL; 2907836SJohn.Forte@Sun.COM 2917836SJohn.Forte@Sun.COM (void) setlocale(LC_ALL, ""); 2927836SJohn.Forte@Sun.COM /* set global command name */ 2937836SJohn.Forte@Sun.COM cmdName = getExecBasename(argv[0]); 2947836SJohn.Forte@Sun.COM 2957836SJohn.Forte@Sun.COM (void) snprintf(versionString, VERSION_STRING_MAX_LEN, "%s.%s", 2967836SJohn.Forte@Sun.COM VERSION_STRING_MAJOR, VERSION_STRING_MINOR); 2977836SJohn.Forte@Sun.COM synTables.versionString = versionString; 2987836SJohn.Forte@Sun.COM synTables.longOptionTbl = &longOptions[0]; 2997836SJohn.Forte@Sun.COM synTables.subCommandPropsTbl = &subcommands[0]; 3007836SJohn.Forte@Sun.COM 3017836SJohn.Forte@Sun.COM ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet); 3027836SJohn.Forte@Sun.COM if (ret != 0) { 3037836SJohn.Forte@Sun.COM return (ret); 3047836SJohn.Forte@Sun.COM } 3057836SJohn.Forte@Sun.COM 3067836SJohn.Forte@Sun.COM return (funcRet); 3077836SJohn.Forte@Sun.COM } /* end main */ 308