« 2007年03月 | メイン | 2007年06月 »

2007年04月23日

keepalived-1.1.13がkernel 2.6.20でコンパイルできない

すでにupdateでkernel 2.6.20になるfc6でkeepalivedのmakeが通らない。

/usr/include/stdint.h:56: error: conflicting types for ‘uint64_t’
/lib/modules/2.6.20-1.2944.fc6/build/include/linux/types.h:124: error: previous declaration of ‘uint64_t’ was here
                                                                                                                 vrrp_arp.c: In function ‘send_gratuitous_arp’:
vrrp_arp.c:84: warning: pointer targets in initialization differ in signedness
make[2]: *** [vrrp_arp.o] Error 1

こんな感じのエラーで止まる。

同じことを悩んでいる方もいました。
keepalived-1.1.13カーネル2.6.20以降でコンパイル通らず

次のバージョンで直る予定らしいですがorz
それまで待てないので、keepalivedのrpmではどうやっているのか、調べたところ、
http://ftp.iij.ad.jp/pub/linux/fedora/extras/6/SRPMS/keepalived-1.1.13-6.fc6.src.rpm
の中で、以下なpatchがあたってました

diff -Naupr keepalived-1.1.13.orig/keepalived/vrrp/vrrp_arp.c keepalived-1.1.13/keepalived/vrrp/vrrp_arp.c
--- keepalived-1.1.13.orig/keepalived/vrrp/vrrp_arp.c   2006-10-11 11:44:59.000000000 +0200
+++ keepalived-1.1.13/keepalived/vrrp/vrrp_arp.c        2007-03-22 16:22:29.000000000 +0100
@@ -22,14 +22,14 @@
  * Copyright (C) 2001-2006 Alexandre Cassen, <acassen@linux-vs.org>
  */
 
-/* system includes */
-#include <linux/if_packet.h>
-
 /* local includes */
 #include "vrrp_arp.h"
 #include "memory.h"
 #include "utils.h"
 
+/* system includes */
+#include <linux/if_packet.h>
+
 /* global vars */
 char *garp_buffer;
 int garp_fd;


includeの順番が変わっただけっぽいですが、これでmake通るようになりました。

2007年04月06日

Plagger::Plugin::Aggregator::Async

Plaggerネタ

YAPC::Asiaのikebeさんのプレゼンにも名前がでてきたHTTP::Asyncを使ったAggregator。
パラレルでFeedの取得ができるので、Simple使うより早い。Xangoより使うのが簡単。
まだ、Cache周りが不完全。

confに以下で使える

plugins:
  - module: Aggregator::Async
  - module: Subscription::Config
    config:
      feed:
        - http://blog.nomadscafe.jp/


ソースは↓追記に張り付けた。

package Plagger::Plugin::Aggregator::Async;
use strict;
use base qw( Plagger::Plugin::Aggregator::Simple );
use HTTP::Async 0.07;

__PACKAGE__->mk_accessors( qw/async/ );

sub register {
    my($self, $context) = @_;

    $self->async(
        HTTP::Async->new( %{$self->conf->{async_args} || {}} )
    );
    $self->{_id2feed} = {};

    $context->register_hook(
        $self,
        'customfeed.handle'   => \&aggregate,
        'aggregator.finalize' => \&finalize,
    );
}

sub aggregate {
    my($self, $context, $args) = @_;
    my $url = $args->{feed}->url;

    my $id = $self->async->add( $self->prep_req( $context, $url) );
    $self->{_id2feed}->{ $id } = $args->{feed};
}

sub prep_req {
    my ( $self, $context, $url ) = @_;
    my $req = HTTP::Request->new(
        GET => $url
    );
    $req->user_agent( "Plagger/$Plagger::VERSION (http://plagger.org/)" );
    
    my $ref = $self->cache->get($url);
    if ( $ref ) {
        $req->if_modified_since( $ref->{LastModified} ) 
            if $ref->{LastModified};
        $req->header('If-None-Match', $ref->{ETag} )
            if $ref->{ETag};
    }

    $req;
}

sub finalize {
    my($self, $context, $args) = @_;
    while ( my ( $response, $id ) = $self->async->wait_for_next_response ) {
        my $feed = $self->{_id2feed}->{$id};
        $context->log(info => "Fetch " . $feed->url);
        $self->handle_response( $context, $response, $feed );
    }
}

sub handle_response {
    my ( $self, $context, $response, $feed )  = @_;
    my $url = $response->request->uri;

    if ( $response->code == 304) {
        $context->log(error => "Not Modified: $url");
        return;
    }
    elsif (! $response->is_success) {
        $context->log(error => "Fetch for $url failed: " . $response->code);
        return;
    }

    my $ufr = TO_URI_FETCH_RESPONSE( $response );
    my $feed_url = Plagger::FeedParser->discover($ufr);
    if ($url eq $feed_url) {
        $self->handle_feed($url, \$response->content, $feed);
    } elsif ($feed_url) {
        my $new_id = $self->async->add( $self->prep_req($context, $feed_url ) );
        $self->{_id2feed}->{$new_id} = $feed;
    } else {
        return;
    }

    $self->cache->set(
        $response->request->uri,
        {
            ETag => $response->header('ETag') || '',
            LastModified => $response->header('Last-Modified') || ''
        }
    );

    return 1;
}

## XXX copy from Xango
sub TO_URI_FETCH_RESPONSE
{
    my ($r) = @_;

    my $ufr = URI::Fetch::Response->new();
    $ufr->http_status($r->code);
    $ufr->http_response($r);
    $ufr->status(
        $r->previous && $r->previous->code == &HTTP::Status::RC_MOVED_PERMANENTLY ? &URI::Fetch::URI_MOVED_PERMANENTLY :
        $r->code == &HTTP::Status::RC_GONE ? &URI::Fetch::URI_GONE :
        $r->code == &HTTP::Status::RC_NOT_MODIFIED ? &URI::Fetch::URI_NOT_MODIFIED :
        &URI::Fetch::URI_OK
    );
    $ufr->etag($r->header('ETag'));
    $ufr->last_modified($r->header('Last-Modified'));
    $ufr->uri($r->request->uri);
    $ufr->content($r->content);
    $ufr->content_type($r->content_type);

    return $ufr;
}

1;

YAPC::Asia 2007でLTしてきました

YAPC::Asia 2007で、LTに出させていただきました。

ネタは以前書いた、同じコマンドを複数のサーバで実行です。

資料はこちら(pdf)です
こういうノウハウ(小手先テクニック)はもっと共有されてもいいと思う。

便利な技があったらいろいろ教えてください。