This file is indexed.

/usr/lib/heartbeat/hb2openais.sh is in pacemaker 1.1.6-2ubuntu3.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
#!/bin/bash

 # Copyright (C) 2008,2009 Dejan Muhamedagic <dmuhamedagic@suse.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; either
 # version 2.1 of the License, or (at your option) any later version.
 # 
 # This software 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.
 # 
 # You should have received a copy of the GNU General Public
 # License along with this library; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #

. /etc/ha.d/shellfuncs
# utillib.sh moved (sigh!)
# cluster-glue doesn't make its shared data dir available
# we guess, and guess that that's safe, that the datadir is the same
testdirs="/usr/share/cluster-glue $HA_NOARCHBIN/utillib.sh"
for d in $testdirs; do
	if [ -f $d/utillib.sh ]; then
		NOARCH_DIR=$d
		break
	fi
done
test -f $NOARCH_DIR/utillib.sh || {
	echo "sorry, could not find utillib.sh in $testdirs"
	exit 1
}

. $NOARCH_DIR/utillib.sh
. $NOARCH_DIR/ha_cf_support.sh

PROG=`basename $0`
PROGDIR=`dirname $0`

# the default syslog facility is not (yet) exported by heartbeat
# to shell scripts
#
DEFAULT_HA_LOGFACILITY="daemon"
export DEFAULT_HA_LOGFACILITY

: ${SSH_OPTS="-T"}

usage() {
	cat<<EOF

usage: $PROG [-UF] [-u user] [-T directory] [revert]

	-U: skip upgrade the CIB to v1.0
	-F: force conversion despite it being done beforehand
	-u user: a user to sudo with (otherwise, you'd
	         have to run this as root)
	-C: force conversion to corosync (default is openais)
	-T directory: a directory containing ha.cf/logd.cf/cib.xml/hostcache
	         (use for testing); with this option files are not
	         copied to other nodes and there are no destructive
	         commands executed; you may run as unprivileged uid

EOF
	exit
}

SUDO_USER=""
MYSUDO=""
TEST_DIR=""
FORCE=""
UPGRADE="1"
while getopts UFCu:T:h o; do
	case "$o" in
		h) usage;;
		U) UPGRADE="";;
		F) FORCE=1;;
		u) SUDO_USER="$OPTARG";;
		T) TEST_DIR="$OPTARG";;
		C) COROSYNC="1";;
		[?]) usage;;
	esac
done
shift $(($OPTIND-1))
[ $# -gt 1 ] && usage
[ "$TEST_DIR" ] && [ $# -ne 0 ] && usage

if [ "$COROSYNC" -o -d /etc/corosync ]; then
	AIS_CONF=/etc/corosync/corosync.conf
	AIS_KEYF=/etc/corosync/authkey
	KEYGEN_PROG="corosync-keygen"
	COROSYNC=1
else
	AIS_CONF=/etc/ais/openais.conf
	AIS_KEYF=/etc/ais/authkey
	KEYGEN_PROG="ais-keygen"
	COROSYNC=""
fi
AIS_CONF_BASE=`basename $AIS_CONF`
PRODUCT=`basename $AIS_CONF_BASE .conf`
AUTHENTICATION=on
MAXINTERFACE=2
MCASTPORT=5405
RRP_MODE=active
SUPPORTED_RESPAWNS="pingd evmsd"

PY_HELPER=$HA_BIN/hb2openais-helper.py
CRM_VARLIB=$HA_VARLIB/crm
CIB=$CRM_VARLIB/cib.xml
CIBSIG=$CRM_VARLIB/cib.xml.sig
CIBLAST=$CRM_VARLIB/cib.xml.last
CIBLAST_SIG=$CRM_VARLIB/cib.xml.sig.last
HOSTCACHE=$HA_VARLIB/hostcache
HB_UUID=$HA_VARLIB/hb_uuid
DONE_F=$HA_VARRUN/heartbeat/.$PROG.conv_done
BACKUPDIR=/var/tmp/`basename $PROG .sh`.backup
RM_FILES=" $CIBSIG $CIBLAST $CIBLAST_SIG"
REMOTE_RM_FILES=" $CIB $RM_FILES"
BACKUP_FILES=" $AIS_CONF $AIS_KEYF $REMOTE_RM_FILES "
DIST_FILES=" $AIS_CONF $AIS_KEYF $DONE_F "
MAN_TARF=/var/tmp/`basename $PROG .sh`.tar.gz

if [ "$TEST_DIR" ]; then
	cp $TEST_DIR/cib.xml $TEST_DIR/cib-out.xml
	CIB=$TEST_DIR/cib-out.xml
	HOSTCACHE=$TEST_DIR/hostcache
	HA_CF=$TEST_DIR/ha.cf
	AIS_CONF=$TEST_DIR/$AIS_CONF_BASE
	if [ "$SUDO_USER" ]; then
		warning "-u option ignored when used with -T"
	fi
else
	ps -ef | grep -wqs [c]rmd &&
		fatal "you must first stop heartbeat on _all_ nodes"
	if [ "$SUDO_USER" ]; then
		MYSUDO="sudo -u $SUDO_USER"
	fi
fi

CIB_file=$CIB
CONF=$HA_CF
LOGD_CF=`findlogdcf $TEST_DIR /etc $HA_DIR`
export CIB_file LOGD_CF

prerequisites() {
	test -f $HA_CF ||
		fatal "$HA_CF does not exist: cannot proceed"
	iscfvartrue crm || grep -w "^crm" $HA_CF | grep -wqs respawn ||
		fatal "crm is not enabled: we cannot convert v1 configurations"
	$DRY test -f $CIB ||
		fatal "CIB $CIB does not exist: cannot proceed"
	[ "$FORCE" ] && rm -f "$DONE_F"
	if [ -f "$DONE_F" ]; then
		info "Conversion to OpenAIS already done, exiting"
		exit 0
	fi
}
# some notes about unsupported stuff
unsupported() {
	respawned_progs=`awk '/^respawn/{print $3}' $HA_CF |while read p; do basename $p; done`
	grep -qs "^serial" $HA_CF &&
		warning "serial media is not supported by OpenAIS"
	for prog in $respawned_progs; do
		case $prog in
		mgmtd|pingd|evmsd) : these are fine
			;;
		*)
			warning "program $prog is being controlled by heartbeat (thru respawn)"
			warning "you have to find another way of running it"
			;;
		esac
	done
}
#
# find nodes for this cluster
#
getnodes() {
	# 1. hostcache
	if [ -f $HOSTCACHE ]; then
		awk '{print $1}' $HOSTCACHE
		return
	fi
	# 2. ha.cf
	getcfvar node
}
#
# does ssh work?
#
testsshuser() {
	if [ "$2" ]; then
		ssh -T -o Batchmode=yes $2@$1 true 2>/dev/null
	else
		ssh -T -o Batchmode=yes $1 true 2>/dev/null
	fi
}
findsshuser() {
	for u in "" $TRY_SSH; do
		rc=0
		for n in `getnodes`; do
			[ "$node" = "$WE" ] && continue
			testsshuser $n $u || {
				rc=1
				break
			}
		done
		if [ $rc -eq 0 ]; then
			echo $u
			return 0
		fi
	done
	return 1
}
important() {
	echo "IMPORTANT: $*" >&2
}
newportinfo() {
	important "the multicast port number on $1 is set to $2"
	important "please update your firewall rules (if any)"
}
changemediainfo() {
	important "$PRODUCT uses multicast for communication"
	important "please make sure that your network infrastructure supports it"
}
multicastinfo() {
	info "multicast for $PRODUCT ring $1 set to $2:$3"
}
netaddrinfo() {
	info "network address for $PRODUCT ring $1 set to $2"
}
backup_files() {
	[ "$TEST_DIR" ] && return
	info "backing up $BACKUP_FILES to $BACKUPDIR"
	$DRY mkdir $BACKUPDIR || {
		echo sorry, could not create $BACKUPDIR directory
		echo please cleanup
		exit 1
	}
	if [ -z "$DRY" ]; then
		tar cf - $BACKUP_FILES | gzip > $BACKUPDIR/$WE.tar.gz || {
			echo sorry, could not create $BACKUPDIR/$WE.tar.gz
			exit 1
		}
	else
		$DRY "tar cf - $BACKUP_FILES | gzip > $BACKUPDIR/$WE.tar.gz"
	fi
}
revert() {
	[ "$TEST_DIR" ] && return
	test -d $BACKUPDIR || {
		echo sorry, there is no $BACKUPDIR directory
		echo cannot revert
		exit 1
	}
	info "restoring $BACKUP_FILES from $BACKUPDIR/$WE.tar.gz"
	gzip -dc $BACKUPDIR/$WE.tar.gz | (cd / && tar xf -) || {
		echo sorry, could not unpack $BACKUPDIR/$WE.tar.gz
		exit 1
	}
}
pls_press_enter() {
	[ "$TEST_DIR" ] && return
	cat<<EOF

Please press enter to continue or ^C to exit ...
EOF
	read junk
	echo ""
}
introduction() {
	cat<<EOF

This is a Heartbeat to OpenAIS conversion tool.

* IMPORTANT * IMPORTANT * IMPORTANT * IMPORTANT * IMPORTANT *

Please read this and don't proceed before understanding what
we try to do and what is required.

1. You need to know your cluster in detail. This program will
inform you on changes it makes. It is up to you to verify
that the changes are meaningful. We will also probably ask
some questions now and again.

2. This procedure is supposed to be run on one node only.
Although the main cluster configuration (the CIB) is
automatically replicated, there are some things which have to
be copied by other means. For that to work, we need sshd
running on all nodes and root access working.

3. Do not run this procedure on more than one node!
EOF
	pls_press_enter
	cat<<EOF
The procedure consists of two parts: the OpenAIS
configuration and the Pacemaker/CRM CIB configuration.

The first part is obligatory. The second part may be skipped
unless your cluster configuration requires changes due to the
change from Heartbeat to OpenAIS.

We will try to analyze your configuration and let you know
whether the CIB configuration should be changed as well.
However, you will still have a choice to skip the CIB
mangling part in case you want to do that yourself.

The next step is to create the OpenAIS configuration. If you
want to leave, now is the time to interrupt the program.
EOF
	pls_press_enter
}
confirm() {
	while :; do
		printf "$1 (y/n) "
		read ans
		if echo $ans | grep -iqs '^[yn]'; then
			echo $ans | grep -iqs '^y'
			return $?
		else
			echo Please answer with y or n
		fi
	done
}
want_to_proceed() {
	[ "$TEST_DIR" ] && return 0
	confirm "Do you want to proceed?"
}
intro_part2() {
	cat<<EOF

The second part of the configuration deals with the CIB.
According to our analysis (you should have seen some
messages), this step is necessary.
EOF
	want_to_proceed || return
}

gethbmedia() {
	grep "^[bum]cast" $HA_CF
}
pl_ipcalc() {
perl -e '
# stolen from internet!
my $ipaddr=$ARGV[0];
my $nmask=$ARGV[1];
my @addrarr=split(/\./,$ipaddr);
my ( $ipaddress ) = unpack( "N", pack( "C4",@addrarr ) );
my @maskarr=split(/\./,$nmask);
my ( $netmask ) = unpack( "N", pack( "C4",@maskarr ) );
# Calculate network address by logical AND operation of addr &
# netmask
# and convert network address to IP address format
my $netadd = ( $ipaddress & $netmask );
my @netarr=unpack( "C4", pack( "N",$netadd ) );
my $netaddress=join(".",@netarr);
print "$netaddress\n";
' $1 $2
}
get_if_val() {
	test "$1" || return
	awk -v key=$1 '
	{ for( i=1; i<=NF; i++ )
		if( match($i,key) ) {
			sub(key,"",$i);
			print $i
			exit
		}
	}'
}
netaddress() {
	ip=`ifconfig $1 | grep 'inet addr:' | get_if_val addr:`
	mask=`ifconfig $1 | grep 'Mask:' | get_if_val Mask:`
	if test "$mask"; then
		pl_ipcalc $ip $mask
	else
		warning "could not get the network mask for interface $1"
	fi
}

sw=0
do_tabs() {
	for i in `seq $sw`; do printf "\t"; done
}
newstanza() {
	do_tabs
	printf "%s {\n" $1
	sw=$(($sw+1))
}
endstanza() {
	sw=$(($sw-1))
	do_tabs
	printf "}\n"
}
setvalue() {
	name=$1
	val=$2
	test "$val" || {
		warning "sorry, no value set for $name"
	}
	do_tabs
	echo "$name: $val"
}
setcomment() {
	do_tabs
	echo "# $*"
}
setdebug() {
	[ "$HA_LOGLEVEL" = debug ] &&
		echo "on" || echo "off"
}

WE=`uname -n`  # who am i?

if [ "$1" = revert ]; then
	revert
	exit
fi

test -d $BACKUPDIR &&
	fatal "please remove the backup directory: $BACKUPDIR"

prerequisites

introduction

backup_files

unsupported

# 1. Generate the openais.conf

prochbmedia() {
	while read media_type iface address rest; do
		info "Processing interface $iface of type $media_type ..."
		case "$media_type" in
			ucast|bcast) mcastaddr=226.94.1.1 ;;
			mcast) mcastaddr=$address ;;
		esac
		if [ -z "$local_mcastport" ]; then
			local_mcastport="$MCASTPORT"
		fi
		netaddress="`netaddress $iface`"
		if [ "$netaddress" ]; then
			let local_mcastport=$local_mcastport+1
			newportinfo $iface $local_mcastport
			echo "$netaddress" "$mcastaddr" "$local_mcastport"
		else
			warning "cannot process interface $iface!"
		fi
	done
}

openaisconf() {

info "Generating $AIS_CONF from $HA_CF ..."

# the totem stanza

cpunum=`grep -c ^processor /proc/cpuinfo`
setcomment "Generated by hb2openais on `date`"
setcomment "Please read the $AIS_CONF_BASE.5 manual page"

[ "$COROSYNC" ] &&
	setvalue compatibility whitetank

newstanza aisexec
setcomment "Run as root - this is necessary to be able to manage resources with Pacemaker"
setvalue user	root
setvalue group	root
endstanza

newstanza service
setcomment "Load the Pacemaker Cluster Resource Manager"
setvalue name	pacemaker
setvalue ver	0
if uselogd; then
	setvalue use_logd	yes
	important "Make sure that the logd service is started (chkconfig logd on)"
fi
if grep -qs "^respawn.*mgmtd" $HA_CF; then
	setvalue use_mgmtd	yes
fi
endstanza

newstanza totem
setvalue version 2
setcomment "How long before declaring a token lost (ms)"
setvalue token          1000
setcomment "How many token retransmits before forming a new configuration"
setvalue token_retransmits_before_loss_const 20
setcomment "How long to wait for join messages in the membership protocol (ms)"
setvalue join           50
setcomment "How long to wait for consensus to be achieved before"
setcomment "starting a new round of membership configuration (ms)"
setvalue consensus      1200
setcomment "Turn off the virtual synchrony filter"
setvalue vsftype        none
setcomment "Number of messages that may be sent by one processor on receipt of the token"
setvalue max_messages   20
setcomment "Limit generated nodeids to 31-bits (positive signed integers)"
setvalue clear_node_high_bit yes
setcomment "Enable encryption"
setvalue secauth $AUTHENTICATION
if [ "$AUTHENTICATION" = on ]; then
	setvalue threads $cpunum
else
	setvalue threads 0
fi
setcomment "Optionally assign a fixed node id (integer)"
setcomment "nodeid:         1234"
ring=0
gethbmedia | prochbmedia |
sort -u |
while read network addr port; do
	if [ $ring -ge $MAXINTERFACE ]; then
		warning "$PRODUCT supports only $MAXINTERFACE rings!"
		info "consider bonding interfaces"
		warning "skipping communication link on $network"
		setcomment "$network skipped: too many rings"
		continue
	fi
	newstanza interface
	setvalue ringnumber $ring
	setvalue bindnetaddr $network
	netaddrinfo $ring $network
	multicastinfo $ring $addr $port
	setvalue mcastport $port
	setvalue mcastaddr $addr
	ring=$(($ring+1))
	endstanza
done
mediacnt=`gethbmedia 2>/dev/null | prochbmedia 2>/dev/null | sort -u | wc -l`
if [ $mediacnt -ge 2 ]; then
	setvalue rrp_mode $RRP_MODE
fi
changemediainfo
endstanza

# the logging stanza

getlogvars
# enforce some syslog facility
[ "$COROSYNC" ] &&
	TO_FILE=to_logfile ||
	TO_FILE=to_file
debugsetting=`setdebug`
newstanza logging
setvalue debug $debugsetting
setvalue fileline off
setvalue to_stderr no
setvalue timestamp off
if [ "$HA_LOGFILE" ]; then
	setvalue $TO_FILE yes
	setvalue logfile $HA_LOGFILE
else
	setvalue $TO_FILE no
fi
if [ "$HA_LOGFACILITY" ]; then
	setvalue to_syslog yes
	setvalue syslog_facility $HA_LOGFACILITY
else
	setvalue to_syslog no
fi
newstanza logger_subsys
setvalue subsys AMF
setvalue debug $debugsetting
endstanza
endstanza

newstanza amf
setvalue mode disabled
endstanza

}

if [ -z "$DRY" ]; then
	openaisconf > $AIS_CONF ||
		fatal "cannot create $AIS_CONF"
	grep -wqs interface $AIS_CONF ||
		fatal "no media found in $HA_CF"
else
	openaisconf
fi

[ "$AIS_KEYF" ] && {
	info "Generating a key for OpenAIS authentication ..."
	if [ "$TEST_DIR" ]; then
		echo would run: $DRY $KEYGEN_PROG
	else
		$DRY $KEYGEN_PROG ||
			fatal "cannot generate the key using $KEYGEN_PROG"
	fi
}

# remove various files which could get in a way

if [ -z "$TEST_DIR" ]; then
	$DRY rm -f $RM_FILES
fi

fixcibperms() {
	[ "$TEST_DIR" ] && return
	uid=`ls -ldn $CRM_VARLIB | awk '{print $3}'`
	gid=`ls -ldn $CRM_VARLIB | awk '{print $4}'`
	$DRY $MYSUDO chown $uid:$gid $CIB
}
upgrade_cib() {
	$DRY $MYSUDO cibadmin --upgrade --force
	$DRY $MYSUDO crm_verify -V -x $CIB_file
}
py_proc_cib() {
	tmpfile=`maketempfile`
	$MYSUDO sh -c "python $PY_HELPER $* <$CIB >$tmpfile" ||
		fatal "cannot process cib: $PY_HELPER $*"
	$DRY $MYSUDO mv $tmpfile $CIB
}
set_property() {
	py_proc_cib set_property $*
}

# remove the nodes section from the CIB
py_proc_cib set_node_ids
info "Edited the nodes' ids in the CIB"

numnodes=`getnodes | wc -w`
[ $numnodes -eq 2 ] &&
	set_property no-quorum-policy ignore

set_property expected-nodes $numnodes overwrite

info "Done converting ha.cf to $AIS_CONF_BASE"
important "Please check the resulting $AIS_CONF"
important "and in particular interface stanzas and logging."
important "If you find problems, please edit $AIS_CONF now!"
#
# first part done (openais), on to the CIB

analyze_cib() {
	info "Analyzing the CIB..."
	$MYSUDO sh -c "python $PY_HELPER analyze_cib <$CIB"
}
check_respawns() {
	rc=1
	for p in $SUPPORTED_RESPAWNS; do
		grep -qs "^respawn.*$p" $HA_CF && {
			info "a $p resource has to be created"
			rc=0
		}
	done
	return $rc
}

part2() {
	intro_part2 || return 0
	opts="-c $HA_CF"
	[ "$TEST_DIR" ] && opts="-T $opts"
	py_proc_cib $opts convert_cib
	info "Processed the CIB successfully"
}
# make the user believe that something's happening :)
some_dots_idle() {
	[ "$TEST_DIR" ] && return
	cnt=0
	printf "$2 ."
	while [ $cnt -lt $1 ]; do
		sleep 1
		printf "."
		ctn=$((cnt+1))
	done
	echo
}
print_dc() {
	crm_mon -1 | awk '/Current DC/{print $3}'
}
dcidle() {
	dc=`$MYSUDO print_dc`
	if [ "$dc" = "$WE" ]; then
		maxcnt=60 cnt=0
		while [ $cnt -lt $maxcnt ]; do
			stat=`$MYSUDO crmadmin -S $dc`
			echo $stat | grep -qs S_IDLE && break
			[ "$1" = "-v" ] && echo $stat
			sleep 1
			printf "."
			cnt=$((cnt+1))
		done
		echo $stat | grep -qs S_IDLE
	else
		some_dots_idle 10 #just wait for 10 seconds
	fi
}
wait_crm() {
	[ "$TEST_DIR" ] && return
	cnt=10
	dc=""
	while [ -z "$dc" -a $cnt -gt 0 ]; do
		dc=`$MYSUDO print_dc`
		cnt=$((cnt-1))
	done

	if [ x = x"$dc" ]; then
		echo "sorry, no dc found/elected"
		exit 1
	fi
	dcidle
}
manage_cluster() {
	if [ "$TEST_DIR" ]; then
		echo would run: /etc/init.d/openais $1
	else
		$DRY /etc/init.d/openais $1
	fi
}
tune_ocfs2() {
	cat<<EOF
The ocfs2 metadata has to change to reflect the cluster stack
change. To do that, we have to start the cluster stack on
this node.
EOF
	pls_press_enter
	py_proc_cib manage_ocfs2 stop
	manage_cluster start
	some_dots_idle 10 "waiting for crm to start"
	if $DRY wait_crm; then
		for fsdev; do
			info "converting the ocfs2 meta-data on $fsdev"
			if [ "$TEST_DIR" ]; then
				echo would run: tunefs.ocfs2 --update-cluster-stack -y $fsdev
			else
				$DRY tunefs.ocfs2 --update-cluster-stack -y $fsdev
			fi
		done
	else
		fatal "could not start pacemaker; please check the logs"
	fi
	manage_cluster stop
	py_proc_cib manage_ocfs2 start
}
convert_csm() {
	info "converting all EVMS2 CSM containers"
	if [ "$TEST_DIR" ]; then
		echo would run: /usr/sbin/csm-converter --scan
	else
		$DRY /usr/sbin/csm-converter --scan ||
			fatal "CSM conversion failed! Aborting"
	fi
}

analyze_cib
rc=$?
[ $rc -gt 1 ] && fatal "error while analyzing CIB"
if [ $rc -eq 1 ] || check_respawns; then
	part2
else
	info "No need to process CIB further"
fi

# upgrade the CIB to v1.0
if [ "$UPGRADE" ]; then
	upgrade_cib
	info "Upgraded the CIB to v1.0"
else
	info "Skipped upgrading the CIB to v1.0"
	important "You should do this sooner rather than later!"
fi
fixcibperms

convert_csm
ocfs2_devs=`$MYSUDO sh -c "python $PY_HELPER $opts print_ocfs2_devs <$CIB"`
[ "$ocfs2_devs" ] &&
	tune_ocfs2 $ocfs2_devs

[ "$TEST_DIR" ] && exit

$DRY touch $DONE_F

# finally, copy files to all nodes
info "Copying files to other nodes ..."
info "(please provide root password if prompted)"
ssh_opts="-l root $SSH_OPTS"
rc=0
for node in `getnodes`; do
	[ "$node" = "$WE" ] &&
		continue
	if [ "$DRY" ]; then
		$DRY "(cd / && tar cf - $DIST_FILES) |
		ssh $ssh_opts $node \"rm -f $REMOTE_RM_FILES &&
			cd / && tar xf -\""
	else
		echo "Copying to node $node ..."
		(cd / && tar cf - $DIST_FILES) |
		ssh $ssh_opts $node "rm -f $REMOTE_RM_FILES &&
			cd / && tar xf -"
		rc=$(($rc+$?))
	fi
done
info "Done transfering files"
if [ $rc -ne 0 ]; then
	warning "we could not update some ssh nodes"
	important "before starting the cluster stack on those nodes:"
	important "copy and unpack $MAN_TARF (from the / directory)"
	important "and execute: rm -f $REMOTE_RM_FILES"
	(cd / && tar cf - $DIST_FILES | gzip > $MAN_TARF)
fi