「Gentoo」詳しいね!で本命彼と距離を縮める・5選「GentooInstallBattleタイムトライアルをする」
今勢いのあるメタディストリビューション「Gentoo」 男性はインストールしていてる人が多いので、会話のタネに持ってこい!
今回は、「Gentoo」で気になる彼との距離を縮める方法をご紹介したいと思います。
■1.Larry the cowのかわいらしさ
Gentooで公式マスコットの座を獲得しているLarry the Cow。「すっとぼけた顔」と呼ばれるそのゆるふわさだけでなく、画像の1つ1つにかわいさがあり、無駄のないデザインにしびれます。「ぽやっとした表情がたまらないよね」「All of the sudden, Larry the Cow was in controlってとこが格好良い」。このセリフを言っておけば、ちゃんとLarry the Cowを知ってる感は出せます。あまり語りすぎるとGの形のロゴは知らないのかと思われてしまうので、さらっと話しましょう。
■2.Linux以外について触れる
男性はLinux以外のOSも大好き!What is Gentoo?のページを見ると、"Gentoo is a free operating system based on either Linux or FreeBSD"と書かれています。 そのまま全てをビルドすることはできませんが、Wikiを読んだりoverlayをいれたりすればGentoo/FreeBSDを楽しめます。
「GentooってLinux以外でも動くって知ってる?」とあくまで詳し過ぎない程度に情報をチラ見せしていきましょう。知らなかった場合は、食いついてくれるはずです。また、彼が知っていた場合でも「お、こいつ結構ちゃんと知ってるじゃん」と思ってくれます。
■3.全然知らないフリ
男性は人に教えるのが大好きです。気になる彼がハマっているのを知りながら、「流行ってるのは知ってるけど、面白いの?」とふっかけてみてください。面白さを熱弁してくれること間違いなし。インストールディスクを持っていたらインストールしてもらいましょう。Gentooインストールは二人の距離を一気に縮めます。インストールが終わってもいろいろな環境設定で会え、そこでどのUSEフラグやCFLAGSがいいのか感想を言い合えます。一番おいしい方法です。
Gentooを使っているひとの前で「ちょっとパーティション設定までしたんだけど、カーネルがうまくビルドできなくて止まってるんだよね」と言うのも良いでしょう。「もったいない!そこからが面白いんじゃん!」と熱弁してくるはずです。「本当?信じて良い?」「うん!信じて、絶対面白いから!」と謎の絆が生まれます。そして、カーネルがブートしたあとは必ず「めちゃくちゃ面白かった!あそこで勧めてくれてありがとう」と褒めて上げてください。他にも面白いUSEフラグがあるか聞いて、次につなげましょう。
■4.GenTwooで遊ぶ
GenTwooというGentooを楽しく使えるサイトがあります。Gentooでパッケージをインストールすると、ビルド記録を残しTwitterにつぶやくことができます。お互いにパッケージをインストールし合い、どちらがより速く目標のパッケージをインストールできるかUSEフラグ勝負をしてみると距離が縮まります。二人でひとつのebuild(パッケージファイル)を見るシチュエーションが自然と生まれるのでオススメです。
■5.GentooInstallBattleタイムトライアルをする
少し前にGentooInstallBattleと呼ばれるオモシロGentooインストールが流行りました。それと同じ要領で、巷ではGentooInstallBattleタイムトライアルが流行っています。GentooのminimalインストールCDを使って、ローカルの人がsshを設定しカーネルの設定をしつつ、リモートの人がsshで入ってその他のインストール作業を行なうと時間を短縮することができます。初心者は特に協力プレイが必要なので、一気に距離が縮まること間違いなし。是非試してみてください!
■おわりに
いかがでしたでしょうか?
Gentooは誰でも楽しめるメタディストリビューションとなっております。大事なのは、詳しくなりすぎないこと。オタクな印象を与えると男性は引いてしまうので気をつけてくださいね!
このへんからです
おれが…おれこそがBtrfsckだ!、という話
Btrfsは非常に安定した安心なファイルシステムです - Togetter
まあ、上のリンクのような話なのだけど、そこからどういうバグだったの?とかどういう状況だったの?とかどうやって直したの?というところを補則するための記事
もともとは多分ここのエラーで、leafがcorruptしたんじゃないかな?と思う。
http://twitpic.com/cv01wy/full
そんでここでささるようになった
こっち側を分析していく。
RIPを見ると死んでる場所は btrfs_drop_inode+0x10 であることがわかる。 btrfs_drop_inode() はこんだけの関数。ちょろい。
int btrfs_drop_inode(struct inode *inode) { struct btrfs_root *root = BTRFS_I(inode)->root; /* the snap/subvol tree is on deleting */ if (btrfs_root_refs(&root->root_item) == 0 && root != root->fs_info->tree_root) return 1; else return generic_drop_inode(inode); }
この中で NULL pointer dereferenceで落ちているので、なんとなく見当はついて、 "inode"か"root"かがNULLなんだろなーと感じたと思う。
一応 objdump -xS inode.o しておくと
000000000000f020 <btrfs_drop_inode>: free: call_rcu(&inode->i_rcu, btrfs_i_callback); } int btrfs_drop_inode(struct inode *inode) { f020: e8 00 00 00 00 callq f025 <btrfs_drop_inode+0x5> f021: R_X86_64_PC32 __fentry__-0x4 struct btrfs_root *root = BTRFS_I(inode)->root; f025: 48 8b 97 20 fe ff ff mov -0x1e0(%rdi),%rdx free: call_rcu(&inode->i_rcu, btrfs_i_callback); } int btrfs_drop_inode(struct inode *inode) { f02c: 55 push %rbp f02d: 48 89 e5 mov %rsp,%rbp struct btrfs_root *root = BTRFS_I(inode)->root; /* the snap/subvol tree is on deleting */ if (btrfs_root_refs(&root->root_item) == 0 && f030: 8b b2 f8 00 00 00 mov 0xf8(%rdx),%esi f036: 85 f6 test %esi,%esi f038: 75 16 jne f050 <btrfs_drop_inode+0x30> root != root->fs_info->tree_root)
ということで、rootがNULLになってるよね、って感じです。 写真のやつ見てもRDXが0になってるもんね。 RDXってf025でmovされてるとこだし、rootがNULLだよね。
じゃあなんで、ここがNULLなのよ?ってことなんですが、Stack traceを見てみると。 btrfs_new_inode+0x135からiputが呼ばれていて、rootがNULLになってるとこがあるんだなあ、とわかります。
btrfs_new_inode()に、こんな感じのコードがあって
inode = new_inode(root->fs_info->sb); if (!inode) { btrfs_free_path(path); return ERR_PTR(-ENOMEM); } /* * we have to initialize this early, so we can reclaim the inode * number if we fail afterwards in this function. */ inode->i_ino = objectid; if (dir) { trace_btrfs_inode_request(dir); ret = btrfs_set_inode_index(dir, index); if (ret) { btrfs_free_path(path); iput(inode); return ERR_PTR(ret); } } /* * index_cnt is ignored for everything but a dir, * btrfs_get_inode_index_count has an explanation for the magic * number */ BTRFS_I(inode)->index_cnt = 2; BTRFS_I(inode)->root = root; BTRFS_I(inode)->generation = trans->transid; inode->i_generation = BTRFS_I(inode)->generation;
あれれ〜? new_inodeでinode作った後に、rootがNULLのままiputしちゃってるよ〜?ってことがわかりますね。 ちなみにここは、ディレクトリにファイルのindexとれなかった時の処理なんで、多分(u64)-1ぐらいのファイル作ったら誰でもbtrfs落とせるんじゃないかしらん。ということで、多分btrfs_drop_inode()のところに、rootがNULLかどうかチェックすればいいんじゃないか、と思う。
さて、ここまではまあバグなんだけど、「ファイルを作りまくって」死んでいるのではなくて、どこかのblockがcorruptしててここのバグをふんでしまっているので、直すべき場所はまだ他にあるんだな。
dmesgを見てみると
[ 188.559920] btrfs: corrupt leaf, slot offset bad: block=387949473792,root=1, slot=5
こんなのが大量にあるのでみんな大好きな "btrfs-debug-tree -b 387949473792
item 5 key (814282 DIR_ITEM 3304014366) itemoff 3749 itemsize 46 location key (987934 INODE_ITEM 0) type 2 namelen 16 datalen 0 name: initramfs.L0vZCH item 6 key (814282 DIR_ITEM 3827348333) itemoff 69239 itemsize 46 location key (0 UNKNOWN.0 0) type 0 namelen 0 datalen 0 name: location key (0 UNKNOWN.0 0) type 0 namelen 0 datalen 0 name: item 7 key (814282 DIR_ITEM 3858130265) itemoff 3657 itemsize 46 location key (987937 INODE_ITEM 0) type 2 namelen 16 datalen 0 name: initramfs.TbTWJF
あー、 item 6がどう見てもおかしい感じですねー。 本来は
<item 6のitemoff> = <item 7のitemoff> + <item 7のitemsize>
になっているべきだし、そのせいか、itemの中身もとれてません。(本来は他のitemのようにファイル名がとれるべき)
(そんで、このまわりのitemの中を見てみるとどーもこれが/var/tmpの下のファイルを管理してるものっぽい気がするよねーということがわかる。実際ls /var/tmpするとIOエラーで読みこめなかった)
そんで、このitem 6を直したいなー、ここ直さないと(/var/tmpだし)結局ここに読み書きしたらファイルシステム死んじゃうし直さないとだめだなー、となる。 じゃあどう直すか?なんだけれど、こういうコードでoreorebtrfsckでも書いて実行してやりゃ直る。 (btrfs-progsのヘッダやらを使っている)
https://gist.github.com/naota/5703328 (なんかgistはれないや、よくわからない)
コメント書いてあるし、なにやってるかなんとなーくわかるかと思う・・・。
ようするに
- 指定したブロック番号に対応するディスク上の場所を探す (RAID1されてるので全てを)
- item 6のoffsetを正しく書きかえる
- (btrfs_print_leafで書きかえがうまくいってitem 6 keyの中が読めてること確認)
- checksumを更新する
- diskに書いてfsyncする
とやっているだけ。
そんでrebootしたらきれいに動く。よかったね。 item 6はちゃんと読めるとこうなる
item 6 key (814282 DIR_ITEM 3827348333) itemoff 3703 itemsize 46 location key (1840149 INODE_ITEM 0) type 2 namelen 16 datalen 0 name: initramfs.JzzElY
rm -rf /var/tmp/initramfs.* してもささらなかったのでこれからも安心して生きていける。
Ustした
Ustでxyzshのebuild書きましたよ。 なんでかって、その、いい題材だったんで・・・・
録画はこちらー ってしたかったけど録画ボタンおしてなかったよ、ふへへへへへ
まとめ
- autotools-utilsでautotoolsなpackageは楽にできるよ
- PATCHES変数
- AUTOTOOLS_AUTORECONF
- AUTOTOOLS_IN_SOURCE_BUILD
- QAは直そう
- CFLAGSがうまくあたってない
- LDFLAGSがうまくあたってない
- ライブラリにSONAMEが設定されてない
- stripされている
- makeが直接呼ばれている ( $(MAKE) にする)
- ライブラリのリンクはちゃんとしよう
- libdlとかもちゃんとね。 (underlinkingされやすい)
- ncursesは最近ライブラリの場所変わったりしてるよ (pkg-configでとれるからそれ使ってね)
定期的にできたらなーって思うけど、ネタが多分ないよう、的なあれもあるんで、こんなネタがいいなとかこんなのほしいとかこのバグ直せよ、とかどうぞどうぞ
freeのshared
freeとかしてみるとsharedが0になっている。
$ free total used free shared buffers cached Mem: 3884436 3371444 512992 0 3492 1434784 -/+ buffers/cache: 1933168 1951268 Swap: 5000188 0 5000188
free(1)を見ても"The shared memory column should be ignored; it is obsolete."と書いてあるし、0固定なんでしょう。でも、なんで0なんでしょう。
freeはprocpsというパッケージのコマンドで proc/sysinfo.cの部分が値を取得するコードになっている。これは /proc/meminfo から情報を読んでいる。 sharedに対応する部分は "MemShared" というところだったのだけれど、これはすでに削除されている。
- procps http://gitorious.org/procps/procps
- MemSharedが削除されたpatch LKML: Marc-Christian Petersen: [PATCH 2.4.21-pre4|BK] remove /proc/meminfo:MemShared
これよりも前のカーネルでも長い間 "MemShared"は表示されていても、0に固定されていた。
なぜかというと、sharedを計算するのはコストが高いから、だそーだ。
linux-2.3.12以前だとこんな感じでsharedramを計算している。
void si_meminfo(struct sysinfo *val) { int i; i = max_mapnr; val->totalram = 0; val->sharedram = 0; val->freeram = nr_free_pages << PAGE_SHIFT; val->bufferram = atomic_read(&buffermem); while (i-- > 0) { if (PageReserved(mem_map+i)) continue; val->totalram++; if (!page_count(mem_map+i)) continue; val->sharedram += page_count(mem_map+i) - 1; } val->totalram <<= PAGE_SHIFT; val->sharedram <<= PAGE_SHIFT; return; }
ようするに、全てのメモリをいちいちなめてsharedを計算している これがlinux-2.3.13だと
void si_meminfo(struct sysinfo *val) { val->totalram = totalram; val->sharedram = 0; val->freeram = nr_free_pages << PAGE_SHIFT; val->bufferram = atomic_read(&buffermem); return; }
このように0固定されている。
3GBのメモリつんでたら、971109回ループがまわることになるし、より大きなシステムだともっと大変なことになってしまうだろう。
ちなみに、当時 これ聞かれまくったのかFAQにものってる http://www.tux.org/lkml/#s14-3
#fav2toshi_a Advent Calendar 最終日
さ、最終日なので何日目とかは関係ないのですよ?
ふぁぼとmikutter・としぁさんとの戦いについてはとしぁさんの記事を見ていただければいいかと思いますが、最近はとしぁさんのmikutterもいろんな意味で落ち着いてきましたよね。
もちろん安定している、という意味でもあるのですが、昔はよくとしぁさんから何回ふぁぼったとかのDM爆撃をされたものです。
その前はリプライだったりして
こんなふうにリプ爆撃をされたころもありました。
こんな感じだったらしいですね。でも
のようにたかだか10分だったわけでセミナーの間中、複数人からふぁぼられているいまとなっては・・・といった感じですね。
しかし、しかし、しかし このころはふぁぼる側とふぁぼられる側との温かな交流があったとも言えるのではないだろうか
なんというか、ふぁぼるリスク・ふぁぼるための試行錯誤・反撃…息をのむような瞬間・・・10分間でありました。
そのふぁぼの緊張感をとりもどしたくはないですか?
というわけで、こちらをごらんください。
はい Minecarftです。ちょっとmodをいれていますが
この人っぽい緑のなにか、拡大してみましょう。
はい、と○ぁですね(
このmobはそれぞれとしぁ氏のついーよと関連づけられていす。そのついーよの中身を定期的に「つぶやき」ます。
また、ライフ・スピード・防御、全てがふぁぼられ数(favstarから取得)に比例しています。 もしふぁぼられが0だったらって? いやいや、そんなオカルトありえません
そして、このと○ぁをたおすと・・・もうお分かりですね?
そう、ふぁぼられます。
と○ぁは金塊をドロップします。これから金のインゴットを作ってクラフトすると・・・・
こんなパーツができるので、6種類のパーツをあつめると、冒頭の「としぁスポーンブロック」ができます。このスポーンブロックは黒曜石と同じぐらい硬いのでこれで部屋を作ってスポーンさせてTNTを落としたりすると一気にふぁぼれていいんじゃないかなあと思います。
まあ、基本的にと○ぁはかなりスポーンするように作ってあるのでてきとーにしてるだけでも結構ふぁぼられるんですけどね。 よくふぁぼられてるやつはめっちゃ強いので気をつけてくださいね。しかもまとまってわくし。ふぁぼられてないとしぁはざこなんですけどねえ。
これから
- スキンの改善
- パーツ画像の改善
- ふぁぼりをasyncにする
- 50個ごとに「と○ぁを50体ふぁぼりたおしました」とかつぶやくようにしたい
- と○ぁスポーンを使ったトラップタワーによるふぁぼ爆撃の実験
技術的なはなし
MIKUって知ってますか? よく知らないでけどLispっぽいなにものかですよね。
今回はそれを尊重して、 Clojureでmodを書きました・・・・・・と言いたかったんですが、いろいろあってmob動作部分は全てJavaになりました…orz
どういう原理かというと Fav2toshi_a.javaの
@Mod(modid="f2t", name="fav2toshi_a", version="0.0.0") @NetworkMod(clientSideRequired=true, serverSideRequired=false) public class Fav2toshi_a { @Init public void load(FMLInitializationEvent event) { String name = "f2t"; this.ns = name + ".core"; System.out.println("Enabling " + name + " clojure Plugin"); invokeClojureFunc("load", this, ExtendableItem.class, ItemStack.class, ExtendableBlock.class, Constants.items, Constants.blocks, Constants.materials); } private void invokeClojureFunc(String enableFunction, Object... args) { try { ClassLoader previous = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); clojure.lang.RT.loadResourceScript(ns.replaceAll("[.]", "/")+".clj"); clojure.lang.RT.var(ns, enableFunction).invoke(args); Thread.currentThread().setContextClassLoader(previous); } catch (Exception e) { System.out.println("Something broke setting up Clojure"); e.printStackTrace(); } } }
と、こういった感じで "clojure.lang.RT"を使って「実行時に」Clojureのファイルを読ませます。引数にしているのは、Clojure側で必要になるクラスとかです。
(defn load [args] (do (def Mod (nth args 0)) (def Item (nth args 1)) (def ItemStack (nth args 2)) (def Block (nth args 3)) (def items (assoc (mapit (nth args 4)) "toshiaHead" (new-item 900 0 "toshiaHead" "封印されしとしぁの頭") "toshiaRightHand" (new-item 901 1 "toshiaRightHand" "封印されしとしぁの右手") "toshiaBody" (new-item 902 2 "toshiaBody" "封印されしとしぁ") "toshiaLeftHand" (new-item 903 3 "toshiaLeftHand" "封印されしとしぁの左手") "toshiaRightLeg" (new-item 904 4 "toshiaRightLeg" "封印されしとしぁの右足") "toshiaLeftLeg" (new-item 905 5 "toshiaLeftLeg" "封印されしとしぁの左足"))) (def materials (mapit (nth args 6))) (def blocks (assoc (mapit (nth args 5)) "toshia" (toshia-spawn))) (create-recipes) (create-mob) (println "#fav2toshi_a loaded")))
Clojure側ではこうやって引数をうけとっています。 たとえば新しいアイテムを生成するnew-itemとかをのぞいてみると
(defn inst [clas & args] (Reflector/invokeConstructor clas (to-array args))) (defn new-item [i icon name name2] (let [item (inst Item (intg i))] (doto item (.icon (intg icon)) (.name name)) (LanguageRegistry/addName item name2) item))
このように "Item"クラスのコンストラクタを Reflectorを使って呼び出して、各種設定をしてアイテム登録をしています。
"Item"クラスは生のマインクラフトのItemクラス、ではなく
public class ExtendableItem extends Item { public ExtendableItem(Integer par1) { super(par1); } public void icon(int i) { this.setIconIndex(i); } public void name(String n) { this.setItemName(n); } @Override public String getTextureFile() { return CommonProxy.ITEMS_PNG; } }
このような薄いラッパクラスをかませています。
さて、なんで Reflectorを使ったり、ラッパクラスを使っているかというと、マイクラの元からあるクラスだと難読化によってクラス名が変わってしまうからなんですね。あーめんど。
このへんをおさえてしまえば、Clojureでマイクラmodを書くことはそんなにはむずかしくもなくなると思います。(Bukkit使う時とはくらべものにならないけど)
さてはて、そんなこんなでマイクラしながらとしぁさんのおもしろいついーよを読んで、ふぁぼれるようになりましたね。
それでは2013年も #fav2toshi_a をよろしくお願いいたします。
hoge
[tex:\displaystyle\sum_{i=1}^{10} a] [tex:\textstyle\sum_{i=1}^{10} a]