The mmaps made through the sys_util API are usually for guest memory or
other large shared memory chunks that will pollute the file system with
huge dumps on crash. By using MADV_DONTDUMP, we save the file system
from storing these useless data segments when crosvm crashes.
TEST=./build_test
BUG=None
Change-Id: I2041523648cd7c150bbdbfceef589f42d3f9c2b9
Reviewed-on: https://chromium-review.googlesource.com/890279
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Files are Pollable because they have an FD. Whether this makes sense for
any specific `File` is not enforced, but it will never be unsafe or
undefined when used with Poller.
BUG=chromium:793688
TEST=None
Change-Id: I2ce7ffd1b408bcee5ffbb3738d26339aa0c466e0
Reviewed-on: https://chromium-review.googlesource.com/985617
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
If POLLHUP is filtered out of the returned tokens, the caller of
Poller::poll will likely just put the same (token, fd) in the next call
to poll which will return instantly. This degrades into a busy poll loop
without the chance for the caller to change the poll list.
Instead, this change changes the filter to return tokens on POLLHUP so
that the caller will hopefully notice the FD associated with the token
has been hungup and will close it.
BUG=chromium:816692
TEST=None
Change-Id: Ie36d8a647a5fd7faabfd57a562205f75c77991e7
Reviewed-on: https://chromium-review.googlesource.com/985616
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
The only instance of libstd getting file flags is the debug formatter
for `File` which would be hacky to depend on. This change adds a type
and method to directly get open file flags.
TEST=cargo test -p sys_util
BUG=chromium:793688
Change-Id: I9fe411d8cb45d2993e2334ffe41f2eb6ec48de70
Reviewed-on: https://chromium-review.googlesource.com/985615
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
This is useful to get the total size of memory without having to write
something that iterates over the regions explicitly.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on caroline
Change-Id: Iac9a341b4c41d6462cf731f6267b92a0169578e4
Reviewed-on: https://chromium-review.googlesource.com/977565
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Calculate the number of bits necessary to represent the enum variant
using the next_power_of_two() and trailing_zeros() functions from the
primitive usize type.
Also add a test to ensure that the returned value is correct when there
is only one variant in the enum.
BUG=none
TEST=unit tests
Change-Id: Ibd15efd4f06e17a74489fee04ff19aca0dde68b2
Signed-off-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/959624
Reviewed-by: Zach Reizner <zachr@chromium.org>
This change simplifies plugin processing by removing the awkward
run_until_started loop. This also switches to use PollContext instead
of the Poller/Pollable interface, which required reallocating a Vec
every loop to satisfy the borrow checker.
TEST=cargo test --features plugin
BUG=chromium:816692
Change-Id: Iedf26a32840a9a038205c4be8d1adb2f1b565a5c
Reviewed-on: https://chromium-review.googlesource.com/938653
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Using an enum implementing PollToken is the recommended way to use
PollContext, but writing the trait impls for each enum is mechanical yet
error prone. This is a perfect candidate for a custom derive, which
automates away the process using a simple derive attribute on an enum.
BUG=chromium:816692
TEST=cargo test -p sys_util
Change-Id: If21d0f94f9af4b4f6cef1f24c78fc36b50471053
Reviewed-on: https://chromium-review.googlesource.com/940865
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
A common cause of silent 100% CPU usage on otherwise idle VMs is because
some poll loop is waiting on sockets that were hung up on. An unrelated
issue is that using the Poller interface requires dynamic allocation on
every poll call for dynamically sized poll lists.
The PollContext struct detects and warns about the first problem at runtime
and solves the latter problem.
TEST=cargo test -p sys_util
BUG=chromium:816692
Change-Id: I42a9c961db07191d25bcba77c5136f5729400ec9
Reviewed-on: https://chromium-review.googlesource.com/933870
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
On Linux, signal handlers installed with signal() will restart
interrupted system calls. When we moved to using sigaction() we forgot
to specify SA_RESTART and so we started experiencing returns from read
write system calls with EINTR, which throws off some of the code.
Instead of sprinkling "handle_eintr" everywhere, let's restore the old
behavior.
TEST=cargo test --features plugin; cargo test -p sys_util
BUG=chromium:800626
Change-Id: I24c23069ad4c9e7be8c484ee4c57f67451a2944d
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/944848
Reviewed-by: Zach Reizner <zachr@chromium.org>
I ran into an issue on ARM where ppoll() was returning EINVAL and it
was becuase our timespec value sent to ppoll contained a negative
value for tv_sec. We need to use the correct type when determining
the max value.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on caroline
Change-Id: I7f8818e5f93e0327fd9facefb5032f7c5fb00ea0
Reviewed-on: https://chromium-review.googlesource.com/945111
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
System functions have 2 ways of signalling errors, either via returning
-1 as result, and setting errno, or directly returning error code, and
we can not distinguish automatically between the 2 options when using
InterruptibleResult trait for i32 values.
Let's remove this trait for i32 and create 2 explicit macros:
handle_eintr_rc and handle_eintr_errno.
TEST=cargo test --features plugin; cargo test -p sys_util
BUG=None
Change-Id: I1dc8e3c023e7bf7875ac3536703eb71fa3206b7b
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/940612
Reviewed-by: Zach Reizner <zachr@chromium.org>
System error codes are positive, we should not try to use the negative
(kernel) form when working with it.
TEST=cargo test --features plugin; cargo test -p sys_util
BUG=None
Change-Id: I8dea773e6148d1814ca0ea5019d5fb7824dc80ac
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/940611
Reviewed-by: Zach Reizner <zachr@chromium.org>
scm_sendmsg() and scm_recvmsg() return negative errors derived from
errnos that are normally positive. When constructing errno::Error from
these error codes we should convert them back into positive values for
error codes to make proper sense.
TEST=cargo test --features plugin; cargo test -p sys_util
BUG=None
Change-Id: Ibf9065b72602e43cb6badd06f85044329d714276
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/940562
Reviewed-by: Zach Reizner <zachr@chromium.org>
This is helpful in passing up low-level errors from system calls.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on caroline
Change-Id: Ic2d8a23240a1449ac78877d37a074fd97a29a065
Reviewed-on: https://chromium-review.googlesource.com/933375
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Sonny Rao <sonnyrao@chromium.org>
This implements the error trait so we can get more useful error
information back on failures.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on caroline
Change-Id: Ia131b1eb14d24709c10f2ba752a962e822134a42
Reviewed-on: https://chromium-review.googlesource.com/938312
Commit-Ready: Sonny Rao <sonnyrao@chromium.org>
Tested-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-by: Sonny Rao <sonnyrao@chromium.org>
We need this ioctl to implement race-free support for kicking/pausing VCPUs.
TEST=cargo test --features plugin; cargo test -p kvm; ./build_test
BUG=chromium:800626
Change-Id: I5dcff54f7eb34568a8d8503e0dde86b6a36ac693
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/932443
Reviewed-by: Zach Reizner <zachr@chromium.org>
Use of signal(2) is only portable with SIG_DFL or SIG_IGN, it should not
be used to set real signal handler. sigaction(2) should be used for this
purpose.
TEST=cargo test --features plugin; cargo test -p kvm; ./build_test
BUG=chromium:800626
Change-Id: I5a8d1f68c7f285b489e08f74f63b573f263e09d1
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/930463
Reviewed-by: Zach Reizner <zachr@chromium.org>
We are planning on using KVM_SET_SIGNAL_MASK and have the signal that we
use to kick VCPU permanently masked to close the race around handling
pause requests, so we need a way to clear pending interrupts, otherwise
VM will never run again.
TEST=cargo test --features plugin; cargo test -p kvm; ./build_test
BUG=chromium:800626
Change-Id: I2dfe6fcb129e4b8156f6a7ff842e171661c56440
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/930462
Reviewed-by: Zach Reizner <zachr@chromium.org>
Move creating sigsets and blocking/unblocking signals form signalfd
module to signal module so they are usable by other parties as well.
BUG=chromium:800626
TEST=cargo test --features=plugin
Change-Id: I281ce784ed6cb341cc1e7cf2784f6fb1e8cc894d
Signed-off-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/930461
Reviewed-by: Zach Reizner <zachr@chromium.org>
Disk images should never be mounted as writable by multiple VMs at once.
Add advisory locking to prevent this.
BUG=chromium:810576
TEST=run crosvm twice with same rwdisk, check that second VM fails to start
Change-Id: I5e6c178515eafa570812a093449eef5a4edc1740
Reviewed-on: https://chromium-review.googlesource.com/929994
Commit-Ready: Stephen Barber <smbarber@chromium.org>
Tested-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
This is used in the plugin process implementation, and it makes sense
that EventFd should have all the RawFd related traits.
TEST=./build_test
BUG=chromium:800626
Change-Id: Ic96623e169e4d9584a082628c1540ca6de709a16
Reviewed-on: https://chromium-review.googlesource.com/900488
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
usize isn't used in this test any more. Remove compiler warning.
Change-Id: I9493e22f563f2fc15532564ea57d70de593c4421
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/902778
Reviewed-by: Sonny Rao <sonnyrao@chromium.org>
We want to be able to run 64-bit ARM kernels using a 32-bit version of
crosvm, to make it more consistent use a u64 to represent
GuestAddress.
BUG=chromium:797868
TEST=./build_test passes on all architectures
TEST=crosvm runs on caroline
Change-Id: I43bf993592caf46891e3e5e05258ab70b6bf3045
Signed-off-by: Sonny Rao <sonnyrao@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/896398
Reviewed-by: Dylan Reid <dgreid@chromium.org>
When servicing requests from a soon to be killed plugin process, a
timeout for poll is needed so that the main process can force kill the
plugin if the plugin takes too long to exit gracefully.
TEST=./build_test
BUG=chromium:800626
Change-Id: Ief0e0b4f01146f85adaee0663bd8e5775c26c588
Reviewed-on: https://chromium-review.googlesource.com/865775
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This will be very useful in tests that need a file as it removes the
need for a temporary file to be created.
Change-Id: I7fb08209174c870279e34ee07aad7a3b05baaad9
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/864625
Reviewed-by: Zach Reizner <zachr@chromium.org>
There were a few places that used this to get the page size inside of an
unsafe block, For convenience, this adds a safe wrapper in sys_util and
replaces all extant usage of sysconf with the wrapper version.
BUG=chromium:800626
TEST=./build_test
Change-Id: Ic65bf72aea90eabd4158fbdcdbe25c3f13ca93ac
Reviewed-on: https://chromium-review.googlesource.com/857907
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This is used to make EventFd passed over unix domain socket, such as by
the plugin API.
TEST=./build_test
BUG=chromium:800626
Change-Id: Ifd6c81c51b31a376d57a007bf413a836f3af870a
Reviewed-on: https://chromium-review.googlesource.com/857906
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Use ok_or to remove the match witch was harder to read. No functional
change. Pull the check in to a function so that it only needs to be
right once.
Change-Id: I0e5801d9e7e82994e7f1fbda0d2692a4afd59d99
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/850850
Reviewed-by: Zach Reizner <zachr@chromium.org>
The other functions in mmap check that the offset doesn't overflow. The
kernel_loader fuzzer found that read forgot to check.
Change-Id: Ifc89dbe40345c5923a5cf29c9f29e810e9e1a1e8
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/850542
Reviewed-by: Zach Reizner <zachr@chromium.org>
The syslog subsystem tries to figure out the file descriptor for the
connection to the system logger so that it can ensure that it doesn't
get closed in each device process.
However, the check does not work properly if there was already an open
connection to the system logger. In this case the openlog call does not
do anything and we end up guessing the wrong file descriptor number for
the syslog connection.
Work around this by adding a closelog() call before attempting all of
this cleverness. In the long run this should be fixed properly by just
bind mounting /dev/log into each device process's jail.
BUG=none
TEST=Running crosvm under minijail0 does not cause an InvalidFd error.
Change-Id: Iffd535d62acdf8053817af74b9e97444c746a0cf
Signed-off-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/851271
Reviewed-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Getting and settings seals is useful to ensure the size of files
underlying memory mappings doesn't shrink, which can trigger a SIGBUS on
access to the truncated pages.
This also bumps the libc version to get MFD_ALLOW_SEALING.
TEST=cargo test
BUG=None
CQ-DEPEND=CL:850535
Change-Id: Ifbe1ec2c47d3d5c51b63472f545acc10d3c8eed2
Reviewed-on: https://chromium-review.googlesource.com/849488
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This is needed to support the plugin process API, which may register
guest memory mapped at an offset from the beginning of a file.
TEST=cargo test
BUG=None
Change-Id: Idf1e9f0287df5510728ab2bcf4dd090f9e81a5bf
Reviewed-on: https://chromium-review.googlesource.com/849495
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This is needed for plugin process style executions because they don't
register guest memory though the GuestMemory interface. Their memory is
more dynamic and ill-suited to the GuestMemory abstraction.
TEST=./build_test
BUG=None
Change-Id: I250b0b874ef6a0e342fd6e659301f389d01a4cda
Reviewed-on: https://chromium-review.googlesource.com/848018
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Add functions to let the kernel know a given range of memory isn't
needed currently. This function will result in `madvise(DONTNEED)`.
The ability to signal memory as not needed will be used by the balloon
driver to allow system memory to be redistributed away from the VM.
Change-Id: I4ca56e09010eec33989824f5738db4a4be0ec428
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/759305
Reviewed-by: Zach Reizner <zachr@chromium.org>
On older kernels, the memfd_create syscall isn't available. Skip shm
tests if that is the case.
Change-Id: I39c1f1779f1f02e90df727c6ca18b5bdae52e855
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/768102
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Mutable references being declared mutable themselves is unnecessary and
now generates a warning.
Change-Id: I29c7652fb86e17a8eda21efc728dd09b726c304f
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/717733
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
To ensure dependencies don't accidentally get updated, their versions are
fixed using the equals constraint. The Cargo.lock file is also checked in
so that the registry won't need to be downloaded by cargo.
These changes are needed so that the crosvm ebuild will not need to
download anything outside of its list of source packages.
TEST=./build_test
BUG=None
Change-Id: Iae8472de77e3589a453685717b26fb1ceb44e257
Reviewed-on: https://chromium-review.googlesource.com/674092
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Pass better errors from mmap and guest_memory. These modules were
written before I understood errors. Now the errors passed back to block
can be propagated.
Change-Id: I1842808a4114a715321c555281aacc211f23511c
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/656837
Reviewed-by: Jason Clinton <jclinton@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
This CL includes a small tweak to sys_util so that cloned processes PIDs
are returned.
The proxy device CHILD_SIGNATURE check was removed because it would
deadlock with the synchronization that DeviceManager's post clone
callback uses to wait for the id maps to be set. The check wasn't that
useful to begin with.
This also bumps the libc version.
TEST=None
BUG=None
Change-Id: I881e08c9626e035044b0be1dd2e9fff3e7e61ec1
Reviewed-on: https://chromium-review.googlesource.com/634270
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
By using libc's openlog, we can ensure that the internal state of the
libc syslogger is consistent with the syslog module. Minijail will be
able to print to stderr and the syslog in the same way the logging
macros in crosvm do. The FD the syslog module uses is shared with libc
and via `syslog::get_fds`, jailed processes can inherit the needed FDs
to continue logging.
Now that `sys_log::init()` must be called in single threaded process,
this moves its tests to the list of the serially run ones in
build_test.py.
TEST=./build_test
BUG=None
Change-Id: I8dbc8ebf9d97ef670185259eceac5f6d3d6824ea
Reviewed-on: https://chromium-review.googlesource.com/649951
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Jason Clinton <jclinton@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Problems that were fixed:
- gcc crate deprecated compile_library
- `cargo test -p kvm` had a compile error
- `cargo test -p kvm_sys` failed to link with libc
- main.rs failed to include `getpid` and had dead code
- fork.rs had a warning in `cargo test -p sys_util`
- unused const in serial.rs
BUG=None
TEST=sudo cargo test -p data_model -p io_jail -p kernel_loader -p kvm \
-p kvm_sys -p net_sys -p net_util -p syscall_defines -p sys_util \
-p virtio_sys -p vhost -p x86_64 -p crosvm
Change-Id: Iaf0389013fbcdfbfaa7cf37ea1a1fc045f480ada
Reviewed-on: https://chromium-review.googlesource.com/642509
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Jason Clinton <jclinton@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
These functions are trivially safe and by adding them to sys_util, we
can remove some unsafe blocks from crosvm. This CL also replaces the
unsafe call sites with the safe alternatives.
There are no previous usages of gete{g,u}id(2), but they will be needed
in a future change.
TEST=None
BUG=None
Change-Id: Ief8787b298cfaa5b7fd1b83f0eba6660369e687d
Reviewed-on: https://chromium-review.googlesource.com/634268
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
This CL adds VM request capabilities to the control socket. These
requests include the basic exit as well as the essential ioeventfd and
irqfd requests. For virtio wayland, the register/unregister device
memory request was added.
TEST=cargo test
BUG=chromium:738638
Change-Id: I0cbf62d85a299cf454bcf6924a4e1d52d5b7183f
Reviewed-on: https://chromium-review.googlesource.com/602593
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>