000000 ランダム
 ホーム | 日記 | プロフィール 【ログイン】

ふるた技工所(てっこうしょ)

PR

キーワードサーチ

▼キーワード検索

楽天プロフィール


Aちゃん22さん

キャッチフレーズは未入力です。

フォローする

フリーページ

2007.12.25
XML
カテゴリ:ソフト開発日誌
iSCSI Enterprise Target 0.4.15 を改造して Logical Unit (Drive) を Removable Media として Windows の initiator に見せる様にした。Data Salvager LE でサルベージができるようになった。ファイナルデータ フォトリカバリーでも物理ドライブスキャンができるようになる。iSCSI Target の実体がハードディスクの仮想ドライブでも、フロッピーの仮想ドライブでも、サルベージ対象になった。

クレバリーの不幸袋に入っていた物で少し幸せになった。

はじめ Removal Media として見せるため INQUIRY の応答で RMB (Removable flag) を 1 にするだけで良いのか少し悩んだ。Removable だと START STOP UNIT (STU), PREVENT ALLOW MEDIUM REMOVAL(PAMR) で Load/Unload, Eject Lock/Unlock が可能なドライブがある。よく考えてみると普通の USB メモリカードリーダーはこれができない。なので STU, PAMR はエラーのまま放置することにした。

iSCSI Enterprise Target のパッチを示す。一度コンパイルして Kernel Version に合わせたパッチを当てた後に修正する必要がある。

参考までに Vine Linux 4.1 Kernel 2.6.16-0vl76.3 に合わせて make したソースのスナップショットを用意した。元々が GPL ライセンスなので、同様のライセンスで扱ってほしい。

修正の詳細を以下に示す。

/etc/ietd.conf の仕様を変更し Removable=yes を付けることができるようにする。Removable Media の振りをするようになる。例えば次のように記述する。

[/etc/ietd.conf]
Target iqn.2007-11.blacky:virtualdrive
    Lun 0 Path=/vhd0/virtualdrive.vhdd,Removable=yes

この仕様に合わせたソース改造箇所を示していく。kernel ディレクトリ以下の修正だ。volume.c を修正して Removal=yes を解釈できるようにする。3 箇所修正箇所がある。
[volume.c part 1 of 3]
enum {
    Opt_type,
    Opt_iomode,
    Opt_removable,
    Opt_err,
};

[volume.c part 2 of 3]
static match_table_t tokens = {
    {Opt_type, "Type=%s"},
    {Opt_iomode, "IOMode=%s"},
    {Opt_removable, "Removable=%s"},
    {Opt_err, NULL},
};


[volume.c part 3 of 3]
        case Opt_iomode:
            if (!(argp = match_strdup(&args[0])))
                err = -ENOMEM;
            if (argp && !strcmp(argp, "ro"))
                SetLUReadonly(volume);
            else if (argp && !strcmp(argp, "wb"))
                SetLUAsync(volume);
            kfree(argp);
            break;
        case Opt_removable:
            if (!(argp = match_strdup(&args[0]))) {
                err = -ENOMEM;
            }
            if (argp && !strcmp(argp, "no")) {
                ClearLURemovable(volume);
            }
            else {
                if (argp && !strcmp(argp, "yes")) {
                    SetLURemovable(volume);
                }
            }
            kfree(argp);
            break;
        default:
            break;

block-io.c を修正して Removal=yes を読み飛ばすようにする。

[block-io.c]
/* Create a match table using our action enums and their matching options */
static match_table_t tokens = {
    {Opt_scsiid, "ScsiId=%s"},
    {Opt_scsisn, "ScsiSN=%s"},
    {Opt_path, "Path=%s"},
    {Opt_ignore, "Type=%s"},
    {Opt_ignore, "IOMode=%s"},
    {Opt_ignore, "Removable=%s"},
    {Opt_err, NULL},
};

file-io.c を修正して Removal=yes を読み飛ばすようにする。

[file-io.c]
static match_table_t tokens = {
    {Opt_scsiid, "ScsiId=%s"},
    {Opt_scsisn, "ScsiSN=%s"},
    {Opt_path, "Path=%s"},
    {Opt_ignore, "Type=%s"},
    {Opt_ignore, "IOMode=%s"},
    {Opt_ignore, "Removable=%s"},
    {Opt_err, NULL},
};

target_disk.c を修正して INQUIRY の応答の RMB ビットを Removable= 指定に合わせるようにする。

[target_disk.c]
    if (!(scb[1] & 0x3)) {
        /* standard response */
        if (LURemovable(cmnd->lun)) {
            data[1]=0x80;   /* RMB=1 */
        } else {
            data[1]=0x00;   /* RMB=0 */
        }
        data[2] = 4;

iscsi.h を修正して Removal=yes を指定されたことを記憶できるようにする。
ノート: ここの修正内容は Door Lock, Eject もサポートする様に書いてある。しかし、利用していない。

[iscsi.h]
enum lu_flags {
    LU_READONLY,
    LU_ASYNC,
    LU_REMOVABLE,   /* Removable media emulation, 0:Not removavle, 1: Removable */
    LU_EJECTED,     /* Ejected, 0:Not Ejected, 1:Ejected */
    LU_DOOR_LOCKED, /* Door locked, 0:Not Locked, 1:Locked */
};

#define LUReadonly(lu) test_bit(LU_READONLY, &(lu)->flags)
#define SetLUReadonly(lu) set_bit(LU_READONLY, &(lu)->flags)

#define LUAsync(lu) test_bit(LU_ASYNC, &(lu)->flags)
#define SetLUAsync(lu) set_bit(LU_ASYNC, &(lu)->flags)

#define LURemovable(lu)     test_bit(LU_REMOVABLE, &(lu)->flags)
#define SetLURemovable(lu)  set_bit(LU_REMOVABLE, &(lu)->flags)
#define ClearLURemovable(lu)    clear_bit(LU_REMOVABLE, &(lu)->flags)

#define LUEjected(lu)       test_bit(LU_EJECTED, &(lu)->flags)
#define SetLUEjected(lu)    set_bit(LU_EJECTED, &(lu)->flags)
#define ClearLUEjected(lu)  clear_bit(LU_EJECTED, &(lu)->flags)

#define LUDoorLocked(lu)    test_bit(LU_DOOR_LOCKED, &(lu)->flags)
#define SetLUDoorLocked(lu) set_bit(LU_DOOR_LOCKED, &(lu)->flags)
#define ClearLUDoorLocked(lu)   clear_bit(LU_DOOR_LOCKED, &(lu)->flags)


dmesg を見ると PREVENT ALLOW MEDIUM REMOVAL に対して、エラーを返している。しかし、メモリカードリーダーも、同様な振る舞いをするので問題ない。






最終更新日  2007.12.25 23:27:10
コメント(0) | コメントを書く

カレンダー

カテゴリ

サイド自由欄

コメント新着

ニューストピックス

Powered By 楽天ブログは国内最大級の無料ブログサービスです。楽天・Infoseekと連動した豊富なコンテンツや簡単アフィリエイト機能、フォトアルバムも使えます。デザインも豊富・簡単カスタマイズが可能!

Copyright (c) 1997-2017 Rakuten, Inc. All Rights Reserved.