XCodeからiTunes Connectへアップロード後に`has change to Invalid Binary`エラー

XCodeからiTunes Connectへアーカイブファイルをアップロードした後にhas change to Invalid Binaryエラーが発生した場合は、問題の詳細がメールで送信されてくる。

Missing Push Notification Entitlement

Missing Push Notification Entitlementは、Apple Developer > Certificates, Identifiers & Profiles > App IDsでPush Notificationsが有効化されていないか、もしくは、XCode -> TARGET -> Capability -> Push NotificationsでPush Notificationsが有効化されていないかのいずれかの場合が多いため、これらの設定を見直した上で再度アップロードを行う。

Missing Push Notification Entitlement – Your app includes an API for Apple’s Push Notification service, but the aps-environment entitlement is missing from the app’s signature. To resolve this, make sure your App ID is enabled for push notification in the Provisioning Portal. Then, sign your app with a distribution provisioning profile that includes the aps-environment entitlement. This will create the correct signature, and you can resubmit your app. See “Provisioning and Development” in the Local and Push Notification Programming Guide for more information. If your app does not use the Apple Push Notification service, no action is required. You may remove the API from future submissions to stop this warning. If you use a third-party framework, you may need to contact the developer for information on removing the API.

Certificatesの修正が必要な場合

Push Notificationsを有効化

XCode上で修正が必要な場合

Push Notificationsを有効化

privacy-sensitive data without a usage description

iOS10よりユーザデータにアクセスする場合は、使用目的をInfo.plistに記述する必要がある。

We have discovered one or more issues with your recent delivery for “YOUR APP NAME”. To process your delivery, the following issues must be corrected: This app attempts to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.

Info.plistに記述した文言は、データアクセスの許可を求めるポップアップ上に表示される。NAVITIMEアプリの場合はこんな感じ。

NAVITIMEアプリ

Fluentd + Elastichsearch + Kibana(4)Fluentdでホスト名を追加する

Fluentdでログを転送する際、ホスト名も付加したい。そんなときは、標準のfilterプラグインを使って、以下の設定を加える。

sudo vi /etc/td-agent/td-agent.conf

<filter **>
  @type record_transformer
  <record>
    hostname ${hostname}
  </record>
</filter>

このときに、matchタグよりも上位に記述しないと動作しないので注意が必要である。

Fluentd + Elastichsearch + Kibana(3)FluentdからElasticsearchへの転送

Fluentdの設定

前回までにFluentd + Elastichsearch + Kibanaの環境設定と、ログの送信元となるMacの設定を行った。

今回は、受信したデータをElasticsearchに転送する処理を扱う。設定は以下の通り。

sudo vi /etc/td-agent/td-agent.conf

<source>
  @type forward
</source>

<match example.app>
  type elasticsearch
  host localhost
  port 9200
  type_name exampleapp
  logstash_format true
</match>

type_nameは、Elasticsearchタイプ名を指定する。識別できる文字列なら好きに指定して良いようだ。logstash_formatは、logstashフォーマットで出力するオプションで、とりあえず今回はtrueにしておく。

Fluentdの再起動

Fluentdを再起動する。

sudo systemctl restart td-agent

Kinabaにアクセス

Kibanaにアクセスすると、データの受信に伴って、インストール直後とは表示が変わっている。ログインすると受信データが確認できる。

http://XXX.XXX.XXX.XXX:5601

  • インストール直後
    Kibana
  • データ入力完了後
    Kibana

Fluentd + Elastichsearch + Kibana(2)MacでFluentdを動かそう

インストールと起動

MacにFluentdをインストールし、Macで動くアプリのログを、Elastichsearchが動くサーバへと転送する。FluentdのダウンロードページにMac用のdmgイメージがあるので、これをダウンロードし実行する。

Mac Fluentd dmg

Macのデーモンは、launchctlと呼ばれるツールで管理される。launchctlは、設定ファイル(plist)のロードによってデーモンを登録し、デーモンの開始や終了など制御する。通常は、デーモンの登録を行った上で、デーモンの開始を行うという流れとなるが、設定ファイル内で「RunAtLoad = true」が設定されている場合は、ロードと同時にデーモンが起動され、OSの起動時にも自動的にデーモンは起動する。

Fluentd(td-agent)の設定ファイルは、「RunAtLoad = true」に設定されているため、設定ファイルをロードするだけで、デーモンは起動され、自動起動に設定される。

launchctl load /Library/LaunchDaemons/td-agent.plist 

元データの設定

Fluentdは、元データの指定と転送先の指定が必要となる。元データは以下のような種類を指定できる。

ログファイルから取得する

転送ログの元データを指定する。設定するパラメータは以下の通り。

パラメータ 意味
type tail
path ログファイルのパス
pos_file 読み込んだ位置を記憶しておくファイル
tag ログの識別子
<source>
  type tail
  format apache
  path /var/log/httpd-access.log
  tag td.apache.access
</source>

httpから取得する

http通信によってデータを取得する。設定するパラメータは以下の通り。

パラメータ 意味
type http
port ポート番号

tagは、URLヘッダで指定する。

<source>
  type http
  port 8888
</source>

実行したコマンドの標準出力から取得する

コマンドの実行によってデータを取得する。設定するパラメータは以下の通り。

パラメータ 意味
type exec
command 実行するコマンド
tag ログの識別子

他のFluentdから取得する

他のFluentdから転送されたデータを受信する。設定するパラメータは以下の通り。

パラメータ 意味
type forward
<source>
  type forward
</source>

設定例

今回は、Macで動作するアプリが出力する以下の形式のログを元データに指定する。

2016-08-11 04:56:31.518 exampleApp[321:2853] <Normal> "Application is started."
2016-08-11 04:56:31.518 exampleApp[321:2853] <Normal> "Application is initialized."
2016-08-11 04:56:31.518 exampleApp[321:2853] <Normal> "Data is received: apple=3, orange=4"
2016-08-11 04:56:31.518 exampleApp[321:2853] <Normal> "Application will be terminated."

Fluentdは様々なログをJSON形式に変換した上で転送を行う。ログの変換を行うためには、どのようなフォーマットでログが記述されているかを正規表現でFluentdに教えてあげる必要があり、この設定が最も難しい。今回のログは、スペース区切りで、[日付][プロセス情報][ステータス][メッセージ]の情報が並んでいるので、正規表現で表現すると以下のようになる。

sudo vi /etc/td-agent/td-agent.conf

<source>
  type tail
  path /tmp/exampleApp.log
  pos_file /var/log/td-agent/exampleApp.log.pos
  tag example.app
  format /(?<time>[^\]]*) (?<process>.*) <(?<stat>.*)> "(?<message>.*)"/
  time_format %Y-%m-%d %H:%M:%S.%N
</source>

出力先の設定

Fluentdは、出力先も様々な方法を選択できる。

標準出力に転送

データを標準出力に転送する。設定するパラメータは以下の通り。

パラメータ 意味
type stdout
<match **>
  type stdout
</match>

ファイルに転送

データをファイルに転送する。設定するパラメータは以下の通り。

パラメータ 意味
type file
path 出力ファイルのパス
time_slice_format ファイル名のサフィックス
time_slice_wait ファイルを分割する時間単位
<match **>
  type file
  path /var/log/fluent/exampleApp.export
  time_slice_format %Y%m%d
  time_slice_wait 10m
</match>

他のFluentdに転送

データを他のFluentdに転送する。設定するパラメータは以下の通り。

パラメータ 意味
type forward
server 転送先サーバの情報

今回は、Macアプリのログを、Elasticsearchを導入した他のサーバに転送したいので、以下の設定とした。

<match **>
  type forward
  <server>
    name server_1
    host XXX.XXX.XXX.XXX
  </server>
</match>

設定ファイル

設定ファイルは以下となった。

sudo vi /etc/td-agent/td-agent.conf

<source>
  type tail
  path /tmp/exampleApp.log
  pos_file /var/log/td-agent/exampleApp.log.pos
  tag example.app
  format /(?<time>[^\]]*) (?<process>.*) <(?<stat>.*)> "(?<message>.*)"/
  time_format %Y-%m-%d %H:%M:%S.%N
</source>

<match **>
  type forward
  <server>
    name server_1
    host XXX.XXX.XXX.XXX
  </server>
</match>

Fluentdを再起動して新たな設定ファイルを読み込む。このとき、/var/log/td-agent/td-agent.logに正常なログが吐き出されていたらOK!

launchctl unload /Library/LaunchDaemons/td-agent.plist 
launchctl load /Library/LaunchDaemons/td-agent.plist 

参考になるページ

シェル(1)Bashの基本設定

Bashとは

シェルは、コマンドライン・インタプリタとも呼ばれ、ユーザが入力したコマンドをカーネルに渡すプログラムである。シェルには、Bashcshzshなど様々な種類が存在するが、LinuxやMac OSでは、Bashが標準シェルとなっている。/bin/shは、Linuxにおける標準シェルを示しており、通常はBashへのシンボリックリンクとなっている。

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4  9月 26 15:52 2014 /bin/sh -> bash

なお、Bashを/bin/shとして実行させるとPOSIX準拠モードで起動するため、厳密にはBashと挙動が異なる。以下のコマンドを実行することで、インストール済みのシェルを確認することができる。

$ cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh

ファイルディスクリプタ

シェルは、実行するプログラムの以下の値を取得することが可能となっている。

ディスクリプタ 略記 内容
<0 < 標準入力
>1 > 標準出力
>2 >2 標準エラー出力

標準出力も標準エラー出力も同時に出力したい場合は、2>&1と記述する。

ショートカット

カーソルの移動や編集を行う際に以下のショートカットを使うと便利。

コマンド 意味 内容
Ctrl + a ahead 行頭に移動
Ctrl + e end 行末へ移動
Alt + b before 一単語左へ
Alt + f foward 一単語右へ
Ctrl + d delete カーソルの文字を消す
Ctrl + h 0x08 (Backspace) カーソルの左の文字を消す
Ctrl + w word カーソルの左の単語を消す
Ctrl + u unix-line-discard カーソルより左の文字を全てカット
Ctrl + k kut カーソルより右の文字を全てカット
Ctrl + y yank ペースト
Ctrl + p previous 前の履歴を表示
Ctrl + n next 次の履歴を表示
Ctrl + r reverse 過去の履歴から検索
OLDPWD 直前にいたディレクトリ

設定ファイルの読み込み順序

bashの設定ファイルはいくつもあるが、以下の順序で読み込まれるらしい。

読み込み順序 読み込み時 対象 ファイル
1 ログイン時 全ユーザ /etc/profile
2 ログイン時 各ユーザ ~/.bash_profile
3 ログイン時 各ユーザ ~/.bash_login
4 bash起動時 各ユーザ ~/.bashrc
5 ログイン時のシェル終了時 各ユーザ ~/.bashrc

PATHを通すときなどに無意識に~/.bashrcにPATHを書いてたけど、~/.bashrcにPATHを書いてbashを複数タブで起動すると、その度に同じPATHが追加されてしまうようだ。というわけで、設定ファイルは、~/.bash_profileに書いておけばいいということか。

設定ファイルの内容

historyコマンド時に時間情報も表示させると便利。
過去のコマンドが消えてしまわないように、historyの上限値も増やしておくと、なお便利。
ちなみに、![履歴番号]で、history内の過去のコマンドを実行できる。

# History
HISTSIZE=50000
HISTTIMEFORMAT='%Y-%m-%d %H:%M:%S '

# Path
PATH="$PATH":/usr/local/bin:/bin:/sbin:/usr/bin

コマンドの実行

シェルで実行ファイルを実行する場合、PATH付きで指定しなければいけない。カレントディレクトリの実行ファイルを、

$ ./a.out

などと書くのは上記ルールによる。ただし、シェルにPATHが通っている場合は、PARHを省略できる。実行したファイルのPATHを確認するにはwitchコマンドを使って、

$ witch ls

alias ls='ls --color=auto'
	/bin/ls

とすればよい。また、cd, echo, pwdなどのコマンドは、ビルトインコマンドと呼ばれ、シェル自身に組み込まれたコマンドである。コマンドのタイプを確認するためには、

$ type pwd
pwd is a shell builtin

typeコマンドを使用する。

AWS S3(2)S3Sync:S3バックアップツール

S3Sync

以前、S3にバケットを作成してGlacierアーカイブを行う手順を確認したが、この仕組みを利用してMacの任意のディレクトリをS3 Glacierと自動的に同期するアプリケーション「S3Sync」を作ってみた。Macのスリープを検知すると同期を始めるので、寝ている間にラクラク同期できる。

といってもこのアプリ、単にNSTaskを使ってシステムコマンドを実行しているだけのアプリなので、任意のコマンドを自由に実行することができる。ステータスバーに常駐しているアプリなので、作業の邪魔にもならない。

S3Sync

スリープ検知

スリープ検知をするには、NSWorkspace ClassNSWorkspaceWillSleepNotification属性を使う。

    func applicationDidFinishLaunching(aNotification: NSNotification) {
        // スリープ検知
        NSWorkspace.sharedWorkspace().notificationCenter.addObserver(self, selector: #selector(self.receiveSleepNotification(_:)), name: NSWorkspaceWillSleepNotification, object: nil)
    }

    func receiveSleepNotification(notification: NSNotification){
        // スリープ実行時に行う処理
    }

システムコマンドの実行

システムコマンドは、NSTask Classから実行することが可能である。
NSTaskは、実行したシステムコマンドの出力結果を取り出すことも可能だが、readDataToEndOfFile()を使うとブロッキング処理が発生してしまうので、dispatch_async()を使って非同期に順次出力処理していく必要がある。

let task = NSTask() 
// 実行コマンドをフルパスで指定
task.launchPath = "/usr/local/bin/aws "
// パラメータを配列形式で指定
task.arguments = ["-h", "hogehoge"]
// 標準出力をパイプに渡す
let pipe: NSPipe = NSPipe()
task.standardOutput = pipe
let stdoutHundle = pipe.fileHandleForReading     
// 非同期処理
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), {
var dataRead = stdoutHundle.availableData
while(dataRead.length > 0){
	let stringRead = NSString(data: dataRead, encoding: NSUTF8StringEncoding)
        if let output = stringRead {
		// 出力結果処理
        }
        dataRead = stdoutHundle.availableData
}
// コマンドの実行
task.launch()

NSTaskは、suspend()terminate()を使って、途中で処理を停止したり、完全に終了してしまったりすることができる。suspend()で中断した処理は、resume()で再開することができる。また、タスクが実行中にも関わらず再度launch()を実行してしまうと、下記の実行エラーが発生してしまう。

task already launched

通知の送信

本アプリは、コマンド実行毎にMacの通知センターに実行状況を通知する。

アプリ通知

Macの通知センターに通知を送信するには、NSUserNotificationCenter Classを使う。送信する通知には、「タイトル」「サブタイトル」の他に様々な項目を設定することが可能である。

// NSUserNotificationCenterDelegateが必要
class AppDelegate: NSObject, NSApplicationDelegate, NSUserNotificationCenterDelegate {

    func deliverNotification(title : String, subtitle : String, informativeText: String){
        // AppDelegate Classにデリゲードを指定
        NSUserNotificationCenter.defaultUserNotificationCenter().delegate = self
        let notification = NSUserNotification()
        notification.title = title
        notification.subtitle = subtitle
        notification.informativeText = informativeText
        notification.contentImage =  NSImage(named: "MainIcon")
        notification.userInfo = ["title" : "タイトル"]
        NSUserNotificationCenter.defaultUserNotificationCenter().deliverNotification(notification)
    }

}

ログを保存するディレクトリの指定

本アプリは、実行ログをファイルに保存することができる。

NSOpenPanel

Macでディレクトリやファイルを開くする際は、NSOpenPanel Classを利用する。
また、保存の際はNSSavePanel Classというクラスも用意されている。

// MARK: ディレクトリ選択画面
let panel = NSOpenPanel()
// ファイル選択の可否
panel.canChooseFiles = false
// ディレクトリ選択の可否
panel.canChooseDirectories = true
// 複数選択の可否
panel.allowsMultipleSelection = false
panel.beginWithCompletionHandler({(num) -> Void in
      if num == NSModalResponseOK {
           // ディレクトリ・ファイル決定時の処理
      }
})

常駐アプリ

ステータスバーに常駐するアプリを作成するためには、Project > TARGET > Info > Custom OS X Application Target Propertiesから、Application is agent (UIElement)YESに設定する。

Application is agent

StoryBoardのTips

  • 常駐アプリであっても、Main Menu > Edit がないと、TextFieldの Shortcut Keyが使えない

Main Menu : Edit

機械学習(1)TensorFlowをMacにインストールする

TensorFlowは、Googleが開発し公開している機械学習ライブラリ。

インストール方法

Pythonパッケージ管理ツール「easy_install」を使うとよいとのことなので、以下のコマンドを実行。このとき、XCodeのコマンドラインツールのインストールも求められる。

sudo easy_install pip
sudo easy_install --upgrade six
sudo pip install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0-py3-none-any.whl

tensorflow-0.8.0-py3-none-any.whl is not a supported wheel on this platform.

TensorFlowを入れるためにはpip3(python3)が必要とのこと。
brewからpython3のインストールを行う。

このときpythonのバージョン管理を行うことのできるpyenvを入れておくと、Python2.7とPython3を切り替えることができるので便利。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install pyenv

現在のPythonバージョンを確認することができる。

pyenv versions
* system (set by /Users/***/.pyenv/version)

まだ何も入れていないので、systemのみ。

ここで、~/.profileファイル(ログイン時に読み込むbash設定)に以下を追加。
設定を読み込ませるためにOS再起動。

vi ~/.profile

export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"

インストール可能なバージョンを確認して、Python3(今回は3.5.1)をインストール。

pyenv install --list
pyenv install 3.5.1

使用するPythonのバージョンを3.5.1に変更。

pyenv global 3.5.1
pyenv versions
  system
* 3.5.1 (set by /Users/eiji/.pyenv/version)

このときにもし以下のようなエラーが発生する場合は、

Downloading Python-3.5.1.tgz...
-> https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz
Installing Python-3.5.1...

BUILD FAILED (OS X 10.11.4 using python-build 20160130)

Inspect or clean up the working tree at /var/folders/my/txp4p33n1lzf2hbzp0vmqbc40000gn/T/python-build.20160515224141.3027
Results logged to /var/folders/my/txp4p33n1lzf2hbzp0vmqbc40000gn/T/python-build.20160515224141.3027.log

Last 10 log lines:
  File "/private/var/folders/my/txp4p33n1lzf2hbzp0vmqbc40000gn/T/python-build.20160515224141.3027/Python-3.5.1/Lib/ensurepip/__main__.py", line 4, in <module>
    ensurepip._main()
  File "/private/var/folders/my/txp4p33n1lzf2hbzp0vmqbc40000gn/T/python-build.20160515224141.3027/Python-3.5.1/Lib/ensurepip/__init__.py", line 209, in _main
    default_pip=args.default_pip,
  File "/private/var/folders/my/txp4p33n1lzf2hbzp0vmqbc40000gn/T/python-build.20160515224141.3027/Python-3.5.1/Lib/ensurepip/__init__.py", line 116, in bootstrap
    _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/private/var/folders/my/txp4p33n1lzf2hbzp0vmqbc40000gn/T/python-build.20160515224141.3027/Python-3.5.1/Lib/ensurepip/__init__.py", line 40, in _run_pip
    import pip
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1

XCodeのコマンドラインツールもインストールする。

xcode-select --install

最後に、TensorFlowをインストール。

sudo pip3 install --upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0-py3-none-any.whl

インストールされたかどうかの確認は、以下のコマンドを打ってエラーが発生しないことを確認する。

python

Python 3.5.1 (default, May 15 2016, 09:29:31) 
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

import tensorflow as tf 

MySQLに外部サーバ定義を登録する

リンクテーブルを作成するときなど、FEDERATED ストレージエンジンで使用する外部サーバーを定義する際には、CREATE SERVERコマンドを使用する。外部サーバを定義するとmysql.serversテーブルにカラムが追加されるが、SQL文で直接mysql.serversにカラムを追加すると正常に動作しないので注意が必要である。

CREATE SERVER server_name FOREIGN DATA WRAPPER mysql OPTIONS (USER 'hoge', PASSWORD 'hogehoge', HOST '192.168.0.x', DATABASE 'database_name');

以下のように追加するのはよくないぽい。

INSERT INTO `mysql`.`servers` (`Server_name` ,`Host` ,`Db` ,`Username` ,`Password` ,`Port` ,`Socket` ,`Wrapper` ,`Owner`)VALUES ('server_name', '192.168.x.1', 'database_name', 'hoge', 'hogehoge', '0', '', '1', 'mysql', '');

XCodeからiTunes Connectへアップロード時にITMS-90530エラー

XCodeからiTunes Connectへアーカイブファイルをアップロードする際にITMS-90530エラーが発生することがある。
対処法は、iPhoneなどの端末を一切接続しない状態で、もう1度アーカイブファイルを作成する。

CentOS7(1)アレイコントローラの認識

HP Dynamic Smart Array B140i Controller

CentOS7をインストールするサーバに、アレイコントローラが搭載されている場合、アレイコントローラのドライバを指定した上でインストールを実行しないと、論理ドライブが認識されずに物理ドライブがそのまま見えてしまう場合がある。HP ProLiantに搭載されているHP Dynamic Smart Array B140i Controllerを認識させる場合は、デバイスドライバの入ったUSBメモリを作成し、このUSBメモリを使ってCentOSインストールと同時にドライバの組み込みも行う。デバイスドライバは、HPのサポートページからダウンロードすることが可能である。

デバイスドライバ(ドライバディスケット)のダウンロード

HPのサポートページから「.gz」形式のドライバーをダウンロードする。

デバイスドライバのダウンロード

デバイスドライバー(ドライバディスケット)の解凍

解凍すると「.dd」形式のファイルとなる。

デバイスドライバの解凍

USBメモリへの書き込み

FAT形式にフォーマットしたUSBメモリにddコマンドを用いてドライバを書き込む。「.dd」形式のファイルをファインダー上でドラッグアンドドロップするだけでは、正常に読み込むことができない

FAT形式にフォーマット

Macの場合は、ディスクユーティリティを使ってFAT形式にフォーマットする。このとき、名前をUNTITLEDと命名すると、通常は/Volumes/UNTITLEDでマウントされる。また、装置欄に記述されている名称(disk2)がデバイス名称(/dev/disk2)となる。

USBメモリのフォーマット

ddコマンドによる書き込み

USBメモリがマウントされている状態では、ddコマンドを実行することができない。

$ sudo dd if=hpdsa-1.2.8-107.rhel7u0.x86_64.dd of=/dev/disk2
Password:
dd: /dev/disk2: Resource busy

そこで、ddコマンドを実行する前に、USBメモリをアンマウントしておく。

$ sudo umount -fv /Volumes/UNTITLED

改めて、ddコマンドを実行する。

$ sudo dd if=hpdsa-1.2.8-107.rhel7u0.x86_64.dd of=/dev/disk2
2584+0 records in
2584+0 records out
1323008 bytes transferred in 0.654908 secs (2020143 bytes/sec)

CentOSをインストール

CentOSをインストールする際にGRUBエントリーの編集を行い、デバイスドライバーのインストールとAHCIの無効化を行う。

GRUB選択画面

eコマンド”で編集画面に遷移し、”inst.dd modprobe.blacklist=ahci“を追記した上で起動を行う。この時点では、まだUSBメモリを挿入しない

vmlinuz initrd=initrd.img inst.stage2=hd:LABEL=CENTOS\X207\X20\X86_64 quit inst.dd modprobe.blacklist=ahci


すると、どのデバイスからドライバをインストールするかを問うプロンプトが表示されるので、**この時点で初めてUSBメモリを挿入**し、”**rコマンド**“によりデバイス一覧の再スキャンを行う。


DD: starting interactive mode

(Page 1 of 0) Driver disk device selection
    /DEVICE TYPE      LABEL
# to select, 'r'-reflesh, or 'c'-continue:

USBメモリが認識されるので、どのデバイスにある、どのドライバを組み込むのかを対話形式で入力する。

(Page 1 of 1) Driver disk device selection
	/DEVICE	TYPE	LABEL
1)	sda1	vfat	VID	XXXXX
2)	sda2	ext4	OEMDRV	XXXXX
# to select, 'r'-reflesh, or 'c'-continue: 2
DD: Examining /dev/sda2

(Page 1 of 1) Select drivers to install
1)	[]	/media/DD-1/rmps/x86_64/kmod-hpdsa-1.2.8-107.rhel7u2.x86_64.rpm
# to toggle selection, or 'c'-continue: 1

(Page 1 of 1) Select drivers to install
1)	[x]	/media/DD-1/rmps/x86_64/kmod-hpdsa-1.2.8-107.rhel7u2.x86_64.rpm
# to toggle selection, or 'c'-continue: c
DD: Extracting: kmod-hpdsa

これでドライバの組み込みが終了したので、この時点で必ずUSBメモリを抜いておく。USBメモリを挿したままインストール作業を実行すると、USBメモリからOSインストールを行おうとしてエラーが発生する。

HP Smart Array P440 FBWC Controller

SAS HDDのアレイコントローラであるP440は、何もしなくてもCentOSから認識された。違いはなんなんだ。