読者です 読者をやめる 読者になる 読者になる

mixi engineer blog

ミクシィ・グループで、実際に開発に携わっているエンジニア達が執筆している公式ブログです。様々なサービスの開発や運用を行っていく際に得た技術情報から採用情報まで、有益な情報を幅広く取り扱っています。

mixiのサーバOS移行のお話 - 前回補足&インストール編

fedora grub mixi

こんにちは。新しもの好きが集まる運用部アプリ運用グループの清水です。

前回の記事では、多くの反響をいただきました。ありがとうございます。
Twitterや、はてブのほとんどのコメントを読ませていただきました。
みなさんのOSの宗派が垣間見えた気がします。

さまざまなコメントをいただいていた中で、よくある代表的なコメントについて、改めてこの場を借りてお答えしたいと思います。

2012年12月28日追記:
以下のQAにつきまして、いわゆる"ネタ"として書きましたが、誤解を招き、不適切な表現で不快な思いをされた方々へ深くお詫び申し上げます。
また、QAの一部に関わるところですが、OS標準のパッケージを否定するつもりは全くございません。 Linuxを安心して使うことができるのは、Linuxディストリビューションに携わっているデベロッパーの方々の素晴らしい活動や成果によるもの、というのが揺るぎない事実であると認識しております。 弊社のシステムの都合で、一部のパッケージをリビルドして運用しているということを、あえて別の表現で書いたことで、誤解を招いてしまいました。 重ねて深くお詫び申し上げます。


Q. なんでRHELじゃないの?

A. Fedoraで困ることもなく安定稼働させてきました。


Q. なんでCentOSじゃないの?

A. 一時期、新しいバージョンでるでる詐欺に遭いました。


Q. セキュリティやばい

A. ひと通りのセキュリティチェック、パッチ、バージョンアップをおこない、ペネトレーションテストをクリアしています。


Q. OSは有償サポート必須ですよね?

A. 自社のエンジニアで解決できますし、ノウハウも貯まります。


Q. 正直不安です。

A. 正直安定しています。


Q. NIC認識しないってどんなNIC?

A. メーカー標準のNICです。実はRAIDも認識しなかったんです。2005年くらいの話です。


Q. 独自でビルドとか工数もったいない。

A. OSデフォルトのRPMをそのまま使うのは小学生まで、と習った記憶があります。


Q. どうせこれからもアップデートしないのでは?

A. 嘘だと思われるかもしれませんが、定期的にアップデートする予定です。


Q. RHELのOS代なんてゴミみたいなもんですよね?

A. ヒント:サーバ台数。


Q. でもなんでFedora 17?

A. Beefy Miracle カッコいいですよね。着ぐるみが欲しいです。お腹空いたのでホットドッグ食べたくなってきました。

このあたりで話を戻して......

これからの記事では、Fedora 17で遭遇した様々な問題について紹介します。
今後、Fedoraをサーバ用途に検討される方や、Kernel 3.x系を使う方に、少しでも参考になれば幸いです。

Fedora 17がインストールできない!

だからFedoraを使うなと(ry みたいなことはさておき、
Fedora 17をサーバマシンにインストールできなかった問題に遭遇した時の事例を紹介したいと思います。
前回の記事の最後にスクリーンショットとエラーメッセージを書きました。
DVDでもkickstartを使っても、

"There was an error installing the bootloader. The system may not be bootable."

というエラーが発生して、インストールの途中で中断されます。

エラー内容は、文章の通りですが、
「ブートローダのインストール中にエラーが起きたので、ブートできないかもね」
というもの。

エラーが起きている箇所を探してみる

Anacondaのコンソールでエラーの原因を探ってみることにしました。

[anaconda root@(none) /]# less /tmp/program.log

で、ログを確認。

19:14:37,207 INFO program: Running... grub2-install --no-floppy /dev/sda
19:14:39,134 ERR program: Installtion finished. No error reported.
19:14:39,295 INFO program: Running... grub2-set-default Fedora Linux, with Linux 3.3.4-5.fc17.x86_64
19:14:39,385 INFO program: Running... grub2-mkconfig -o /boot/grub2/grub.cfg
19:14:39,552 ERR program: Generating grub.cfg ...

grub.cfgの生成時にエラーが出ていることを確認。
直接、grub2-mkconfigコマンドを実行してみます。

[anaconda root@(none) /]# chroot /mnt/sysimage
[anaconda root@hostname /]# grub2-mkconfig -o /boot/grub2/grub.cfg ; echo $?
Generating grub.cfg ...
1

エラーメッセージは特に無く、終了コードが1で返ってきて失敗していました。

grub2-mkconfigをオプションなしでConfigの内容を表示させてみる。

[anaconda root@hostname /]# grub2-mkconfig
if [ x$feature_default_font_path = xy ] ; then
    font=unicode
else
insmod part_gpt
insmod ext2
set root='hd0,gpt4'

ここで止まっていた。

grub2-mkconfigスクリプトを追う

grub2-mkconfigはシェルスクリプトなので、簡単にコードを追うことができます。

/usr/share/grub/grub-mkconfig_lib

prepare_grub_to_access_device関数内の

hints="`"${grub_probe}" --device "${device}" --target=hints_string 2> /dev/null`"

この1行でエラーとなり、スクリプトが中断されていました。

${grub_probe}は、grub2-probeコマンドということなので、直接コマンドを実行してみます。

[anaconda root@hostname /]# grub2-probe --device /dev/sda --target=hints_string
grub2-probe: error: cannot open `/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host4/port-4:0/end_device-4:0/sas_device:end_device-4:0/phy_identifier': No such file or directory.

「No such file or directory」ということは、パスが間違っている?と疑い、実際のパスを追ってみると

/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host4/port-4:0/end_device-4:0/sas_device/end_device-4:0/phy_identifier

が実際に存在するパス。

/sys/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host4/port-4:0/end_device-4:0/sas_device:end_device-4:0/phy_identifier

がgrub2-probeが参照しようとするパス。
sas_deviceのあとの1箇所だけ、スラッシュとなるところがコロンになっていました。

grub2-probeのコードを追う

さらに原因を調べるにはGRUB2のソースコードを追う必要がありました。

http://alpha.gnu.org/gnu/grub/

から grub-2.00~beta4.tar.gz(当時のGRUBバージョン) をダウンロードして、まず grub-probe.c を見てみます。

hints_stringの文字列を条件にしているこの箇所があやしい。

util/grub-probe.c

static void
probe (const char *path, char **device_names, char delim)
...
      if (print == PRINT_HINT_STR)
	{
	  const char *osdev = grub_util_biosdisk_get_osdev (dev->disk);
	  const char *ofpath = osdev ? grub_util_devname_to_ofpath (osdev) : 0;
...

パスの問題の可能性が高いことから grub_util_devname_to_ofpath 関数を追う。

util/ieee1275/ofpath.c

char *
grub_util_devname_to_ofpath (const char *sys_devname)
{
  char *name_buf, *device, *devnode, *devicenode, *ofpath;

  name_buf = xrealpath (sys_devname);

  device = get_basename (name_buf);
  devnode = strip_trailing_digits (name_buf);
  devicenode = strip_trailing_digits (device);

  if (device[0] == 'h' && device[1] == 'd')
    ofpath = of_path_of_ide(name_buf, device, devnode, devicenode);
  else if (device[0] == 's'
	   && (device[1] == 'd' || device[1] == 'r'))
    ofpath = of_path_of_scsi(name_buf, device, devnode, devicenode);
...

マシンのディスクはSAS(Serial Attached SCSI)なので、of_path_of_scsi 関数をさらに追う。

util/ieee1275/ofpath.c

static char *
of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *device,
		const char *devnode __attribute__((unused)),
		const char *devicenode)
{
  const char *p, *digit_string, *disk_name;
  int host, bus, tgt, lun;
  char *sysfs_path, disk[MAX_DISK_CAT - sizeof ("/fp@0,0")];
  char *of_path;

  sysfs_path = block_device_get_sysfs_path_and_link(devicenode);
  p = get_basename (sysfs_path);
  sscanf(p, "%d:%d:%d:%d", &host, &bus, &tgt, &lun);
  check_sas (sysfs_path, &tgt);

check_sas 関数へと進む。


util/ieee1275/ofpath.c

static void
check_sas (char *sysfs_path, int *tgt)
{
...

  path_size = (strlen (p) + strlen (ed)
	       + sizeof ("%s/sas_device:%s/phy_identifier"));
  path = xmalloc (path_size);
  snprintf (path, path_size, "%s/sas_device:%s/phy_identifier", p, ed);

  fd = open (path, O_RDONLY);
  if (fd < 0)
    grub_util_error (_("cannot open `%s': %s"), path, strerror (errno));

...
}

まさにこのコード。

snprintf (path, path_size, "%s/sas_device:%s/phy_identifier", p, ed);

でパス文字列を構成していて、コロンで区切られていました。
これをスラッシュに直してみます。

snprintf (path, path_size, "%s/sas_device/%s/phy_identifier", p, ed);

この修正をpatch化し、GRUB2のRPMを作りなおして、Anacondaに使ってもらえるようにrepo設定をすると問題は解消しました。

まとめ

GRUBのバグによって、Fedora 17は、SASを搭載したマシンにはインストールできないという問題でした。
パッチを当てたバージョンのRPMをインストール用のリポジトリに置くことでインストールできるようになります。

この問題はサーバ用途では大きな影響を与えそうという事もあり、

Red Hat Bugzilla
https://bugzilla.redhat.com/show_bug.cgi?id=826833

にレポートを提出しました。併せて、

GNU GRUBバグML
http://savannah.gnu.org/bugs/?36572

にもレポート提出しました。
Red Hat Bugzillaの方のレポートを見るとわかるのですが、多くの方がこの問題に遭遇していたようです。

これらは、無事にコミットされ、GRUB 2正式リリース版で取り込まれています。
今後、GRUB 2を使ったディストリビューションに対しても少しばかりか貢献できたのではと思っています。次期RHEL 7にもGRUB 2が採用される話もありますね。

何もGRUBを修正してまでFedora使わなくてもいいじゃん!って思う方も多いかもしれません。
OSに限らず、ミドルウェアやフレームワークなどのOSSを使っていく際に、新しい機能を使って何かを実現するために、リリースされたばかりのものを使うケースがあると思います。

そして、何か問題に直面した時に、何も考えずに古いバージョンに戻すではなく、新しいバージョンの何が問題なのか、問題がわかればパッチを提供してOSSへ貢献したり、さらに使い続けるのも大事だと考えています。

次回予告

次回は、新しいKernelの導入に際して起きた問題や注意点等について紹介したいと思います。
ぜひご期待ください。