ファイルサーバのRAIDディスクが1つ飛んだので修復してみる

この記事を書いているこのタイミングではまだRAIDアレイのリビルド中なので終了待ちです。今回はRAIDアレイの修復作業ではなくもっと違ったところで大変なことが起こっていたのでそれをメインに書いてみたいと思います。

 

RAID5のディスクの認識ができなくなった

まずはじめに出た問題がこれ。ログを見る限りでは4日前ほどに不良セクタの発生でI/Oエラーが出てアクセスができなくなったようです。その前後でHDDのコントローラが応答不能に陥り強制的にRAIDアレイから除外された、という状態だったようです。早めに気がついてよかったです。ということでRAID5なので早急にHDDを取り替えてRAIDアレイの修復を行う必要が出てきたのですが、ここでHDDに関するとある問題が発生しました。

 

スペアとなるHDDがない。同じ型番のHDDはすでに販売されていない。そして・・・

このファイルサーバを組み立てたときに8TB以上あり、GB単価で一番安かったのがSeagateのST8000AS0002というもの。これ、実はArchiveHDDと呼ばれているもので、組んだ当時は用途的にはぴったりのものだったのですが、スペアを買っていない(というか1年ほど前に1台故障して同一型番のものと取り替えている)ため、手元に存在しておらず、同じ型番のものはすでに販売終了。しかも後継となるHDDはなんと存在していません。これは困った。というのも、RAIDアレイの再構築を行うためのストレージは「必ず残りのストレージデバイスが持つ容量以上のものを使わなければならない」という条件があります。これが意外と問題。

というのも、HDD本体の容量は確かに「8TB」なのですが、同じ「8TB」のHDDだからといってセクタ単位で見たときに容量が足りているか、は必ずしも明記されていません。メーカや型番によりこのあたりは異なる可能性があり、例えばWesternDigitalの場合はこれが明記されていません。そのため、ST8000AS0002の代替としてWesternDigital製の8TBHDDを考えるときセクタ数が足りているかどうか確証が持てない、という問題が発生します。RAIDの場合これが致命傷になる可能性があり、この時点でWesternDigital製のHDDは8TBより上のものを使わないと代用できない可能性が出てきます。幸いにもSeagateの場合は「Guaranteed Sectors」(最低保障セクタ数)という概念があり、8TB系のHDDはすべてGuaranteed Sectorsが同じであったため代用できるだろう、という感じで考えることができます。なお、あくまで「最低保障」なので、個体により微妙に異なる可能性は否定できないのですが・・・。

というわけで今回の代替用途にはSeagateのST8000VN004が発売時期も最近なのでちょうどいいかな、と思っていたのですが・・・。

 

近くにあるショップはSeagate製大容量のNAS用HDDがおいていない!というか・・・

そもそも8TBより容量が大きいHDDを取り扱っているショップが見当たらない、と言う事態が発覚し大分困り果てました。8TBのHDDがあった場合もBarracudaかWesternDigital製という間の悪さ。地方のショップはこんなものなのでしょうかね・・・。なんとか急場をしのぐために「とりあえず」でHDDを購入してリビルド作業に移っています。(つまりセクタ数はなんとか足りていたわけですね)

 

RAID5はリビルド作業が怖いのでそろそろRAID6で組み立てたいが

RAID5は1台が壊れても復旧が可能ということで個人用途では悪い選択肢ではないのですが、最大の問題点はRAIDアレイの再構築中に別のHDDが壊れてしまいRAIDアレイが完全に崩壊してしまう可能性が大きいこと。特に同じ時期に同一型番のHDDを買って使うため、故障時期も近くなる可能性が大きくなるからです。それを防ぐにはRAID6が有効なのですが、こちらだとHDDが一つ余計に必要なことと、SATAの端子数が必要(例えば4+2台で組む場合はさらにシステムドライブが1台必要となるため、拡張ボードなしだとマザーボードに端子が8つ必要になってしまう)ということで、コストがかかるのが難点です。ちなみに現段階でRAID6による40TB保存マシン(HDDは10TB*(4+2))を軽く設計してみるとすべてで40万円前後となり、YouTubeの動画にでもして広告収入を稼ぎたくなるようなマシンとなってしまうな、というところです。

 

 

C言語の仕様書に従うならNULLは0もしくは(void *)0らしい

ちょっとtwitter上でNULLに関することをつぶやきましたが、ツッコミが帰ってきてしまったため気になって仕様書(C89およびC99のもの)を読み込んでみました。そしてすべての論理をつなげてみると次のような結論となりました。

整数値の0もしくはそれをvoid *にキャストしたものがNULLとして定義される、と。

 

仕様書にはどう書いてあったか、というと・・・

C89でもC99でも記述は同じなのでそれは置いておいて。まず、null pointerおよびそれに関わる用語の定義です。関わる部分だけざっくりと翻訳すると次のようになります。

  • 整数値の0、もしくはそれをvoid *にキャストして表したものをnull pointer constant(ヌルポインタ定数)と呼びます
  • null pointer constant(ヌルポインタ定数)をそれぞれのポインタに変換したものをnull pointerと呼びます
  • null pointerはほかのどのオブジェクトおよび関数とも一致しないことが保証されています
  • null pointerをほかのポインタ型に変換してもそれはその型でのnull pointerとなります
  • null pointer constant(ヌルポインタ定数)はstddef.hでNULLとして定義されます

というわけで、この部分からNULLの定義について読み取るなら、それは1行目と5行目をつなぎ合わせることになり、「NULLは整数値0もしくは(void *)0として定義する」という結論が得られるわけです。ただし、3行目の説明を読んでみると、「何も指さないことが保証されている」という参考書の説明とは微妙に食い違っているように見えるのですが…。細かいことをいうなら特定のメモリ空間をオブジェクトに含めるのかどうか?というところでしょうか。

 

いくつかのシステムにおける例外について

なお、以下はWikipediaの記述(+リンクされていた参考資料)から読み取っている項目ですが、いずれもかなり古いシステムにおいて

  • null pointerが指しているアドレスが0でないシステムもある
  • (void *)0をキャストしてアクセスすると特定の読み書きとして成立するシステムもある

とのことでした。前者は48bitアドレスというなかなか変わった方式のものですし、後者は仮想メモリやメモリ保護の概念がない時代のものですので、今の時代には全くそぐわないものですから無視してもよいかもしれません。

 

ちなみにif(!p){ }の是非について

これが「ポインタ変数pがnull pointerのとき」の意味になるのか?については、仕様書から読み取ると

  • !pという演算は0==pと同一となる
  • ポインタとnull pointer constant(ヌルポインタ定数)が比較される場合はポインタの型に合わせたnull pointerとの比較として扱われる
  • 0はnull pointer constant(ヌルポインタ定数)として扱われる

ため、if(!p){ } はちゃんと「ポインタ変数pがnull pointerのとき」の意味になるようです。

 

意外と細かい仕様があってびっくり

というわけで「C言語の仕様書に従っている限りはNULLは0だし、null pointerによるifの判定にも誤りはない」という結論になりました。仕様書を読んでみるといろいろな動作についてちゃんと定義が書いてあるので、これに従ったコンパイラを完全に作るのは確かに大変だな、という感想もあります。ただし、逆にNULLをポインタにキャストしてアクセスした場合常にメモリ保護例外などのエラーとなるとは限らない、というのは調べていてびっくりした点です。今のシステムではほぼあり得ないことですが、昔のメモリ空間がカツカツだったりする環境のためなのでしょうかね。

 

C++にはnull pointerを表す定数が追加されていることを初めて知った

しばらく技術書を細かく眺めていなかったので知らなかったのですが、nullptrが追加されていて、C++11以降ではこれがnull pointerとして扱われるようです。NULLは上記の定義より整数型としての値を持つことがあり、引数として整数型とポインタ型のオーバーロードがあった場合にNULLを指定すると誤って整数型を引数とする方が呼び出されてしまう、という問題が起こってしまいます。それを防ぐために明示的にnull pointerで呼び出していることを示すものということでした。そういえば昔この手の問題で悩まされたことがあったな~と懐かしみながら。

 

logrotateが動作しない? systemctlで制御されているlogrotateに注意

久しぶりのサーバネタです。せめて仕事になるネタでも書かないとだめなのに…と思いながら書いています。

 

Fedora30のlogrotateがなぜか動作していない?

今現在Fedoraを入れているサーバはプログラムやWebサイトなどの動作テストを行うためのサーバなのですが、それだけではもったいないのでffmpegを入れてとあるバッチスクリプトを書いておくことで動画エンコードサーバとしています。これはまあいいのですが、今日気がついてみるとサーバが応答しなくなっているという事態に。テスト用のサーバなので、電源を強制OFFにした後付け直してログによっていつ、何が起こったのか把握しようと思っていたのですが…。/var/log以下を見てびっくり。

なんとFedora30を入れてから今日までのログが一つのファイルに固まったまま巨大なログファイルとなっていました…。

まあ、外部からのアクセスもほとんどないサーバですし、セキュリティ的な問題でもないでしょうからまだましなのですが、何かあったときの追跡が非常にやりづらいこと。気がついてよかったです。で、そうなると今までログファイルを分割していたlogrotateは一体何をやっていたのか?ということで少し追跡してみました。

 

systemctlに管理された場合のlogrotateはcronで動作させた場合と少し違う

いつ切り替わったのかよく分からないのですが…。今現在使っているCentOS7ではlogrotateはcronが一定期間ごとに動かすように設定されているのですが、Fedora30ではsystemctlがlogrotateを起動するように設定されているようです。で、これの設定が今までと違うやり方になっていてびっくり。どうなっているかというと

  • systemctlに登録されているlogrotate.serviceは「systemctlのタイマで一定期間ごとに呼び出されるログ処理を一度だけ行うスクリプト」という扱い。
  • 「一定期間」を設定しているのはsystemctlが持っているタイマの機能で、これは/usr/lib/systemd/system/logrotate.timerで定義されている

というわけで、logrotateを動作させるスクリプトとlogrotateを「一定期間ごとに」動作させるスクリプトは別になっているという理屈です。このsystemctlがタイマを持ち、一定期間ごとに動作させる、というのがこれを考える肝になるようで、systemctlからlogrotate.serviceの動作を見ても状態が「inactive (dead)」となっていますが、これは「そのタイミングでは動いていない」だけで、常駐している(定期的に動作するように設定されている)かどうかは別の方法で確認しなければいけない、ということになります。

 

デフォルトでlogrotate.timerは登録されていないのか・・・?

確認するためには

$ sudo systemctl list-timers --all

を使います。これでlogrotate.timerに関する行が存在する場合(コマンド実行中は左右キーが効くので右も確認する)はlogrotateが一定期間で動くのですが、関する行がない場合はlogrotateは動かない、ということになるようです。きちんと動作させるには

$ sudo systemctl enable logrotate.timer
$ sudo systemctl start logrotate.timer

により動作を追加する必要があります。タイマが登録されればlogrotateはlogrotate.timerに記述されている一定期間で動くようになる、ということになります。

 

ほかにsystemctlのtimerで抜けているものがあるのでは…?

ちょっと気になったのがこのこと。システムのログ処理で重要な部分であるlogroateがこれなので、ほかの「一定期間ごとに動作するサービス」の部類で同じようなものがある可能性があるな~と考えたからです。見つけた段階で一つ一つ登録していく必要があるのでしょうかね。

 

cronとsystemctlのタイマ処理との棲み分けとなるのか?

ちょっと気になるところです、cronの機能をsystemctlがある程度持つのであればcronを吸収することになるのか、システムの中心と簡単なバッチ処理のように棲み分けるのか、これからの発展が少し気になるな~と思っています。

JOYSOUNDとDAMの採点を(2年ぶりに,個人的に)調べてみた

2年前から今年の4月まではいろいろと忙しかった期間で、さすがに一人でカラオケ、というのも微妙すぎていかなかったのですが、ちょっと調べてみたいな~ということで、2年ぶりくらいに調べてみました。ちなみに今は暇な期間ですので、簡単なプログラムやアプリ、スクリプトならば仕事ができる状態になっています。

 

DAMは採点の方式そのものが変わっていたのね

さすがに2年もたつと採点が変わってしまうとは、というやつです。おそらく2年前くらいの採点の方式に加算点ルールが見えやすくなって追加された、というところでしょうか。採点してみていままでの記録に追加してみようと思ったら、(2年前までの記録から見て)DAMの採点の平均点に対しておよそ6点増えているということが分かり、採点記録を今まで自分が作ってきた個人のデータに登録しようかどうか迷ってしまうくらいになっています。なお、加算点のおかげで、DAMの採点の平均点とJOYSOUNDの採点の平均点が大体同じになったかな、という感じです。インタフェイスについては記憶している限りはほぼ変わっていないのでそちらで困ることはないですが…。

まあ、採点の平均点が同じくらいになったのであればDAMとJOYSOUNDの点数が直接比較できるのでそれはそれでありがたい、というべきなのでしょうかね。私の場合は平均点が90点前後で歌唱力は(おそらく)平均すこし下レベルということを考えると、ほとんどの人がいつ頃かは知りませんが、この変更でよくなったのだと思います。

 

JOYSOUNDはインタフェイスが大きく変わった様子

近くでJOYSOUNDが使えるカラオケ店だとJOYSOUNDの最新版が使えないので世代が少し古いタイプだと思うのですが、採点のシステムがやっぱり変わっていたのが印象的でした。なんかDAMに近づけようとしたのかは分かりませんが、記憶に残っている限りからの変更点だと

  • 判定音階の処理が(おそらく内部データで)二小節ずつ表示するようになっている。あくまで内部データ準拠なので、曲本体において途中で拍子が変わる場合、楽譜によっては「拍子変更処理が入っている」か、「拍子変更を無視してずれを許容したデータになっている」かで、表示のされ方が異なる。また、曲のテンポが急激に下がる場合は、こちらも拍子を無視したデータになっている場合が多く、表示される小節の区切りが変わっていく。
  • 音階表示は一定範囲が一致していれば音階表示バーが点灯する方式(DAMの方式)になった。ただし、判別されている音階はキラキラが追従するので視覚的にはリアルタイムのものが確認できる。また、音階一致率も常に脇に表示されているので、DAMより一致率の判定状態が確認しやすい。
  • 通常の曲であれば音階表示が下側に出てくる。また、歌詞のフォントサイズも小さくなるので、見やすいような見にくいような。ただし、本人画像など背景が特殊でかつ採点可能の場合は音階表示が上側に行く(DAMと同じ表示)になる

というところでしょうか。個人的には2年前くらいの「音階表示が右側からどんどんスライドしてくる」表示よりは見やすいと思うのでそれはOKだと思います。ただ、二小節固定になっているために、(テンポが速く設定されている曲など)曲によっては音階表示されている時間が非常に短い曲もあり、音階を見ながら微妙な調整をする私には不満が少し。

 

ゲーム会社からの曲提供や動画提供が面白い

DAMには(たぶん)ない機能ですね。このタイプのものは必要になったらJOYSOUNDの中央サーバからデータをダウンロードするらしく、すぐに曲開始しなければならない場所の場合ダウンロード待ちがあることと、採点システムに対応していない場合がほとんど(つまりボーカルラインのデータがない)であることが残念ですが、それでも歌う曲数を増やしやすくしたり、歌っている間の盛り上がりを重視するならよい機能だと思います。これのおかげで個人的に歌いたかったゲームの曲がカラオケシステムで歌えるようになったことがうれしいく、機能を確認したあといろいろ歌ってみて満足しました。あと、この機能を変に利用して動画配信サイト代わりに使っているアニメ等もあるようですが、それは面白い試みだと思いました。

 

個人的に?通常の男性ボーカル曲より女性ボーカル曲の方が歌いやすい…

男性ボーカル曲の音階の方が安定せずふらついてしまい苦戦しています。どうも女性ボーカル曲の高い音階で練習して男性ボーカル曲での練習をしなかったことと、できるだけ高い音階で発声するようにして歌っていたので、その影響もあるのかもしれません。練習の成果といえるかも。

あと、「歌う部分がすべて自分の裏声のピッチに入っている場合、すべてを裏声で歌うと高得点を稼ぎやすい」もあるようで。私の場合はずっと裏声で歌い続けた方が音階が安定するようなんですよ…。一応ソプラノ領域まで裏声で出せますので。そのため、いくつかの曲でテストしていますが、それなりの点数まで出せますし。まあ、テストした曲の平均点もよいので単に歌いやすいだけなのかもしれませんが。

 

ということでいろいろと遊んでみた

あとは採点データをどうするか、かな。データを管理しているExcelのシートを新しくするのが正しいのだろうか…。

WordPressのCaptchaを変更してみる(Advanced noCaptcha & invisible Captcha)

というわけで、Captchaが大分バグっている、というかとある事情で不具合が起こっていたようなので更新しました。その更新について少し書いておきたいと思います。一応コメントの書き込みテストはしているのでキャッシュ処理に関する問題はないはずですが…。

 

大量のスパムコメントがあった理由は…

4月までの数年間WordPressの更新は「緊急性の高いものを除きとりあえずセキュリティアップデートだけ」という状態だったので、一部の事態に鈍感になっていたことが大きかったです。で、本題の大量のスパムコメントですが、とりあえずコメントのフィルタシステムでスパム扱いされていたので半分無視していたのですが、妙に気になったのでCaptchaに関して調べてみると・・・。

SI Captcha Anti-SpamCaptchaは問題あり

という内容の記事があり、調べてみると開発者が変わって更新が止まっているとかバックドアが仕込まれているとかいろいろと情報がありました。ちなみに私が二年前の段階で導入していたのがSI Captcha Anti-Spamの方で、どうもこれがスパムコメントの原因だったようです。

 

別の種類のCaptchaを導入してみることに

さすがにCaptchaが一つもない、というのは微妙ということで調べてみていくつか導入候補を考えたのですが、それが

  • Google Captcha (reCAPTCHA)
  • Login No Captcha reCAPTCHA
  • Advanced noCaptcha & invisible Captcha

になりました。ところがどっこい。基本的にこれらはすべてGoogleのCaptchaシステムを借りて行うものなので変に所有者が変わらない限りはCaptchaとしての動きはほぼ変わりません。後は信頼度と設定がどこまでできるか?に依存するため、今回はAdvanced noCaptcha & invisible Captchaを使ってみることにしました。

 

導入の手順はおそらくこの3つともほとんど変わらない(と思う)

というのも、結局はGoogleのreCAPTCHAを借りることになるため、

  1. WordPressの管理画面からプラグインを検索してインストールする
  2. GoogleのreCAPTCHAの管理画面にGoogleアカウントでログインしてAPIキーとSecretキーを取得する
  3. 設定画面でAPIキーとSecretキーを登録して、ほか必要な設定を行う

となります。GoogleからAPIキーを取得するためのアドレスは大抵プラグインの設定画面にリンクが張られていると思うのでそれを参照すればよいと思います。ちょっと注意が必要なのが、reCAPTCHAのキーを取得するときに認証のバージョンなどを設定することができますが、そのバージョンにプラグイン側の設定も合わせる必要がある、ということです。v2(noCaptchaもしくはinvisible Captcha)で設定する場合とv3で設定する場合でそれぞれ方法が異なりますので注意しましょう。

あとはどの場所にCaptchaを設置するかどうかです。Advanced noCaptcha & invisible Captchaではいくつかの場所にチェックボックスだけで設定できるので、コメント投稿およびログイン画面に設定することにしました。これで安全性がかなり高まるかと思います。ちなみにAdvanced noCaptcha & invisible Captchaの場合はbbPressやBuddyPress、WooCommerceとも連動させてCaptchaをかけることができるので、これらのプラグインでサイトを作っている人には簡単に設定できるようになる分おすすめかもしれません。

 

Captchaのプラグインを変えるだけでスパムコメントが一切なくなった…

というわけで、Captchaのプラグインを変えて数日間たったわけですが、スパムコメントが一切なくなりました。まあ、このサイトこの2年間くらい記事更新がほとんどなかったこともありコメントらしいコメントもないので正しいコメントが受け付けられているかどうかはテストしたこと以上のことは不明なのですが、それでも管理の手間が大分減っているのでちょっと感動です。スパムコメントのフィルタリングに関してはIPフィルタ以上の効果ですね。