<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Блоги: заметки с тегом nfs</title>
<link>https://blogengine.ru/blogs/tags/nfs/</link>
<description>Автоматически собираемая лента заметок, написанных в блогах на Эгее</description>
<author></author>
<language>ru</language>
<generator>Aegea 11.0 (v4079e)</generator>

<itunes:subtitle>Автоматически собираемая лента заметок, написанных в блогах на Эгее</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit>no</itunes:explicit>

<item>
<title>Неблокирующий режим файлов в PHP</title>
<guid isPermaLink="false">128981</guid>
<link>https://bolknote.ru/all/neblokiruyuschiy-rezhim-faylov-v-php/</link>
<pubDate>Thu, 15 Dec 2022 18:24:51 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/neblokiruyuschiy-rezhim-faylov-v-php/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p style="background: rgb(222, 235, 217); padding: 10px; color:#000"&gt;Позже я внимательно прочитал документацию на теме. По всей видимости, это ничего не даст в отношении проверки системы хранения на зависание.&lt;/p&gt;
&lt;p&gt;Смотрел недавно исходники языка ПХП, хотел изучить подробнее как реализованы там стримы. Пока читал, случайно натолкнулся на недокументированную возможность — у функции &lt;tt&gt;fopen&lt;/tt&gt;, как оказалось, есть режим открытия в неблокирующем режиме (буква &lt;tt&gt;n&lt;/tt&gt;).&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="cpp"&gt;#if defined(O_NONBLOCK)
        if (strchr(mode, &amp;#039;n&amp;#039;)) {
                flags |= O_NONBLOCK;
        }
#endif&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Доступно не на всех системах, только там, где есть константа &lt;tt&gt;O_NONBLOCK&lt;/tt&gt; в &lt;tt&gt;fcntl.h&lt;/tt&gt;, то есть в Линуксах, например.&lt;/p&gt;
&lt;p&gt;Для меня это довольно полезное знание, так как я давно ищу возможность проверить из ПХП не зависла ли подмонтированная через &lt;i&gt;NFS&lt;/i&gt; система хранения. Из-за таких зависаний виснет драйвер в ядре и все системные вызовы, которые к нему обращаются. В конечном счёте виснет процесс, который пытается работать с такой файловой системой, да так, что его не получается убить через &lt;tt&gt;SIGKILL&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;В общем, надо будет попробовать при следующем таком инциденте — не спасает ли открытие в неблокирующем режиме. Код, кажется, должен выглядеть примерно так:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="php"&gt;function tryToOpen(string $path, float $timeout): ?bool
{
	$dio_fd = dio_open($path, O_RDONLY | O_NONBLOCK);
	if ($dio_fd === false) {
		return null;
	}

	foreach (glob(&amp;#039;/proc/self/fd/*&amp;#039;) as $file) {
	    if (is_link($file) &amp;amp;&amp;amp; readlink($file) === $path) {
		$fd = basename($file);
		$read = [fopen(&amp;quot;php://fd/$fd&amp;quot;, &amp;#039;rn&amp;#039;)];
		$write = $except = null;

		$timeout_us = (int) ($timeout * 1e6);
		return stream_select($read, $write, $except, 0, $timeout_us) === 1;
             }
	}
	return null;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Тут используется модуль ПХП &lt;i&gt;Direct IO&lt;/i&gt;, чтобы обратиться к системной функции &lt;tt&gt;open&lt;/tt&gt; мимо ПХП. Приходится так делать, потому что функция &lt;tt&gt;fopen&lt;/tt&gt;, которая есть в языке, сначала попытается проверить существование файла и в моей задаче сразу зависнет.&lt;/p&gt;
&lt;p&gt;После этого я, пользуясь &lt;tt&gt;/proc&lt;/tt&gt;, ищу среди своих файловых дескрипторов тот, который отвечает за только что открытый файл и переоткрываю его через &lt;tt&gt;fopen&lt;/tt&gt; (в этом месте делается дубликат файлового дескриптора, а прежний закрывается — вызывается &lt;tt&gt;dup&lt;/tt&gt;), так как мы тут работаем с номером файлового дескриптора, то проверка на существование файла не используется.&lt;/p&gt;
&lt;p&gt;Переоткрытие файла нужно, так как в вызов &lt;tt&gt;stream_select&lt;/tt&gt;, который я использую для ожидания данных из файла с таймаутом, можно передать результат &lt;tt&gt;fopen&lt;/tt&gt;, но не &lt;tt&gt;dio_open&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Надеюсь случай испытать этот код представится нескоро.&lt;/p&gt;
</description>
</item>


</channel>
</rss>