カテゴリー別アーカイブ: Debian

uim 1:1.8.6+gh20161003.0.d63dadd-6

unstableのuimを更新しました。以下の2つのRC bugを修正してあります。

前者の問題は、いくつかのパッケージ統合作業を行った時に、libuim-devのドキュメントをsymlinkに変えたことがトリガで発生した問題です。postinstで以下の処理を追加しました。これにより、symlinkが必要に応じて生成されます。

dpkg-maintscript-helper dir_to_symlink \
                /usr/share/doc/libuim-dev /usr/share/doc/libuim8 1:1.8.6+gh20161003.0.d63dadd-2.1 -- "$@"

後者の問題は 、uimバイナリパッケージに/var/lib/uimのみを所属させていたのがトリガです。パッケージ統合作業の時にlibuim-dataを廃止したのですが、このパッケージのpostrmではpurge時に”rmdir –ignore-fail-on-non-empty”を呼び出して/var/lib/uimを削除しようとします。uimパッケージに所属しているのはディレクトリのみなので、ここで削除されてしまうというわけです。

こちらの対処としては、/var/lib/uim/READMEを用意してディレクトリを空にしないという方向で解決しました。同様の処置をしているパッケージは他にもあるので、対処としては間違ってないと思います。多分。

pdnsdからdnsmasqに移行

最近自宅の光回線が非常に遅い状況だったので、改善を試みました。そのついでに、ローカルのキャッシュDNSサーバーをpdnsdからdnsmasqに変更しました。

単にIPoEでnative IPv6を導入し、DS-Liteの設定をしただけなのですが、ローカルのDNSキャッシュサーバーのフォワード先をIPv6にしたかったのです。それでいてなおかつ、/etc/hostsの内容もみてくれるものを、ということでdnsmasqにしました。

apt-getでパッケージを入れて、/etc/dnsmasq.d/local.confというファイルを新規作成して、内容を以下のようにしました。

resolv-file=/etc/dnsmasq.resolv.conf
listen-address=192.168.xxx,y,127.0.0.1

localhostとローカル側のIPでlistenするようにし、フォワード先の設定が書かれたファイルを記述しているだけです。

自分が使っているISPはv4のDNSキャッシュサーバーだとAAAAフィルタがかかっているので、それをv6に変えたことでnative v6も扱えるようになりました。

一点注意が必要だったのは、apt-get install dnsmasqだけしても他のdnsサーバーパッケージはremoveされないというところです。おかげでport 53を他のサーバーが掴んだままでdnsmasqが起動できない、という状態に陥りました。

一応今はPPPoEも併用して、IPv4側のglobal addressから接続できる状態を意地できるよう、ポリシールーティングを設定しています。DS-Liteだけだとv4で繋げるすべがないので…

DS-Liteのおかげで、通信速度は17Mbps前後だったものが70Mbps程度でるようになりました。

Mini Debian Conference Japan 2016参加

2016/12/10に開催されたMini Debian Conference Japan 2016に参加してきました。場所は日本橋のサイボウズオフィス内で、LibreOffice Kaigi 2016と同時開催でした。自分も一応両方に参加するつもりで申し込みも両方にしたのですが、結果としてDebian側の話ばかり聞いていました。

その時の様子はハッシュタグ#debianjpでツイッターを検索するとある程度様子が伺えると思います。自分が参加しているセッションについてはある程度ツイートしています。せっかくなのでMomentsを使ってみようかと思ったのですが、全部のツイートが出てこない上に時系列に並んでいない、並び替えはすべて手動という使い勝手の悪いインターフェースで断念しました。

個人的には音響モデルを含めて自由ソフトウェア実装として作ったバーチャルシンガー徵音梅林(ちおんメイリン)に最もインパクトを受けました。発表は台湾の張正一(Chou Shouichi)さんでした。

発表資料の中でも触れられていましたが、クリプトン・フィーチャーの商用ソフトウェアであるVOCALOIDは作成できる内容に制限があります。初音ミクのEULA(PDF)にありますが、公序良俗に反するなどの歌詞を含めることを禁止しています。現実にはそういった内容のものが作成、公開されているのですが、規約レベルではアウトです。張さんは、ギターを燃やすパフォーマンスの写真などを交えて「音楽活動は自由であるべきだ」と主張されていました。これには強く同意します。

ソフトウェアのベースはWORLD(修正BSDライセンス)というパテントフリーなものを使っているとのことでした。音響モデルもマスコットキャラクターもCC-BY 3.0で配布しています。

残念ながら、まだフロントエンドについては実装がこなれていないようです。デモではWineでVOCALOIDのエディタを利用されていました。まだ日本で利用している例はほとんどなさそうですが、頑張って欲しいと思います。

2016年9〜10月の活動

ここ2ヶ月ぐらいの活動を記録しておきます。

Debian関係

  • Namazuのbuild-arch/build-arch-indep対応
  • ChaSen symbolsの主要arch対応
    • qemu-debootstrapの利用
    • porterboxの利用

ChaSenに関しては前回の投稿とも関係があるのですが、とりあえずは主要(公式リリース)アーキテクチャのみ、一通りlibchasen2.symbolsの更新を行いました。

恥ずかしながら今回はじめてporterboxを使いました。これまでporterboxにログインしたことはあっても結局使い方がよくわからなくて諦めたりしていたのですが、たまたまログインしたホストのmotd(ログイン時に表示されるメッセージ)にschrootの使い方へのリンクhttps://dsa.debian.org/doc/schroot/が掲載されていて、それではじめて使い方を理解した次第です。

しかし、qemu-debootstrapでどうにかなる範囲についてはそちらで対応しました。

第12回 カーネル/VM探検隊参加

qemu-debootstrapについてそれなりに理解を深めたので、その紹介という形で発表をしてきました。

 

Qiitaへの投稿

写経に関する記事のストック数が多いのが以外です。

FSIJ月例会(予定)

今月10月の28日に、いつもの場所(東京体育館)、いつもの時間(18:30〜19:30)で勉強会が開催予定です。

GnuPG 2.1のお話だそうで、期待できます。今の時点でのDebian stable(8.x/Jessie)ではまだ標準のGnuPGが1.4系なのですが、次のリリースには2.1が標準になる予定なので、大いに参考になることでしょう。

C++ template instanceのシンボルを隠す

ここ数日、C++がらみで苦労しています。自分がC++を覚えたのが学生の頃、20年以上前になるので、今時のC++についていけていません。

ChaSenのライブラリをビルドしていると、基本的にABIとしてはC言語の範囲でしか定義していないのに、一部のC++シンボルがexportされてしまいます。ざっと調べてみたところ、どうやらtemplateのインスタンスを定義した場合には有無をいわさず外部参照できてしまうようです。

GCC拡張であればvisibilityの制御でこの挙動を変えられるようなので、pragmaを使ってdartsのインスタンスシンボルを隠すことはできるようになりました(参考: Visibility – GCC Wiki)。

#include <string>
#include <vector>
#include <map>
#include <iostream>
#pragma GCC visibility push(hidden)
#include <darts.h>
#pragma GCC visibility pop
extern "C" {
#include <stdlib.h>
#include <stdio.h>
#include "dartsdic.h"
#include "chalib.h"
}

typedef Darts::DoubleArrayImpl<char, unsigned char, long, unsigned long>
DoubleArrayL;

そもそもなぜこんなことをする必要があるかいうと、Debian packageのsymbolsの仕組みに引っかかるからです。C++のsymbol name mangling ruleはgccのメジャーバージョンが上がると微妙に変わることがあって、現在stable標準のgcc 5.xとunstable標準のgcc 6.xでまさにこれが影響しています。これまでビルドしていたライブラリのシンボル情報をdebian/<package-name>.symbols.<arch>という名前で保存していて、ビルド結果のバイナリーに含まれるシンボルがこのファイルと異なった場合、ビルドエラーとなるようになっています。これはABI互換性が壊れないことを保証するための仕組みです。

そもそも内部で使っているだけのC++シンボルが見えてしまっているのを回避して、この問題を根本から対応したかったのでした。

しかしまだ一部の標準ライブラリのC++ template instance symbol(std::ctype<char>とか)が残ってしまっているので、それをどうしたものかと苦慮しているところです。

 

USB 3.0フラッシュメモリにGPT/UEFIブートできるDebianのインストールを試みた

USB 3.0ポートを持つ機器が手元に増えてきたので、そのようなマシンで起動できるUSBメモリ上のDebian環境を作ろうと頑張ってみました。最終的には一応できたのですが、手作業がちょっと必要でした。

そもそも、USB 2.0のフラッシュメモリ上にUEFI bootable Debianを作るのはまったく問題ありません。しかし3.0だとjessie/stretchのインストーラーで起動できる状態に持っていけませんでした。jessieで作った場合には”no bootable os”と言われたり、stretchで作った場合ではgrubは入るもののrescue consoleが立ち上がるだけ、という妙な状態です。2.0と3.0で何か扱いが違うのでしょうか…

ともかく、対応としてはstretchからインストールしたメディアを一度外して、他のDebian環境からそのメディアをマウントしてEFIパーティションの/EFI/BOOT/以下にルートパーティションの/boot/grub/grub.cfgをコピーしてやることで動くようになりました。

頑張ればjessie(現stable)でも設定できそうな気がしますが、stretch環境は手元になかったのでとりあえずこいつで運用してみようと思っています。

参考:USB HDDにMBR/EFI両ブート可能なUbuntuイメージを作る方法 – bellbind

USB 2.0と3.0で違いが出るのはなぜなのか、原因を知っている人がいたらぜひ教えてください。ベンダーのファームウェア依存なのかもしれませんが…(今回はVAIO Duo11を使用) 起動できないのはUSB 3.0フラッシュメモリにインストールしたDebian環境だけでなく、rufusで作成したインストールメディアでも同様の状況(grub rescue consoleに落ちる)でした。

Orange PI PCで動画のハードウェアエンコードはできるのか

これはLinux Advent Calendar 2015 18日目の記事です。

ARMベースの小型PCとしてRaspberry PIシリーズが人気です。ハードウェアによる動画(H.264)エンコード支援がついていて、それが目的で使っている人もいるようです。

しかし私はRaspberry PI 2の代わりにOrange PI PCを購入しました。機能的には持っているようなので、できればなんとか使いたいところです。

参考にするため、そもそもRasPiではどうやっているのかをちょっと調べてみました。Googleで検索すると、gstreamerでomxh264encを使うという方法が紹介されています

これはgst-omxというコンポーネントのようで、OpenMaxというコーデックの取り扱いを抽象化したAPIのようです。さらに調べてみると、RasPiではlibopenmaxil.soという共有ライブラリが呼び出されているようです。

ではこいつのソースコードはどこだと探してみましたが、ファームウェアの一部という扱いでバイナリーのみが配布されているという残念な状況でした。RasPi側からの調査はここが限界です。

ではOrange PIではどうか。Orange PIとAllwinnerのチップの情報に関しては、linux-sunxi.orgが総本山のようです。ここにいろいろと情報がありました。

Orange PI PC用カーネルにはcedar-veというモジュールが追加されており、これがハードウェアコーデック用のデバイスドライバとなっています。/dev/cedar_devというスペシャルデバイスを介してioctlで直接ハードウェアを操作する機能を提供しています。残念ながらメインラインにはマージされていないようです。

そしてそれを使うよう改造されたffmpegが公開されています。これを動かすことを目標としていろいろ試してみました。リポジトリにはdeb化されたバイナリーもありますが、どうもwheezy向けのようです。しかもパッケージングの作法もよろしくなく、既存のdebianパッケージとファイル単位でいろいろ衝突を起こすので、これを利用するのはお勧めしません。

そこで手動でのビルドを行いましたが、ライブラリ周りで苦労しました。最終的には以下のような手順でビルドできると思います。

# apt-get build-dep ffmpeg
# apt-get install frei0r-plugins-dev libgnutls28-dev ladspa-sdk \
libiec61883-dev libavc1394-dev libass-dev libbluray-dev libbs2b-dev  \
libcaca-dev flite1-dev libgme-dev libgsm1-dev libmodplug-dev \
libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev \
libopenjpeg-dev libopus-dev librtmp-dev libshine-dev libssh-dev \
libspeex-dev libtheora-dev libtwolame-dev libvo-aacenc-dev libvo-amrwbenc-dev \
libvorbis-dev libvpx-dev libwavpack-dev libwebp-dev libx265-dev \
libxvidcore-dev libzvbi-dev libopenal-dev
# ./configure --prefix=/opt/ffmpeg \
        --build-suffix="-ffmpeg" \
        --toolchain=hardened \
        --enable-gpl \
        --enable-shared \
        --disable-stripping \
        --disable-decoder=libopenjpeg \
        --disable-decoder=libschroedinger \
        --enable-avresample \
        --enable-avisynth \
        --enable-gnutls \
        --enable-ladspa \
        --enable-libass \
        --enable-libbluray \
        --enable-libbs2b \
        --enable-libcaca \
        --disable-libcdio \
        --enable-libflite \
        --enable-libfontconfig \
        --enable-libfreetype \
        --enable-libfribidi \
        --enable-libgme \
        --enable-libgsm \
        --enable-libmodplug \
        --enable-libmp3lame \
        --enable-libopenjpeg \
        --enable-openal \
        --enable-libopus \
        --enable-libpulse \
        --enable-librtmp \
        --enable-libschroedinger \
        --enable-libshine \
        --enable-libspeex \
        --enable-libssh \
        --enable-libtheora \
        --enable-libtwolame \
        --enable-libvorbis \
        --enable-libvpx \
        --enable-libwavpack \
        --enable-libwebp \
        --enable-libx265 \
        --enable-libxvid \
        --enable-libzvbi \
        --disable-opengl \
        --enable-x11grab \
        --enable-version3 \
        --enable-libopencore_amrnb \
        --enable-libopencore_amrwb \
        --enable-libvo_aacenc \
        --enable-libiec61883 \
        --enable-libzmq \
        --enable-frei0r \
        --enable-libx264 \
        --enable-libopencv \
        --enable-libvo_amrwbenc
# make

ビルドしたバイナリを実行してみます。/dev/cedar_devへのrwアクセスができる状態でffmpegを実行します。

$ ffmpeg -i inputfile.ts -vcodec cedrus264 -pix_fmt nv12 output.mp4
ffmpeg version git-2015-01-22-f86a076 Copyright (c) 2000-2014 the FFmpeg developers
  built on Dec  7 2015 14:04:23 with gcc 4.9.2 (Debian 4.9.2-10)
(中略)
[VE SUNXI] VE version 0x0000 opened.
[cedrus264 @ 0x1f42f0] Cannot allocate frame.
Output #0, mp4, to 'output.mp4':
    Stream #0:0: Video: h264, q=2-31, 128 kb/s, SAR 1:1 DAR 0:0, 29.97 fps
    Metadata:
      encoder         : Lavc56.0.101 cedrus264
    Stream #0:1: Audio: aac, 0 channels, 128 kb/s
    Metadata:
      encoder         : Lavc56.0.101 libvo_aacenc
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg2video (native) -> h264 (cedrus264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (libvo_aacenc))
Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

残念ながらうまく動きませんでした。gdbで追いかけてみると、ve_open()で/dev/cedar_devをオープンしてioctl IOCTL_GET_ENV_INFOで構造体ve_infoの値を取得していますが、これ自体は失敗しないものの、各種メンバの値reserved_mem, reserved_mem_size, registersがすべて0になっています。これによりve_mallocが失敗して6行目のエラーメッセージが表示されます。ドライバ側のコードを読むと、「このインターフェースは使うな」というコメントがあり、実際に0を返していました。きっと古いcedar_devで動くコードだったのでしょう…

http://linux-sunxi.org/CedarX/Encoderの記述によると、現在あるコード以外にもsunxi_memドライバという物理メモリにアクセスするドライバ(/dev/sunxi_mem)と併用して動くCedarXというライブラリが別にあるようです。ハードウェアエンコーダのサンプルコードもあるのですが、やはりバイナリでしか存在しないライブラリ群に依存しています。

それでもいいからなんとか動かせないかと、sunxi_memドライバを追加した勝手カーネルをビルドしようとしたのですが、mach/includes.hという存在しないヘッダファイルを必要としてビルドできませんでした。ここはまだ調査不足です。

現状の結論として、Orange PI PCでH.264のハードウェアエンコードは「できそうな雰囲気」という煮え切れない結論となってしまいました。linux-sunxi MLの購読を始めたので、今後はこのあたりどうなっているかを尋ねてみたいと思っています。

Debian上でmecab-ipadicをベースに単語を追加する

今時のMeCabには、新しく追加した単語だけコストを計算させる機能があるので、実際に動かしてみました。

参考となるURLはhttps://taku910.github.io/mecab/dic.htmlです。Web上には古いgoogle code上のページがまだ残っており、Googleで検索するとそちらが上位に引っかかるので注意が必要です。

前提として、mecab-utilsとmecab-ipadic(EUC-JP版、UTF-8は不可)がインストールされている必要があります。

次に、登録する単語のエントリーを用意します。諸事情により、EUC-JPで保存しておきます。以下は実際の例です。foo.csvという名前で保存しておきます。

日生協,,,,名詞,固有名詞,組織,*,*,*,にっせいきょう,ニッセイキョウ,ニッセイキョウ

次にモデルファイルを前述のページから取得します。リンク先はGoogle Driveのようです。この記事を書いている2015年10月の時点では、mecab-ipadic-2.7.0-20070801.modelというファイル名になっています。

必要なファイルが集まったら、以下を実行します。

$ mkdir tmp
$ cp /var/lib/mecab/dic/ipadic/* /usr/share/mecab/dic/ipadic/* tmp/
$ /usr/lib/mecab/mecab-dict-index -m ./mecab-ipadic-2.7.0-20070801.model \
  -d ./tmp -u foo2.csv -f euc-jp -t euc-jp -a foo.csv

すると、foo2.csvに単語のコストが記録された新しい結果が出力されます。

日生協,1292,1292,3062,名詞,固有名詞,組織,*,*,*,にっせいきょう,ニッセイキョウ,ニッセイキョウ

元のmecab-ipadicのソース(/var/lib/mecab/dic/ipadic/*.csv)とモデルmecab-ipadic-2.7.0-20070801.model)がEUC-JPであるため、新しい辞書の文字コードもEUC-JPに合わせる必要があります。

Debian Jessie i386をamd64に無理やり移行させる

i386環境から再インストールをしないでamd64に移行させる作業をやってみました。なんとか実現できたものの、今のところは無理やり感が否めません。実際にやってみた感触を記録しておきます。

背景

Debianはメジャーリリース間のアップグレードが行えることを重要視しているディストリビューションであり、実際自分もbo(1.3)からwheezy(7.x)まで更新し続けているインスタンスを持っています。

しかしながら、当然そのような古くからのシステムはアーキテクチャがi386のままです。amd64が公式にサポートされたのはetch(4.0.x, 2007~)からです。途中でmultiarchという複数のアーキテクチャのパッケージを一つのシステムに導入する仕組みもできましたが、それはi386→amd64への移行に直接利用できるようなものではありません。

手法

i386→amd64化を試みた人はこれまでにもあり、いくつかはネット上の私的なドキュメントとして残されています。今回はDebian Wikiに書かれている方法をとってみました。

作業の流れ

大まかに実施する作業の流れを以下に示します。

  • amd64 kernelパッケージのインストール
    • i386アーキテクチャでもlinux-image-*-amd64パッケージがあり、kernelだけ64bit化することはできる
  • debootstrapで/chroot64 以下にamd64の最小環境を構築
    • あとで必要になるパッケージ群を追加で入れる(libc6-i386 file bzip2 openssh-client lftp)
  • Live CD/USB等を使って起動し、/chroot64以下の実行ファイルを/にコピー
    • /chroot64/etc/ld.so.cache も忘れずコピーする
    • /chroo64/lib64は/lib64にコピーを行う
      • Wikiではsymlinkを張る、と記述されているがコピーでないと正常に動作しなかった
      • 動作するかどうかは実際にchroot /chroot64 /bin/sh 等を実行してみれば判断できる
  • amd64 kernelでブートする
    • この段階でパニックを起こした場合、/lib64等が適切に処理されておらずdll不足でinitが実行できなかった可能性が高い
  • インストールされているパッケージをi386からamd64に入れ替える
    • apt-get updateを実行
    • 依存関係と戦いながらi386パッケージをamd64に置き換える
      • インストールパッケージ数が多いほどここの作業は大変
      • 何かあったら以下の手段を試す
        • dpkg –remove –force-all [パッケージ名]:i386; apt-get install [パッケージ名]
        • apt-get -f install
        • cd /var/cache/apt/archives; dpkg -i –force-all [パッケージ名]*.deb ; apt-get -f install

簡単な解説

やっていることは、最低限のバイナリをamd64に置き換えて、あとはapt/dpkgに任せてパッケージを入れ替えます。dpkgがamd64 binaryに変わった時点でシステムの認識はi386からamd64に変わります。しかしaptのDBはi386のままなので、まず一度apt-get updateを行う必要があります。

i386なバイナリもdllさえそろっていれば動作します(/chroot64にlibc6-i386を入れるのはこのため)。再起動した時点で一応システム全体は動くようです。

しかしi386が混在しているのでパッケージの衝突は発生します。dpkg –force-allとapt-get -f installを駆使してなんとか乗り切りましょう。

個人的なハマリポイント

ネットワークの設定はnetwork-manager任せにしていたので、ssh越しに作業をしていたらnetwork-managerの更新がかかったタイミングで通信できなくなり、コンソールからの作業を余儀なくされました。GNU screen/tmuxを活用すべきだったと反省しています。

壊れた仮想ディスクを扱う

立ち上げっぱなしのWindowsマシンが、気が付くとBSoDで落ちてしまいました。原因は追加したHDDにあるようで、Linuxで観測してみると不定期にSATAのエラーを吐きます。

再起動したら、HDD自体が認識されず困ったので、testdiskでパーティションテーブルの復元を試みました。幸いなことに、これでNTFSパーティションの復旧はできました。このtestdiskはSystemRescueCD辺りも含まれているので、普段から起動ディスクとして用意しておくと安心です。

しかしこれだけでは不完全で、NTFSパーティション自体がdirtyになっていたので、回復コンソールからchkdsk /fを実施することでファイルシステムレベルの修正できました。

しかし不幸はこれだけでは終わりませんでした。対象HDD内においていた仮想マシンが起動しなくなり、grubのプロンプトに落ちるという状況になりました。Debianのインストーラーrescueモードで見ると、そもそもext2/3としてのsignatureまで壊れてしまっているようでした。

使っていた仮想マシンのディスク形式はVMware Playerからimportしてきたvmdk形式だったので、いったんqemu-imgでraw形式に変換し、kpartxでパーティションを認識、fsckを実施しました。

# qemu-img convert -f vmdk -O raw /path/to/disk.vmdk /output/disk.img
# kpartx -av /output/disk.img
# fsck.ext3 -y /dev/mapper/loop1p1

大量のエラーが発生し、lost+foundにかなりのデータがおいやられたものの、なんとかfsckは完走しました。/homeごとなくなってしまいましたが…

幸い、以前変換したときの元のイメージも残っていたので、現在はそちらをraw形式に変換してデータの復元を試みています。重要なデータはlost+foundの方を参照することにします。