Перемещение файлов подкачки в отдельный раздел в Snow Leopard

27022
e.James

До сих пор я мог перемещать файлы подкачки виртуальной памяти Apple в выделенный раздел на моем жестком диске. Техника, которую я использовал, описана в теме на forums.macosxhints.com.

Однако с предварительной версией Snow Leopard для разработчиков этот метод больше не работает. Кто-нибудь знает, как это можно сделать с новой ОС?

Обновление: я отметил ответ dblu как принятый, хотя он не вполне сработал, потому что он дал превосходные, подробные инструкции и потому что его предложение использовать в plutilконечном итоге указало мне правильное направление. Полное, рабочее решение размещено здесь в вопросе, потому что у меня недостаточно репутации, чтобы редактировать принятый ответ.

Обновление № 2: Изменена процедура, чтобы проиллюстрировать технику ekl, что значительно упрощает все это, устраняя необходимость в промежуточном сценарии оболочки:

Комплексное решение:

1. Откройте Терминал и создайте резервную копию динамического списка Apple_pager.plist по умолчанию:

$ cd /System/Library/LaunchDaemons $ sudo cp com.apple.dynamic_pager.plist{,_bak} 

2. Преобразуйте plist из двоичного в простой XML:

$ sudo plutil -convert xml1 com.apple.dynamic_pager.plist 

3. Откройте преобразованный список с помощью вашего текстового редактора. (Я использую pico, см. Ответ dblu для примера использования vim):

$ sudo pico -w com.apple.dynamic_pager.plist 

Это должно выглядеть следующим образом:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs$ <plist version="1.0"> <dict> <key>EnableTransactions</key> <true/> <key>HopefullyExitsLast</key> <true/> <key>Label</key> <string>com.apple.dynamic_pager</string> <key>OnDemand</key> <false/> <key>ProgramArguments</key> <array> <string>/sbin/dynamic_pager</string> <string>-F</string> <string>/private/var/vm/swapfile</string> </array> </dict> </plist> 

4. Измените массив ProgramArguments (строки с 13 по 18), чтобы использовать команду оболочки wait4path (как предложено ZILjr ) до запуска dynamic_pager. См. Примечание № 1 для получения подробной информации о том, почему это необходимо. В следующем примере мой раздел называется «Swap», и я решил поместить файлы подкачки в скрытый каталог этого раздела с именем «.vm», чтобы убедиться, что указанный вами каталог действительно существует . XML должен выглядеть следующим образом:

<key>ProgramArguments</key> <array> <string>/bin/bash</string> <string>-c</string> <string>/bin/wait4path /Volumes/Swap/ &amp;&amp; /sbin/dynamic_pager -F /Volumes/Swap/.vm/swapfile</string> </array> 

5. Сохраните plist и вернитесь к терминалу. Используя pico, команды будут:

<ctrl+o> to save the file <enter> to accept the same filename (com.apple.dynamic_pager.plist) <ctrl+x> to exit 

6. Преобразовать измененный plist обратно в двоичный файл:

$ sudo plutil -convert binary1 com.apple.dynamic_pager.plist 

7.Перезагрузите ваш Mac. Если у вас возникли проблемы, переключитесь в подробный режим запуска, удерживая Command-v сразу после запуска. Это позволит вам увидеть все сообщения при запуске, которые появляются во время запуска. Если вы столкнетесь с еще более серьезными проблемами (т.е. вы никогда не увидите экран входа в систему), вместо этого удерживайте Command-s. Это загрузит компьютер в однопользовательском режиме (без графического интерфейса, просто командная строка) и позволит вам восстановить резервную копию com.apple.dynamic_pager.plist, созданную на шаге 1.

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

$ cd /Volumes/Swap/.vm $ ls -l 

Вы должны увидеть что-то вроде этого:

-rw------- 1 someUser staff 67108864 18 Sep 12:02 swapfile0 

9. Удалить старые файлы подкачки:

$ cd /private/var/vm $ sudo rm swapfile* 

10. Прибыль!

Примечание 1

Изменение аргументов для dynamic_pager в plist без использования wait4pathне всегда работает, а когда происходит сбой, это происходит невероятно тихо. Проблема связана с тем, что dynamic_pager запускается очень рано в процессе запуска. Если ваш раздел подкачки еще не был смонтирован при первой загрузке dynamic_pager (по моему опыту, это происходит в 99% случаев), тогда система будет фальсифицирована. Он создаст символическую ссылку в вашем каталоге / Volumes, имя которой совпадает с именем вашего раздела подкачки, но указывает на расположение файла подкачки по умолчанию (/ private / var / vm). Затем, когда ваш текущий раздел подкачки монтируется, ему будет присвоено имя Swap 1(или YourDriveName 1). Вы можете увидеть проблему, открыв Терминал и перечислив содержимое вашего каталога / Volumes:

$ cd /Volumes $ ls -l 

Вы увидите что-то вроде этого:

drwxrwxrwx 11 yourUser staff 442 16 Sep 12:13 Swap -> private/var/vm drwxrwxrwx 14 yourUser staff 5 16 Sep 12:13 Swap 1  lrwxr-xr-x 1 root admin 1 17 Sep 12:01 System -> / 

Обратите внимание, что этот сбой может быть очень трудно обнаружить. Если бы вы проверили файлы подкачки, как я покажу в шаге 12, вы все равно бы их увидели ! Символическая ссылка создаст впечатление, что ваши файлы подкачки были перемещены, даже если они на самом деле хранятся в расположении по умолчанию.

Заметка 2

Первоначально я не смог заставить это работать в Snow Leopard, потому что com.apple.dynamic_pager.plist хранился в двоичном формате. Я сделал копию исходного файла и открыл его с помощью редактора списков свойств Apple (доступного с Xcode), чтобы внести изменения, но этот процесс добавил некоторые расширенные атрибуты в файл plist, которые заставили систему игнорировать его и просто использовать значения по умолчанию, Как указал dblu, использование plutilдля преобразования файла в обычный XML работает как шарм.

Заметка 3

Вы можете проверить консольное приложение, чтобы увидеть любые сообщения, которые dynamic_pager_init выводят на экран. Если вы видите, что следующие строки повторяются снова и снова, есть проблема с настройкой. Я столкнулся с этими сообщениями, потому что я забыл создать каталог .vm, который я указал в dynamic_pager_init.

com.apple.launchd[1] (com.apple.dynamic_pager[176]) Exited with exit code: 1 com.apple.launchd[1] (com.apple.dynamic_pager) Throttling respawn: Will start in 10 seconds 

Когда все работает должным образом, вы можете увидеть вышеупомянутое сообщение только пару раз, и тогда больше не будет сообщений «Возобновление дросселирования». Это означает, что система должна была ждать загрузки раздела, но в итоге она прошла успешно.

30
Мне действительно любопытно, почему вы хотели бы сделать это? BinaryMisfit 14 лет назад 0
Для небольшого прироста производительности. Мне нравится хранить разделы жесткого диска в соответствии с их использованием. У меня есть один раздел для ОС и приложений, один для папки пользователя, один для документов, один для медиа (музыка, фильмы и т. Д.) И один для файлов подкачки. По моему опыту, хранение файлов подкачки отдельно от остальной системы снижает фрагментацию диска. Я предпочел бы иметь своп на выделенном диске, но обычно достаточно другого раздела. e.James 14 лет назад 0
Достаточно справедливо - однако разделы на одном диске фактически требуют больше работы для самого диска, однако разделы на разных дисках обеспечивают выигрыш в производительности. Жесткий диск должен выполнять больше работы при переходе между разделами на одном диске. Я спрашиваю только потому, что у меня еще не было проблем с фрагментацией и производительностью на моем Mac после почти 2 лет использования, и когда я вижу эти сообщения, они меня интересуют. BinaryMisfit 14 лет назад 4
Я склонен работать на своей машине довольно усердно; разделение между разработкой Какао, 3D рендерингом и работой в Photoshop, и немного случайных игр, когда у меня есть время. Я, возможно, немного * слишком * обеспокоен крошечными проблемами с производительностью, но я провожу так много времени, сидя перед машиной, что стал к ним чувствителен :) e.James 14 лет назад 0
Снежный барс все еще находится под NDA до 28го числа. Все предварительные версии для разработчиков также находятся под NDA. Chealion 14 лет назад 0
Я полагаю, ты прав. Возможно, поэтому здесь нет ответов. Я надеюсь, что у вас будет один для меня в конце месяца :) e.James 14 лет назад 0
Я не уверен, почему я не могу опубликовать ответ _ (** 101 ** повторение, которое - если я помню свои математические вычисления - больше, чем ** 10 **, которого требует защищенное состояние) _, но я нашел решение, не относящееся к `wait4path`, благодаря тому, что Xupport Applicorn изменил для меня. Я опубликую полный ответ, как только выясню, как это сделать, но если коротко, то нужно заменить последний аргумент программы просто новым путем (например, `/Volumes/swap/.vm/swapfile`), измените ключ` OnDemand` на ``, и добавьте ключ` StartOnMount` в конец со значением ``. _P.S. Это решение отлично работает в Lion (для меня, по крайней мере) ._ Slipp D. Thompson 12 лет назад 1
@Slipp Дуглас: Выглядит законно для меня. Флаг `StartOnMount` был добавлен в 10.5 в соответствии с: http://www.mactech.com/articles/mactech/Vol.25/25.10/2510MacEnterprise-SnowLeopard-launchdandLunch/index.html e.James 11 лет назад 1
Гораздо более простым способом было бы удалить папку / private / var / vm и создать ссылку на том, где вы хотите их сохранить. Вот как я это делаю. Laurent Crivello 11 лет назад 0
@ LaurentCrivello: Это интригующая идея, но вы уверены, что она действительно работает? (подробности см. в моей заметке # 1) dynamic_pager имеет тенденцию молча возвращаться к использованию / private / var / vm, если целевой раздел еще не был смонтирован. Я не уверен на 100%, как работают символические ссылки в этих условиях. e.James 11 лет назад 0
@ e.James: Так я работаю уже неделю, и мои дисковые пространства полностью исчезли. Файл swp отправляется на 2-ой внутренний диск моей машины (не на загрузочный раздел), возможно, именно поэтому он монтируется с самого начала ... Laurent Crivello 11 лет назад 0
Перекрестная ссылка на аналогичный вопрос вступительного плаката в «Разное»: [Как я могу переместить файлы подкачки виртуальной памяти на другой диск или раздел?] (Http://apple.stackexchange.com/q/1465/8546) (2010-09 -12) Graham Perrin 10 лет назад 0

8 ответов на вопрос

10
dblu

ПРИМЕЧАНИЕ . См. (Также) исправленный / улучшенный ответ в самом вопросе.


Следующее решение сработало для меня:

Откройте терминал и создайте резервную копию com.apple.dynamic_pager.plist, который вы собираетесь изменить за секунду:

$ cd / System / Library / LaunchDaemons $ sudo cp com.apple.dynamic_pager.plist {, _ bak}

преобразовать двоичный plist в xml:

$ sudo plutil -convert xml1 com.apple.dynamic_pager.plist

и откройте его в вашем любимом текстовом редакторе

$ sudo vim com.apple.dynamic_pager.plist

это будет выглядеть примерно так:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 <plist version="1.0"> 4 <dict> 5 <key>EnableTransactions</key> 6 <true/> 7 <key>HopefullyExitsLast</key> 8 <true/> 9 <key>Label</key> 10 <string>com.apple.dynamic_pager</string> 11 <key>OnDemand</key> 12 <false/> 13 <key>ProgramArguments</key> 14 <array> 15 <string>/sbin/dynamic_pager</string> 16 <string>-F</string> 17 <string>/private/var/vm/swapfile</string> 18 </array> 19 </dict> 20 </plist> 

В строке 17 измените / private / var / vm / swapfile (например, / Volumes / partition2 / swapfile), сохраните и закройте ваш редактор (": x" сделает оба в vim).

преобразовать файл plist обратно в двоичный файл:

$ sudo plutil -convert binary1 com.apple.dynamic_pager.plist

После перезагрузки Mac вы должны найти файлы подкачки в указанном вами каталоге.

Если у вас возникнут какие-либо проблемы, вы можете восстановить резервную копию, созданную на первом шаге, с помощью:

$ cd / System / Library / LaunchDaemons $ sudo cp com.apple.dynamic_pager.plist 
Вы уверены, что файл подкачки * фактически * перемещается в раздел с этой настройкой? Когда я впервые попробовал этот подход, динамический_пейджер загружался до монтирования вторичных разделов. Система подделает свой путь, создав символическую ссылку на partition2 в каталоге / Volumes, которая просто указывает на / private / var / vm. Вы можете определить ошибку, выполнив команду ls -al в каталоге / Volumes, где вы увидите и «partition2» (символическая ссылка), и «partition2 1» (ваш фактический раздел). e.James 14 лет назад 0
В любом случае, +1 за метод преобразования файлов plist в двоичный формат. com.apple.dynamic_pager.plist был в текстовом формате в 10.5.x, но в двоичном формате по состоянию на 10.6. Что является частью моей проблемы. Я изменял plist-файлы с помощью приложения Property List Editor, которое поставляется с Xcode, и, возможно, именно поэтому все не работает. Я попробую Плутиль и посмотрю, получится ли это дальше. e.James 14 лет назад 0
На данный момент я не могу протестировать его с другим разделом, однако во время тестов я создал dynamic_pager, создающий файлы подкачки на флэш-накопителе, используя вышеописанную технику. dblu 14 лет назад 0
Я смог заставить работать оригинальную технику, благодаря вашему предложению использовать `plutil` для преобразований. Я разместил полное решение в вопросе (так как у меня недостаточно представителей, чтобы добавить его к вашему ответу). См. Мою заметку № 1 для подробного описания проблем, с которыми я столкнулся, просто изменив список. e.James 14 лет назад 0
В любом случае, спасибо за ответ. Вы составили отличный набор инструкций, и вы указали мне правильное направление, поэтому я отметил это как принятое. Ура! :) e.James 14 лет назад 0
На более новых версиях OS X _ (10.10, но не 10.8, неуверенно около 10.9) _, com.apple.dynamic_pager.plist` в стандартной установке в формате XML - обе строки sudo plutil -convert… не нужны. Slipp D. Thompson 9 лет назад 0
3

Я принял эту идею и развил ее немного дальше, рассматривая стратегии роста и освоения.

Подробности на http://www.crypticide.com/dropsafe/article/3848 ; Я бы опубликовал ссылку на страницу проекта GoogleCode "dynamicpagerwrapper", но в блоге говорится, что у меня недостаточно очков репутации ...

+1 Отличный материал! Я пробую это прямо сейчас. Вот ссылка на проект GoogleCode: http://code.google.com/p/dynamicpagerwrapper/ e.James 14 лет назад 1
убедитесь, что вы используете как минимум версию 8 скрипта: http://code.google.com/p/dynamicpagerwrapper/source/browse/trunk/dynamic_pager_wrapper 14 лет назад 0
3
ekl

просто вопрос: почему бы просто не отредактировать добавление файла .plist wait4pathвместо использования промежуточного dynamic_pager_init?

что-то вроде этого:

РЕДАКТИРОВАТЬ: как объяснено в комментарии e.James и моем следующем комментарии, сразу следующий блок XML не годится, и потому, что есть ошибка (отсутствует &&), и потому что только первый аргумент массива ProgramArguments анализируется как программа для запуска !

но .. (прокрутите вниз)

 ... 13 <key>ProgramArguments</key> 14 <array> 15 <string>/bin/wait4path</string> 16 <string>/Volumes/Swap/</string> 17 <string>/sbin/dynamic_pager</string> 18 <string>-F</string> 19 <string>/Volumes/Swap/.vm/swapfile</string> 20 </array> ... 

конец неправильного блока xml


этот блок XML должен работать вместо:

 ... 13 <key>ProgramArguments</key> 14 <array> 15 <string>/bin/bash</string> 16 <string>-c</string> 17 <string>/bin/wait4path /Volumes/Swap/ &amp;&amp; /sbin/dynamic_pager -F /Volumes/Swap/.vm/swapfile</string> 18 </array> ... 

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

Как это устроено:

base: executing wait4path /path && commandозначает, что commandзапускается, только если wait4pathзаканчивается и завершается без ошибок, и это происходит только тогда, когда /pathесть доступный путь, поэтому мы можем с уверенностью сказать, dynamic_pagerиспользовать этот том для файлов подкачки

1) как написано в launchd.plistmanpage, ключи Programи ProgramArgumentsотображаются на execvpвызов, это означает, что все, кроме первой строки в массиве, рассматривается как аргумент для первой строки в массиве, запускаемой программы;

2) как написано в bashmanpage, есть bash -c <string>опция для запуска строки, переданной как команды

1 + 2 = 3) что происходит с использованием этой командной строки в launchd plist ??

/bin/bash -c "wait4path /Volumes/Swap/ && /sbin/dynamic_pager -F /Volumes/Swap/.vm/swapfile"

/bin/bashзапускаемая программа, -cпервый аргумент и строка в двойных кавычках второй аргумент

Я предполагаю, что оно должно работать точно так же, как ваше решение, без промежуточного скрипта: launchdзапустит сервис, который будет ждать заданного пути, а затем запустит dynamic_pager..

Обратите внимание, что:
* строка, которую вы хотите выполнить, должна быть заключена в двойные кавычки, если вы запускаете bash -cв Terminal, но это не двойные кавычки в файле plist! (я думаю, потому что это уже объявлено как строка с соответствующим тегом)
* два &в строке должны быть изменены &amp;в файл plist

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

спасибо, что поделились с нами своей работой

Это интересная идея. Я не уверен, допустимо ли помещать в массив ProgramArguments более одной программы, но это, безусловно, стоит того. Вы пробовали это? e.James 13 лет назад 0
Извините, в моем предыдущем посте произошла ошибка, моя идея состояла в том, чтобы запустить следующую командную строку (обратите внимание на отсутствующий &&): wait4path / Volumes / Swap / && / sbin / dynamic_pager -F /Volumes/Swap/.vm/swapfile если кто-то найдет способ «отформатировать» эту строку так, чтобы launchd понравился, думаю, это должно сработать (я подумываю над этим, возможно, вызывая / bin / bash, передавая остальное в качестве аргументов?); дополнительные пояснения к полям Program и ProgramArguments доступны на man-странице launchd.plist, и это приведет к man-странице execvp (3). Я читаю и думаю, если кто-то быстрее, пожалуйста, напишите :) ekl 13 лет назад 0
я отредактировал предыдущее сообщение с решением, которое должно работать, пожалуйста, прокомментируйте, если вы видите какую-либо ошибку или что-то еще, что может не работать должным образом, спасибо! ekl 13 лет назад 0
Я попробовал это на своем ноутбуке, и это, кажется, работает. Я буду следить за этим в течение нескольких дней, чтобы убедиться, но похоже, что вы упростили весь процесс безмерно! Хорошая работа `:)` e.James 13 лет назад 0
Ваш упрощенный метод работает как шарм на моем ноутбуке. Спасибо! Я обновлю основной вопрос, чтобы включить ваше решение. e.James 13 лет назад 0
2
Michael Spurlock

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

Я использовал описанный выше трюк, чтобы переместить мои файлы подкачки на другой внутренний диск (мой загрузочный диск - SSD с микросхемами MLC, поэтому отключение vm может сохранить ожидаемый срок службы). В любом случае, после создания нового тома у меня был том Swap в Finder, который я никогда не собираюсь использовать в самом Finder, поэтому я решил сделать том невидимым для Finder. Вам нужно установить Apple Developer Toolkit. Затем введите:

/Developer/Tools/SetFile -a V /Volumes/Swap/ 

… И замените / Volumes / Swap на то, что вы назвали своим томом. Перезапустите Finder и нажмите «Престо», больше не меняйте громкость в Finder!

1
ZILjr

Вы можете использовать wait4path для ожидания монтирования тома; в противном случае launchd будет перезапускать ваш скрипт dynamic_pager_init снова и снова, пока не произойдет ...

Brilliant! Я использовал `wait4path` вместо комбинации` if` / `grep`, и это довольно просто. Спасибо за совет. e.James 14 лет назад 0
1

Может быть, мы можем использовать Xupport, чтобы сделать эту грязную работу для нас :) http://www.applicorn.com/

Оптимизатор виртуальной памяти:

Изменение расположения файлов подкачки В Mac OS X информация о виртуальной памяти хранится в так называемых «файлах подкачки». Поскольку файлы подкачки являются наиболее интерактивными системными файлами, имеет смысл поместить их в отдельный раздел. Рекомендуется хранить файлы подкачки в первом разделе вашего самого быстрого внутреннего жесткого диска. Рекомендуемый минимальный размер раздела должен быть примерно в 3 или 4 раза больше размера физической встроенной памяти (например, 1 ГБ физической памяти = 4 ГБ раздела подкачки). Рекомендации и инструкции по оптимальной производительности системы:

1. Переразделите жесткий диск разделом подкачки как ПЕРВЫЙ раздел (используя установочный DVD Mac OS X). ВНИМАНИЕ: ПЕРЕЗАГРУЗКА ЖЕСТКОГО ДИСКА БУДЕТ УДАЛИТЬ ВСЕ СУЩЕСТВУЮЩИЕ ДАННЫЕ!

2. Восстановите системные данные или установите новую систему в системный раздел.

3. Загрузиться с системного раздела.

4. Если вы хотите, чтобы ваш том подкачки был невидим для Finder: • Запустите Xupport и выберите «Настройки» • Включите «Показать скрытые файлы и папки» и перезапустите Finder • Переименуйте том подкачки с «swap» на «.swap» (Точка делает его невидимым для Finder) • Отключите «Показать скрытые файлы и папки» и перезапустите Finder снова

5. Выберите новый раздел подкачки в разделе «Том хранилища подкачки». Затем нажмите кнопку «Установить», чтобы применить новые параметры расположения файла подкачки (требуется перезагрузка).

Кстати, это работает для меня. Snow Leopard 10.6.2 @ Macbook Pro 2,4 ГГц, 4 ГБ оперативной памяти, 500 ГБ HD

Выглядит многообещающе. Спасибо за ссылку и подробные инструкции! e.James 14 лет назад 0
http://www.applicorn.com/ - 404 pkoch 12 лет назад 0
1
cregox

Скорее всего, это нежелательный ответ (поскольку я не могу комментировать после Diago), но почему вы действительно настаиваете, что это даст небольшой прирост производительности? Я прошел обсуждение на яблочных форумах и пришел к выводу, что это не очень хорошая идея. И я очень сопротивлялся, отказываясь от него. Не могли бы вы представить данные, доказывающие это хотя бы для себя, или это просто «чувство»?

С тех пор, как я использовал swap даже в Linux, 10 лет назад, а в настоящее время в Ubuntu, я никогда не видел улучшений в производительности. Моя причина этого была в том, чтобы предотвратить проблемы со свободным пространством в OSX и в Linux для возможности перехода в спящий режим. Это все обмен для меня.

Но я никогда не проводил более глубоких исследований ни самостоятельно, ни в сети.

Это действительная критика. У меня нет данных, подтверждающих мои претензии :) e.James 14 лет назад 0
Здорово. Так что, в конце концов, вы можете перестать переживать все эти неприятности! :П cregox 14 лет назад 0
1
Jesse

Это не ответ, но, возможно, очень полезное дополнение. Apple предоставляет бесплатный редактор списков рассылки PlistEdit Pro . Это позволяет вам безопасно редактировать эти файлы. Похоже, вы могли бы просто изменить аргумент со значением / private / var / vm / swapfile на что-то вроде / Volumes / OtherDrive / vm / myswapfilename, чтобы переместить файлы подкачки куда-то еще ...

Опять я не проверял это ...

Это хорошая мысль, и первое, с чего я начал, когда шел по этому маршруту. Проблема в том, что раздел подкачки не всегда монтируется в тот момент, когда запускается динамический пейджер. См. Примечание № 1 в самом вопросе для деталей о том, что я имею в виду. e.James 13 лет назад 0

Похожие вопросы