btrfs and tar sparse truncate archives
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
Fix Released
|
Medium
|
Joseph Salisbury | ||
Artful |
Fix Released
|
Medium
|
Joseph Salisbury | ||
tar (Ubuntu) |
New
|
Undecided
|
Unassigned | ||
Artful |
New
|
Undecided
|
Unassigned |
Bug Description
== SRU Justification ==
This bug causes btrfs and tar sparse to truncate archives. This bug has been
fixed in v4.15-rc3 by commit e3b8a4858566, which has a prereq commit of f48bf66b662e.
These commits were cc'd to upstream stable and are already in Bionic. However, upstream
4.13 is EOL, so Artful never recieved the fixes, which is the reason for
the SRU request.
== Fixes ==
f48bf66b662e ("Btrfs: move definition of the function btrfs_find_
e3b8a4858566 ("Btrfs: fix reported number of inode blocks after buffered append writes")
== Regression Potential ==
Low. This fix was also sent and accepted to stable, so it has had additional upstream review.
== Test Case ==
A test kernel was built with these patches and tested by the original bug reporter.
The bug reporter states the test kernel resolved the bug.
root@ubuntu:~# lsb_release -rd
Description: Ubuntu 17.10
Release: 17.10
root@ubuntu:~# apt-cache policy linux-image-virtual
linux-image-
Installed: 4.13.0.37.40
Candidate: 4.13.0.37.40
Version table:
*** 4.13.0.37.40 500
500 http://
500 http://
100 /var/lib/
4.13.0.16.17 500
500 http://
3. Taring files into an archive are not truncated
4. Files included in tar are filled with NULLs
To reproduce, run an Artful system with one spare disk:
- mkfs.btrfs -f /dev/sda
- mount /dev/sda /mnt
- grep sda /proc/mounts
/dev/sda /mnt btrfs rw,relatime,
Then run this script which copies a 4MB binary to a btrfs filesystem, tars the directory up containing the binary; then untars to stdout and md5sum compares, showing it's different.
% SPARSE="-S"; rm -rf /mnt/tmp; md5sum /usr/bin/python3.6; mkdir -p /mnt/tmp; cp -a /usr/bin/python3.6 /mnt/tmp; tar -C /mnt/tmp $SPARSE -czf /mnt/test.tgz .; tar $SPARSE -xzf /mnt/test.tgz -O | md5sum
e4121d2f3126b8c
0ce8c4139740198
And now without the sparse flag:
# SPARSE=""; rm -rf /mnt/tmp; md5sum /usr/bin/python3.6; mkdir -p /mnt/tmp; cp -a /usr/bin/python3.6 /mnt/tmp; tar -C /mnt/tmp $SPARSE -czf /mnt/test.tgz .; tar $SPARSE -xzf /mnt/test.tgz -O | md5sum
e4121d2f3126b8c
e4121d2f3126b8c
This has been reported to both gnu-tar and linux-btrfs; I'm not aware of an actual fix.
Note that Xenial 4.4 kernels do not exhibit this behavior, and Bionic 4.15 kernel appears to be fixed as well though I'm not sure what the difference is.
References:
https:/
https:/
https:/
ProblemType: Bug
DistroRelease: Ubuntu 17.10
Package: linux-image-virtual 4.13.0.37.40
ProcVersionSign
Uname: Linux 4.13.0-37-generic x86_64
AlsaDevices:
total 0
crw-rw---- 1 root audio 116, 1 Mar 21 22:55 seq
crw-rw---- 1 root audio 116, 33 Mar 21 22:55 timer
AplayDevices: Error: [Errno 2] No such file or directory: 'aplay': 'aplay'
ApportVersion: 2.20.7-0ubuntu3.7
Architecture: amd64
ArecordDevices: Error: [Errno 2] No such file or directory: 'arecord': 'arecord'
AudioDevicesInUse: Error: command ['fuser', '-v', '/dev/snd/seq', '/dev/snd/timer'] failed with exit code 1:
CRDA: N/A
Date: Wed Mar 21 23:08:05 2018
IwConfig: Error: [Errno 2] No such file or directory: 'iwconfig': 'iwconfig'
Lsusb: Error: command ['lsusb'] failed with exit code 1:
MachineType: QEMU Standard PC (i440FX + PIIX, 1996)
PciMultimedia:
ProcEnviron:
TERM=xterm-
PATH=(custom, no user)
LANG=C.UTF-8
SHELL=/bin/bash
ProcFB:
ProcKernelCmdLine: BOOT_IMAGE=
RelatedPackageV
linux-
linux-
linux-firmware N/A
RfKill: Error: [Errno 2] No such file or directory: 'rfkill': 'rfkill'
SourcePackage: linux
UpgradeStatus: No upgrade log present (probably fresh install)
dmi.bios.date: 04/01/2014
dmi.bios.vendor: SeaBIOS
dmi.bios.version: Ubuntu-
dmi.chassis.type: 1
dmi.chassis.vendor: QEMU
dmi.chassis.
dmi.modalias: dmi:bvnSeaBIOS:
dmi.product.name: Standard PC (i440FX + PIIX, 1996)
dmi.product.
dmi.sys.vendor: QEMU
Related branches
- Server Team CI bot: Needs Fixing (continuous-integration)
- curtin developers: Pending requested
-
Diff: 10328 lines (+4964/-2110)175 files modifiedHACKING.rst (+122/-0)
LICENSE (+11/-657)
LICENSE-AGPLv3 (+661/-0)
bin/curtin (+4/-0)
curtin/__init__.py (+2/-17)
curtin/block/__init__.py (+60/-27)
curtin/block/clear_holders.py (+92/-45)
curtin/block/iscsi.py (+1/-18)
curtin/block/lvm.py (+3/-16)
curtin/block/mdadm.py (+1/-19)
curtin/block/mkfs.py (+4/-16)
curtin/block/zfs.py (+243/-0)
curtin/commands/__init__.py (+1/-16)
curtin/commands/apply_net.py (+6/-30)
curtin/commands/apt_config.py (+2/-16)
curtin/commands/block_attach_iscsi.py (+3/-16)
curtin/commands/block_detach_iscsi.py (+3/-16)
curtin/commands/block_info.py (+3/-16)
curtin/commands/block_meta.py (+179/-29)
curtin/commands/block_wipe.py (+1/-16)
curtin/commands/clear_holders.py (+3/-16)
curtin/commands/collect_logs.py (+171/-0)
curtin/commands/curthooks.py (+70/-17)
curtin/commands/extract.py (+60/-47)
curtin/commands/hook.py (+1/-16)
curtin/commands/in_target.py (+23/-39)
curtin/commands/install.py (+17/-25)
curtin/commands/main.py (+4/-18)
curtin/commands/mkfs.py (+1/-16)
curtin/commands/net_meta.py (+1/-16)
curtin/commands/pack.py (+1/-16)
curtin/commands/swap.py (+1/-16)
curtin/commands/system_install.py (+1/-16)
curtin/commands/system_upgrade.py (+1/-16)
curtin/commands/unmount.py (+3/-16)
curtin/commands/version.py (+1/-16)
curtin/config.py (+3/-16)
curtin/deps/__init__.py (+29/-18)
curtin/deps/check.py (+1/-16)
curtin/deps/install.py (+1/-16)
curtin/futil.py (+3/-16)
curtin/gpg.py (+4/-17)
curtin/log.py (+1/-16)
curtin/net/__init__.py (+1/-18)
curtin/net/network_state.py (+3/-16)
curtin/pack.py (+1/-17)
curtin/reporter/__init__.py (+2/-16)
curtin/reporter/events.py (+2/-16)
curtin/reporter/handlers.py (+3/-1)
curtin/reporter/legacy/__init__.py (+4/-0)
curtin/reporter/legacy/maas.py (+4/-0)
curtin/reporter/registry.py (+3/-4)
curtin/swap.py (+18/-16)
curtin/udev.py (+1/-17)
curtin/url_helper.py (+151/-5)
curtin/util.py (+59/-22)
curtin/version.py (+4/-0)
debian/changelog (+49/-0)
dev/null (+0/-253)
doc/index.rst (+1/-1)
doc/topics/config.rst (+44/-1)
doc/topics/hacking.rst (+2/-0)
doc/topics/integration-testing.rst (+15/-0)
doc/topics/storage.rst (+224/-1)
examples/finalize.windows (+3/-0)
examples/tests/basic-zfsroot.yaml (+31/-0)
examples/tests/basic.yaml (+13/-0)
examples/tests/dirty_disks_config.yaml (+20/-4)
examples/tests/filesystem_battery.yaml (+101/-0)
examples/tests/mdadm_bcache.yaml (+22/-5)
examples/tests/pollinate-useragent.yaml (+4/-0)
examples/tests/uefi_basic.yaml (+0/-15)
examples/tests/zfsroot.yaml (+102/-0)
helpers/common (+15/-1)
helpers/install-grub (+3/-0)
helpers/list-flash-kernel-packages (+4/-0)
helpers/partition (+3/-0)
helpers/shell-archive (+5/-2)
helpers/smtar (+2/-0)
tests/unittests/__init__.py (+0/-1)
tests/unittests/helpers.py (+3/-16)
tests/unittests/test_apt_custom_sources_list.py (+3/-2)
tests/unittests/test_apt_source.py (+3/-2)
tests/unittests/test_basic.py (+2/-1)
tests/unittests/test_block.py (+34/-7)
tests/unittests/test_block_iscsi.py (+2/-0)
tests/unittests/test_block_lvm.py (+4/-0)
tests/unittests/test_block_mdadm.py (+2/-1)
tests/unittests/test_block_mkfs.py (+4/-0)
tests/unittests/test_block_zfs.py (+378/-0)
tests/unittests/test_clear_holders.py (+66/-4)
tests/unittests/test_commands_apply_net.py (+4/-0)
tests/unittests/test_commands_block_meta.py (+50/-1)
tests/unittests/test_commands_collect_logs.py (+337/-0)
tests/unittests/test_commands_install.py (+141/-0)
tests/unittests/test_commands_unmount.py (+3/-0)
tests/unittests/test_config.py (+2/-0)
tests/unittests/test_curthooks.py (+73/-0)
tests/unittests/test_feature.py (+4/-0)
tests/unittests/test_gpg.py (+4/-0)
tests/unittests/test_make_dname.py (+2/-0)
tests/unittests/test_net.py (+2/-1)
tests/unittests/test_pack.py (+6/-3)
tests/unittests/test_partitioning.py (+2/-0)
tests/unittests/test_public.py (+3/-0)
tests/unittests/test_reporter.py (+19/-16)
tests/unittests/test_swap.py (+39/-0)
tests/unittests/test_url_helper.py (+122/-0)
tests/unittests/test_util.py (+86/-0)
tests/unittests/test_version.py (+2/-1)
tests/vmtests/__init__.py (+161/-52)
tests/vmtests/helpers.py (+4/-16)
tests/vmtests/image_sync.py (+2/-81)
tests/vmtests/releases.py (+16/-1)
tests/vmtests/report_webhook_logger.py (+5/-1)
tests/vmtests/test_apt_config_cmd.py (+4/-0)
tests/vmtests/test_apt_source.py (+4/-0)
tests/vmtests/test_basic.py (+4/-0)
tests/vmtests/test_bcache_basic.py (+4/-0)
tests/vmtests/test_bcache_bug1718699.py (+4/-0)
tests/vmtests/test_centos_basic.py (+4/-0)
tests/vmtests/test_fs_battery.py (+179/-0)
tests/vmtests/test_install_umount.py (+4/-0)
tests/vmtests/test_iscsi.py (+4/-0)
tests/vmtests/test_journald_reporter.py (+4/-0)
tests/vmtests/test_lvm.py (+4/-0)
tests/vmtests/test_lvm_iscsi.py (+4/-0)
tests/vmtests/test_lvm_root.py (+5/-2)
tests/vmtests/test_mdadm_bcache.py (+28/-6)
tests/vmtests/test_mdadm_iscsi.py (+5/-0)
tests/vmtests/test_multipath.py (+4/-0)
tests/vmtests/test_network.py (+4/-0)
tests/vmtests/test_network_alias.py (+4/-0)
tests/vmtests/test_network_bonding.py (+4/-0)
tests/vmtests/test_network_bridging.py (+4/-0)
tests/vmtests/test_network_enisource.py (+4/-1)
tests/vmtests/test_network_ipv6.py (+4/-0)
tests/vmtests/test_network_ipv6_enisource.py (+4/-0)
tests/vmtests/test_network_ipv6_static.py (+4/-0)
tests/vmtests/test_network_ipv6_vlan.py (+4/-0)
tests/vmtests/test_network_mtu.py (+6/-4)
tests/vmtests/test_network_static.py (+4/-0)
tests/vmtests/test_network_static_routes.py (+4/-0)
tests/vmtests/test_network_vlan.py (+4/-0)
tests/vmtests/test_nvme.py (+4/-0)
tests/vmtests/test_old_apt_features.py (+4/-0)
tests/vmtests/test_pollinate_useragent.py (+66/-0)
tests/vmtests/test_raid5_bcache.py (+4/-0)
tests/vmtests/test_simple.py (+4/-0)
tests/vmtests/test_ubuntu_core.py (+4/-0)
tests/vmtests/test_uefi_basic.py (+19/-1)
tests/vmtests/test_vmtests.py (+4/-0)
tests/vmtests/test_zfsroot.py (+83/-0)
tools/build-deb (+3/-0)
tools/curtainer (+60/-18)
tools/curtin-from-container (+2/-1)
tools/curtin-log-print (+4/-16)
tools/find-tgt (+3/-1)
tools/jenkins-runner (+1/-0)
tools/launch (+18/-11)
tools/make-tarball (+4/-0)
tools/new-upstream-snapshot (+3/-0)
tools/noproxy (+4/-1)
tools/report_webhook_logger (+3/-0)
tools/run-pep8 (+3/-0)
tools/run-pyflakes (+3/-0)
tools/run-pyflakes3 (+4/-0)
tools/ssh-keys-list (+4/-0)
tools/tox-venv (+3/-1)
tools/usquery (+4/-16)
tools/vmtest-sync-images (+4/-0)
tools/vmtest-system-setup (+2/-1)
tools/webserv (+4/-0)
tools/write-curtin (+3/-0)
tools/xkvm (+2/-1)
- Server Team CI bot: Needs Fixing (continuous-integration)
- curtin developers: Pending requested
-
Diff: 10328 lines (+4964/-2110)175 files modifiedHACKING.rst (+122/-0)
LICENSE (+11/-657)
LICENSE-AGPLv3 (+661/-0)
bin/curtin (+4/-0)
curtin/__init__.py (+2/-17)
curtin/block/__init__.py (+60/-27)
curtin/block/clear_holders.py (+92/-45)
curtin/block/iscsi.py (+1/-18)
curtin/block/lvm.py (+3/-16)
curtin/block/mdadm.py (+1/-19)
curtin/block/mkfs.py (+4/-16)
curtin/block/zfs.py (+243/-0)
curtin/commands/__init__.py (+1/-16)
curtin/commands/apply_net.py (+6/-30)
curtin/commands/apt_config.py (+2/-16)
curtin/commands/block_attach_iscsi.py (+3/-16)
curtin/commands/block_detach_iscsi.py (+3/-16)
curtin/commands/block_info.py (+3/-16)
curtin/commands/block_meta.py (+179/-29)
curtin/commands/block_wipe.py (+1/-16)
curtin/commands/clear_holders.py (+3/-16)
curtin/commands/collect_logs.py (+171/-0)
curtin/commands/curthooks.py (+70/-17)
curtin/commands/extract.py (+60/-47)
curtin/commands/hook.py (+1/-16)
curtin/commands/in_target.py (+23/-39)
curtin/commands/install.py (+17/-25)
curtin/commands/main.py (+4/-18)
curtin/commands/mkfs.py (+1/-16)
curtin/commands/net_meta.py (+1/-16)
curtin/commands/pack.py (+1/-16)
curtin/commands/swap.py (+1/-16)
curtin/commands/system_install.py (+1/-16)
curtin/commands/system_upgrade.py (+1/-16)
curtin/commands/unmount.py (+3/-16)
curtin/commands/version.py (+1/-16)
curtin/config.py (+3/-16)
curtin/deps/__init__.py (+29/-18)
curtin/deps/check.py (+1/-16)
curtin/deps/install.py (+1/-16)
curtin/futil.py (+3/-16)
curtin/gpg.py (+4/-17)
curtin/log.py (+1/-16)
curtin/net/__init__.py (+1/-18)
curtin/net/network_state.py (+3/-16)
curtin/pack.py (+1/-17)
curtin/reporter/__init__.py (+2/-16)
curtin/reporter/events.py (+2/-16)
curtin/reporter/handlers.py (+3/-1)
curtin/reporter/legacy/__init__.py (+4/-0)
curtin/reporter/legacy/maas.py (+4/-0)
curtin/reporter/registry.py (+3/-4)
curtin/swap.py (+18/-16)
curtin/udev.py (+1/-17)
curtin/url_helper.py (+151/-5)
curtin/util.py (+59/-22)
curtin/version.py (+4/-0)
debian/changelog (+49/-0)
dev/null (+0/-253)
doc/index.rst (+1/-1)
doc/topics/config.rst (+44/-1)
doc/topics/hacking.rst (+2/-0)
doc/topics/integration-testing.rst (+15/-0)
doc/topics/storage.rst (+224/-1)
examples/finalize.windows (+3/-0)
examples/tests/basic-zfsroot.yaml (+31/-0)
examples/tests/basic.yaml (+13/-0)
examples/tests/dirty_disks_config.yaml (+20/-4)
examples/tests/filesystem_battery.yaml (+101/-0)
examples/tests/mdadm_bcache.yaml (+22/-5)
examples/tests/pollinate-useragent.yaml (+4/-0)
examples/tests/uefi_basic.yaml (+0/-15)
examples/tests/zfsroot.yaml (+102/-0)
helpers/common (+15/-1)
helpers/install-grub (+3/-0)
helpers/list-flash-kernel-packages (+4/-0)
helpers/partition (+3/-0)
helpers/shell-archive (+5/-2)
helpers/smtar (+2/-0)
tests/unittests/__init__.py (+0/-1)
tests/unittests/helpers.py (+3/-16)
tests/unittests/test_apt_custom_sources_list.py (+3/-2)
tests/unittests/test_apt_source.py (+3/-2)
tests/unittests/test_basic.py (+2/-1)
tests/unittests/test_block.py (+34/-7)
tests/unittests/test_block_iscsi.py (+2/-0)
tests/unittests/test_block_lvm.py (+4/-0)
tests/unittests/test_block_mdadm.py (+2/-1)
tests/unittests/test_block_mkfs.py (+4/-0)
tests/unittests/test_block_zfs.py (+378/-0)
tests/unittests/test_clear_holders.py (+66/-4)
tests/unittests/test_commands_apply_net.py (+4/-0)
tests/unittests/test_commands_block_meta.py (+50/-1)
tests/unittests/test_commands_collect_logs.py (+337/-0)
tests/unittests/test_commands_install.py (+141/-0)
tests/unittests/test_commands_unmount.py (+3/-0)
tests/unittests/test_config.py (+2/-0)
tests/unittests/test_curthooks.py (+73/-0)
tests/unittests/test_feature.py (+4/-0)
tests/unittests/test_gpg.py (+4/-0)
tests/unittests/test_make_dname.py (+2/-0)
tests/unittests/test_net.py (+2/-1)
tests/unittests/test_pack.py (+6/-3)
tests/unittests/test_partitioning.py (+2/-0)
tests/unittests/test_public.py (+3/-0)
tests/unittests/test_reporter.py (+19/-16)
tests/unittests/test_swap.py (+39/-0)
tests/unittests/test_url_helper.py (+122/-0)
tests/unittests/test_util.py (+86/-0)
tests/unittests/test_version.py (+2/-1)
tests/vmtests/__init__.py (+161/-52)
tests/vmtests/helpers.py (+4/-16)
tests/vmtests/image_sync.py (+2/-81)
tests/vmtests/releases.py (+16/-1)
tests/vmtests/report_webhook_logger.py (+5/-1)
tests/vmtests/test_apt_config_cmd.py (+4/-0)
tests/vmtests/test_apt_source.py (+4/-0)
tests/vmtests/test_basic.py (+4/-0)
tests/vmtests/test_bcache_basic.py (+4/-0)
tests/vmtests/test_bcache_bug1718699.py (+4/-0)
tests/vmtests/test_centos_basic.py (+4/-0)
tests/vmtests/test_fs_battery.py (+179/-0)
tests/vmtests/test_install_umount.py (+4/-0)
tests/vmtests/test_iscsi.py (+4/-0)
tests/vmtests/test_journald_reporter.py (+4/-0)
tests/vmtests/test_lvm.py (+4/-0)
tests/vmtests/test_lvm_iscsi.py (+4/-0)
tests/vmtests/test_lvm_root.py (+5/-2)
tests/vmtests/test_mdadm_bcache.py (+28/-6)
tests/vmtests/test_mdadm_iscsi.py (+5/-0)
tests/vmtests/test_multipath.py (+4/-0)
tests/vmtests/test_network.py (+4/-0)
tests/vmtests/test_network_alias.py (+4/-0)
tests/vmtests/test_network_bonding.py (+4/-0)
tests/vmtests/test_network_bridging.py (+4/-0)
tests/vmtests/test_network_enisource.py (+4/-1)
tests/vmtests/test_network_ipv6.py (+4/-0)
tests/vmtests/test_network_ipv6_enisource.py (+4/-0)
tests/vmtests/test_network_ipv6_static.py (+4/-0)
tests/vmtests/test_network_ipv6_vlan.py (+4/-0)
tests/vmtests/test_network_mtu.py (+6/-4)
tests/vmtests/test_network_static.py (+4/-0)
tests/vmtests/test_network_static_routes.py (+4/-0)
tests/vmtests/test_network_vlan.py (+4/-0)
tests/vmtests/test_nvme.py (+4/-0)
tests/vmtests/test_old_apt_features.py (+4/-0)
tests/vmtests/test_pollinate_useragent.py (+66/-0)
tests/vmtests/test_raid5_bcache.py (+4/-0)
tests/vmtests/test_simple.py (+4/-0)
tests/vmtests/test_ubuntu_core.py (+4/-0)
tests/vmtests/test_uefi_basic.py (+19/-1)
tests/vmtests/test_vmtests.py (+4/-0)
tests/vmtests/test_zfsroot.py (+83/-0)
tools/build-deb (+3/-0)
tools/curtainer (+60/-18)
tools/curtin-from-container (+2/-1)
tools/curtin-log-print (+4/-16)
tools/find-tgt (+3/-1)
tools/jenkins-runner (+1/-0)
tools/launch (+18/-11)
tools/make-tarball (+4/-0)
tools/new-upstream-snapshot (+3/-0)
tools/noproxy (+4/-1)
tools/report_webhook_logger (+3/-0)
tools/run-pep8 (+3/-0)
tools/run-pyflakes (+3/-0)
tools/run-pyflakes3 (+4/-0)
tools/ssh-keys-list (+4/-0)
tools/tox-venv (+3/-1)
tools/usquery (+4/-16)
tools/vmtest-sync-images (+4/-0)
tools/vmtest-system-setup (+2/-1)
tools/webserv (+4/-0)
tools/write-curtin (+3/-0)
tools/xkvm (+2/-1)
- Server Team CI bot: Approve (continuous-integration)
- curtin developers: Pending requested
-
Diff: 711 lines (+470/-12)15 files modifiedcurtin/commands/curthooks.py (+63/-0)
curtin/url_helper.py (+60/-0)
debian/changelog (+12/-0)
doc/topics/config.rst (+31/-0)
examples/tests/basic.yaml (+4/-0)
examples/tests/pollinate-useragent.yaml (+4/-0)
helpers/shell-archive (+4/-2)
tests/unittests/test_curthooks.py (+72/-0)
tests/unittests/test_url_helper.py (+98/-0)
tests/vmtests/__init__.py (+30/-2)
tests/vmtests/report_webhook_logger.py (+1/-1)
tests/vmtests/test_lvm_root.py (+1/-1)
tests/vmtests/test_mdadm_bcache.py (+22/-4)
tests/vmtests/test_network_mtu.py (+2/-2)
tests/vmtests/test_pollinate_useragent.py (+66/-0)
- Scott Moser (community): Approve
- Server Team CI bot: Approve (continuous-integration)
-
Diff: 24 lines (+4/-2)1 file modifiedhelpers/shell-archive (+4/-2)
description: | updated |
Changed in linux (Ubuntu): | |
status: | Triaged → In Progress |
Changed in linux (Ubuntu Artful): | |
status: | Triaged → In Progress |
Changed in linux (Ubuntu): | |
status: | In Progress → Fix Released |
Changed in linux (Ubuntu Artful): | |
status: | In Progress → Fix Committed |
This change was made by a bot.