Wirtualizacja

Nazwa nie zdradza istoty zagadnienia - przymiotnik "wirtualny" jest obecnie używany coraz powszechniej, i dotyczy coraz większych obszarów aktywności. Jednak niniejsza prezentacja będzie miała niewiele wspólnego z Internetem - zastanowimy się jak zwirtualizować system operacyjny.

Załóżmy, że mamy dostęp do pewnego sprzętu komputerowego, na którym zainstalowany jest system operacyjny. Może się zdarzyć, że nie spełnia on wszystkich naszych potrzeb: z pewnością istnieją użyteczne aplikacje, które nie współpracują z tym środowiskiem. Mamy wówczas do wyboru: zaopatrzyć się w analogicznie działającą aplikację możliwą do uruchomienia (nie zawsze istnieje - jest produktem wyspecjalizowanym, starszym etc.) lub wymodelować nowe środowisko w obrębie naszego.

Również badanie innych systemów operacyjnych jest celem samym w sobie. Informatyka jest jedną z najbardziej dynamicznie rozwijających się dziedzin, powstało już (i wciąż powstaje) bardzo wiele rozmaitych środowisk. Można poznawać je bezpośrednio - wymaga to jednak dużych nakładów pracy i sprzętu (zwłaszcza że dane systemy mogą mieć różne wymagania). W tym wypadku możliwość modelowania danego środowiska na innym wydaje się nieodzowna. Takie właśnie modelowanie jest istotą tego, co w tej prezentacji określamy jako "wirtualizacja" (z łac. "virtualis" tzn... skuteczny). Operuje ona na danym środowisku zewnętrznym (nazywanym hostem), udostępniając wewnątrz niego aplikację sprawiającą wrażenie innego systemu operacyjnego (ang. guest), a nawet innego sprzętu.

Do "wirtualizacji" zalicza się również (nieco oderwany od podanych powodów) przypadek, gdy oba systemy są jednakowe. Przykładem jest znany UML, który jednak był już omawiany.

Podstawowe typy wirtualizacji

1. Czysta emulacja

Jest to najprostszy koncepcyjnie model wirtualizacji, jednak stosunkowo pracochłonny i złożony technicznie. Jest on najbliższy ideałowi całkowitego uniezależnienia emulowanego środowiska od hosta. Jego istotą jest modelowanie danych instrukcji hosta przez instrukcje charakterystyczne dla modelowanego środowiska.

Podczas każdej wirtualizacji krytycznym problemem jest dostęp do niepodzielnych zasobów, które niestety należą do środowiska hosta. Dlatego każde skorzystanie z dysku, myszy klawiatury, monitora, drukarki, karty sieciowej, wymaga interakcji z hostem. W czystej emulacji ta interakcja odbywa się właśnie przez modelowanie instrukcji - w momencie gdy wirtualne środowisko zamierza skorzystać z danego zasobu, robi to za pomocą właściwej sobie instrukcji. Dzięki emulatorowi system hosta otrzyma w wyniku jedną (ale częściej niestety dużo więcej) instrukcję interpretowaną przez siebie, która może oddziaływać na dany zasób (np. wyświetlić punkt na monitorze). Przypomina to nieco tłumaczenie poszczególnych zdań za pomocą klasycznego słownika.

Dostosowanie się do środowiska jest wyłącznie kwestią odpowiedniego tłumaczenia. Dzięki temu emulatory posiadają znacznie większą od innych narzędzi do wirtualizacji, zdolność adaptacji do skrajnie różnych środowisk. W szczególności są one jedynym narzędziem zdolnym do modelowania sprzętu o architekturze innej niż host. Dlatego też dla niektórych typy sprzętu (ATARI, Amiga), które nie mają obecnie swojej naturalnej kontynuacji, ten typ wirtualizacji jest jedyną możliwością działania.

Jednak istotnym czynnikiem zaważającym na ocenie tego typu narzędzi jest czas działania. Naturalne jest, że odległe od siebie architektury nie mogą być tłumaczone w sposób prosty - lista instrukcji hosta odpowiadających jednej charakterystycznej dla modelowanego środowiska wydłuża się, przez co zwiększa się czas działania takich narzędzi. W skrajnych wypadkach może przekraczać nawet kilkaset razy czas wykonywania tej samej instrukcji w naturalnym środowisku (tzn. na sprzęcie i z oprogramowaniem odpowiadającym tym, który chcemy emulować). Dlatego też zastosowanie tego typu wirtualizacji w aplikacjach użytkowych może byc mocno ograniczone. Dlatego też częściej stosuje się w nich pozostałe dwa typy wirtualizacji.

2. Emulacja przez interfejs aplikacji

W większości współczesnych aplikacji można wyróżnić element zwany API - interfejs aplikacji. Jest to, jak wiadomo, element pośredni między systemem operacyjnym a działającą w nim aplikacją, zapewniający jej pewną izolację od zagadnień systemowych i zapewniający właściwe podśrodowisko. Pomysł emulacji przez interfejs, opiera się na zbudowaniu interfejsu analogicznego do istniejących dla standardowych aplikacji danego systemu, dla aplikacji w normalnych warunkach do niego nieprzystosowanej. Interfejs musi zostać stworzony na tyle sprytnie, by zachowywał zgodność zarówno z systemem operacyjnym hosta, jak i z daną aplikacją (jest to oczywiscie pracochłonne i, podobnie jak w poprzednim modelu wymaga rozpatrzenia każdej instrukcji. Oczywiście wymaga to pewnej zgodności w architekturze sprzętu między obydwoma składnikami (tzn. ten typ wirtualizacji można stosowac wyłącznie na sprzęcie w architekturze x86, na której zdefiniowane są interfejsy aplikacji). Takie podejście ma niewątpliwe zalety: dzięki dostosowaniu do siebie aplikacji i środowiska hosta działanie jest znacząco szybsze. Poza tym, ponieważ jedynym emulowanym elementem jest wspomniany interfejs, narzędzie działa w pewnym oderwaniu od macierzystego systemu operacyjnego danej aplikacji (wniosek1: do badania systemów operacyjnych ten typ wirtualizacji się nie nadaje; wniosek2: do używania tego typu wirtualizacji nie są potrzebne żadne uprawnienia ani licencje dotyczące wirtualizowanego systemu).

3. Pełna wirtualizacja

Idea tego modelu wirtualizacji odbywa się na wykorzystaniu podobieństwa wykonania poszczególnych instrukcji dla pewnych systemów. Oczywistym warunkiem jest istnienie owego podobieństwa, do czego konieczna jest identyczność platform hosta i wirtualizowanego systemu. Model bazuje na fakcie, że wiele spośród instrukcji systemowych (zwłaszcza obsługi urządzeń zewnętrznych) w rzeczywistości pokrywa się dla róznych systemów. Dlatego też wirtualizacja pozostawia te instrukcje do wykonania przez procesor w sposób standardowy (wspólny dla obu systemów: hosta i modelowanego). Modelowanie można ograniczyć do pozostałych instrukcji. Takie podejście również daje akceptowalne narzuty czasowe, ponieważ wykorzystanie mechanizmów charakterystycznych dla hosta powoduje wykonanie instrukcji w czasie dokładnie odpowiadającym czasowi ich wykonania w środowisku hosta.

Niestety, architektura x86, której przede wszystkim dotyczy problem, nie była tworzona pod kątem wirtualizacji - istnieje w niej może niezbyt wielka, ale uciążliwa dla programistów grupa instrukcji nieustandaryzowanych, których wykrycie i odpowiednie modelowanie spędza sen z powiek programistom. Niemniej jednak ten model wirtualizacji jest zdecydowanie najpowszechniej stosowany i najbardziej odpowiedni dla większości aplikacji użytkowych.

Szczegóły

Poszczególne typy wirtualizacji są omówione osobno:
1. Czysta emulacja (na przykładzie Bochsa)
2. Emulacja API (na przykładzie WINE)
3. Pełna wirtualizacja (na przykładzie Virtual PC)
Na końcu części trzeciej znajduje się mini porównanie tych typów w formie tabelki. Można tam również znaleźć garść linków, oraz słówko o wirtualnej maszynie Javy.

Autorzy: Jarosław Paszek, Wojciech Wąs, Stanisław Witkowski