виртуальный бокс + perl + общая папка == сбой

Это запутанный вопрос, так что потерпите меня. У меня есть сценарий Perl, который находится в гостевой системе Windows VirtualBox. Я хочу вызвать этот скрипт с хоста Linux и заставить его читать общую папку с хоста. Чтение папки не удается.

На хосте я вызываю этот скрипт, и он дает мне следующий результат:

host:~/$ ./script.pl /nfs/nasi/temp
[2014-04-02 10:50:55] Uploading file records to localhost
[2014-04-02 10:50:55] Running VirtualBox for Kaspersky
fatal: opendir(E:\nasi\temp) failed: No such file or directory
[2014-04-02 10:50:56] Uploading malware samples data to localhost
host:$

Скрипт преобразует аргумент /nfs/nasi/temp в E:\nasi\temp и вызывает скрипт с помощью следующей команды:

/usr/bin/VBoxManage guestcontrol <guest> execute \
  --image "C:\strawberry\perl\bin    \perl.exe"   \
  --username <user> --password <pass>              \
  --wait-stdout --wait-stderr --wait-exit --        \
  "C:\antivirus\kaspersky.pl" "E:\nasi\temp"

Когда я запускаю этот же скрипт, используя ту же опцию от гостя напрямую, я получаю следующее:

C:\antivirus>C:\strawberry\perl\bin\perl.exe C:\antivirus\kaspersky.pl E:\nasi\temp
[2014-04-02 10:54:19] Running Kaspersky Antivirus
[2014-04-02 10:54:20] Parsing Kaspersky report
[2014-04-02 10:54:20] Uploading Kaspersky results to 10.0.0.1
C:\antivirus>

Но подождите, дальше будет еще страннее. Когда вместо предоставления общего каталога E:\ я вместо этого указываю ему C:\, у него нет проблем с чтением каталога, и он просто счастливо продолжает работу. Таким образом, ошибка появляется только тогда, когда я запускаю команду с хоста через VirtualBox и указываю ее на общий ресурс.

Вот соответствующий код:

sub createSamplesMap {
    opendir( my $dh, $ARGV[0] ) or
        die "fatal: opendir($ARGV[0]) failed: $!\n";
    my @files = readdir( $dh );
    foreach my $file ( @files ) {
        if (! -d $file ) {
            ...
        }
    }
    closedir($dh);
}

Я пробовал разные способы чтения имен файлов из каталога, но они не работали. Вот что я пробовал.

my @files = <$ARGV[0]\\*>;
my @files = glob( $ARGV[0] . '\\*' );

Я не знаю, виноват ли перл или виртуальный бокс. У кого-нибудь есть идеи, в чем может быть проблема?

  • Windows 7, Strawberry Perl v5.18.2
  • Ubuntu 12.04.04, Перл v5.14.2
  • Виртуалбокс 4.2.16r86992

кросспост: https://forums.virtualbox.org/viewtopic.php?f=2&t=61011


person jurgen    schedule 02.04.2014    source источник
comment
Общие папки VirtualBox делают время от времени меня подводят; иногда я просто копирую файлы из общей папки в c:\temp и работаю с ними там.   -  person Massa    schedule 02.04.2014
comment
К сожалению, на хосте недостаточно места на диске для хранения всех файлов дважды, а копирование значительно замедлит работу. Кроме того, прямо сейчас он всегда терпит неудачу, поэтому должно быть что-то еще, что идет не так, как просто ненадежное программное обеспечение.   -  person jurgen    schedule 02.04.2014
comment
Упростите сценарий и просто попробуйте открыть каталог, указав путь в виде жестко заданной строки. Это покажет, является ли путь нечетным или фактический путь недоступен.   -  person Richard Huxton    schedule 02.04.2014
comment
@Richard Huxton, скрипт работает нормально и, как и ожидалось, при запуске непосредственно из гостя с помощью E:\nasi\test. И он отлично работает с C:\. Так же нормально работает вызов с хоста с C:\. Только при вызове с хоста с помощью E:\nasi\test происходит сбой. Также другое программное обеспечение не может прочитать каталог, cmd.exe /c dir также не может прочитать каталог.   -  person jurgen    schedule 02.04.2014
comment
Итак, папка определенно не читается. Похоже, VirtualBox умен и перехватывает одни системные вызовы, но не другие. Возможно, вы сможете обойти это с помощью одной из библиотек Win32, но первым шагом будет выяснить у людей, занимающихся виртуальными боксами, что именно он делает.   -  person Richard Huxton    schedule 02.04.2014
comment
вы можете сделать еще один диск и разделить его между разными виртуальными машинами; таким образом, вместо E:\ вы бы использовали D:\...   -  person Massa    schedule 02.04.2014
comment
Вы имеете в виду пробел между C:\strawberry\perl\bin и \perl.exe ?   -  person mob    schedule 02.04.2014
comment
Я заметил еще две детали: во-первых, ваш диск E: кажется дважды подключенным к сети (один раз через виртуальный бокс, а другой через NFS, поскольку его путь начинается с / nfs ...). Вы пытались сопоставить его напрямую через NFS внутри машины Windows VB? И во-вторых, вы открываете сеанс и входите в систему со своим пользователем заранее? Потому что, если нет, у вас может не быть подключен диск E: при выполнении вашего сценария guestcontrol! попробуйте увидеть вывод net use внутри вашего скрипта kapersky.pl...   -  person Massa    schedule 02.04.2014
comment
@mob нет, пробел только в посте, я боролся со stackoverflow, он продолжал требовать пробелы для блоков кода   -  person jurgen    schedule 03.04.2014
comment
@massa Я не понимаю ваш первый комментарий о разных виртуальных машинах, мне нужна связь только между 1 виртуальной машиной и ее хостом. И я не думаю, что запуск общей папки на другом томе что-то изменит.   -  person jurgen    schedule 03.04.2014
comment
@massa, ты очень наблюдателен, раз заметил NFS. Да, с точки зрения гостей, это просто общая папка в локальном каталоге на хосте. Но с точки зрения хоста это монтирование NFS. Это необходимо, потому что на хосте нет места на диске для хранения всех файлов. Я пытался напрямую подключить гостевую систему Windows к NFS, что не так-то просто. Я исключил эту часть из обсуждения, потому что она решает только МОЮ проблему доступа к файлам, а не проблему запуска виртуального бокса.   -  person jurgen    schedule 03.04.2014
comment
@massa Я пробовал все комбинации вызова скрипта, которые только мог придумать; Я вошел в систему как тот же пользователь, другой пользователь, вообще не вошел в систему, все. Ничего из этого не сработало. Кроме того, общая папка VirtualBox не является настоящей сетевой папкой CIFS. Таким образом, он виден, когда вы добавляете его с помощью функции «карты сетевого диска» проводника, и после запуска все программы могут получить доступ к диску E, но такие команды, как «net view» и «net use», ничего не видят.   -  person jurgen    schedule 03.04.2014
comment
Вы пытались открыть файл внутри kapersky.pl через имя UNC? как \\vboxsrv\sharedfoldername ?? я говорю о разных виртуальных машинах, потому что вы сказали, что на машине нет места на диске для хранения файлов дважды, но теперь я понимаю, что вы имеете в виду... Как вы сказали, общая папка не является настоящим сетевым ресурсом CIFS, и это почему ваш скрипт его не видит. Мое предложение попытаться подключить виртуальную машину Windows напрямую к общему ресурсу NFS - лучшее предложение, которое у меня есть на данный момент... :(   -  person Massa    schedule 03.04.2014
comment
@massa Да, я почти отказался от попыток заставить общую папку работать, пока не наткнулся на сообщение в блоге, о котором я упоминал в ответе ниже. Заставить NFS хорошо работать в Windows не так просто, особенно потому, что у меня нет доступа к серверу NFS (и параметрам конфигурации, и Windows Professional, и настройкам реестра, и настройкам брандмауэра, и NAT, пфффф). К счастью, теперь он работает так, как изначально предполагалось и хотелось :)   -  person jurgen    schedule 03.04.2014


Ответы (1)


Я нашел проблему. Как упоминалось на форуме виртуального бокса, возникла проблема с набором переменных среды при запуске сценария Perl. После долгих поисков я также нашел сообщение в блоге от kissmyarch где он описывает, как решил проблему.

Вы можете установить переменные среды, используя параметр --environment в VBoxManage guestcontrol, и, согласно kissmyarch, вам нужно установить USERPROFILE, чтобы заставить его работать. Это не сработало для меня.

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

foreach $key (sort keys(%ENV)) {
  print "$key = $ENV{$key}\n";
}

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

/usr/bin/VBoxManage guestcontrol <vm> execute \
   --image "C:\strawberry\perl\bin\perl.exe" \
   --username <user> --password <pass> \
   --environment "USERPROFILE=C:\Users\<user>" \
   --environment "APPDATA=C:\Users\<user>\AppData\Roaming" \
   --environment "LOCALAPPDATA=C:\Users\<user>\AppData\Local" \
   --environment "HOMEDRIVE=C:" \
   --environment "HOMEPATH=\Users\<user>" \
   --environment "LOGONSERVER=\\\<server>" \
   --environment "SESSIONNAME=Console" \
   --environment "TEMP=C:\Users\<user>\AppData\Local\Temp" \
   --environment "TMP=C:\Users\<user>\AppData\Local\Temp" \
   --environment "USERDOMAIN=<domain>" \
   --environment "USERNAME=<user>" \
   --wait-stdout --wait-stderr --wait-exit \
   -- "C:\antivirus\kaspersky.pl" "E:\nasi\temp"

Где-то в этой большой куче переменных окружения есть одна важная.

Спасибо всем, кто помог.

person jurgen    schedule 03.04.2014