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 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 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 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 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 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 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 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