const char *policy_str;
} def_pol[] = {
/* audio */
- { .label = "es1370", .policy_str = "reset" },
- { .label = "es1371", .policy_str = "reset" },
- { .label = "sb16", .policy_str = "reset" },
+ { .label = "es1370", .policy_str = "reset" },
+ { .label = "es1371", .policy_str = "reset" },
+ { .label = "sb16", .policy_str = "reset" },
/* bus */
- { .label = "i2c", .policy_str = "restart" },
- { .label = "pci", .policy_str = "restart" },
- { .label = "ti1225", .policy_str = "restart" },
+ { .label = "i2c", .policy_str = "restart" },
+ { .label = "pci", .policy_str = "restart" },
+ { .label = "ti1225", .policy_str = "restart" },
/* clock */
- { .label = "readclock.drv", .policy_str = "restart" },
+ { .label = "readclock.drv", .policy_str = "restart" },
/* eeprom */
- { .label = "cat24c256", .policy_str = "restart" },
+ { .label = "cat24c256", .policy_str = "restart" },
/* examples */
- { .label = "hello", .policy_str = "restart" },
+ { .label = "hello", .policy_str = "restart" },
/* hid */
- { .label = "pckbd", .policy_str = "reset" },
+ { .label = "pckbd", .policy_str = "reset" },
/* iommu */
- { .label = "amddev", .policy_str = "" },
+ { .label = "amddev", .policy_str = "" },
/* net */
- { .label = "3c90x", .policy_str = "restart" },
- { .label = "atl2", .policy_str = "restart" },
- { .label = "dec21140A", .policy_str = "restart" },
- { .label = "dp8390", .policy_str = "restart" },
- { .label = "dpeth", .policy_str = "restart" },
- { .label = "e1000", .policy_str = "restart" },
- { .label = "fxp", .policy_str = "restart" },
- { .label = "lance", .policy_str = "restart" },
- { .label = "lan8710a", .policy_str = "restart" },
- { .label = "rtl8139", .policy_str = "restart" },
- { .label = "rtl8169", .policy_str = "restart" },
- { .label = "uds", .policy_str = "reset" },
- { .label = "virtio_net", .policy_str = "restart" },
+ { .label = "3c90x", .policy_str = "reset" },
+ { .label = "atl2", .policy_str = "reset" },
+ { .label = "dec21140A", .policy_str = "reset" },
+ { .label = "dp8390", .policy_str = "reset" },
+ { .label = "dpeth", .policy_str = "reset" },
+ { .label = "e1000", .policy_str = "reset" },
+ { .label = "fxp", .policy_str = "reset" },
+ { .label = "lance", .policy_str = "reset" },
+ { .label = "lan8710a", .policy_str = "reset" },
+ { .label = "orinoco", .policy_str = "reset" },
+ { .label = "rtl8139", .policy_str = "reset" },
+ { .label = "rtl8169", .policy_str = "reset" },
+ { .label = "uds", .policy_str = "reset" },
+ { .label = "virtio_net", .policy_str = "reset" },
/* power */
- { .label = "acpi", .policy_str = "" },
- { .label = "tps65217", .policy_str = "" },
- { .label = "tps65590", .policy_str = "" },
+ { .label = "acpi", .policy_str = "" },
+ { .label = "tps65217", .policy_str = "" },
+ { .label = "tps65590", .policy_str = "" },
/* printer */
- { .label = "printer", .policy_str = "restart" },
+ { .label = "printer", .policy_str = "restart" },
/* sensors */
- { .label = "bmp085", .policy_str = "" },
- { .label = "sht21", .policy_str = "restart" },
- { .label = "tsl2550", .policy_str = "restart" },
+ { .label = "bmp085", .policy_str = "" },
+ { .label = "sht21", .policy_str = "restart" },
+ { .label = "tsl2550", .policy_str = "restart" },
/* storage */
- { .label = "ahci", .policy_str = "reset" },
- { .label = "at_wini", .policy_str = "reset" },
- { .label = "fbd", .policy_str = "reset" },
- { .label = "filter", .policy_str = "reset" },
- { .label = "floppy", .policy_str = "reset" },
- { .label = "memory", .policy_str = "restart" },
- { .label = "mmc", .policy_str = "reset" },
- { .label = "virtio_blk", .policy_str = "reset" },
- { .label = "vnd", .policy_str = "reset" },
+ { .label = "ahci", .policy_str = "reset" },
+ { .label = "at_wini", .policy_str = "reset" },
+ { .label = "fbd", .policy_str = "reset" },
+ { .label = "filter", .policy_str = "reset" },
+ { .label = "floppy", .policy_str = "reset" },
+ { .label = "memory", .policy_str = "restart" },
+ { .label = "mmc", .policy_str = "reset" },
+ { .label = "virtio_blk", .policy_str = "reset" },
+ { .label = "vnd", .policy_str = "reset" },
/* system */
- { .label = "gpio", .policy_str = "restart" },
- { .label = "log", .policy_str = "reset" },
- { .label = "random", .policy_str = "restart" },
+ { .label = "gpio", .policy_str = "restart" },
+ { .label = "log", .policy_str = "reset" },
+ { .label = "random", .policy_str = "restart" },
/* tty */
- { .label = "pty", .policy_str = "restart" },
- { .label = "tty", .policy_str = "" },
+ { .label = "pty", .policy_str = "restart" },
+ { .label = "tty", .policy_str = "restart" },
/* usb */
- { .label = "usbd", .policy_str = "" },
- { .label = "usb_hub", .policy_str = "" },
- { .label = "usb_storage", .policy_str = "" },
+ { .label = "usbd", .policy_str = "" },
+ { .label = "usb_hub", .policy_str = "" },
+ { .label = "usb_storage", .policy_str = "" },
/* video */
- { .label = "fb", .policy_str = "" },
- { .label = "tda19988", .policy_str = "" },
+ { .label = "fb", .policy_str = "" },
+ { .label = "tda19988", .policy_str = "" },
/* vmm_guest */
- { .label = "vbox", .policy_str = "" },
+ { .label = "vbox", .policy_str = "" },
/* fs */
- { .label = "ext2", .policy_str = "" },
- { .label = "hgfs", .policy_str = "" },
- { .label = "isofs", .policy_str = "" },
- { .label = "mfs", .policy_str = "" },
- { .label = "pfs", .policy_str = "" },
- { .label = "procfs", .policy_str = "" },
+ { .label = "ext2", .policy_str = "" },
+ { .label = "hgfs", .policy_str = "" },
+ { .label = "isofs", .policy_str = "" },
+ { .label = "mfs", .policy_str = "restart" },
+ { .label = "pfs", .policy_str = "restart" },
+ { .label = "procfs", .policy_str = "restart" },
{ .label = "ptyfs", .policy_str = "" },
- { .label = "vbfs", .policy_str = "" },
+ { .label = "vbfs", .policy_str = "" },
/* net */
- { .label = "inet", .policy_str = "reset" },
- { .label = "lwip", .policy_str = "" },
+ { .label = "inet", .policy_str = "reset" },
+ { .label = "lwip", .policy_str = "" },
/* servers */
- { .label = "devman", .policy_str = "" },
- { .label = "ds", .policy_str = "" },
- { .label = "input", .policy_str = "reset" },
- { .label = "ipc", .policy_str = "restart" },
- { .label = "is", .policy_str = "restart" },
- { .label = "pm", .policy_str = "" },
- { .label = "rs", .policy_str = "" },
- { .label = "sched", .policy_str = "" },
- { .label = "vfs", .policy_str = "" },
- { .label = "vm", .policy_str = "" },
+ { .label = "devman", .policy_str = "restart" },
+ { .label = "ds", .policy_str = "restart" },
+ { .label = "input", .policy_str = "reset" },
+ { .label = "ipc", .policy_str = "restart" },
+ { .label = "is", .policy_str = "restart" },
+ { .label = "pm", .policy_str = "restart" },
+ { .label = "rs", .policy_str = "restart" },
+ { .label = "sched", .policy_str = "restart" },
+ { .label = "vfs", .policy_str = "restart" },
+ { .label = "vm", .policy_str = "" },
//{ .label = "", .policy_str = "" },
};
return pol[slot].formatted;
}
+/* Returns a ASCIIZ string encoding RS flags. */
+static const char *
+service_get_flags(index_t slot)
+{
+ static char str[10];
+ int flags, sys_flags;
+
+ flags = rproc.proc[slot].r_flags;
+ sys_flags = rproc.pub[slot].sys_flags;
+
+ str[0] = (flags & RS_ACTIVE) ? 'A' : '-';
+ str[1] = (flags & RS_UPDATING) ? 'U' : '-';
+ str[2] = (flags & RS_EXITING) ? 'E' : '-';
+ str[3] = (flags & RS_NOPINGREPLY) ? 'N' : '-';
+ str[4] = (sys_flags & SF_USE_COPY) ? 'C' : '-';
+ str[5] = (sys_flags & SF_USE_REPL) ? 'R' : '-';
+ str[6] = (sys_flags & SF_NEED_COPY) ? 'c' : '-';
+ str[7] = (sys_flags & SF_NEED_REPL) ? 'r' : '-';
+ str[8] = (sys_flags & SF_CORE_SRV) ? 's' : '-';
+ str[9] = '\0';
+
+ return str;
+}
+
/*
* Return whether a slot is in use and active. The purpose of this check is
* to ensure that after eliminating all slots that do not pass this check, we
buf_printf("endpoint: %d\n", rpub->endpoint);
buf_printf("pid: %d\n", rp->r_pid);
buf_printf("restarts: %d\n", rp->r_restarts);
+ buf_printf("flags: %s\n", service_get_flags(slot));
buf_printf("policies: %s\n", service_get_policies(policies, slot));
}
# for each restatability policy call the policy test function if it is
# supported. No accounting of failed / successful test is done, as a
# failed test can currently provoque cascading effects, so instead we
-# fail the test as a whole on the first failurei found.
+# fail the test as a whole on the first failure is found. Live update tests
+# are currently policy-agnostic.
#
# Supported policies have to be in the POLICIES variable, and define a test
# function.
# Known limitations:
# - Currently not all recovery policies are tested
# - Running this test under X11 hangs the X server
+# - Live update tests do not test rollback situations
#
# To add a new policy, you have to do the following:
# 1. Add the policy into the active policies array by:
# Currently known policies:
# /* user | endpoint */
# POL_RESET, /* visible | change */
-# POL_RESTART, /* transparent | preserved */
-# POL_LIVE_UPDATE /* transparent | preserved */
+# POL_RESTART /* transparent | preserved */
#######################################################################
# Utility functions & global state initializations
do
sleep 1
retry=$((${retry} + 1))
- test -f $1 && break
+ test -f $1 && test $(get_value restarts $1) -ne $2 && break
done
}
restarts_pre=$(get_value restarts ${service})
endpoint_pre=$(get_value endpoint ${service})
- service refresh ${label}
- wait_for_service ${service}
+ service fi ${label}
+ wait_for_service ${service} ${restarts_pre}
restarts_post=$(get_value restarts ${service})
endpoint_post=$(get_value endpoint ${service})
pol_reset() {
local label service
local endpoint_pre endpoint_post
+ local restarts_pre restarts_post
service=$1
label=$2
+ restarts_pre=$(get_value restarts ${service})
endpoint_pre=$(get_value endpoint ${service})
- service refresh ${label}
- wait_for_service ${service}
+ service fi ${label}
+ wait_for_service ${service} ${restarts_pre}
+ restarts_post=$(get_value restarts ${service})
endpoint_post=$(get_value endpoint ${service})
# This policy doesn't guarantee the endpoint to be kept, but there
# is a slight chance that it will actualy stay the same, and fail
# the test.
- if [ ! ${endpoint_post} -eq ${endpoint_pre} ]
+ if [ ${restarts_post} -gt ${restarts_pre} \
+ -a ${endpoint_post} -ne ${endpoint_pre} ]
+ then
+ echo ok
+ else
+ echo not ok
+ fi
+}
+
+#######################################################################
+# Live update test
+#######################################################################
+lu_test_one() {
+ local label=$1
+ local prog=$2
+ local result=$3
+ lu_opts=${lu_opts:-}
+ lu_maxtime=${lu_maxtime:-3HZ}
+ lu_state=${lu_state:-1}
+
+ service ${lu_opts} update ${prog} -label ${label} -maxtime ${lu_maxtime} -state ${lu_state}
+ if [ $? -ne $result ]
+ then
+ echo not ok
+ return 1
+ else
+ return 0
+ fi
+}
+
+lu_test() {
+ local label service
+ local endpoint_pre endpoint_post
+ local restarts_pre restarts_post
+
+ service=$1
+ label=$2
+
+ restarts_pre=$(get_value restarts ${service})
+ endpoint_pre=$(get_value endpoint ${service})
+
+ lu_test_one ${label} self 0 || return
+ if ! echo "vm pm vfs rs" | grep -q ${label}
+ then
+ lu_opts="-o" lu_test_one ${label} self 0 || return
+ fi
+ lu_opts="-x" lu_test_one ${label} self 200 || return
+ if ! echo "rs" | grep -q ${label}
+ then
+ lu_opts="-y" lu_test_one ${label} self 78 || return
+ lu_maxtime="1HZ" lu_opts="-z" lu_test_one ${label} self 4 || return
+ fi
+ lu_maxtime="1HZ" lu_state="5" lu_test_one ${label} self 4 || return
+
+ restarts_post=$(get_value restarts ${service})
+ endpoint_post=$(get_value endpoint ${service})
+
+ # Make sure endpoint and restarts are preserved
+ if [ ${restarts_post} -eq ${restarts_pre} \
+ -a ${endpoint_post} -eq ${endpoint_pre} ]
then
echo ok
else
fi
}
+multi_lu_test_one() {
+ local result=$1
+ shift
+ local labels="$*"
+ local ret=0
+ local index=0
+ local once_index=1
+
+ lu_opts=${lu_opts:-}
+ lu_maxtime=${lu_maxtime:-3HZ}
+ lu_state=${lu_state:-1}
+ lu_opts_once=${lu_opts_once:-$lu_opts}
+ lu_maxtime_once=${lu_maxtime_once:-$lu_maxtime}
+ lu_state_once=${lu_state_once:-$lu_state}
+
+ for label in ${labels}
+ do
+ if [ $index -eq $once_index ]
+ then
+ service ${lu_opts_once} -q update self -label ${label} -maxtime ${lu_maxtime_once} -state ${lu_state_once} || ret=1
+ else
+ service ${lu_opts} -q update self -label ${label} -maxtime ${lu_maxtime} -state ${lu_state} || ret=1
+ fi
+ index=`expr $index + 1`
+ done
+ service sysctl upd_run
+ if [ $? -ne $result ]
+ then
+ ret=1
+ fi
+ if [ $ret -eq 1 ]
+ then
+ echo not ok
+ fi
+ return $ret
+}
+
+multi_lu_test() {
+ local labels="$*"
+
+ multi_lu_test_one 0 ${labels} || return
+ lu_opts_once="-x" multi_lu_test_one 200 ${labels} || return
+ lu_opts_once="-y" multi_lu_test_one 200 ${labels} || return
+ lu_maxtime_once="1HZ" lu_opts_once="-z" multi_lu_test_one 200 ${labels} || return
+ lu_maxtime_once="1HZ" lu_state_once="5" multi_lu_test_one 4 ${labels} || return
+
+ echo ok
+}
+
+#######################################################################
+# Service management routines
+#######################################################################
+prepare_service() {
+ local label service
+
+ service=$1
+ label=$2
+
+ flags=$(get_value flags ${service})
+ echo $flags | grep -q 'r' || return 0
+ echo $flags | grep -q 'R' && return 0
+
+ service clone $label
+ return 1
+}
+
+cleanup_service() {
+ local label
+
+ label=$1
+
+ service unclone $label
+}
+
#######################################################################
# main()
#######################################################################
exit 1
fi
- labels=$(echo /proc/service/*)
- for label in ${labels}
+ services=$(echo /proc/service/*)
+ for service in ${services}
do
- service_policies=$(grep policies ${label}|cut -d: -f2)
+ label=$(basename ${service})
+ service_policies=$(grep policies ${service}|cut -d: -f2)
for pol in ${service_policies}
do
# Check if the supported policy is under test
if echo "${POLICIES}" | grep -q ${pol}
then
echo "# testing ${label} :: ${pol}"
- result=$(pol_${pol} ${label} $(basename ${label}))
- #pol_${pol} ${label} $(basename ${label})
- #result="FAILED"
+ cleanup=0
+ prepare_service ${service} ${label} || cleanup=1
+ result=$(pol_${pol} ${service} ${label})
if [ "x${result}" != "xok" ]
then
echo "not ok # failed ${label}, ${pol}"
exit 1
fi
+ if [ $cleanup -eq 1 ]
+ then
+ cleanup_service ${label}
+ fi
fi
done
done
+ multi_lu_labels=""
+ for service in ${services}
+ do
+ label=$(basename ${service})
+ service_policies=$(grep policies ${service}|cut -d: -f2)
+ if echo "${service_policies}" | grep -q "[a-zA-Z]"
+ then
+ echo "# testing ${label} :: live update+rollback"
+ result=$(lu_test ${service} ${label})
+ if [ "x${result}" != "xok" ]
+ then
+ echo "not ok # failed ${label}, live update+rollback"
+ exit 1
+ fi
+ if [ "x${label}" = "xrs" ]
+ then
+ continue
+ fi
+ service_flags=$(get_value flags ${service})
+ if echo $service_flags | grep -q 's'
+ then
+ multi_lu_labels="${multi_lu_labels} ${label}"
+ fi
+ fi
+ done
+ multi_lu_labels="${multi_lu_labels} rs"
+ echo "# testing ${multi_lu_labels} :: whole-OS live update+rollback"
+ result=$(multi_lu_test $multi_lu_labels)
+ if [ "x${result}" != "xok" ]
+ then
+ echo "not ok # failed whole-OS live update+rollback"
+ exit 1
+ fi
echo ok
exit 0