• Авторизация


Исполняем жёсткие ссылки 09-09-2006 21:18 к комментариям - к полной версии - понравилось!


Если вдруг кому-нибудь прийдётся писать что-либо на PHP и в особенности, если будет необходимость запускать внешние программы для каких-либо целей, то следующее руководство для вас.
    Имеем: Windows 2003 Server + Internet Information Server 6.0 + PHP 5.0

    Задача: Необходимость создать хардлинк (от англ. hard link - жёсткая ссылка) на файл, находящийся на отличной от расположения директории "Inetpub" партиции.

Что такое жёсткая ссылка? В общем-то, как я понял, после кошмарного количества убитого времени, это дополнительное имя файла, на который она ссылается. Точнее сказать, жёсткая ссылка следит не за именем файла, а за закреплённым за файлом идентификатором (в UNIX-системах этот идентификатор назывется inode). Недостатком этого рода ссылок является то, что они живут только в пределах одной партиции, одной файловой системы, так как на каждом разделе жёсткого диска имеется своя собственная, независимая ФС, которая и присваивает всем файлам свои ID, в независимости от того, какие ID были присвоены файлам на другой партиции. Недостатком номер два является невозможность создавать ссылки на директории, обьяснения этому я так и не нашёл.

Почему именно hardlink? Да потому что Windows 2003 Server не в состоянии создать обыкновенную символьную ссылку через консоль. Вот и приходится извращаться как только можно.

Скрипт, в общем-то, совершенно простой, но для того, чтобы заставить его работать, пришлось снова потанцевать с бубном вокруг монитора.
[показать]
    // Генерируем строку длинной 32 символа, состоящую из символов указанных в переменной $letters
    $letters = 'abcdef0123456789';
    srand((double) microtime() * 1000000);
    $string = '';
    for ($i = 1; $i <= rand(32,32); $i++) {
    $q = rand(1,12);
    $string = $string . $letters[$q];
    }

    // Файл, для которого будет создан хардлинк
    $file = "F:\\archive\\somefile.mpeg";

    // Адрес, где будет создан хардлинк и под каким именем
    $hlink = "F:\\tmpfiles\\$string\\somefile.mpeg";

    // Создаём директорию с именем $string
    if(!exec("mkdir \"F:\\tmpfiles\\$string\"",$status_dir,$error_dir)){
    echo "Не могу создать директорию \"F:\\tmpfiles\\$string\"
    ";
    }else{
    echo "Директория \"F:\\tmpfiles\\$string\" создана!
    ";
    }

    if($error_dir) print_r($status_dir);

    // Создаём хардлинк
    if(!exec("fsutil hardlink create $hlink $file",$status,$error)){
    echo "Не могу создать хардлинк!
    ";
    }else{
    echo "Хардлинк создан!
    ";
    }

    if($error) print_r($status);

При настройках по умолчанию, такой скрипт выдаст следующие радостные строки:

    Не могу создать директорию "F:\tmpfiles\fae72cba8a3bacb8a3b892"
    Array ( )
    Не могу создать хардлинк!
    Array ( )

Вот такие вот сообщения и два пустых массива.

На Windows XP Professional Corporate Edition with Service Pack 2 + Denwer 2.0 хардлинк создаётся. На Windows 2003 Server with Service Pack 3 - нет. Причём, если написать тоже самое в консоли серверной версии Windows (mkdir "F:\tmpfiles\fae72cba8a3bacb8a3b892\", fsutil hardlink create "F:\tmpfiles\fae72cba8a3bacb8a3b892\somefile.mpeg" "F:\archive\somefile.mpeg"), то и директория и линк будут созданы без проблем с сообщением "Hardlink created for D:\temp\link.to.file.avi <<===>> D:\files\file.avi".

В чём же дело? Сперва, нужно проверить не работает ли PHP в безопастном режиме, когда он намерено ограничивает свой функционал. Проявляется это в отказе в работе функций exec(), system(), passthru() и появлении сообщения:
    Warning: SAFE MODE Restriction in effect...

Для этого открываем файл %windir%\php.ini, ищём строку safe_mode = On, и изменяем эту директриву на Off. Затем сохраняем файл и перезагружаем web-сервисы. Радуйтесь, если это поможет!

В противном случае, пытаемся заменить exec() на system(), добавить в самое начало команды start (start mkdir...), попытаться поразному экранировать слеши. Ежели и это бессильно перед вашими проблемами, то вам на следующей абзац.

Else - дело в правах. Кому нужно что раздать? IUSR'y права на чтение папки archive и права на запись в папку tmpfiles? Или на выполнение программы fsutil? Чёрт его знает. Что я только не пробывал. Как не мучался. Оказалось всё гораздо проще!

Нужно было дать права IUSR (Internet Guest Account) на исполнение %windir%/system32/cmd.exe!

Но, если будет сделан только этот шаг, то вы получите следующую ошибку:
    Array ( [0] => The FSUTIL utility requires that you have administrative privileges. )

Поэтому, IUSR нужно наделить урезанными правами администратора.

Если же необходимо создавать ссылки на директории, то можно использовать вот эту программу: http://www.sysinternals.com/Utilities/Junction.html
вверх^ к полной версии понравилось! в evernote


Вы сейчас не можете прокомментировать это сообщение.

Дневник Исполняем жёсткие ссылки | _BAZIL_ - God is Real, unless declared as Integer | Лента друзей _BAZIL_ / Полная версия Добавить в друзья Страницы: раньше»