もっふもっふにしてやんよ!

勉強会行った話9割、手を動かした話1割。

0埋めファイルを作るとき、ddよりもheadが早い!?そんな馬鹿な!?

いきさつ

キッカケは、以下のツイートを拝見したからです。


想定と実行時の違い

脳内イメージでは以下のような感じで、bs=1GBで1回実行のほうが早いんじゃね?って思いました。

f:id:moffumoffu:20170402202113j:plain

しかし、実際にやってみたところ、結果が異なっていました。

そんなわけで、認識とはズレていたので、結局何が早いんだろうというところから、付随して原因までわかったので書きます。

実行環境

  • VMware Workstation 12 Player
  • CentOS 7.2 minimal
    • 割り当てメモリ: 8GiB
    • 割り当てHDD:40GB(事前割り当て)
    • ゲストOS内HDDフォーマット:ext4

結論

大して変わらん!

  • headとddで、0埋めファイルを生成する早さは変わらない
    • 早さに違いがあったのは、ディスクへの書き込みの実行タイミングが、ファイルディスクリプタの変更によってOSに任されたため
      • headでは、OSに任される
      • ddでは、アプリケーションで書き込み完了まで行う
      • OSのI/O処理に依存させないため、時間計測にsyncコマンドを追加した
    • 実体のファイルを作成するので安心
  • 同様の目的を果たすのに、truncateとfallocateコマンドが存在する
    • ファイルの実体は作成されないので、アプリケーションごとにメモリ割り当ての際不都合が発生する場合があるので、オススメできない。
    • 上記2つのコマンドでは、スパースファイルを作成する
    • ファイルを読み出す関数であるread()が呼ばれたとき、仕様として0を返します
    • メモリに割り当てる関数であるmmap()が実行された場合は正直よくわかってません。。。

よく考えたら・・・

リクエストのことすっかり忘れてた・・・

結局、パフォーマンスは変わらないので、/dev/zeroから持ってくる方法であれば、ddでもheadでもいいと思います。(truncateとfallocateは微妙にやりたいことと違う点、また、他にファイル生成の案が出なかったため。)

付記(headとddの違いについて)

  • bsによるメモリサイズの調整は、少なくとも1GB程度のテストファイルでは有意な差は見られませんでした
    • head、dd共に内部では、read関数やwrite関数を呼び出す
      • headでは8KBもしくは4KB単位での操作(bs=8KB,4KBと同等のシステム関数呼び出し)
      • 何万回と呼び出されていても速度に変わりなかった
    • TBなどのスケールだと、チューニングの効果が出るかもしれません

ソースコード

検証に使用したシェルスクリプトを記載しています。汚くてゴメンナサイ。

#!/bin/bash
rm *file -f;

function syori(){
  free -m > /dev/null
  echo 3 > /proc/sys/vm/drop_caches
  free -m > /dev/null
}

#head
echo "------------head---------------"
syori
time bash -c 'head -c 1GiB /dev/zero > headfile;sync;sync;sync'

#dd bs=4MB
echo "------------dd bs=4MiB---------"
syori
time bash -c 'dd if=/dev/zero of=4MBfile bs=4MiB count=256;sync;sync;sync'

#dd bs=1GiB
syori
echo "------------dd bs=1GiB---------"
time bash -c 'dd if=/dev/zero of=1GBfile bs=1GiB count=1;sync;sync;sync'

#truncate
syori
echo "------------truncate-----------"
time bash -c 'truncate -s 1G truncatefile;sync;sync;sync'

#fallocate
syori
echo "------------fallocatte---------"
time bash -c 'fallocate -l 1GiB fallocatefile;sync;sync;sync'


echo "------------syuuryou-----------"
syori

実行ログ(一例)

実行結果は、以下の通りです。time関数により計測しています。
十数回ほど実行しましたが、実行結果毎に1秒以上の差は出ませんでした。

[root@localhost tmp]# ./command.sh 
------------head---------------

real    0m5.736s
user    0m0.024s
sys     0m0.465s
------------dd bs=4MiB---------
256+0 レコード入力
256+0 レコード出力
1073741824 バイト (1.1 GB) コピーされました、 0.872527 秒、 1.2 GB/秒

real    0m6.139s
user    0m0.002s
sys     0m0.425s
------------dd bs=1GiB---------
1+0 レコード入力
1+0 レコード出力
1073741824 バイト (1.1 GB) コピーされました、 0.653189 秒、 1.6 GB/秒

real    0m5.760s
user    0m0.002s
sys     0m0.550s
------------truncate-----------

real    0m0.011s
user    0m0.000s
sys     0m0.007s
------------fallocatte---------

real    0m0.013s
user    0m0.000s
sys     0m0.007s
------------syuuryou-----------

謝辞

今回の調査に際して、以下の放送でプログラミング生放送コミュニティを利用させていただきました。コミュニティ運営の皆様、そしてコメントをしていただいた皆様、さらに視聴いただいた皆様、ありがとうございました。

live.nicovideo.jp

標準インストールされているWindows ストアアプリが英語表記になってしまう問題とその対処法

はじめに

・当方で対応したのは0x80070057エラーでアップデートが出来なかった場合です。 ・対処法として考えられるものを列挙したので、マイクロソフト社のソースと一緒にご参考とまで。 ・最終的に、原因特定にはいたっていません。 再起動したら直りました。

対処法

対処法に入る前に1点だけ。ストアアプリはWINHTTP通信を使用するため、そこに起因する問題(netsh winhttp proxyや、FW等々)を事前に疑いましょう。

1. マイクロソフト社公式のトラブルシューティングツールを実行する

まずはコレを試しましょう。

Windows アプリのトラブルシューティング ツールを実行する

尚、コレを試すと「アカウントにログインしていません」と怒られました。(間違いなくそうじゃねえ!)

2. アプリの削除、再インストール

以下に示されている通り、PowerShellを使ってアプリの再インストールを行います。

answers.microsoft.com

万が一ストアアプリを常用している場合は、各アプリが保持している設定などがどう扱われるかをご確認ください。

3. なんかよくわからないけど再起動する!!

上記を実行した結果、結局治らなかったのでとりあえず再起動したところ、再起動毎にいくつかのストアアプリにアップデートがかかり、アップデートが掛かったものから英語表記から日本語表記に戻りました。

結論

Windowsの挙動は不思議なものばかりですね。今回は再起動したら直りましたが、再発する可能性も十分に考えられます。

対処の中で、プロキシのログなども確認しましたが、マイクロソフト社サーバーから403の返事が返ってきてたりこなかったりで謎ですし、端末のIEから通常モードのブラウジングではmicrosoft.comに接続できなかったのにInPrivateだと接続できたりと、謎です。

何かご存知の情報があればコメントしていただければ非常に助かります。

参考情報

Preview版での情報なので実施の際はスルーしましたが、Swayに手順が示されています。情報源は以下より。

answers.microsoft.com

社内のフェデレーションユーザーがOffice365にアクセスできない場合の対処法

クライアント端末を見ると、以下のイベントが記録されます。 CertificateServicesClient-CertEnroll

Microsoft-Windows-CertificateServicesClient-CertEnroll

イベントIDは87が記録されます。

結論を書いておくと、セキュリティ上の制約によりADFSサービスへアクセスはできていたんですが、ADFSサービスからの応答を拒否していました。(こんな事例滅多にないみたいで、イベント87の資料が英語でも日本語でも全然無いので参考になれば・・・)

基本的には、下記ガイドの9ページ~12ページに示される認証フローに従い、障害切り分けを行いました。

Microsoft Office 365 自習書 AD FS によるシングル サインオン環境構築ステップ バイ ステップ ガイド https://www.microsoft.com/ja-jp/download/details.aspx?id=28716

今回は、社内ネットワークに当たるので、以下の①~⑨のどこかということになります。(9ページより引用)

f:id:moffumoffu:20170222002014j:plainf:id:moffumoffu:20170222002017j:plain

ADFSサービスのエラー画面は到達するので、①~④のDNS名前解決までは基本的に問題ありません。そのため、ADFSサービスのログを解析しました。フェデレーションサービスが全てダウンしている場合は、以下のトラブルシュートが参考になります。

フェデレーション ユーザーが Office 365 ウェブリソースにサインインしようとすると、ブラウザーに AD FS Web ページが表示されない https://support.microsoft.com/ja-jp/help/2419389/internet-browser-can-t-display-the-ad-fs-webpage-when-a-federated-user-tries-to-sign-in-to-office-365,-azure,-or-intune

Ad FS 2.0 のエラー: このページを表示できません https://support.microsoft.com/ja-jp/help/3044971/adfs-2.0-error-this-page-cannot-be-displayed

ADFSサービスのログは、サーバーマネージャからも見ることは出来ますが、イベントビューワーで見ることも出来ます。基本的に、正常系から異常系全てのログが混在しているので、必要に応じてフィルタをかけましょう。

blogs.msdn.microsoft.com

ADFSサービスにアクセス ( https://login.microsoftonline.com/ から、メールアドレスを入力した後に表示されるの画面にたどり着いた際)した場合、ADFSサーバにリクエストの受信、リクエストの検証、レスポンスの送信という3つのログが出力されるので、それを元にアクセス元IPなどの情報を集めます。 (メールアドレスを tesutodayo@contoso.com みたいに出鱈目なユーザIDを指定してあげると、ログの解析が楽になります。)

ここでエラーログが出力されていなければ問題ありません。事実、サーバーは「俺は正常にレスポンスを返したぞ」と主張しているので、ADFSサービスからクライアント端末までのどこかでレスポンスが落ちたことがわかります。ロードバランサやプロキシサーバなどを介している場合は、そちらのログを追うといいかもしれません。

そんなわけで、問題を切り分けた結果、クライアント端末しか疑いようが無かったため、色々とセキュリティ関連のソフトウェアをオフにして正常に接続が出来ることを確認しました。灯台元暗しというやつですね。