Commit graph

48 commits

Author SHA1 Message Date
Chungkai Mei
1db2d481ea libmodprobe: remove dummy parameters for kernel
we consume load_sequential only in libmodprobe, so remove this parameter
before sending them into kernel layer

Bug: 332435366
Test: Built and boot husky targets
Change-Id: I37e63723d3c8d4fd8ca1fda682b344a721b9a637
Signed-off-by: Chungkai Mei <chungkai@google.com>
2024-04-22 19:56:46 -07:00
Junki Min
c8dc7ffd5e toolbox/libmodprobe: add toolbox to vendor_ramdisk
toolbox and libmodprobe are required for module loading before
first stage init begin.

BUG: 329807942
Signed-off-by: Junki Min <joonki.min@samsung.com>
Change-Id: Icf04888e602b012758ebf353ed8e4aff2585fd07
2024-03-18 17:35:26 +09:00
Will McVicker
2d3658a421 libmodprobe: Make IsBlocklisted() public
This allows tools like modprobe to check if a module is blocklisted.

Test: verified lsmod on pixel 6
Bug: 324018983
Change-Id: I5d5278ab056e58a4ee103db94b573928cbeb5c5f
2024-03-07 15:01:54 -08:00
Treehugger Robot
a33362ed50 Merge "libmodprobe: LPM: Cleanup of redundant check" 2023-06-29 17:21:18 +00:00
Kelvin Zhang
db15b6f93d Improve error message of libmodprobe
Log path of module if that module is not found.

Bug: 273752147
Test: th
Change-Id: I428a116ee26f97455229df642acbdc1297098a32
2023-06-27 13:53:43 -07:00
William McVicker
bb8637b399 Merge "Revert "Revert "libmodprobe: LPM: Load all modules in *.load with *.dep satisfied""" 2023-06-09 18:54:42 +00:00
Colin Cross
d459ccd14e Use android::base::Basename instead of basename
basename can have different behavior based on whether the glibc
or posix version is used, and musl doens't provide the glibc version
at all.  Avoid the problem by using the one in libbase instead.

Test: m USE_HOST_MUSL=true host-native -k
Change-Id: If17c7622ed9b9cffc218567a46afb059b608d3c9
2023-04-13 21:59:58 -07:00
Wasim Nazir
ecd154e702 libmodprobe: LPM: Cleanup of redundant check
Removing find-check while removing modules in loop.

Test: Normal/Recovery Boot to home
Bug: 261678056
Change-Id: I5ff41b3e8cf633dc687f819a146404b863d2ae0a
Signed-off-by: Wasim Nazir <quic_wasimn@quicinc.com>
2023-04-06 15:07:31 +05:30
Chung-Kai (Michael) Mei
763e869b38 Revert "Revert "libmodprobe: LPM: Load all modules in *.load with *.dep satisfied""
This reverts commit a0e6703f73.

Reason for revert: the failed devices has disabled the feature now, we'll fixed the problem later so releand this patch first

Change-Id: Ib12b84edbd9489d769a4988908bb89f45c13ca43
2023-04-06 15:04:33 +05:30
Kelvin Zhang
bdd595f0f9 Allow libmodprobe to be used by host binaries
Cuttlefish tooling need libmodprobe to determine if a kernel module is
signed.

Bug: 273752147
Test: th
Change-Id: Icea49802d032b27bd89ed8f0bee1bc4814298774
2023-03-29 15:29:02 -07:00
William McVicker
a0e6703f73 Revert "libmodprobe: LPM: Load all modules in *.load with *.dep satisfied"
This reverts commit 3e6c9dbee8.

Reason for revert: This is breaking boot on several devices.
Bug: 267836481
Bug: 261678056
Change-Id: I67c4b784936828c448a53e3092af70d949fcbc65
2023-02-06 19:36:37 +00:00
Wasim Nazir
3e6c9dbee8 libmodprobe: LPM: Load all modules in *.load with *.dep satisfied
Load all hard-dependent-modules even if they are not listed in *.load.
Defer softdep module loading to InsmodWithDeps, as loading it parallel
breaks the purpose of softdep which is used to load the modules
according to dependency/sequence(pre/post) added.

Test: Normal/Recovery Boot to home
Bug: 261678056
Change-Id: I0aea7580545affbf4caa9205281868aad00a2bb0
Signed-off-by: Wasim Nazir <quic_wasimn@quicinc.com>
2023-01-24 14:15:25 +05:30
chungkai
8b451523a4 libmodprobe: check blockedlist if load failed
check blockedlist if load failed and fix potential race condition

Test: Boot to home
Bug: 240210009
Signed-off-by: chungkai <chungkai@google.com>
Change-Id: I0ccc6c58897c03f5bb5f6349b5c3ec047b458505
2022-08-06 04:48:55 +00:00
chungkai
d84c42e3b3 libmodprobe: allow module with soft dependencies to load in parallel
1. integrate modules which have soft dependencies into parallel loading flow. First, check the soft dependencies are in `module.load`  list. If yes, regard soft dependencies as hard dependencies and load the modules only when their dependencies are loaded. If not, abandon these soft dependencies.

2. also add an allowlist and use the term "load_sequential=1" to load specific modules in sequential.

Test: R4 saves 350ms+ (48%) to load all modules
Bug: 229794277
Signed-off-by: chungkai <chungkai@google.com>
Change-Id: I904fe31cd02f9d499dadc537335cadc88d8add70
2022-07-27 04:57:10 +00:00
Treehugger Robot
a41f3812fd Merge "Load kernel modules in parallel" 2022-03-23 07:40:18 +00:00
Florian Mayer
c6a8821fa7 Add libmodprobe to hwasan-postsubmit
Test: Run tests under HWASan.
Bug: 193568145
Change-Id: I6a259705923d619292b0ae16e4b18a9647032f4e
2022-03-18 21:48:29 +00:00
Chungkai
c60300a2cc Load kernel modules in parallel
First, we load independent module in parallel, then we singly load
modules which have soft-dependencies. then remove them from dependency
list of other modules. Repeat these steps until all modules are loaded.

Bug: 180676019
Test: boot successfully, and save more than 400 ms on Pixel 6 Pro.
Signed-off-by: chungkai <chungkai@google.com>
Change-Id: Ib844cfee72d4049bd951528692c818b4fa6c8e8f
2022-03-18 08:06:07 +00:00
Elliott Hughes
22e082e87a Split up the system/core/ TEST_MAPPING.
A lot of things had moved out of system/core/ without their TEST_MAPPING
entries having gone with them, reducing the amount of presubmit coverage
for those things.

In order to reduce the likelihood of that happening again, I've pushed
all that remained in the system/core/ TEST_MAPPING down into the
individual subdirectories.

Test: treehugger
Change-Id: Ib75d65f9200fa64ae1552471da6fbe5b7023cf94
2021-08-16 16:37:10 -07:00
Inseob Kim
2e20058069 Completely migrate init first stage to Soong
adb_debug.prop is migrated too. And ramdisk_available is added to all
dependencies.

Bug: 187196593
Test: boot
Change-Id: I59cd149e0021211b8fd59c44b93bbf18dc8637bf
2021-06-18 14:26:55 +09:00
Will McVicker
87b2ef0edf libmodprobe: refactor blocklist functionality
Remove the function EnableBlocklist() and add a constructor argument to
enable/disable the use of modules.blocklist. In all cases, the
enabling/disabling of the blocklist happens immediately after creating
the Modprobe object. So this simplies libmodprobe.

Additionally, the use of the blocklist by libmodprobe should be enabled
by default unless explicitly disabled during creation of the Modprobe
object. Currently, only modprobe(8) defaults to not using the blocklist
and includes the argument -b BLOCKLIST for enabling it. That
functionality remains.

This refactor allows us to use the blocklist during first stage init.
However, additional logic is needed to not return an error for the
blocked non-aliased modules during first stage init; otherwise, the
error would result in an init crash leading to a device reboot. So fixup
LoadListedModules() to allow blocking modules without returning an
error.

Bug: 182582036
Test: boot test on pixel 5 with a module in modules.blocklist
Change-Id: I394b5aa98fa98821011982cfe693749010c381f7
2021-03-31 09:34:47 -07:00
Elliott Hughes
9369539a1e Update libmodprobe's OWNERS.
Test: treehugger
Change-Id: I714516a3a655facbe447b798f7de59ab899035ea
2021-03-23 17:53:08 -07:00
Bob Badour
d69ad69a93 [LSC] Add LOCAL_LICENSE_KINDS to system/core
Added SPDX-license-identifier-Apache-2.0 to:
  bootstat/Android.bp
  cli-test/Android.bp
  code_coverage/Android.bp
  cpio/Android.bp
  debuggerd/crasher/Android.bp
  debuggerd/proto/Android.bp
  diagnose_usb/Android.bp
  fs_mgr/libdm/Android.bp
  fs_mgr/libfiemap/Android.bp
  fs_mgr/liblp/Android.bp
  fs_mgr/libsnapshot/Android.bp
  fs_mgr/libstorage_literals/Android.bp
  fs_mgr/libvbmeta/Android.bp
  fs_mgr/tests/Android.bp
  fs_mgr/tools/Android.bp
  gatekeeperd/Android.bp
  healthd/Android.bp
  healthd/testdata/Android.bp
  init/Android.bp
  init/Android.mk
  init/sysprop/Android.bp
  init/test_kill_services/Android.bp
  init/test_service/Android.bp
  libappfuse/Android.bp
  libasyncio/Android.bp
  libbinderwrapper/Android.bp
  libcrypto_utils/Android.bp
  libcrypto_utils/tests/Android.bp
  libdiskconfig/Android.bp
  libgrallocusage/Android.bp
  libkeyutils/mini_keyctl/Android.bp
  libmodprobe/Android.bp
  libnetutils/Android.bp
  libpackagelistparser/Android.bp
  libprocessgroup/Android.bp
  libprocessgroup/cgrouprc/Android.bp
  libprocessgroup/cgrouprc_format/Android.bp
  libprocessgroup/profiles/Android.bp
  libprocessgroup/setup/Android.bp
  libqtaguid/Android.bp
  libsparse/Android.bp
  libstats/push_compat/Android.bp
  libsuspend/Android.bp
  libsync/Android.bp
  libsystem/Android.bp
  libsysutils/Android.bp
  libusbhost/Android.bp
  libutils/Android.bp
  libvndksupport/Android.bp
  libvndksupport/tests/Android.bp
  llkd/Android.bp
  llkd/tests/Android.bp
  property_service/libpropertyinfoparser/Android.bp
  property_service/libpropertyinfoserializer/Android.bp
  property_service/property_info_checker/Android.bp
  qemu_pipe/Android.bp
  reboot/Android.bp
  rootdir/Android.bp
  rootdir/Android.mk
  rootdir/avb/Android.bp
  rootdir/avb/Android.mk
  run-as/Android.bp
  sdcard/Android.bp
  set-verity-state/Android.bp
  shell_and_utilities/Android.bp
  storaged/Android.bp
  toolbox/Android.bp
  trusty/apploader/Android.bp
  trusty/confirmationui/Android.bp
  trusty/confirmationui/fuzz/Android.bp
  trusty/coverage/Android.bp
  trusty/fuzz/Android.bp
  trusty/fuzz/test/Android.bp
  trusty/gatekeeper/Android.bp
  trusty/gatekeeper/fuzz/Android.bp
  trusty/keymaster/Android.bp
  trusty/keymaster/fuzz/Android.bp
  trusty/libtrusty/Android.bp
  trusty/libtrusty/tipc-test/Android.bp
  trusty/secure_dpu/Android.bp
  trusty/storage/interface/Android.bp
  trusty/storage/lib/Android.bp
  trusty/storage/proxy/Android.bp
  trusty/storage/tests/Android.bp
  trusty/utils/spiproxyd/Android.bp
  trusty/utils/trusty-ut-ctrl/Android.bp
  usbd/Android.bp
  watchdogd/Android.bp

Added SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD to:
  debuggerd/Android.bp
  fastboot/Android.bp
  libkeyutils/Android.bp

Added SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
    SPDX-license-identifier-MIT
to:
  libcutils/Android.bp

Added SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-MIT
to:
  fs_mgr/Android.bp
  fs_mgr/libfs_avb/Android.bp
  trusty/Android.bp
  trusty/utils/rpmb_dev/Android.bp

Added SPDX-license-identifier-BSD
to:
  fastboot/fuzzy_fastboot/Android.bp

Bug: 68860345
Bug: 151177513
Bug: 151953481

Test: m all

Exempt-From-Owner-Approval: janitorial work
Change-Id: Id740a7d2884556081fdb68876584b25eb95e1bef
2021-02-19 12:59:05 -08:00
Elliott Hughes
c3a206ccda Revert "[LSC] Add LOCAL_LICENSE_KINDS to system/core"
This reverts commit 187b7d1950.

Reason for revert: system/core is multiple projects, not one.

Change-Id: I790ea41741f8cd9b8b6db2f59a49e71fb0958fd6
2021-02-16 20:01:20 +00:00
Bob Badour
187b7d1950 [LSC] Add LOCAL_LICENSE_KINDS to system/core
Added SPDX-license-identifier-Apache-2.0 to:
  bootstat/Android.bp
  cli-test/Android.bp
  code_coverage/Android.bp
  cpio/Android.bp
  debuggerd/crasher/Android.bp
  debuggerd/proto/Android.bp
  diagnose_usb/Android.bp
  fs_mgr/libdm/Android.bp
  fs_mgr/libfiemap/Android.bp
  fs_mgr/liblp/Android.bp
  fs_mgr/libsnapshot/Android.bp
  fs_mgr/libstorage_literals/Android.bp
  fs_mgr/libvbmeta/Android.bp
  fs_mgr/tests/Android.bp
  fs_mgr/tools/Android.bp
  gatekeeperd/Android.bp
  healthd/Android.bp
  healthd/testdata/Android.bp
  init/Android.bp
  init/Android.mk
  init/sysprop/Android.bp
  init/test_kill_services/Android.bp
  init/test_service/Android.bp
  libappfuse/Android.bp
  libasyncio/Android.bp
  libbinderwrapper/Android.bp
  libcrypto_utils/Android.bp
  libcrypto_utils/tests/Android.bp
  libdiskconfig/Android.bp
  libgrallocusage/Android.bp
  libkeyutils/mini_keyctl/Android.bp
  libmodprobe/Android.bp
  libnetutils/Android.bp
  libpackagelistparser/Android.bp
  libprocessgroup/Android.bp
  libprocessgroup/cgrouprc/Android.bp
  libprocessgroup/cgrouprc_format/Android.bp
  libprocessgroup/profiles/Android.bp
  libprocessgroup/setup/Android.bp
  libqtaguid/Android.bp
  libsparse/Android.bp
  libstats/push_compat/Android.bp
  libsuspend/Android.bp
  libsync/Android.bp
  libsystem/Android.bp
  libsysutils/Android.bp
  libusbhost/Android.bp
  libutils/Android.bp
  libvndksupport/Android.bp
  libvndksupport/tests/Android.bp
  llkd/Android.bp
  llkd/tests/Android.bp
  property_service/libpropertyinfoparser/Android.bp
  property_service/libpropertyinfoserializer/Android.bp
  property_service/property_info_checker/Android.bp
  qemu_pipe/Android.bp
  reboot/Android.bp
  rootdir/Android.bp
  rootdir/Android.mk
  rootdir/avb/Android.bp
  rootdir/avb/Android.mk
  run-as/Android.bp
  sdcard/Android.bp
  set-verity-state/Android.bp
  shell_and_utilities/Android.bp
  storaged/Android.bp
  toolbox/Android.bp
  trusty/apploader/Android.bp
  trusty/confirmationui/Android.bp
  trusty/confirmationui/fuzz/Android.bp
  trusty/coverage/Android.bp
  trusty/fuzz/Android.bp
  trusty/fuzz/test/Android.bp
  trusty/gatekeeper/Android.bp
  trusty/gatekeeper/fuzz/Android.bp
  trusty/keymaster/Android.bp
  trusty/keymaster/fuzz/Android.bp
  trusty/libtrusty/Android.bp
  trusty/libtrusty/tipc-test/Android.bp
  trusty/secure_dpu/Android.bp
  trusty/storage/interface/Android.bp
  trusty/storage/lib/Android.bp
  trusty/storage/proxy/Android.bp
  trusty/storage/tests/Android.bp
  trusty/utils/spiproxyd/Android.bp
  trusty/utils/trusty-ut-ctrl/Android.bp
  usbd/Android.bp
  watchdogd/Android.bp

Added SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD to:
  debuggerd/Android.bp
  fastboot/Android.bp
  libkeyutils/Android.bp

Added SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD
    SPDX-license-identifier-MIT
to:
  Android.bp
  libcutils/Android.bp

Added SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-MIT
to:
  fs_mgr/Android.bp
  fs_mgr/libfs_avb/Android.bp
  trusty/utils/rpmb_dev/Android.bp

Added SPDX-license-identifier-BSD
to:
  fastboot/fuzzy_fastboot/Android.bp

Bug: 68860345
Bug: 151177513
Bug: 151953481

Test: m all

Exempt-From-Owner-Approval: janitorial work
Change-Id: I5bd81adb5cdcf2b4dd4141b204eb430ff526af8f
2021-02-16 04:10:03 -08:00
Elliott Hughes
21de4e727e Add new owners to various sub-projects.
Test: treehugger
Change-Id: Ia2a99c0499633ccc5d23c37a1ec93867c876d637
2020-12-11 12:45:45 -08:00
Andrew Scull
fb18f6ef05 libmodprobe: Fail when modules.dep lacks colon
The first argument in a modules.dep line must end with a colon so fail
if that condition is not met.

Test: libmodprobe_tests
Change-Id: I6f3a22758302f16b924e5a16f7af9bf35f1a56f3
2020-10-19 12:00:08 +01:00
Tom Cherry
3085d957e8 libmodprobe: remove SetMinimumLogSeverity() from constructor
Only the parent executable, not libraries should set this value.

Note that `modprobe` in toolbox and first stage init, the two primary
users of this library already set this same minimum log severity.

Test: build
Change-Id: I888968deede3323cc270efc3cfd1b40fc521d2da
2020-08-04 08:28:36 -07:00
Mark Salyzyn
ce30bb8e4b libmodprobe: remove unused EnableVerbose() method
modprobe command no longer uses EnableVerbose, opting to do the
associated operations directly.

Test: compile
Change-Id: Iffc8324f37f34de4eeb9a27e92fdf5524afa2220
2020-06-26 22:30:21 +00:00
Treehugger Robot
2ab39411eb Merge "libmodprobe: improve error reporting." 2020-06-16 22:22:13 +00:00
Elliott Hughes
1ab2c02324 libmodprobe: improve error reporting.
Bug: http://b/159064719
Test: treehugger
Change-Id: Ie3ea73a934a30b4674b30fd3823f59f062418ac7
2020-06-16 11:48:28 -07:00
Mark Salyzyn
9debda17ab modprobe: Use more inclusive language for libmodprobe (Part Deux)
Remove blacklist

Test: none
Change-Id: I14ed08390a7db0b4b962343c61d60230751047ce
2020-06-16 05:14:09 -07:00
Mark Salyzyn
703fb74fb5 modprobe: Use more inclusive language for modprobe and libmodprobe
blacklist is replaced with blocklist.

Test: none
Change-Id: I59f9fde5900b9aee82aca1eab4a6ded3d136063b
2020-06-15 12:51:38 -07:00
Steve Muckle
b0c4881ea9 add libmodprobe api to query the number of modules loaded
In the short term this will be used to help implement support for
multiple kernel module directories but it may be useful in other
contexts as well.

Bug: 157645635
Change-Id: I15a252b6e9394292c8f3557ed65112c935830441
2020-06-03 10:51:45 -07:00
Steve Muckle
4c59323dc6 first_stage_init: load modules in modules.load.recovery in recovery
In recovery mode, load modules from modules.load.recovery if it
exists. Otherwise load from modules.load as usual.

Change-Id: I7636bb5958ed10ae9a66015f04f168129618272f
2020-04-06 12:24:16 -07:00
Steve Muckle
373a3cadd7 libmodprobe: parse kernel command line for module options
Bug: 145808811
Test: atest libmodprobe_tests, verify on flame
Change-Id: I0b41b1610fe13ae526d38f029da888f6f0d8a02d
2019-12-27 13:39:23 -08:00
Mark Salyzyn
d478271b2b libmodprobe: add strict bool argument to LoadListedModules
Continue loading remaining modules after error if strict flag false.

Test: libmodprobe_test
Bug: 141311820
Change-Id: Ib21d4eade1254b16621e7bf2c9efaa173092e7c7
2019-10-31 10:30:35 -07:00
Mark Salyzyn
8c1051918e libmodprobe: Do not reload modules previously instantiated
For modprobe operation.

For an interlocking driver set of about 50 modules, the impact of
their dependencies resulted in a 30 second impact in boot time
trying to load previously loaded modules. This impact is handily
eliminated by keeping a list of modules paths that have been loaded
and skipping them proactively.

Test: Confirmed device boot and 50 module set of drivers functions.
Test: libmodprobe_tests
Bug: 142938937
Bug: 140827934
Change-Id: Iccd11399d6043b38cbd5f93578ee202022e7770c
2019-10-30 07:20:18 -07:00
Treehugger Robot
b02f9b549c Merge changes from topic "toolbox-modprobe"
* changes:
  toolbox: add modprobe
  libmodprobe: add verbose mode
  libmodprobe: add GetAllDependencies
  libmodprobe: add support to list modules
  libmodprobe: add support for a blacklist
  libmodprobe: support parameters in LoadWithAliases
  libmodprobe: add support to remove modules
  libmodprobe: make name canonical in LoadWithAliases
  libmodprobe: make available in vendor
2019-08-07 17:09:09 +00:00
Steve Muckle
ded44c06be libmodprobe: add verbose mode
Change-Id: I2be18320461cd712a4828400b8f29bb5f07c801f
2019-08-06 13:58:13 -07:00
Steve Muckle
781aa78ee2 libmodprobe: add GetAllDependencies
Add a method to retrieve the dependencies (both hard and soft) of a
module.

Change-Id: Ie44ceb3e36856bb1a3e68c5d3c0d55a38deb0ef9
2019-08-06 13:58:13 -07:00
Steve Muckle
012cfa19b0 libmodprobe: add support to list modules
List the known modules with a name matching a given pattern.

Change-Id: I7f6bd1f09a688c66682f94c5837e61d7dc61c1f7
2019-08-06 13:58:13 -07:00
Steve Muckle
e31f840a0a libmodprobe: add support for a blacklist
If the blacklist is enabled, blacklisted modules are treated as though
they are not present.

Change-Id: Ie8712f24298e78f92d5028b1ca3a8a3e07a9190a
2019-08-06 13:58:13 -07:00
Steve Muckle
13700a69d3 libmodprobe: support parameters in LoadWithAliases
Add support to specify module parameters in LoadWithAliases. These
parameters will be appended to any which are specified for the module in
modules.options.

Change-Id: I9aff1656ea397826f815b658b3b52c1892748601
2019-08-06 13:58:13 -07:00
Steve Muckle
bb58b01574 libmodprobe: add support to remove modules
Add a remove method which will unload a given module from the kernel,
along with any modules it depended on, assuming those modules are now
unused.

Change-Id: Ie66dc153ef1771f50e26421d38d3656e95954780
2019-08-06 13:58:13 -07:00
Steve Muckle
73b2928b94 libmodprobe: make name canonical in LoadWithAliases
Make the module name canonical in LoadWithAliases so it may be used
more easily from outside the class.

Change-Id: I7ee496b77a2beea43a6b68daed7af42660747559
2019-08-06 13:58:13 -07:00
Steve Muckle
4104b8803a libmodprobe: make available in vendor
A toolbox implementation of modprobe will require libmodprobe.

Change-Id: I7790576b828ad8cd5fae0c51926d8da9fb540d30
2019-08-06 13:58:13 -07:00
Steve Muckle
025cad4269 libmodprobe: add OWNERS file
Change-Id: I812c0420d982d2c927f40ca43545bdd15bc7b8be
2019-08-05 11:29:01 -07:00
Steve Muckle
18b981ea7c create libmodprobe, integrate into first_stage_init
Modprobe functionality is required both within first stage init and also
as a standalone binary. Create a library for this using and extending
the logic in modalias_handler.cpp.

First stage init will attempt to load modules from /lib/modules.

Bug: 129780532
Change-Id: Ie3582358fd839c2f64e1b386b30ed551a86aef5d
2019-06-18 13:24:56 -07:00