はじめに
rubyのgemであるruby-quotaを日本語で試されている人の文献が見つからなかったので、個人的なメモを残します。
gemについての詳しい情報はこちら => https://github.com/axic/ruby-quota
いわゆるクォータ情報を見たり、更新したり等々するものです。
現在設定されているクォータ情報の取得と更新を試してみたのでその際の記録を残していきます。
環境
今回試しているのは以下の環境になります。
- Ruby
- ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]
- ruby-quota
- ruby-quota-0.8.0.gem
- Cent OS
- CentOS release 6.5 (Final)
- kernel 2.6.32-431.5.1.el6.x86_64
使い方
install
ご存知gem installで完了です。
# gem install ruby-quota --no-ri --no-rdoc
Fetching: ruby-quota-0.8.0.gem (100%)
Building native extensions. This could take a while...
Successfully installed ruby-quota-0.8.0
1 gem installed
require
使うには quota という名前でrequireできます。
require 'quota'
check
※私の環境ではgetquota実行時に権限が足りてなさそうだったので root で実行しました。linux の repquota コマンドで必要な権限分の権限は必要と思われます。
- uid のクォータ情報を取得
基本的にはuidかgidを引数にとってQuota::UserIDかQuota::GroupIDでインスタンス化してgetquotaで取得します。
※uidの番号であれば直接インスタンス化せず情報が取れるみたいです。
構造化データで返ってきます。
user = Quota::UserID.new(000)
user_quota = Quota.getquota('/var', user)
p user_quota
=> #<struct Struct::DiskQuota bhardlimit=0, bsoftlimit=0, curblocks=111111, ihardlimit=0, isoftlimit=0, curinodes=104, btimelimit=0, itimelimit=0>
- gid のクォータ情報を取得
uidと同様です。
group = Quota::GroupID.new(111) # => #<Quota::GroupID:0x007f2f9a09bcc8>
group_quota = Quota.getquota('/var', group)
p group_quota # => #<struct Struct::DiskQuota bhardlimit=1124000, bsoftlimit=1024000, curblocks=483328, ihardlimit=0, isoftlimit=0, curinodes=118, btimelimit=0, itimelimit=0>
update
更新の場合はgetquotaしてきたデータに対してsetterで新しい値を入力し、setquotaしてあげれば反応してくれると思います。
※未検証だけど、おそらくこの形
group = Quota::GroupID.new(111) # => #<Quota::GroupID:0x007f2f9a09bcc8>
group_quota = Quota.getquota('/var', group)
group_quota.bhardlimit = 1224000
p group_quota # => #<struct Struct::DiskQuota bhardlimit=1224000, bsoftlimit=1024000, curblocks=483328, ihardlimit=0, isoftlimit=0, curinodes=118, btimelimit=0, itimelimit=0>
Quota.setquota('/var', group, group_quota)
=> NameError: `curspace' is not a struct member
getquotaからsetquotaの書き換えは curblocks があってだめっぽいです。これは設定を変更するものではなくて常に変わっていくものだからという考え方の用に思えます。したがって別な方法でやってみました。
group = Quota::GroupID.new(1247)
limit_config = Quota::DiskQuota.new
limit_config.bsoftlimit = 5120000
limit_config.bhardlimit = 5620000
p limit_config
#<struct Struct::DiskQuota bhardlimit=5620000, bsoftlimit=5120000, curblocks=nil, ihardlimit=nil, isoftlimit=nil, curinodes=nil, btimelimit=nil, itimelimit=nil>
Quota.setquota('/var', group, limit_config)
=> NameError: `curspace' is not a struct member
from (pry):16:in `setquota'
これもだめでした。
先輩と話をした結果 ruby-quota のソースコード、linux の quotactl あたりの確認をするかということになりました。
結果、ruby-quotaで書かれているコードを変更して暫定対応とすることとしました。以下にその対応を記載します。
ruby-quota の 変更
手順は
- quota.c の編集
- コンパイル
- gemファイルの入れ替え
- Quota.setquotaの再実行
です
quota.c の編集
差分を表示します。
※ 取り急ぎの対応です
※ わたくしの環境での修正になりますのでご注意ください。
curspace がらみでエラーが出るようだったので、下記の通り編集しています。
--- from_file
+++ C:\Users\katsumata\nfEngine\ruby-quota-master\quota.c
@@ -350,7 +350,7 @@
c_dqb->dqb_bhardlimit = GetMember("bhardlimit");
c_dqb->dqb_bsoftlimit = GetMember("bsoftlimit");
#if !defined(USE_LINUX_CURBLOCKS)
- c_dqb->dqb_curspace = GetMember("curspace");
+ c_dqb->dqb_curspace = GetMember("curblocks");
#else
c_dqb->dqb_curblocks = GetMember("curblocks");
#endif
@@ -612,4 +612,4 @@
rb_alias(CLASS_OF(rb_mQuota), rb_intern("setlimit"), rb_intern("setqlim"));
rb_alias(CLASS_OF(rb_mQuota), rb_intern("setusage"), rb_intern("setuse"));
コンパイル
書き換えたものを含んだgemをまるごとアップロードし実際に使うサーバ上でコンパイルします。
gemのディレクトリ内で
$ ruby ./extconf.rb
checking for unistd.h... yes
checking for linux/quota.h... yes
checking for linux/types.h... yes
checking for sys/quota.h... yes
checking for sys/types.h... yes
checking for sys/fs/ufs_quota.h... no
checking for ufs/ufs/quota.h... no
checking for sys/ucred.h... no
checking for sys/statvfs.h... yes
creating Makefile
$ make
compiling quota.c
quota.c: In function ‘__getdevice’:
quota.c:213: 警告: unused variable ‘buf’
linking shared-object quota.so
上記手順を踏むと quota.so というファイルが生成されます。
gemファイルの差し替え
このファイルを既存の ruby-quota の quota.so 差し替えます。
私の環境では差し替えるべきファイルは以下の三点でした。
- ./lib/ruby/gems/2.1.0/gems/ruby-quota-0.8.0/quota.so
- ./lib/ruby/gems/2.1.0/gems/ruby-quota-0.8.0/lib/quota.so
- ./lib/ruby/gems/2.1.0/extensions/x86_64-linux/2.1.0-static/ruby-quota-0.8.0/quota.so
これを差し替えた上で再実行します。
再実行
require 'quota'
group = Quota::GroupID.new(1247)
group_quota = Quota.getquota('/var', group)
=> #<struct Struct::DiskQuota
bhardlimit=1124000,
bsoftlimit=1024000,
curblocks=499712,
ihardlimit=0,
isoftlimit=0,
curinodes=122,
btimelimit=0,
itimelimit=0>
group_quota.bhardlimit = 1224000
group_quota.bsoftlimit = 1124000
p group_quota
#<struct Struct::DiskQuota bhardlimit=1224000, bsoftlimit=1124000, curblocks=499712, ihardlimit=0, isoftlimit=0, curinodes=122, btimelimit=0, itimelimit=0>
Quota.setquota('/var', group, group_quota)
=> nil
quota_after = Quota.getquota('/var', group)
=> #<struct Struct::DiskQuota
bhardlimit=1224000,
bsoftlimit=1124000,
curblocks=499712,
ihardlimit=0,
isoftlimit=0,
curinodes=122,
btimelimit=0,
itimelimit=0>
上記の設定をした後に
- quota.setquotaでエラーがでなくなった
- quota.getquotaで設定している値がとれている
- repquota コマンドで変更が反映されている
がうまくいっていることを確認しました。
終わりに
gemを手作業で直接変更してしまっているので、同環境を構築しなければいけない際に自動で行くようにしておくことが課題。
とりあえず動きました。