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