Введение
Возможность 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'
Он выведет список этих деталей:
- Идентификатор сессии
- Идентификатор сеанса с добавленным @cellmanager.
- (Мне неизвестно.)
- Владелец сеанса
- Спецификация
- Тип сеанса: 0=Резервное копирование, 1=Восстановление, 3=МедиаМ
- Start Time_t (в секундах с эпохи Unix)
- End Time_t (в секундах с эпохи Unix)
- Статус: 2=Завершено, 3=Завершено/Ошибки, 5=Сбой, 7=Прервано, 13=Завершено/Ошибки
- (Мне неизвестно.)
- # Предупреждение (количество предупреждений)
- # Ошибки (количество ошибок)
- (Мне неизвестно.)
- (Мне неизвестно.)
запрос 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.
- ИМХО жаль, что документации почти нет.