Существует ли алгоритм, чтобы решить если символьная ссылка циклы?

Вы не должны ожидать, что эта переменная изменится. Это используется для хранения пути к оболочке по умолчанию, т.е. того, сохраненного в базе данных пароля, не, которые окружают, Вы в настоящее время работаете.

16
08.11.2013, 15:24
6 ответов

Хорошо, после того, как еще некоторые думали, что я думаю, что у меня есть ясное решение.

Критическое понимание то, что, если каждая ссылка, которая является частью пути, решает к чему-то, затем вся твердость пути. Или наоборот, если путь не решает затем, должна быть определенная символьная ссылка, которая требует пересечения, которое не решает.

При размышлении об этой проблеме ранее я использовал алгоритм, который пересек элементы пути, начинающего с корня, и когда это встретилось с символьной ссылкой, это заменило тот элемент пути содержанием символьной ссылки и затем продолжило пересекать. Так как этот подход не помнит, какая символьная ссылка он в настоящее время разрешает, что не может обнаружить, когда это находится в цикле неразрешения.

Если алгоритм отслеживает, которой символьной ссылки он в настоящее время решает (или который символьные ссылки в случае рекурсивных ссылок), он может обнаружить, если он пытается разрешить ссылку снова рекурсивно, которую это все еще занято, разрешая.

Алгоритм:

initialize `location` to the current working directory
initialize `link_contents` to the path we want to resolve
initialize `active_symlinks` to the empty set

def resolve_symlink(location, link_contents, active_symlinks) :
    loop forever:
        next_location = location / [first element of link_contents]
        see if next_location is a symlink.
        if so:
            if next_location in active_symlinks: abort, we have a loop
            location = resolve_symlink(location, readlink(next_location), active_symlinks ∪ {next_location})
        else:
            location = next_location
        strip first element of link_contents
        if link_contents is empty: 
            return location

править:

У меня есть рабочая реализация этого в Python в https://bitbucket.org/JanKanis/python-inotify/src/853ed903e870cbfa283e6ce7a5e41aeffe16d4e7/inotify/pathresolver.py? at=pathwatcher.

5
27.01.2020, 19:48

Я не полностью понимаю то, что Вы спрашиваете. Если я не знал ничего лучшего, я думаю, что Вы спрашивали, был ли способ обнаружить это в то время как посреди контакта с файлом. Я не полагаю, что это возможно.

Единственный метод, из которого я могу забеременеть, делает находку, где Вы конкретно начинаете просматривать конкретное ответвление в дереве каталогов.

Пример

$ tree 
.
`-- a
    `-- b
        |-- c
        |   `-- d
        |       `-- e -> ../../../../a/b
        `-- e -> e

5 directories, 1 file

find команда обнаружит этот цикл, но не действительно скажет Вам много об этом.

$ find -L . -mindepth 15
find: File system loop detected; `./a/b/c/d/e' is part of the same file system loop as `./a/b'.
find: `./a/b/e': Too many levels of symbolic links

Я произвольно выбрал 15 уровней, чтобы заблокировать любой вывод, отображаемый find. Можно однако отбросить тот переключатель (-mindepth) если Вы не заботитесь об отображаемом дереве каталогов. find команда все еще обнаруживает цикл и остановки:

$ find -L . 
.
./a
./a/b
./a/b/c
./a/b/c/d
find: File system loop detected; `./a/b/c/d/e' is part of the same file system loop as `./a/b'.
find: `./a/b/e': Too many levels of symbolic links

Кстати, если Вы хотите переопределить значение по умолчанию MAXSYMLINKS который является, по-видимому, 40 на Linux (более новый 3.x версии ядра), Вы видите это названные Вопросы и ответы U&L: Как Вы увеличиваете MAXSYMLINKS.

Используя команду символьных ссылок

Существует инструмент, который специалисты по обслуживанию FTP-сайта могли использовать названный symlinks который поможет выставить проблемы с инструментом долго или повисшими деревьями, которые были вызваны символьными ссылками.

В определенных случаях symlinks инструмент мог использоваться для удаления предлагаемых каналов также.

Пример

$ symlinks -srv a
lengthy:  /home/saml/tst/99159/a/b/c/d/e -> ../../../../a/b
dangling: /home/saml/tst/99159/a/b/e -> e

glibc библиотека

glibc библиотека надеется предлагать некоторые функции C вокруг этого, но я не полностью знаю их роли или как на самом деле использовать их. Таким образом, я могу только просто указать на них Вам.

Страница справочника, man symlink показывает функциональное определение для вызванной функции symlink(). Описание идет как это:

символьная ссылка () создает символьную ссылку, названную newpath, который содержит строку oldpath.

Одно из состояний ошибки, которые возвращает эта функция:

С ELOOP Слишком много символьных ссылок встретились в разрешении newpath.

Я также направлю Вас к странице справочника, man path_resolution который обсуждает, как Unix определяет пути к объектам на диске. Конкретно этот абзац.

If  the component is found and is a symbolic link (symlink), we first 
resolve this symbolic link (with the current lookup directory as starting 
lookup directory).  Upon error, that error is returned.  If the result is 
not a directory, an ENOTDIR error is returned.  If the resolution of the 
symlink is successful and returns a directory, we set the current lookup
directory to that directory, and go to the next component.  Note that the 
resolution process here involves recursion.  In order  to  protect  the 
kernel against stack overflow, and also to protect against denial of 
service, there are limits on the maximum recursion depth, and on the maximum 
number of symbolic links followed.  An ELOOP error is returned  when  the
maximum is exceeded ("Too many levels of symbolic links").
10
27.01.2020, 19:48
  • 1
    Если возможный я хотел бы способ обнаружить цикл символьной ссылки при предоставлении единственного пути и разрешения символьных ссылок вручную в программе вместо того, чтобы позволить ОС сделать это. Но я задаюсь вопросом, возможно ли это вообще. Решение для находки выглядит интересным, но у Вас есть какая-либо идея/how/, находят, обнаруживает циклы символьной ссылки, и если метод, который это использует, завершен (т.е. обнаруживает все возможные циклы и не не распознает путей нецикличного выполнения)? $ –  JanKanis 07.11.2013, 11:04
  • 2
    @Somejan - посмотрите мои обновления A. Сообщите мне, имеет ли это смысл. –  slm♦ 07.11.2013, 15:14

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

>>> import networkx as nx
>>> G = nx.DiGraph()
>>> G.add_edge('A', 'B')
>>> G.add_edge('B', 'C')
>>> G.add_edge('C', 'D')
>>> G.add_edge('C', 'A')
>>> nx.simple_cycles(G)
[['A', 'B', 'C', 'A']]
3
27.01.2020, 19:48
  • 1
    я также думал об использовании некоторого алгоритма графика, но я не уверен, может ли дерево каталогов с символьными ссылками быть соответственно представлено в простом графике. В abc дерева каталогов, где c является символьной ссылкой на.., существует цикл, но соединяет каналом как a/b/c/b/c/b, все еще решают, поскольку они только следуют за циклом конечное количество раз и не сохраняют цикличное выполнение. –  JanKanis 07.11.2013, 11:09
  • 2
    @Somejan: пространство имен файловой системы является графиком, и имя файла является путем, предпочтенным тому графику. –  ninjalj 07.11.2013, 13:55
  • 3
    @ninjalj: Да файловая система является графиком, но я не думаю, что имя файла является просто путем по тому графику. Имя файла может рассматриваться как ряд инструкций относительно того, как пересечь график. Даже если график содержит циклы, который не означает, что имя файла, которое следует за тем циклом обязательно, не решает, посмотрите мой пример в моем предыдущем комментарии. –  JanKanis 08.11.2013, 02:09

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

В живой системе нет никакого способа обнаружить циклы, потому что символьные ссылки могут измениться, в то время как детектор цикла работает. Чтение каждой символьной ссылки является атомарным, но переходить по символьной ссылке не. Если некоторые символьные ссылки продолжают изменяться, в то время как ядро делает обход, оно могло закончиться на бесконечном пути, включающем отличные ссылки.

3
27.01.2020, 19:48
  • 1
    Существуют способы смягчить те изменения, чтобы принести ему 98-99%-ю точность. Вы могли заставить его обратить внимание на метки времени на файлах, и я не был бы, предлагая на самом деле переходить по ссылкам. Так как это рекурсивно от корня, это найдет фактический каталог позже. –  Back2Basics 13.11.2013, 08:06
  • 2
    @Back2Basics Эти числа абсолютно бессмыслен. Это - интерфейс ядра. Если это не работает все время, это не работает, период. –  Gilles 'SO- stop being evil' 13.11.2013, 10:18

Почти я могу сказать от рассмотрения текущих источников ядра Linux, все ядро делает, проводят подсчет того, сколько ссылок это сопровождается, и это ошибки, если это больше, чем некоторое число. Посмотрите строку 1330 в namei.c для комментария, и nested_symlink() функция. Макрос ELOOP (код ошибки, возвращенный из a read(2) системный вызов этой ситуации), обнаруживается во многих местах в том файле, таким образом, это не может быть столь просто, как, считая ссылки сопровождаемыми, но это уверено, на что это похоже.

Существует много алгоритмов для нахождения "циклов" в связанных списках (алгоритм обнаружения цикла Floyd) или в ориентированных графах. Это не ясно мне, какой необходимо было бы сделать для обнаружения фактического "цикла" или "цикла" в конкретном пути. В любом случае алгоритмы могли занять много времени для выполнения, таким образом, я предполагаю, что просто подсчет количества перешедших символьных ссылок получает Вас 90% пути к Вашей цели.

2
27.01.2020, 19:48
  • 1
    Для практических применений, просто считая количество ссылок пересеченным прекрасен, тем более, что, именно это ядро делает, поэтому даже при обнаружении с правильно путем разрешения, который имеет слишком много символьных ссылок, Вы все еще не можете использовать тот путь ни для чего практического (т.е. это не включает вручную разрешение символьных ссылок), –  JanKanis 08.11.2013, 02:13

Создайте список со всеми символическими ссылками/файлами, которые вы посещаете, чтобы при переходе по первой символической ссылке вы добавляли ее в список. Если символическая ссылка указывает на файл в списке (, то есть файл, который вы уже посетили ), вы знаете, что существует цикл

1
28.02.2021, 09:23

Теги

Похожие вопросы