Kopiowanie danych między dwoma serwerami za pośrednictwem trzeciego.

Co zrobić gdy trzeba znaleźć sprytny sposób na skopiowanie większej ilości danych pomiędzy dwoma serwerami, które nie mają ze sobą bezpośredniej łączności? Można skorzystać z trzeciego serwera i wydać na nim następujące polecenie:

$ ssh remote_server_1 'sudo sh -c "cd /source/path && tar cpf - *"' | ssh remote_server_2 'sudo sh -c "cd /destination/path && tar xpf -"'

Polecenie to zostało wykonane na trzech systemach HP-UX, ale analogiczne można wykonać na systemach Linux.

Za jakiś czas postaram się napisać nieco bardziej szczegółowy wpis na temat kopiowania danych z wykorzystaniem ssh, tar i potoków.

Wyjątek RPC podczas wykonywania swcopy.

Pewnego razu podczas próby stworzenia z płyt instalacyjnych HP-UX depotu, napotkałem następujący problem:

# swcopy -x enforce_dependencies=FALSE -x reinstall=TRUE -x mount_all_filesystems=false -s /var/opt/ignite/iso/ \* @ /var/opt/ignite/depots/0314

ERROR:   RPC exception: "Connection request rejected (dce / rpc)"
09/05/14 11:44:09 EST
ERROR:   Could not perform the requested operation for
"server:/var/opt/ignite/depots/0314",
possibly due to a network communications failure or the agent
timing out. Check that the host is still accessible from the
network, and the agent_timeout_minutes option is not set too
low.

Po krótkich poszukiwaniach okazało się, że rozwiązanie jest bardzo proste. Wygląda na to, że paczek jest za dużo dla swcopy w związku z czym zadanie należy rozbić na kilka etapów. Ja na przykład podzieliłem pliki na te zaczynające się cyframi, małymi i wielkimi literami:

# swcopy -x enforce_dependencies=FALSE -x reinstall=TRUE -x mount_all_filesystems=false -s /var/opt/ignite/iso/ [0-9]\* @ /var/opt/ignite/depots/0314
# swcopy -x enforce_dependencies=FALSE -x reinstall=TRUE -x mount_all_filesystems=false -s /var/opt/ignite/iso/ [a-z]\* @ /var/opt/ignite/depots/0314
# swcopy -x enforce_dependencies=FALSE -x reinstall=TRUE -x mount_all_filesystems=false -s /var/opt/ignite/iso/ [A-Z]\* @ /var/opt/ignite/depots/0314

Sourcing psuje getopts w ksh88.

Jakiś czas temu natknąłem się na pewną ciekawostkę w powłoce Korna (ksh) w wersji 88. Okazuje się, że sourcowanie skryptu wraz z przekazaniem parametrów do niego wewnątrz innego skryptu przesłania parametry przekazywane do tego drugiego skryptu. Zobaczmy na przykładzie zrealizowanym w systemie AIX 7 (tak samo jest w HP-UX 11.31).

Zaczynamy od zwykłego skryptu, który będzie przyjmował opcje „-a” i „-b”:

#! /usr/bin/ksh

while getopts ab OPTION
do
  case $OPTION in
    a) print "AAA" ;;
    b) print "BBB" ;;
  esac
done

Uruchomienie go daje następujące rezultaty:
$ ./test.ksh
$ ./test.ksh -a
AAA
$ ./test.ksh -b
BBB
$

Tak więc gdy skrypt jest wywoływany bez parametrów nic się nie dzieje. W przypadku wywołania z opcją „-a” na ekranie zostaje wypisane „AAA”, w przypadku „-b” „BBB”. Jest to zgodne z naszymi oczekiwaniami.

Dodajmy sourcowanie skryptu source.ksh:

#! /usr/bin/ksh

. ./source.ksh

while getopts ab OPTION
do
  case $OPTION in
    a) print "AAA" ;;
    b) print "BBB" ;;
  esac
done

Treść source.ksh nie jest tu zbyt istotna – u mnie było to po prostu:

print "Sourced script!"

Wyniki uruchomień skryptu są następujące:
$ ./test.ksh
Sourced script!
$ ./test.ksh -a
Sourced script!
AAA
$ ./test.ksh -b
Sourced script!
BBB
$ ./test.ksh -ab
Sourced script!
AAA
BBB
$

Czyli jak na razie nic szczególnego się nie dzieje. Jedyna różnica w porównaniu z poprzednią wersją skryptu jest taka, że widać działanie sourcowanego skryptu – pojawia się napis „Sourced script!”.

Jednak co będzie gdy dodamy do wywołania source.ksh parametr?

#! /usr/bin/ksh

. ./source.ksh xyz

while getopts ab OPTION
do
  case $OPTION in
    a) print "AAA" ;;
    b) print "BBB" ;;
  esac
done

Wyniki wywołań są następujące:
$ ./test.ksh
Sourced script!
$ ./test.ksh -a
Sourced script!
$ ./test.ksh -b
Sourced script!
$ ./test.ksh -ab
Sourced script!
$

Za każdym razem wynik jest ten sam! Niezależnie od tego, czy wywołujemy test.ksh z opcjami czy nie, nie są one przetwarzane. Aby sprawdzić, co się dzieje, dodajmy na końcu test.ksh instrukcję wydrukowania pierwszego parametru pozycyjnego skryptu:

#! /usr/bin/ksh

. ./source.ksh xyz

while getopts ab OPTION
do
  case $OPTION in
    a) print "AAA" ;;
    b) print "BBB" ;;
  esac
done

print $1

Sprawdźmy:
$ ./test.ksh
Sourced script!
xyz
$ ./test.ksh -a
Sourced script!
xyz
$

Jak widać pierwszym parametrem pozycyjnym, zarówno podczas wywołania skryptu bez parametrów jak i z, jest parametr podany do source.ksh.

Sprawdźmy co będzie w przypadku zastosowania ksh93:

#! /usr/bin/ksh93

. ./source.ksh xyz

while getopts ab OPTION
do
  case $OPTION in
    a) print "AAA" ;;
    b) print "BBB" ;;
  esac
done

Sprawdźmy:
$ ./test.ksh
Sourced script!
$ ./test.ksh -a
Sourced script!
AAA
$ ./test.ksh -b
Sourced script!
BBB
$ ./test.ksh -ab
Sourced script!
AAA
BBB
$

Czyli zaobserwowany podczas używania ksh88 problem nie istnieje.

Porównajmy to z bashem (wersja 4.3.39). Mamy testowy skrypt test.bash:

#! /bin/bash

. ./source.bash xyz

while getopts ab OPTION
do
  case $OPTION in
    a) echo "AAA" ;;
    b) echo "BBB" ;;
  esac
done

Gdy wywołamy ten skrypt otrzymujemy:
$ ./test.bash -a
Sourced script!
AAA
$ ./test.bash -b
Sourced script!
BBB
$

A zatem wynik diametralnie inny niż w ksh88.

No dobrze. A co się dzieje w przypadku ksh93 dostępnego w Linuksie?

#! /bin/ksh

. ./source.ksh xyz

while getopts ab OPTION
do
  case $OPTION in
    a) print "AAA" ;;
    b) print "BBB" ;;
  esac
done

Otrzymujemy następujące wyniki:
$ ./test.ksh
Sourced script!
$ ./test.ksh -a
Sourced script!
AAA
$ ./test.ksh -b
Sourced script!
BBB
$

Wnioski? Należy pamiętać, że gdy chcemy skorzystać w ksh88 z getopts i jednocześnie przekazać parametry do sourcowanego skrytpu to getopts musi zostać wykorzystane wcześniej niż sourcowanie. Unikniemy w ten sposób przesłonięcia parametrów pozycyjnych głównego skryptu.

Zmiana wielkości primary swap w HP-UX.

Jakiś czas temu okazało się, że na jednym z moich serwerów popełniłem błąd podczas instalacji systemu i zamiast 64 GB swapu skonfigurowałem tylko 8. Dodatkowo należało utworzyć kolejne 64 GB drugorzędnej przestrzeni wymiany (czyli po angielsku „secondary swap”). Jak wykonać takie zadanie?

      1. Zacznijmy od sprawdzenia aktualnej konfiguracji grupy wolumenowej vg00 i pamieci swap, aby zweryfikować stan obecny:
        # vgdisplay -v vg00
        # swapinfo
        W moim przypadku potwierdziło się, że grupa vg00 składa się z 8 wolumenów logicznych, a lvol2, służący za przestrzeń wymiany, liczy sobie tylko 8 GB. Swapinfo potwierdziło, że jest to jedyny swap z jakiego korzysta system.
      2. Następnie utworzyłem wolumen logiczny na drugorzędny swap:
        # lvcreate -C y -L 65536 -n lvol9 /dev/vg00
        Wolumen logiczny pod przestrzeń wymiany musi być spójny, tak więc konieczne jest użycie opcji -C z argumentem y. Opcja -L pozwala nam podać wielkość wolumenu w MB. Dzięki opcji -n możemy zdefiniować nazwę wolumenu – ja nie byłem tu zbyt odkrywczy i skorzystałem ze standardowej konwencji nazewniczej HP-UX tworząc „lvol9”.
      3. Kolejnym krokiem jest włączenie swapowania na nowo utworzonym wolumenie:
        # swapon -p 2 /dev/vg00/lvol9
        Opcja -p jest konieczna do zdefiniowania priorytetu przestrzeni swap. Zdefiniowanie priorytetu innego niż jeden konieczne jest jeśli chcemy później bezproblemowo usunąć informacje o konfiguracji pierwszorzędnego swapu z konfiguracji grupy wolumenowej vg00.
      4. Aby podejrzeć czy poprawnie włączyliśmy swap możemy zerknąć na wynik polecenia:
        # swapinfo
        Na tym etapie jak usyskałem informację o dwóch przestrzeniach swap: lvol2 z priorytetem 1 i o wielkości 8 GB i lvol9 z priorytetem 2 i o wielkości 64 GB.
      5. Skoro miałem już dodatkową przestrzeń wymiany, którą mój dość mocno obciążony system mógł wykorzystać, mogłem wyłączyć swapowanie na lvol2:
        # swapoff /dev/vg00/lvol2
      6. Po raz kolejny sprawdziłem poprawoności wykonania poprzedniej operacji:
        # swapinfo
      7. Teraz możliwej już było usunięcie informacji o primary swap i urządzeniu przeznaczonym na dumpy (w moim przypadku również lvol2) z konfiguracji grupy wolumenowej vg00:
        # lvrmboot -s vg00
        # lvrmboot -d lvol2 /dev/vg00
        Bez wykonania powyższych operacji niemożliwe jest usunięcie lvol2.
      8. Wreszcie mogłem usunąć lvol2:
        # lvremove /dev/vg00/lvol2
      9. Kolejnym krokiem było ponowne utworzenie wolumenu lvol2 o nowej wielkości:
        # lvcreate -C y -r n -L 65536 -n lvol2 /dev/vg00
        Podobnie jak wcześniej podczas tworzenia lvol9 i teraz musimy użyć opcji -C z argumentem „y”. Wcześniej za to nie używaliśmy opcji -r, która w tym przypadku jest konieczna – wraz z argumentem „n” wyłącza relokację danych w przypadku wystąpienia bad blocków.
      10. Teraz należało dodać do konfiguracji vg00 informację o primary swap i urządzeniu przeznaczonym na dumpy:
        # lvlnboot -s /dev/vg00/lvol2
        # lvlnboot -d /dev/vg00/lvol2
        W przypadku niewykonania powyższych poleceń system po restarcie nie będzie wiedział, których urządzeń użyć do swapowania i zrzucania dumpów.
      11. Tak jak wcześniej sprawdziłem poprawność wykonanych przeze mnie operacji:
        # vgdisplay -v vg00
        # lvdisplay /dev/vg00/lvol2
      12. Teraz mogłem już aktywować swap na lvol2:
        # swapon -p 1 /dev/vg00/lvol2
        Użyłem opcji -p 1 ponieważ chciałem aby był to primary swap.
      13. Sprawdziłem czy wszystko poszło jak planowałem:
        # swapinfo
        Wynik polecenia mówił, że mam teraz dwa urządzenia, na których zachodzi swapowanie: lvol2 i lvol9 – oba mające po 64 GB wielkości.
      14. Na koniec pozostało dodanie informacji o drugorzędnym urządzeniu swap do fstab:
        # vi /etc/fstab
        Na końcu pliku konieczne było dodanie linii:
        /dev/vg00/lvol9 / swap pri=2 0 0
        Znak „/”, który widzisz w drugim polu, może być zastąpiony „.” (aktualny katalog) lub dowolną inną ścieżką – nie jest to dla systemu istotne.

Pamiętaj aby wszystkie powyższe komendy znajdują się w /usr/sbin, a wykonywać należy je z konta roota lub poprzez sudo.

No i proszę – wszystko naprawione. Można brać się za realizację innych zadań.


Użyteczne zasoby: