YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

諸々ディストリビューションのバージョンを確認する

動機

修論に計算機環境を書かなければならなくなったため,ついでに諸々のOSでバージョン情報を調べる方法を調べてみたくなった.

方法

Cygwin

cygcheckコマンドで入っているパッケージとかの情報を見ることができます.

# cygcheck -c
Cygwin Package Information
Package              Version            Status
_update-info-dir     00575-1            OK
alternatives         1.3.29a-1          OK
ash                  20040127-3         OK
atk                  1.10.3-1           OK
(略)
ubuntu

lsb_releaseというコマンドを使うみたい.

# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 6.06.1 LTS
Release:        6.06
Codename:       dapper
Debian

Debianの場合は特にコマンドとかではなく,/etc/debian_versionというファイルに書いてある.

# less /etc/debian_version
4.0
FreeBSD

FreeBSDではもろにカーネルのバージョンと一致.

# uname -a
FreeBSD xxx.xxx.xxx.xxx 6.2-RELEASE FreeBSD 6.2-RELEASE #0: Fri Jan 12 11:05:30 UTC 2007
root@dessler.cse.buffalo.edu.:/usr/obj/usr/src/sys/SMP  i386
Solaris

unameで確認するか、/etc/releaseで確認するか。

# uname -sr
SunOS 5.10

# less /etc/release
AIX

Service Packが当たるベースとなっているバージョンの確認は下記。oslevelのオプションでもっと細かく確認できる。

# oslevel -q
Known Maintenance Levels
------------------------
6.1.0.0

参考

unameコマンド

ちなみに他のOSでunameコマンドを使うとカーネルバージョンを見ることが出来る.

  • Cygwin
# uname -a
CYGWIN_NT-5.1 xxxxx 1.5.25(0.156/4/2) 2007-12-14 19:21 i686 Cygwin
  • Debian
Linux xxxxx 2.4.27-3-386 #1 Wed Dec 6 00:38:33 UTC 2006 i686 GNU/Linux
/etc/xxx_versionファイル

各ディストリビューションでxxxの部分は異なるが,大体一緒.

# less /etc/debian_version
# less /etc/redhat-release
# less /etc/vine-release

こんな感じ.ちなみにubuntuはDebianベースだけど,バージョンファイルを見ると

# less /etc/debian_version
testing/unstable

となってます.

MICO CORBAでCOMM_FAILUREで落ちる

動機

昨日からCORBAのテストアプリケーションを動かしているが,localhostではうまくいくのに,サーバ/クライアントを別マシンにするとエラーが出て落ちる..

調査

下記のエラーが出て落ちる

uncaught MICO exception: IDL:omg.org/CORBA/COMM_FAILURE:1.0 (0, not-completed)

原因を見つけるために `netstat -c` で監視しつつ,例外メッセージを調べていたらなんとなく原因が分かってきた.どうもCORBAではリスナーポートにアクセスしてきた元のポートにそのままデータを返すみたい.これはJavaだけど,このような例外らしい.

netstat -cで確認をしたところ

Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 hoge:44532           hoge:5005            ESTABLISHED
tcp        0      0 hoge:5005            hoge:44532           ESTABLISHED
tcp        0      0 hoge:5005            fuga:3901              ESTABLISHED

この直後に3番目の通信が切れ,test_client.shが上記の例外を吐いて落ちる.おそらくclientがNameServerにたどり着いた後,NameServerがfugaの3901番ポートにアクセスしようとして,ポートの接続制限によって通信が切断されるためではないかと思われる.
ためしにNameServer, test_server, test_clientをすべてhoge上で行ったときは,

Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 localhost.localdo:42688 localhost.localdo:60095 ESTABLISHED
tcp        0      0 hoge:44724           hoge:5005            ESTABLISHED
tcp        0      0 localhost.localdo:60095 localhost.localdo:42688
ESTABLISHED
tcp        0      0 hoge:44725           hoge:5005            ESTABLISHED
tcp        0      0 hoge:5005            hoge:44725           ESTABLISHED
tcp        0      0 hoge:5005            hoge:44724           ESTABLISHED

hoge上の44724番ポートから5005番にアクセスしているのがserverで,44725番から5005番にアクセスしているのがclient.NameServerは5005番からserverとclient,両方のポートにアクセスできています.またlocalhost.localdo:42688と60095が何をしているのかがよくわからないけど,とりあえずポート周りであろうと分かった.

テストコード

test_server.idl
interface TestServer
{
    long display_message(in string msg);
    long get_message(out string msg);
    void destroy();
};

interface TestServerFactory
{
    TestServer create();
};
test_server_impl.h
class TestServer_impl
    : virtual public POA_TestServer
{
public:
    TestServer_impl();
    ~TestServer_impl();

    CORBA::Long display_message(const char* msg);
    CORBA::Long get_message(CORBA::String_out msg);
    void destroy();
};

class TestServerFactory_impl
    : virtual public POA_TestServerFactory
{
public:
    TestServerFactory_impl();
    ~TestServerFactory_impl();

    TestServer_ptr create();
};
test_server_impl.cc
#include "test_server_impl.h"

#include <iostream>
using namespace std;

TestServer_impl::TestServer_impl()
{
}

TestServer_impl::~TestServer_impl()
{
}

CORBA::Long TestServer_impl::display_message(const char* msg)
{
    cerr << msg << endl;
    return 0;
}

CORBA::Long TestServer_impl::get_message(CORBA::String_out msg)
{
    msg = CORBA::string_dup("I am TestServer");
    return 0;
}

void TestServer_impl::destroy()
{
    PortableServer::POA_var poa = _default_POA();
    PortableServer::ObjectId_var id = poa->servant_to_id(this);
    poa->deactivate_object(id);
}

TestServer_ptr TestServerFactory_impl::create()
{
    TestServer_impl* test = new TestServer_impl;
    TestServer_ptr tref = test->_this();
    if(CORBA::is_nil(tref))
    {
        cerr << "TestServerFactory: failed to create TestServer object" << endl;
    }
    return tref;
}

TestServerFactory_impl::TestServerFactory_impl()
{
}

TestServerFactory_impl::~TestServerFactory_impl()
{
    PortableServer::POA_var poa = _default_POA();
    PortableServer::ObjectId_var id = poa->servant_to_id(this);
    poa->deactivate_object(id);
}
test_client.cc
#include <coss/CosNaming.h>
#include <test_server.h>
#include <iostream>
using namespace std;

int main(int argc, char** argv)
{
    CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);

    /*
     * Acquire a reference to the Naming Service
     */
    CORBA::Object_var nsobj;
    CosNaming::NamingContext_var nc;
    try
    {
        nsobj = orb->resolve_initial_references ("NameService");
        nc = CosNaming::NamingContext::_narrow (nsobj);
    }
    catch(CORBA::Exception& ex)
    {
        cerr << "client: error at connecting to NameService" << endl;
        return 1;
    }
    if (CORBA::is_nil (nc))
    {
        cerr << "client: I cannot access the Naming Service!" << endl;
        return 1;
    }

    CosNaming::Name name;
    name.length (1);
    name[0].id = CORBA::string_dup ("TestServer");
    name[0].kind = CORBA::string_dup ("");

    /*
     * try to find that node in the Naming Service tree
     */
    CORBA::Object_var obj;
    try
    {
        obj = nc->resolve(name);
    }
    catch(CORBA::Exception& ex)
    {
        cerr << "client: cannot connect to TestServerFactory" << endl;
        return 1;
    }
    cerr << "client: connected to TestServerFactory" << endl;

    /*
     * The Naming Service returns a generic reference as a CORBA::Object
     * We need to narrow this to the desired type
     */
    cerr << "creating TestServerFactory object" << endl;
    TestServerFactory_var fact = TestServerFactory::_narrow (obj);

    TestServer_var test = fact->create();

    if (CORBA::is_nil(test))
    {
        cerr  << "client: cannot create TestServer" << endl;
        return 1;
    }

    test->display_message("Hello!");

    CORBA::String_var msg;
    test->get_message(msg);
    cout << (const char*)msg << endl;

    test->destroy();

    return 0;
}
起動時の各オプション
# nsd -ORBIIOPAddr inet:hoge:5005
# ./server.exe -ORBInitRef NameService=corbaloc::hoge:5005/NameServer
# ./client.exe -ORBInitRef NameService=corbaloc::hoge:5005/NameServer
テスト動作(成功時)
  • server側
# ./server.exe -ORBInitRef NameService=corbaloc::hoge:5005/NameServer
TestServer: binding in the Naming Service ... done.
TestServer: ready
Hello!
  • client側
# ./client.exe -ORBInitRef NameService=corbaloc::hoge:5005/NameServer
client: connected to TestServerFactory
I am TestServer
テスト動作(エラー時)
  • client側
# ./client.exe -ORBInitRef NameService=corbaloc::hoge:5005/NameServer
client: connected to TestServerFactory
creating TestServerFactory object
uncaught MICO exception: IDL:omg.org/CORBA/COMM_FAILURE:1.0 (0, not-completed)

まとめ

クライアントの使用ポートを指定する方法はないのかなぁ?それができればポートの開放とかも楽になるんだけど.是非ご教授願いたい.