{
    "version": "https:\/\/jsonfeed.org\/version\/1.1",
    "title": "Блоги: заметки с тегом nfs",
    "_rss_description": "Автоматически собираемая лента заметок, написанных в блогах на Эгее",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": false,
    "_itunes_explicit": "no",
    "home_page_url": "https:\/\/blogengine.ru\/blogs\/tags\/nfs\/",
    "feed_url": "https:\/\/blogengine.ru\/blogs\/tags\/nfs\/json\/",
    "icon": false,
    "authors": [
        {
            "name": "Илья Бирман",
            "url": "https:\/\/blogengine.ru\/blogs\/",
            "avatar": false
        }
    ],
    "items": [
        {
            "id": "128981",
            "url": "https:\/\/bolknote.ru\/all\/neblokiruyuschiy-rezhim-faylov-v-php\/",
            "title": "Неблокирующий режим файлов в PHP",
            "content_html": "<p style=\"background: rgb(222, 235, 217); padding: 10px; color:#000\">Позже я внимательно прочитал документацию на теме. По всей видимости, это ничего не даст в отношении проверки системы хранения на зависание.<\/p>\n<p>Смотрел недавно исходники языка ПХП, хотел изучить подробнее как реализованы там стримы. Пока читал, случайно натолкнулся на недокументированную возможность — у функции <tt>fopen<\/tt>, как оказалось, есть режим открытия в неблокирующем режиме (буква <tt>n<\/tt>).<\/p>\n<pre class=\"e2-text-code\"><code class=\"cpp\">#if defined(O_NONBLOCK)\n        if (strchr(mode, &#039;n&#039;)) {\n                flags |= O_NONBLOCK;\n        }\n#endif<\/code><\/pre><p>Доступно не на всех системах, только там, где есть константа <tt>O_NONBLOCK<\/tt> в <tt>fcntl.h<\/tt>, то есть в Линуксах, например.<\/p>\n<p>Для меня это довольно полезное знание, так как я давно ищу возможность проверить из ПХП не зависла ли подмонтированная через <i>NFS<\/i> система хранения. Из-за таких зависаний виснет драйвер в ядре и все системные вызовы, которые к нему обращаются. В конечном счёте виснет процесс, который пытается работать с такой файловой системой, да так, что его не получается убить через <tt>SIGKILL<\/tt>.<\/p>\n<p>В общем, надо будет попробовать при следующем таком инциденте — не спасает ли открытие в неблокирующем режиме. Код, кажется, должен выглядеть примерно так:<\/p>\n<pre class=\"e2-text-code\"><code class=\"php\">function tryToOpen(string $path, float $timeout): ?bool\n{\n\t$dio_fd = dio_open($path, O_RDONLY | O_NONBLOCK);\n\tif ($dio_fd === false) {\n\t\treturn null;\n\t}\n\n\tforeach (glob(&#039;\/proc\/self\/fd\/*&#039;) as $file) {\n\t    if (is_link($file) &amp;&amp; readlink($file) === $path) {\n\t\t$fd = basename($file);\n\t\t$read = [fopen(&quot;php:\/\/fd\/$fd&quot;, &#039;rn&#039;)];\n\t\t$write = $except = null;\n\n\t\t$timeout_us = (int) ($timeout * 1e6);\n\t\treturn stream_select($read, $write, $except, 0, $timeout_us) === 1;\n             }\n\t}\n\treturn null;\n}<\/code><\/pre><p>Тут используется модуль ПХП <i>Direct IO<\/i>, чтобы обратиться к системной функции <tt>open<\/tt> мимо ПХП. Приходится так делать, потому что функция <tt>fopen<\/tt>, которая есть в языке, сначала попытается проверить существование файла и в моей задаче сразу зависнет.<\/p>\n<p>После этого я, пользуясь <tt>\/proc<\/tt>, ищу среди своих файловых дескрипторов тот, который отвечает за только что открытый файл и переоткрываю его через <tt>fopen<\/tt> (в этом месте делается дубликат файлового дескриптора, а прежний закрывается — вызывается <tt>dup<\/tt>), так как мы тут работаем с номером файлового дескриптора, то проверка на существование файла не используется.<\/p>\n<p>Переоткрытие файла нужно, так как в вызов <tt>stream_select<\/tt>, который я использую для ожидания данных из файла с таймаутом, можно передать результат <tt>fopen<\/tt>, но не <tt>dio_open<\/tt>.<\/p>\n<p>Надеюсь случай испытать этот код представится нескоро.<\/p>\n",
            "date_published": "2022-12-15T18:24:51+05:00",
            "date_modified": "2024-06-26T00:01:28+05:00",
            "tags": [
                "nfs",
                "php",
                "программирование"
            ],
            "author": {
                "name": "Евгений Степанищев",
                "url": "https:\/\/bolknote.ru\/",
                "avatar": "https:\/\/bolknote.ru\/pictures\/userpic\/userpic@2x.jpg?1760600028"
            },
            "_date_published_rfc2822": "Thu, 15 Dec 2022 18:24:51 +0500",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "128981",
            "_rss_enclosures": [],
            "_e2_data": {
                "is_favourite": false,
                "links_required": null,
                "og_images": []
            }
        }
    ],
    "_e2_version": 4079,
    "_e2_ua_string": "Aegea 11.0 (v4079e)"
}