Bug 38132

Summary: На вход утилите usb_modeswitch_dispatcher передаётся неверный параметр, либо он неправильно обрабатывается
Product: Sisyphus Reporter: invariabilis <invariabilis>
Component: usb-modeswitchAssignee: Mikhail Efremov <sem>
Status: CLOSED FIXED QA Contact: qa-sisyphus
Severity: normal    
Priority: P5 CC: asy, demitelinevazhno, imz, klark, sem, sotor, vercha
Version: unstable   
Hardware: x86_64   
OS: Linux   

Description invariabilis 2020-02-20 11:13:07 MSK
На стенде p9 workstation x86_64 установлено приложение usb-modeswitch.

Устанавливаю -> правлю конфиг /etc/usb_modeswitch.conf ->
меняю DisableSwitching=0 на DisableSwitching=1 и EnableLogging=0 на EnableLogging=1 ->перезапускаю систему -> подключаю USB-модем к ПК -> lsusb -> ls /dev/ttyUSB*-> Пытаюсь найти лог-файл с записью Switching globally disabled , но такого файла нигде нет.

Ожидаемый результат: лог-файл в /var/log с записью об запретом на переключение режимов.

Фактически лог-файла в системе нет. Невозможно отследить выполняемые действия и корректность их выполнения.
Comment 1 Ivan Zakharyaschev 2021-08-08 06:39:39 MSK
Да, проблема в том, что он вызывается из /lib/systemd/system/usb_modeswitch@.service с неправильным аргументом.

[root@blacky ~]# cat /lib/systemd/system/usb_modeswitch@.service
[Unit]
Description=USB_ModeSwitch_%i

[Service]
Type=oneshot
ExecStart=/usr/sbin/usb_modeswitch_dispatcher --switch-mode %i
#ExecStart=/bin/echo %i


Провёл такой же эксперимент. Результат: появился файл /var/log/usb_modeswitch_1-1.2_1-1.2

[root@blacky ~]# cat /var/log/usb_modeswitch_1-1.2_1-1.2

USB_ModeSwitch log from Sun Aug 08 05:58:43 MSK 2021
Raw parameters: --switch-mode 1-1.2_1-1.2:1.0
Use global config file: /etc/usb_modeswitch.conf

Use global config file: /etc/usb_modeswitch.conf
Top device directory not found (/sys/bus/usb/devices/1-1.2_1-1.2)! Exit

Правильные (точнее, рабочие) параметры были бы такие:

/usr/sbin/usb_modeswitch_dispatcher --switch-mode 1-1.2:1.0

-- без части до подчёркивания.

Проведём эксперимент с "правильным" параметром:

[root@blacky ~]# /usr/sbin/usb_modeswitch_dispatcher --switch-mode 1-1.2:1.0

Результат: появился файл /var/log/usb_modeswitch_1-1.2:

[root@blacky ~]# cat /var/log/usb_modeswitch_1-1.2

USB_ModeSwitch log from Sun Aug 08 06:01:58 MSK 2021
Raw parameters: --switch-mode 1-1.2:1.0
Use global config file: /etc/usb_modeswitch.conf

Use global config file: /etc/usb_modeswitch.conf
Use top device dir /sys/bus/usb/devices/1-1.2
Check class of first interface ...
 Interface 0 class is 08.

----------------
USB values from sysfs:
  manufacturer	HUAWEI Technology
  product	HUAWEI Mobile
  serial	
----------------
Logger is /usr/bin/logger

Switching globally disabled. Exit

[root@blacky ~]# 

Искомая строчка есть.

[root@blacky ~]# rpm -q usb-modeswitch
usb-modeswitch-2.6.0-alt1.x86_64


* * *

Как так параметр получается неправильный?..

Во-первых, так написан шаблон для сервиса (см. код выше в моём сообщении).
Во-вторых, его экземпляр из шаблона так строит /lib/udev/usb_modeswitch:

[root@blacky ~]# tail /lib/udev/usb_modeswitch
init_path=`readlink -f /sbin/init`
if sd_booted; then
	systemctl=/bin/systemctl
	exec $systemctl --no-block start usb_modeswitch@"${1%%/*}_${1##*/}".service
else
	# only old distros, new udev will kill all subprocesses
	exec 1<&- 2<&- 5<&- 7<&-
	exec usb_modeswitch_dispatcher --switch-mode "$p2"
fi
exit 0

* * *

Как это должно быть исправлено, я не знаю.

В /sys/bus/usb/devices/ есть оба пути:

1-1.2/1-1.2:1.0
1-1.2:1.0

/lib/udev/usb_modeswitch хочет запихнуть в имя экземпляра сервиса и в параметр именно более длинный (возможно, потому что так udev ему передал его; и это может быть вполне правильно и универсально). Но дальше происходит непонимание этого параметра в скрипте /usr/sbin/usb_modeswitch_dispatcher; он хочет врехнюю часть пути сам отделить по двоеточию...

Кстати, глядя на этот код

if {![regexp {(.*?):.*$} $arg1 d device]} {
	if {![regexp {([0-9]+-[0-9]+\.?[0-9]*.*)} $arg1 d device]} {
		ShowUsage
		Log "Could not determine device dir from udev values! Exit"
		SafeExit
	}
}

я подумал, что можно и ещё одним двоеточием вместо / или _ разделить:

[root@blacky ~]# rm /var/log/usb_modeswitch* -fv
[root@blacky ~]# /usr/sbin/usb_modeswitch_dispatcher --switch-mode 1-1.2:1-1.2:1.0
[root@blacky ~]# cat /var/log/usb_modeswitch_1-1.2 

USB_ModeSwitch log from Sun Aug 08 06:33:11 MSK 2021
Raw parameters: --switch-mode 1-1.2:1-1.2:1.0
Use global config file: /etc/usb_modeswitch.conf

Use global config file: /etc/usb_modeswitch.conf
Use top device dir /sys/bus/usb/devices/1-1.2
Check class of first interface ...
 Interface 0 class is 08.

----------------
USB values from sysfs:
  manufacturer	HUAWEI Technology
  product	HUAWEI Mobile
  serial	
----------------
Logger is /usr/bin/logger

Switching globally disabled. Exit

[root@blacky ~]# 

Т.е. вроде как работает.

Попробуем без DisableSwitching=1:

[root@blacky ~]# rm /var/log/usb_modeswitch* -fv
удалён '/var/log/usb_modeswitch_1-1.2'
[root@blacky ~]# /usr/sbin/usb_modeswitch_dispatcher --switch-mode 1-1.2:1-1.2:1.0
[root@blacky ~]# cat /var/log/usb_modeswitch_1-1.2 

USB_ModeSwitch log from Sun Aug 08 06:37:05 MSK 2021
Raw parameters: --switch-mode 1-1.2:1-1.2:1.0
Use global config file: /etc/usb_modeswitch.conf

Use global config file: /etc/usb_modeswitch.conf
Use top device dir /sys/bus/usb/devices/1-1.2
Check class of first interface ...
 Interface 0 class is 08.

----------------
USB values from sysfs:
  manufacturer	HUAWEI Technology
  product	HUAWEI Mobile
  serial	
----------------
bNumConfigurations is 1 - don't check for active configuration
ConfigList: /usr/share/usb_modeswitch/12d1:1446~ /usr/share/usb_modeswitch/12d1:1446.my /usr/share/usb_modeswitch/12d1:1446
SCSI attributes not needed, move on
Check config: /usr/share/usb_modeswitch/12d1:1446~
! matched. Read config data
Command line:
usb_modeswitch -W -D -u -1 -b 1 -g 31 -v 12d1 -p 1446 -f $flags(config)

Verbose debug output of usb_modeswitch and libusb follows
(Note that some USB errors are to be expected in the process)
--------------------------------

Read long config from command line

 * usb_modeswitch: handle USB devices with multiple modes
 * Version 2.6.0 (C) Josua Dietze 2017
 * Based on libusb1/libusbx

 ! PLEASE REPORT NEW CONFIGURATIONS !

DefaultVendor=  0x12d1
DefaultProduct= 0x1446
TargetVendor=   0x12d1
TargetProductList="1001,1404,1406,140b,140c,1412,1417,141b,1429,1432,1433,1436,14ac,1506,150c,1511"
HuaweiNewMode=1
System integration mode enabled

Use given bus/device number: 001/031 ...
Look for default devices ...
 bus/device number matched
  found USB ID 12d1:1446
   vendor ID matched
   product ID matched
 Found devices in default mode (1)
Get the current device configuration ...
Use interface number 0
 with class 8
Use endpoints 0x01 (out) and 0x81 (in)

USB description data (for identification)
-------------------------
Manufacturer: HUAWEI Technology
     Product: HUAWEI Mobile
  Serial No.: not provided
-------------------------
Using standard Huawei switching message
Looking for active drivers ...
 OK, driver detached
 OK, driver detached
Set up interface 0
Use endpoint 0x01 for message sending ...
Trying to send message 1 to endpoint 0x01 ...
 OK, message successfully sent
Read the response to message 1 (CSW) ...
 Response reading failed (error -9)
 Device is gone, skip any further commands
ok:busdev
--------------------------------
(end of usb_modeswitch output)

Check success of mode switch for max. 20 seconds ...
 Wait for device file system (1 sec.) ...
 Wait for device file system (2 sec.) ...
 Wait for device file system (3 sec.) ...
 Wait for device file system (4 sec.) ...
 Read attributes ...
 All attributes matched
Mode switching was successful, found 12d1:1436 (HUAWEI Technology: HUAWEI Mobile)
Logger is /usr/bin/logger
Serial USB driver bound to interface 0
 will try to guess and symlink modem port on next connect
Check for AVOID_RESET_QUIRK kernel attribute
 AVOID_RESET_QUIRK activated

All done, exit


[root@blacky ~]# l /dev/ttyU*
crw-rw---- 1 root uucp 188, 2 авг  8 06:37 /dev/ttyUSB2
crw-rw---- 1 root uucp 188, 1 авг  8 06:37 /dev/ttyUSB1
crw-rw---- 1 root uucp 188, 0 авг  8 06:37 /dev/ttyUSB0
[root@blacky ~]# 

Сработало и так.

Насколько правильным будет заменить _ в /lib/udev/usb_modeswitch на : не берусь сказать. Может, upstream уже что-то решил.
Comment 2 Ivan Zakharyaschev 2021-08-08 06:43:03 MSK
*** Bug 38208 has been marked as a duplicate of this bug. ***
Comment 3 Sergey Y. Afonin 2022-03-07 13:00:56 MSK
(In reply to Ivan Zakharyaschev from comment #1)

> Да, проблема в том, что он вызывается из
> /lib/systemd/system/usb_modeswitch@.service с неправильным аргументом.

> [Service]
> Type=oneshot
> ExecStart=/usr/sbin/usb_modeswitch_dispatcher --switch-mode %i

Если почитать в usb_modeswitch_dispatcher, то предполагается, что его вызывают из /lib/udev/rules.d/40-usb_modeswitch.rules. Но проблема где-то рядом.
Comment 4 Sergey Y. Afonin 2022-03-07 13:08:03 MSK
(In reply to Ivan Zakharyaschev from comment #1)

> Может, upstream уже что-то решил.

В usb-modeswitch-2.6.1 ещё нет.
Comment 5 Sergey Y. Afonin 2022-03-07 16:32:02 MSK
(In reply to invariabilis from comment #0)

> -> ls /dev/ttyUSB*-> Пытаюсь найти лог-файл с записью Switching globally
> disabled , но такого файла нигде нет.
> 
> Ожидаемый результат: лог-файл в /var/log с записью об запретом на
> переключение режимов.
> 
> Фактически лог-файла в системе нет. Невозможно отследить выполняемые
> действия и корректность их выполнения.

Лог, на самом деле, есть, только там нет Switching globally disabled:

/var/log/usb_modeswitch_3-5_3-5:

USB_ModeSwitch log from Mon Mar 07 17:10:57 +04 2022
Raw parameters: --switch-mode 3-5_3-5:1.0
Use global config file: /etc/usb_modeswitch.conf

Use global config file: /etc/usb_modeswitch.conf
Top device directory not found (/sys/bus/usb/devices/3-5_3-5)! Exit
Comment 6 Sergey Y. Afonin 2022-03-07 17:18:04 MSK
(In reply to Sergey Y. Afonin from comment #4)

> > Может, upstream уже что-то решил.
> 
> В usb-modeswitch-2.6.1 ещё нет.

И, кстати, это не апстрим, это из systemd-detection.patch:

+if sd_booted; then
+       systemctl=/bin/systemctl
+       exec $systemctl --no-block start usb_modeswitch@"${1%%/*}_${1##*/}".service

И, вроде бы, так же помогает модификация usb_modeswitch_dispatcher:

-if {![regexp {(.*?):.*$} $arg1 d device]} {
+if {![regexp {(.*?)_.*$} $arg1 d device]} {

Только в usb_modeswitch_dispatcher лезть не надо наверное, так как без systemd всё работает, и в логе получается

USB_ModeSwitch log from Mon Mar 07 18:12:49 +04 2022
Raw parameters: --switch-mode 2-2:1.0
Use global config file: /etc/usb_modeswitch.conf
Comment 7 Sergey Y. Afonin 2022-03-07 18:03:35 MSK
(In reply to Sergey Y. Afonin from comment #6)

> И, кстати, это не апстрим, это из systemd-detection.patch:
> 
> +if sd_booted; then
> +       systemctl=/bin/systemctl
> +       exec $systemctl --no-block start
> usb_modeswitch@"${1%%/*}_${1##*/}".service

Можно посмотреть https://git.altlinux.org/tasks/296310 для p10:

#300 usb-modeswitch 2.6.0-alt1 -> 2.6.1-alt2
 Mon Mar 07 2022 Sergey Y. Afonin <asy@altlinux> 2.6.1-alt2
 - updated systemd-detection.patch (ALT #38132)
 - added %config(noreplace) for %_sysconfdir/usb_modeswitch.conf
 Sat Mar 05 2022 Sergey Y. Afonin <asy@altlinux> 2.6.1-alt1
 - 2.6.1

Поменял 
-+      exec $systemctl --no-block start usb_modeswitch@"${1%%/*}_${1##*/}".service
++      exec $systemctl --no-block start usb_modeswitch@"$p2".service

Вроде работает с Huawei E1550
Comment 8 gosts 87 2022-03-07 20:17:43 MSK
(Ответ для Sergey Y. Afonin на комментарий #7)
> (В ответ Сергею Юрьевичу Afonin from comment #6) > И, кстати, это не
> апстрим, это из systemd-detection.патч: > > если sd_booted; тогда > +
> systemctl=/Бен/systemctl > + старпома $systemctl --нет-блок запуска >
> usb_modeswitch@"${1%%/*}_${1 +##*/}".услуги Можно посмотреть
> https://git.altlinux.org/tasks/296310 для Р10: #300 с USB-modeswitch 2.6.0-с
> ALT1 -> 2.6.1-alt2 Пн Мар 07 2022 Сергей Юрьевич Afonin <asy@altlinux>
> 2.6.1-alt2 - обновленный systemd-detection.патч (ALT #38132) - добавлен
> %config(noreplace) для %_sysconfdir/usb_modeswitch.conf Сб Мар 05 2022
> Сергей Юрьевич Afonin <asy@altlinux> 2.6.1-alt1  - 2.6.1 Поменял  -+ exec
> $systemctl --no-block start usb_modeswitch@"${1%%/*}_${1##*/}".service ++
> exec $systemctl --no-block start usb_modeswitch@"$p2".service Вроде работает
> с Huawei E1550

Багу можно закрывать! Всё работает нормально. Спасибо большущее, Сергей!!!
Comment 9 Repository Robot 2022-03-07 20:23:22 MSK
usb-modeswitch-2.6.1-alt2 -> sisyphus:

 Mon Mar 07 2022 Sergey Y. Afonin <asy@altlinux> 2.6.1-alt2
 - updated systemd-detection.patch (ALT #38132)
 - added %config(noreplace) for %_sysconfdir/usb_modeswitch.conf