dtrace: как получить цель символической ссылки из файла

Я использую dtrace для записи всех удаляемых файлов.

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

Одно из решений, которое я придумал, состоит в том, чтобы использовать «системную» функцию dtrace для вызова моей собственной программы, которая распечатает цель символической ссылки: 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, и причина этого заключается в том, чтобы иметь возможность получить каталог символической ссылки в случае, если пользователь не указывает каталог в звонок в рм).

    #!/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;
    }

Спасибо!


person user2533268    schedule 18.11.2013    source источник


Ответы (2)


На уровне Solaris VFS (также известном как структура vnode_t) цель символической ссылки не присоединена к узлу самой символической ссылки. Это деталь реализации файловой системы.

Для файловых систем UFS, если путь к цели ссылки короче 48 байт (то, что UFS называет «быстрой символической ссылкой»), он записывается встроенно со структурой inode_t, и вы можете распечатать значение через 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.

person FrankH.    schedule 19.11.2013
comment
Спасибо, Фрэнк, это для FreeBSD? Я получаю ошибки компиляции для ufs_vnodeops и i_db, что они не являются известными переменными или членами i_node. - person user2533268; 20.11.2013
comment
нет, это Солярис. Я не знаю, имеет ли FreeBSD' UFS механизм быстрой символической ссылки, который есть у Solaris UFS (где прямые указатели блоков повторно используются для хранения целевого пути символической ссылки, если он подходит). - person FrankH.; 21.11.2013
comment
Так получилось, что ссылки, с которыми я имею дело, намного длиннее 48 байт. Но спасибо, что прояснили это. Я не был уверен, есть ли способ получить доступ к цели напрямую, используя сам файл. - person user2533268; 04.12.2013

У меня есть следующее возможное решение - при доступе, как вы сказали:

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;
}

(Здесь я ограничиваю трассировку своим каталогом).

Таким образом, это использует тот факт, что при входе arg0 является именем символической ссылки, а при возврате дескриптор файла доступен для получения пути, который является путем к фактическому файлу. Так что это будет целью символической ссылки. На самом деле не критично, что трассировка выполняется при удалении, просто записывается символическая ссылка -> цель.

person user2533268    schedule 20.11.2013