Введение

Возможность omniwl.pl манипулировать спецификацией заставила меня задуматься: можно ли использовать это из других скриптов? Могу ли я использовать это с других хостов? Краткий ответ: да! util_cmd.exe имеет скрытые функции для получения и установки всевозможных вещей, которые я считал возможными только через графический интерфейс.

В этой статье я покажу возможности util_cmd/dpcom, как я их видел и/или использовал с Data Protector 9.

Привет мир

Для нетерпеливых, например, привет, мир:

echo -e "*FUNCTION*GetDatalists\n*EOF*" | /opt/omni/lbin/util_cmd.exe -dpcom localhost util_cmd.exe | sed -r -e "s/(filename|mtime)='.*'/\1='hidden'/" | tail -n 11
},{
 type='E2010';
 filename='hidden';
 mtime='hidden';
},{
 type='IDB';
 filename='hidden';
 mtime='hidden';
})
*EOF*
*RETVAL*0

Вау, мы получили все характеристики (названия должностей) этого Cell Manager! Давайте исследуем то, что мы только что сделали:

  • Мы вызвали util_cmd.exe со скрытым параметром «-dpcom»; мы сказали ему связаться с сотовым сервером DP «localhost».
  • Аргумент «util_cmd.exe» до сих пор для меня загадка.
  • Sed предназначен только для того, чтобы скрыть специфические данные клиента.
  • Хвост предназначен только для обрезки вывода.
  • Эхо служит входом для util_cmd. Обратите внимание на часть «GetDatalists». Мы сказали util_cmd получить списки данных из Cell Manager, и это сработало.

Надеюсь, теперь я привлек ваше внимание к тому, что dpcom/util_cmd — это мощный инструмент/жемчужина.

Список всех возможных функций

Когда я узнал о dpcom/util_cmd, мне сразу стало интересно, какие еще функции можно вызывать. Ну и "струны" в помощь:

strings /opt/omni/lbin/util_cmd.exe | grep ^__dpcom | sort
__dpcom__Connect
__dpcom__DeleteFile
__dpcom__Disconnect
__dpcom__FormatPackedMessage
__dpcom__GetCellInfo
__dpcom__GetCsvFile
__dpcom__GetDatalist
__dpcom__GetDatalists
__dpcom__GetInstallInfo
__dpcom__Listen
__dpcom__OB2_CellServer
__dpcom__OB2_CmnRunScript
__dpcom__OB2_DecodePassword
__dpcom__OB2_EncodePassword
__dpcom__OB2_EndBackup
__dpcom__OB2_EndObjectBackup
__dpcom__OB2_EndObjectRestore
__dpcom__OB2_EndRestore
__dpcom__OB2_Exit
__dpcom__OB2_ExpandHostname
__dpcom__OB2_GetConfig
__dpcom__OB2_GetSMHandle
__dpcom__OB2_Init
__dpcom__OB2_NlsGetCatalogString
__dpcom__OB2_PutConfig
__dpcom__OB2_RunScript
__dpcom__OB2_StartBackup
__dpcom__OB2_StartObjectBackup
__dpcom__OB2_StartObjectRestore
__dpcom__OB2_StartRestore
__dpcom__OB2_UserAdd
__dpcom__OB2_UserCommit
__dpcom__OB2_UserDel
__dpcom__Port
__dpcom__PutDatalist
__dpcom__PutToFile
__dpcom__Query
__dpcom__QueryFetch
__dpcom__QueryInit
__dpcom__RunningSessions
__dpcom__%s
__dpcom__Send
__dpcom__UtilListenerStart
__dpcom__UtilListenerWaitMsg

GetDatalists, GetDatalist, Запрос, PutDatalist, PutToFile. Интересный!

Трудная часть состоит в том, чтобы знать, какой функции нужен какой аргумент или аргументы. Лишь некоторые из них можно угадать, но большинство из них необходимо соблюдать при использовании параметра отладки DP «-debug 1–500 debugfile.txt» для утилит командной строки, таких как omnirpt, omnidownload, omnidb, omnistat.

Пока достаточно просто суммировать возможности.

(Если вы знаете другие способы обнаружения имен аргументов, поделитесь ими со мной.)

Задний план

Прежде чем я слишком утолю вашу жажду: немного предыстории. Мое расследование началось с новости о том, что DP 9.05 выпустил omniwl.pl, инструмент для управления списками данных/спецификациями/заданиями через командную строку.

Оказывается, omniwl.pl вряд ли творит чудеса, так как сильно зависит от Perl-модуля Omniback.pm (находится в /opt/omni/lib/perl в Linux с Data Protector 9).

Omniback.pm

Файл Omniback.pm содержит Perl-пакет DPCom. Этот пакет обеспечивает связь с Cell Manager через util_cmd.exe. Этот пакет обрабатывает ввод и вывод из util_cmd.exe.

util_cmd.exe получает упакованные данные из Cell Manager в формате, который показывает явные признаки объектов Perl, как если бы они были инициализированы в исходном коде; Data Protector, похоже, настроил вывод для чтения Perl, чтобы Perl читал его с помощью eval() (хотя Omniback.pm на самом деле не использует eval()). Я надеюсь, что вы либо такие же любители Perl, как и я, либо способны анализировать вывод Perlish на своем любимом языке.

Сериализация и упаковка

Если вы собираетесь написать свой собственный синтаксический анализатор, посмотрите на Omniback.pm, как сериализовать и десериализовать объекты. Также обратите внимание на экранирование специальных символов:

  • Подпрограмма Serialize — сериализация
  • Подпрограммы DeSerialize и iDeSerialize — десериализация
  • Подпрограмма PackString — экранирование специальных символов
  • Подпрограмма UnpackString — отмена экранирования специальных символов

Коротко об упаковке:

  • \001 — управляющий символ.
  • \001\001 — это буквальный \001.
  • \001q — одинарная кавычка.
  • \001Q — двойная кавычка.

Сериализация не является ракетостроением, но слишком длинная, чтобы записывать ее здесь.

Использование Omniback.pm

Если вы собираетесь использовать Perl, вы также можете использовать Omniback. Я предпочитаю Perl, поставляемый ОС (например, RHEL), а не Perl, поставляемый Data Protector. Чтобы использовать с OS Perl, попробуйте этот пример кода:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
## We prefer to use packages shipped with the OS rather than shipped by
## Perl. Therefore, we cannot use “use lib ‘/opt/omni/lib/perl’” as it
## will be inserted at the head instead of the tail. Add it manually to
## the tail then.
BEGIN
{
    push (@INC, ‘/opt/omni/lib/perl’);
}
use Omniback;
CmnInit ();
my $info = $OMNI->GetCellInfo ({‘cellserver’ => ‘localhost’});
print Dumper ($info);
CmnExit ();

Список запросов

Вывод «strings» показывает функцию «Query»:

strings /opt/omni/lbin/util_cmd | grep ^__dpcom__Query
__dpcom__QueryFetch
__dpcom__Query
__dpcom__QueryInit

Omniback.pm знает несколько запросов:

sed -n -r -e 's/^\s*(FUN_[A-Z]+).*/\1/p' /opt/omni/lib/perl/Omniback.pm
FUN_FINDSESSION
FUN_LISTOVEROFSESSION
FUN_LISTOVEROFAPPBACKUP
FUN_LISTCATALOG
FUN_LISTOBJECTS
FUN_LISTVEROFOBJECT
FUN_GETOVER
FUN_LISTSESSIONS
FUN_LISTMEDIAOFOVER

util_cmd.exe знает гораздо больше запросов и также может помочь:

strings /opt/omni/lbin/util_cmd | grep -E -o '^FUN[^/]+' | while read FUN; do /opt/omni/lbin/util_cmd -query_help "${FUN}"; done | sort -n | grep -v '^\*RETVAL\*1030$'
(1000) FUN_FINDSESSION(sessionName %s)
(1001) FUN_GETOVER(overId %s)
(1002) FUN_FINDOVER(objectName %s, sessionName %s [,copyID %s])
(1006) FUN_GETTOTLPROTECTDDATA()
(1007) FUN_GETLISTCBLBYBARTYPE()
(1009) FUN_GETLISTCBLDETAILED(server %s)
(1020) FUN_LISTSESSIONS(datalist %s, sesType %d, sinceTime %ld, untilTime %ld)
(1022) FUN_LISTOBJECTS(objType %d [flags %d [appType %s]])
(1024) FUN_LISTVEROFOBJECT(objectName %s, vType %hd (0: backup, 1: restore), onlyValid %d, [flags %d])
(1026) FUN_LISTOVEROFSESSION(sessionName %s)
(1028) FUN_LISTSESMSGS(sessionName %s)
(1032) FUN_LISTCATALOG(overId %s)
(1033) FUN_LISTFILENAMES(flags %d, hostname %s, root %s)
(1036) FUN_FILEPATTERNSEARCH(pattern %s, host %s, tree %s, youngerThan %d, olderThan %d, flags %d, timeStart %d, timeEnd %d)
(1038) FUN_LISTTREEMPOS(overId %s, objectName %s, path %s)
(1050) FUN_FBLISTALLOVER(objName %s, flags %d [,noresult %d, timeFrameStart %d, timeFrameEnd %d, statusFilter %d])
(1052) FUN_FBLISTFULLRESCHAIN(overId %s, directory %s)
(1054) FUN_FBLISTDIR(level %d, directory %s)
(1060) FUN_FBLISTFILEVERS(view %d, path %s)
(1062) FUN_GETCDBINFO()
(1064) FUN_LISTOVERMPOS(overId %s)
(1069) FUN_LISTPARTOFOBJECT(objType %ld, partOfObject %s)
(1071) FUN_DCBF_DIR_LIST()
(1077) FUN_GETSMBFINFO()
(1079) FUN_GETSIBFINFO()
(1083) FUN_LISTOVEROFAPPBACKUP(backupID %s, hostname %s, appName %s)
(1098) FUN_DCBF_LISTALLFILESANDFILTER(filter %d)
(1102) FUN_GETOVERWITHBACKUPTAG(objType %ld, backupTag %s)
(1102) FUN_GETOVERWITHBACKUPTAG(objType %ld, backupTag %s)
(1104) FUN_GET_ALT_OBJECTNAMES(objectName %s)
(1106) FUN_GET_OBJECTNAME_FROM_ALT_NAME()
(1135) FUN_GETTELEMETRY()
(1137) FUN_GET_METADATAINFO_MOM(Metadata: %s)
(1137) FUN_GET_METADATAINFO_MOM(Metadata: %s)
(1139) FUN_GETCLIENTOBJECTSIZE()
(1141) FUN_GETLIBRARYUSAGESIZE()
(1311) FUN_FINDMEDIUM(MediumId %s)
(1319) FUN_FINDORIGMEDIUM(MediumId %s)
(1340) FUN_GETSTORE(stName %s)
(1342) FUN_GETDEVICE(devName %s)
(1344) FUN_LISTSTORES(stType %d [mediaClass %d])
(1346) FUN_LISTDEVICES(mediaClass %d [rptId %d csHostname %s])
(1348) FUN_LISTPOOLS(Pool %s)
(1350) FUN_LISTMEDIAOFPOOL(PoolName %s)
(1354) FUN_LISTREPOSITORY(device name %s)
(1366) FUN_GETMMDBINFO()
(1387) FUN_GET_METADATAINFO(Metadata: %s)
(1389) FUN_GET_GW_LIST(targetCell %s, targetStore %s)
(1399) FUN_GETSTORE2(stName %s)
(1399) FUN_GETSTORE2(stName %s)
(1601) FUN_CHANGEOVERPROT(overID %s, protType %d, protTime %d)
(1612) FUN_LISTMEDIAOFOVER(overID %s, flags %d)
(1614) FUN_LISTOVERONMEDIUM(MedSearchStr %s)
(1616) FUN_LISTCATALOGONMED(overID %s, mediumID %s)
(1616) FUN_LISTCATALOGONMED(overID %s, mediumID %s)
(1620) FUN_GETRESTOREGRAPH(objectName %s, flags %d)
(1800) FUN_GETFILE()
(1801) FUN_PUTFILE()
(1803) FUN_EXECUTIL()
(1806) FUN_EXECINTEGUTIL()
(1810) FUN_FSBROWSE(host %s, mountPoint %s)
(1812) FUN_FSLISTDIR(rootDir %s)
(1840) FUN_ALLBDF()
(1843) FUN_INVOKEVEPABAR()
(1872) FUN_EXECINTEGUTILEX()
(1872) FUN_EXECINTEGUTILEX()
(1882) FUN_ENCRYPTION()
(1885) FUN_EXECVMWAREGRE()

Множество запросов, которые кажутся многообещающими для автоматизации задач и автоматизации отчетности!

запрос FUN_FINDSESSION (1000)

Помощь:

FUN_FINDSESSION(sessionName %s)

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_FINDSESSION '2018/01/01-1'

Он выведет список этих деталей:

  1. Идентификатор сессии
  2. Идентификатор сеанса с добавленным @cellmanager.
  3. (Мне неизвестно.)
  4. Владелец сеанса
  5. Спецификация
  6. Тип сеанса: 0=Резервное копирование, 1=Восстановление, 3=МедиаМ
  7. Start Time_t (в секундах с эпохи Unix)
  8. End Time_t (в секундах с эпохи Unix)
  9. Статус: 2=Завершено, 3=Завершено/Ошибки, 5=Сбой, 7=Прервано, 13=Завершено/Ошибки
  10. (Мне неизвестно.)
  11. # Предупреждение (количество предупреждений)
  12. # Ошибки (количество ошибок)
  13. (Мне неизвестно.)
  14. (Мне неизвестно.)

запрос FUN_FINDOVER (1002)

Помощь:

FUN_FINDOVER(objectName %s, sessionName %s [,copyID %s])

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_FINDOVER '"06 fileserver.somedomain:/CONFIGURATION // fileserver.somedomain [/CONFIGURATION]" "2018/01/01 0001" "48"'

Я не уделял этому запросу/функции особого внимания. Важно уметь цитировать (довольно странно, если вы спросите меня).

запрос FUN_LISTSESSIONS (1020)

Помощь:

FUN_LISTSESSIONS(datalist %s, sesType %d, sinceTime %ld, untilTime %ld)

Пример:

/opt/omni/lbin/util_cmd -server someremotecellserver.somedomain -query FUN_LISTSESSIONS '"" -1 0 0'

Это фактический запрос с фактическим параметром, который выдает графический интерфейс, когда требуются все сеансы (т.е. без фильтрации).

запрос FUN_LISTOBJECTS (1022)

Помощь:

FUN_LISTOBJECTS(objType %ld)

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_LISTOBJECTS '6'

Это позволит получить все объекты типа 6 (WinFS). Другие типы, которые я видел:

  • 2: файловая система (например, Linux)
  • 5: Бар (например, E2010, VEAgent, MSSQL)
  • 6: WinFS (т.е. Windows)

запрос FUN_LISTOVEROFSESSION (1026)

Помощь:

FUN_LISTOVEROFSESSION(sessionName %s)

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_LISTOVEROFSESSION '"2018/01/01 0001"'

Обратите внимание на кавычки внутри кавычек.

запрос FUN_FILEPATTERNSEARCH (1036)

Помощь:

FUN_FILEPATTERNSEARCH(pattern %s, host %s, tree %s, youngerThan %d, olderThan %d, flags %d, timeStart %d, timeEnd %d)

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_FILEPATTERNSEARCH '"*" "someserver.somedomain" "/Windows/System32/drivers/etc/" -3150349999999 12884901888 0 1514761200 1830294000'

Это позволит получить все записи в /Windows/System32/drivers/etc и все резервные копии. Первые три числовых аргумента для меня загадка, два других — временные метки эпохи Unix.

запрос FUN_FBLISTALLOVER (1050)

Помощь:

FUN_FBLISTALLOVER(objName %s, flags %d [,noresult %d, timeFrameStart %d, timeFrameEnd %d, statusFilter %d])

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_FBLISTALLOVER '"06 somewindowsserver.somedomain:/C // somewindowsserver.somedomain [/C]" 0'

запрос FUN_FBLISTFULLRESCHAIN ​​(1052)

Помощь:

FUN_FBLISTFULLRESCHAIN(overId %s, directory %s)

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_FBLISTFULLRESCHAIN '"3AB1B38C-FB6D-41A1-B469-4EC8ED414CB3/9493336" ""'

Я видел это во время отладки с помощью

/opt/omni/bin/omnidb -debug 1-499 debugfile.txt -winfs 'fileserver.somedomain:/CONFIGURATION' 'fileserver.somedomain [/CONFIGURATION]' -session 2018/01/01-1 -listdir /Profiles

UUID можно увидеть в базе данных PostgreSQL:

/opt/omni/sbin/omnidbutil -run_script <(echo -e "\\x\nSELECT UUID, DP_NUMKEY, NAME, LONG_NAME, DESCRIPTION, OWNER, DATALIST, START_TIME, END_TIME, QUEUE_TIME, STATUS_ID, FLAGS, NUM_OF_ERRORS, NUM_OF_WARNINGS, BACKUP_TYPE_ID, TYPE_ID, OPTIONS FROM DP_SESSIONS WHERE (NAME = '2018/01/01 0001')") -detail

И 9493336, похоже, исходит из этого запроса:

opt/omni/sbin/omnidbutil -run_script <(echo -e "\\x\nSELECT UUID, DP_NUMKEY, SESS_UUID, SESS_NUMKEY, OBJECT_UUID, OBJECT_NUMKEY, VERIFICATION_SESSION_UUID, VERIFICATION_SESSION_NUMKEY, RESTORE_GRAPH_ID, POINT_IN_TIME, END_TIME, REL_TIME, OBJECT_SIZE, OBJECT_SIZE_HI, STATUS, FLAGS, BACKUP_TYPE_ID, PROT_TYPE, PROT_TIME, VERIFICATION_STATUS, CATPROT_TYPE, CATPROT_TIME, ACCESS_TYPE, NUM_OF_FILES, NUM_OF_ERRORS, NUM_OF_WARNINGS, DISKAGENT_ID, MEDIA_CLASS_ID, DF_TYPE_ID, DF_SUBTYPE_ID, GENERATION, BACKUP_DEVICE, OPTIONS, OWNER, START_TIME, BACKUP_NAME, RESUMEPOINT FROM DP_OBJ_VERSIONS WHERE ((SESS_UUID = '3ab1b38c-fb6d-41a1-b469-4ec8ed414cb3') and (SESS_NUMKEY = 9493324)) ORDER BY POINT_IN_TIME") -detail

Но я понятия не имею, для чего нужен FUN_FBLISTFULLRESCHAIN. Я могу только догадываться, что RES означает RESTORE, и, следовательно, это должно быть для построения какой-то цепочки восстановления.

запрос FUN_GETSTORE (1340)

Помощь:

FUN_GETSTORE(stName %s)

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_GETSTORE 'somestorename'

запрос FUN_LISTSTORES (1344)

Помощь:

FUN_LISTSTORES(stType %d [mediaClass %d])

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_LISTSTORES '-1 -1'

запрос FUN_LISTDEVICES (1346)

Помощь:

FUN_LISTDEVICES(mediaClass %d [rptId %d csHostname %s])

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_LISTDEVICES -1

запрос FUN_GETFILE (1800)

Помощь:

none

Пример:

/opt/omni/lbin/util_cmd -server somecellserver.somedomain -query FUN_GETFILE 'somecellserver.somedomain barschedules/idb/someidbspec'

FUN_GETFILE — единственная известная мне возможность DP, которая может получить файл. У меня есть скрипт для проверки расписаний на наличие человеческих ошибок (дважды в одном окне резервного копирования, ноль в следующем). Этот запрос поможет преобразовать скрипты, работающие на каждом сотовом сервере, в один скрипт, работающий, скажем, на сервере Manager-of-Manager.

запрос FUN_FSBROWSE (1810)

Помощь:

FUN_FSBROWSE(host %s, mountPoint %s)

Пример:

sorry

Я видел FUNFSBROWSE во время

/opt/omni/lbin/util_cmd -listremotedir someserver.somedomain /C /

Вывод

  • ИМХО, util_cmd/dpcom предлагает многое для автоматизации Data Protector 9.
  • ИМХО жаль, что документации почти нет.