Ноя 23 2010

readahead-list

Published by

Readahead — утилита, которая кэширует файлы и позволяет быстрее запускать программы/службы.
Readahead-list — список приложений и библиотек, запускаемых в Вашей системе, который используется  readahead.

Установка

Gentoo:

emerge readahead-list

Arch:

yaourt -S readahead-list

Использование
В целом, весь процесс делится на две части: профилирование (создание readahead-list) и собственно использование. Также обычно разделяют профилирование процесса загрузки системы (boot profiling) и профилирование рабочего окружаения (desktop profiling).

Gentoo
Судя по всему для Gentoo устанавливается уже готовый readahead-list, поэтому для того, чтобы всё заработало достаточно выполнить команды:

# rc-update add readahead-list-early boot
# rc-update add readahead-list boot

Автоматическое создание листов:
Автоматизировать создание листов можно с помощью небольшого скрипта на python (readahead-watcher.py):

#!/usr/bin/python

"""
Date: 2007-10-14
Autor: Stephan Birkl (sbp a-t extio d0t de)

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
"""


import os
import sys
import pyinotify
import stat

WATCH_BASEPATHS = ["/bin",
                   "/lib",
                   "/sbin",
                   "/usr/kde",
                   "/usr/qt",
                   "/usr/local/bin",
                   "/usr/bin",
                   "/usr/lib",
                   "/usr/share",
                   "/usr/X11R6",
                   "/usr/sbin"]

WATCHED_EVENTS  = pyinotify.EventsCodes.IN_OPEN | pyinotify.EventsCodes.IN_ACCESS
WORKDIR         = "/tmp"
VERIFY_FILENAME = "readahead-watcher-verify-file"
OUTFILE         = "readahead-watcher-output"
LOGFILE         = "readahead-watcher-log"
CHECKREADY      = False

class ProcessEventHandler(pyinotify.ProcessEvent):
  def __init__(self):
    self.ready = False
    self.watchedFiles = {}
    self.lastFile = ""
 
  def process_IN_ACCESS(self, event):
    self.__process_event(event)
   
  def process_IN_OPEN(self, event):
    self.__process_event(event)

  def __process_event(self, event):
    try:
      if not CHECKREADY or self.ready:
        filename = os.path.join(str(event.path), str(event.name))
        if filename != self.lastFile:
          self.lastFile = filename
         
          fileMode = os.stat(filename)[stat.ST_MODE]
          if stat.S_ISREG(fileMode):
            if not self.watchedFiles.has_key(filename):
              self.watchedFiles[filename] = 0
             
            self.watchedFiles[filename] += 1
     
      else:
        if str(event.name) == VERIFY_FILENAME:
          print "File watching is now ready."
          self.ready = True
   
    except:
      pass

class Main(object):
  def __init__(self):
    print "Scanning directory structure. This can take up to a couple of minutes..."
    sys.stdout.flush()

    self.WatchMngr = pyinotify.WatchManager()
    if CHECKREADY:
      self.WatchMngr.add_watch(WORKDIR, WATCHED_EVENTS, rec=True)
    for basepath in WATCH_BASEPATHS:
      self.WatchMngr.add_watch(basepath, WATCHED_EVENTS, rec=True)
   
    self.EvtHandler = ProcessEventHandler()
    self.Notifier = pyinotify.Notifier(self.WatchMngr, self.EvtHandler)
 
  def Run(self):
    if CHECKREADY:
      self.__TouchVerifyFile()
   
    print "File watching is now active."
   
    self.__SetDaemonMode()
   
    while(True):
      try:
        self.Notifier.process_events()
        if self.Notifier.check_events():
          self.Notifier.read_events()
      except:
        self.Notifier.stop()
        break

    self.OutputResult()

  def OutputResult(self):
    # Sort output list by the count of accesses
    tmpOutList = self.EvtHandler.watchedFiles.keys()
    tmpOutList.sort(self.__outListSort)
   
    f = open(os.path.join(WORKDIR, OUTFILE), "w")
    f.write("\n".join(tmpOutList))
    f.close()
 
  def __outListSort(self, x, y):
    cnt1 = self.EvtHandler.watchedFiles[x]
    cnt2 = self.EvtHandler.watchedFiles[y]
   
    if cnt1 < cnt2:
      return -1
    else:
      return (cnt1 > cnt2)

  def __TouchVerifyFile(self):
    f = open(os.path.join(WORKDIR, VERIFY_FILENAME), "w")
    f.write("ok")
    f.close()

  def __SetDaemonMode(self):
    sys.stdout = sys.stderr = open(os.path.join(WORKDIR, LOGFILE), "w")
   
    pid = os.fork()
    if pid > 0:
        sys.exit(0)

    os.chdir("/")
    os.setsid()
    os.umask(0)

    pid = os.fork()
    if pid > 0:
        sys.exit(0)

MainObj = Main()
MainObj.Run()

Не забываем дать нужные права:

chmod a+x readahead-watcher.py

Далее пишем небольшой демон (/etc/init.d/readahead-watcher):

#!/sbin/runscript

depend() {
        need localmount
}

start() {
        ebegin "Starting readahead-watcher"
        <path -to-readahead-watcher>
        eend $?
}

И добавляем в загрузку:

# rc-update add readahead-watcher boot

Перезагружаемся. Находим и убиваем демон:

ps ax | grep readahead-watcher
# kill -2 <PID>

Сгенеированный файл находится в /tmp/readahead-watcher-output. Его нужно скопировать в /etc/readahead-list/runlevel-default.
Демон readahead-watcher можно убрать из автозагрузки.

Arch
В вики-статье предлагается разделить профилирование загрузки системы и профилирование рабочего окружения.

Профилирование загрузки
Выбираем загрузку системы без иксов (убиваем демоны kdm/gdm в rc.conf или меняем runlevel в inittab на 3-й).
Далее в самое начало /etc/rc.sysinit добавляем

echo "starting readahead-watch..."
/usr/sbin/readahead-watch -o /etc/readahead/boot
echo "readahead is watching..."

Перезагружаемся. Проверяем, что readahead запустился и отработал:

ps ax | grep readahead

Прибиваем:

# kill <PID>

Убираем или комментируем то, что добавили в /etc/rc.sysinit. Возвращаем на место демоны ДЕ (уровень запуска в inittab).
Сгенерированный лист находится в /etc/readahead/boot.

Профилирование рабочего окружения
Добавляем readahead-watch-desktop в /etc/rc.conf в секцию DAEMONS, например:

DAEMONS=(preload syslog-ng network netfs @crond @alsa @hal @fam @powernowd cups readahead-watch-desktop gdm)

Пере загружаемся. Входим в ДЕ, запускаем все программы, которые вы хотите добавить в профиль (браузер, почтовый клиент и всё что вашей душе угодно). Далее выполняем уже знакомые команды:

 ps ax | grep readahead
# kill <PID>

Сгенерированный лист находится в /etc/readahead/desktop.

Использование сгенерированных листов
Для активации загрузочного профиля в самое начало /etc/rc.sysinit добавляем:

#!/bin/bash
#
# /etc/rc.sysinit
#
# uncomment the next threee lines to profile the boot process
# be sure you disable gdm from starting before you reboot
# add a bang character to gdm in the daemons array in rc.conf
#
# echo "starting readahead-watch..."
# /usr/sbin/readahead-watch -o /etc/readahead/boot
# echo "readahead is watching..."

# this starts readahead with your boot profile
/usr/sbin/readahead-list /etc/readahead/boot

. /etc/rc.conf
. /etc/rc.d/functions

Для профиля рабочего окружения в rc.conf добавляем readahead-list-desktop ДО gdm/kdm. Пример:

DAEMONS=(preload syslog-ng network netfs @crond @alsa @hal @fam @powernowd cups @readahead-list-desktop gdm)

Не забывайте периодически обновлять листы.

4 responses so far

4 Responses to “readahead-list”

  1. vurdalakon 24 Ноя 2010 at 15:03

    Так для генты достаточно добавить демоны в автозагрузку, или все же нужно запускать скрипты?

  2. vurdalakon 24 Ноя 2010 at 15:06

    И еще, он дополняет preload или заменяет его? Т.е. достаточно установить readahead или совмостно с preload скорость будет больше?

  3. unikumon 24 Ноя 2010 at 15:21

    Судя по арчевскому вики, preload и readehead-list вполне могут сосуществовать. Конкретные цифры, говорящие об ускорении от readehead-list мне не встречались, тем более от совместного использования readehead-list и preload. А вот сомнения насчёт прироста от readehead-list в паре комментах попадались. Будем тестировать, смотреть.

    Также хочу отметить, что readehead-list — это статичный лист, который генерируется пользователем, preload же действует на основании собранной статистики об используемых библиотеках.

    Лично моё мнение, от readehead-list есть профит при загрузки системы, всё остальное, сказанное в статьях и темах на форумах, нужно тестировать.

  4. Landgrafon 16 Авг 2012 at 20:25

    А куда readahead-watcher.py кидать?

Comments RSS

Leave a Reply


*

Powered by WordPress