試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

特定のプロファイルのFirefoxの動作中にcpufreqdのプロファイルを自動的に切り替える

  1. cpufreqdのためにFirefoxの別プロファイルを異なるプロセス名で動かすことに
  2. 切り替えたいcpufreqdプロファイルについて
  3. シェルスクリプトがプロセス名にうまくマッチングしない?
  4. C言語のsystem()関数で実行すると...


cpufreqdのためにFirefoxの別プロファイルを異なるプロセス名で動かすことに

以前、風博士というWebブラウザをある用途で用いていたのだが、Firefoxのバージョン3.5系が既に以前(1.0/1.5系や2.0系の頃)と比べてかなり軽くなっていることに加え、Firefox向けのある拡張機能が重宝していることや、3.0系からアドレスバーが強化されるなどの機能面もあり、このブラウザの使用をやめ、Firefoxの別プロファイルとして使うことになった。
このFirefoxプロファイルは(以前風博士で行っていたのと同様)短時間に多くのサイトを一気に巡回し、用が済んだらすぐに終了してしまうという使い方をしているのだが、巡回対象のサイトは重いページが多く、Flashのあるページも多い。Flashが邪魔なら拡張によりフィルタする手もあるのだが、それらのFlash自体が目的の一部分でもあるのでそうはいかない。
一方で省電力目的でcpufreqdを導入しているのだが、conservativeのような動作モードに任せると無駄に動作が重く感じる場面が頻繁に出てくるため、以前はcpufreqdのprogramsプラグイン風博士のプロセス名「kazehakase」が動作中だけ通常時(低負荷時はCPUが持つ最低クロックの1.0GHzまで下げている)と比べて高いクロックで動かすようにしていたのだが、Firefoxはメインで使用しているプロファイルも別にあり、同時に動かすこともあるため、プロセス名でのマッチングを行うわけにはいかない。

切り替えたいcpufreqdプロファイルについて

手元の環境(Athlon64 3500+)ではクロックが下から2段階目の1.8GHzで固定されている状態で十分なので、切り替えたいcpufreqdプロファイルは、このクロックで固定されるようなものとなる。
[一部]ファイル名: /etc/cpufreqd.conf

[Profile]
name=[名前A]
minfreq=1800000
maxfreq=1800000
policy=powersave
[/Profile]

以前はondemandを使っていたこともあったのだが、ページ移動やスクロールなどの度にクロック変動が無駄に頻繁に起きてしまうこと*1と、先にも述べた通り「一気に巡回してすぐ閉じる」使い方をすることから、クロック固定に方針を変更した。

シェルスクリプトがプロセス名にうまくマッチングしない?

通常のFirefoxとは異なるプロセスとして認識させるため、まずは次のようなシェルスクリプトを作成してみた。

#! /bin/sh
env GTK_IM_MODULE=xim GTK2_RC_FILES=/usr/share/themes/Bluecurve/gtk-2.0/gtkrc firefox -no-remote -P [Firefoxのプロファイル名]

「env ... gtkrc」の部分は手元の環境の都合(関連記事)により付けた部分なので省略可。また、firefoxコマンドの場所も必要に応じて変更する。
cpufreqd側のルール設定は以下のようになる。
[一部]ファイル名: /etc/cpufreqd.conf

[Rule]
name=[ルール名]
cpu_interval=0-100
programs=[上のシェルスクリプトの名前]
profile=[名前A]
[/Rule]

これで試したところ、残念ながらこのシェルスクリプトからFirefoxを起動しても(cpufreqdから正しくプロセス名が認識されず)cpufreqdのプロファイルは切り替わらなかった。
このときにpsコマンドなどで確認されるシェルスクリプトのプロセスは

/bin/sh [シェルスクリプトの場所]

のようになっていて、恐らくはこの形になっていることがcpufreqdのprogramsプラグインからプロセスとして見えていない原因と考えられた。
(一般的に)コマンドへのシンボリックリンクを作成してそれを実行するとプロセス名がシンボリックリンク名になるが、firefoxコマンドがシェルスクリプトだと、そのリンクから実行しても同様にうまく動作しなかった。

C言語のsystem()関数で実行すると...

そこで、C言語system()関数を用いて子プロセスとしてFirefoxを実行する下のようなプログラムを作成して

#define _XOPEN_SOURCE 1
#include <stdlib.h>

/*
 * gcc -Wall -Wextra -O2 -pipe [このファイル] -o [実行ファイル名]
 */

int
main ()
{
  int status = system ("env GTK_IM_MODULE=xim GTK2_RC_FILES=/usr/share/themes/Bluecurve/gtk-2.0/gtkrc firefox -no-remote -P [Firefoxのプロファイル名]");
  if (status == -1)
    return -1;                    /* エラー */
  else
    return WEXITSTATUS (status);  /* 終了ステータス(戻り値) 実行失敗は127 */
}

これをコンパイルした実行ファイルの名前(パスではない)を
[一部]ファイル名: /etc/cpufreqd.conf

[Rule]
name=[ルール名]
cpu_interval=0-100
programs=[実行ファイルのファイル名]
profile=[名前A]
[/Rule]

のように指定してみたところ、このプロセス名(実行ファイル名)がcpufreqdから認識され、無事にcpufreqdプロファイルが自動的に切り替わるようになった。
(2015/1/14)manページのリンク先を修正

関連URL:

使用したバージョン:

*1:更に、上で書いたように重く感じる場面もある