https://naba-san.hatenablog.com/


ESXi 6.7 +PT2 (PT3/USB) パススルー + Intel QSV をやりたい。

ESXi を使った PT2 仮想化+QSVエンコードにトライ中。

まだ全然完成してないけど、試行錯誤の内容を忘れそうなので、そろそろメモに残しておく。

検証構成(その1)

  • 本体: Fujitsu ESPRIMO D586/P
  • CPU: Core i5 6500 (Skylake)
  • メモリ: 32GB (DDR4 8GB×4)
  • SSD: 480GB (余りモノ)
    • 【2022/11/20 追記】安SSDを酷使すると、最後速度低下がエグい事になります。空き容量が十分に確保できるサイズを選びましょう。
  • USB-Flash: MLC相当を謳う某microSD+ツライチカードリーダー
    • 【2022/11/20 追記】フラッシュメモリはやめた方が良いです。割とすぐにOS飛びます。素直にSSDにインストールしましょう。
  • ハイパーバイザ: VMware ESXi 6.7
  • (補足)パススルー対象: PT2×2枚、Intel HD Graphics

USB-Flash に ESXi をインストールし、SSD は全領域をVMのストレージとして割り当てる。 【2022/11/20 追記】USB-Flash信用ならんです。SSDにESXiもゲストOSも全部突っ込む方が良いです。

PCIパススルーなので、Intel VT-d とかに対応したCPUが必要。パススルーを受けるゲストOSは、仮想マシンのメモリ割り当てを固定する必要がある。ホストのメモリ量はその点を見越して多めに積んでおくことを推奨。

【2022/11/20 追記】検証環境その2:

  • 本体: Fujitsu ESPRIMO Q556/M
  • CPU: Core i5 6500T (Skylake)
  • メモリ: 12GB (DDR4 8GBx1 + 4GBx1)
  • SSD: 480GB (PayPayフリマで3000円で買った)
    • HDD: 1TB (QuaStationから抜き取った2.5インチを光学ドライブと挿げ替え‥)
  • ハイパーバイザ: VMware ESXi 6.7
  • (補足)パススルー対象: Intel HD Graphics 530、Intel xHCI USB 3.0 Host Controller

当初の目論見(構成1)とは別目的で組んだ録画PC。PT2ではなく、USBチューナーを沢山積む方針。

ESXi のカスタマイズISO作成 (7.0対応)

標準イメージは Realtek NIC に対応しない為、カスタマイズISOを作成する。
管理者権限で立ち上げた powershell にて。(ESXi 7.0 を使う場合、v67をv70に書き換える)

PS C:\Windows\system32> Install-Module -Name VMware.PowerCLI
PS C:\Windows\system32> Set-ExecutionPolicy Unrestricted
PS C:\Windows\system32> cd C:\createESXi\
PS C:\createESXi> .\ESXi-Customizer-PS.ps1 -ozip -v67
PS C:\createESXi> .\ESXi-Customizer-PS.ps1 -v67 -izip .\ESXi-6.7.0-20200804001-standard.zip -pkgdir .\vibs\ 

作業ディレクトリには、 以下のスクリプトを配置(githubが最新版)

追加したいドライバは「vibs」フォルダの下に配置。入手元はこの辺。

ライセンスは普通に取得してください。インストール手順も普通にどうぞ。

Realtek NIC について

ESXi 6.7 まではRealtek向けのドライバが利用できる が、手元の環境だと自動ネゴシエーションで 1000Mbps でリンクアップしなかったり、動作が怪しい。(1000Mbps に固定しても、知らぬ間に 10Mbps, 100Mbps とかに落ちてる事がある)

USB-NICよりマシかな?って思って6.7選んだけど、ぶっちゃけUSB-NICの方が安定してる疑惑あり。

【2022/11/20 追記】これ蟹の問題じゃなくてケーブルの品質が原因っぽいです。きしめんケーブルとか細ケーブルは避けましょう。

USB-NIC について

手元にあるASIXチップ搭載NICを幾つか試したが、NICとして認識しない率が結構高い‥?(USBパススルー対象になってしまう)

  • PLANEX UE-200TXG: NG
  • IODATA ETG4-US2: NG
  • Logitec: LAN-GTJU3: OK 6.7 のみOK (7.0では認識できず)

# ESXi に繋ぎたい時とゲストに繋ぎたい時、どう切り替えればいいんだ‥?

(参考)

https://twitter.com/colinhd8/status/1031468984149766145

PT2 パススルー

Windows で検証した限り、特にハマる要素なし。(PT3 もうまくいくんじゃね?)
冒頭に記載の通り、PCIパススルーを使う際はメモリ割り当てを固定する必要あり。

USBパススルー

結構相性が出た。

ゲストの環境設定で USB ホストを 2.0→3.0 に変えると、認識しなかったデバイスが認識する場合があった。(例えば USB 3.0 対応フラッシュとか。多分逆もありそう)

カードリーダーは、どう頑張っても HITACHI はうまく認識しなかった(再起動すると切れる)。NTT com推奨。

【2021/10/28 追記】

件の日立カードリーダー(M-520U)、デバイスマネージャー上で無効→有効を繰り返すことで、稀にきちんと認識できる場合があることに気付いた。

devcon.exe を使って、スタートアップ時に以下のスクリプトを叩く事でうまく認識できるようになる‥かもしれない。

@echo off
cd %~dp0
: Enable_M520U
echo Enable Smartcard Reader/Writer M-520U
devcon enable "USB\VID_0858&PID_2102&REV_0100"
TIMEOUT /T 5

devcon status "USB\VID_0858&PID_2102&REV_0100"|find "problem: 10"
IF NOT ERRORLEVEL 1 (
  echo Disable Smartcard Reader/Writer M-520U
  devcon disable "USB\VID_0858&PID_2102&REV_0100"
  TIMEOUT /T 3
  GOTO Enable_M520U
)

exit

ハードウェアIDはデバイスマネージャー上で確認して各々置換、devcon.exe の入手方法、スタートアップ スクリプトの指定方法は適当に調べて下さい。

環境によっては、iGPUのパススルーでも「再起動後にうまく認識しない(エラーコード43)」みたいな問題があるようなので、そのスタートアップ処理にも流用できるかもしれません。(シャットダウン時に無効化スクリプトも併せて配備しておく方が安定するかも)

【2021/10/30 更に追記】

PCI-Express to USB3.0 なボードをPCIパススルーすることで問題が生じなくなりました。他にもESXiのUSBパススルーって細かな制約が多そうなので、USBハードウェア常用するなら絶対に刺しておいた方が良さそうです。

【2022/11/20 またまた追記】

オンボードUSBでもホストコントローラごとPCIパススルーできました。上記PT2とは別構成ですが、USBチューナー、カードリーダー両方繋いで安定稼働できています。

そのままPCIパススルーから選ぼうとしても、既定ではグレーアウトしており選択ができないので、以下のパススルー定義に追記をします。

My Virtual School: How to FORCE passthrough the internal USB controller in the mother board

[root@localhost:~] lspci -v

(略)

0000:00:14.0 Serial bus controller USB controller: Intel Corporation 100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller
         Class 0c03: 8086:a12f

[root@localhost:~] vi /etc/vmware/passthru.map

# [Custom] Intel USB 3.0 xHCI Controller
8086  a12f  d3d0     default

ざっくりこんな感じ。

iGPU パススルー (Intel HD Graphics)

【2022/11/20 追記】事前の仕込みとして、ESXiがiGPUを掴まないように画面出力を切っておく必要がある。

esxcli system settings kernel set -s vga -v FALSE

ESXi 6.7u2 の初期ビルド辺りまでは何もせずパススルーを有効化できた気がするが、6.7 の最新パッチ適用 or 7.0以降では、この仕込みをしないとiGPUパススルーを有効化できない。(パススルーON→再起動すると無効に戻ってしまう)

ゲストが Windows の場合

物理端子からの映像出力を諦めれば使えなくもない。

Windows インストールの時点ではパススルーさせず、後からパススルーを追加する。

そのままではドライバがコード31などで読み込まれないので、仮装マシンの詳細オプションに「hypervisor.cpuid.v0 = "FALSE"」を追加する。

後は通常通り Intel の提供ドライバをインストールことで、デバイスの認識まで可能。(物理ポートからの映像出力はできないが、この状態でもQSVは動作)

Windows 10以上だとGPUを跨いで映像をミラーできるので、頑張ればVMRCの仮想コンソールとiGPUの両方に同じ映像を出力可能。(=HD Graphicsを有効にしつつリモート コンソール操作が可能)

【事象:ディスプレイに何も出ない!/デスクトップにアイコンが出ない!】

HD Graphics認識直後、プライマリGPUが物理GPUに切り替わってしまう事がある。リモート コンソールがセカンダリ ディスプレイになってしまうので、何の対処もしていないと詰む。プライマリ画面が見えない(物理端子からは何の信号も出ない)、マウス操作もできない状態で、どうにかしてログインし、どうにかしてプライマリ ディスプレイを切り替える必要がある。

以下のコマンドをスタートアップとかに突っ込んでおくと、スタートアップ時にクローンモードへ切り替えてくれるようになり幸せになれる。併せてユーザーの自動ログインとかも仕込んでおくと良いと思う。

C:\Windows\System32\DisplaySwitch.exe /clone

仕込みはiGPUパススルーを切った状態でやりましょう。

ゲストがUbuntu (18.04/20.04辺り)の場合

結論から言うと使い物にならない。

OSインストールの時点でGPUが繋がっていると操作不能になる為、こちらも後からパススルーを追加する。

フレーバーが Server/Desktop、起動モードが BIOS/EFI の組み合わせで動きが違うように見えるが、大抵画面は出力されないし、SSHすら繋がらず完全にハングアップする事もある。(条件により起動ロゴが出力される事もあるが‥症状が安定しない)

「hypervisor.cpuid.v0 = "FALSE"」の設定有無で動きは変わる様子。(ドライバが何かチェックしてる?)

#この手の情報を調べてると「mce.enable = "TRUE"」と「vhu.enable = "TRUE"」が並んで出てくる事があるが、どちらもよく調べてないので効果は不明。

ゲストがCentOS (7/8辺り)の場合

やや厳しい。

OSインストール後にiGPUを接続する方法のみ検証中。

デスクトップなしの場合、起動自体は問題なく完了するが、時間差でi915ドライバを読み込むのか?途中でVMRSのリモートコンソールが操作不能になる。(物理ディスプレイに何も出ない‥)

(Linux) 物理端子の認識状況
# ls -l /sys/class/drm/
# grep . /sys/class/drm/card?-*/status

Intel Graphics - ArchWiki 

(脱線)シリアル接続を使ったコンソール ログイン

↑の調査で起動の様子を確認する為、仮想環境とのシリアル接続を試してみた。操作される側のゲスト設定は以下参照。

www.hiroom2.com

www.hiroom2.com

隣にWindows ゲストOSを準備して、それぞれの仮想マシンにシリアル ポートを追加する。

f:id:naba_san:20201004173048p:plain f:id:naba_san:20201004173112p:plain

Windows 側から TeraTerm とか開いて立ち上げると、懐かしい感じの起動メッセージが出てきてコンソール操作できる。

(更に脱線)

VMRCでクリップボード転送したい場合、仮想マシンの詳細設定で以下のオプションを設定する。

isolation.tools.copy.disable : FALSE
isolation.tools.paste.disable : FALSE
isolation.tools.setGUIOptions.enable : TRUE

(メモ)ESXi を代替できそうなもの

  • oVirt
  • Proxmox VE
  • kimchi

 (さらにメモ)現時点で一番正解に近そうな情報源

7.0なんだよなぁ‥CPUの世代も違うし動くかなぁ‥頑張って上げるか‥

www.virtuallyghetto.com

NEC VersaPro J タイプVS+ウルトラブック プロ キーボード=?

ここに去年3万5千円でポチった*1NECタブレットがあるじゃろ。


ここに3万円でポチった、ThinkPad Helix ウルトラブック プロ キーボードがあるじゃろ。


これと


これを


こうして


こうじゃ!!


【補足】ひっくり返して装着すると…

スタンドモード、テントモードにもなります。まさにYOGA。


装着したままタブレットモードでも利用可能。クラムシェルモードの時、画面が狭いのと、重心が高い事が気になるくらい。

安く入手できるなら、買っておいても悪くないと思います。

製品情報とか

http://www.bizpc.nec.co.jp/pcseek/cgi-bin/cpu_smart.pl?KATA=PC-VK12CSKE56FK
http://amzn.to/2pIakPO

http://akiba-pc.watch.impress.co.jp/docs/wakiba/find/1027916.html
http://akiba-pc.watch.impress.co.jp/docs/wakiba/find/1029376.html

  • ThinkPad Helix ウルトラブック プロ キーボード - 日本語 (4X30G93920)

http://www3.lenovo.com/jp/ja/p/4X30G93920
http://amzn.to/2pHJDe7

独り言

あきばおー通販でタブレット買ってから、ここに至るまで、フォリオラップケースとか、2台目の ThinkPad ワイヤレス トラックパッド キーボードとか、色々買い込みました。

総額は結構な出費になってしまってます…

Bay-Trail M Atomの中華PCにUbuntu 16.04(.2)をインストールしました

使い慣れるのでCentOS入れたかったんですが、そのままではKernelがemmc諸々に対応してくれないとの事なので断念。

Ubuntu LTSを下地に、DockerなりKVMなり(動くのか?)何なり使えばいいかと割り切りつつ、Ubuntu Server入れてみました。

方針

メンテナンスが必要なものは増やしたくない*1

  • インストール後の環境へバイナリを差し込まない。
  • 同様に、カーネルビルドは極力避ける。

準備したもの

現物
  • 中華PC

Bay-Trail M なAtomを搭載した3735Fマシン。所謂32bit EFI

まだ円安だった頃に、1万円くらいで買ったやつ。今回、ジャンク箱の奥底から発掘してきました。

FAT32でフォーマットしておく。

インストーラの準備
  • Ubuntu 16.04.2 LTS (Xenial Xerus)

公式 または ftp.riken.jp から、「64-bit PC (AMD64) server install image」(ubuntu-16.04.2-server-amd64.iso)
ISOの中身を展開し、そのままUSBメモリにコピーする。

  • USB起動に使う、EFI GRUBイメージ

bootia32.efi (jfwells - github)
保存した bootia32.efi を、USBメモリの /BOOT/EFI/ へ配置する。

これでインストーラUSBメモリの準備はOK。

インストール手順

インストーラ起動からインストール完了まで

SecureBootを切った状態でUSBメモリ起動。

幾つかの問題点を避けつつ、一通りインストール。

一通りインストールが終わった時、GRUBの設定でコケました。この時点ではIA32 EFIに対応しないようです。

GRUBの手動設定か何かを選び、ガイドインストーラを抜け、インストールの完了操作を行いました。
(LVMルートを示すデバイスパスが表示されるので、予め控えておきます。)

USBメモリから対象環境起動

再度インストーラを入れたUSBを起動し、インストール済みの環境を立ち上げます。

  • GRUBの起動メニューで「c」キーを押下
  • コマンドを叩いて環境起動

ls (hd1,gpt2)
linux (hd1,gpt2)/vmlinuz-4.4.0-62-generic root=【控えておいたデバイスパス(「/dev/mapper/」で始まるやつ)】
initrd (hd1,gpt2)/initrd.img-4.4.0-62-generic
boot

※ hd1, gpt2は、LVMとは別に切られたbootパスを指定するように、適宜に読み替えて下さい。
※ デバイスパーティション「(hd1,gpt2)」等を指定した後は、tab補完が効きます。

これでインストール済みの環境が起動しました。

(番外編)ネットワーク接続(NIC)の追加、設定

今回の中華PCは、小型PCなので有線NICを搭載しておらず、インストール完了後にUSB NICを追加しました。

少し手間取りましたが、以下の手順でNICを確認し、認識させました。

  • まずはインタフェース名を確認

# lshw -C network

  *-network
       description: Ethernet interface
       physical id: 1
       bus info: usb@1:2.4
       logical name: enx0090******** (控えておく)
       serial: 00:90:**:**:**:**
       size: 1Gbit/s
       capacity: 1Gbit/s
       capabilities: ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=ax88179_178a duplex=full ip=**.***.*.*** link=yes multicast=yes port=MII speed=1Gbit/s
  • 続けて設定追加

# vim /etc/network/interfaces

auto enx0090********
iface enx0090******** inet dhcp

# ifdown enx0090********
# ifup enx0090********

  • 無事疎通

# ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=47 time=37.7 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=47 time=37.7 ms

これで apt-get できるようになりました!

EFI環境へのGRUBインストール
  • IA32 EFI GRUBはaptで入手できました。

# apt-get install grub-efi-ia32

# grub-install --efi-directory=/boot/efi

Installing for i386-efi platform.
Installation finished. No error reported.

※ 他のイメージを間違えて削除しないように注意。

  • GRUBの設定は、修正が必要でしたので、下記の通り書き換えます。

# vim /etc/default/grub

#GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX_DEFAULT=""

※ splash オプションが邪魔でした。quiet は、あってもなくても良さそうです。
※ nomodeset の設定が必要というページを散見しましたが、これも設定有無にかかわらず起動しました。

  • GRUB の設定内容を反映します。

# update-grub

Generating grub configuration file ...
Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.
Found linux image: /boot/vmlinuz-4.4.0-62-generic
Found initrd image: /boot/initrd.img-4.4.0-62-generic
Adding boot menu entry for EFI firmware configuration
done
  • (蛇足)EFIの設定状況確認

# efibootmgr

BootCurrent: 0000
Timeout: 5 seconds
BootOrder: 0000,0003,0001,0002,0004
Boot0000* ubuntu
Boot0001* UEFI:CD/DVD Drive
Boot0002* UEFI:Removable Device
Boot0003  UEFI: Built-in EFI Shell
Boot0004* UEFI:Network Device
  • 再起動して動作を確認

# shutdown -r now

EFI上で、起動順が正しく設定されているか確認する。

一通りの作業を終えて、とりあえず起動するようになりました。

*1:NonPAEの時、後々の運用が面倒だったので

*2:たぶんmmcのブロックに異常があって、LVMだからすんなり進んだ?

Servlet環境構築時の用語メモ

Struts1/Struts2のお仕事受けたのはいいけど、まじめにサーブレット環境構築した事なんてないぞ・・

とりあえず用語を並べてみる。設定ファイル大杉。。

Servlet

Javaを使ったサーバサイド処理の仕組みを決めた仕様。エンジンの実装は別で存在する。

コンテキスト

サーブレットエンジン上で動作させる、アプリケーションの単位のこと。
サーブレットエンジン(Tomcat)上では、複数のアプリケーションを同時に起動できる。
このとき、アプリケーション毎にセッションや設定(URLの解決等)を行っており、「コンテキスト」として管理する。

コンテキストルート

アプリケーションのルートに当たるディレクトリパス、またはそれに紐づくURL。

web.xml / デプロイメント ディスクリプタ(配置記述子)

サーブレットエンジンがコンテキストを初期化する際に必要となる、基本設定を書くところ。

Tomcat の場合、コンテキストルート内の /WEB-INF/web.xml に配置されたファイルを参照する。
※ デプロイメント ディスクリプタ自体は、Servlet の標準に則って配置するもの。

URLと各クラスのマッピング、メッセージ画面の定義などを記述する。
新しい画面を作成する場合、原則として編集が必要となる(または、WebServlet アノテーションでURLパターンを記述する)。

他にフレームワークを組み合わせる場合、ここでフレームワークの指定クラスを全URLパターンに紐づけたりする事も。

WEB-INF, META-INF

Servlet 上、クライアントから見せないディレクトリ。
設定ファイルなどを配置する場合、原則としてここに置く。

JVMの動作に必要なものは、原則として WEB-INF 以下に配置する。

[WEB-INF/classes] : コンパイル済み class ファイル (プロパティもここに配置する)
[WEB-INF/lib] 参照ライブラリ(jar)

Tomcat

言わずと知れたサーブレットエンジン。
Tomcatのバージョンにより、準拠しているServletのバージョンが異なる。

server.xml

Tomcat固有のサーバ環境設定ファイル。

原則として、Tomcat の環境毎に1つのみ存在し、待機ポートの指定、読み込むコンテキストなどを記述する。
コネクションプールを利用する場合、ここで Resource 要素を使ってDB資源を記述する。

※ 特定コンテキストのみに紐づく設定は、context.xml としてデプロイ対象に含めることが可能(Tomcat 5.5辺りから)。

context.xml

server.xml 同様、これも Tomcat 固有の設定ファイル。
/META-INF/context.xml に配置されたファイルを参照する。

server.xml から、 要素の中身をデプロイ対象のアプリケーションに吐き出したもの。
つまり対象アプリケーション(コンテキスト)固有の Tomcat に対する設定があれば、ここに書く。
(共用環境などでは、server.xml 側で許可されていない事もあるらしい。)

コネクションプールで使用するDB資源も、ここに記述可能。

Eclipse

ここもいろいろハマった。

動的Webプロジェクト

Tomcat と連携させた場合、プロジェクト名がそのままコンテキスト名になる。

WebContent/

Eclipseの動的Web プロジェクトを扱う場合のみ、ドキュメント ルートとなるディレクトリ(初期設定でそのようになっているだけ)。

デプロイの設定

プロジェクトのプロパティから「Web デプロイメント・アセンブリー」で変更可能。

動的にビルドされた、Tomcat が実際に利用するファイルは、
「workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps」
等に展開されるので、設定する際はココと突き合わせるとよい。(多少パスは変わるはず)

Windows 10 Pro向けのWindows Updateグループポリシー設定メモ

自動再起動させたくないので。

コンピュータの構成 > 管理用テンプレート > Windows コンポーネント > Windows Update

自動更新を有効にする
  • 有効
  • 自動更新の構成 : 2 - ダウンロードとインストールを通知
スケジュールされた時刻に常に自動的に更新する
  • 無効
スケジュールされた自動更新のインストールで、ログインしているユーザがいる場合には自動的に更新しない
  • 有効

SELinux扱うときの参考になるページ

Red Hat系をメインに、よさげな記事を備忘録として。(RedHatの資料読みづらい。。)

Qiita

SELinuxのせいで動かない」撲滅ガイド

SELinuxとのお付き合いで知っておくべき指針がまとまってる。考えれてみれば、言うまでもない事も多いけど。
http://qiita.com/yunano/items/857ab36faa0d695573dd

JavaScript 連想配列(オブジェクト)ツリーに対する複合キーのサンプル

単純な話ですが、データ取得にハマったので、備忘録としてサンプルをメモしておきます。

サンプルデータ

var testMap =({
  "depth1-a": {
    "depth2-a": {
        "depth3-x": "1",
        "depth3-y": "2"
    },
    "depth2-b": {
        "depth3-z": "3"
    }
  },
  "depth1-b": "depth1-value"
});

普通に取得しようとすると‥

こんな具合になります。(こうですよね?)

実行結果(正常ケース)
console.log(testMap["depth1-a"]["depth2-a"]["depth3-x"]);
1
実行結果(深さ違い、キー不一致)
console.log(testMap["depth1-b"]["depth2-a"]["depth3-x"]);
VM1132:1 Uncaught TypeError: Cannot read property 'depth3-x' of undefined(…)
実行結果(キー不一致)
console.log(testMap["depth1-X"]["depth2-a"]["depth3-x"]);
VM1133:1 Uncaught TypeError: Cannot read property 'depth2-a' of undefined(…)

内包オブジェクトの深さが異なる、または一部のキーが一致しない場合、途中にundefinedを挟むケースが生じる為、例外が発生して都合が悪いです。

深さに関係なく、一律にundefinedが帰ってくると嬉しいなーと。

探し方が悪いのか、良いサンプルが見つからないので書いてみた。

function getValue(map, keyArray) {
  for (var i = 0; i < keyArray.length; i++) {
    var key = keyArray[i];
    map= map[key];
    if(map == undefined) {
      return undefined;
    }
  }
  return map;
};
実行結果(正常ケース)
getValue(testMap, ["depth1-a","depth2-a","depth3-x"]);
"1"
getValue(testMap, ["depth1-a","depth2-b","depth3-z"]);
"3"
実行結果(異常ケース)
getValue(testMap, ["depth1-b","depth2-a","depth3-x"]);
undefined
getValue(testMap, ["depth1-X","depth2-a","depth3-x"]);
undefined