xref: /illumos-gate/usr/src/cmd/tzreload/tzreload.c (revision d1419d5a)
1*d1419d5aSNobutomo Nakano /*
2*d1419d5aSNobutomo Nakano  * CDDL HEADER START
3*d1419d5aSNobutomo Nakano  *
4*d1419d5aSNobutomo Nakano  * The contents of this file are subject to the terms of the
5*d1419d5aSNobutomo Nakano  * Common Development and Distribution License (the "License").
6*d1419d5aSNobutomo Nakano  * You may not use this file except in compliance with the License.
7*d1419d5aSNobutomo Nakano  *
8*d1419d5aSNobutomo Nakano  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d1419d5aSNobutomo Nakano  * or http://www.opensolaris.org/os/licensing.
10*d1419d5aSNobutomo Nakano  * See the License for the specific language governing permissions
11*d1419d5aSNobutomo Nakano  * and limitations under the License.
12*d1419d5aSNobutomo Nakano  *
13*d1419d5aSNobutomo Nakano  * When distributing Covered Code, include this CDDL HEADER in each
14*d1419d5aSNobutomo Nakano  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d1419d5aSNobutomo Nakano  * If applicable, add the following below this CDDL HEADER, with the
16*d1419d5aSNobutomo Nakano  * fields enclosed by brackets "[]" replaced with your own identifying
17*d1419d5aSNobutomo Nakano  * information: Portions Copyright [yyyy] [name of copyright owner]
18*d1419d5aSNobutomo Nakano  *
19*d1419d5aSNobutomo Nakano  * CDDL HEADER END
20*d1419d5aSNobutomo Nakano  */
21*d1419d5aSNobutomo Nakano 
22*d1419d5aSNobutomo Nakano /*
23*d1419d5aSNobutomo Nakano  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*d1419d5aSNobutomo Nakano  * Use is subject to license terms.
25*d1419d5aSNobutomo Nakano  */
26*d1419d5aSNobutomo Nakano 
27*d1419d5aSNobutomo Nakano /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*d1419d5aSNobutomo Nakano /*	All Rights Reserved	*/
29*d1419d5aSNobutomo Nakano 
30*d1419d5aSNobutomo Nakano #include <atomic.h>
31*d1419d5aSNobutomo Nakano #include <errno.h>
32*d1419d5aSNobutomo Nakano #include <fcntl.h>
33*d1419d5aSNobutomo Nakano #include <limits.h>
34*d1419d5aSNobutomo Nakano #include <stdio.h>
35*d1419d5aSNobutomo Nakano #include <stdlib.h>
36*d1419d5aSNobutomo Nakano #include <string.h>
37*d1419d5aSNobutomo Nakano #include <unistd.h>
38*d1419d5aSNobutomo Nakano #include <sys/mman.h>
39*d1419d5aSNobutomo Nakano #include <sys/stat.h>
40*d1419d5aSNobutomo Nakano #include <locale.h>
41*d1419d5aSNobutomo Nakano #include <libintl.h>
42*d1419d5aSNobutomo Nakano #include <zone.h>
43*d1419d5aSNobutomo Nakano #include <libzonecfg.h>
44*d1419d5aSNobutomo Nakano #include <sys/brand.h>
45*d1419d5aSNobutomo Nakano #include <dlfcn.h>
46*d1419d5aSNobutomo Nakano 
47*d1419d5aSNobutomo Nakano #define	TZSYNC_FILE	"/var/run/tzsync"
48*d1419d5aSNobutomo Nakano 
49*d1419d5aSNobutomo Nakano static void	init_file(void);
50*d1419d5aSNobutomo Nakano static void	doit(const char *zname, const char *zroot, int get);
51*d1419d5aSNobutomo Nakano static void	counter_get(const char *zname, int fd);
52*d1419d5aSNobutomo Nakano static void	counter_set(int fd);
53*d1419d5aSNobutomo Nakano static void	walk_zones(int get);
54*d1419d5aSNobutomo Nakano static void	send_cron_msg(const char *zname, const char *zroot);
55*d1419d5aSNobutomo Nakano 
56*d1419d5aSNobutomo Nakano /*
57*d1419d5aSNobutomo Nakano  * There are undocumeted command line options:
58*d1419d5aSNobutomo Nakano  * -l	list the value of semaphore.
59*d1419d5aSNobutomo Nakano  * -I	initialize the semaphore file (ie /var/run/tzsync)
60*d1419d5aSNobutomo Nakano  */
61*d1419d5aSNobutomo Nakano 
62*d1419d5aSNobutomo Nakano int
main(int argc,char ** argv)63*d1419d5aSNobutomo Nakano main(int argc, char **argv)
64*d1419d5aSNobutomo Nakano {
65*d1419d5aSNobutomo Nakano 	int	arg;
66*d1419d5aSNobutomo Nakano 	int	all = 0, get = 0, init = 0;
67*d1419d5aSNobutomo Nakano 
68*d1419d5aSNobutomo Nakano 	(void) setlocale(LC_ALL, "");
69*d1419d5aSNobutomo Nakano 	(void) textdomain(TEXT_DOMAIN);
70*d1419d5aSNobutomo Nakano 
71*d1419d5aSNobutomo Nakano 	while ((arg = getopt(argc, argv, "alI")) != EOF) {
72*d1419d5aSNobutomo Nakano 		switch (arg) {
73*d1419d5aSNobutomo Nakano 		case 'a':
74*d1419d5aSNobutomo Nakano 			all = 1;
75*d1419d5aSNobutomo Nakano 			break;
76*d1419d5aSNobutomo Nakano 		case 'l':
77*d1419d5aSNobutomo Nakano 			get = 1;
78*d1419d5aSNobutomo Nakano 			break;
79*d1419d5aSNobutomo Nakano 		case 'I':
80*d1419d5aSNobutomo Nakano 			init = 1;
81*d1419d5aSNobutomo Nakano 			break;
82*d1419d5aSNobutomo Nakano 		default:
83*d1419d5aSNobutomo Nakano 			(void) fprintf(stderr,
84*d1419d5aSNobutomo Nakano 			    gettext("Usage: tzreload [-a]\n"));
85*d1419d5aSNobutomo Nakano 			exit(1);
86*d1419d5aSNobutomo Nakano 		}
87*d1419d5aSNobutomo Nakano 	}
88*d1419d5aSNobutomo Nakano 
89*d1419d5aSNobutomo Nakano 	if (init) {
90*d1419d5aSNobutomo Nakano 		init_file();
91*d1419d5aSNobutomo Nakano 		return (0);
92*d1419d5aSNobutomo Nakano 	}
93*d1419d5aSNobutomo Nakano 
94*d1419d5aSNobutomo Nakano 	if (all)
95*d1419d5aSNobutomo Nakano 		walk_zones(get);
96*d1419d5aSNobutomo Nakano 	else
97*d1419d5aSNobutomo Nakano 		doit(NULL, "", get);
98*d1419d5aSNobutomo Nakano 
99*d1419d5aSNobutomo Nakano 	return (0);
100*d1419d5aSNobutomo Nakano }
101*d1419d5aSNobutomo Nakano 
102*d1419d5aSNobutomo Nakano /*
103*d1419d5aSNobutomo Nakano  * Create /var/run/tzsync atomically.
104*d1419d5aSNobutomo Nakano  *
105*d1419d5aSNobutomo Nakano  * While creating the /var/run/tzsync initially, there is a timing window
106*d1419d5aSNobutomo Nakano  * that the file is created but no disk block is allocated (empty file).
107*d1419d5aSNobutomo Nakano  * If apps mmap'ed the file at the very moment, it succeeds but accessing
108*d1419d5aSNobutomo Nakano  * the memory page causes a segfault since disk block isn't yet allocated.
109*d1419d5aSNobutomo Nakano  * To avoid this situation, we create a temp file which has pagesize block
110*d1419d5aSNobutomo Nakano  * assigned, and then rename it to tzsync.
111*d1419d5aSNobutomo Nakano  */
112*d1419d5aSNobutomo Nakano static void
init_file(void)113*d1419d5aSNobutomo Nakano init_file(void)
114*d1419d5aSNobutomo Nakano {
115*d1419d5aSNobutomo Nakano 	char	path[sizeof (TZSYNC_FILE) + 16];
116*d1419d5aSNobutomo Nakano 	char	*buf;
117*d1419d5aSNobutomo Nakano 	int	fd, pgsz;
118*d1419d5aSNobutomo Nakano 	struct stat st;
119*d1419d5aSNobutomo Nakano 
120*d1419d5aSNobutomo Nakano 	/* We don't allow to re-create the file */
121*d1419d5aSNobutomo Nakano 	if (stat(TZSYNC_FILE, &st) == 0) {
122*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr, gettext("%s already exists.\n"),
123*d1419d5aSNobutomo Nakano 		    TZSYNC_FILE);
124*d1419d5aSNobutomo Nakano 		exit(1);
125*d1419d5aSNobutomo Nakano 	}
126*d1419d5aSNobutomo Nakano 
127*d1419d5aSNobutomo Nakano 	pgsz = sysconf(_SC_PAGESIZE);
128*d1419d5aSNobutomo Nakano 
129*d1419d5aSNobutomo Nakano 	(void) strcpy(path, TZSYNC_FILE "XXXXXX");
130*d1419d5aSNobutomo Nakano 	if ((fd = mkstemp(path)) == -1) {
131*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr,
132*d1419d5aSNobutomo Nakano 		    gettext("failed to create a temporary file.\n"));
133*d1419d5aSNobutomo Nakano 		exit(1);
134*d1419d5aSNobutomo Nakano 	}
135*d1419d5aSNobutomo Nakano 
136*d1419d5aSNobutomo Nakano 	if ((buf = calloc(1, pgsz)) == NULL) {
137*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr, gettext("Insufficient memory.\n"));
138*d1419d5aSNobutomo Nakano errout:
139*d1419d5aSNobutomo Nakano 		(void) close(fd);
140*d1419d5aSNobutomo Nakano 		(void) unlink(path);
141*d1419d5aSNobutomo Nakano 		exit(1);
142*d1419d5aSNobutomo Nakano 	}
143*d1419d5aSNobutomo Nakano 
144*d1419d5aSNobutomo Nakano 	if (write(fd, buf, pgsz) != pgsz) {
145*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr,
146*d1419d5aSNobutomo Nakano 		    gettext("failed to create tzsync file, %s\n"),
147*d1419d5aSNobutomo Nakano 		    strerror(errno));
148*d1419d5aSNobutomo Nakano 		goto errout;
149*d1419d5aSNobutomo Nakano 	}
150*d1419d5aSNobutomo Nakano 	(void) close(fd);
151*d1419d5aSNobutomo Nakano 
152*d1419d5aSNobutomo Nakano 	/* link it */
153*d1419d5aSNobutomo Nakano 	if (link(path, TZSYNC_FILE) != 0) {
154*d1419d5aSNobutomo Nakano 		if (errno == EEXIST) {
155*d1419d5aSNobutomo Nakano 			(void) fprintf(stderr, gettext("%s already exists.\n"),
156*d1419d5aSNobutomo Nakano 			    TZSYNC_FILE);
157*d1419d5aSNobutomo Nakano 		} else {
158*d1419d5aSNobutomo Nakano 			(void) fprintf(stderr, gettext("failed to create %s\n"),
159*d1419d5aSNobutomo Nakano 			    TZSYNC_FILE);
160*d1419d5aSNobutomo Nakano 		}
161*d1419d5aSNobutomo Nakano 		(void) unlink(path);
162*d1419d5aSNobutomo Nakano 		exit(1);
163*d1419d5aSNobutomo Nakano 	}
164*d1419d5aSNobutomo Nakano 	(void) unlink(path);
165*d1419d5aSNobutomo Nakano 
166*d1419d5aSNobutomo Nakano 	/*
167*d1419d5aSNobutomo Nakano 	 * Unplivileged apps may fail to open the file until the chmod
168*d1419d5aSNobutomo Nakano 	 * below succeeds. However, it's okay as long as open() fails;
169*d1419d5aSNobutomo Nakano 	 * ctime() won't cache zoneinfo until file is opened and mmap'd.
170*d1419d5aSNobutomo Nakano 	 */
171*d1419d5aSNobutomo Nakano 
172*d1419d5aSNobutomo Nakano 	/* /var/run/tzsync has been made. Adjust permission */
173*d1419d5aSNobutomo Nakano 	if (chmod(TZSYNC_FILE, 0644) != 0) {
174*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr,
175*d1419d5aSNobutomo Nakano 		    gettext("failed to change permission of %s\n"),
176*d1419d5aSNobutomo Nakano 		    TZSYNC_FILE);
177*d1419d5aSNobutomo Nakano 		(void) unlink(TZSYNC_FILE);
178*d1419d5aSNobutomo Nakano 		exit(1);
179*d1419d5aSNobutomo Nakano 	}
180*d1419d5aSNobutomo Nakano }
181*d1419d5aSNobutomo Nakano 
182*d1419d5aSNobutomo Nakano /*
183*d1419d5aSNobutomo Nakano  * Open the /var/run/tzsync, then set or get the semaphore.
184*d1419d5aSNobutomo Nakano  *
185*d1419d5aSNobutomo Nakano  * zname	name of zone (NULL if no need to consider zones)
186*d1419d5aSNobutomo Nakano  * zroot	zone's root path
187*d1419d5aSNobutomo Nakano  * get		get/set semaphore
188*d1419d5aSNobutomo Nakano  */
189*d1419d5aSNobutomo Nakano static void
doit(const char * zname,const char * zroot,int get)190*d1419d5aSNobutomo Nakano doit(const char *zname, const char *zroot, int get)
191*d1419d5aSNobutomo Nakano {
192*d1419d5aSNobutomo Nakano 	int	fd;
193*d1419d5aSNobutomo Nakano 	char	file[PATH_MAX + 1];
194*d1419d5aSNobutomo Nakano 
195*d1419d5aSNobutomo Nakano 	if (strlcpy(file, zroot, sizeof (file)) >= sizeof (file) ||
196*d1419d5aSNobutomo Nakano 	    strlcat(file, TZSYNC_FILE, sizeof (file)) >= sizeof (file)) {
197*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr, gettext("zonepath too long\n"));
198*d1419d5aSNobutomo Nakano 		exit(1);
199*d1419d5aSNobutomo Nakano 	}
200*d1419d5aSNobutomo Nakano 
201*d1419d5aSNobutomo Nakano 	if ((fd = open(file, get ? O_RDONLY : O_RDWR)) < 0) {
202*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr,
203*d1419d5aSNobutomo Nakano 		    gettext("Can't open file %s, %s\n"),
204*d1419d5aSNobutomo Nakano 		    file, strerror(errno));
205*d1419d5aSNobutomo Nakano 		exit(1);
206*d1419d5aSNobutomo Nakano 	}
207*d1419d5aSNobutomo Nakano 
208*d1419d5aSNobutomo Nakano 	if (get) {
209*d1419d5aSNobutomo Nakano 		counter_get(zname, fd);
210*d1419d5aSNobutomo Nakano 	} else {
211*d1419d5aSNobutomo Nakano 		counter_set(fd);
212*d1419d5aSNobutomo Nakano 		/* let cron reschedule events */
213*d1419d5aSNobutomo Nakano 		send_cron_msg(zname, zroot);
214*d1419d5aSNobutomo Nakano 	}
215*d1419d5aSNobutomo Nakano 
216*d1419d5aSNobutomo Nakano 	(void) close(fd);
217*d1419d5aSNobutomo Nakano }
218*d1419d5aSNobutomo Nakano 
219*d1419d5aSNobutomo Nakano /*
220*d1419d5aSNobutomo Nakano  * Get semaphore value and print.
221*d1419d5aSNobutomo Nakano  */
222*d1419d5aSNobutomo Nakano static void
counter_get(const char * zname,int fd)223*d1419d5aSNobutomo Nakano counter_get(const char *zname, int fd)
224*d1419d5aSNobutomo Nakano {
225*d1419d5aSNobutomo Nakano 	uint32_t counter;
226*d1419d5aSNobutomo Nakano 	caddr_t	addr;
227*d1419d5aSNobutomo Nakano 
228*d1419d5aSNobutomo Nakano 	addr = mmap(NULL, sizeof (uint32_t), PROT_READ, MAP_SHARED, fd, 0);
229*d1419d5aSNobutomo Nakano 	if (addr == MAP_FAILED) {
230*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr,
231*d1419d5aSNobutomo Nakano 		    gettext("Error mapping semaphore: %s\n"),
232*d1419d5aSNobutomo Nakano 		    strerror(errno));
233*d1419d5aSNobutomo Nakano 		exit(1);
234*d1419d5aSNobutomo Nakano 	}
235*d1419d5aSNobutomo Nakano 	counter = *(uint32_t *)(uintptr_t)addr;
236*d1419d5aSNobutomo Nakano 
237*d1419d5aSNobutomo Nakano 	(void) munmap(addr, sizeof (uint32_t));
238*d1419d5aSNobutomo Nakano 
239*d1419d5aSNobutomo Nakano 	if (zname == NULL)
240*d1419d5aSNobutomo Nakano 		(void) printf("%u\n", counter);
241*d1419d5aSNobutomo Nakano 	else
242*d1419d5aSNobutomo Nakano 		(void) printf("%-20s %u\n", zname, counter);
243*d1419d5aSNobutomo Nakano 
244*d1419d5aSNobutomo Nakano }
245*d1419d5aSNobutomo Nakano 
246*d1419d5aSNobutomo Nakano /*
247*d1419d5aSNobutomo Nakano  * Increment semaphore value.
248*d1419d5aSNobutomo Nakano  */
249*d1419d5aSNobutomo Nakano static void
counter_set(int fd)250*d1419d5aSNobutomo Nakano counter_set(int fd)
251*d1419d5aSNobutomo Nakano {
252*d1419d5aSNobutomo Nakano 	caddr_t	addr;
253*d1419d5aSNobutomo Nakano 
254*d1419d5aSNobutomo Nakano 	addr = mmap(NULL, sizeof (uint32_t), PROT_READ|PROT_WRITE,
255*d1419d5aSNobutomo Nakano 	    MAP_SHARED, fd, 0);
256*d1419d5aSNobutomo Nakano 	if (addr == MAP_FAILED) {
257*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr,
258*d1419d5aSNobutomo Nakano 		    gettext("Error mapping semaphore: %s\n"),
259*d1419d5aSNobutomo Nakano 		    strerror(errno));
260*d1419d5aSNobutomo Nakano 		exit(1);
261*d1419d5aSNobutomo Nakano 	}
262*d1419d5aSNobutomo Nakano 
263*d1419d5aSNobutomo Nakano 	/*LINTED*/
264*d1419d5aSNobutomo Nakano 	atomic_add_32((uint32_t *)addr, 1);
265*d1419d5aSNobutomo Nakano 
266*d1419d5aSNobutomo Nakano 	(void) munmap(addr, sizeof (uint32_t));
267*d1419d5aSNobutomo Nakano }
268*d1419d5aSNobutomo Nakano 
269*d1419d5aSNobutomo Nakano /*
270*d1419d5aSNobutomo Nakano  * Walk through running zones and call doit() for each zones.
271*d1419d5aSNobutomo Nakano  *
272*d1419d5aSNobutomo Nakano  * Note: we call zone_get_rootpath() indirectly using dlopen().
273*d1419d5aSNobutomo Nakano  * This is because tzreload resides under /sbin and needs to run
274*d1419d5aSNobutomo Nakano  * without /usr (ie /usr/lib/libzonecfg.so.1). The reason tzreload
275*d1419d5aSNobutomo Nakano  * being in /sbin is that tzreload -I may be called to create
276*d1419d5aSNobutomo Nakano  * /var/run/tzsync before /usr is mounted. To do that zone_get_rootpath()
277*d1419d5aSNobutomo Nakano  * isn't necessary. Therefore, libzonecfg is dlopen'd when required
278*d1419d5aSNobutomo Nakano  * rather than having static linkage to it which would make tzreload
279*d1419d5aSNobutomo Nakano  * unable to run without /usr.
280*d1419d5aSNobutomo Nakano  */
281*d1419d5aSNobutomo Nakano static void
walk_zones(int get)282*d1419d5aSNobutomo Nakano walk_zones(int get)
283*d1419d5aSNobutomo Nakano {
284*d1419d5aSNobutomo Nakano 	zoneid_t *zids;
285*d1419d5aSNobutomo Nakano 	uint_t	ui, nzents, onzents;
286*d1419d5aSNobutomo Nakano 	char	zroot[PATH_MAX + 1];
287*d1419d5aSNobutomo Nakano 	char	zname[ZONENAME_MAX];
288*d1419d5aSNobutomo Nakano 	char	zbrand[MAXNAMELEN];
289*d1419d5aSNobutomo Nakano 	static int (*get_zroot)(char *, char *, size_t);
290*d1419d5aSNobutomo Nakano 
291*d1419d5aSNobutomo Nakano 	if (getzoneid() != GLOBAL_ZONEID) {
292*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr, gettext("not in the global zone.\n"));
293*d1419d5aSNobutomo Nakano 		exit(1);
294*d1419d5aSNobutomo Nakano 	}
295*d1419d5aSNobutomo Nakano 
296*d1419d5aSNobutomo Nakano 	if (get_zroot == NULL) {
297*d1419d5aSNobutomo Nakano 		void	*hdl;
298*d1419d5aSNobutomo Nakano 
299*d1419d5aSNobutomo Nakano 		if ((hdl = dlopen("libzonecfg.so.1", RTLD_NOW)) == NULL) {
300*d1419d5aSNobutomo Nakano 			(void) fprintf(stderr,
301*d1419d5aSNobutomo Nakano 			    gettext("unable to get zone configuration.\n"));
302*d1419d5aSNobutomo Nakano 			exit(1);
303*d1419d5aSNobutomo Nakano 		}
304*d1419d5aSNobutomo Nakano 		get_zroot = (int (*)(char *, char *, size_t))
305*d1419d5aSNobutomo Nakano 		    dlsym(hdl, "zone_get_rootpath");
306*d1419d5aSNobutomo Nakano 		if (get_zroot == NULL) {
307*d1419d5aSNobutomo Nakano 			(void) fprintf(stderr,
308*d1419d5aSNobutomo Nakano 			    gettext("unable to get zone configuration.\n"));
309*d1419d5aSNobutomo Nakano 			exit(1);
310*d1419d5aSNobutomo Nakano 		}
311*d1419d5aSNobutomo Nakano 	}
312*d1419d5aSNobutomo Nakano 
313*d1419d5aSNobutomo Nakano 	nzents = 0;
314*d1419d5aSNobutomo Nakano 	if (zone_list(NULL, &nzents) != 0) {
315*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr,
316*d1419d5aSNobutomo Nakano 		    gettext("failed to get zoneid list\n"));
317*d1419d5aSNobutomo Nakano 		exit(1);
318*d1419d5aSNobutomo Nakano 	}
319*d1419d5aSNobutomo Nakano 
320*d1419d5aSNobutomo Nakano again:
321*d1419d5aSNobutomo Nakano 	if (nzents == 0)
322*d1419d5aSNobutomo Nakano 		return;
323*d1419d5aSNobutomo Nakano 
324*d1419d5aSNobutomo Nakano 	if ((zids = malloc(nzents * sizeof (zoneid_t))) == NULL) {
325*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr, gettext("Insufficient memory.\n"));
326*d1419d5aSNobutomo Nakano 		exit(1);
327*d1419d5aSNobutomo Nakano 	}
328*d1419d5aSNobutomo Nakano 
329*d1419d5aSNobutomo Nakano 	onzents = nzents;
330*d1419d5aSNobutomo Nakano 	if (zone_list(zids, &nzents) != 0) {
331*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr,
332*d1419d5aSNobutomo Nakano 		    gettext("failed to get zoneid list\n"));
333*d1419d5aSNobutomo Nakano 		exit(1);
334*d1419d5aSNobutomo Nakano 	}
335*d1419d5aSNobutomo Nakano 
336*d1419d5aSNobutomo Nakano 	if (nzents != onzents) {
337*d1419d5aSNobutomo Nakano 		/* zone increased while doing zone_list() */
338*d1419d5aSNobutomo Nakano 		free(zids);
339*d1419d5aSNobutomo Nakano 		goto again;
340*d1419d5aSNobutomo Nakano 	}
341*d1419d5aSNobutomo Nakano 
342*d1419d5aSNobutomo Nakano 	for (ui = 0; ui < nzents; ui++) {
343*d1419d5aSNobutomo Nakano 		if (zone_getattr(zids[ui], ZONE_ATTR_BRAND, zbrand,
344*d1419d5aSNobutomo Nakano 		    sizeof (zbrand)) < 0) {
345*d1419d5aSNobutomo Nakano 			(void) fprintf(stderr,
346*d1419d5aSNobutomo Nakano 			    gettext("failed to get zone attribute\n"));
347*d1419d5aSNobutomo Nakano 			exit(1);
348*d1419d5aSNobutomo Nakano 		}
349*d1419d5aSNobutomo Nakano 		/* We only take care of native zones */
350*d1419d5aSNobutomo Nakano 		if (strcmp(zbrand, NATIVE_BRAND_NAME) != 0)
351*d1419d5aSNobutomo Nakano 			continue;
352*d1419d5aSNobutomo Nakano 		if (getzonenamebyid(zids[ui], zname, sizeof (zname)) < 0) {
353*d1419d5aSNobutomo Nakano 			(void) fprintf(stderr,
354*d1419d5aSNobutomo Nakano 			    gettext("failed to get zone name\n"));
355*d1419d5aSNobutomo Nakano 			exit(1);
356*d1419d5aSNobutomo Nakano 		}
357*d1419d5aSNobutomo Nakano 
358*d1419d5aSNobutomo Nakano 		if (zids[ui] == GLOBAL_ZONEID) {
359*d1419d5aSNobutomo Nakano 			zroot[0] = '\0';
360*d1419d5aSNobutomo Nakano 		} else {
361*d1419d5aSNobutomo Nakano 			if ((*get_zroot)(zname, zroot,
362*d1419d5aSNobutomo Nakano 			    sizeof (zroot)) != Z_OK) {
363*d1419d5aSNobutomo Nakano 				(void) fprintf(stderr,
364*d1419d5aSNobutomo Nakano 				    gettext("failed to get zone's root\n"));
365*d1419d5aSNobutomo Nakano 				exit(1);
366*d1419d5aSNobutomo Nakano 			}
367*d1419d5aSNobutomo Nakano 		}
368*d1419d5aSNobutomo Nakano 		doit(zname, zroot, get);
369*d1419d5aSNobutomo Nakano 	}
370*d1419d5aSNobutomo Nakano }
371*d1419d5aSNobutomo Nakano 
372*d1419d5aSNobutomo Nakano #include "cron.h"
373*d1419d5aSNobutomo Nakano 
374*d1419d5aSNobutomo Nakano /*
375*d1419d5aSNobutomo Nakano  * Send REFRESH event to cron.
376*d1419d5aSNobutomo Nakano  */
377*d1419d5aSNobutomo Nakano static void
send_cron_msg(const char * zname,const char * zroot)378*d1419d5aSNobutomo Nakano send_cron_msg(const char *zname, const char *zroot)
379*d1419d5aSNobutomo Nakano {
380*d1419d5aSNobutomo Nakano 	struct message msg;
381*d1419d5aSNobutomo Nakano 	int	msgfd;
382*d1419d5aSNobutomo Nakano 	char	fifo[PATH_MAX + 1];
383*d1419d5aSNobutomo Nakano 
384*d1419d5aSNobutomo Nakano 	if (strlcpy(fifo, zroot, sizeof (fifo)) >= sizeof (fifo) ||
385*d1419d5aSNobutomo Nakano 	    strlcat(fifo, FIFO, sizeof (fifo)) >= sizeof (fifo)) {
386*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr, gettext("zonepath too long\n"));
387*d1419d5aSNobutomo Nakano 		exit(1);
388*d1419d5aSNobutomo Nakano 	}
389*d1419d5aSNobutomo Nakano 
390*d1419d5aSNobutomo Nakano 	(void) memset(&msg, 0, sizeof (msg));
391*d1419d5aSNobutomo Nakano 	msg.etype = REFRESH;
392*d1419d5aSNobutomo Nakano 
393*d1419d5aSNobutomo Nakano 	if ((msgfd = open(fifo, O_WRONLY|O_NDELAY)) < 0) {
394*d1419d5aSNobutomo Nakano 		if (errno == ENXIO || errno == ENOENT) {
395*d1419d5aSNobutomo Nakano 			if (zname != NULL) {
396*d1419d5aSNobutomo Nakano 				(void) fprintf(stderr, gettext(
397*d1419d5aSNobutomo Nakano 				    "cron isn't running in %s zone.\n"), zname);
398*d1419d5aSNobutomo Nakano 			} else {
399*d1419d5aSNobutomo Nakano 				(void) fprintf(stderr,
400*d1419d5aSNobutomo Nakano 				    gettext("cron isn't running.\n"));
401*d1419d5aSNobutomo Nakano 			}
402*d1419d5aSNobutomo Nakano 		} else {
403*d1419d5aSNobutomo Nakano 			if (zname != NULL) {
404*d1419d5aSNobutomo Nakano 				(void) fprintf(stderr, gettext(
405*d1419d5aSNobutomo Nakano 				    "failed to send message to cron "
406*d1419d5aSNobutomo Nakano 				    "in %s zone.\n"), zname);
407*d1419d5aSNobutomo Nakano 			} else {
408*d1419d5aSNobutomo Nakano 				(void) fprintf(stderr, gettext(
409*d1419d5aSNobutomo Nakano 				    "failed to send message to cron.\n"));
410*d1419d5aSNobutomo Nakano 			}
411*d1419d5aSNobutomo Nakano 		}
412*d1419d5aSNobutomo Nakano 		return;
413*d1419d5aSNobutomo Nakano 	}
414*d1419d5aSNobutomo Nakano 
415*d1419d5aSNobutomo Nakano 	if (write(msgfd, &msg, sizeof (msg)) != sizeof (msg)) {
416*d1419d5aSNobutomo Nakano 		(void) fprintf(stderr, gettext("failed to send message.\n"));
417*d1419d5aSNobutomo Nakano 	}
418*d1419d5aSNobutomo Nakano 
419*d1419d5aSNobutomo Nakano 	(void) close(msgfd);
420*d1419d5aSNobutomo Nakano }
421