[OpenIndiana-discuss] Split-root installations

Kees Nuyt k.nuyt at zonnet.nl
Sat Nov 30 11:52:31 UTC 2013


On Sat, 30 Nov 2013 12:26:38 +0100, you wrote:

>So... I went over the SMF method scripts and their include files,
>and built a diagram of service dependencies involved in networking
>and filesystems leading up to filesystem/local (there are also
>other branches regarding nuances of networking like IPSEC and
>iptun, which are not covered here).


Not a solution, but related:
I found the script below, called "svcstree"
on the interwebs some 3 years ago.

Alas, it only lists service dependencies,
not file and networking dependencies, but
your struggle reminded me of its existence, 
and it could be useful for some people :D

Sorry for hijacking your thread.

Regards,
Kees Nuyt


#!/usr/bin/perl -w

# VERSION = 3.0

### Main ###

use strict;
use warnings;
use diagnostics;
use Getopt::Long qw(:config prefix_pattern=\(-i\) posix_default no_ignore_case);

our @indent = ();    # stores the indent string
our $more = "|   ";  # used this to indent if there are more services
our $last = ".   ";  # used this to indent if this is the last service
our $linenum = 10000;    # page number.  he he he... thats line number!
our %svc;            # by default stores the line number of first occurence
                     # If -u option is provided then it is used to decide when
		     # to print the service.
our ($fmri, $state);
our @tmp = ("error");
my $PROGNAME = "svcstree";
my $SVCS = "/usr/bin/svcs";
my ($h_opt, $man_opt, $d_opt, $D_opt, $l_opt, $u_opt, $m_opt, $s_opt); # options
our $svcs_opts = "-H -o fmri";  # options passed to svcs command

our ($blue, $green, $red, $darkred, $nocolr);  # colour the fmri
our ($startcolr, $endcolr);
$blue = "\033[34m";
$green = "\033[32m";
$red = "\033[31m";
$darkred = "\033[31;1m";
$nocolr = "\033[39;0m";
$startcolr = "";
$endcolr = $nocolr;
 
&usage if (!GetOptions("h"=>\$h_opt,   # help
	   "man"=>\$man_opt,            # print man page
	   "d"=>\$d_opt,               # svcs -d
	   "D"=>\$D_opt,               # svcs -D
	   "l"=>\$l_opt,               # long listing
	   "u"=>\$u_opt,               # unique listing
	   "m"=>\$m_opt,               # expand milestones too
	   "s"=>\$s_opt));             # show state of service/instance

# Parse and verify options
# Give preference to -h if both -h and -man are provided.
# Ignore other options if -h or -man is provided.
($tmp[0] = "-h", &usage) if ($h_opt);
&manpage if ($man_opt);

# Print error message, including usage message on error, to STDERR
select STDERR;

# Options check
if ($d_opt && $D_opt) {
	print "ERROR: Only one of the '-d' or '-D' option can be specified\n\n";
	&usage;
}
if (!$d_opt && !$D_opt) {
	print "ERROR: One of the '-d' or '-D' option must be specified\n\n";
	&usage;
}
if ($l_opt && $u_opt) {
	print "ERROR: Only one of the '-l' or '-u' option can be specified\n\n";
	&usage;
}

# Arguments check
if (@ARGV != 1) {
	print "ERROR: Service name not provided\n\n";
	&usage;
}
@tmp = `$SVCS $svcs_opts $ARGV[0]`;
print "ERROR: The argument \"$ARGV[0]\" matches more than one services/instances\n" if (@tmp > 1);
print "ERROR: The argument \"$ARGV[0]\" does not match any service/instance\n" if (@tmp < 1);
exit 4 if (@tmp != 1);

# Restore output to STDOUT
select STDOUT;

# Get the fmri and if asked, state of service too.
# The first argument has to be printed here.  Otherwise the function will
# not print anything if a milestone is passed as argument.  It also
# prevents an extra unwanted indentation.
$svcs_opts .= ",state" if ($s_opt);
($fmri, $state) = split(' ', `$SVCS $svcs_opts $ARGV[0]`);
&setcolr($state);
print $linenum++, "\t", $startcolr, "$fmri $state\n", $endcolr;

# Set appropriate svcs option
$svcs_opts .= " -d" if ($d_opt); 
$svcs_opts .= " -D" if ($D_opt);
&showdep(`$SVCS $svcs_opts $ARGV[0]`);
exit 0;

### Functions ###

# Prints the list of FMRIs passed in a loop.  Finds its dependent/supporting
# services and recurses on them.
# The argument is a list of services.  If -s option is provided then every
# line has two part: service and its state.
sub showdep {
	# If -u option is provided, increment the hit count of this service
	if ($u_opt) {
		my $entry;
		foreach $entry (@_) {
			chomp ($entry);
			$svc{"$entry"} += 1;
		}
	}
	while(@_){
		chomp (my $i = shift(@_));

		# Set state
		($fmri, $state) = split(' ', $i) if($s_opt);

		# Set state to null string if -s not provided.
		($fmri = $i, $state = "") if(!$s_opt);

		# If the hit count of a service is not zero, continue.  If
		# the hit count is zero, then print it.  Also set the hit
		# count to a large value so that it does not come down to
		# zero again.
		if ($u_opt) {
			$svc{"$fmri"} -= 1;
			next if ($svc{"$fmri"} > 0);
			$svc{"$fmri"} = 10000000000;
		}

		# Set color for state
		&setcolr($state);

		# Default action: (without -l and -u).
		# If service already printed, then print it again along
		# with the line number where it was first printed and skip.
		if (!$l_opt && !$u_opt && $svc{"$fmri"}) {
			print $linenum++, "\t", join("", @indent), "+-->",
			    $startcolr,
			    "$fmri $state <line#:$svc{\"$fmri\"}>\n", $endcolr;
			next;
		}

		# Print the service.
		print $linenum, "\t", join("", @indent), "+-->", $startcolr,
		    "$fmri $state\n", $endcolr;

		# Do not expand a milestone's tree.
		($linenum++, next) if (!$m_opt && index($fmri, "milestone") >= 0);

		# Save the line number if NOT a leaf service.
		my @nextdep = `$SVCS $svcs_opts $fmri`;
		$svc{"$fmri"} = $linenum if (@nextdep != 0 && !$u_opt);
		$linenum++;

		if (@_ > 0) {
			push(@indent, $more);
		} else {
			push(@indent, $last);
		}

		# Get dependent/supporting services and recursively print.
		&showdep(@nextdep);

		pop(@indent);
	}
}

# Set startcolr based on the state of the service
sub setcolr {

	chomp (my $i = shift(@_));

	$startcolr = $blue if ($i =~ /online/);
	$startcolr = $green if ($i =~ /disabled/);
	$startcolr = $red if ($i =~ /offline/);
	$startcolr = $darkred if ($i =~ /maintenance/);
}

# Prints usage message and exits
sub usage {
	print "    Usage: $PROGNAME <-d|-D>|<-h>|<-man> [-l|-u] [-m] [-s] <fmri>
	-d : print the services tree on which the given service depends.
	     Cannot be used with -D.
	-D : print the services tree which depend on this service.
	     Cannot be used with -d.
	-l : long listing.  Except milestones.
	-u : unique listing.  Except milestones.
	-m : expand milestones too.  Default is not to expand milestones
	-s : show the state of the service/instance.
	-h : print this help message.
	-man : show the man page. (pipe the output to more(1) or less(1)).
	<fmri> : a unique service name\n\n";

	exit 0 if ($tmp[0] eq "-h");
	exit 2;
}

# Prints the man page and exits
sub manpage {
	print "
NAME
     $PROGNAME - program to dump the dependendent or supporting tree of
     a service.

SYNOPSIS
     Usage: $PROGNAME <-d|-D>|<-h>|<-man> [-l|-u] [-m] [-s] <fmri>

DESCRIPTION
     The $PROGNAME program prints a tree of dependent services or
     supporting services of the given service.  It can even report the
     status of each service.

     While printing the tree, the line is prepended with a '|' in the
     appropritate column if there are more dependent/supporting services or
     with a '.' if this is the last one.  This helps in interpreting very
     long trees.

     Also, every line has a line number at its beginning.  A repeating
     service, by default, is not expanded.  Instead it is printed along
     with the line number where it was first expanded.  This is similar to
     the behaviour of cflow(1).  Line numbers of leaf services in the tree
     are not printed.

OPTIONS

     -d    Prints the tree of servies on which the given service depends.
	   This  uses the -d  option  of  svcs(1).  The output is indented
	   based on the  level of dependency.  This option cannot be used
	   with -D option.

     -D    Prints the tree of services which depend on given service.  This
	   uses the -D option of svcs(1).  The output is indendented based
	   on the level of dependency.  This option cannot be used with -d
	   option.

     -h    Prints the usage message.  If this option is present, then all
           other options are ignored.

     -l    Long listing.  This option expands the service even if it was
	   expanded earlier.  This option cannot be used with -u option.
	   See -m option also.

     -m    By default a milestone is not expanded.  Even if -l or -u option
	   is provied. This option expands milestones too.  This option can
	   be used when you really want to expand a milestone.  Note that
	   if a milestone service is provided at the command line, then it
	   is expanded even without this option.  But to expand its
	   dependent/supporting milestones, this option is required.

     -man  Prints this manual page.  If this option is present, then all
           other options are ignored.  The -h option has a higer precedence
	   over this option.  Pipe the output to a PAGER like more(1) or
	   less(1) for a  convinient read.

     -s    Prints the current stauts of each service.

     -u    Unique listing.  This option does not print any recurring
	   services and instead shows a unique listing of the
	   dependent/supporting services tree.  This options helps the best
	   in understanding the dependencies.  See -m option also.

     Providing both -m and -l option on a top node shows the full tree.
     But this could be a veeeeeeeery long list taking forever to print.
     Note that the top node could be different based on -d or -D option.

     Providing both -m and -u option prints the full list of services that
     depend on or support the given service.

     -u option lists all the direct dependent/supporting services of the
     first service.  The second level of services is printed only if it did
     not appear in the first level.  The third level of service is printed
     only if it did not appear in the first and second level and so on.
     This output format is easy to understand and also maintains the
     format.

     All output is printed to STDOUT and all error messages to STDERR.  The
     usage message is also printed to the STDERR if there is an error.  If
     -h option is provided, the the usage message is printed to STDOUT.

OPERANDS

     fmri  The unique service name.  This name should match a unique name
	   in the 'svcs -a' output.  Regular expression is accepted as long
	   as they match a unique entry.  If this matches more than one
	   service or none of the services then the program exits with an
	   error.

EXIT STATUS
     The following exit values are returned:

     0       Successful program execution

     2       Invalid command line options

     4       Incorrect operand

     Print the usage message due to -h or -man option is considered
     successful operation and the exit code is 0.  If the usage message is
     printed due to an error, then the exit code would either 2 of 4,
     depending on the type of the error.

SEE ALSO
     svcs(1), smf(5), cflow(1)

COMMENTS and FEEDBACK
     jayakara.kini\@gmail.com

";

	exit 0;
} 


-- 
Groet, Cordialement, Pozdrawiam, Regards,

Kees Nuyt




More information about the OpenIndiana-discuss mailing list