关于如何用DSM7+虚拟linux系统驱动HP老旧打印机并实现无线打印
引子
HP的老旧激光打印机用来在家里给孩子打打作业什么的而是一个不错的选择。然而老旧有老旧的问题:如我的P1108只有USB口,默认情况下只能开PC打印,实在是麻烦。家里正好有常年工作的DS920+,而群晖内置的cups又基本是个废的,只好折腾一下来实现网络共享和无线打印。注意本文基本都是ssh下的终端操作。
准备工作
设备:1台P1108,一台DS920+(DSM7.1),一台工作笔记本。
软件:工作笔记本上备好putty、winscp等工具,DS920+开启SSH,下载好最新的hplip和hplip-plugin。
驱动地址:HP Developers Portal | Version: 3.22.10
插件地址:HP Developers Portal | Plugins
步骤
因为相关类似的文章挺多的,我这里不全面展开了,很多内容都有成熟的文章可以参考。主要按照操作步骤梳理下, 帮助大家避坑。
1、为什么用虚拟机不用docker。现存的文章用docker的很多,但是我实际操作后暂时没有成功过,常见的几个docker镜像中预置的hplip都不完整或者版本陈旧,总之没有一个能正常把我的P1108驱动起来,而且因为镜像内linux用了小众发行版或者魔改严重、发行版陈旧的问题,无法正常完成hplip的自行编译安装。这条路走不通,于是干脆转向虚拟机了,920+支持VMM,实际上是基于qemu的虚拟机,可以用它跑一个最小化安装的ubuntu server。况且一个完整的linux虚拟机其实能做不少事情,多功能和一也不算浪费。
2、宿主机(群晖)准备。为了防止群晖自带cups的不可知冲突,建议干掉它,这部分因为DSM7以后的变化,实际上网上能查到的相关命令并不完整,只有一条关闭服务,并且还要在计划任务里增加杀服务的任务。实际上我们需要执行3条指令,执行完后不需要再添加计划任务了。
连接宿主机(群晖)的ssh,分别执行以下几条命令。首先停下cups:
sudo synosystemctl stop cupsd
然后禁用自启:
sudo synosystemctl disable cupsd
最后禁用服务
sudo synosystemctl mask cupsd
操作完以后群晖自带的cups就先让它byebye了。
3、Ubuntu虚拟机安装。这里不详细展开了,可以参考以下几篇文章,为了节省资源我是装的server版,没有安装图形界面,这个可以丰简由人。我给虚拟机分配了20G虚拟磁盘空间,主要考虑给后续其他折腾的东西做点预留。注意下可以直接在安装时候就指定好虚拟机的固定ip,并且22.04 server安装的时候可以选择最小化安装,另外记得替换国内源并开启ssh。
我没装qemu-guest-agent,可以sudo apt-get install qemu-guest-agent安装一下
参考1:群晖+vmm虚拟机套件安装Ubuntu详细教程(一) - 知乎 (zhihu.com)
参考2:Ubuntu 20.04 live server版安装(详细版) - 运维密码 - 博客园 (cnblogs.com)
4、打印机驱动安装前的一些小准备。这里主要是对环境进行进一步配置,比如重要的cups安装。首先使用putty开启ssh连接至虚拟机(前面安装虚拟机时候可以手动设置地址或者自动获取,记住那个ip)。
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install cups
安装完成后需要配置下
sudo vi /etc/cups/cupsd.conf
注意vi下面按下insert键后进去插入模式可以编辑文本,编辑完成后按esc退出编辑,再键入:wq并回车保存退出。主要是访问权限的设置,不然后续会打不开设置页面。如果只工作在自家局域网,可以把所有的验证改成none,并且删除要求系统管理员的条目,并允许所有访客,各个区段里的样子类似这样。这里我也不熟悉,不多说了,可以找点专业的文章看看。
AuthType None
Order Allow,Deny
Allow from All
另外监听的网络地址也要从localhost改为0.0.0.0。全部完成后重启cups。
sudo /etc/init.d/cups restart
这时候可以开浏览器看看有没有跑起来,访问[虚拟机ip]:631,如192.168.1.100:631,出现以下页面即可。
下面准备hplip的编译安装环境,主要有几个坑,ubuntu上同时有python2.X和3.X。hplip会默认识别到2.X并导致一系列问题,为避免问题,安装一个小插件即可:
sudo apt install python-is-python3
另外如果缺失libavahi-core也会编译出错,这里预先安装上:
sudo apt install libavahi-core-dev
另外因为国内访问python的官方源非常慢,建议预先将源改至国内镜像。
相关内容可参考:How to Install the Latest HPLIP Driver in Ubuntu 20.04 [Fix Dependency Issue] | UbuntuHandbook
5、编译安装hplip驱动。这里仍旧是在虚拟机的ssh操作,将前面下载好的3个hplip和hplip-plugin及校验包推至虚拟机,可以用winscp推上去,这里假设放在/tmp/,即文件的路径分别为/tmp/hplip-3.22.10.run 、/tmp/hplip-3.22.10-plugin.run和/tmp/hplip-3.22.10-plugin.run.asc。
首先赋予执行权限:
chmod +x /tmp/hplip*.run
然后运行安装
sh /tmp/hplip-3.22.10.run
安装模式可以选自动或手动,如果是单一打印的老式单usb机器,可以在手动模式下把所有模块都关掉,可以减少依赖要求,安装出错可能性减少。
选择后需要验证下登录用户密码。
后面基本就都是yes和enter,如果预先配置好python和ubuntu的国内镜像源,应该不会有什么问题,直至完成安装即可。
6、安装hp-plugin。很多docker镜像里就缺这东西。在虚拟机ssh执行:
hp-plugin -i
三个选项建议选p并指定至/tmp/hplip-3.22.10-plugin.run,从官方下载会非常慢,后面如果提示文件校验不了选择忽略就行。我已经安好了,就不继续下一步截图了。
7、安装并驱动打印机。这里需要开启打印机电源、usb口插在群晖上,然后在群晖的VMM里进行如下设置。(这个动作后续会用脚本自动化)
然后继续在虚拟机ssh中执行:
lsusb
可以看到打印机已经被系统识别,记住这个id,后面用的到:
Bus 001 Device 003: ID 03f0:002a HP, Inc LaserJet P1102
执行打印机安装,这里需要sudo,不然识别不到
sudo hp-setup -i
应该就能识别到usb打印机,基本一路y就行,最后可以打印测试页,能打印就说明驱动完成。记得开启共享。回到cups页面也能看到打印机了。
8、应对打印机自动关机引发的问题。P1108会自动关机,关机后再开机,宿主机(群晖)并不会自动把这个usb设备附加到虚拟机中,那不就完蛋了么,为应对这个问题继续操作(话说这机器在PC上是可以设置不自动关机的,不过我设置不成功,可能需要USB直连时候才能正常设置,回头再试,先解决重新开机后自动附加到虚拟机上的问题)。
这里我们用到udev匹配设备插入动作,并使用virsh自动向虚拟机附加usb设备。以下在宿主机(群晖)的ssh运行,首先查看虚拟机的name:
sudo virsh list --all
可以看到所有现存的虚拟机,记下配置了打印机的这个虚拟机的name,就是中间那一串hex数字加连字符:
Id Name State
------------------------------------------------------
1 864bf6fa-628e-46f0-a1f1-e8274axxxxxx running
下面写一个udev的触发规则,为了不和系统自带规则搞混,把规则放在/etc/udev/rules.d/下,由于群晖没有自带这个规则,可能需要mkdir创建两级目录,并给与755权限。
sudo mkdir /etc/udev
sudo chmod 755 /etc/udev
sudo mkdir /etc/udev/rules.d
sudo chmod 755 /etc/udev/rules.d
新建一条规则,注意优先级给高一点,比如99,文件名规则就是:数字-文件名.rules。我这里如下创建:
sudo vi /etc/udev/rules.d/99-usb-hp.rules
进入vi后按insert开始编辑,输入以下两条规则
ACTION=="add", SUBSYSTEM=="usb", DRIVER=="usb", ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="002a", RUN+="/usr/bin/sh /etc/udev/rules.d/usb_udev.sh"
ACTION=="remove", SUBSYSTEM=="usb", DRIVER=="usb", ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="002a", RUN+="/usr/bin/sh /etc/udev/rules.d/usb_udev_rm.sh"
这里的ATTRS{idVendor}和ATTRS{idProduct}分别是前面lsusb时候记下的id里冒号前后的数字。RUN+=后是需要执行的命令,这里执行的命令需要指定到命令的二进制文件地址,我才疏学浅没找到virsh在群晖里的二进制位置,只能退而求其次写两个脚本实现功能。完成编辑后先esc然后:wq回车保存退出。
继续写两个脚本,分别是插入usb设备和取下时候的动作,其实可以合并一个脚本加个action判断,不过我懒。
sudo vi /etc/udev/rules.d/usb_udev.sh
里面内容是
#!/bin/bash
virsh attach-device 864bf6fa-628e-46f0-a1f1-e8274axxxxxx /etc/udev/rules.d/hpusb.xml
中间那一串是刚记下的虚拟机name,后面那个是usb设备的描述,等会写它。
vi保存退出,给脚本赋权:
sudo chmod +x /etc/udev/rules.d/usb_udev.sh
再写拔下设备的脚本
sudo vi /etc/udev/rules.d/usb_udev_rm.sh
里面内容如下,注意attach变成detach
#!/bin/bash
virsh detach-device 864bf6fa-628e-46f0-a1f1-e8274axxxxxx /etc/udev/rules.d/hpusb.xml
vi保存退出,给脚本赋权:
sudo chmod +x /etc/udev/rules.d/usb_udev_rm.sh
继续写hpusb.xml:
sudo vi /etc/udev/rules.d/hpusb.xml
里面内容:
<hostdev mode="subsystem" type="usb">
<source>
<vendor id="0x03f0"/>
<product id="0x002a"/>
</source>
</hostdev>
注意vendorid和productid和前面的规则里保持一致。保存退出。
至此规则写完,让udev重新加载规则:
sudo udevadm control --reload
sudo synosystemctl daemon-reload
这样就OK了。打印机重启或者usb拔下重插后会自动附加到虚拟机里。不需要人工去VMM挂上。
9、打印机共享。这里没什么需要设置的,局域网里的PC能直接识别到。如果是安卓设备可以装个Mopria Print,连上局域网同网段WIFI也可以自动识别到打印机。
到这里基本就折腾完了,P1108本身没有内置的纸槽,所以我没有完全无人值守的需求,那个不自动关机的设置对我来说没有非常大的必要所以一直没有直连测试。孩子打作业就自己开打印机放上纸,然后平板上操作打印完事。
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

值友5563633563
按文章里的办法加了udev规则,连接打印机的规则可以正常触发,但是断开打印机的规则死活触发不了。
后来我在群晖ssh里执行sudo udevadm monitor --property观察了一下,发现打印机连接和断开时都有一个可以识别设备的唯一标识ID_MODEL,然后我就修改了一下rules:
ACTION=="add", ENV{ID_MODEL}=="Deskjet_F2400_series", RUN+="/usr/bin/sh /etc/udev/rules.d/usb_udev.sh"
ACTION=="remove", ENV{ID_MODEL}=="Deskjet_F2400_series", RUN+="/usr/bin/sh /etc/udev/rules.d/usb_udev_rm.sh"
然后就可以正常触发连接和断开的脚本了,希望给遇到同样问题的朋友一点帮助。
校验提示文案
xeon8300
校验提示文案
蛙爹
校验提示文案
rui3bo2
校验提示文案
值友1734331160
-bash: hp-plugin: command not found
这个是啥原因
校验提示文案
icbcyang
校验提示文案
不剁不舒服
镜像用debian11的,网络选host,关闭DSM的Bonjour [不关就不能用Airprint,因为默认端口631已经占用]
打开容器终端:
apt update
apt install hplip
apt install gnupg
hp-plugin -i #此处不能自动下载的话就要提前下载好,选自行指定文件目录
apt install cups
passwd root [cups管理页面账号密码是系统的账号密码]
---这下就好了
如果下次启动不自动加载服务,那写一个sh脚本当容器启动入口
#!/bin/bash
service dbus start
service avahi-daemon start
service cups start
service cups-browsed start
service saned start
校验提示文案
zsj002
校验提示文案
值友6430903821
校验提示文案
luoxiaocool
校验提示文案
值友5563633563
按文章里的办法加了udev规则,连接打印机的规则可以正常触发,但是断开打印机的规则死活触发不了。
后来我在群晖ssh里执行sudo udevadm monitor --property观察了一下,发现打印机连接和断开时都有一个可以识别设备的唯一标识ID_MODEL,然后我就修改了一下rules:
ACTION=="add", ENV{ID_MODEL}=="Deskjet_F2400_series", RUN+="/usr/bin/sh /etc/udev/rules.d/usb_udev.sh"
ACTION=="remove", ENV{ID_MODEL}=="Deskjet_F2400_series", RUN+="/usr/bin/sh /etc/udev/rules.d/usb_udev_rm.sh"
然后就可以正常触发连接和断开的脚本了,希望给遇到同样问题的朋友一点帮助。
校验提示文案
不剁不舒服
镜像用debian11的,网络选host,关闭DSM的Bonjour [不关就不能用Airprint,因为默认端口631已经占用]
打开容器终端:
apt update
apt install hplip
apt install gnupg
hp-plugin -i #此处不能自动下载的话就要提前下载好,选自行指定文件目录
apt install cups
passwd root [cups管理页面账号密码是系统的账号密码]
---这下就好了
如果下次启动不自动加载服务,那写一个sh脚本当容器启动入口
#!/bin/bash
service dbus start
service avahi-daemon start
service cups start
service cups-browsed start
service saned start
校验提示文案
icbcyang
校验提示文案
值友1734331160
-bash: hp-plugin: command not found
这个是啥原因
校验提示文案
luoxiaocool
校验提示文案
值友6430903821
校验提示文案
rui3bo2
校验提示文案
蛙爹
校验提示文案
xeon8300
校验提示文案
zsj002
校验提示文案