ubuntuからwindowsの共有フォルダにアクセスする。

ubuntuからwindows10の共有フォルダにアクセスしてみます。アクセスの仕方はファイルアプリを使う方法とマウントコマンドを使う方法です。windowsの共有フォルダは設定済みです。

最初にubuntu側の環境ですが以下のパッケージがインストールされています。

$ dpkg -l | grep smb
ii libsmbclient
ii libsmbios-c2
$
$ dpkg -l | grep samba
ii samba-libs
$
$ dpkg -l | grep cifs
$
(詳細は以下)

libsmbclientは入っていますが、samba-client、および、cifs-utilsは入れていません。なお、libsmbclientがインストールされた時に以下のものもインストールされたようです。

$ dpkg -l | grep 2:4.7.6+dfsg
ii libsmbclient
ii libwbclient0
ii samba-libs
(詳細は以下)

まずファイルアプリを使う方法です。

ファイルアプリを開いて「他の場所」を選択すると下部に「サーバーへ接続」が表示されるのでwindows10の共有フォルダの場所を「smb://windowsのIPアドレス/共有フォルダ名」のように指定して「接続」ボタンを押下します。

すると、ユーザー名、ドメイン、パスワードを入力する画面が表示されるのでアカウント情報を入力します。

共有フォルダに接続できるとファイルアプリの左側にwindows10の共有フォルダが表示されます(赤枠)。共有の解除をするには隣の矢印(青枠)をクリックすると解除されます。

次にマウントコマンドを使ってwindows10の共有フォルダにアクセスします。

ubuntuに共有フォルダをマウントするディレクトリを作成します。ここでは、/home/user/work/mnt にマウントするようにします。マウントコマンドでは「-o」オプションを使うのですが、このオプションはroot権限がないと使えないため作業はrootユーザーで行います。

rootユーザーにスイッチした後に以下のコマンドを実行します。


# mount -t cifs -o username=<ユーザー名>,password=<パスワード> //windowsのIPアドレス/共有フォルダ名 /マウント先のディレクトリ

気をつけないといけないのは「username=<ユーザー名>,password=<パスワード>」は1つの引数のようで、ユーザー名とパスワードの間のカンマ「,」の後ろにスペースを入れてはいけません。あと、わかりづらいですが「//windowsのIPアドレス/共有フォルダ名」と「/マウント先のディレクトリ」は別々の引数です。

実際にはこんな感じです。


# mount -t cifs -o username=user,password=XXXX //192.168.0.3/jake /home/user/work/mnt

ファイルアプリでアクセスしたときはドメインに「WORKGROUP」を入力しなければならなかったのですが、マウントコマンドのときはドメイン情報は入力しなくても大丈夫でした(ユーザー名とパスワードは必要です)。

ファイルアプリでマウントしたディレクトリ(/home/user/work/mnt)を見てみます。

mntディレクトリのアイコンが普通のものと違うようです。コンセントの差込口みたいなものが表示されています。

マウントの解除は一般ユーザーでは行なえません。ファイルアプリから矢印(上の青枠)をクリックしてもエラーになってしまいます。マウントを解除するにはrootユーザーで以下のコマンドを実行します。

# umount -a -t cifs

これでマウントが解除されます。

Nginxでのリクエストとレスポンスのバッファサイズのチューニング

Nginxで運用しているWEBサーバーに画像ファイルをアップロード(フォームからのPOSTを)した際、「413 Request Entity Too Large」と表示されてアップロードができませんでした。

これはどうやらnginxがデフォルトで受信できるリクエストサイズが小さいためにエラーとなっているようです(デフォルトでは1メガバイトのようです)。この画面が表示されたときのnginxのerror.logには「client intended to send too large body」と出力されていました。受信できるリクエストサイズを拡張するにはclient_max_body_sizeディレクティブに適切な値を設定する必要があるとのこと。画像ファイルのアップロードにはPHPを使用しており、php.iniの中のupload_max_filesizeで最大2メガバイトと指定しているので、client_max_body_sizeには2メガバイト以上を指定することにしました。

この設定で画像のアップロードはできるようになったものの、error.logには「a client request body is buffered to a temporary file」のワーニングが表示されていました。気持ちが悪いので、このワーニングも対処することにします。調べてみるとclient_body_buffer_sizeディレクティブに適切な値を設定することで解消するらしい。client_body_buffer_sizeのデフォルト値は64ビットOSの場合は16キロバイトが一般的でリクエストサイズがこれを超えた場合にワーニングを出力するとのことです。このサイズを超えたリクエストはバッファに収まらないので一時ファイルに出力したことをワーニングとして示しているようです。デフォルト値ではあまりにも小さいので思い切ってアップロード可能な画像サイズまで引き上げました。一時ファイルを出力することはディスクI/Oが発生して処理時間が長くなってしまいますので。

なお、この一時ファイルはディスク上のファイルではなくメモリ上のファイル(tmpfsという)も指定可能なようです。tmpfsを使用すればディスクI/Oは発生しないので良いように思えるのですが、リクエストサイズがtmpfsの容量を溢れてしまうとスワップ領域に一時ファイルが書き出されてしまうということでtmpfsの使用はやめました。ちなみに一時ファイルの出力先の指定はclient_body_temp_pathディレクティブで指定できるとのことです。tmpfsはディスク容量を確認する際に使用するdfコマンドで確認できます。

ちなみに先ほど書いた「a client request body is buffered to a temporary file」のワーニングですが、初期設定のnginxでWordPressを運用していると必ず出てしまうようですね。。

これで画像ファイルのアップロード時のエラーおよびワーニングは出なくなりました。なので、いったんこれで様子見をしようと思います。

まとめ。リクエストのバッファリングに関する設定は以下をチューニングする。

client_max_body_size
受信できる最大リクエストサイズ。デフォルトでは 1M 。

client_body_buffer_size
メモリ上のバッファに読み込む最大リクエストサイズ。デフォルトでは 8k or 16k(使用するOSにより変わる)。このサイズを超えるリクエストだった場合はclient_body_temp_pathに指定された一時ファイルにリクエストを書き出す(ディスクI/Oが発生する)。

client_body_temp_path
バッファの代わりとして使用する一時ファイルの出力先。

[広告]

ここからはリクエスト時のバッファサイズについて調べているうちにわかったことを覚え書きとして残しておきます。nginxではリクエストだけではなくレスポンスのバッファについても設定ができるようになっています。レスポンス時のバッファって何のこと?と最初は思ったのですが、PHPやCGIを処理するFastCGIサーバーからのレスポンスのバッファリングのことだと理解しました。

nginxではPHPやCGIを処理する際、fastcgi_passディレクティブでFastCGIサーバーのIPアドレスとポートを指定します。

FastCGIを使っている場合のレスポンスのバッファリングに関する設定は以下のようなものがあります。

fastcgi_buffering
バッファリングを有効にするかどうかの設定。デフォルトでは有効となっている。

fastcgi_buffer_size
一番最初のレスポンスをバッファリングする際のサイズを指定する。デフォルトでは 4k or 8k(使用するOSにより変わる)。

fastcgi_buffers
fastcgi_buffer_sizeにレスポンスが収まりきらなかった場合、fastcgi_buffersを使用する。fastcgi_buffersはパラメータを2つ持ち、1つ目のパラメータは領域の個数、2つ目のパラメータは1領域分のサイズを指定する。デフォルトでは 8 4k or 8k。4kもしくは8k(使用するOSにより変わる)の領域を最大8個使用するという意味。

fastcgi_busy_buffers_size
FastCGIサーバーからのレスポンスを受信しているときの最大バッファサイズ。デフォルトでは 8k or 16k(使用するOSにより変わる)。fastcgi_buffersと同じにするか、2倍程度にするのが一般的らしい。

fastcgi_max_temp_file_size
FastCGIサーバーからのレスポンスがバッファから溢れたときに書き出される一時ファイルの最大サイズ。

デフォルトだとfastcgi_buffer_size、fastcgi_buffersがかなり小さくメモリ上のバッファが足りなくなった場合は一時ファイルに書き出すとのこと。その際、「an upstream response is buffered to a temporary file」のメッセージがerror.logに出力されるらしい。ところがFastCGIサーバーからのレスポンスがどう考えてもfastcgi_buffer_size、fastcgi_buffersのバッファサイズを超えていると思われるのだけれど、このメッセージがerror.logに出力されていない。画像ファイルをレスポンスにしているからかなりのサイズだと思うのだけれど。これについて思い当たるのは以下の2点ということに考えが至りました。

  • 上の絵ではnginxとFastCGIサーバーは別々のサーバーとしていますが、実際の僕の環境はnginxとFastCGIサーバーはUnixソケットを通じて同一のサーバーでデータ連携をしている。これがバッファリング時のエラーを回避させているのか?
  • 上の絵ではnginxはWEBサーバーであってリバースプロキシの役割は持たせていない。nginxをリバースプロキシとして運用する場合はproxy_passディレクティブを設定してプロキシ先を指定するが、そのような構成ではない。レスポンス時のバッファリングのエラーはプロキシとして運用したときの場合のものか?

ちなみに2点目にあるリバースプロキシとしてnginxを運用する場合は以下のディレクティブでバッファリングに関する設定を行います。FastCGIのときの意味合いとほぼ同じだと思っているのですが。。

proxy_buffering
proxy_buffer_size
proxy_buffers
proxy_busy_buffers_size
proxy_max_temp_file_size

「an upstream response is buffered to a temporary file」が発生しない理由はよくわからないのですが、とりあえず上手くいっているようなのでFastCGIのレスポンスのバッファリングの設定はデフォルトのままとしています。

最後にFastCGI系とプロキシ系のレスポンス時のバッファリングに関するディレクティブの説明(nginxの公式サイト)を載せておきます。

FastCGI系
プロキシ系