Tips & Technique for Solaris

【コマンド】

システム関連の情報を表示するコマンド

 prtconf  メモリサイズ、ハードウエアの構成、システム設定を表示
 sysdef  swapの場所やサイズ、カーネル変数、カーネルの設定を表示
 psrinfo  MPシステムでアクティブなプロセッサ数を表示
 prtdiag  システムの diagnostic information の表示
 snoop  IP packetを調べる

 

【/etc/system ファイルを編集する】

/etc/system の設定をおかしくしてしまい、ブートできなくなった時の対処方法

以降で /etc/system ファイルを変更するにあたり、まず、これを覚えておくことは重要。
boot -as でブートして下さい。 カーネルはシステム・ファイルの名前を含むいろいろな種類の質問をしてきます。 どのシステムファイルを使用するか訪ねられた際に、以前の /etc/system ファイル(バックアップを取ってある場合)を使用するか、/dev/null を指定してください。

 

プロセスごとのファイル・ディスクリプタ数を設定する方法

    * set hard limit on file descriptors (デフォルトは 1024)
    set rlim_fd_max = 4096
    * set soft limit on file descriptors (デフォルトは 64)
    set rlim_fd_cur = 1024

上記の設定を /etc/system ファイルに記述することで、ディスクプリタの数を設定することができます。でも、Solaris 2.4 以降です。それ以前のバージョンはカーネルをいじる必要がある。

注意しなくてはならないのは、ソフト・リミットを 256 より大きく設定した場合、BCP(Binary Compatibility) なアプリケーションの動作保証がない。 リミットを 1024 より大きく設定した場合、 select() を使用しているアプリケーションの動作保証がされないということです。 Solaris7(64bit)では、最大65536まで拡張されました。

 

イーサネットアダプタを全2重に設定する方法

Sun の hme ファースト・イ−サネット・アダプタを使用している場合、 全2重イ−サネットを設定することができます。 出荷時の初期設定は、デフォルトでは有効になっていません。

デフォルトの設定を変更し、全2重モードにするには何通りかの方法があります(スイッチの設定も同様に変更する必要があります)。

/etc/system で設定する場合:

    set hme:hme_adv_autoneg_cap=0
    set hme:hme_adv_100hdx_cap=0
    set hme:hme_adv_100fdx_cap=1

ndd で設定する場合:

    ndd -set /dev/hme adv_autoneg_cap 0
    ndd -set /dev/hme adv_100hdx_cap 0
    ndd -set /dev/hme adv_100fdx_cap 1

 

System V IPC を OS ブート時にロードする方法

OS ブート時にいつも ipcs が「組み込まれていない」というような以下のようなメッセージを出力します。

 IPC status from <running system> as of <date>
 Message Queue facility not in system.
 Shared Memory facility not in system.
 Semaphore facility not in system. 

これは、Message Queue/Shared Memory または、Semaphore をまだ使用 していないことを意味します。 それらは、最初に使用された時に初めてロードされます。これを、ブート時にロードしたい場合は /etc/system に以下を追加します。

    forceload: sys/msgsys
    forceload: sys/semsys
    forceload: sys/shmsys 
 

System V IPC のパラメータを変更する方法

次のパラメータを使用することで、セマフォの数、共有メモリの量、 IPC メッセージの数を変更することができます。 これらは、/etc/system ファイルで設定します。 IPC設定のデフォルト値を sysdef コマンドを利用することで確認できます。
    set semsys:seminfo_semusz = <value>
    set semsys:seminfo_semopm = <value>
    set semsys:seminfo_semume = <value>
    set semsys:seminfo_semaem = <value>
    set semsys:seminfo_semmap = <value>
    set semsys:seminfo_semvmx = <value>
    set semsys:seminfo_semmsl = <value>
    set semsys:seminfo_semmni = <value>
    set semsys:seminfo_semmns = <value>
    set semsys:seminfo_semmnu = <value>
 
    set shmsys:shminfo_shmmax = <value>
    set shmsys:shminfo_shmmin = <value>
    set shmsys:shminfo_shmmni = <value>
    set shmsys:shminfo_shmseg = <value>
 
    set msgsys:msginfo_msgseg = <value>
    set msgsys:msginfo_msgssz = <value>
    set msgsys:msginfo_msgtql = <value>
    set msgsys:msginfo_msgmap = <value>
    set msgsys:msginfo_msgmax = <value>
    set msgsys:msginfo_msgmnb = <value>
    set msgsys:msginfo_msgmni = <value>
共有メモリについては ORACLE などを利用する際に設定が必要になるかな....
 
デフォルト
最小
最大
詳細
shmmax 1048576 1 4294967295 (4 GB) unsigned int Maximum size for a shared segment
shmmin 1 1 4294967295 (4 GB) unsigned int Minimum size for a shared segment
shmmni 100 1 2147483648 (2 GB) signed int Max number shared memory identifiers
shmseg 6 1 32767 (32 k) short Max number shared segments per process
最大値 4GBは Solaris 2.5.1 以降、それ以前の OS は 2GB。value は、以下のように 10進でも 16進でも設定できる。
    set shmsys:shminfo_shmmax=0xffffffff    /* hexidecimal */
    set shmsys:shminfo_shmmax=4294967295    /* decimal     */

 

ユーザあたりのプロセス数を設定する方法

/etc/system に以下を記述します。しかし、通常 maxprc は maxusers 変数とかかわりがあります。
    set maxuprc = <num>  

 

maxusers 変数の意味

maxusers 変数は、システム上で許されるユーザ数を制限するものではありません。この変数は、他のパラメータを同時にスケールするためのものです。この仕組みは、昔のカーネル・コンフィグレーションで利用しているものと同じ設定方法を採用しています。
    * The big knob, scales automatically
    set maxusers = < amount of available physical memory in MB >
 
    * Maximum number of allowable processes; currently at most 30000
    set max_nprocs = 10 + 16 * maxusers 
 
    * Max processes per user (5 are reserved for the super user) 
    set maxuprc = max_nprocs - 5
 
    * Number of quota structures (need one per user per filesystem w/ quotas)
    set ndquot = maxusers * NMOUNT / 4 + max_nprocs
 
    * Maximum size of the directory name lookup cache (DNLC)
    set ncsize = 4 * (max_nprocs + maxusers) + 320
    set ufs_ninode = ncsize 

 

48 以上のpesudo tty を設定する方法

/etc/system に以下の行を追加してください:
    * System V pseudo terminals
    set pt_cnt = <num>
設定後、システムを halt し、boot -r でデバイスを再設定させるオプションを指定してブートします。
一応、好きな数だけ設定することができるようですが、 他の部分で制限を受けることになるようです。(何処まで設定で来るのかやっていないので限界はわかりません)

BSD スタイル の pty も同様に増やすことができるようですが面倒なのでここには書きません。マニュアルでも調べて下さい(変数は npty を使い、さらに /etc/iu.ap を編集するとか...)。

 

バッファオーバーフロー攻撃を保護する方法

/etc/system に以下の行を追加してください:
    set noexec_user_stack=1
    set noexec_user_stack_log=1

「典型的なバッファオーバーフロー」は、リターンアドレスを上書きし、次に特定のコードをポイントするように作られており、 関数からからの次のリターンがクラッカーのコードにジャンプします。

noexec_user_stack を利用することで、実行されるコードはスタック上に残り、 OSはそのコードが実行されることを許可しません。

多くのスタックオーバーフローには有効だが、ヒープオーバーフローなどについては有効になりません。また、sun4u/sun4d/sun4m である SPARCシステムでしか利用できません。

 

【いろいろな設定ファイル】

ホストネームを変更する方法

いろいろファイルをいじってホスト名を変更する方法がありますが、最も安全な方法は sys-unconfig コマンドを利用することです。このコマンドは、システムの多くの設定(特にネットワークの設定)を初期化します。
    # /usr/sbin/sys-unconfig
このコマンドを実行後、システムがリブートしホストネームや 他のネットワークのパラメータを再設定できるようになります。

設定処理によって /etc/nsswitch.conf は上書きされてしまうので、 前もってコピーしておいた方がよいかもしれません。

sys-unconfig はディスクレスや、 データレスなワークステーションではサポートされていません。 それらの場合、手作業でファイルを編集する必要があります。 変更が必要なファイルのリストは、sys-unconfig(1M) を参照してください。

 

デバイスの追加方法。 /dev/MAKEDEV は BSD系の OS のコマンド...

デバイス・ドライバは動的にリンクされているので、 新しいデバイスを追加するには単にシステムをシャットダウンし、 /devices と /dev ディレクトリを再構成するための -r オプションをつけてブートすれば良いだけです。

   ok? boot -r
デフォルトのディスクでない場合、ドライブも指定する

または、/reconfigure というファイルを作成してリブートすることでデバイスを再構成します。

   # touch /reconfigure
   # init 6

SCSI ディスクを追加するだけの場合、リブートする必要はありません。 (root で)以下のスクリプトを走らせて下さい:

    #!/bin/sh
    #
    # add-disk
    #
    # Runs the commands to make Solaris locate a new disk that
    # has been plugged in after the system was booted.
    #
 
    /usr/sbin/drvconfig
    /usr/sbin/devlinks
    /usr/sbin/disks      # テープの場合 /usr/sbin/tapes
    /usr/ucb/ucblinks    # 互換リンク
 
    exit 0

これは、システムに少なくとも SCSI ディスクが 1 つは存在しないと機能しないので 注意して下さい。 (なぜなら、このスクリプトは単にシボリック・リンクをするだけで、 SCSI のドライバ・カーネル・モジュール等をロードするわけではないから)

 

/etc/rc と /etc/rc.local しか知らない BSD系 UNIXユーザーの為に

BSD 系の UNIXで /etc/rc, /etc/rc.local で設定されていた項目は、たくさんのファイルに細かく分割されました。 また、「ラン・レベル」と呼ばれる実行レベルがあり、そのランレベルによって使用する rc スクリプトが異なります。

【ランレベル(init コマンドでランレベルが変更できます)】

    init S    シングルユーザーモード
    init 0    PROMモード(SVR4では電源切断状態)
    init 1    カーネルシングルユーザーモード(/, /usr のみマウント)
    init 2    マルチユーザーモード
    init 3    マルチユーザーモード + NFS, RFS
    init 4    予備のマルチユーザーモード
    init 5    電源切断(SVR4ではファームウェア状態)
    init 6    リブート

【ランレベルと rcスクリプト】

    /etc/inittab - どのプログラムをいつ起動するかを定義
    /sbin/init.d ------------ スクリプトが分りやすいファイル名で保存されている
    /sbin/rcS, /etc/rcS.d/* - ランレベルS
    /sbin/rc0, /etc/rc0.d/* - ランレベル0
    /sbin/rc1, /etc/rc1.d/* - ランレベル1
    /sbin/rc2, /etc/rc2.d/* - ランレベル2
    /sbin/rc3, /etc/rc3.d/* - ランレベル3

【inittabファイル】

<id>:<rstate>:<action>:<process>

フィールド 内容
id エントリを識別するための1文字、ないしは2文字のユニークな文字列を指定 文字のユニークな文字列ap, fs, s0
rstate エントリを実行するrun levelを指定 level「S,2,3」で実行する場合、「S23」と記述
action エントリの挙動(ふるまい)を指定 下記の表を参照
process エントリで実行されるプロセスを指定 /sbin/rc3

actionで指定されているもの
オプション 処理内容
initdefault initが最初に起動された時に実行
sysinit initの起動後,特定のrun levelに移行する前に実行
respawn プロセスが実行されていなければ実行
wait 該当するrun levelに入ったらprocessを実行してその終了を待つ
powerfail initがSIGPWRシグナルを受けた時に実行

/etc/rc*.d/* のすべてのファイルは /etc/init.d(わかりやすいファイル名) に含まれるスクリプトからハードリンクされています。

/etc/rc?.d ディレクトリの中のスクリプトを実行する際、 K* スクリプトが最初に実行され、次に S* スクリプトが実行されます。この K はスクリプトに stop を引数として渡し、S はスクリプトに start を引数として渡します。つまり、K で始まるサービスを停止し、S で始まるサービスを起動します。SやKの後の数字はスクリプトを実行する順番です。スクリプトを無効にしたい場合、削除するか S,K 以外で始まる名前にしておくとよい。

基本的な起動スクリプトは以下のような構造になっています:

    #!/bin/sh
    # init.d のスクリプトの例
    # /etc/init.d/your-daemon下にスクリプトのコピーをインストールしてください。
    # /etc/rc2.d/Sxxyour-daemon(又は rc3.d)と
    # /etc/rc[01].d/Kxxyour-daemon へリンクして下さい。
    # .sh で終わるスクリプトは sh の "." コマンドで実行されます。
    # .sh で終わらないスクリプトは "sh script" として実行されます。
    case "$1" in
        start)
            #... commands to start daemon ....
            <デーモン起動のための処理を記述>
            ;;
        stop)
            #... commands to stop daemon ....
            <デーモン停止のための処理を記述>
            ;;
    esac 

 

root で rlogin/telnetを利用する方法(セキュリティーがあまくなるのでお勧めしない)

よく、root でリモートログインやテルネットしようとすると "Not on system console.....Connection closed." と表示されます。これは、セキュリティー強化の関係で、コンソール端末以外から root によるログインをできないようになっているからです。同様に、hosts.equivに '+'の記述もありません。 ネットワークからの root のログインを許可するためには、 /etc/default/login ファイルの CONSOLE= 行を変更する必要があります。

/etc/default/login ファイルの CONSOLE エントリーは以下のように使用されます。

    CONSOLE=/dev/console(デフォルト)  # root のログインは直接コンソールからのみ
    CONSOLE=/dev/ttya                   # root のログインは直接 /dev/ttya からのみ
    CONSOLE= -                          # どの端末からも直接の root のログインは許可されない
    #CONSOLE(または行の削除)          # すべての端末から root のログインが許可される

 

DNS や NIS を利用する時に設定が必要な nsswitch.conf ファイル

passwd, group, hosts, services, netgroup等といったサービスを、NIS(YP)、NIS+、/etc にあるファイル、DNS("hosts" のみ)のどれから読みとるかを制御することができます。

例えば以下のような場合:

    hosts: dns [NOTFOUND=return] files

これは、まず DNS にホスト情報を問い合わせ、 もし欲しい情報が見つからなかった場合、フォールバックとしてローカルマシンのホスト・テーブル(/etc/hosts)を調べるということを意味します。

また、[NOTFOUND=return] は DNS の問い合わせに対して "Not Found" を返してきた場合 /etc 以下のファイルを見ることなく戻ることを意味しています。 (つまりホストが見つからないものとして処理する)

 

インターフェイス毎に複数のアドレスを持たせる方法

ifconfig コマンドを使用して、 インターフェイス毎に1つ以上の IP アドレスを割り振ることができます。

    ifconfig IF:N ip-address up

"IF" はインターフェイス(例えば、le0)で、 Solaris 2.5 までは "N" は 1 から 255の間の数字、それ以降のバージョンは ndd コマンドによって値を設定でき 8192まで増やせます。 (adb でさらに増やすことは可能です)

    /usr/sbin/ndd -set /dev/ip ip_addrs_per_if 4000

割り当てた IPアドレスは、 "ifconfig IF:N 0.0.0.0 down" で無効にできます。
ホスト名の関連付け等の関係で /etc/hostname.IF:X ファイルを作成する必要があります。

 

IP Forwarding を止める

デュアルホーム・ゲートウェイを Solaris で構築したいような時、IP Forwardingを止める必要がでてきます。その設定方法は、/etc/notrouter という空ファイルを作成することで実現できます。これは、/etc/init.d/inetinit を覗いてみると実際に何をしているか確認できます。

    # touch /etc/notrouter

/etc/init.d/inetinit を覗くと ndd コマンドを利用して ip_forwarding の値に 0 をセットしていることが確認できます。

    /usr/sbin/ndd -set /dev/ip ip_forwarding 0
    /usr/sbin/ndd -set /dev/ip ip_forward_src_routed 0
    /usr/sbin/ndd -set /dev/ip ip_forward_directedbroadcasts 0 

ip_forwading の値

2(デフォルト) ネットワークインターフェースを二つ以上持つ場合転送を行う
1 常にデータグラムの転送を行う
0 データグラム転送を行わない

 

TCP 関連のチューニングを行なう

Solaris を、Web アプリケーションサーバーとして使用する場合、幾つかチューニングを行なうことでパフォーマンスを向上させることが出来ます。

ストリームドライバのキューサイズと TCP に対するハッシュサイズを制御します。0 に設定すると無限になるので、パフォーマンスはバッファの容量不足による影響を受けなくなります。(安全値の目安は、64MのRAMなら25、128Mなら50ぐらい)/etc/system ファイルに記述します。

    set sq_max_size = 0                 (デフォルトは 2)
    set tcp:tcp_conn_hash_size = 262144   (デフォルトは 256)

TCPスタックに関するパラメータを ndd コマンドで設定します。/etc/init.d/inetinit に記述しておくことでシステム起動時に設定されます。(Solaris のバージョンによってはパッチが必要です)

    ndd -set /dev/tcp tcp_close_wait_interval       60000   (240000)
    ndd -set /dev/tcp tcp_time_wait_interval        60000   (240000)
    ndd -set /dev/tcp tcp_mss_max                   6000
    ndd -set /dev/tcp tcp_fin_wait_2_flush_interval 16000
    ndd -set /dev/ip  ip_path_mtu_discovery         0
    ndd -set /dev/tcp tcp_conn_req_max_q            1024    (128)
    ndd -set /dev/tcp tcp_conn_req_max_q0           4096    (1024)
    ndd -set /dev/tcp tcp_conn_req_min              1
    ndd -set /dev/tcp tcp_xmit_hiwat                65535   (送信バッファ:8129)
    ndd -set /dev/tcp tcp_recv_hiwat                65535   (受信バッファ:8129)
    ndd -set /dev/tcp tcp_cwnd_max                  65534
    ndd -set /dev/tcp tcp_keepalive_interval        90000   (負荷が大きい場合小さく:720000)
    ndd -set /dev/tcp tcp_ip_abort_interval         60000   (480000)
    ndd -set /dev/tcp tcp_ip_abort_cinterval        60000   (480000)
    ndd -set /dev/tcp tcp_rexmit_interval_initial   3000    (再転送率が 30-40% を超える場合大きく:3000)
    ndd -set /dev/tcp tcp_rexmit_interval_min       3000    (200)
    ndd -set /dev/tcp tcp_rexmit_interval_max       10000   (240000)
    ndd -set /dev/tcp tcp_smallest_anon_port        1024    (32768)
    ndd -set /dev/tcp tcp_conn_grace_period         500
    ndd -set /dev/ip  ip_ignore_redirect            1
    ndd -set /dev/tcp tcp_slow_start_initial        2       (Solaris 2.5, 2.6の場合)

 

【その他】

dtlogin を有効/無効にする方法

/usr/dt/bin/dtconfig コマンドを使用して設定できます。
    /usr/dt/bin/dtconfig -d         (オートスタートを無効にする)
    /usr/dt/bin/dtconfig -e         (オートスタートを有効にする)
    /usr/dt/bin/dtconfig -kill      (dtlogin を終了させる)
    /usr/dt/bin/dtconfig -reset     (dtlogin をリスタートさせる)
    /usr/dt/bin/dtconfig -p         (printer action update)
    /usr/dt/bin/dtconfig -inetd     (inetd.conf /usr/dt daemons)
    /usr/dt/bin/dtconfig -inetd.ow  (inetd.conf /usr/openwin daemons)

 

NFS サーバーの設定

NFS 関連 daemon が動作している必要があります。通常、 Run-level 3 (rc3.d)で daemon が動作するよう設定されています。ただし、設定ファイルである /etc/dfs/dfstab 内容によっては NFSサーバー が起動されない場合があります。
共有させたいディレクトリの公開は、share コマンドを使用して行います。 share は以下のように使用し、同じ内容を /etc/dfs/dfstab ファイルに記述することで、 システムがブートする時に有効になります。

    # share -F nfs -o [ro|rw|root|...] -d "comment" dir

主に良く利用されるオプションは、 ro, rw(省略値), root=host などです。hostを複数指定する場合、コロン(:)を使用して区切ります。 例えば、/usr/local を公開し、host1と host2 のスーパーユーザーがディスクをアクセスした場合、nobody としてではなく root として扱われるように設定する場合:

    # share -F nfs -o root=host1:host2 -d "Free Soft" /usr/local/

shareコマンドを直接タイプせずに /etc/dfs/dfstab に記述した場合、記述後 shareall コマンドによりディレクトリーを公開できます。もし NFS サーバーが起動されていない場合、手動で NFS 関連デーモンを起動するかシステムをリーブートする必要があります。

    # /etc/init.d/nfs.server start
ちなみに、公開済みディレクトリを非公開にするには unshare/unshareall を使用します。

どんなディスクが公開されているか確認するには dfshares を使用する。

    # dfshares 
    RESOURCE                             SERVER ACCESS    TRANSPORT
    hostfs:/home                         hostfs  -         -
    hostfs:/proj                         hostfs  -         -
ディスクがどこからアクセスされているか確認すには dfmounts を使用する。
    # dfmounts
    RESOURCE     SERVER PATHNAME                  CLIENTS
      -          hostfs /home                    host1,host2,host3,host4,host5
      -          hostfs /proj                    host1,host5

クライアント側は、mount コマンドでマウントできます。たとえば、NFS サーバー nfshost がシェアしている /proj を自分の空ディレクトリー /mnt にマウントする場合以下のようになります。

    # mount -F nfs nfshost:/proj /mnt

このとき、キャッシュファイルしシステムを利用するとデータにアクセスする速度が増すため、ネットワークトラフィックの負荷が軽減されます。 100MBのキャッシュファイルしシステムを作成し、NFS マウントするには以下のように実行します。

    # cfsadmin -c -o maxfilesize=100 /projcache
    # mount -F cachefs -o backfstype=nfs,cachedir=/projcache nfshost:/proj /mnt

キャッシュファイルシステムの削除には、-d オプションを使用して削除します。

    # umount /mnt
    # cfsadmin -d /projcache

 

ディスクとデバイス名

Solarisには、/dev, /devices といったデバイスに関するディレクトリーが用意されています。/dev は今までの UNIX と同じような型式でデバイスファイルが存在します。/devices はバスの情報や場所、接続されているデバイス、デバイスのID などが、パスやファイルの名前で理解できるようになっています(そのお蔭で非常に長い)。

    ブロックデバイス        /dev/dsk/c0t3d0s0
    キャラクターデバイス    /dev/rdsk/c0t3d0s0

 
 c0  コントローラターゲット。コントローラが増えると c1, c2 と増える。
 t3  ターゲットで SCSI-ID と対応。 IDE(ATA) ディスクの場合、無し。
 d0  RAID ディスク等で使用する.....
 s0  スライス。パーティションと呼ばれていたもので a-h が 0-8 に 対応。
 昔のなごりなのかデフォルトで s2(c) はディスク全体として使用されている。

/dev は以前の UNIX との互換のためのリンクで存在している。実体は、以下の様に /devices に存在する。

    /devices/iommu@f,e0000000/sbus@f,e0001000/espdma@f,400000/esp@f,800000/sd@3,0:a 

 

スーパーブロックの修復

fsck を実行したときに BAD SUPER BLOCK... と表示されることがあります。この問題を解決するには、スーパーブロックを修復しなければなりません。その方法は以下の手順で行います。

  1. メッセージの確認
        # fsck -F ufs /dev/rdsk/c0t0d0s0
        BAD SUPER BLOCK ...
  2. 代替用のスーパーブロックを探す(newfs の -N オプションはバックアップ用スーパーブロックを表示するだけで、ファイルシステムの内容は変更しない)
        # newfs -N /dev/rdsk/c0t0d0s0
  3. ファイルシステムを修復する(代替ブロックとしてブロック番号32を利用)
        # fsck -F ufs -o b=32 /dev/rdsk/c0t0d0s0

 

今はどっち? 32/64 bit

Solaris 7 以降、64 bit 対応になりました。そこで、どのモードが利用できるのか知る方法が必要になりました。それは、以下の方法で知る事が出来ます。

  1. isainfo コマンドを利用する
      【64 bit の場合】
        # isainfo -v    実行可能なアプリケーション
        64-bit sparcv9 applications
        32-bit sparc applications
        # isainfo -b    アドレス空間のビット幅
        64
        # isainfo -n    ネイティブな命令セット
        sparcv9
     
      【32 bit の場合】
        # isainfo -v
        32-bit sparc applications
  2. OS ブート時のメッセージ
      【64 bit の場合】
       SunOS Release 5.7 Version Generic 64-bit [UNIX(R) System V Release 4.0]
        
      【32 bit の場合】
       SunOS Release 5.7 Version Generic [UNIX(R) System V Release 4.0]
  3. おまけ:32 ビット と 64 ビット のデータタイプ
       ------------------------------------------
    Data Type ILP32 LP64
    ------------------------------------------
    char 8 8
    short 16 16
    int 32 32
    long 32 64
    long logn 64 64
    pointers 32 64
    enum 32 32
    float 32 32
    double 64 64
    long double 128 128
    ------------------------------------------

ダイナミックリンク

コマンドやアプリケーションが、どんなライブラリをダイナミックリンクしているのか調べるには ldd コマンドを利用します。 ダイナミックライブラリに対しても調べることが出来ます。 スタティックリンクされたアプリケーションは、シェアードライブラリーを使用していないといったメッセージが表示されます。

    # ldd /bin/sh
        libc.so.1 =>     /usr/lib/libc.so.1
        libdl.so.1 =>    /usr/lib/libdl.so.1
    #
    # ldd /usr/lib/libsocket.so.1
        libnsl.so.1 =>   /usr/lib/libnsl.so.1
        libc.so.1 =>     /usr/lib/libc.so.1
        libdl.so.1 =>    /usr/lib/libdl.so.1
        libmp.so.2 =>    /usr/lib/libmp.so.2
    #
    # ldd /sbin/sh
    ldd: /sbin/sh: file is not a dynamic executable or shared object

ダイナミックライブラリが見つからない場合、以下のように表示されます。

    # ldd a.out
        libX11.so.6.1 => (not found)
        libc.so.1 =>     /usr/lib/libc.so.1
        libdl.so.1 =>    /usr/lib/libdl.so.1

これは、LD_LIBRARY_PATH や LD_LIBRARY_PATH_64 変数をきちんと設定(ライブラリーの含まれるパスをセットする)することで解決することが出来ます。

Solaris 8 からは、Linux の ld.conf のような機能があります。直接ファイルを編集するのではなく、crle コマンドを利用します。新規登録の場合、以下のように設定ファイル(/var/ld/ld.config)を指定して基本的なライブラリーのパスを -l オプションで指定し登録します。

    # crle -c /var/ld/ld.config -l /usr/lib

ここで、/usr/lib を入れ忘れるとダイナミックライブラリを使用しているコマンド(ls, more, などほとんどすべて)が利用できなくなります。しかし、crle コマンドは利用できるので慌てずに /usr/lib を追加します。

別のパスを追加するには、-u オプションを使用します。

    # crle -u -l /usr/local/lib
上記の二つの操作でそれぞれのコマンドは、/usr/lib, /usr/local/lib に含まれるダイナミックライブラリーを参照します。上記の操作を一度で行うには以下のように実行します。
    # crle -c /var/ld/ld.config -l /usr/lib:/usr/local/lib

パッケージの追加や削除

Solaris のアプリケーションは、System V のパッケージ形式で提供されることがあります。

    pkginfo <pkg>                 - インストールされているパッケージの一覧を表示します。
    pkgadd -d /<path> <pkg ...>   - パッケージを追加します。
    pkgrm <pkg ...>               - インストールされているパッケージを削除します。
    pkgchk -q <pkg>               - パッケージが存在するかチェックします。
    pkgchk <options> [pkg]        - インストールされたパッケージの整合性をチェックします。

 

ジャーナリングファイルシステムの利用

Solaris 7 からジャーナリングファイルシステムが標準装備されました。(バグがあるものがあるのでシステムのパッチはチェックしてね)
この機能は、トランザクション (ファイルの変更など) をログ領域に格納してから、非同期でファイルシステムに適用します。この機能は「ロギング」と呼ばれ、ファイルシステムの操作やシステムのブートを高速化する働きがあります。また、ファイルシステムが矛盾する可能性がなくなるため、(まったくではないが)fsckを実行する必要がなくなります。このロギングにより、システムがクラッシュしたり異常停止した場合でも、ファイルシステムの修復が簡単かつ安全に行われ、システムをリブートする時間が短縮されます。

ロギングを有効にするには、mount コマンドのオプション logging によって有効にすることができます。

コマンドラインで有効にする場合(/mnt1 パーティションで logging を有効にする場合)
    # umount /mnt1
    # mount -o logging /mnt1
 
 /etc/vfstab ファイルに記述する場合
    修正前    /dev/dsk/c0t0d0s3 /dev/rdsk/c0t0d0s3 /usr ufs 1 no -
    修正後    /dev/dsk/c0t0d0s3 /dev/rdsk/c0t0d0s3 /usr ufs 1 no logging

ついでですが、ファイルシステムの高速化といえば、通常 UFS では、ファイルにアクセスすると、そのアクセスした時間が記録されます。しかし、前回アクセスした時刻を確認する必要がなければ、大きなオーバーヘッドをかけてまでアクセス情報を維持する必要がありません。 (たとえば、アクセス時間が重要でないにもかかわらず頻繁にアクセスされる Usenet ニューススプールや Web サーバーのコンテンツ などを含むファイルシステム)
そこで、オーバーヘッドを軽減するためにファイルに対するアクセス時間更新を無視させます。これは、UFS ファイルシステムをマウントするときに、-o noatime オプションを指定することで実現できます。

ファイルのアクセス時間は、ls コマンドの -u オプションで確認できます。(# はプロンプト)

    # ls -lu
total 20
-rw-r--r-- 1 moto staff 2906 Apr 8 10:55 truerand.c
-rw-rw-r-- 1 moto staff 26 Apr 8 11:49 truerand.h
-rw-r--r-- 1 moto staff 5145 Apr 8 10:52 truerand2.c
#
# more truerand.h
unsigned long truerand();
#
# ls -lu
total 20
-rw-r--r-- 1 moto staff 2906 Apr 8 10:55 truerand.c
-rw-rw-r-- 1 moto staff 26 Apr 23 16:49 truerand.h
-rw-r--r-- 1 moto staff 5145 Apr 8 10:52 truerand2.c
#

 

ちょっと番外編

HP-UX で利用される.depot ってなに?

HP-UX では、よく .depot という拡張子のついたファイルがあります。これは、System V のパッケージと同じようなものでアプリケーションを提供する際に利用されます。 swinstall コマンドを利用してアプリケーションをインストールします。

    /usr/sbin/swinstall -s /<full-path>/<depot-file>.depot '*'

 

 

 

 

 

Copyright (C) 2000 Shin Motomiya, All Rights Reserved.