понеділок, 31 травня 2010 р.

Без ГМО

В связи с новыми заскоками с наклеиванием надписи "без ГМО" на абсолютно все продуткы, включая соль и минералку, аж захотелось найти что-нибудь в продаже с ГМО

понеділок, 24 травня 2010 р.

Есть же еще порядочные люди

В процессе катания распития пива на ВДНХ потерял велосипедные очки (дурацкая привычка снятые очки цеплять на шлем, где они и остаются после снятия шлема и потом выпадают в процессе тягания шлема на руле). Проехался по маршруту следования и не нашел. Но в конце маршрута поиска освистали ребята из ларька, где брали пиво, и вернули очки :)

неділя, 16 травня 2010 р.

Тараканы в мире windows

Они там, похоже, считают вирусы неприятным, но вполне терпимым явлением. На работе каждый раз как бухгалтер возвращается с налоговой или пенсионного, так на дискетке, на которой она туда отчеты носит, и приносит кучу вирусни. Я по этому поводу уже предложил купить ей вместо обычной флешки SD карточку с компактным переходником на usb: на SD карточках есть rw lock.
Но вообще я вспомнил об этом по другому поводу. Подключаю сегодня к ноутбуку свой GPS навигатор (он видится как обычный usb mass storage device), и обнаруживаю на нем такое:
"tmp.exe infected with Win32.HLLW.Lime.22" (c) http://vms.drweb.com/online/?lng=ru
Это мне так на майские праздники на авторизованной точке продажи Garmin обновили мою официально купленную карту...

zfs only system & geom_eli

Непосредственно с geom_eli грузиться нельзя: ни loader, ни никакой из boot-ов его не умеют и загрузить ядро оттуда не смогут. Поэтому делается схема с /boot на отдельном разделе, без geli.
Вообще для этого можно практически дословно вспользоваться инструкцией http://wiki.freebsd.org/RootOnZFS/UFSBoot , но наличие дополнительного ufs раздела мне не нравится: это fsck после unclean shutdown, отсутствие дешевых снапшотов (к хорошему привыкаешь быстро). Поэтому была взята за основу эта статья, http://wiki.freebsd.org/RootOnZFS/GPTZFSBoot и вместе творчески доработаны до получения конфигурации с двумя zfs pool.
# gpart show ada0
=>       34  976773101  ada0  GPT  (466G)
         34         30        - free -  (15K)
         64        128     1  freebsd-boot  (64K)
        192       1856        - free -  (928K)
       2048   16777216     2  freebsd-swap  (8.0G)
   16779264    2097152     3  freebsd-zfs  (1.0G)
   18876416  957896719     4  freebsd-zfs  (457G)
Тут опять напоминаю владельцам дисков WesternDigital о желательности выравнивания начала разделов по 4K границе (gpart сам этого не делает).
swap в принципе может размещаться на zpool, но при этом не будет возможности получить crash dump ядра.
Понятно что на ada0 надо накатить pmbr и gptzfsboot
На 3-й раздел я повесил gpt label zboot для удобства. Использовать метку на 4-м разделе не получится: он должен быть размечен через geli с -b , а при этом ядро как только увидит geli label на ada0p4 , так сразу и запросит для него пароль, не зависимо от наличия gpt label
# geli list
Geom name: ada0p4.eli
EncryptionAlgorithm: AES-CBC
KeyLength: 128
Crypto: software
UsedKey: 0
Flags: BOOT
Providers:
1. Name: ada0p4.eli
   Mediasize: 490443119616 (457G)
   Sectorsize: 512
   Mode: r1w1e1
Consumers:
1. Name: ada0p4
   Mediasize: 490443120128 (457G)
   Sectorsize: 512
   Mode: r1w1e1
Кстати geli label содержит определенные метаданные, без которых получить данные с раздела не возможно. Поэтому не забывайте о необходимости сохранить их с помощью чего-нибудь типа
# geli backup ada0p4 /boot/geli.meta
Ну а дальше можно создавать два пула:
# zpool status
  pool: zboot
 state: ONLINE
 scrub: none requested
config:

        NAME         STATE     READ WRITE CKSUM
        zboot        ONLINE       0     0     0
          gpt/zboot  ONLINE       0     0     0

errors: No known data errors

  pool: zdata
 state: ONLINE
 scrub: none requested
config:

        NAME          STATE     READ WRITE CKSUM
        zdata         ONLINE       0     0     0
          ada0p4.eli  ONLINE       0     0     0

errors: No known data errors
# zpool get bootfs zboot
NAME   PROPERTY  VALUE   SOURCE
zboot  bootfs    zboot   local
# zpool get bootfs zdata
NAME   PROPERTY  VALUE   SOURCE
zdata  bootfs    -       default
# zfs list -o name,mountpoint zboot
NAME   MOUNTPOINT
zboot  /zboot
# zfs list -o name,mountpoint,exec,compression -r zdata
NAME                       MOUNTPOINT            EXEC  COMPRESS
zdata                      legacy                  on       off
zdata/usr                  /usr                    on       off
zdata/usr/home             /usr/home               on       off
zdata/usr/local            /usr/local              on       off
zdata/usr/local/arch       /usr/local/arch         on      lzjb
zdata/usr/local/jails      /usr/local/jails        on       off
zdata/usr/local/tinderbox  /usr/local/tinderbox    on       off
zdata/usr/ports            /usr/ports              on      lzjb
zdata/usr/ports/distfiles  /usr/ports/distfiles   off       off
zdata/usr/ports/packages   /usr/ports/packages    off       off
zdata/usr/src              /usr/src               off      lzjb
zdata/var                  /var                    on       off
zdata/var/crash            /var/crash             off      lzjb
zdata/var/db               /var/db                off       off
zdata/var/db/pkg           /var/db/pkg             on      lzjb
zdata/var/empty            /var/empty             off       off
zdata/var/log              /var/log               off      lzjb
zdata/var/mail             /var/mail              off      gzip
zdata/var/run              /var/run               off       off
zdata/var/tmp              /var/tmp                on      lzjb
# ls -l /boot
lrwxr-xr-x  1 root  wheel  11 12 кві 18:30 /boot -> /zboot/boot
# fgrep zfs /boot/loader.conf
zfs_load="YES"
vfs.root.mountfrom="zfs:zdata"
vfs.zfs.debug=1
#
# cat /etc/fstab
# Device   Mountpoint      FStype  Options         Dump    Pass#
/dev/gpt/swap   none            swap    sw      0       0       0
tmpfs   /tmp    tmpfs   rw,size=3221225472      0       0
proc    /proc   procfs  rw      0       0
fdescfs /dev/fd fdescfs rw 0 0
linproc /usr/compat/linux/proc  linprocfs       rw,late 0       0
/dev/cd0                /cdrom          cd9660  ro,noauto,-CKOI8-U      0       0
Вот так оно и живет на моем ноутбуке. Уже больше месяца как.

середа, 12 травня 2010 р.

zpool on whoole disk or not?

zfs в своих метках, которые он сохраняет на все диски, входящие в zpool, зачем-то сохраняет имена vdev-ов, из которых он состоит. Зачем он там делает не понятно, ввиду того, что все-равно сохраняются и всегда проверяются еще и GUID-ы дисков. Наверное так делается для усложнения жизни.
На solaris оно вроде как не должно быть ничем страшно ввиду того, что там диски обзываются согласно их расположению. А вот на FreeBSD это чревато проблема в случае, когда съедет нумераци дисков (а она обязательно съедет после ребута с отвалившимся диском)
Оно то вроде и не особо страшно: zfs export && zfs improt и всё снова работает. Но все-равно дополнительные действия (а как поступать в случае zfs only system я вообще не представляю). Поэтому лучше таки так не делать.
Из обдуманых и нарытых в инете советов я дла себя выбрал создание одного большого GPT раздела с gpt меткой: по сравнение с glabel гарантия что не возникнет непоняток из-за вдруг обнаруженных в начале диска zfs меток, и вроде как более переносимо (теоретически, а говорят даже практически существует возможность импортировать в solaris pool, экспортированный из FreeBSD).
Кстати при разметке WD дисков сразу рекомендую не забывать про 4K сектора: gpart для GPT по умолчанию предлагает начинать раздел с 34-го 512B сектора, чего явно делать не стоит.

середа, 5 травня 2010 р.

Пляски с ZFS

Из цитат на #freebsd@RusNet:
zfs = оно то вроде работает, но если/когда она развалится, то что с ней делать не понятно вообще (c) levsha.
fsck не нужен, потому что не поможет (c) kib
"Вот наконец настал тот час", и zfs у меня поломался.
На сервере отвалился один диск (не из того пула, который потом сломался, а из другого). Но это отваливание как-то серьезно переклинило контроллер (да, adaptec говно), и посыпалась куча таймаутов от контроллера.
Полностью выключил сервер, подождал некоторое время и включил. В результате после загрузки получил панику. Попробовал удалить /boot/zfs/zpool.cache . В результате пулы перестали автоматически подключаться (совершенно справедливо) и стали видны по zpool import. При этом нужный пул стал помечен UNAVAILABLE, хотя он состял из одного raidz из 6 дисков, причем и raidz и все 6 дисков отображались как ONLINE.
Для ковыряний попробовал использовать zdb. Он при попытке запуска на пул падал по segmentation fault. Это оказалось плюсом: zdb использует тот же код, что и zfs.ko, но на user level, что, впервых, дает core dump вместо panic, во вторых позовляет использовать обычный gdb.
Ковыряния кода с помощью gdb показали, что где-то в душе вызывается zio_vdev_io_start() с zio->io_vd == NULL . Где и почему это происходит я не нашел. При этом zio_vdev_io_start считает что может справиться с такой ситуацией:
if (vd == NULL) {
if (!(zio->io_flags & ZIO_FLAG_CONFIG_WRITER))
spa_config_enter(spa, SCL_ZIO, zio, RW_READER);

/*
* The mirror_ops handle multiple DVAs in a single BP.
*/
return (vdev_mirror_ops.vdev_op_io_start(zio));
}
Вот только vdev_op_io_start совершенно не приспособлен до такой ситуаци: он в конце концов вызывает вот такую функцию:
boolean_t
vdev_is_dead(vdev_t *vd)
{
return (vd->vdev_state < VDEV_STATE_DEGRADED); }





за что сразу получает по голове (или sigsgev в случае zdb, или panic в случае zfs.ko).
Простенький патч вида
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c (revision 207555)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c (working copy)
@@ -1845,6 +1845,10 @@
boolean_t
vdev_is_dead(vdev_t *vd)
{
+ if( vd == NULL ){
+ printf("XXX: Attemt to call vdev_is_dead for NULL vd\n");
+ return 1;
+ }
return (vd->vdev_state < VDEV_STATE_DEGRADED); }





панику исправил, вот только к работоспособности это не привело: теперь операции, которые проходили по этому коду, просто бесконечно долго ждали завершения io.
Дальнейшие ковыряния в направлении "а почему же этот пул помечается как UNAVALIABLE и что с этим можно сделать?" дали результатом такое: UNAVAILABLE пул считается тогда, когда zfs решил что некоторые устройства из пула недоступны, но не может определить какие именно. Для того, чтобы было возможно определить такую ситуацию, zfs записывает в каждый uberblock (The uberblock is similar to the superblock in UFS (c) ZFS On-Disk Specification) контрольную сумму идентификаторов всех устройств, входящих в пул. Поизучавши http://hub.opensolaris.org/bin/download/Community+Group+zfs/docs/ondiskformat0822.pdf была накалякана вот такая приблуда:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <errno.h>

#define UBERBLOCK_MAGIC 0x00bab10c /* oo-ba-bloc! */
#define UBERBLOCK_SHIFT 10 /* up to 1K */

typedef struct dva {
uint64_t dva_word[2];
} dva_t;

typedef struct zio_cksum {
uint64_t zc_word[4];
} zio_cksum_t;

typedef struct blkptr {
dva_t blk_dva[3]; /* 128-bit Data Virtual Address */
uint64_t blk_prop; /* size, compression, type, etc */
uint64_t blk_pad[3]; /* Extra space for the future */
uint64_t blk_birth; /* transaction group at birth */
uint64_t blk_fill; /* fill count */
zio_cksum_t blk_cksum; /* 256-bit checksum */
} blkptr_t;

typedef struct uberblock {
uint64_t ub_magic; /* UBERBLOCK_MAGIC */
uint64_t ub_version; /* SPA_VERSION */
uint64_t ub_txg; /* txg of last sync */
uint64_t ub_guid_sum; /* sum of all vdev guids */
uint64_t ub_timestamp; /* UTC time of last sync */
blkptr_t ub_rootbp; /* MOS objset_phys_t */
} uberblock_t;

int main(int argc, char* argv[]){

uberblock_t* ub = malloc(sizeof ub);
int res;

while( (res = read(0, ub, sizeof *ub) ) > 0 ){
if( ub->ub_magic != 0x00bab10c )
continue;
printf("ub_magic=%jx, ub_version=%ju, ub_txg=%ju, ub_guid_sum=%ju, ub_timestamp=%ju\n",
ub->ub_magic, ub->ub_version, ub->ub_txg, ub->ub_guid_sum, ub->ub_timestamp);

}
if( res < 0 ){ fprintf(stderr, "read(): %d\n", errno); } free(ub); return 0; }





На stdin пограммы были скормлены dd if=(тут перебираем все диски) bs=128k count=1 skip=(тут перебираем 1,3, последний и предпоследний блок на диске) . С блоками так потому, что zfs записывает на каждый диск 4 vdev label: две в начале и две в конце, и каждая vdev label заниает 256KBytes, из которых вторая половина это uberblocks array.
В моём случае было обнаружено что на нулевом диске несколько последних uberblock-ов содержат другую ub_guid_sum. Поэтому этот диск был просто вытянут, после чего zfs спокойно распознала этот пул.
Вот такое вот шаманство этот zfs...