⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drbd_resource.pm

📁 Linux Distributed Replication Block Device
💻 PM
字号:
package LGE_CTH::DRBD_ResourceInstance;use strict;use warnings;use Carp;## helper class first. This is one instance of a pair of DRBDs.#use LGE_CTH ":util";our @ISA = 'LGE_CTH::Component';sub takes_events { 0 };our %ClassData = (	events => {},	config_template => {			master_resource => undef,			index    => undef,			settings => undef,			disk     => undef,	},	states => {		role => [ qw(active passive) ],		data => [ qw(valid inconsistent) ],		disk => [ qw(attached detached) ],		# keep these state names, I may depend on the sort order!		conn => [ qw(Alone Try connected syncSource syncTarget) ],	},);sub wait_sync {	my ($me,$event) = @_;	my ($link,$minor,$name) = @{$me->{_config}->{master_resource}->{_config}}{qw( link minor name )};	my $node = $me->{_config}->{settings}->{node};	my ($hostname,$ip) = @{$node->{_config}}{qw/hostname admin_ip/};	my $cmd;	if ($link->{_status}->{status} ne 'up') {		warn "$link->{_id} not up??\n";	} elsif ($node->{_busy} and $node->{_busy} !~ /^wait_sync/) {		warn "$node->{_id} busy: $node->{_busy}\n";	} else {		$cmd = "on $ip: drbd_wait_sync DEV=/dev/$DRBD_DEVNAME$minor";		$node->{_busy} = "wait_sync" unless $node->{_busy};		$node->{_busy} .= " $name ";		$LGE_CTH::FAILED += 0x1000;		_spawn( "wait_sync $name on $hostname after $event", $cmd,			sub {				my $ex = $_[0];				$node->say("wait_sync $name on $hostname done: $ex");				$node->{_busy} =~ s/ $name / /;				$node->{_busy} = ""  if $node->{_busy} =~ /^wait_sync\s*$/;				$LGE_CTH::FAILED -= 0x1000;				# TODO update state and so on.			}		);	}}sub initial_setup {	my ($me,$node) = @_;	my ($mr,$settings,$disk) = @{$me->{_config}}{qw(master_resource settings disk )};	die unless $node == $settings->{node};	return if $me->{DID_SETUP}++;	_spawn("$me->{_id}: initial_setup on $node->{_config}->{hostname}",		sub {			my $cmd = ". ./functions.sh; on $node->{_config}->{admin_ip}: drbd_append_config"			     . " RES=$mr->{_config}->{name} LO_DEV=$disk->{_config}->{dev}"			     . " NAME=$disk->{_config}->{name}"			     . " START_CLEAN=$::DRBD_SKIP_INITIAL_SYNC";			open (DRBD_CONF,"|$cmd")				or die "$cmd $node->{_id}:drbd.conf: $!";			print DRBD_CONF $mr->as_conf_string				or die "print | $cmd $node->{_id}:drbd.conf: $!";			close DRBD_CONF				or die "close $node->{_id}:drbd.conf status $? $!";			0;		},		'SYNC'	);	$me->wait_sync('initial_boot');}sub Node_changed {	my ($me,$node,$info,$event) = @_;		my ($hostname,$ip) = @{$node->{_config}}{qw/hostname admin_ip/};	my $name = $me->{_config}->{master_resource}->{_config}->{name};	my ($cmd,$what);	return if ($node->{_status}->{status} eq 'down');	$what = ($event eq 'END_OF_TEST') ? "down" : "up";	return $me->initial_setup($node) if ($event eq 'initial_boot');	$cmd = "on $ip: drbdadm_$what name=$name";	_spawn( "drbdadm $what $name on $hostname after $event", $cmd, 'SYNC');	$me->wait_sync($event) if $what eq 'up';}sub Disk_changed {	my ($me,$disk,$info,$event) = @_;		my $node = $me->{_config}->{settings}->{node};	my ($hostname,$ip) = @{$node->{_config}}{qw/hostname admin_ip/};	my ($link,$minor,$name) = @{$me->{_config}->{master_resource}->{_config}}{qw( link minor name )};	my ($cmd,$what);	return if $event ne 'heal';	return if $node->{_status}->{status} ne 'up';	$cmd = "on $ip: drbd_reattach DEV=/dev/$DRBD_DEVNAME$minor name=$name";	_spawn( "drbd_reattach $name on $hostname", $cmd, 'SYNC');	$me->wait_sync("attach");}1;########################################################################package LGE_CTH::DRBD_Resource;use strict;use warnings;use Carp;use LGE_CTH ":util";use LGE_CTH::Disk;use LGE_CTH::Component;our @ISA = 'LGE_CTH::Component'; # XXX no, its a resource/service ...our %ClassData = (	states => [ qw(operational degraded FUBAR) ],	events => {},	config_template => {		name              => undef,		minor             => undef,		protocol          => 'C',       # A,B,C		usize             => 0,  	        'incon-degr-cmd'  => "reboot -f",		startup => {			'degr-wfc-timeout' => 120, # 2 minutes.		},		disk    => {			'on-io-error' => 'detach', # passon,panic,detach			# 'size'        => undef,    # deprecated		},		net     => {			'sndbuf-size'    => 2*65535,  # 512*1024 or similar			'timeout'        => 60,       #  6 seconds  (unit = 0.1 seconds)			'connect-int'    => 10,       # 10 seconds  (unit = 1 second)			'ping-int'       => 10,       # 10 seconds  (unit = 1 second)			'max-buffers'    => 32,			'max-epoch-size' => 2048,		},		syncer  => {			'rate'  => '10M',			'group' => 1,			'al-extents' => 257,		},		link   => undef,		peers  => [{			node         => undef,			lodev        => undef,			port         => undef,			'meta-disk'  => 'internal',			'meta-index' => -1,			lo_may_fail   => 0,			meta_may_fail => 0,		}],	},);# does not take eventssub takes_events { 0 }sub CheckConfig {	my $me = shift;	my $c = $me->{_config};	my $link  = $c->{link};	my $peers = $c->{peers};	die "link should be a LGE_CTH::Link, not '$link'!\n"		unless ref $link and $link->isa('LGE_CTH::Link');	die "need exactly two peers.\n"		unless @$peers == 2;	for (my $i = 0; $i < 2; $i++) {		my $n = $peers->[$i];		my ($node,$lodev) = @$n{qw(node lodev)};		die "sorry, meta-disk != internal not yet implemented\n"			if $n->{'meta-disk'} ne 'internal';		$n->{'meta-index'} = -1;		die "node should be a LGE_CTH::Node, not '$node'!\n"			unless ref $node and $node->isa('LGE_CTH::Node');		die "$node->{_id} not connected to $link->{_id}!\n"			unless exists $link->{_config}->{_nodes}->{$node->id};		my $disk = new LGE_CTH::Disk {			node => $node,			name => $c->{name},			dev  => $lodev,			may_fail => \$n->{lo_may_fail},			usize => ($c->{usize} ? ($c->{usize}+128*1024) : 0)		};		my $instance = new LGE_CTH::DRBD_ResourceInstance {			master_resource => $me,			disk     => $disk,			index    => $i,			settings => $n,		};		push @{$me->{_config}->{_instances}}, $instance;		$instance->depends_on($node);		$instance->depends_on($disk);		$me->depends_on($instance);	}	$me->depends_on($link);}sub as_conf_string {	my $me = shift;	my $c  = $me->{_config};	my $link = $me->{_config}->{link};	my $s  = <<___ ;resource $c->{name} {    protocol        $c->{protocol};    incon-degr-cmd "$c->{'incon-degr-cmd'}";___	for my $n (@{$me->{_config}->{peers}}) {		my $ip = $link->{_config}->{_nodes}->{$n->{node}->id}->{ip};		$s .= <<___ ;    on $n->{node}->{_config}->{hostname} {        device         /dev/$DRBD_DEVNAME$c->{minor};        disk           /dev/mapper/$c->{name};        address        $ip:$n->{port};        meta-disk      $n->{'meta-disk'}@{[ $n->{'meta-disk'} eq "internal" ? ";" : "[$n->{'meta-index'}];" ]}    }___	};	for my $k (qw(net disk syncer startup)) {		$s .= "    $k {\n        "		. join "\n        ",		map {			my $v = $c->{$k}->{$_};			$v =~ /\s/			? sprintf('%-14s "%s";', $_, $v)			: sprintf('%-14s %s;', $_, $v)		} sort keys %{$c->{$k}};		$s .= "\n    }\n";	}	$s .= "}\n";	return $s;};sub start {	my ($me,$node) = @_;	# FIXME paranoia: $node in peers, and up...	my $c = $me->{_config};	my ($minor,$name) = @$c{qw( minor name )};	my ($hostname,$ip) = @{$node->{_config}}{qw/hostname admin_ip/};	my ($cmd,$force);	if ($me->{_config}->{do_once_per_node} and not $me->{"did_once:$node->{_id}"}++) {		$cmd = "on $ip: $c->{do_once_per_node} " . $me->env;		_spawn("$me->{_id} do once per node on $node->{_id}", $cmd, 'SYNC');	}	if (not $me->{did_on_first_start}++) {		if ($c->{do_on_first_start}) {			$cmd = "on $ip: $c->{do_on_first_start} " . $me->env;			_spawn("$me->{_id} do on first start on $node->{_id}", $cmd, 'SYNC') if $cmd;		}		$force = 1;	}       	$cmd = "on $ip: drbd_wait_peer_not_pri minor=$minor";	_spawn("$me->{_id}: wait for $hostname to recognize ... ",$cmd,'SYNC');       	$cmd = "on $ip: drbdadm_pri name=$name";        $cmd .=	' "force=-- --do-what-I-say"' if $force;	_spawn("$me->{_id}: Primary $name on $node->{_config}->{hostname}",$cmd,'SYNC');	if ($force) {		for my $i (@{$c->{_instances}}) {			$i->wait_sync("forced Primary")				if $c->{peers}->[$i->{_config}->{index}]->{node} == $node;		}	}}sub stop {	my ($me,$node) = @_;	my $name = $me->{_config}->{name};	my ($hostname,$ip) = @{$node->{_config}}{qw/hostname admin_ip/};	# FIXME paranoia: $node in peers, and up...	my $cmd = "on $ip: drbdadm_sec name=$name";	_spawn("$me->{_id}: Secondary $name on $hostname",$cmd,'SYNC');}sub DRBD_ResourceInstance_changed {	# FIXME}sub Link_changed {	my ($me,$link,$info,$event) = @_;		# FIXME update internal state	if ($event eq 'heal') {		for my $i (@{$me->{_config}->{_instances}}) { $i->wait_sync("$link->{_id} heal"); }	}}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -