| # Copyright 2018 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| description "Start the wilco_dtc daemon" |
| author "chromium-os-dev@chromium.org" |
| |
| # Start the wilco_dtc daemon (diagnostics and telemetry collector), which is |
| # responsible for processing and analyzing telemetry and diagnostics information |
| # obtained from wilco_dtc_supportd. `wilco_dtc_dispatcher` will manage the |
| # lifecycle of both this process and wilco_dtc_supportd. |
| start on starting wilco_dtc_dispatcher |
| stop on stopped wilco_dtc_dispatcher |
| |
| respawn |
| # If the job respawns 3 times in 10 seconds, stop trying. |
| respawn limit 3 10 |
| |
| # Allow STARTUP_PROCESSES env variable to be sent to the job. If |
| # STARTUP_PROCESSES is true (default), the VM will start the DTC binaries. If it |
| # is false, the kernel parameter -p maitred.no_startup_processes will be added |
| # preventing the DTC binaries from starting. |
| import STARTUP_PROCESSES |
| |
| # Allow TEST_DBUS_CONFIG env variable to be sent to the job. If |
| # TEST_DBUS_CONFIG is true, the VM will start dbus with a test |
| # configuration. If it is false (default) the production config is used. |
| # TODO(tbegin): remove this parameter when the wilco_dtc VM can be built in a |
| # test configuration. |
| import TEST_DBUS_CONFIG |
| |
| env STARTUP_PROCESSES=true |
| env TEST_DBUS_CONFIG=false |
| env MAITRED_LISTEN_PORT=7788 |
| env MAITRED_PORT=8888 |
| env VM_CPUS=1 |
| env VM_MEM=128 |
| env VM_CID=512 |
| env VM_PATH=/opt/wilco/dtc-vm |
| env RUNTIME_PATH=/run/wilco-vm |
| env STORAGE_PATH=/var/lib/wilco |
| env STORAGE_FILE=/var/lib/wilco/storage.img |
| env STORAGE_SIZE=64M |
| |
| pre-start script |
| # Sanitize the STARTUP_PROCESSES and TEST_DBUS_CONFIG environment variables |
| # to ensure they are boolean values. |
| case "${STARTUP_PROCESSES}" in |
| true|false) ;; |
| *) |
| logger -t "${UPSTART_JOB}" \ |
| "STARTUP_PROCESSES env variable is not a boolean" |
| exit 1 |
| ;; |
| esac |
| |
| case "${TEST_DBUS_CONFIG}" in |
| true|false) ;; |
| *) |
| logger -t "${UPSTART_JOB}" \ |
| "TEST_DBUS_CONFIG env variable is not a boolean" |
| exit 1 |
| ;; |
| esac |
| |
| # Make sure the vsock module is loaded. |
| modprobe -q vhost-vsock |
| |
| # Create the runtime directory. |
| if [ -d "${RUNTIME_PATH}" ]; then |
| rm -r "${RUNTIME_PATH}" |
| fi |
| mkdir "${RUNTIME_PATH}" |
| chown -R wilco_dtc:wilco_dtc "${RUNTIME_PATH}" |
| |
| # Create persistent VM storage if it does not exist. |
| if [ ! -d "${STORAGE_PATH}" ]; then |
| mkdir -p "${STORAGE_PATH}" |
| fi |
| |
| if [ ! -f "${STORAGE_FILE}" ]; then |
| truncate --size "${STORAGE_SIZE}" "${STORAGE_FILE}" |
| mkfs.ext4 "${STORAGE_FILE}" |
| chown wilco_dtc:wilco_dtc "${STORAGE_FILE}" |
| |
| # If the VM storage exists but is not the correct size, attempt to resize it. |
| elif [ "$(du -h --apparent-size "${STORAGE_FILE}" | cut -f1)" != \ |
| "${STORAGE_SIZE}" ]; then |
| |
| # Used jailing parameters: |
| # -e: new network namespace; |
| # -l: new IPC namespace; |
| # -n: the no_new_privs bit; |
| # -p: new PID namespace; |
| # -r: remount /proc readonly; |
| # -v: new VFS namespace; |
| # -u, -g: user account and group; |
| # --profile: Set up a minimalistic mount namespace; |
| # -k /var: a new tmpfs filesystem for /var; |
| # -b ${STORAGE_PATH}: give read/write access to persistent storage; |
| minijail0 -e -l -n -p -r -v \ |
| -u wilco_dtc -g wilco_dtc \ |
| --profile=minimalistic-mountns \ |
| -k 'var,/var,tmpfs,MS_NODEV|MS_NOSUID|MS_NOEXEC' \ |
| -b "${STORAGE_PATH}",,1 \ |
| -S /usr/share/policy/wilco-dtc-e2fsck-seccomp.policy \ |
| -- /sbin/e2fsck -fp "${STORAGE_FILE}" |
| |
| minijail0 -e -l -n -p -r -v \ |
| -u wilco_dtc -g wilco_dtc \ |
| --profile=minimalistic-mountns \ |
| -k 'var,/var,tmpfs,MS_NODEV|MS_NOSUID|MS_NOEXEC' \ |
| -b "${STORAGE_PATH}",,1 \ |
| -S /usr/share/policy/wilco-dtc-resize2fs-seccomp.policy \ |
| -- /sbin/resize2fs "${STORAGE_FILE}" "${STORAGE_SIZE}" |
| fi |
| |
| end script |
| |
| # Used jailing parameters: |
| # -e: new network namespace; |
| # -i: exit after forking; |
| # -l: new IPC namespace; |
| # -n: the no_new_privs bit; |
| # -p: new PID namespace; |
| # -r: remount /proc readonly; |
| # -t: a new tmpfs filesystem for /tmp; |
| # -v: new VFS namespace; |
| # --uts: new UTS/hostname namespace; |
| # -u, -g: user account and group; |
| # -G: inherit supplementary groups; |
| # --mount-dev: a new /dev mount; |
| # --profile: minimalistic mount namespace; |
| # -k /run: a new tmpfs filesystem for /run, with the subsequent parameters |
| # mounting specific files into this directory; |
| # -k /var: a new tmpfs filesystem for /var |
| # -b /dev/chromeos-low-mem: crosvm can alert system of low memory; |
| # -b /dev/log: provide minijail log access; |
| # -b /dev/kvm: give access to crosvm to start VMs; |
| # -b /dev/vhost-vsock: give access for VM communication; |
| # -b ${STORAGE_PATH}: give access to persistent storage; |
| # -b ${DIAGNOSTICS_PARTITION}: give read only access to diagnostics partition; |
| # -b ${RUNTIME_PATH}: temporary directories to create VM sock |
| script |
| |
| # Give wilco_dtc permission to read the diagnostics partition. |
| DIAGNOSTICS_PARTITION="$(cgpt find -l DIAGNOSTICS $(rootdev -d -s) | head -1)" |
| setfacl -m u:wilco_dtc:r "${DIAGNOSTICS_PARTITION}" |
| |
| # Parse the environment variables. |
| set -- |
| if [ "${STARTUP_PROCESSES}" = false ]; then |
| set -- "$@" -p maitred.no_startup_processes |
| fi |
| |
| if [ "${TEST_DBUS_CONFIG}" = true ]; then |
| set -- "$@" -p dtc.use_test_dbus_config |
| fi |
| |
| exec minijail0 -e -l -n -p -r -t -v --uts \ |
| -u wilco_dtc -g wilco_dtc \ |
| -G \ |
| --mount-dev \ |
| --profile=minimalistic-mountns \ |
| -k 'tmpfs,/run,tmpfs,MS_NODEV|MS_NOSUID|MS_NOEXEC,mode=755,size=10M' \ |
| -k 'var,/var,tmpfs,MS_NODEV|MS_NOSUID|MS_NOEXEC,mode=755,size=32M' \ |
| -b /dev/chromeos-low-mem \ |
| -b /dev/log \ |
| -b /dev/kvm,,1 \ |
| -b /dev/vhost-vsock,,1 \ |
| -b "${STORAGE_PATH}",,1 \ |
| -b "${DIAGNOSTICS_PARTITION}" \ |
| -b "${RUNTIME_PATH}",,1 \ |
| -- /usr/bin/crosvm run \ |
| -r "${VM_PATH}"/vm_rootfs.img \ |
| -p maitred.listen_port="${MAITRED_LISTEN_PORT}" \ |
| -p printk.devkmsg=on \ |
| --serial num=1,type=syslog,console=false \ |
| --syslog-tag wilco_dtc \ |
| -c "${VM_CPUS}" \ |
| -m "${VM_MEM}" \ |
| -s "${RUNTIME_PATH}" \ |
| --cid "${VM_CID}" \ |
| -d "${DIAGNOSTICS_PARTITION}" \ |
| --rwdisk "${STORAGE_FILE}" \ |
| "$@" \ |
| "${VM_PATH}"/vm_kernel |
| end script |
| |
| post-start script |
| # Default cpu.shares is 1024. Limit the Wilco VM to 1/8th of that. |
| cgroup_dir="/sys/fs/cgroup/cpu/wilco-dtc" |
| mkdir -p "${cgroup_dir}" |
| echo $(status | cut -f 4 -d ' ') > "${cgroup_dir}/tasks" |
| echo 128 > "${cgroup_dir}/cpu.shares" |
| end script |
| |
| pre-stop script |
| maitred_client --cid=512 --port=8888 --shutdown |
| end script |