КатегорииLinksUnix Tutorial
Personal Development Ruslan Valiev Solaris Performance Team Damien Farnham Fintan Ryan Nicky Veitch Niall Mullen Sean McGrath DTrace Bryan Cantrill Brendan Gregg ZFS Tim Foster General Ben Rockwood Learning Solaris 10 Privacy policy |
Friday, 10 December. 2004
Предикаты в DTrace Добавил Gleb Reys
в категории DTrace в
19:52
Комментарии (0) Обратные ссылки (0) Select language: English Defined tags for this entry: dtrace
Предикаты в DTrace
В DTrace нет условных операторных скобок типа if..then..else, вместо них используются предикаты.
Предикат - это заключённые в слэши (/) условия, приводимые сразу после строки объявления той или иной пробы, и предназначенные для контроля за необходимостью выполнения кода, относящегося к этой пробе. Скажем, следующий скрипт выведет список всех системных вызовов, кроме write, для всех процессов, запущенных на системе. Так как DTrace отслеживает события на уровне thread'ов, в примере запуска этого скрипта видно, что некоторые иднентификаторы процессов повторяются. Это потому что пробы сработали для различных thread'ов одного и того же процесса: CODE: #!/usr/sbin/dtrace -s #pragma D option quiet syscall::: /probefunc != "write"/ { printf("probefunc: %s, pid: %d, execname: %s\n", probefunc, pid, execname); } После запуска скрипта вы увидите примерно следующее: CODE: probefunc: ioctl, pid: 28603, execname: dtrace probefunc: ioctl, pid: 28603, execname: dtrace probefunc: ioctl, pid: 28603, execname: dtrace probefunc: ioctl, pid: 28603, execname: dtrace probefunc: ioctl, pid: 28603, execname: dtrace probefunc: sysconfig, pid: 28603, execname: dtrace probefunc: sysconfig, pid: 28603, execname: dtrace probefunc: sysconfig, pid: 28603, execname: dtrace probefunc: sysconfig, pid: 28603, execname: dtrace probefunc: sigaction, pid: 28603, execname: dtrace probefunc: sigaction, pid: 28603, execname: dtrace probefunc: sigaction, pid: 28603, execname: dtrace probefunc: sigaction, pid: 28603, execname: dtrace ... Т.е. скрипт учёл и системные вызовы, выполненные командой dtrace, которая выполняла скрипт. Для того, чтобы исключить эту команду из нашей статистики, следует изменить предикат: CODE: /probefunc != "write" && execname != "dtrace"/ и тогда вывод команды будет включать уже все другие процессы, кроме dtrace, в моём примере это парочка моих терминалов rxvt и java: CODE: probefunc: pollsys, pid: 28411, execname: rxvt probefunc: ioctl, pid: 28411, execname: rxvt probefunc: ioctl, pid: 28411, execname: rxvt probefunc: pollsys, pid: 28411, execname: rxvt probefunc: pollsys, pid: 28406, execname: rxvt probefunc: ioctl, pid: 28406, execname: rxvt probefunc: ioctl, pid: 28406, execname: rxvt probefunc: pollsys, pid: 28406, execname: rxvt probefunc: lwp_cond_wait, pid: 27870, execname: java_vm probefunc: lwp_cond_signal, pid: 27870, execname: java_vm probefunc: lwp_cond_signal, pid: 27870, execname: java_vm probefunc: lwp_cond_wait, pid: 27870, execname: java_vm ... В выражениях предикатов могут использоваться любые константы и переменные, ранее использовавшиеся в коде, или стандартные переменные, как в приведённых примерах. А если учесть, что локальные переменные уникальны для каждого thread'а процесса, то можно строить и конструкции посложнее... Локальные для каждого thread'а переменные объявляются с помощью оператора -> специального идентификатора self, например: self->flag = 1;. Приведённые ниже пример выведет лишь по одному сообщению про системный вызов write каждого из thread'ов всех процессов, выполняющих этот вызов. Как видно из кода, едва мы сообщаем об очередном thread'е, который мы уличили в завершении системного вызова write, мы тут же отмечаем в локальной для этого thread'а переменной, что он уже был обработан: self->processed = 1;. А предикат уже позаботится о том, чтобы в следующий раз для уже отмеченного thread'а мы не выполняли код нашей пробы: CODE: #!/usr/sbin/dtrace -s #pragma D option quiet syscall::write:return / self->processed == 0/ { printf("tid: %d, pid: %d, execname: %s\n", tid, pid, execname); self->processed = 1; } Как видно, каждый thread был зарегистрирован только один раз: CODE: tid: 1, pid: 21583, execname: soffice.bin tid: 4, pid: 21750, execname: thunderbird-bin tid: 4, pid: 27406, execname: mozilla-bin tid: 1, pid: 27406, execname: mozilla-bin tid: 1, pid: 21450, execname: icewm tid: 4, pid: 21583, execname: soffice.bin tid: 1, pid: 21750, execname: thunderbird-bin tid: 1, pid: 28636, execname: dtrace Всех способов использования предикатов не расскажешь в одной записи, так что в следующий раз я постараюсь показать ещё несколько вариантов использования этой замечательной возможности DTrace. Thursday, 9 December. 2004SMF: Работа с сервисами Solaris 10 - продолжение
Продолжая начатую ранее тему про SMF, хочу рассказать немного о том, как работать с сервисами.
Итак, команда svcs -a поможет получить текущий список инстансов (instances) сервисов в системе, с указанием их статусов. Далее, можно воспользоваться командой svcs -l чтобы узнать о конкретном сервисе побольше. Этот вариант вызова svcs покажет всю доступную информацию об инстансе сервиса. В общем-то, вся выводимая этой командой информация полезна, но особенно полезны поля state_time - когда инстанс сервиса перешёл в текущее состояние, logfile - где можно почитать про то, как и когда именно запускался данный сервис, и ещё очень полезны зависимости этого сервиса - список тех сервисов, без которых данный инстанс не может быть запущен. Указывается состояние этих сервисов, так что удобно замечать те их зависимостей, которые в состоянии, отличном от online, чтобы смотреть уже информацию про них с помощью той же svcs -l... CODE: bash-3.00$ svcs -l svc:/network/nfs/client:default fmri svc:/network/nfs/client:default name NFS client service enabled true state online next_state none state_time Mon Dec 06 15:45:08 2004 logfile /var/svc/log/network-nfs-client:default.log restarter svc:/system/svc/restarter:default dependency require_any/error svc:/milestone/network (online) dependency require_all/error svc:/network/nfs/nlockmgr (online) dependency optional_all/error svc:/network/nfs/cbd (online) dependency optional_all/error svc:/network/nfs/mapid (online) dependency require_all/restart svc:/network/rpc/bind (online) dependency optional_all/none svc:/network/rpc/keyserv (online) dependency optional_all/none svc:/network/rpc/gss (online) dependency require_all/refresh svc:/milestone/name-services (online) В данном примере видно, что сервис NFS client запущен, потому что все его жёсткие зависимости (те сервисы, которые обязательно должны быть запущены, чтобы позволить инстансу этого сервиса так же быть запущенным). Если бы некоторые из дополнительных зависимостей (которые видны в строчках optional_all) не были запущены, NFS client всё равно бы запустился. На самом деле, после небольшой практики работы с командами, вырабатывается методика нахождения и решения проблем с запусками сервисов, и тогда начинают использоваться другие ключи команды svcs. На пример, ключик -d поможет вывести лишь список зависимостей указанного инстанса: CODE: bash-3.00$ svcs -d svc:/network/nfs/client:default STATE STIME FMRI online Dec_06 svc:/milestone/network:default online Dec_06 svc:/network/rpc/bind:default online Dec_06 svc:/network/rpc/keyserv:default online Dec_06 svc:/milestone/name-services:default online Dec_06 svc:/network/rpc/gss:default online 17:52:29 svc:/network/nfs/nlockmgr:default online 17:52:29 svc:/network/nfs/cbd:default online 17:52:29 svc:/network/nfs/mapid:default Есть ещё один полезный вариант вызова команды svcs - это svcs -D. Такая команда покажет список всех сервисов, зависимых от указанного - т.е. расследование какой-то проблемы можно начать и с другой стороны. CODE: bash-3.00$ svcs -D svc:/network/nfs/client:default STATE STIME FMRI online Dec_06 svc:/system/filesystem/autofs:default online Dec_06 svc:/system/dumpadm:default online Dec_06 svc:/milestone/multi-user:default Также полезной является опция -p, которая показывает PID процессов, связанных с указанным инстансом сервиса. В примере ниже мы может увидеть процесс и его идентификатор для сервиса svc:/network/nis/client:default (ВНИМАНИЕ! В этом примере используется nis/client, а не nfs/client, как во всех предыдущих примерах) CODE: bash-3.00$ svcs -p svc:/network/nis/client:default STATE STIME FMRI online Dec_06 svc:/network/nis/client:default Dec_06 176 ypbind Этот полезный ключик можно использовать и без указания сервиса, тогда вы получите очень длинный список сервисов с указанием процессов, к ним относящихся. СЛЕДУЕТ ПОМНИТЬ: Сервисы - это не только демоны и запущенные в системе процесс, поэтому в длинном списке, полученном после выполнения на вашей системе svcs -p, далеко не каждый инстанс сервиса будет иметь относящийся к нему процесс. Wednesday, 8 December. 2004
pkg-get Добавил Gleb Reys
в категории Solaris в
18:20Комментарии (2) Обратные ссылки (0) Select language: English
pkg-get
Сегодня ещё немного времени провёл с pkg-get и установкой пакетов с BlastWave.org...
В общем-то, очень хорошая идея - по крайней мере, когда что-то нужно быстро установить и попробовать, можно смело её использовать. В отличие от apt-get и прочих вещей для Linux, мне здесь понравилось то, что все пакеты кладутся именно в /opt/csw каталог, т.е. их легко потом можно удалить, как средствами pkgrm, так и вручную... Хотя жутким преимуществом это назвать и нельзя, мне всё же показалось, что так удобнее - когда всё ставится в какой-то общий каталог, и это не /usr/local, а что-нибудь другое. Как минимум, с пакетами с SunFreeware.Com нельзя будет перепутать... Tuesday, 7 December. 2004
Встроенные ... Добавил Gleb Reys
в категории DTrace в
17:51
Комментарии (0) Обратные ссылки (0) Defined tags for this entry: dtrace
Встроенные переменные DTrace
В DTrace есть довольно много очень полезных встроенных переменных.
Полный их список приведён здесь, а пока я расскажу лишь про несколько из них. В этой заметке мы рассмотрим простейшие переменные, а в последующих записях постепенно научимся использовать и более сложные. Позволю себе разбить переменные на несколько групп. Помимо имени переменной, я также приведу её тип. Итак: 1) Имена файлов и каталогов string cwd - имя текущего каталога того процесса, которому принадлежит текущий thread string execname - символьное имя, которое было передано функции exec(2) для исполнения текущего процесса. 2) Процессы id_t tid - номер текущего thread'а. Для thread'ов пользовательских процессов, это значение будет равно результату вызова pthread_self(3C). pid_t pid - идентификатор процесса (PID) текущего процесса pid_t ppid - parent PID текущего процесса uid_t uid - пользовательский ID текущего процесса gid_t gid - идентификатор группы (group ID) текущего процесса 3) Пробы uint_t id - ID номер текущей пробы. Это тот самый номерок, что видно в таблице доступны проб при вызове команды dtrace -l string probefunc - имя функции согласно описанию текущей пробы string probemod - имя модуля согласно описанию текущей пробы string probename - имя пробы согласно описанию текущей пробы string probeprov - имя провайдера согласно описанию текущей пробы 4) Прочее int errno - код ошибки, возвращённый последним системным вызовом, выполненным текущим thread'ом uint64_t timestamp - текущее время счётчика наносекунд. Данный счётчик не привязан к текущему времени в системе, и потому должен использоваться только для относительных вычислений. Использовать эти переменные можно как угодно - один из простейших вариантов применения приведён ниже. Я привожу полный текст скрипта, поэтому если вы его сохраните под именем script.d и сделаете этому файлу chmod u+x ./script.d, то его можно будет запускать прямо из командной строки. Пока не обращайте внимания на строку с pragma D option, про несколько полезных опций DTrace я расскажу через несколько дней. ВНИМАНИЕ: в целях компактного размещения кода, я разбил длинные строки с printf на несколько строк. Если вы хотите запустить данный скрипт, вам следует склеить такие строки. CODE: #!/usr/sbin/dtrace -s #pragma D option quiet :::write:entry { printf("\nProcess info:\ntid=%d, pid=%d, ppid=%d, uid=%d, gid=%d\n", tid, pid, ppid, uid, gid); printf("CWD=%s, execname=%s\n", cwd, execname); printf("Probe info:\nid=%d, probeprov=%s, probemod=%s, probefunc=%s, probename=%s\n", id, probeprov, probemod, probefunc, probename); } Запущенный на вашей машине, данный скрипт выдаст вам примерно следующее (будет ОЧЕНЬ много строк, так как мы ловим, согласно шаблону, все обращения к вызову write): CODE: Process info:
tid=1, pid=22157, ppid=21995, uid=123, gid=10 CWD=/export/greys/./dtrace, execname=dtrace Probe info: id=6295, probeprov=fbt, probemod=genunix, probefunc=write, probename=entry Process info: tid=1, pid=21993, ppid=21450, uid=123, gid=10 CWD=/home/gr128638, execname=rxvt Probe info: id=12, probeprov=syscall, probemod=, probefunc=write, probename=entry Monday, 6 December. 2004
Официальное ... Добавил Gleb Reys
в категории DTrace в
20:06
Комментарии (2) Обратные ссылки (0) Select language: English Defined tags for this entry: dtrace
Официальное руководство по DTrace
Это уже далеко не новость, так как вы все, скорее всего, уже знаете эту ссылку, но тем не менее:
Solaris Dynamic Tracing Guide А вспомнил про эту ссылку я потому, что хотел рассказать о примерах, которые приведены в этом руководстве. Их довольно много, они простые и в то же время очень полезные. Так что на практике могут запросто пригодиться. Все эти примеры находятся в каталоге /usr/demo/dtrace, и открыв в вашем браузере файл /usr/demo/dtrace/index.html, вы сможете увидеть все примеры в таблице, разбирающей их по главам руководства по DTrace. |




