1*24a03f35SRobert Mustacchi#!/usr/bin/ksh 2*24a03f35SRobert Mustacchi# 3*24a03f35SRobert Mustacchi# This file and its contents are supplied under the terms of the 4*24a03f35SRobert Mustacchi# Common Development and Distribution License ("CDDL"), version 1.0. 5*24a03f35SRobert Mustacchi# You may only use this file in accordance with the terms of version 6*24a03f35SRobert Mustacchi# 1.0 of the CDDL. 7*24a03f35SRobert Mustacchi# 8*24a03f35SRobert Mustacchi# A full copy of the text of the CDDL should have accompanied this 9*24a03f35SRobert Mustacchi# source. A copy of the CDDL is also available via the Internet at 10*24a03f35SRobert Mustacchi# http://www.illumos.org/license/CDDL. 11*24a03f35SRobert Mustacchi# 12*24a03f35SRobert Mustacchi 13*24a03f35SRobert Mustacchi# 14*24a03f35SRobert Mustacchi# Copyright 2025 Oxide Computer Company 15*24a03f35SRobert Mustacchi# 16*24a03f35SRobert Mustacchi 17*24a03f35SRobert Mustacchi# 18*24a03f35SRobert Mustacchi# The purpose of this program is to go through and dump the internal libc state 19*24a03f35SRobert Mustacchi# from every time zone that we encounter so that we can go back and do a before 20*24a03f35SRobert Mustacchi# an after comparison of this information. 21*24a03f35SRobert Mustacchi# 22*24a03f35SRobert Mustacchi 23*24a03f35SRobert Mustacchiunalias -a 24*24a03f35SRobert Mustacchiset -o pipefail 25*24a03f35SRobert Mustacchiexport LANG=C.UTF-8 26*24a03f35SRobert Mustacchi 27*24a03f35SRobert Mustacchilc_arg0=$(basename $0) 28*24a03f35SRobert Mustacchilc_dir=$(dirname $0) 29*24a03f35SRobert Mustacchilc_print="*lclzonep::print -tL struct state" 30*24a03f35SRobert Mustacchilc_prev= 31*24a03f35SRobert Mustacchilc_out= 32*24a03f35SRobert Mustacchilc_libc=0 33*24a03f35SRobert Mustacchilc_zdump=0 34*24a03f35SRobert Mustacchilc_prog=${ZDUMP:-/usr/sbin/zdump} 35*24a03f35SRobert Mustacchi 36*24a03f35SRobert Mustacchi# 37*24a03f35SRobert Mustacchi# These will be filled in with the variable size that we detect via a program so 38*24a03f35SRobert Mustacchi# we can survive some changes in libc without as much pain. 39*24a03f35SRobert Mustacchi# 40*24a03f35SRobert Mustacchilc_chars= 41*24a03f35SRobert Mustacchilc_times= 42*24a03f35SRobert Mustacchi 43*24a03f35SRobert Mustacchi# 44*24a03f35SRobert Mustacchi# List of timezones 45*24a03f35SRobert Mustacchi# 46*24a03f35SRobert Mustacchilc_zones= 47*24a03f35SRobert Mustacchi 48*24a03f35SRobert Mustacchiusage() 49*24a03f35SRobert Mustacchi{ 50*24a03f35SRobert Mustacchi typeset msg="$*" 51*24a03f35SRobert Mustacchi [[ -z "$msg" ]] || echo "$msg" >&2 52*24a03f35SRobert Mustacchi cat <<USAGE >&2 53*24a03f35SRobert MustacchiUsage: $lc_arg0 [-c] [-z] -o dir 54*24a03f35SRobert MustacchiDump information about all timezones to a directory. 55*24a03f35SRobert Mustacchi 56*24a03f35SRobert Mustacchi -c dump state from inside of libc 57*24a03f35SRobert Mustacchi -o directory dump data to output directory 58*24a03f35SRobert Mustacchi -z dump zone with zdump(8) 59*24a03f35SRobert MustacchiUSAGE 60*24a03f35SRobert Mustacchi exit 2 61*24a03f35SRobert Mustacchi} 62*24a03f35SRobert Mustacchi 63*24a03f35SRobert Mustacchifatal() 64*24a03f35SRobert Mustacchi{ 65*24a03f35SRobert Mustacchi typeset msg="$*" 66*24a03f35SRobert Mustacchi [[ -z "$msg" ]] && msg="failed" 67*24a03f35SRobert Mustacchi echo "lcx_arg0: $msg" >&2 68*24a03f35SRobert Mustacchi exit 1 69*24a03f35SRobert Mustacchi} 70*24a03f35SRobert Mustacchi 71*24a03f35SRobert Mustacchiget_tzparams() 72*24a03f35SRobert Mustacchi{ 73*24a03f35SRobert Mustacchi eval $($lc_dir/tzparams.64); 74*24a03f35SRobert Mustacchi [[ -z "$TZ_MAX_TIMES" ]] && "failed to get TZ_MAX_TIMES" 75*24a03f35SRobert Mustacchi [[ -z "$TZ_MAX_CHARS" ]] && "failed to get TZ_MAX_CHARS" 76*24a03f35SRobert Mustacchi 77*24a03f35SRobert Mustacchi lc_chars="$TZ_MAX_CHARS" 78*24a03f35SRobert Mustacchi lc_times="$TZ_MAX_TIMES" 79*24a03f35SRobert Mustacchi 80*24a03f35SRobert Mustacchi for i in {0..$((lc_times - 1))}; do 81*24a03f35SRobert Mustacchi lc_prev+="$lc_print prev[0t$i].std[] prev[0t$i].alt[]\n" 82*24a03f35SRobert Mustacchi done 83*24a03f35SRobert Mustacchi 84*24a03f35SRobert Mustacchi lc_zones=$($lc_dir/tzlist.64) 85*24a03f35SRobert Mustacchi [[ -z "$lc_zones" ]] && fatal "failed to get time zones" 86*24a03f35SRobert Mustacchi} 87*24a03f35SRobert Mustacchi 88*24a03f35SRobert Mustacchidump_one() 89*24a03f35SRobert Mustacchi{ 90*24a03f35SRobert Mustacchi typeset tz="$1" 91*24a03f35SRobert Mustacchi typeset dir="$lc_out/$tz" 92*24a03f35SRobert Mustacchi 93*24a03f35SRobert Mustacchi if ! mkdir -p $dir; then 94*24a03f35SRobert Mustacchi fatal "failed to make output directory $dir" 95*24a03f35SRobert Mustacchi fi 96*24a03f35SRobert Mustacchi 97*24a03f35SRobert Mustacchi printf "Dumping %s\n" "$tz" 98*24a03f35SRobert Mustacchi if (( lc_libc != 0 )); then 99*24a03f35SRobert Mustacchi TZ=$tz mdb $lc_dir/tzload.32 > "$dir/libc-out.32" \ 100*24a03f35SRobert Mustacchi 2>"$dir/libc-err.32" <<EOF 101*24a03f35SRobert Mustacchi::bp mdb_hook 102*24a03f35SRobert Mustacchi::run 103*24a03f35SRobert Mustacchi*lclzonep::printf "name: [%s]\n" struct state zonename 104*24a03f35SRobert Mustacchi*lclzonep::printf "alt0: [%s]\n" struct state default_tzname0 105*24a03f35SRobert Mustacchi*lclzonep::printf "alt1: [%s]\n" struct state default_tzname1 106*24a03f35SRobert Mustacchi$lc_print zonerules daylight default_timezone default_altzone 107*24a03f35SRobert Mustacchi$lc_print leapcnt timecnt typecnt charcnt charsbuf_size 108*24a03f35SRobert Mustacchi$lc_print chars | ::dump -r -l 0t$lc_chars 109*24a03f35SRobert Mustacchi$(echo "$lc_prev") 110*24a03f35SRobert Mustacchi$lc_print ats types ttis lsis last_ats_idx start_rule end_rule 111*24a03f35SRobert Mustacchi\$q 112*24a03f35SRobert MustacchiEOF 113*24a03f35SRobert Mustacchi 114*24a03f35SRobert Mustacchi TZ=$tz mdb $lc_dir/tzload.64 > "$dir/libc-out.64" \ 115*24a03f35SRobert Mustacchi 2>"$dir/libc-err.64" <<EOF 116*24a03f35SRobert Mustacchi::bp mdb_hook 117*24a03f35SRobert Mustacchi::run 118*24a03f35SRobert Mustacchi*lclzonep::printf "name: [%s]\n" struct state zonename 119*24a03f35SRobert Mustacchi*lclzonep::printf "alt0: [%s]\n" struct state default_tzname0 120*24a03f35SRobert Mustacchi*lclzonep::printf "alt1: [%s]\n" struct state default_tzname1 121*24a03f35SRobert Mustacchi$lc_print zonerules daylight default_timezone default_altzone 122*24a03f35SRobert Mustacchi$lc_print leapcnt timecnt typecnt charcnt charsbuf_size 123*24a03f35SRobert Mustacchi$lc_print chars | ::dump -r -l 0t$lc_chars 124*24a03f35SRobert Mustacchi$(echo "$lc_prev") 125*24a03f35SRobert Mustacchi$lc_print ats types ttis lsis last_ats_idx start_rule end_rule 126*24a03f35SRobert Mustacchi\$q 127*24a03f35SRobert MustacchiEOF 128*24a03f35SRobert Mustacchi fi 129*24a03f35SRobert Mustacchi 130*24a03f35SRobert Mustacchi if (( lc_zdump != 0 )); then 131*24a03f35SRobert Mustacchi $lc_prog -v $tz 2>&1 >"$dir/zdump" 132*24a03f35SRobert Mustacchi fi 133*24a03f35SRobert Mustacchi} 134*24a03f35SRobert Mustacchi 135*24a03f35SRobert Mustacchiwhile getopts ":co:z" c $@; do 136*24a03f35SRobert Mustacchi case "$c" in 137*24a03f35SRobert Mustacchi c) 138*24a03f35SRobert Mustacchi lc_libc=1 139*24a03f35SRobert Mustacchi ;; 140*24a03f35SRobert Mustacchi o) 141*24a03f35SRobert Mustacchi [[ ! -d "$OPTARG" ]] && fatal "$OPTARG is not a directory" 142*24a03f35SRobert Mustacchi lc_out="$OPTARG" 143*24a03f35SRobert Mustacchi ;; 144*24a03f35SRobert Mustacchi z) 145*24a03f35SRobert Mustacchi lc_zdump=1 146*24a03f35SRobert Mustacchi ;; 147*24a03f35SRobert Mustacchi :) 148*24a03f35SRobert Mustacchi usage "option requires an argument -- $OPTARG" 149*24a03f35SRobert Mustacchi ;; 150*24a03f35SRobert Mustacchi *) 151*24a03f35SRobert Mustacchi usage "invalid option -- $OPTARG" 152*24a03f35SRobert Mustacchi ;; 153*24a03f35SRobert Mustacchi esac 154*24a03f35SRobert Mustacchidone 155*24a03f35SRobert Mustacchi 156*24a03f35SRobert Mustacchi[[ -z "$lc_out" ]] && usage "missing required output directory" 157*24a03f35SRobert Mustacchi(( lc_libc == 0 && lc_zdump == 0 )) && usage \ 158*24a03f35SRobert Mustacchi "at least one of -c or -z is required" 159*24a03f35SRobert Mustacchi 160*24a03f35SRobert Mustacchiget_tzparams 161*24a03f35SRobert Mustacchifor z in $lc_zones; do 162*24a03f35SRobert Mustacchi dump_one "$z" 163*24a03f35SRobert Mustacchidone 164*24a03f35SRobert Mustacchiexit 0 165