d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * CDDL HEADER START
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano *
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * The contents of this file are subject to the terms of the
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Common Development and Distribution License (the "License").
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * You may not use this file except in compliance with the License.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano *
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * or http://www.opensolaris.org/os/licensing.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * See the License for the specific language governing permissions
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * and limitations under the License.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano *
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * When distributing Covered Code, include this CDDL HEADER in each
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * If applicable, add the following below this CDDL HEADER, with the
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * fields enclosed by brackets "[]" replaced with your own identifying
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * information: Portions Copyright [yyyy] [name of copyright owner]
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano *
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * CDDL HEADER END
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Use is subject to license terms.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/* All Rights Reserved */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <atomic.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <errno.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <fcntl.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <limits.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <stdio.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <stdlib.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <string.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <unistd.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <sys/mman.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <sys/stat.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <locale.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <libintl.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <zone.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <libzonecfg.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <sys/brand.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include <dlfcn.h>
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#define TZSYNC_FILE "/var/run/tzsync"
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void init_file(void);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void doit(const char *zname, const char *zroot, int get);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void counter_get(const char *zname, int fd);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void counter_set(int fd);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void walk_zones(int get);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void send_cron_msg(const char *zname, const char *zroot);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * There are undocumeted command line options:
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * -l list the value of semaphore.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * -I initialize the semaphore file (ie /var/run/tzsync)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanoint
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanomain(int argc, char **argv)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano{
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano int arg;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano int all = 0, get = 0, init = 0;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) setlocale(LC_ALL, "");
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) textdomain(TEXT_DOMAIN);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano while ((arg = getopt(argc, argv, "alI")) != EOF) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano switch (arg) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano case 'a':
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano all = 1;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano break;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano case 'l':
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano get = 1;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano break;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano case 'I':
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano init = 1;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano break;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano default:
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("Usage: tzreload [-a]\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (init) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano init_file();
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano return (0);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (all)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano walk_zones(get);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano else
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano doit(NULL, "", get);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano return (0);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano}
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Create /var/run/tzsync atomically.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano *
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * While creating the /var/run/tzsync initially, there is a timing window
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * that the file is created but no disk block is allocated (empty file).
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * If apps mmap'ed the file at the very moment, it succeeds but accessing
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * the memory page causes a segfault since disk block isn't yet allocated.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * To avoid this situation, we create a temp file which has pagesize block
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * assigned, and then rename it to tzsync.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanoinit_file(void)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano{
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano char path[sizeof (TZSYNC_FILE) + 16];
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano char *buf;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano int fd, pgsz;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano struct stat st;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano /* We don't allow to re-create the file */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (stat(TZSYNC_FILE, &st) == 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("%s already exists.\n"),
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano TZSYNC_FILE);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano pgsz = sysconf(_SC_PAGESIZE);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) strcpy(path, TZSYNC_FILE "XXXXXX");
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if ((fd = mkstemp(path)) == -1) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("failed to create a temporary file.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if ((buf = calloc(1, pgsz)) == NULL) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("Insufficient memory.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanoerrout:
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) close(fd);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) unlink(path);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (write(fd, buf, pgsz) != pgsz) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("failed to create tzsync file, %s\n"),
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano strerror(errno));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano goto errout;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) close(fd);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano /* link it */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (link(path, TZSYNC_FILE) != 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (errno == EEXIST) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("%s already exists.\n"),
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano TZSYNC_FILE);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano } else {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("failed to create %s\n"),
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano TZSYNC_FILE);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) unlink(path);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) unlink(path);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano /*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Unplivileged apps may fail to open the file until the chmod
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * below succeeds. However, it's okay as long as open() fails;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * ctime() won't cache zoneinfo until file is opened and mmap'd.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano /* /var/run/tzsync has been made. Adjust permission */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (chmod(TZSYNC_FILE, 0644) != 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("failed to change permission of %s\n"),
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano TZSYNC_FILE);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) unlink(TZSYNC_FILE);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano}
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Open the /var/run/tzsync, then set or get the semaphore.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano *
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * zname name of zone (NULL if no need to consider zones)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * zroot zone's root path
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * get get/set semaphore
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanodoit(const char *zname, const char *zroot, int get)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano{
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano int fd;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano char file[PATH_MAX + 1];
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (strlcpy(file, zroot, sizeof (file)) >= sizeof (file) ||
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano strlcat(file, TZSYNC_FILE, sizeof (file)) >= sizeof (file)) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("zonepath too long\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if ((fd = open(file, get ? O_RDONLY : O_RDWR)) < 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("Can't open file %s, %s\n"),
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano file, strerror(errno));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (get) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano counter_get(zname, fd);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano } else {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano counter_set(fd);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano /* let cron reschedule events */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano send_cron_msg(zname, zroot);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) close(fd);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano}
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Get semaphore value and print.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanocounter_get(const char *zname, int fd)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano{
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano uint32_t counter;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano caddr_t addr;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano addr = mmap(NULL, sizeof (uint32_t), PROT_READ, MAP_SHARED, fd, 0);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (addr == MAP_FAILED) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("Error mapping semaphore: %s\n"),
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano strerror(errno));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano counter = *(uint32_t *)(uintptr_t)addr;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) munmap(addr, sizeof (uint32_t));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (zname == NULL)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) printf("%u\n", counter);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano else
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) printf("%-20s %u\n", zname, counter);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano}
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Increment semaphore value.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanocounter_set(int fd)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano{
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano caddr_t addr;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano addr = mmap(NULL, sizeof (uint32_t), PROT_READ|PROT_WRITE,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano MAP_SHARED, fd, 0);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (addr == MAP_FAILED) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("Error mapping semaphore: %s\n"),
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano strerror(errno));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano /*LINTED*/
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano atomic_add_32((uint32_t *)addr, 1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) munmap(addr, sizeof (uint32_t));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano}
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Walk through running zones and call doit() for each zones.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano *
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Note: we call zone_get_rootpath() indirectly using dlopen().
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * This is because tzreload resides under /sbin and needs to run
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * without /usr (ie /usr/lib/libzonecfg.so.1). The reason tzreload
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * being in /sbin is that tzreload -I may be called to create
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * /var/run/tzsync before /usr is mounted. To do that zone_get_rootpath()
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * isn't necessary. Therefore, libzonecfg is dlopen'd when required
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * rather than having static linkage to it which would make tzreload
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * unable to run without /usr.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanowalk_zones(int get)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano{
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano zoneid_t *zids;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano uint_t ui, nzents, onzents;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano char zroot[PATH_MAX + 1];
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano char zname[ZONENAME_MAX];
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano char zbrand[MAXNAMELEN];
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano static int (*get_zroot)(char *, char *, size_t);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (getzoneid() != GLOBAL_ZONEID) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("not in the global zone.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (get_zroot == NULL) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano void *hdl;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if ((hdl = dlopen("libzonecfg.so.1", RTLD_NOW)) == NULL) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("unable to get zone configuration.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano get_zroot = (int (*)(char *, char *, size_t))
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano dlsym(hdl, "zone_get_rootpath");
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (get_zroot == NULL) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("unable to get zone configuration.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano nzents = 0;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (zone_list(NULL, &nzents) != 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("failed to get zoneid list\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanoagain:
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (nzents == 0)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano return;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if ((zids = malloc(nzents * sizeof (zoneid_t))) == NULL) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("Insufficient memory.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano onzents = nzents;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (zone_list(zids, &nzents) != 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("failed to get zoneid list\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (nzents != onzents) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano /* zone increased while doing zone_list() */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano free(zids);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano goto again;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano for (ui = 0; ui < nzents; ui++) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (zone_getattr(zids[ui], ZONE_ATTR_BRAND, zbrand,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano sizeof (zbrand)) < 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("failed to get zone attribute\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano /* We only take care of native zones */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (strcmp(zbrand, NATIVE_BRAND_NAME) != 0)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano continue;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (getzonenamebyid(zids[ui], zname, sizeof (zname)) < 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("failed to get zone name\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (zids[ui] == GLOBAL_ZONEID) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano zroot[0] = '\0';
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano } else {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if ((*get_zroot)(zname, zroot,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano sizeof (zroot)) != Z_OK) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("failed to get zone's root\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano doit(zname, zroot, get);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano}
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano#include "cron.h"
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano/*
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano * Send REFRESH event to cron.
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano */
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanostatic void
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakanosend_cron_msg(const char *zname, const char *zroot)
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano{
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano struct message msg;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano int msgfd;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano char fifo[PATH_MAX + 1];
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (strlcpy(fifo, zroot, sizeof (fifo)) >= sizeof (fifo) ||
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano strlcat(fifo, FIFO, sizeof (fifo)) >= sizeof (fifo)) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("zonepath too long\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano exit(1);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) memset(&msg, 0, sizeof (msg));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano msg.etype = REFRESH;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if ((msgfd = open(fifo, O_WRONLY|O_NDELAY)) < 0) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (errno == ENXIO || errno == ENOENT) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (zname != NULL) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext(
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano "cron isn't running in %s zone.\n"), zname);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano } else {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr,
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano gettext("cron isn't running.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano } else {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (zname != NULL) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext(
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano "failed to send message to cron "
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano "in %s zone.\n"), zname);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano } else {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext(
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano "failed to send message to cron.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano return;
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano if (write(msgfd, &msg, sizeof (msg)) != sizeof (msg)) {
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) fprintf(stderr, gettext("failed to send message.\n"));
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano }
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano (void) close(msgfd);
d1419d5a02eaedd520f925cd465fd62f3950ae43Nobutomo Nakano}