Когда-то недавно написал я, вроде неплохую, статью про то как к компьютеру прикрутить две клавиатуры, две мышки, два монитора и заставить все это работать независимо для двух разных пользователей.
Под катом русскоязычный вариант статья. English version
here В данной статье рассматривается реализация multiseat на базе Ubuntu 10.04 LTS с аппаратным ускорением. Пример, рассмотренный в этой статье, уже введен в эксплуатацию и работает около полугода в обычном Минском офисе. Описываются проблемы реализации и внедрения готовой системы в работу с точки зрения обычного студента-электроприводчика, который подрабатывает на полставки системным администратором.
Вступление
Вот время работы системным администратором в небольшом офисе при обновлении парка компьютеров появилась небольшая проблема. Современные компьютеры дают уровень производительности, много превосходящий необходимый для офисных компьютеров. Причем реалии рынка таковы, что различия в производительности мало сказываются на цене. И вроде бы дешевые компьютеры на базе Atom по ценовому признаку практически не отличаются от более производительных компьютеров на базе обычных процессоров Amd и Intel (материнская плата с процессором Atom стоит около 100-150 у.е. на май 2010 года, Минск, и та же цена на октябрь 2010 в том же Минске).
Та же ситуация и с жесткими дисками: для офисной работы нет необходимости в объеме диска более 40-80 Гб. Но на рынке такие жесткие диски уже практически не представлены. На момент написания статьи в продаже были жесткие диски емкостью 160 Гб (38$), 250 Гб (39$), 320 Гб (40$), 500 Гб (41$), дальше различия по ценам заметны сильнее. Цена за гигабайт жестких дисков малого объема довольно высока. Та же ситуация и со всеми остальными комплектующими.
Возникает закономерный вопрос, как рационально все это использовать? Давайте подойдем логически - чтобы удешевить систему можно либо купить комплектующие похуже (не сильно удешевляет), либо отказаться от некоторых комплектующих. По сути, в рабочем месте обязательными являются устройства ввода (клавиатура, мышь, планшет и т.д.) и устройства отображения информации (монитор, проектор и т.д.). Остальная часть системы пользователей особо не касается, и от нее можно избавляться. Безусловно, от всего избавиться не получится. Давайте заглянем под крышку системного блока. Тут мы обязательно видим материнскую плату, видеокарту (может быть уже на материнской плате), процессор (тоже может быть на материнской плате) и память. А вот остальные комплектующие уже не так важны. Оптический привод мало востребован, и поэтому его, скорее всего, не будет.
С жестким диском тоже интересная ситуация. Его может и не быть, тогда у нас будет так называемая бездисковая станция. Тут вся информация загружается по сети с сервера (реализация PXE+NFS и немного бубна). Но хочется чего-то большего.
Тогда и возникла идея подключить к одному компьютеру две клавиатуры, две мыши и два монитора и заставить их работать независимо. В зарубежных источниках такие системы называются
multiseat.
Но можно на этом и не ограничиваться, а делать бездисковую multiseat-станцию. Этот вариант отлично подойдет для пары multiseat-станций с сервером. В данной статье не рассматривается.
Давайте более пристально взглянем на multiseat. Чтобы подключить нужное нам количество клавиатур и мышек нам придется воспользоваться портами USB. Сейчас это не проблема. Для подключения нескольких мониторов нам надо либо несколько портов на видеокарте, либо несколько видеокарт, либо скомбинировать эти варианты.
После настройки всего этого у нас должно получится нужное нам количество рабочих мест, способных удовлетворить все потребности пользователей. Процессорное время и память делится между этими пользователями, а ситуация, когда всем пользователям одновременно понадобиться вся производительность системы, очень редка.
На первый взгляд получается очень выгодная система. Но почему же тогда про такие системы мало кто слышал? Ответ довольно прост - настройка таких систем довольно сложна. И далеко не каждый администратор (даже проффи) сможет собрать все эти комплектующие вместе и заставить их работать.
Варианты реализации
Давайте попробуем начать реализовывать такую систему. Начнем с выбора операционной системы. Multiseat можно построить на базе современных ОС: Linux, Windows и, возможно, других.
Сразу же интересный для многих вариант на базе ОС Windows на деле непрактичен. Во-первых, лицензия запрещает устанавливать одну копию Windows в такие системы, поэтому требуется покупка двух лицензий, что сразу же убивает многие плюсы, в том числе и экономию средств. Во-вторых, сделать такую систему самому весьма проблематично, т.к. надо писать или покупать дополнительно ПО. По цене этот вариант приближается к варианту покупки двух независимых компьютеров, а то и превышает его. Такой вариант рассмотрен
здесь. У него есть и преимущества - вам не надо много думать и делать. Все уже готово, только ставим софт и получаем результат.
Второй вариант - multiseat на базе Linux - имеет множество решений. Среди них можно выделить как решение без аппаратного ускорения (XGL, Xephyr, Xnest и т.д.), так и с аппаратным ускорением (xorg). В данной статье описывается реализация multiseat с аппаратным ускорение на базе Ubuntu Linux 10.04 LTS.
Система получается довольно гибкой и может работать с любым количеством мониторов. В теории на каждой из видеокарт запускается по собственному графическому X-серверу. Дальше каждый сервер запускает себе среду графического стола (Gnome, KDE и т.д.) .... profit :). Поэтому ПК, на котором будет базироваться multiseat-система должен обладать необходимым количеством видеокарт.
По сути, ядро Linux берет на себя все функции распределения аппаратных ресурсов. Графические сервера берут в свое полное использование видеокарты и уже от ядра Linux получают процессорное время.
Реализация
А теперь перейдем к практике. Как ни странно, она отличается от теории. В моем случае система представляла собой материнскую плату ASUS M3A78-CM со встроенной видеокартой ATI Radeon 3100. Была докуплена вторая видеокарта ATI Radeon 2600 и установлена в единственный слот PCI Express 16x. Установить больше видеокарт не проблема, проблема достать видеокарты PCI Express 1x. Но есть замечательное
решение. Следующий шаг: убедиться, что две видеокарты работают одновременно. Предполагается, что в этот момент у вас уже установлена операционная система Linux, где есть отличная консольная команда lspci, которая показывается все pci-устройства в вашей системе. Чтобы ограничится устройствами, в которых присутствует слово VGA можно сделать вот такую конструкцию: lspci | grep VGA. В моем случае картина была такова:
andrey@k211-multiseat:~$ lspci | grep VGA
01:05.0 VGA compatible controller: ATI Technologies Inc Radeon 3100 Graphics
02:00.0 VGA compatible controller: ATI Technologies Inc RV630 [Radeon HD 2600 Series]
Тут мы и видим наши две видеокарты. Конечно, появились они здесь не сразу. Пришлось пару раз залезть в BIOS и поменять настройки. Результат оправдал ожидания.
Дальше, по инерции, был установлен проприетарный драйвер ATI. Эта была очень грубая ошибка. Но я понял об этом позже. И вам расскажу тоже позже :).
Теперь еще немного теории. Рассмотрим, как загружается система. До момента загрузки дисплейного менеджера (GDM, KDM и т.д.) происходит много всего, но это останется за рамками данной статьи. Как только дисплейный менеджер загрузился, он потребует от вас ввести имя пользователя и пароль (или не потребует, если вы его так настроили). И дальше он запускает Xorg-сервер и выбранную вами рабочую среду. Если его хорошо попросить, то он может запустить и несколько Xorg-серверов с разными настройками и для разных пользователей и, по желанию, с разными менеджерами рабочего стола.
Настройка KDM
А теперь к практике. Некоторые дисплейные менеджеры очень сложно уговорить и надо их даже патчить (GDM), поэтому выбираем KDM, который более сговорчивый. По умолчанию он в системе не установлен. Установка решается простой командой в консоли: sudo apt-get install kdm. Соглашаемся и ждем. Если все успешно, KDM установлен. Теперь начнем его уговаривать :). Файл, отвечающий за настройку менеджера, находится в /etc/kde4/kdm и называется kdmrc. В нем очень много настроек, но нас интересует всего пара. В секции [General] меняем два параметра таким образом:
[General]
StaticServers=:0,:1
ReserveServers=:2,:3
Это значит, что KDM будет запускать сервера 0 и 1 , а сервера 2 и 3 не будет трогать. Дальше ищем секцию [X-:0-Core] и меняем в ней настройку таким образом:
[X-:0-Core]
ServerAttempts=2
ServerArgsLocal= -br -nolisten tcp -layout seat1 -isolateDevice PCI:2:0:0 vt6
AutoLoginEnable=true
AutoLoginUser=alexandr
Первый параметр ServerAttempts=2, возможно, ни на что не влияет, он появился путем долго стучания в бубен и попыток запустить систему. Как говорится, так сложилось исторически :).
Самый важный параметр - это следующий, ServerArgsLocal= -br -nolisten tcp -layout seat1 -isolateDevice PCI:2:0:0 vt6. Рассмотрим его. Это аргументы запуска графического сервера Xorg. Давайте рассмотрим их:
-br - вместо серого узора будет черный фон. Так немного красивее.
-nolisten tcp - эта опция говорит о том, что не надо использовать tcp/ip для работы, или что сервер запускается локально.
-layout seat1 говорит, какую конфигурацию следует использовать из файла xorg.conf (о нем позже).
-isolateDevice PCI:2:0:0 - главная опция, просит сервер использовать только одну видеокарту, которая PCI:2:0:0.
vt6 показывает, что сервер запустится на шестом виртуальном терминале.
Следующая опция (AutoLoginEnable=true) включает автоматический вход в систему под пользователем AutoLoginUser=alexandr. Не забудьте ее поменять на имя вашего пользователя :).
Дальше модифицируем файл таким образом:
[X-:1-Core]
ServerAttempts=2
ServerArgsLocal= -br -nolisten tcp -layout seat0 -sharevts -novtswitch -isolateDevice PCI:1:5:0 vt5
AutoLoginEnable=true
AutoLoginUser=andrey
Почти со всем опциями мы уже знакомы. Обращаю внимание на -layout seat0. Это уже другая конфигурация seat0 из файла xorg.conf. Двух одинаковых конфигураций быть не может, т.к. ничего не будет работать. Также сменилось и устройство -isolateDevice PCI:1:5:0 и виртуальный терминал vt5. Опция -sharevts заставляет сервера работать одновременно на одном терминале, а -novtswitch запрещает сменять текущий терминал нажатием клавиш Ctrl+Alt + n, где n - номер виртуального терминала. Более подробно об опциях запуска х-сервера можно узнать из консоли (man xserver). Далее следует параметр включения автологина и указано имя пользователя (andrey).
Да, и не забудьте создать двух пользователей. Сделать это можно командой в консоли ADDUSER. Там же есть и графическая оболочка. На первый запуск следует отключить опцию автологина, чтобы можно было выбрать графическую среду вручную .
Есть еще один важный момент. Наверное вы уже обратили внимание, что используются виртуальные терминалы 5 и 6, а не 7, который идет по умолчанию для xorg-сервера. Это связано с тем, что если на клавиатуре второго рабочего места нажать комбинацию клавиш Ctrl+c (довольно распространенная комбинация), то xorg на vt7 падает. Очень неприятная особенность. Но решается простым смешением xorg с vt7 на любой другой vt.
Настройка xorg.conf
Приступим теперь к основной конфигурации, а именно зададим те самые seat0 и seat1. Для этого нам понадобится файл /etc/X11/xorg.conf, которого у вас может и не быть, но его можно создать. Пишем в него такие строчки:
Section "ServerLayout"
Identifier "seat0"
Screen 0 "Screen0" 0 0
InputDevice "Mouse0" "CorePointer"
InputDevice "Keyboard0" "CoreKeyboard"
EndSection
Это значит, что мы определили профиль seat0 экраном Screen0, мышкой Mouse0 и клавиатурой Keyboard0. Второй профиль определяется аналогично:
Section "ServerLayout"
Identifier "seat1"
Screen 1 "Screen1" 0 0
InputDevice "Mouse1" "CorePointer"
InputDevice "Keyboard1" "CoreKeyboard"
EndSection
Вдумчивый читатель, наверное, уже задался вопросом: “А что такое за Screen1, Mouse1, Keyboard1, Screen0, Mouse0, Keyboard0?” Эти устройства определяются в этом же файле.
Section "InputDevice"
Identifier "Keyboard0"
Driver "evdev"
Option "Device" "/dev/input/by-path/platform-i8042-serio-0-event-kbd"
Option "XkbModel" "pc105"
Option "XkbRules" "xorg"
Option "XkbLayout" "us,ru(winkeys)"
Option "XkbOptions" "grp:alt_shift_toggle,grp_led:scroll"
EndSection
В современном Linux за устройства ввода отвечает evdev, поэтому он указывается в качестве драйвера. Один из наиболее сложных этапов настройки - это определить идентификатор на ту самую клавиатуру, которая вам нужна. Все устройства ввода находятся в папке /dev/input/, где дублируются в папка by-path и by-id. Или же есть файлы event0 - event5 для клавиатур. Вам нужно выбрать одну из клавиатур, которая вам понравится. Определить правильность выбора довольно просто: достаточно в консоли набрать sudo cat /dev/input/eventX, где Х - номер вашей клавиатуры. При нажатии на клавишу этой клавиатуру в консоли должен появиться символ.
Каждый такой event то же самое, что клавиатура в /dev/input/by-path/ и /dev/input/ by-id/. Так что делайте, так как вам удобнее. У меня две разные клавиатуры, поэтому мне удобнее ориентироваться по моделям, но при одинаковых клавиатурах, наверное, удобнее будет работать с event.
Опция "XkbModel" "pc105" говорит, что у нас будет стандартная 105-клавишная клавиатура. Опция "XkbLayout" "us,ru(winkeys)" добавляет две раскладки: us и ru (английскую и русскую) .
Опция "XkbOptions" "grp:alt_shift_toggle,grp_led:scroll" означает, что переключение раскладок осуществляется комбинацией alt+shift, и при русской раскладке будет гореть светодиод scroll lock.
Для второй клавиатуры все почти такое же:
Section "InputDevice"
Identifier "Keyboard1"
Driver "evdev"
Option "Device" "/dev/input/by-id/usb-Chicony_USB_Keyboard-event-kbd"
Option "XkbModel" "pc105"
Option "XkbRules" "xorg"
Option "XkbLayout" "us,ru(winkeys)"
Option "XkbOptions" "grp:alt_shift_toggle,grp_led:scroll"
EndSection
Перейдем к мышкам.
Section "InputDevice"
Identifier "Mouse0"
Driver "evdev"
Option Device" "/dev/input/by-id/usb-PIXART_USB_OPTICAL_MOUSE-event-mouse"
Option "GrabDevice" "on"
Option "Buttons" "12"
EndSection
Вроде все как в клавиатуре, но есть опция Option "GrabDevice" "on", которая захватывает все события от устройства в монопольное использование. И опция Option "Buttons" "12", которая говорит, что у нашей мышки будет 12 клавиш.
Теперь экраны.
Section "Screen"
Identifier "Screen0"
Device "Device0"
DefaultDepth 24
EndSection
Определяем устройство, к которому подключен экран (Device0) и, на всякихй случай, глубину цвета. То же делаем и со вторым экраном.
Section "Screen"
Identifier "Screen1"
Device "Device1"
DefaultDepth 24
EndSection
А вот и устройства.
Section "Device"
Identifier "Device0"
Driver "radeon"
VendorName "ATI Technologies Inc"
BoardName "ATI 3100"
BusID "PCI:1:5:0"
Option "Int10" "off"
EndSection
Еще раз обращаю внимание на драйвер "radeon". Ни в коем случае не проприетарный драйвер ATI (про карты Nvidia сказать ничего не могу, но там вроде все наоборот). Чуть позже расскажу подробнее, почему. BusID "PCI:1:5:0" - те самый цифры для данной видеокарты, полученные при команде lspci | grep VGA. Option "Int10" "off" отключает инициализацию видеокарты, используя прерывание BIOS. Эта опция обязательна. Без нее у вас ничего не получится.
И для второй видеокарты.
Section "Device"
Identifier "Device1"
Driver "radeon"
VendorName "ATI Technologies Inc"
BoardName "ATI 2600"
BusID "PCI:2:0:0"
Option "Int10" "off"
EndSection
Также в файле xorg.conf необходимо указать параметры сервера.
Section "ServerFlags"
Option "DefaultServerLayout" "seat0"
Option "AllowMouseOpenFail" "true"
Option "AutoAddDevices" "false"
Option "AllowEmptyInput" "false"
EndSection
Рассмотрим все опции:
"DefaultServerLayout" "seat0" - если вдруг что-то случится с kdm и xorg запустится без параметров, то серверу надо знать, какую конфигурацию загружать.
"AllowMouseOpenFail" "true" - даже если мышки нет, то считать мышку рабочей и не смущать сервер. По сути, вроде не должно работаться при использовании evdev. Возможно, больше не используется . Но исторически так получилось :)
"AutoAddDevices" "false" - запрещает добавлять устройства автоматически, только те, которые прописаны в файле xorg.conf. А то придет добрый человек и подключит мышку к компьютеру, и, по логике вещей, она появился на всех рабочих местах и будет перебивать мышку, определенную соответствующему рабочему столу. Нам такого не надо, поэтому и отключаем. И пусть добрый человек смотрит на мышку и думает: “Чего это она не работает?” Незачем не уполномоченному лицу устанавливать мышки в сложные системы. Сломает еще чего :)
"AllowEmptyInput" "false" - не добавляет стандартный драйвера для мышки и клавиатуры, если вдруг мы забыли прописать мышку и клавиатуру в xorg.conf.
Первый запуск
Вот первый этап и закончен. Теперь можно перегружаться и, если все прошло успешно, то вы увидите приглашение KDM на ввод логина и пароля. Остается ввести логин и пароль, выбрать среду рабочего стала, затем, если все хорошо, включить автологин в файле /etc/kde4/kdm/kdmrc и настраивать систему дальше :).
У меня загрузка графических серверов выглядит следующим образом:
Такая красивая картинка получена замечательной программой bootchart. Вот
полная версия графика.
А сейчас я расскажу, почему нельзя было ставить проприетарный драйвер ATI. Этот драйвер очень сложно уговорить. Опцию -isolateDevice он воспринимает несколько по-своему. Долгий анализ логов xorg-сервера показал, что происходит примерно такая ситуация.
Запуск первого Х-сервера (xorg1), который запускает проприетарный драйвер ATI (fglrx1).
fglrx1 - вау, видеокарта, ух ты, она меня устраивает. Будем с ней работать.
fglrx1 - вау, вторая. Класс, хочу. В общем, мне она нравится, я ее тоже забираю.
Xorg1 - ок, работаем.
Запуск второго Х-сервера (xorg2), который запускает проприетарный драйвер ATI (fglrx2).
fglrx2 - э-э-э, а где видеокарта? Не, мужик, я не понял, где видеокарта?
fglrx2 - ну и сам работай без видеокарты.
Xorg2 - эээ.. кто обидел драйвер, почему он от меня ушел (убегая с компа)? Вернись, fglrx2, я все прощу.
С открытым драйвером такого нет. Он отлично распознает опцию запуска на отдельном устройстве.
Решенные проблемы
Продолжим настройку системы дальше. Хоть все и работает, но всегда есть много мелочей, не заметных на первый взгляд. Когда мы только брались за настройку, мы и не могли даже предположить, что в такой конфигурации компьютер откажется перезагружаться и выключаться. Казалось бы, почему? А все из-за таких интересных штук как
ConsoleKit и
PolicyKit. Информации по ним не очень много, но все сводится к тому, что PolicyKit разрешает непривилегированным процессам общаться с привилегированными. Или, проще говоря, он контролирует политику системы. В нашем случае именно он и не дает выключить нам компьютер, потому что у нас нет прав на это. Информацию для PolicyKit о том, кто мы, дает тот самый ConsoleKit, и задача этой подсистемы отслеживать пользователей, их сессии и те самые сеты. Только вот незадача, в документации есть очень нехорошая приписка: “True, hardware, multi-seat capabilities will be added in a later release“. А мы хотим multiseat уже сейчас. Можно пропатчить ConsoleKit, но давайте немного углубимся и посмотрим, можно ли обойтись без этого. При входе пользователя в систему ему создается сессия, причем сессия маркируется как активная. А вот при одновременном входе двух пользователей (наш multiseat) им создается две сессии, но ConsoleKit теряется и делает их неактивными. Посмотреть текущие сессии можно, набрав в консоли команду ck-list-sessions.
andrey@k211-multiseat:~$ ck-list-sessions
Session1:
unix-user = '1000'
realname = 'андрей'
seat = 'Seat3'
session-type = ''
active = FALSE
x11-display = ':1'
x11-display-device = ''
display-device = ''
remote-host-name = ''
is-local = TRUE
on-since = '2010-10-25T14:14:04.812473Z'
login-session-id = ''
Session2:
unix-user = '1001'
realname = 'александр'
seat = 'Seat4'
session-type = ''
active = FALSE
x11-display = ':0'
x11-display-device = ''
display-device = ''
remote-host-name = ''
is-local = TRUE
on-since = '2010-10-25T14:14:05.146443Z'
login-session-id = ''
Я долго пытался уговорить ConsoleKit сделать сессии активными, пока не решил зайти с другого конца. Компьютер не дает выключить PolicyKit, у которого есть правила на выключение компьютера, и неактивный пользователь там не походит. Ищем файл, отвечающий за политику выключение компьютера, и находим все политики в этот папке /usr/share/polkit-1/actions. Файл, отвечающий за выключение, перезагрузку и т.д. называется org.freedesktop.consolekit.policy. Открываем его. И видим обычный xml-файл. В секции
видим множество событий. Давайте рассмотрим первое.
Stop the system
System policy prevents stopping the system
no
yes
В поле action id указывается действие. В данном случае это выключение системы. Дальше следует description, то есть описание, что это такое. Данный текст будет выводиться при необходимости авторизации для данного действия. В поле message указывается сообщение, которое получит человек при необходимости авторизации. Дальше идет раздел , который и управляет разрешениями на действия. В нем есть два поля: allow_inactive - условие разрешение выполнять действие неактивному пользователю (оба-на, да это же наша неактивная сессия в ConsoleKet) и allow_active - активному. Вообще,
документация говорит еще об поле allow_any. Но на момент создания данной системы я про это ничего не слышал, возможно, опция появилась позже. В качестве параметров могут выступать такие ключи:
no - отказать в действии
yes - разрешить действия
auth_self - затребовать пароль пользователя
auth_admin - затребовать пароль администратора
auth_self_keep - затребовать пароль пользователя и помнить его некоторое время
auth_admin_keep - затребовать пароль администратора и помнить его некоторое время.
Теперь меняем опцию no на yes и мы можем выключить компьютер от любого пользователя, но при условии, что у нас всего одна сессия на компьютере, а не две. Для других действия следует поменять опции на такие:
Stop the system when multiple users are logged in
System policy prevents stopping the system when other users are logged in
Внимание! Система используется другим пользователем. Вы точно хотите ее выключить?
auth_admin_keep
auth_admin_keep
Вот, это наш случай. У нас два пользователя, и когда один захочет выключить компьютер, ему выводится окошко с требованием ввести пароль. Если в системе один пользователь, то окошко не будет появляться.
Многие спросят, а зачем пароль? Давайте представим ситуацию. Вот работают два человека за компьютером. Один собирается домой и выключает компьютер, забыв, что второй человек еще работает. В результате компьютер выключается к большому негодованию второго, который не готов к такому развитию событий. Предупреждение с требованием лишний раз ввести пароль все-таки сбережет нервы обоим пользователям.
Остальные параметры аналогичны.
Restart the system
System policy prevents restarting the system
yes
yes
Restart the system when multiple users are logged in
System policy prevents restarting the system when other users are logged in
Внимание! Система используется другим пользователем. Вы точно хотите ее перезагрузить?
auth_admin_keep
auth_admin_keep
С выключением и перезагрузкой компьютера разобрались.
USB-накопители
Еще одна интересная ситуация происходит при использовании USB-накопителя. Мы вставляем флэшку, и две копии Gnome (в моем случае) сражаются за то, кто ее примонтирует. Побеждает всего один из них, а второй обиженно ругается ошибкой. Причем, первый монтирует ее с правами только для своего пользователя,а второго на флэшку не пускает. Довольно неприятная ситуация, которая способна погубить всю затею multiseat. Будем с ней бороться.
Вариант, который сразу пришел на ум - спустится немного ниже к железу и монтировать флэшку до Gnome. Пришлось почитать мануалы и посовещаться с Гуглом. И ответ был найден. Имя ему - UDEV. UDEV - это менеджер устройств, который и берет на себя услуги по сопровождению устройства при его появлении в системе до эксплуатации компонента. Также на его совести обратный путь - аккуратный вывод устройства из системы.
Но для любого накопителя есть свои особенности. Его нужно не только примонтировать, но и размонтировать. И ситуация такая - накопитель монтируется при присоединении флэшки, а для размонтирования ему надо дать команду от пользователя (правой клавишей мышки → безопасно отключить накопитель). Если пометка об устройстве есть в файле /etc/fstab, то любой пользователь может размонтировать устройство, иначе это может сделать только пользователь с правами администратора. Наш план таков: при подключении флэшки записываем параметр для монтирования в /etc/fstab, вызываем mount, получаем флэшку. При нажатии безопасного удаления устройства вызываем umount. Базовая идея была найдена
в этом блоге.
Настройка UDEV
Все правила UDEV находятся в папке /etc/udev/rules.d. Правила начинают срабатывать в алфавитном порядке. Название правил значения не имеет. Для себя я создавал файл 40-usbmount.rules с таким содержанием:
ACTION=="add", KERNEL=="sd[b-z][0-9]", RUN+="/bin/mkdir -p /media/%k"
ACTION=="add", KERNEL=="sd[b-z][0-9]", RUN+="/bin/sed -i '/\/dev\/%k.*/d' /etc/fstab"
ACTION=="add", KERNEL=="sd[b-z][0-9]", RUN+="/bin/sed -i '$a\/dev/%k /media/%k auto rw,noauto,noexec,nodev,noatime,users,iocharset=utf8,uid=1000,gid=100,umask=0, 0 0' /etc/fstab"
ACTION=="add", KERNEL=="sd[a-z][0-9]", RUN+="/bin/mount /dev/%k"
ACTION=="remove", KERNEL=="sd[b-z][0-9]", RUN+="/bin/umount -l /dev/%k"
ACTION=="remove", KERNEL=="sd[b-z][0-9]", RUN+="/bin/rmdir /media/%k"
ACTION=="remove", KERNEL=="sd[b-z][0-9]", RUN+="/bin/sed -i '/\/dev\/%k.*/d' /etc/fstab"
Давайте разберемся, что тут происходит. Посмотрим на первые четыре строчки. Они срабатывают при добавлении устройства (ACTION=="add"), то есть нашей флэшки (KERNEL=="sd[b-z][0-9]"), и после этого запускается команда RUN+="команда". Значок == означает условие. Если истина, то строчка выполняется дальше, если ложь, то пропускается. У меня в системе один жесткий диск - sda. Как знает большая часть linux-пользователей (я, по крайней мере, так думаю), диски в linux обозначаются sd[X][Y], где X - буква латинского алфавита, по порядку дисков (a- первый, b - второй и т.д.), а Y - номер раздела диска. Поэтому в моем случае стоит KERNEL=="sd[b-z][0-9]". Если у вас два жестких диска, то вам следует сменить запись на такую KERNEL=="sd[с-z][0-9]". И так далее. Команды, которые следуют за оператором RUN+= рассмотрим чуть позже.
Три последние команды срабатывают при отключении устройства (ACTION=="remove"), будь-то безопасное извлечение или просто выдернутая флэшка. Срабатывает на те же самые сменные накопители.
Рассмотрим теперь команды, идущие после оператора RUN+=. В этом операторе указываются используемые приложения, которые должны запуститься в случае истинности всех прошлых условий. Также есть небольшой нюанс: надо указывать полные пути к исполняемому файлу.
Команда /bin/mkdir -p /media/%k создает папку для дальнейшего монтирования накопителя. %k - это переменная UDEV, означающая имя устройства, которое вызвало срабатывание данного правила. То есть при подключении флэшки это будет sdb1 (в мое случае). И при срабатывании данной команды должна создаться папка /media/sdb1. Папку создаем в /media , потому что в Ubuntu так принято. А сделать мы хотим систему с минимальными отличиями.
Следующая команда /bin/sed -i '/\/dev\/%k.*/d' /etc/fstab. Команда уже отличается небольшой сложностью. Она должна удалить все упоминания нашего устройства из файла /etc/fstab. Если вдруг мы случайно выключили компьютер с флэшкой в нем, то у нас будет небольшая проблема с дальнейшим монтированием флэшек. Данная строчка и предназначена для борьбы с этим. Разберем ее по порядку. Запускается команда /bin/sed с ключем -i, который означает, что надо редактировать файл, указанный в конце команды (в нашем случае /etc/fstab). Средняя часть команды '/\/dev\/%k.*/d' - это регулярное выражение, которое означает, что мы ищем все упоминая /dev/sdb.* (для нашего примера) и, найдя такую строчку, удаляем ее.
Команда /bin/sed -i '$a\/dev/%k /media/%k auto rw,noauto,noexec,nodev,noatime,users,iocharset=utf8,uid=1000,gid=100,umask=0, 0 0' /etc/fstab заносит запись в новую строку ($a) в файл /etc/fstab. В нашем случае строка будет /dev/sdb1 /media/sdb1 auto rw,noauto,noexec,nodev,noatime,users,iocharset=utf8,uid=1000,gid=100,umask=0, 0 0
Все, что идет после sdb1, это параметры для монтирования, про них я расскажу чуть позже.
По нашему скрипту дальше идет команда /bin/mount /dev/%k . Тут все просто. Вызывается команда монтирования устройства /dev/sdb1 (для моего случая) с параметрами, указанными в файле /etc/fstab. Это те самые параметры, про которые я обещал вам рассказать чуть позже. Вот чуть позже это я и сделаю :) На этом этапе с флэшкой можно работать.
Остальные три строки будут выполняться, если вы вдоволь наработались с флэшкой, и вам хочется извлечь ее. Команда /bin/umount -l /dev/%k размонтирует флэшку.
Ключ -l означает «ленивое» размонтирование. Довольно опасная опция. По сути, игнорирует все открытые файлы, но не задает пользователю лишних вопросов. Однако при этом гарантируется сохранение целостности файловой системы.
/bin/rmdir /media/%k удаляет папку, в которую монтировалась флэшка.
/bin/sed -i '/\/dev\/%k.*/d' /etc/fstab удаляет запись об флэшке из файла fstab. Работу ее мы уже рассматривали выше.
Этот метод не совершенен. Скажем, я случайно столкнулся с тем, что он не понимает USB CD-ROM. И возможно что-то еще. Но проблема, по сути, решается просто добавлением в строчку KERNEL=="sd[b-z][0-9]" еще и этих устройств. Вот только осталось выяснить имена этих устройств. Если у вас в системе они используются, то сделать это просто. Есть же их нет, но они потенциально могут появиться, то ситуация становится немного сложнее.
Еще немного узнать про UDEV вам поможет справка Linux. Для этого достаточно набрать в консоли man udev.
Настало время разобраться со строчкой, которую мы занесли в файл /etc/fstab.
Запись в файле fstab представляет собой конструкцию “что -- куда -- файловая система -- парметры монтирования--флаг для dump -- флаг проверки”.
Для нашего случая она будет иметь вид /dev/sdb1 /media/sdb1 auto rw,noauto,noexec,nodev,noatime,users,iocharset=utf8,uid=1000,gid=100,umask=0, 0 0
Тут /dev/sdb1-- устройство, которое мы хотим монтировать. /media/sdb1-- путь, куда мы хотим монтировать устройство.
Далее идет тип файловой системы. Auto означает, что тип файловой системы будет определяться автоматически. Довольно удобно, ведь даже в мире Windows есть как минимум две файловые системы для флэшек: fat и ntfs.
После этого идут параметры монтирования:
rw - диск монтируется как на чтение, так и на запись.
noauto -- данная запись не будет восприниматься командой mount -a. То есть монтирование всех доступных устройств.
noexec - флаг разрешения запуска бинарных файлов установлен в 0. То есть вы не сможете запустить бинарные файлы напрямую с этой флэшки. Вам придется выставить флаг разрешения запуска файла.
nodev - говорит о том, что на данной файловой системе нельзя размещать устройства (папку /dev).
noatime - не обновлять время доступа к файлу. По описанию так должно работать быстрее.
users - монтировать это устройство может обычный пользователь, а не только root.
iocharset=utf8 - кодировка файловой системы. Опция характерна только для файловых систем fat и ntfs.
uid=1000 -- id пользователя, права которого будут распространяться на файл. Опция характерна только для файловых систем fat и ntfs
gid=100 -- id группы, права которой будут распространяться на файл. Не забудьте двух или более пользователей добавить в одну группу, чтобы они могли без проблем работать с флэшкой, ведь она монтируется сразу всем. Если же пользователи входят в разные группы, то одна из групп не сможет работать с флэшкой. Опция характерна только для файловых систем fat и ntfs.
umask=0 -- маска доступа к файлам. Ноль означает, что остается по умолчанию. Подробнее об этом можно узнать в
Википедии.
Предпоследний ноль означает, что не надо делать бэкап файловой системы утилитой dump. А последний, что не надо проверять файловую систему утилитой fsck.
Более подробно ознакомится со всеми остальными опциями монтирования можно с помощью команд man fstab и man mount в консоли.
После того как мы разобрались с монтированием флэшки и создали новое правило, надо же как-то сказать об этом UDEV, а то откуда же он узнает об наших изменениях. Для этого можно в консоли набрать команду udevadm control -reload-rules. Теперь можно вставить флэшку и посмотреть на результат работы.
Опыт использования
Вот собственно на этом и все. За кадром, конечно, осталось множество вопросов. Скажем, я не стал решать проблему с аудиосистемой, то есть с разделением звука от двух рабочих мест на разные аудиовыходы. За пол года работы это так ни разу никому и не понадобилось. Компьютер все же офисный.
Среди известных проблем системы следует отметить, что flash-видео проигрывается с двойной скоростью, также стандартный проигрывать видео все играет с двойной скоростью. VLC воспрроизводит все нормально.
А теперь возможно самое интересное - опыт использования системы. За этим компьютером сидит два пользователя. Мужчина и женщина. Оба этих человека чуть старше 50 лет. С компьютерами знакомы на уровне шумящей коробочки, в которой есть офисные документы и пара офисных игрушек. До этого они пользовались Windows XP. Проблем с переходом у них не возникло. В общей сложности на консультацию этих людей я потратил около часа, это общее время за пару недель. Большая часть вопросов возникла в первое время - все же непривычно. Мужчина уже самостоятельно разобрался, как в центре приложений установить свои любимые карточные игрушки, и даже женщину обрадовал игрушками для нее. Хотя до сих пор этот человек не очень понимает, как поставить программу в Windows. Так что систему можно назвать довольно дружественной к пользователю. Во внутренней сети используется обычный сервер (невыключающийся компьютер :) ). Ссылка на него успешно создалась в меню переход, и оттуда ее уже и используют. Женщине очень хотелось видеть программу Консультант+. Программа отлично запустилась через wine.
Большинство проблем оказалось чисто психологические, люди боятся всего нового. Никто не хочет ни в чем разбираться, но это проблема, наверное, большинства людей в мире. И тут, наверное, можно только заставить или мотивировать. Также людей надо обучать новому. Очень плохо, что начальство этого не понимает. Людей очень смущает отсутствие антивируса в системе. До конца мне они так и не поверили, что в нем нет необходимости. Это одна их самых больших психологических проблем. Приученные к антивирусу пользователи (до этого пришлось их приучивать) чувствуют большой дискомфорт при отсутствии антивирусного ПО. Пользователям также очень непривычно делить компьютер с кем-либо, и они опасаются, что их важные офисные документы удалят. При этом пользователи не боятся скидывать важную информацию в помойку на сервер, где все могут стереть их файлы. Было очень сложно объяснить им, что рабочие столы у них разные и файлы в домашней директории одного пользователя другой удалить не сможет. Но они тоже вроде не особо мне поверили. У них всегда свое мнение на эти вопросы :).
Из технических проблем ничего отмечено не было. Хотя, конечно, если что-либо сломается, то починить может очень малое количество людей. Поэтому такую систему не очень рекомендуется ставить без грамотного системного администратора, разбирающегося в Linux. Хотя, с другой стороны, если все настроить и отобрать у пользователей права, то система работает как часы. За пол года технических проблем по вине пользователей не возникало. И, в принципе, возникнуть и не должно.
Наверное, самое ценное в этой системе - это значительная экономия денег. Причем как на комплектующих, так и на электричестве. А учитывая, что компьютер офисный и включен порядка 9 часов в день (8 рабочих плюс обед), то экономия на электричестве получается заметной. Что касается цены комплектующих, то системный блок c клавиатурой и мышкой в моем случае стоит 407$, монитор - 162$, то есть стоимость одного рабочего места составила 569$. Второй монитор (162$), клавиатура (8$), мышка (7$) и видеокарта (48$) вместе стоили 225$, что составляет 40% от стоимости первого рабочего места. Если посчитать стоимость одного рабочего места, то получаем 397$. Как-то неплохо за нормальный компьютер. А если в процентах, то одно рабочее место становится дешевле на 30%.
Возможно, я упустил некоторые моменты в описании. Поэтому все файлы, которые упоминаются в статье, можно скачать в полном виде
вот здесь.
Вид на готовую систему:
В статье не упомянут специальный патч для ядра и версия драйвера, которые позволяют запускать по графическому серверу на каждый выход видеокарты. Подробности в
ЖЖ у
airlied Впервые статься опубликована
здесь Отдельная благодарность
tamakio и
morrigan_sher за помощь в подготовке статьи. Вы лучшие :)