7 ответов:
в общем, нет. (так что большинство ответов здесь неверны.) Это может будьте в безопасности, в зависимости от того, какое свойство вы хотите. Но это легко в конечном итоге с ошибками в коде, если вы предполагаете слишком много о согласованности файла в
/proc. Например, см. эта ошибка, которая возникла из предположения, что/proc/mountsбыл последовательный снимок.например:
/proc/uptimeis совершенно атомным, как кто-то упомянул в другом ответе-но только с Linux 2.6.30, которому меньше двух лет. Так что даже этот крошечный, тривиальный файл был подвержен состоянию гонки до тех пор, и все еще находится в большинстве ядер предприятия. Смотритеfs/proc/uptime.cдля текущего источника, или фиксация, которая сделала его атомарным. На ядре pre-2.6.30 вы можетеopenфайлreadнемного, то если вы позже вернетесь иreadопять же, часть, которую вы получите, будет несовместима с первой частью. (Я только что продемонстрировал это-попробуйте сами для удовольствия.)
/proc/mountsи атомарный в пределах одногоreadсистемный вызов. если выreadвесь файл сразу, вы получаете один последовательный снимок точек монтирования в системе. Однако, если вы используете несколькоreadсистемные вызовы -- и если файл большой, это именно то, что произойдет, если вы используете обычный Библиотеки ввода/вывода и не обращайте особого внимания на эту проблему-вы будете подвержены состоянию гонки. Вы не только не получите согласованный снимок, но и точки монтирования, которые присутствовали до того, как вы начали и никогда не прекращали присутствовать, могут отсутствовать в том, что вы видите. Чтобы увидеть, что это атомарный для одногоread()посмотриm_start()наfs/namespace.cи смотрите, как он захватывает семафор, который охраняет список точек монтирования, который он держит доm_stop(), который называется, когдаread()выполняемый. Чтобы увидеть, что может пойти не так, см. эта ошибка с прошлого года (тот же самый, который я связал выше) в другом высококачественном программном обеспечении, которое беспечно читает/proc/mounts.
/proc/net/tcp, о котором вы на самом деле спрашиваете, еще менее последователен, чем это. Это атомные только в каждой строке таблицы. Чтобы увидеть это, посмотрите наlistening_get_next()наnet/ipv4/tcp_ipv4.cиestablished_get_next()чуть ниже в этом же файле и посмотреть замки они вынимают на каждом входе по очереди. У меня нет кода repro, удобного для демонстрации отсутствия согласованности от строки к строке, но там нет блокировок (или чего-либо еще), которые сделали бы его последовательным. Что имеет смысл, если вы подумаете об этом-сеть часто является супер-занятой частью системы, поэтому не стоит накладных расходов, чтобы представить последовательное представление в этом диагностическом инструменте.другой кусок, который держит
/proc/net/tcpатомарный внутри каждой строки является буферизация вseq_read(), который вы можете прочитать наfs/seq_file.c. Это гарантирует, что как только выread()часть одной строки, текст всей строки хранится в буфере, так что следующийread()получит остальную часть этой строки перед началом нового. Тот же механизм используется в/proc/mountsчтобы сохранить каждую строку атомарной, даже если вы делаете несколькоread()звонки, и это также механизм, который/proc/uptimeв новых ядрах используется, чтобы оставаться атомарным. Этот механизм делает не буфера весь файл, потому что ядро осторожно относится к использованию памяти.большинство файлов в
/procбудет по крайней мере так же последовательно, как/proc/net/tcp, С каждой строкой последовательное изображение одной записи в любой информации, которую они предоставляют, потому что большинство из них используют то же самоеseq_fileабстракция. Как то/proc/uptimeпример иллюстрирует, однако, некоторые файлы все еще были перенесены для использованияseq_fileеще в 2009 году; я уверен, что есть еще некоторые, которые используют старые механизмы и даже не имеют этого уровень атомарности. Эти предостережения редко документируются. Для данного файла ваша единственная гарантия-прочитать источник.в случае
/proc/net/tcp, вы можете прочитать его и парсить каждую строку без страха. Но если вы попытаетесь сделать какие-либо выводы из нескольких строк сразу-будьте осторожны, другие процессы и ядро are изменение его во время чтения, и вы, вероятно, создаете ошибку.
хотя файлы
/procпоявляются как обычные файлы в пользовательском пространстве, они на самом деле не файлы, а скорее сущности, которые поддерживают стандартные операции с файлами из пользовательского пространства (open,read,close). обратите внимание, что это сильно отличается от обычного файла на диске, который изменяется ядром.все, что делает ядро, это печатает свое внутреннее состояние в свою собственную память с помощью
sprintf- как функция, и эта память копируется в пользовательское пространство всякий раз, когда вы выпускаетеread(2)системный вызов.ядро обрабатывает эти вызовы совершенно иначе, чем для обычных файлов, что может означать, что весь снимок данных, которые вы будете читать, может быть готов в то время, когда вы
open(2)это, в то время как ядро гарантирует, что параллельные вызовы являются последовательными и атомарными. Я нигде этого не читал, но это действительно не имеет смысла быть иначе.мой совет-взглянуть на реализацию файла proc в вашем конкретном вкусе Unix. Это действительно проблема реализации (как и формат и содержание вывода), которая не регулируется стандартом.
самым простым примером может быть реализация
uptimeproc файл в Linux. Обратите внимание, как весь буфер создается в функции обратного вызова, поставляемой вsingle_open.
/proc-это виртуальная файловая система : на самом деле, он просто дает удобный вид внутренностей ядра. Это определенно безопасно читать его (вот почему он здесь), но это рискованно в долгосрочной перспективе, так как внутренние из этих виртуальных файлов могут развиваться с более новой версией ядра.
EDIT
дополнительная информация доступна в документация proc в ядре Linux doc глава 1.4 сетей Я не могу найти если информация, как информация меняться со временем. Я думал, что он был заморожен на открытом, но не может иметь определенного ответа.
EDIT2
по данным Sco doc (не linux, но я уверен, что все ароматы *nix ведут себя так)
хотя состояние процесса и следовательно, содержание /proc файлы могут меняться от мгновенного до мгновенное, одно чтение(2) a /proc файл гарантированно вернуть `вменяемый" представительства государств, которые есть, чтение будет атомарным снимок состояния процесса. Такая гарантия не распространяется на последовательные чтения, применяемые к a /proc файл для запущенного процесса. В кроме того, атомарность является специфически не гарантируется для любого ввода / вывода, примененного к файл as (адресное пространство); содержание адреса любого процесса пространство может быть одновременно изменено с помощью LWP этого процесса или любого другого процесс в системе.
API procfs в ядре Linux предоставляет интерфейс, чтобы убедиться, что чтение возвращает согласованные данные. Читайте комментарии в
__proc_file_read. Пункт 1) в большом блоке комментариев объясняет этот интерфейс.это, как говорится, это, конечно, до реализации конкретного файла proc, чтобы правильно использовать этот интерфейс, чтобы убедиться, что его возвращаемые данные непротиворечивы. Итак, чтобы ответить на ваш вопрос: нет, ядро не гарантирует согласованность файлов proc во время чтение, но оно предоставляет средства для реализации этих файлов для обеспечения согласованности.
у меня есть источник для Linux 2.6.27.8 удобный, так как я занимаюсь разработкой драйверов в данный момент на встроенной цели ARM.
файл ...
linux-2.6.27.8-lpc32xx/net/ipv4/raw.cв строке 934 содержится, напримерseq_printf(seq, "%4d: %08X:%04X %08X:%04X" " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", i, src, srcp, dest, destp, sp->sk_state, atomic_read(&sp->sk_wmem_alloc), atomic_read(&sp->sk_rmem_alloc), 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));выходы
[wally@zenetfedora ~]$ cat /proc/net/tcp sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode 0: 017AA8C0:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 15160 1 f552de00 299 1: 00000000:C775 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 13237 1 f552ca00 299 ...функции
raw_sock_seq_show()который является частью иерархии procfs функции обработки. Текст не генерируется до тех пор, покаread()запрос из/proc/net/tcpфайл, разумный механизм с тех пор procfs чтения, безусловно, гораздо менее распространены, чем обновление информации.некоторые драйверы (например, мой) реализуют функцию proc_read с помощью одного
sprintf(). Дополнительная сложность в реализации основных драйверов заключается в обработке потенциально очень длинного вывода, который может не поместиться в промежуточный буфер пространства ядра во время одного чтения.Я проверил это с помощью программы, использующей буфер чтения 64K, но это приводит к буферу пространства ядра 3072 байта в моей системе для proc_read, чтобы вернуть данные. Несколько вызовов с опережающими указателями необходимы, чтобы получить больше, чем столько текста возвращается. Я не знаю, как правильно сделать возвращенные данные согласованными, когда требуется более одного ввода-вывода. Конечно, каждая запись в
/proc/net/tcpсамосогласованности. Существует некоторая вероятность того, что линии бок о бок снимаются в разное время.
за исключением неизвестных ошибок, нет никаких условий гонки в
/procэто приведет к чтению поврежденных данных или смеси старых и новых данных. В этом смысле, это безопасно. Однако есть еще состояние гонки, что большая часть данных, которые Вы читаете из/procпотенциально-устаревший, как только он генерируется, и даже более того, к тому времени, когда вы доберетесь до его чтения/обработки. Например, процессы могут умереть в любое время, и новому процессу может быть назначен тот же pid; единственные идентификаторы процессов, которые вы можете когда-либо использование без условий расы - это ваши собственные дочерние процессы". То же самое касается сетевой информации (открытые порты и т. д.) и действительно большая часть информации в/proc. Я бы счел это плохой и опасной практикой полагаться на любые данные в/procбыть точным, за исключением данных о вашем собственном процессе и потенциально его дочерних процессах. Конечно, все еще может быть полезно представить другую информацию от/procпользователю / администратору для получения информации / ведения журнала / и т. д. цели.
когда вы читаете из файла /proc, ядро вызывает функцию, которая была зарегистрирована заранее, чтобы быть функцией" read " для этого файла proc. Смотрите
__proc_file_readфункция в fs / proc/generic.с.таким образом, безопасность чтения proc так же безопасна, как и функция, которую ядро вызывает для удовлетворения запроса на чтение. Если эта функция правильно блокирует все данные, к которым она прикасается, и возвращает их вам в буфер, то это абсолютно безопасно для чтения с помощью этой функции. Поскольку прок файлы, такие как тот, который используется для удовлетворения запросов на чтение /proc/net/tcp, были вокруг некоторое время и подверглись скрупулезному обзору, они примерно так же безопасны, как вы могли бы попросить. На самом деле, многие распространенные утилиты Linux полагаются на чтение из файловой системы proc и форматирование вывода по-другому. (С моей головы, я думаю, что " ps " и "netstat" делают это).
этот документ описывает интерфейсы в /proc/сеть/TCP и /труды/нетто/tcp6.
Обратите внимание, что эти интерфейсы устарел в пользу tcp_diag. Эти интерфейсы /proc предоставляют информацию о текущем активном TCP соединения, и реализованы с помощью tcp4_seq_show () в net/ipv4/tcp_ipv4.с и tcp6_seq_show() в net / ipv6 / tcp_ipv6.c, соответственно.
Comments