エラー時にexit(1)しちゃうようなプログラムにコアダンプさせる
かなり久々の記事。
昨日、一昨日とmixiが障害発生のために閲覧できなくなっていた。
DDoSアタックでもないらしいし、なにが原因かなーと思ってたら、
mixiのCTO @nealsato氏がtwitterで下記のツイートをしてた。
二日とも複数台のmemcachedが連続して落ちました。コアは吐かずにストンと落ちるので、原因追及に時間がかかりましたが、memcachedへの接続数が異常に多いと落ちる事は再現できました。
#mixi
コア吐かないってことはプログラム側でexitしてるんだろうなーと思いつつ、
またまたtwitterで@kazuho氏による下記ツイートを発見。
「正常終了してるなら exit を LD_PRELOAD して SEGV させてコアダンプ採取すればいいじゃない」ってじっちゃんが言ってた
おーなるほどと思い、実際やってみた。
まずコアダンプしてくれるか設定確認。
# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 4096 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
core file sizeが0だとコアダンプしてくれないので、
下記コマンドを実行。
# ulimit -c 1048576
これでコアファイルのサイズは1MBになり、
コアダンプしてくれるようになる。
んで、テストプログラム。
///// // test.c #include <stdio.h> #include <stdlib.h> int main() { puts("hello, world!"); exit(0); } /////
コンパイルして実行。
# gcc -o test test.c # ./test hello, world!
次はexitのラッパー関数。
///// // sigsegv.c #include <signal.h> void exit(int status) { raise(SIGSEGV); } /////
# gcc -fPIC -shared -o sigsegv.o sigsegv.c
んでexitを置き換えて実行。
# LD_PRELOAD=./sigsegv.o ./test hello, world! セグメンテーション違反です (core dumped)
成功!
これは色々使えそう。
ASP.NETにおけるformタグのaction属性書換
ASP.NETにおけるformタグのaction属性を書き換える方法を書いてみます。
formタグのaction属性を直接aspxファイルに記述しても、
実行時に上書きされてしまいます。
ポストバック時にページ内リンク(例/index.asp#main)を使用したい場合など、
この仕様だと不都合が生じることがあります。
そこで、HtmlTextWriterクラスのサブクラスを作成し、
そのクラス内でaction属性を書き換えます。
public class MyWriter : HtmlTextWriter { private TextWriter writer; private string anchor; /// <summary> /// formタグのaction属性に設定される値です。 /// </summary> public string Anchor { get { return this.anchor; } set { this.anchor = value; } } public MyWriter(TextWriter writer) : base(writer) { this.writer = writer; } public MyWriter(TextWriter writer, string tabString) : base(writer, tabString) { this.writer = writer; } public override void WriteAttribute(string name, string value, bool fEncode) { if (string.Compare(name, "action", true) == 0) { // ここでaction属性値を書換 value = this.anchor == null ? "" : this.anchor; } base.WriteAttribute(name, value, fEncode); } }
引用元:How to render form tag with action="" - uber1024's WebLog
http://weblogs.asp.net/uber1024/archive/2004/04/08/109720.aspx
引用元では、formタグ検出時の処理もカスタム出来るように
RenderBeginTagメソッドをオーバーライドしていますが、
単なるaction属性の書き換えの場合は必要ないと思われるので省略しました。
上記コードでは、Anchorプロパティの値をaction属性として扱います。
そのため、WriteAttributeメソッドが実行される前に、
Anchorプロパティに値を設定する必要があります。
最後に、ページ本体でRenderメソッドをオーバーライドし、
上記MyWriterクラスを利用してaction属性を書き換える処理を記述します。
public partial class _Default : Page { private MyWriter myWriter; protected void Page_Load(object sender, EventArgs e) { } protected override void Render(HtmlTextWriter writer) { if (this.myWriter == null) { this.myWriter = new MyWriter(writer); this.myWriter.Anchor = "index.aspx#main"; } base.Render(this.mywriter); } }
こんな感じでしょうか。
デモ作りました。
2nd demoを作り、以下のURLにて販売中です。
宜しければ是非。
http://shop2.genesis-ec.com/search/item.asp?shopcd=17263&item=500226
08/06/27(Fri) at Nakano Moonstep [Deadmen Don't Die!!!]
ライブの告知です。
オールドスクール、ニュースクール、エモーショナル、メロディックと多種多様なハードコアバンドが出演する熱いイベントです!
KILLING OF THE DEAD presents
[DEAD MEN DON'T DIE]
2008/06/27(fri) at Nakano Moon Step
Adv. - \1,300 / Door - \1,500
Open - 18:00 / Start - 18:30
Bands)
KILLING OF THE DEAD (http://www.myspace.com/killingofthedead)
A Branded To Kill (http://www.myspace.com/abrandedtokilldemo)
Everyday New Dare (http://www.myspace.com/everydaynewdare)
The Longisland LxLxP (http://www.myspace.com/thelongislandlxlxp)
BARBAROSSA (http://www.myspace.com/barbarossajapan)
A.L.F.
DJ)
Yasuaki(ex. barbarossa)
SQL Server 2005/データ移行メモ
グループウェアの移行に伴い、
SQL Server 2005のデータ移行も必要になったのでメモ。
移行元サーバ、移行先サーバは、
ファイアウォールの都合上、直接接続出来ないので、
移行元サーバでバックアップをとり、
それを移行先サーバでリストアする、
という「バックアップ/リストア」な手法をとります。
バックアップ
1, 移行元サーバのManagement Studioを起動。
2, 「データベース」から移行対象を右クリックし、「タスク」→「バックアップ」を選択。
3, 「全般」ページで、バックアップ先を任意の場所に設定。
4, 「オプション」ページで、「既存のすべてのバックアップ セットを上書きする」を選択。
5, 「OK」ボタンをクリックし、バックアップを実行。
ファイル転送
バックアップで出力したファイルを何らかの手段で移行先サーバに転送しておく。
リストア
1, 移行先サーバのManagement Studioを起動。
2, 「データベース」から移行対象を右クリックし、「タスク」→「復元」→「データベース」を選択。
3, 「全般」ページで「復元用のソース」として「デバイスから」を選択。
4, 「...」ボタンをクリックし、転送したバックアップファイルを選択。
5, 「復元するバックアップ セットの選択」で、出てきた行にチェックを入れる。
6, 「オプション」ページで「既存のデータベースを上書きする」にチェックを入れる。※これいらないかも
7, 「OK」ボタンでリストアを実行。
以上で移行完了です。
が、この作業でデータベースの移行を行うと、
そのデータベースに含まれるユーザでSQL Server認証経由のログインが出来なくなってしまいます。
なので、必要であれば最後に以下の作業を実行します。
ログインアカウント設定
1, 移行先サーバのManagement Studioを起動。
2, 「新しいクエリ」を開き、以下のコマンドを実行。
USE [データベース名];
EXEC sp_change_users_login 'Update_one', '[ユーザ名]', '[ユーザ名]';
ドメインに応じてメール転送
qmailで受信メールの送信元のドメインを判別し、
特定のドメインであれば転送する、
ということをやってみました。
まず、判定スクリプト。
/usr/local/bin/chkdomというパスで作りました。
#!/bin/sh addr=${1#*\<} addr=${addr%\>*} while [ "$3" != "" ]; do if expr "$addr" : ".*@$3" > /dev/null; then exit 0 fi shift 1 done exit 1
condredirect [転送先アドレス] /usr/local/bin/chkdom $SENDER [ドメイン] |
メール転送設定スクリプト
qmail+vpopmailで、ユーザに転送設定するスクリプトを書いてみました。
ちなみに前提は次の通りです。
・vpopmailパス
/home/vpopmail
・vpopmailユーザ
vpopmail
・vpopmailグループ
vchkpw
[setfwrd]
#!/bin/sh if [ -z $1 ]; then echo "please input your name." exit 1 fi if [ -z $2 ]; then echo "please input your domain." exit 1 fi if [ -z $3 ]; then echo "please specify the spool flag." exit 1 fi name=`echo $1 | tr '[A-Z]' '[a-z]'` domain=$2 is_spool=$3 flg=0 if [ -d /home/vpopmail/domains/$domain/$name ]; then flg=1 datapath=/home/vpopmail/domains/$domain/$name else count=0 count_max=20 while [ $count -le $count_max ]; do if [ -d /home/vpopmail/domains/$domain/$count/$name ]; then flg=1 datapath=/home/vpopmail/domains/$domain/$count/$name count=$count_max fi count=`expr $count + 1` done fi if [ $flg -eq 1 ]; then if [ -f $datapath/.qmail ]; then mv -f $datapath/.qmail $datapath/.qmail.bak fi touch $datapath/.qmail while [ "$4" != "" ]; do echo "&$4" >> $datapath/.qmail shift 1 done if [ $is_spool != "0" ]; then echo "$datapath/Maildir/" >> $datapath/.qmail fi chown vpopmail:vchkpw $datapath/.qmail else echo "specified account not found." fi
使い方は、
setfwrd [ユーザ名] [ドメイン名] [メールを残す=1 残さない=0] [転送先1] [転送先2] [転送先3]...
setfwrd taro.yamada foo.com 1 t.yamada@bar.com taro@hoge.com
みたいな感じです。