Назад | Перейти на главную страницу

Драйвер IBM iSeries ODBC не отправляет трафик при вызове через isql или иным образом, получая [08S01] [unixODBC] и [ISQL] ОШИБКА: не удалось SQLConnect

Примечание. Я заменил IP-адреса, имена баз данных и пользователей серверов примерами. Это не должно ни на что повлиять.


Установка

Я установил unixODBC (yum install unixODBC) и официальный драйвер IBM iSeries ODBC (yum install ibm-iaccess-1.1.0.5-1.0.x86_64.rpm, RPM загружен из областей входа в систему IBM). Установка успешно добавила драйверы в /etc/odbcinst.ini:

[IBM i Access ODBC Driver]
Description             = IBM i Access for Linux ODBC Driver
Driver          = /opt/ibm/iaccess/lib/libcwbodbc.so
Setup           = /opt/ibm/iaccess/lib/libcwbodbcs.so
Driver64                = /opt/ibm/iaccess/lib64/libcwbodbc.so
Setup64         = /opt/ibm/iaccess/lib64/libcwbodbcs.so
Threading               = 0
DontDLClose             = 1
UsageCount              = 1

[IBM i Access ODBC Driver 64-bit]
Description             = IBM i Access for Linux 64-bit ODBC Driver
Driver          = /opt/ibm/iaccess/lib64/libcwbodbc.so
Setup           = /opt/ibm/iaccess/lib64/libcwbodbcs.so
Threading               = 0
DontDLClose             = 1
UsageCount              = 1

Указанные файлы библиотеки существуют, и они правильно связаны (проверено через ldd, без недостающих звеньев).

Мой ~/.odbc.ini файл выглядит так:

[Foo]
Driver          = IBM i Access ODBC Driver
DATABASE        = FooDB
SYSTEM          = 123.45.67.8
HOSTNAME        = 123.45.67.8
PORT            = 446
PROTOCOL        = TCPIP

Эта проблема

Когда я бегу isql Foo USER PASSWORD -v, Примерно через минуту я получаю этот результат:

user@example.com [~]# isql FooDB USER PASSWORD -v
[08S01][unixODBC]
[ISQL]ERROR: Could not SQLConnect

Исправление проблем

Похоже, время истекло, правда?

ping 123.45.67.8 возвращает:

user@example.com [~]# ping 123.45.67.8
PING 123.45.67.8 (123.45.67.8) 56(84) bytes of data.
64 bytes from 123.45.67.8: icmp_seq=1 ttl=63 time=29.8 ms
64 bytes from 123.45.67.8: icmp_seq=2 ttl=63 time=29.8 ms
64 bytes from 123.45.67.8: icmp_seq=3 ttl=63 time=29.8 ms
64 bytes from 123.45.67.8: icmp_seq=4 ttl=63 time=31.0 ms
64 bytes from 123.45.67.8: icmp_seq=5 ttl=63 time=29.9 ms

telnet 123.45.67.8 446 возвращает:

user@example.com [~]# telnet 123.45.67.8 446
Trying 123.45.67.8...
Connected to 123.45.67.8.
Escape character is '^]'.
foobar
^]
telnet> quit
Connection closed.

Включение журнала ODBC с Trace и TraceFile в /etc/odbcinst.ini производит такой вывод:

[ODBC][22093][1454628360.104274][__handles.c][450]
                Exit:[SQL_SUCCESS]
                        Environment = 0x13a4750
[ODBC][22093][1454628360.104316][SQLAllocHandle.c][364]
                Entry:
                        Handle Type = 2
                        Input Handle = 0x13a4750
[ODBC][22093][1454628360.104339][SQLAllocHandle.c][482]
                Exit:[SQL_SUCCESS]
                        Output Handle = 0x13a5080
[ODBC][22093][1454628360.104363][SQLConnect.c][3614]
                Entry:
                        Connection = 0x13a5080
                        Server Name = [FooDB][length = 4 (SQL_NTS)]
                        User Name = [USER][length = 7 (SQL_NTS)]
                        Authentication = [*******][length = 7 (SQL_NTS)]
                UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'

                DIAG [08S01]

[ODBC][22093][1454628423.118602][SQLConnect.c][3982]
                Exit:[SQL_ERROR]
[ODBC][22093][1454628423.118628][SQLError.c][430]
                Entry:
                        Connection = 0x13a5080
                        SQLState = 0x7fff9a5bd7b0
                        Native = 0x7fff9a5bd5a8
                        Message Text = 0x7fff9a5bd5b0
                        Buffer Length = 500
                        Text Len Ptr = 0x7fff9a5bd5ae
[ODBC][22093][1454628423.118656][SQLError.c][467]
                Exit:[SQL_SUCCESS]
                        SQLState = 08S01
                        Native = 0x7fff9a5bd5a8 -> 10060
                        Message Text = [[unixODBC]]
[ODBC][22093][1454628423.118685][SQLError.c][430]
                Entry:
                        Connection = 0x13a5080
                        SQLState = 0x7fff9a5bd7b0
                        Native = 0x7fff9a5bd5a8
                        Message Text = 0x7fff9a5bd5b0
                        Buffer Length = 500
                        Text Len Ptr = 0x7fff9a5bd5ae
[ODBC][22093][1454628423.118704][SQLError.c][467]
                Exit:[SQL_NO_DATA]
[ODBC][22093][1454628423.118722][SQLError.c][510]
                Entry:
                        Environment = 0x13a4750
                        SQLState = 0x7fff9a5bd7b0
                        Native = 0x7fff9a5bd5a8
                        Message Text = 0x7fff9a5bd5b0
                        Buffer Length = 500
                        Text Len Ptr = 0x7fff9a5bd5ae
[ODBC][22093][1454628423.118739][SQLError.c][547]
                Exit:[SQL_NO_DATA]
[ODBC][22093][1454628423.118765][SQLFreeHandle.c][279]
                Entry:
                        Handle Type = 2
                        Input Handle = 0x13a5080
[ODBC][22093][1454628423.118784][SQLFreeHandle.c][330]
                Exit:[SQL_SUCCESS]
[ODBC][22093][1454628423.118827][SQLFreeHandle.c][212]
                Entry:
                        Handle Type = 1
                        Input Handle = 0x13a4750

Он успешно выделяет дескриптор, затем пытается подключиться к базе данных, терпит неудачу с общим SQL_ERROR, пытается что-то сделать с ошибкой (не знаете, что?), А затем освобождает дескриптор.

Моим последним средством было проверить сетевой трафик напрямую. Вот начальный тест с использованием telnet:

[root@host /opt/ibm/iaccess]# tshark -i tun0 -x
Running as user "root" and group "root". This could be dangerous.
Capturing on tun0
0.000000000   10.10.1.10 -> 123.45.67.8  TCP 60 42054 > ddm-rdb [SYN] Seq=0 Win=13660 Len=0 MSS=1366 SACK_PERM=1 TSval=1992917110 TSecr=0 WS=128

...PACKETS...

2.316931937   10.10.1.10 -> 123.45.67.8  TCP 60 42054 > ddm-rdb [PSH, ACK] Seq=1 Ack=1 Win=13696 Len=8 TSval=1992919427 TSecr=4147650000

0000  45 10 00 3c f1 b3 40 00 40 06 73 d2 0a 0a 01 0a   E..<..@.@.s.....
0010  ac 10 1e 02 a4 46 01 be e0 f5 71 c8 1d a8 3b 71   .....F....q...;q
0020  80 18 00 6b f5 9b 00 00 01 01 08 0a 76 c9 89 83   ...k........v...
0030  f7 38 1d d0 66 6f 6f 62 61 72 0d 0a               .8..foobar..

...PACKETS...

Мы видим несколько TCP-пакетов, один из которых содержит foobar, как мы и ожидали.

А вот и тест с isql:

[root@host /opt/ibm/iaccess]# tshark -i tun0 -x
Running as user "root" and group "root". This could be dangerous.
Capturing on tun0
^C0 packets captured

Нет движения !?


Честно говоря, я здесь немного застрял. Не уверен, что попробовать дальше. Есть мысли о том, что может пойти не так, или как решить эту сложную ситуацию?

Обратите внимание, что сама настройка сервера в порядке. Я могу без проблем подключиться, используя драйверы IBM iSeries ODBC для Windows.

Хорошо, наконец-то разобрался. Какая дурацкая.

Прежде всего, сделайте себе одолжение и возьмите один из старых драйверов IBM iSeries, а не новые iAccess. При входе в систему перейдите в IBM Software > Downloads > No-charge products, tools, and toolkits, затем поиск odbc. Вы должны увидеть такие драйверы, как IBM i Access for Linux (V7R1). Возьми один из них.

Теперь, с этими более старыми драйверами, вы получите правильное сообщение об ошибке:

[08S01][unixODBC][IBM][System i Access ODBC Driver]Communication link failure. comm rc=10060 - CWBCO1048 - A firewall blockage or time-out occurred trying to connect to the IBM i

Ницца! По крайней мере, сейчас мы можем быть абсолютно уверены на 120% в том, что проблема заключается в какой-то блокировке.

Но что такое завал? На помощь приходит прекрасно организованный указатель документации IBM: http://www-01.ibm.com/support/docview.wss?uid=nas8N1012436

Таблица из статьи воспроизведена здесь:

PC Function                   Port (non-SSL) SSL Port
Server Mapper                 449            449
License Management (see Note) 8470           9470
RPC/DPC (Remote Command)      8475           9475
Sign-On Verification          8476           9476
Database Access               8471           9471

Разблокировали порт 8471 ("Доступ к базе данных") и вуаля! Все заработало!

Обновление 3/8/2016: по какой-то причине Windows нужно открыть больше портов, чем Linux. Чтобы это работало в Windows, нам также понадобился Server Mapper и Sign-On Verification порты.


Боковое примечание, вот еще один важный абзац из статьи:

Эти номера портов (кроме Server Mapper) можно настроить, и, хотя значения по умолчанию перечислены выше, фактические значения в системе могут отличаться. Порты извлекаются из сервисной таблицы. Определите эти порты с помощью команды WRKSRVTBLE в рассматриваемой системе, чтобы определить, были ли порты изменены по сравнению со значениями по умолчанию.