ablog

不器用で落着きのない技術者のメモ

macOS上でLinuxアプリケーションをそのまま動作させるアプリ ケーション Noah を使ってみた

7. macOSやWindowsでLinuxバイナリを動かすプログラムを作った話 (ぬるぽへ) で聞いた Noah をインストールして使ってみた。

Noahとは

ハイパーバイザ技術を用いたクロスOSなLinuxバイナリ互換プラットフォームの構築
佐伯 学哉・西脇 友一
ー Noah : Hypervisor-Based Darwin Subsystem for Linux


Noah
NoahはmacOS上でLinuxアプリケーションをそのまま動作させるアプリケーションです。ハイパーバイザを用いた新しい手法で、従来のバイナリ互換技術よりも安全かつ高速なLinuxエミュレーションを実現。Noahを使えば、apt-getやLinux向けgcc、それにあなたがこれから作る新しいLinuxアプリケーションが、そのままmacOSで動作します。


もう移植を待つ必要も、する必要もありません。
Noahの登場と、最近登場したWSLやLinuxulatorの組み合わせで、Linuxアプリケーションさえ開発すれば、それがそのままmacOS, Windows,FreeBSD, Linuxの4つの主要なOSで動作します。LinuxはいまやPOSIXに替わる次世代のリッチな標準開発規格です。

https://www.ipa.go.jp/files/000059135.pdf

Noah が開発された背景やメリット、アーキテクチャなどは Noah Hypervisor-Based Darwin Subsystem for Linux に詳しく書かれています。

インストール

% brew install linux-noah/noah/noah

起動する

% noah
Noah is installing the initial filesystem in ~/.noah/tree. Proceed? [Y/n] Y
Password:

(中略)

Noah is still under development, so please enable it at your own risk! [y/N] y

(中略)

I have no name!@186590d05b55:~$
I have no name!@186590d05b55:~$ ls -1
AWS Schema Conversion Tool
Applications
Books
Desktop
Documents
Downloads

遊んでみる

  • Noah で perl を実行する
I have no name!@186590d05b55:/bin$ perl -le 'while(1){print qq/foo/}' > /dev/null
%  sudo dtruss -deflo -p 3759
Password:
	PID/THRD  RELATIVE  ELAPSD    CPU SYSCALL(args) 		 = return

(中略)

 4507/0xa56f:  15708753       3      2 writev(0x1, 0x7FFF50A8C450, 0x1)		 = 4 0
 4507/0xa56f:  15708760       4      2 writev(0x1, 0x7FFF50A8C450, 0x1)		 = 4 0
 4507/0xa56f:  15708767       4      2 writev(0x1, 0x7FFF50A8C450, 0x1)		 = 4 0
 4507/0xa56f:  15708775       4      2 writev(0x1, 0x7FFF50A8C450, 0x1)		 = 4 0
 4507/0xa56f:  15708782       4      2 writev(0x1, 0x7FFF50A8C450, 0x1)		 = 4 0
 4507/0xa56f:  15708789       3      1 writev(0x1, 0x7FFF50A8C450, 0x1)		 = 4 0
 4507/0xa56f:  15708796       4      2 writev(0x1, 0x7FFF50A8C450, 0x1)		 = 4 0
 4507/0xa56f:  15708814       6      3 writev(0x1, 0x7FFF50A8C450, 0x1)		 = 4 0


%  sudo dtruss -deflo sudo -u yohei-a noah 2>dtruss.log
% grep -C 5 noah  dtruss.log
 6323/0x112ba:      6904       3      2 read_nocancel(0x6, "##\n# Group Database\n# \n# Note that this file is consulted directly only when the system is running\n# in single-user mode.  At other times this information is provided by\n# Open Directory.\n#\n# See the opendirectoryd(8) man page for additional information ab", 0x1000)		 = 2600 0
 6323/0x112ba:      6985       1      0 read_nocancel(0x6, "s:*:53:\n_mcxalr:*:54:\n_appleevents:*:55:\n_geod:*:56:\n_serialnumberd:*:58:\n_devdocs:*:59:\n_sandbox:*:60:\nlocalaccounts:*:61:\nnetaccounts:*:62:\n_mdnsresponder:*:65:\n_uucp:*:66:\n_ard:*:67:\ndialer:*:68:\nnetwork:*:69:\n_www:*:70:_devicemgr,_teamsserver\n_eppc:*:7", 0x1000)		 = 0 0
 6323/0x112ba:      6990       4      3 close_nocancel(0x6)		 = 0 0
 6323/0x112ba:      7042       6      5 setgroups(0xD, 0x7FAA33822AA8, 0x1000)		 = 0 0
 6323/0x112ba:      7047       4      3 seteuid(0x3DD45FE0, 0x7FAA33822AA8, 0x1000)		 = 0 0
 6323/0x112ba:      7069      15     14 stat64("/Users/yohei-a/.pyenv/shims/noah\0", 0x7FAA32D03420, 0x1000)		 = -1 Err#2
 6323/0x112ba:      7072       2      1 stat64("/Users/yohei-a/.pyenv/bin/noah\0", 0x7FAA32D03420, 0x1000)		 = -1 Err#2
 6323/0x112ba:      7082       9      8 stat64("/usr/local/bin/noah\0", 0x7FAA32D03420, 0x1000)		 = 0 0
 6323/0x112ba:      7088       4      3 seteuid(0x0, 0x7FAA32D03420, 0x1000)		 = 0 0
 6323/0x112ba:      7089       1      0 setuid(0x0, 0x7FAA32D03420, 0x1000)		 = 0 0
 6323/0x112ba:      7093       4      3 setegid(0x0, 0x7FAA32D03420, 0x1000)		 = 0 0
 6323/0x112ba:      7095       1      0 setgroups(0x16, 0x7FAA34001CF0, 0x1000)		 = -1 Err#22
 6323/0x112ba:      7098       3      1 sysctl([CTL_KERN, 18, 0, 0, 0, 0] (2), 0x7FFF592A3364, 0x7FFF592A3368, 0x0, 0x0)		 = 0 0
--
--
 6324/0x112c6:      8130       1      0 lseek(0x3, 0x0, 0x1)		 = 0 0
 6324/0x112c6:      8140       3      2 read(0x3, "/System/Library/Perl/Extras/5.18\n\004\b\0", 0x2000)		 = 33 0
 6324/0x112c6:      8141       1      0 read(0x3, "@\004\b\0", 0x2000)		 = 0 0
 6324/0x112c6:      8146       5      3 close(0x3)		 = 0 0
 6324/0x112c6:      8156       8      6 stat64("/System/Library/Perl/Extras/5.18/darwin-thread-multi-2level\0", 0x7FFF52ABB390, 0x2000)		 = 0 0
 6324/0x112c6:      8174      12     11 open("/usr/local/bin/noah\0", 0x0, 0x1B6)		 = 3 0
 6324/0x112c6:      8176       1      0 ioctl(0x3, 0x4004667A, 0x7FFF52ABB29C)		 = -1 Err#25
 6324/0x112c6:      8178       1      0 ioctl(0x3, 0x40487413, 0x7FFF52ABB2A0)		 = -1 Err#25
 6324/0x112c6:      8179       1      0 lseek(0x3, 0x0, 0x1)		 = 0 0
 6324/0x112c6:      8188       1      0 fcntl(0x3, 0x2, 0x1)		 = 0 0
 6324/0x112c6:      8195       2      1 fstat64(0x3, 0x7FFF52ABB6B0, 0x1)		 = 0 0
--
--
 6324/0x112c6:     60900      12     10 open_nocancel("/etc/.mdns_debug\0", 0x0, 0x0)		 = -1 Err#2
 6324/0x112c6:     60904       1      0 issetugid(0x7FFFA3A8422A, 0x0, 0x0)		 = 0 0
 6324/0x112c6:     60905       1      0 issetugid(0x7FFFA3A8422A, 0x0, 0x0)		 = 0 0
 6324/0x112c6:     61089       2      0 getuid(0x7FFFA3A8422A, 0x0, 0x0)		 = 1037328352 0
 6324/0x112c6:     61473       3      1 fcntl(0x3, 0x2, 0x1)		 = 0 0
 6324/0x112c6:     61695       9      7 stat64("/Users/yohei-a/.noah\0", 0x7F96AE001270, 0x1)		 = 0 0
 6324/0x112c6:     61702       6      5 stat64("/Users/yohei-a/.noah/tree\0", 0x7F96AE001270, 0x1)		 = 0 0
 6324/0x112c6:     61705       1      0 geteuid(0x7F96ADC427E0, 0x7F96Adtrace: error on enabled probe ID 2109 (ID 266: syscall::execve:return): invalid address (0x7f96adc0a6e0) in action #12 at DIF offset 24
E001270, 0x1)		 = 1037328352 0
--
 6324/0x112c6:     61705       1      0 geteuid(0x7F96ADC427E0, 0x7F96Adtrace: error on enabled probe ID 2109 (ID 266: syscall::execve:return): invalid address (0x7f96adc0a6e0) in action #12 at DIF offset 24
E001270, 0x1)		 = 1037328352 0
 6324/0x112c6:     61715       7      7 stat64("/usr/local/Cellar/noah/0.5.0/libexec/noah\0", 0x7F96AE001270, 0x1)		 = 0 0
 6324/0x112c6:     61778       2      1 lseek(0x3, 0x75C, 0x0)		 = 1884 0
 6324/0x112c6:     61779       1      0 lseek(0x3, 0x0, 0x1)		 = 1884 0
 6324/0x112c6:     61796       7      5 pipe(0x3, 0x0, 0x1)		 = 4 0
 6324/0x112c6:     61805       2      0 sigprocmask(0x1, 0x7FFF52ABB9A4, 0x7FFF52ABB9A0)		 = 0x0 0
 6324/0x112c6:     62642     805    803 fork()		 = 6325 0
--
--
 6325/0x112c9:      5884       4      3 seteuid(0x3DD45FE0, 0x7FFF5645CAB8, 0x1)		 = 0 0
 6325/0x112c9:      5903      12      9 sysctlbyname(kern.hv_support, 0xF, 0x7FFF5645E76C, 0x7FFF5645E760, 0x0)		 = 0 0
 6325/0x112c9:      5971      29     27 stat64("/\0", 0x7FFF5645CA10, 0x7FFF5645E76C)		 = 0 0
 6325/0x112c9:      5992      19     17 getattrlist("/Users\0", 0x7FFFA3A2EB04, 0x7FFF5645E320)		 = 0 0
 6325/0x112c9:      6009      17     16 getattrlist("/Users/yohei-a\0", 0x7FFFA3A2EB04, 0x7FFF5645E320)		 = 0 0
 6325/0x112c9:      6019       9      8 getattrlist("/Users/yohei-a/.noah\0", 0x7FFFA3A2EB04, 0x7FFF5645E320)		 = 0 0
 6325/0x112c9:      6024       5      4 getattrlist("/Users/yohei-a/.noah/tree\0", 0x7FFFA3A2EB04, 0x7FFF5645E320)		 = 0 0
 6325/0x112c9:      6541       9      4 mmap(0x0, 0x40000000, 0x7, 0x1201, 0xFFFFFFFF, 0x0)		 = 0x109DC3000 0
 6325/0x112c9:      6656       2      0 sigaction(0x1, 0x0, 0x7FFF5645E738)		 = 0 0
 6325/0x112c9:      6657       1      0 sigaction(0x2, 0x0, 0x7FFF5645E738)		 = 0 0
 6325/0x112c9:      6658       0      0 sigaction(0x3, 0x0, 0x7FFF5645E738)		 = 0 0
 6325/0x112c9:      6659       0      0 sigaction(0x4, 0x0, 0x7FFF5645E738)		 = 0 0
--
--
 6325/0x112c9:      6677       0      0 sigaction(0x1C, 0x0, 0x7FFF5645E738)		 = 0 0
 6325/0x112c9:      6678       0      0 sigaction(0x1D, 0x0, 0x7FFF5645E738)		 = 0 0
 6325/0x112c9:      6679       0      0 sigaction(0x1E, 0x0, 0x7FFF5645E738)		 = 0 0
 6325/0x112c9:      6680       1      0 sigaction(0x1F, 0x0, 0x7FFF5645E738)		 = 0 0
 6325/0x112c9:      6687       1      0 sigprocmask(0x0, 0x0, 0x7FFF5645E738)		 = 0x0 0
 6325/0x112c9:      6715      23     22 open("/Users/yohei-a/.noah/tree\0", 0x100000, 0x0)		 = 3 0
 6325/0x112c9:      6732       2      0 getrlimit(0x1008, 0x7FFF5645E730, 0x0)		 = 0 0
 6325/0x112c9:      6741       2      1 fcntl(0x0, 0x1, 0x0)		 = 0 0
 6325/0x112c9:      6742       1      0 fcntl(0x1, 0x1, 0x97C6B00)		 = 0 0
 6325/0x112c9:      6743       1      0 fcntl(0x2, 0x1, 0x97C6B00)		 = 0 0
 6325/0x112c9:      6744       0      0 fcntl(0x4, 0x1, 0x97C6B00)		 = -1 Err#9