xref: /titanic_44/usr/src/cmd/stmfsvc/stmfsvc.c (revision 86b7dbefda771542da92c8e031c0153fd809ff01)
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 /*
22*86b7dbefSPeter Gill  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23fcf3ce44SJohn Forte  * Use is subject to license terms.
24fcf3ce44SJohn Forte  */
25fcf3ce44SJohn Forte 
26fcf3ce44SJohn Forte #include <stdlib.h>
27fcf3ce44SJohn Forte #include <stdio.h>
28fcf3ce44SJohn Forte #include <strings.h>
29fcf3ce44SJohn Forte #include <sys/types.h>
30fcf3ce44SJohn Forte #include <unistd.h>
31fcf3ce44SJohn Forte #include <libintl.h>
32fcf3ce44SJohn Forte #include <errno.h>
33fcf3ce44SJohn Forte #include <time.h>
34fcf3ce44SJohn Forte #include <string.h>
35fcf3ce44SJohn Forte #include <assert.h>
36fcf3ce44SJohn Forte #include <getopt.h>
37fcf3ce44SJohn Forte #include <cmdparse.h>
38fcf3ce44SJohn Forte #include <libstmf.h>
39fcf3ce44SJohn Forte #include <signal.h>
40fcf3ce44SJohn Forte #include <pthread.h>
41fcf3ce44SJohn Forte #include <locale.h>
42fcf3ce44SJohn Forte 
43fcf3ce44SJohn Forte static int svcStart(int, char **, cmdOptions_t *, void *);
44fcf3ce44SJohn Forte static int svcStop(int, char **, cmdOptions_t *, void *);
45fcf3ce44SJohn Forte static int online();
46fcf3ce44SJohn Forte 
47fcf3ce44SJohn Forte /*
48fcf3ce44SJohn Forte  *  MAJOR - This should only change when there is an incompatible change made
49fcf3ce44SJohn Forte  *  to the interfaces or the output.
50fcf3ce44SJohn Forte  *
51fcf3ce44SJohn Forte  *  MINOR - This should change whenever there is a new command or new feature
52fcf3ce44SJohn Forte  *  with no incompatible change.
53fcf3ce44SJohn Forte  */
54fcf3ce44SJohn Forte #define	VERSION_STRING_MAJOR	    "1"
55fcf3ce44SJohn Forte #define	VERSION_STRING_MINOR	    "0"
56fcf3ce44SJohn Forte #define	VERSION_STRING_MAX_LEN	    10
57fcf3ce44SJohn Forte 
58fcf3ce44SJohn Forte /* 10 ms sleep in nanoseconds */
59fcf3ce44SJohn Forte #define	TEN_MS_NANOSLEEP  10000000
60fcf3ce44SJohn Forte 
61fcf3ce44SJohn Forte /* tables set up based on cmdparse instructions */
62fcf3ce44SJohn Forte 
63fcf3ce44SJohn Forte /* add new options here */
64fcf3ce44SJohn Forte optionTbl_t longOptions[] = {
65fcf3ce44SJohn Forte 	{NULL, 0, 0, 0}
66fcf3ce44SJohn Forte };
67fcf3ce44SJohn Forte 
68fcf3ce44SJohn Forte /*
69fcf3ce44SJohn Forte  * Add new subcommands here
70fcf3ce44SJohn Forte  */
71fcf3ce44SJohn Forte subCommandProps_t subcommands[] = {
72fcf3ce44SJohn Forte 	{"start", svcStart, NULL, NULL, NULL, OPERAND_NONE, NULL},
73fcf3ce44SJohn Forte 	{"stop", svcStop, NULL, NULL, NULL, OPERAND_NONE, NULL},
74fcf3ce44SJohn Forte 	{NULL, 0, NULL, NULL, 0, NULL, 0, NULL}
75fcf3ce44SJohn Forte };
76fcf3ce44SJohn Forte 
77fcf3ce44SJohn Forte /* globals */
78fcf3ce44SJohn Forte char *cmdName;
79fcf3ce44SJohn Forte 
80fcf3ce44SJohn Forte /*
81fcf3ce44SJohn Forte  * svcStop
82fcf3ce44SJohn Forte  *
83fcf3ce44SJohn Forte  * Offlines the stmf service
84fcf3ce44SJohn Forte  *
85fcf3ce44SJohn Forte  */
86fcf3ce44SJohn Forte /*ARGSUSED*/
87fcf3ce44SJohn Forte static int
88fcf3ce44SJohn Forte svcStop(int operandLen, char *operands[], cmdOptions_t *options,
89fcf3ce44SJohn Forte     void *args)
90fcf3ce44SJohn Forte {
91fcf3ce44SJohn Forte 	int stmfRet;
92fcf3ce44SJohn Forte 	int ret = 0;
93fcf3ce44SJohn Forte 	stmfState state;
94fcf3ce44SJohn Forte 	boolean_t serviceOffline = B_FALSE;
95fcf3ce44SJohn Forte 	struct timespec rqtp;
96fcf3ce44SJohn Forte 
97fcf3ce44SJohn Forte 	bzero(&rqtp, sizeof (rqtp));
98fcf3ce44SJohn Forte 
99fcf3ce44SJohn Forte 	rqtp.tv_nsec = TEN_MS_NANOSLEEP;
100fcf3ce44SJohn Forte 
101fcf3ce44SJohn Forte 	if ((stmfRet = stmfOffline()) != STMF_STATUS_SUCCESS) {
102fcf3ce44SJohn Forte 		switch (stmfRet) {
103fcf3ce44SJohn Forte 			case STMF_ERROR_PERM:
104fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
105fcf3ce44SJohn Forte 				    gettext("permission denied"));
106fcf3ce44SJohn Forte 				break;
107fcf3ce44SJohn Forte 			case STMF_ERROR_SERVICE_NOT_FOUND:
108fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
109fcf3ce44SJohn Forte 				    gettext("STMF service not found"));
110fcf3ce44SJohn Forte 				break;
111fcf3ce44SJohn Forte 			case STMF_ERROR_SERVICE_OFFLINE:
112fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
113fcf3ce44SJohn Forte 				    gettext("STMF service already offline"));
114fcf3ce44SJohn Forte 				break;
115fcf3ce44SJohn Forte 			default:
116fcf3ce44SJohn Forte 				(void) fprintf(stderr, "%s: %s\n", cmdName,
117fcf3ce44SJohn Forte 				    gettext("unable to offline service"));
118fcf3ce44SJohn Forte 				break;
119fcf3ce44SJohn Forte 		}
120fcf3ce44SJohn Forte 		return (1);
121fcf3ce44SJohn Forte 	}
122fcf3ce44SJohn Forte 
123fcf3ce44SJohn Forte 	/* wait for service offline */
124fcf3ce44SJohn Forte 	while (!serviceOffline) {
125fcf3ce44SJohn Forte 		stmfRet = stmfGetState(&state);
126fcf3ce44SJohn Forte 		if (stmfRet != STMF_STATUS_SUCCESS) {
127fcf3ce44SJohn Forte 			ret = 1;
128fcf3ce44SJohn Forte 			break;
129fcf3ce44SJohn Forte 		}
130fcf3ce44SJohn Forte 		if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
131fcf3ce44SJohn Forte 			serviceOffline = B_TRUE;
132fcf3ce44SJohn Forte 		} else {
133fcf3ce44SJohn Forte 			(void) nanosleep(&rqtp, NULL);
134fcf3ce44SJohn Forte 		}
135fcf3ce44SJohn Forte 	}
136fcf3ce44SJohn Forte 
137fcf3ce44SJohn Forte 	return (ret);
138fcf3ce44SJohn Forte }
139fcf3ce44SJohn Forte 
140fcf3ce44SJohn Forte /*
141fcf3ce44SJohn Forte  * loadConfig
142fcf3ce44SJohn Forte  *
143fcf3ce44SJohn Forte  * Loads the stmf config from the SMF repository
144fcf3ce44SJohn Forte  *
145fcf3ce44SJohn Forte  */
146fcf3ce44SJohn Forte /*ARGSUSED*/
147fcf3ce44SJohn Forte static int
148fcf3ce44SJohn Forte svcStart(int operandLen, char *operands[], cmdOptions_t *options,
149fcf3ce44SJohn Forte     void *args)
150fcf3ce44SJohn Forte {
151fcf3ce44SJohn Forte 	int stmfRet;
152fcf3ce44SJohn Forte 	int ret = 0;
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,
169*86b7dbefSPeter Gill 				    gettext("Unable to load the configuration. "
170*86b7dbefSPeter Gill 				    "See /var/adm/messages for details"));
171*86b7dbefSPeter Gill 				(void) fprintf(stderr, "%s: %s\n", cmdName,
172*86b7dbefSPeter Gill 				    gettext("For information on reverting the "
173*86b7dbefSPeter Gill 				    "stmf:default instance to a previously "
174*86b7dbefSPeter Gill 				    "running configuration see the man page "
175*86b7dbefSPeter Gill 				    "for svccfg(1M)"));
176*86b7dbefSPeter Gill 				(void) fprintf(stderr, "%s: %s\n", cmdName,
177*86b7dbefSPeter Gill 				    gettext("After reverting the instance "
178*86b7dbefSPeter Gill 				    "you must clear the service maintenance "
179*86b7dbefSPeter Gill 				    "state. See the man page for svcadm(1M)"));
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
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 *
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
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