dtrace ( отслеживание ):Как получить целевую символическую ссылку из файла
-
27-12-2019 - |
Вопрос
Я использую dtrace для записи всех удаляемых файлов.
Можно ли узнать, что такое целевая символическая ссылка (если это символическая ссылка)?Я хочу вывести имя файла символической ссылки и целевое имя файла для входа в систему на случай, если мне понадобится восстановить ссылку позже.
Одно из решений, которое я придумал, - использовать функцию dtrace "system" для вызова моей собственной программы, которая распечатает целевую символическую ссылку:system ("myprogram %s"), где %s - полное имя символической ссылки, для которой я хочу распечатать цель.
Это работает нормально (это очень короткая программа на C и выполняет свою работу) - но есть ли способ получить информацию напрямую через dtrace, поскольку мы все равно обрабатываем файл, мы должны иметь возможность искать целевую символическую ссылку?
Я просмотрел структуру fileinfo_t, но в ней нет цели символической ссылки:http://docs.oracle.com/cd/E18752_01/html/817-6223/chp-io-args.html#chp-io-fileinfo
Пока что это мой сценарий:Это есть в Solaris 10.(Это проверка fop_remove, а не syscall::unlink, и причина этого в том, чтобы иметь возможность получить каталог символьной ссылки в случае, если пользователь не указывает каталог при вызове rm).
#!/usr/sbin/dtrace -s
#pragma D option quiet
fbt::fop_remove:entry
{
self->dir = stringof(args[0]->v_path);
self->file = stringof(args[1]);
}
fbt::fop_remove:return
/self->file != NULL/
{
printf("%s/%s\n", self->dir, self->file);
self->file = 0;
self->dir = 0;
}
Спасибо!
Решение
На уровне Solaris VFS (он же vnode_t
структура), целью символьной ссылки является нет прикрепленный к узлу для самой символической ссылки.Это деталь реализации файловой системы.
Для файловых систем UFS, если путь к целевой ссылке короче 48 байт (то, что UFS называет "быстрой символической ссылкой"), он записывается встроенным с inode_t
struct, и вы можете распечатать значение через DTrace через:
vnode = args[0];
inode = (inode_t*)vnode->v_data;
printf("symlink tgt: %47s\n",
vnode->v_type != VLNK ||
vnode->v_op != ufs_vnodeops ||
inode->i_flags & I_FASTSYMLINK == 0 ?
"[unresolved]" :
(char *)inode->i_db);
Для других файловых систем / в общем случае вам придется использовать fsinfo::readlink:return
(или fop::fop_readlink:return
) зондирующие точки для получения целевого доступа, то есть они (обычно) не могут быть извлечены непосредственно из vnode_t
.
Другие советы
У меня есть следующее возможное решение - на доступ как вы сказали:
syscall::open:entry /strstr(stringof(copyinstr(arg0)), "mydirectory")!=NULL/ {
self->file=copyinstr(arg0);
}
syscall::open:return /self->file != "" && strstr(stringof(fds[arg0].fi_pathname), "mydirectory")!=NULL / {
printf("%s %s\n", self-> file, fds[arg0].fi_pathname);
self -> file=0;
}
syscall::open:return {
self -> file=0;
}
.
(Я ограничиваю отслеживание к MyDirectory здесь).
Так что это использует тот факт, что на входе ARG0 - это имя SymLink, а по возвращении файловый дескриптор доступен, чтобы получить путь, который является исходным значением фактического файла.Так что это будет цель симличиной связи. На самом деле не имеет решающее значение, чтобы след выполнен в делеции, только что SymLink -> цель записана.