Configuring scanner buttons Canon 9000f on Linux

Saned works out of the box - you can scan with no issues.

To get the buttons working get scandb you need to use a workaround.

Background
Scanbd is a net proxy that pulls dbus every second for scanner events and proxies scanner calls to saned.
I first installed scanbd from ubuntu repo - 1.4.1-8, but that one seem to be biggy, instead got another one from https://sourceforge.net/projects/scanbd/
Compiled and relinked, but it was still was not working correctly. In scanbd-1.5.1/src/scanbd/scanbd.h I found that it was calling sane_exit twice and triggering segfault. However, not using sane_exit and sane_init makes sane_get_devices not to refresh. I updated to the latests (1.0.27) sane_backends from https://launchpad.net/~rolfbensch/+archive/ubuntu/sane-git/+packages, but there is A BUG in sane 1.0.27 that calling sane_exit more than once will cause segfault.
In scanbd source code you can set everything to reinit by uncommenting
#define SANE_REINIT // do a sane_exit()/sane_init() sequence if new devices are found
the device detection will work but in my testing it will also cause segfaults

Eventually I came up with a workaround to start and stop service via udev whenever the scanner is connected/disconnected, i.e start and stop scanbd on device hotplug. Here is how to install it:

Move existing versions out (if any)

sudo systemctl stop scanbd
sudo mv /usr/sbin/scanbm /usr/sbin/scanbm-1.4.1
sudo mv /usr/sbin/scanbd /usr/sbin/scanbd-1.4.1
sudo ln -s /usr/local/sbin/scanbd /usr/sbin/scanbd
sudo ln -s /usr/local/sbin/scanbm /usr/sbin/scanbm

Configure saned to take over normal saned functions, and call saned when it needs it
ln -sf ../sane.d/saned.conf /etc/scanbd/
edit /etc/sane.d/dll.conf - disable everything except net
edit /etc/sane.d/net.conf

set connect_timeout = 3
localhost # scanbm is listening on localhost

edit /etc/scanbd/sane.d/dll.conf - disable net, and to speed things up leave just pixma there

cp /etc/scanbd/scanner.d/cs9000f.conf
cp /usr/share/scanbd/scripts/cs9000f.sh

edited it to my liking
chmod 755 /usr/share/scanbd/scripts/cs9000f.sh
append this line to /etc/scanbd/scanbd.conf:
include(scanner.d/cs9000f.conf)

systemctl disable saned
systemctl enable scanbd
systemctl enable scanbm

The workaround create the following file to start and stop scanbd on turning on and off scanner.
/etc/udev/rules.d/99-scanbd.rules

ACTION=="remove", SUBSYSTEMS=="usb", ENV{ID_VENDOR_ID}=="04a9", ENV{ID_MODEL_ID}=="190d", RUN+="/usr/bin/pkill -SIGTERM scanbd"
ENV{libsane_matched}=="yes", TAG+="systemd", ENV{SYSTEMD_WANTS}="scanbd.service"

Notes
The workaround could also be done by using systemd binding to the scanner and disconnecting when needed but this uses specific usb bus location.
get device name:
systemctl list-units --all --full | grep "Can"
edit
under [Unit]
add

BindsTo=sys-devices-pci0000:00-0000:00:14.0-usb1-1\x2d3-1\x2d3.1.device
After=sys-devices-pci0000:00-0000:00:14.0-usb1-1\x2d3-1\x2d3.1.device

Troubleshooting udev rules
udevadm control --log-priority=debug
udevadm monitor --environment --udev
udevadm should reload all rules automatically. you can trigger them all by udevadm trigger

Links

File locations
systemd config:

/etc/systemd/system/multi-user.target.wants/scanbd.service -> /lib/systemd/system/scanbd.service
/etc/systemd/system/dbus-de.kmux.scanbd.server.service -> /lib/systemd/system/scanbd.service
/etc/systemd/system/sockets.target.wants/scanbm.socket -> /lib/systemd/system/scanbm.socket

udev
/lib/udev/rules.d/99-saned.rules
dbus
/etc/dbus-1/system.d/scanbd_dbus.conf