xref: /illumos-gate/usr/src/cmd/stmfsvc/stmfsvc.c (revision bbf21555)
1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte /*
224b31676fSsrivijitha dugganapalli  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23fcf3ce44SJohn Forte  */
24fcf3ce44SJohn Forte 
25fcf3ce44SJohn Forte #include <stdlib.h>
26fcf3ce44SJohn Forte #include <stdio.h>
27fcf3ce44SJohn Forte #include <strings.h>
28fcf3ce44SJohn Forte #include <sys/types.h>
29fcf3ce44SJohn Forte #include <unistd.h>
30fcf3ce44SJohn Forte #include <libintl.h>
31fcf3ce44SJohn Forte #include <errno.h>
32fcf3ce44SJohn Forte #include <time.h>
33fcf3ce44SJohn Forte #include <string.h>
34fcf3ce44SJohn Forte #include <assert.h>
35fcf3ce44SJohn Forte #include <getopt.h>
36fcf3ce44SJohn Forte #include <cmdparse.h>
37fcf3ce44SJohn Forte #include <libstmf.h>
38fcf3ce44SJohn Forte #include <signal.h>
39fcf3ce44SJohn Forte #include <pthread.h>
40fcf3ce44SJohn Forte #include <locale.h>
41fcf3ce44SJohn Forte 
42fcf3ce44SJohn Forte static int svcStart(int, char **, cmdOptions_t *, void *);
43fcf3ce44SJohn Forte static int svcStop(int, char **, cmdOptions_t *, void *);
44fcf3ce44SJohn Forte static int online();
45fcf3ce44SJohn Forte 
46fcf3ce44SJohn Forte /*
47fcf3ce44SJohn Forte  *  MAJOR - This should only change when there is an incompatible change made
48fcf3ce44SJohn Forte  *  to the interfaces or the output.
49fcf3ce44SJohn Forte  *
50fcf3ce44SJohn Forte  *  MINOR - This should change whenever there is a new command or new feature
51fcf3ce44SJohn Forte  *  with no incompatible change.
52fcf3ce44SJohn Forte  */
53fcf3ce44SJohn Forte #define	VERSION_STRING_MAJOR	    "1"
54fcf3ce44SJohn Forte #define	VERSION_STRING_MINOR	    "0"
55fcf3ce44SJohn Forte #define	VERSION_STRING_MAX_LEN	    10
56fcf3ce44SJohn Forte 
57fcf3ce44SJohn Forte /* 10 ms sleep in nanoseconds */
58fcf3ce44SJohn Forte #define	TEN_MS_NANOSLEEP  10000000
59fcf3ce44SJohn Forte 
60fcf3ce44SJohn Forte /* tables set up based on cmdparse instructions */
61fcf3ce44SJohn Forte 
62fcf3ce44SJohn Forte /* add new options here */
63fcf3ce44SJohn Forte optionTbl_t longOptions[] = {
64fcf3ce44SJohn Forte 	{NULL, 0, 0, 0}
65fcf3ce44SJohn Forte };
66fcf3ce44SJohn Forte 
67fcf3ce44SJohn Forte /*
68fcf3ce44SJohn Forte  * Add new subcommands here
69fcf3ce44SJohn Forte  */
70fcf3ce44SJohn Forte subCommandProps_t subcommands[] = {
71fcf3ce44SJohn Forte 	{"start", svcStart, NULL, NULL, NULL, OPERAND_NONE, NULL},
72fcf3ce44SJohn Forte 	{"stop", svcStop, NULL, NULL, NULL, OPERAND_NONE, NULL},
73e9f63cd6SToomas Soome 	{NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL}
74fcf3ce44SJohn Forte };
75fcf3ce44SJohn Forte 
76fcf3ce44SJohn Forte /* globals */
77fcf3ce44SJohn Forte char *cmdName;
78fcf3ce44SJohn Forte 
79fcf3ce44SJohn Forte /*
80fcf3ce44SJohn Forte  * svcStop
81fcf3ce44SJohn Forte  *
82fcf3ce44SJohn Forte  * Offlines the stmf service
83fcf3ce44SJohn Forte  *
84fcf3ce44SJohn Forte  */
85fcf3ce44SJohn Forte /*ARGSUSED*/
86fcf3ce44SJohn Forte static int
svcStop(int operandLen,char * operands[],cmdOptions_t * options,void * args)87fcf3ce44SJohn Forte svcStop(int operandLen, char *operands[], cmdOptions_t *options,
88fcf3ce44SJohn Forte     void *args)
89fcf3ce44SJohn Forte {
90fcf3ce44SJohn Forte 	int stmfRet;
91fcf3ce44SJohn Forte 	int ret = 0;
92fcf3ce44SJohn Forte 	stmfState state;
93fcf3ce44SJohn Forte 	boolean_t serviceOffline = B_FALSE;
94fcf3ce44SJohn Forte 	struct timespec rqtp;
95fcf3ce44SJohn Forte 
96fcf3ce44SJohn Forte 	bzero(&rqtp, sizeof (rqtp));
97fcf3ce44SJohn Forte 
98fcf3ce44SJohn Forte 	rqtp.tv_nsec = TEN_MS_NANOSLEEP;
99fcf3ce44SJohn Forte 
100fcf3ce44SJohn Forte 	if ((stmfRet = stmfOffline()) != STMF_STATUS_SUCCESS) {
101fcf3ce44SJohn Forte 		switch (stmfRet) {
102fcf3ce44SJohn Forte 			case STMF_ERROR_PERM:
103fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
104fcf3ce44SJohn Forte 				    gettext("permission denied"));
105fcf3ce44SJohn Forte 				break;
106fcf3ce44SJohn Forte 			case STMF_ERROR_SERVICE_NOT_FOUND:
107fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
108fcf3ce44SJohn Forte 				    gettext("STMF service not found"));
109fcf3ce44SJohn Forte 				break;
110fcf3ce44SJohn Forte 			case STMF_ERROR_SERVICE_OFFLINE:
111fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
112fcf3ce44SJohn Forte 				    gettext("STMF service already offline"));
113fcf3ce44SJohn Forte 				break;
114fcf3ce44SJohn Forte 			default:
115fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
116fcf3ce44SJohn Forte 				    gettext("unable to offline service"));
117fcf3ce44SJohn Forte 				break;
118fcf3ce44SJohn Forte 		}
119fcf3ce44SJohn Forte 		return (1);
120fcf3ce44SJohn Forte 	}
121fcf3ce44SJohn Forte 
122fcf3ce44SJohn Forte 	/* wait for service offline */
123fcf3ce44SJohn Forte 	while (!serviceOffline) {
124fcf3ce44SJohn Forte 		stmfRet = stmfGetState(&state);
125fcf3ce44SJohn Forte 		if (stmfRet != STMF_STATUS_SUCCESS) {
126fcf3ce44SJohn Forte 			ret = 1;
127fcf3ce44SJohn Forte 			break;
128fcf3ce44SJohn Forte 		}
129fcf3ce44SJohn Forte 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
130fcf3ce44SJohn Forte 			serviceOffline = B_TRUE;
131fcf3ce44SJohn Forte 		} else {
132fcf3ce44SJohn Forte 			(void) nanosleep(&rqtp, NULL);
133fcf3ce44SJohn Forte 		}
134fcf3ce44SJohn Forte 	}
135fcf3ce44SJohn Forte 
136fcf3ce44SJohn Forte 	return (ret);
137fcf3ce44SJohn Forte }
138fcf3ce44SJohn Forte 
139fcf3ce44SJohn Forte /*
140fcf3ce44SJohn Forte  * loadConfig
141fcf3ce44SJohn Forte  *
142fcf3ce44SJohn Forte  * Loads the stmf config from the SMF repository
143fcf3ce44SJohn Forte  *
144fcf3ce44SJohn Forte  */
145fcf3ce44SJohn Forte /*ARGSUSED*/
146fcf3ce44SJohn Forte static int
svcStart(int operandLen,char * operands[],cmdOptions_t * options,void * args)147fcf3ce44SJohn Forte svcStart(int operandLen, char *operands[], cmdOptions_t *options,
148fcf3ce44SJohn Forte     void *args)
149fcf3ce44SJohn Forte {
150fcf3ce44SJohn Forte 	int stmfRet;
151fcf3ce44SJohn Forte 	int ret = 0;
1524b31676fSsrivijitha dugganapalli 	(void) stmfLoadStmfProps();
153fcf3ce44SJohn Forte 	if ((stmfRet = stmfLoadConfig()) != STMF_STATUS_SUCCESS) {
154fcf3ce44SJohn Forte 		switch (stmfRet) {
155fcf3ce44SJohn Forte 			case STMF_ERROR_PERM:
156fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
157fcf3ce44SJohn Forte 				    gettext("permission denied"));
158fcf3ce44SJohn Forte 				break;
159fcf3ce44SJohn Forte 			case STMF_ERROR_SERVICE_NOT_FOUND:
160fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
161fcf3ce44SJohn Forte 				    gettext("STMF service not found"));
162fcf3ce44SJohn Forte 				break;
163fcf3ce44SJohn Forte 			case STMF_ERROR_SERVICE_ONLINE:
164fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
165fcf3ce44SJohn Forte 				    gettext("STMF service must be offline"));
166fcf3ce44SJohn Forte 				break;
167fcf3ce44SJohn Forte 			default:
168fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
16986b7dbefSPeter Gill 				    gettext("Unable to load the configuration. "
17086b7dbefSPeter Gill 				    "See /var/adm/messages for details"));
17186b7dbefSPeter Gill 				(void) fprintf(stderr, "%s: %s\n", cmdName,
17286b7dbefSPeter Gill 				    gettext("For information on reverting the "
17386b7dbefSPeter Gill 				    "stmf:default instance to a previously "
17486b7dbefSPeter Gill 				    "running configuration see the man page "
175*bbf21555SRichard Lowe 				    "for svccfg(8)"));
17686b7dbefSPeter Gill 				(void) fprintf(stderr, "%s: %s\n", cmdName,
17786b7dbefSPeter Gill 				    gettext("After reverting the instance "
17886b7dbefSPeter Gill 				    "you must clear the service maintenance "
179*bbf21555SRichard Lowe 				    "state. See the man page for svcadm(8)"));
180fcf3ce44SJohn Forte 				break;
181fcf3ce44SJohn Forte 		}
182fcf3ce44SJohn Forte 		return (1);
183fcf3ce44SJohn Forte 	}
184fcf3ce44SJohn Forte 	ret = online();
185fcf3ce44SJohn Forte 	return (ret);
186fcf3ce44SJohn Forte 
187fcf3ce44SJohn Forte }
188fcf3ce44SJohn Forte 
189fcf3ce44SJohn Forte /*
190fcf3ce44SJohn Forte  * online
191fcf3ce44SJohn Forte  *
192fcf3ce44SJohn Forte  * Onlines the stmf service
193fcf3ce44SJohn Forte  *
194fcf3ce44SJohn Forte  */
195fcf3ce44SJohn Forte /*ARGSUSED*/
196fcf3ce44SJohn Forte static int
online()197fcf3ce44SJohn Forte online()
198fcf3ce44SJohn Forte {
199fcf3ce44SJohn Forte 	int stmfRet;
200fcf3ce44SJohn Forte 	int ret = 0;
201fcf3ce44SJohn Forte 	stmfState state;
202fcf3ce44SJohn Forte 	boolean_t serviceOnline = B_FALSE;
203fcf3ce44SJohn Forte 	struct timespec rqtp;
204fcf3ce44SJohn Forte 
205fcf3ce44SJohn Forte 	bzero(&rqtp, sizeof (rqtp));
206fcf3ce44SJohn Forte 
207fcf3ce44SJohn Forte 	rqtp.tv_nsec = TEN_MS_NANOSLEEP;
208fcf3ce44SJohn Forte 
209fcf3ce44SJohn Forte 	if ((stmfRet = stmfOnline()) != STMF_STATUS_SUCCESS) {
210fcf3ce44SJohn Forte 		switch (stmfRet) {
211fcf3ce44SJohn Forte 			case STMF_ERROR_PERM:
212fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
213fcf3ce44SJohn Forte 				    gettext("permission denied"));
214fcf3ce44SJohn Forte 				break;
215fcf3ce44SJohn Forte 			case STMF_ERROR_SERVICE_NOT_FOUND:
216fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
217fcf3ce44SJohn Forte 				    gettext("STMF service not found"));
218fcf3ce44SJohn Forte 				break;
219fcf3ce44SJohn Forte 			case STMF_ERROR_SERVICE_ONLINE:
220fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
221fcf3ce44SJohn Forte 				    gettext("STMF service already online"));
222fcf3ce44SJohn Forte 				break;
223fcf3ce44SJohn Forte 			default:
224fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
225fcf3ce44SJohn Forte 				    gettext("unable to online service"));
226fcf3ce44SJohn Forte 				break;
227fcf3ce44SJohn Forte 		}
228fcf3ce44SJohn Forte 		return (1);
229fcf3ce44SJohn Forte 	}
230fcf3ce44SJohn Forte 
231fcf3ce44SJohn Forte 	/* wait for service online */
232fcf3ce44SJohn Forte 	while (!serviceOnline) {
233fcf3ce44SJohn Forte 		stmfRet = stmfGetState(&state);
234fcf3ce44SJohn Forte 		if (stmfRet != STMF_STATUS_SUCCESS) {
235fcf3ce44SJohn Forte 			ret = 1;
236fcf3ce44SJohn Forte 			break;
237fcf3ce44SJohn Forte 		}
238fcf3ce44SJohn Forte 		if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
239fcf3ce44SJohn Forte 			serviceOnline = B_TRUE;
240fcf3ce44SJohn Forte 		} else {
241fcf3ce44SJohn Forte 			(void) nanosleep(&rqtp, NULL);
242fcf3ce44SJohn Forte 		}
243fcf3ce44SJohn Forte 	}
244fcf3ce44SJohn Forte 
245fcf3ce44SJohn Forte 	return (ret);
246fcf3ce44SJohn Forte }
247fcf3ce44SJohn Forte 
248fcf3ce44SJohn Forte 
249fcf3ce44SJohn Forte /*
250fcf3ce44SJohn Forte  * input:
251fcf3ce44SJohn Forte  *  execFullName - exec name of program (argv[0])
252fcf3ce44SJohn Forte  *
253fcf3ce44SJohn Forte  *  copied from usr/src/cmd/zoneadm/zoneadm.c in OS/Net
254fcf3ce44SJohn Forte  *  (changed name to lowerCamelCase to keep consistent with this file)
255fcf3ce44SJohn Forte  *
256fcf3ce44SJohn Forte  * Returns:
257fcf3ce44SJohn Forte  *  command name portion of execFullName
258fcf3ce44SJohn Forte  */
259fcf3ce44SJohn Forte static char *
getExecBasename(char * execFullname)260fcf3ce44SJohn Forte getExecBasename(char *execFullname)
261fcf3ce44SJohn Forte {
262fcf3ce44SJohn Forte 	char *lastSlash, *execBasename;
263fcf3ce44SJohn Forte 
264fcf3ce44SJohn Forte 	/* guard against '/' at end of command invocation */
265fcf3ce44SJohn Forte 	for (;;) {
266fcf3ce44SJohn Forte 		lastSlash = strrchr(execFullname, '/');
267fcf3ce44SJohn Forte 		if (lastSlash == NULL) {
268fcf3ce44SJohn Forte 			execBasename = execFullname;
269fcf3ce44SJohn Forte 			break;
270fcf3ce44SJohn Forte 		} else {
271fcf3ce44SJohn Forte 			execBasename = lastSlash + 1;
272fcf3ce44SJohn Forte 			if (*execBasename == '\0') {
273fcf3ce44SJohn Forte 				*lastSlash = '\0';
274fcf3ce44SJohn Forte 				continue;
275fcf3ce44SJohn Forte 			}
276fcf3ce44SJohn Forte 			break;
277fcf3ce44SJohn Forte 		}
278fcf3ce44SJohn Forte 	}
279fcf3ce44SJohn Forte 	return (execBasename);
280fcf3ce44SJohn Forte }
281fcf3ce44SJohn Forte 
282fcf3ce44SJohn Forte int
main(int argc,char * argv[])283fcf3ce44SJohn Forte main(int argc, char *argv[])
284fcf3ce44SJohn Forte {
285fcf3ce44SJohn Forte 	synTables_t synTables;
286fcf3ce44SJohn Forte 	char versionString[VERSION_STRING_MAX_LEN];
287fcf3ce44SJohn Forte 	int ret;
288fcf3ce44SJohn Forte 	int funcRet;
289fcf3ce44SJohn Forte 	void *subcommandArgs = NULL;
290fcf3ce44SJohn Forte 
291fcf3ce44SJohn Forte 	(void) setlocale(LC_ALL, "");
292fcf3ce44SJohn Forte 	/* set global command name */
293fcf3ce44SJohn Forte 	cmdName = getExecBasename(argv[0]);
294fcf3ce44SJohn Forte 
295fcf3ce44SJohn Forte 	(void) snprintf(versionString, VERSION_STRING_MAX_LEN, "%s.%s",
296fcf3ce44SJohn Forte 	    VERSION_STRING_MAJOR, VERSION_STRING_MINOR);
297fcf3ce44SJohn Forte 	synTables.versionString = versionString;
298fcf3ce44SJohn Forte 	synTables.longOptionTbl = &longOptions[0];
299fcf3ce44SJohn Forte 	synTables.subCommandPropsTbl = &subcommands[0];
300fcf3ce44SJohn Forte 
301fcf3ce44SJohn Forte 	ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet);
302fcf3ce44SJohn Forte 	if (ret != 0) {
303fcf3ce44SJohn Forte 		return (ret);
304fcf3ce44SJohn Forte 	}
305fcf3ce44SJohn Forte 
306fcf3ce44SJohn Forte 	return (funcRet);
307fcf3ce44SJohn Forte } /* end main */
308