LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Debian
User Name
Password
Debian This forum is for the discussion of Debian Linux.

Notices


Reply
  Search this Thread
Old 05-19-2013, 08:50 AM   #16
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled

uname -a

Code:
Linux lenny 3.2.0-4-686-pae #1 SMP Debian 3.2.41-2 i686 GNU/Linux
/var/lib/dpkg/info/linux-headers-3.2.0-4-686-pae.postinst

Code:
#! /usr/bin/perl
#
use strict;
use warnings;
use Cwd 'abs_path';
use Debconf::Client::ConfModule qw(:all);
use POSIX ();
version('2.0');
my $capb = capb('backup', 'escape');

$|=1;

# Predefined values:
my $version           = "3.2.0-4-686-pae";
my $link_in_boot      = "";
my $no_symlink        = "";
my $do_symlink        = "Yes";  # target machine defined
my $kimage            = "vmlinuz";
my $initrd            = "YES";        # initrd kernel
my $mkimage           = "";     # command to generate the initrd image
my $use_hard_links    = ''; # hardlinks do not work across fs boundaries
my $postinst_hook     = '';          #Normally we do not
my $minimal_swap      = '';          # Do not swap symlinks
my $ignore_depmod_err = '';          # normally we do not
my $kernel_arch       = "x86";
my $ramdisk           = '';
my $package_name      = "linux-image-$version";

#known variables
my $image_dest      = "/";
my $realimageloc    = "/boot/";
my $have_conffile   = "";

my $modules_base    = '/lib/modules';
my $CONF_LOC        = '/etc/kernel-img.conf';

# Ignore all invocations except when called on to configure.
exit 0 unless $ARGV[0] =~ /configure/;

my $DEBUG = 0;

# Do some preliminary sanity checks here to ensure we actually have an
# valid image dir
chdir('/')           or die "could not chdir to /:$!\n";
die "Internal Error: ($realimageloc) is not a directory!\n"
  unless -d $realimageloc;

if (-r "$CONF_LOC" && -f "$CONF_LOC"  ) {
  if (open(CONF, "$CONF_LOC")) {
    while (<CONF>) {
      chomp;
      s/\#.*$//g;
      next if /^\s*$/;

      $do_symlink      = "" if /do_symlinks\s*=\s*(no|false|0)\s*$/i;
      $no_symlink      = "" if /no_symlinks\s*=\s*(no|false|0)\s*$/i;
      $link_in_boot    = "" if /link_in_boot\s*=\s*(no|false|0)\s*$/i;
      $use_hard_links  = '' if /use_hard_links\s*=\s*(no|false|0)\s*$/i;
      $minimal_swap    = '' if /minimal_swap\s*=\s*(no|false|0)\s*$/i;
      $ignore_depmod_err = '' if /ignore_depmod_err\s*=\s*(no|false|0)\s*$/i;

      $do_symlink      = "Yes" if /do_symlinks\s*=\s*(yes|true|1)\s*$/i;
      $no_symlink      = "Yes" if /no_symlinks\s*=\s*(yes|true|1)\s*$/i;
      $link_in_boot    = "Yes" if /link_in_boot\s*=\s*(yes|true|1)\s*$/i;
      $use_hard_links  = "Yes" if /use_hard_links\s*=\s*(yes|true|1)\s*$/i;
      $minimal_swap    = 'Yes' if /minimal_swap\s*=\s*(yes|true|1)\s*$/i;
      $ignore_depmod_err = 'Yes' if /ignore_depmod_err\s*=\s*(yes|true|1)\s*$/i;

      $image_dest      = "$1"  if /image_dest\s*=\s*(\S+)/i;
      $postinst_hook   = "$1"  if /postinst_hook\s*=\s*(\S+)/i;
      $mkimage         = "$1"  if /mkimage\s*=\s*(.+)$/i;
      $ramdisk         = "$1"  if /ramdisk\s*=\s*(.+)$/i;
    }
    close CONF;
    $have_conffile = "Yes";
  }
}


if ($link_in_boot) {
  $image_dest = $realimageloc;
}

# Tack on at least one trainling /
$image_dest = "$image_dest/";
$image_dest =~ s|^/*|/|o;
$image_dest =~ s|/+$|/|o;

if (! -d "$image_dest") {
  die "Expected Image Destination dir ($image_dest) to be a valid directory!\n";
}

# sanity
if ($do_symlink && $no_symlink) {
  warn "Both do_symlinks and no_symlinks options enabled; disabling no_symlinks\n";
  $no_symlink = 0;
}

# most of our work is done in $image_dest (nominally /)
chdir("$image_dest") or die "could not chdir to $image_dest:$!\n";

$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch;


die "Internal Error: Could not find image (" . $realimageloc
  . "$kimage-$version)\n" unless -e $realimageloc
  . "$kimage-$version";


######################################################################
######################################################################
###########        Test whether a relative symlinkwould be OK #######
######################################################################
######################################################################
sub test_relative {
  my %params = @_;
  my $cwd;

  die "Internal Error: Missing Required paramater 'Old Dir' "
    unless $params{'Old Dir'};
  die "Internal Error: Missing Required paramater New Dir' "
    unless $params{'New Dir'};


  die "Internal Error: No such dir $params{'Old Dir'} "
    unless -d $params{'Old Dir'};
  die "Internal Error: No such dir $params{'New Dir'} "
    unless -d $params{'New Dir'};

  warn "Test relative: testing $params{'Old Dir'} -> $params{'New Dir'}"
    if $DEBUG;
  chomp($cwd = `pwd`);
  chdir ($params{'New Dir'}) or die "Could not chdir to $params{'New Dir'}:$!";
  my $ok = 0;
  $params{'Old Dir'}  =~ s|^/*||o;
  if (-d $params{'Old Dir'} ) {
    if (defined $params{'Test File'}) {
      if (-e $params{'Old Dir'} . $params{'Test File'}) {
        $ok  = 1;
      }
    } else {
      $ok = 1;                  # well, backward compatibility
    }
  }
  chdir ($cwd) or die "Could not chdir to $params{'New Dir'}:$!";
  return $ok;
}


sub spath {
  my %params = @_;

  die "Missing Required paramater 'Old'" unless $params{'Old'};
  die "Missing Required paramater 'New'" unless  $params{'New'};

  my @olddir  = split '/', `readlink -q -m $params{'Old'}`;
  my @newdir  = split '/', `readlink -q -m $params{'New'}`;
  my @outdir  = @olddir;

  my $out = '';
  my $i;
  for ($i = 0; $i <= $#olddir && $i <= $#newdir; $i++) {
    $out++ if ($olddir[$i] ne $newdir[$i]);
    shift @outdir unless $out;
    unshift @outdir, ".." if $out;
  }
  if ($#newdir > $#olddir) {
    for ($i=0; $i < $#newdir; $i++) {
      unshift @outdir, "..";
    }
  }
  return join ('/', @outdir);
}

# This routine is invoked if there is a symbolic link in place
# in $image_dest/$kimage -- so a symlink exists in the destination.
# What we are trying to determine is if we need to move the symbolic link over
# to the the .old location
sub move_p {
  my $kimage     = $_[0];       # Name of the symbolic link
  my $image_dest = $_[1];       # The directory the links goes into
  my $image_name = $_[2]; 
  my $src_dir    = $_[3]; 
  my $force_move = 0;
  warn "Move?: kimage=$kimage, image_dest=$image_dest, \n" .
    "\timage_name=$image_name, src_dir=$src_dir" if $DEBUG;

  if ($no_symlink) {
    # we do not want links, yet we have a symbolic link here!
    warn "found a symbolic link in " . $image_dest . "$kimage \n" .
      "even though no_symlink is defined\n" if $no_symlink;
    # make sure we change this state of affairs
    $force_move = 1;
    return $force_move;
  }

  warn "DEBUG: OK. We found symlink, and we should have a symlink here.\n"
    if $DEBUG;
  my $vmlinuz_target = readlink "$kimage";
  my $real_target = '';
  my $target = `readlink -q -m "${realimageloc}${kimage}-$version"`;
  $real_target = abs_path($vmlinuz_target) if defined($vmlinuz_target);

  if (!defined($vmlinuz_target) || ! -f "$real_target") {
    # what, a dangling symlink?
    warn "The link "  . $image_dest . "$kimage is a dangling link" .
      "to $real_target\n";
    $force_move = 1;
    return $force_move;
  }


  warn "DEBUG: The link $kimage points to ($vmlinuz_target)\n" if $DEBUG;
  warn "DEBUG: ($vmlinuz_target) is really ($real_target)\n" if $DEBUG;
  my $cwd;
  chomp ($cwd=`pwd`);
  if ($vmlinuz_target !~ m|^/|o) {
    $vmlinuz_target = $cwd . "/" . $vmlinuz_target;
    $vmlinuz_target =~ s|/+|/|o;
  }
  $vmlinuz_target = `readlink -q -m $vmlinuz_target`;

  if ("$vmlinuz_target" ne "$target") {
    warn "DEBUG: We need to handle this.\n" if $DEBUG;
    if ($minimal_swap) {
      warn "DEBUG: Minimal swap.\n" if $DEBUG;
      if (-l "$kimage.old") {
        warn "DEBUG: There is an old link at $kimage.old\n" if $DEBUG;
        my $old_target = readlink "$kimage.old";
        my $real_old_target = '';
        $real_old_target=abs_path($old_target) if defined ($old_target);

        if ($real_old_target  && -f "$real_old_target") {
          if ($old_target !~ m|^/|o) {
            $old_target = $cwd . "/" . $old_target;
            $old_target =~ s|/+|/|o;
          }
          $old_target = `readlink -q -m $old_target`;
          if ("$old_target"  ne "$target") {
            $force_move = 1;
            warn "DEBUG: Old link ($old_target) does not point to us ($target)\n"
              if $DEBUG;
          } 
          else {            # The .old points to the current
            warn "$kimage.old --> $target -- doing nothing";
            $force_move = 0;
          }
        } 
        else { 
          warn "DEBUG: Well, the old link does not exist -- so we move\n"
            if $DEBUG;
          $force_move = 1;
        }
      } 
      else {
        warn "DEBUG: No .old link -- OK to move\n"
          if $DEBUG;
        $force_move = 1;
      }
    } 
    else {
      warn "DEBUG: ok, minimal swap is no-- so we move.\n"
        if $DEBUG;
      $force_move = 1;
    }
  }
  else {                  # already have proper link
    warn "$kimage($vmlinuz_target) points to $target ($real_target) -- doing nothing";
    $force_move = 0;
  }
  return $force_move;
}


# This routine moves the symbolic link around (/vmlinuz -> /vmlinuz.old)
# It pays attention to whether we should the fact whether we should be using
# hard links or not.
sub really_move_link {
  my $kimage     = $_[0];       # Name of the symbolic link
  my $image_dest = $_[1];       # The directory the links goes into
  my $image_name = $_[2]; 
  my $src_dir    = $_[3]; 
  warn "really_move_link: kimage=$kimage, image_dest=$image_dest\n" .
    "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;

  # don't clobber $kimage.old quite yet
  rename("$kimage", "$kimage.$$") ||
    die "failed to move " . $image_dest . "$kimage:$!";
  my $Old = $src_dir;
  my $cwd;

  chomp($cwd=`pwd`);
  if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd,
                     'Test File' => "$image_name")) {
    $Old   =~ s|^/*||o;
  }
  # Special case is they are in the same dir
  my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" );
  $Old ="" if $rel_path =~ m/^\s*$/o;

  if ($use_hard_links =~ m/YES/i) {
    if (! link("${Old}${image_name}", "$kimage")) {
      rename("$kimage.$$", "$kimage");
      die("Failed to link ${Old}${image_name} to " .
          "${image_dest}${kimage}.\n");
    }
  } 
  else {
    if (! symlink("${Old}${image_name}", "$kimage")) {
      rename("$kimage.$$", "$kimage");
      die("Failed to symbolic-link ${Old}${image_name} to " .
          "${image_dest}${kimage}.\n");
    }
  }

  # Ok, now we may clobber the previous .old file
  if (-l "$kimage.old" || ! -e "$kimage.old" ) {
    rename("$kimage.$$", "$kimage.old");
  }
  else {
    warn "$kimage.old is not a symlink, not clobbering\n";
    warn "rm $kimage.$$";
  }
}

# This routine handles a request to do symlinks, but there is no
# symlink file already there.  Either we are supposed to use copy, or we are
# installing on a pristine system, or the user does not want symbolic links at
# all.  We use a configuration file to tell the last two cases apart, creating
# a config file if needed.
sub handle_missing_link {
  my $kimage     = $_[0];       # Name of the symbolic link
  my $image_dest = $_[1];       # The directory the links goes into
  my $image_name = $_[2]; 
  my $src_dir    = $_[3]; 
  warn "handle_missing_link: kimage=$kimage, image_dest=$image_dest\n" .
    "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;

  if ($no_symlink) {
    my $ret = system("cp -a --backup=t " . $realimageloc .
                     "$image_name "   . " $kimage");
    if ($ret) {
      die("Failed to copy " . $realimageloc . "$image_name to "
          . $image_dest . "$kimage .\n");
    }
  }

  if (! $no_symlink && $do_symlink =~ /Yes/i) {
    my $Old = $realimageloc;
    my $New = $image_dest;
    my $Name = "$image_name";
    my $Link_Dest = "$kimage";

    if (test_relative ('Old Dir' => $Old,
                       'New Dir' => $New,
                       'Test File' => $Name)) {
      $Old   =~ s|^/*||o;
    }
    # Special case is they are in the same dir
    my $rel_path = spath('Old' => "$Old", 'New' => "$New" );
    $Old ="" if $rel_path =~ m/^\s*$/o;

    symlink($Old . "$Name", "$Link_Dest") ||
      die("Failed to symbolic-link ${Old}$Name to $Link_Dest.\n");

  }
}

# This routine handles the rest of the cases, where the user has requested 
# non-traditional handling, like using cp or hard links.
sub handle_non_symlinks {
  my $kimage     = $_[0];       # Name of the symbolic link
  my $image_dest = $_[1];       # The directory the links goes into
  my $image_name = $_[2]; 
  my $src_dir    = $_[3]; 
  warn "handle_non_link: kimage=$kimage, image_dest=$image_dest\n" .
    "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;

  # Save the current image. We do this in all four cases
  rename("$kimage", "$kimage.$$") || 
    die "failed to move " . $image_dest . "$kimage:$!";

  ##,#### 
  # case One
  #`####
  if ($no_symlink) {
    # Maybe /$image_dest is on a dos system?
    my $ret = system("cp -a --backup=t " . $realimageloc
                     . "$image_name " . "$kimage");
    if ($ret) {
      if (-e "$kimage.$$") {
        rename("$kimage.$$", "$kimage");
      }
      die("Failed to copy " . $realimageloc . "$image_name to "
          . $image_dest . "$kimage .\n");
    }
  }
  ##,#### 
  # case Two
  #`####
  elsif ($use_hard_links =~ m/YES/i ) {
    # Ok then. this ought to be a hard link, and hence fair game
    # don't clobber $kimage.old quite yet
    my $Old = $realimageloc;
    my $cwd;
    chomp($cwd=`pwd`);
    if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd,
                       'Test File' => "$image_name")) {
      $Old   =~ s|^/*||o;
    }
    # Special case is they are in the same dir
    my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" );
    $Old ="" if $rel_path =~ m/^\s*$/o;

    if (! link($Old . "$image_name", "$kimage")) {
      rename("$kimage.$$", "$kimage");
      die("Failed to hard link " . $realimageloc . "$image_name to "
          . $image_dest . "$kimage .\n");
    }
  }
  ##,####
  # case Three
  #`####
  else {
    # We just use cp
    my $ret = system("cp -a --backup=t " . $realimageloc
                     . "$image_name " . "$kimage");
    if ($ret) {
      if (-e "$kimage.$$") {
        rename("$kimage.$$", "$kimage");
      }
      die("Failed to copy " . $realimageloc . "$image_name to "
          . $image_dest . "$kimage .\n");
    }
  }
  # Ok, now we may clobber the previous .old file
  rename("$kimage.$$", "$kimage.old") if -e "$kimage.$$";
}

# This routine is responsible for setting up the symbolic links
# So, the actual kernel image lives in
# $realimageloc/$image_name (/boot/vmlinuz-2.6.12).
# This routine creates symbolic links in $image_dest/$kimage (/vmlinuz)
sub image_magic {
  my $kimage     = $_[0];       # Name of the symbolic link
  my $image_dest = $_[1];       # The directory the links goes into
  my $image_name = "$kimage-$version";
  my $src_dir    = $realimageloc;
  warn "image_magic: kimage=$kimage, image_dest=$image_dest\n" .
    "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG;

  if (-l "$kimage") {           # There is a symbolic link
    warn "DEBUG: There is a symlink for $kimage\n" if $DEBUG;
    my $force_move = move_p($kimage, $image_dest, $image_name, $src_dir);

    if ($force_move) {
      really_move_link($kimage, $image_dest, $image_name, $src_dir);
    }
  }
  elsif (! -e "$kimage") {
    # Hmm. Pristine system? How can that be? Installing from scratch?
    # Or maybe the user does not want a symbolic link here.
    # Possibly they do not want a link here. (we should be in /
    # here[$image_dest, really]
    handle_missing_link($kimage, $image_dest, $image_name, $src_dir);
  }
  elsif (-e "$kimage" ) {
    # OK, $kimage exists -- but is not a link
    handle_non_symlinks($kimage, $image_dest, $image_name, $src_dir);
  }
}

######################################################################
######################################################################
######################################################################
######################################################################

sub do_modules {
  print STDERR "Running depmod.\n";
  my $ret = system("depmod -a -F $realimageloc/System.map-$version $version");
  my $exit_value  = $? >> 8;
  my $signal_num  = $? & 127;
  my $dumped_core = $? & 128;
  if ($ret) {
    my $seen;
    my $answer;
    my $question;
    $question = "${package_name}/postinst/depmod-error-initrd-$version";

    ($ret,$seen) = fset ("$question", 'seen', 'false');
    die "Error setting debconf flags in $question: $seen" if $ret;

    $ret = subst("$question", 'modules_base', "$modules_base");
    die "Error setting debconf substitutions in $question: $seen" if $ret;

    $ret = subst("$question", 'SIGNAL', ", and got a signal $signal_num");
    die "Error setting debconf substitutions in $question: $seen" if $ret;

    if ($dumped_core) {
      $ret = subst("$question", 'CORE', ", and dumped core");
      die "Error setting debconf substitutions in $question: $seen" if $ret;
    }
    else {
      $ret = subst("$question", 'CORE', " ");
      die "Error setting debconf substitutions in $question: $seen" if $ret;
    }

    ($ret,$seen) = input('medium', "$question");
    if ($ret && $ret != 30 ) {
      die "Error setting debconf question $question: $seen";
    }

    ($ret,$seen) = go ();
    if ($ret && $ret != 30 ) {
      die "Error asking debconf question $question: $seen";
    }

    ($ret,$answer) = get("$question");
    die "Error retreiving answer for $question: $answer" if $ret;

    if (! $ignore_depmod_err) {
      if ($answer =~ /^(y|t)/i) {
        exit(1);
      }
      else {
        print STDERR "Ok, continuing as directed\n";
      }
    }
  }

  # If we are installing (not upgrading) a package for a newer
  # upstream version than that of the running kernel, check whether
  # the user might be missing necessary firmware, perhaps because
  # it has now been removed from the kernel.
  #
  # We base this check on the modules used in the running kernel and
  # the corresponding (by name) modules in the new kernel.  This is
  # not entirely accurate because:
  # 1. A device may now be handled by a module with a different name,
  #    leading us to miss the dependency
  # 2. A device may be handled by a module that needs firmware only
  #    for some other device, leading us to claim a dependency wrongly

  if (!defined($ARGV[1]) || $ARGV[1] eq '') {
    sub version_code {
      my $version = shift;
      $version =~ s/^2\.(\d+)\.(\d+).*/2*65536 + $1*256 + $2/e
	or $version =~ s/^(\d+)\.(\d+).*/$1*65536 + $2*256/e
	or $version = 0;
      return $version;
    }
    (undef, undef, my $running_version) = POSIX::uname();

    if (version_code($version) > version_code($running_version)) {
      my $missing = '';
      my %module_paths;
      open(DEP, "<$modules_base/$version/modules.dep") or return;
      while (<DEP>) {
	if (m|(.*/([^/]*)\.ko):|) {
	  my ($path, $module) = ($1, $2);
	  $module =~ s/-/_/g;
	  $module_paths{$module} = $path;
	}
      }
      close(DEP);
      open(MODULES, '</proc/modules') or return;
      while (<MODULES>) {
	s/ .*//s;
	my $module = $_;
	my $module_path = $module_paths{$module};
	if (defined($module_path)) {
	  my $first = 1;
	  if ($module_path !~ m|^/|) {
	    $module_path = "$modules_base/$version/$module_path";
	  }
	  open(MODINFO, "modinfo -F firmware '$module_path' |");
	  while (<MODINFO>) {
	    chomp;
	    my $firmware = $_;
	    unless (-e "/lib/firmware/$firmware" ||
		    -e "/lib/firmware/$version/$firmware") {
	      if ($first) {
		$missing .= "\\n" if $missing ne '';
		$missing .= "$module: ";
		$first = 0;
	      } else {
		$missing .= ', ';
	      }
	      $missing .= $firmware;
	    }
	  }
	  close(MODINFO);
	}
      }
      close(MODULES);

      if ($missing ne '') {
	my ($ret, $seen);
	my $text = "${package_name}/postinst/missing-firmware-${version}";

	($ret, $seen) = subst($text, 'runningversion', $running_version);
	die "Error setting debconf substitutions in $text: $seen" if $ret;

	($ret, $seen) = subst($text, 'version', $version);
	die "Error setting debconf substitutions in $text: $seen" if $ret;

	($ret, $seen) = subst($text, 'missing', $missing);
	die "Error setting debconf substitutions in $text: $seen" if $ret;

	($ret, $seen) = input('high', $text);
	if ($ret && $ret != 30) {
	  die "Error setting debconf question $text: $seen";
	}

	($ret, $seen) = go();
	if ($ret && $ret != 30) {
	  die "Error asking debconf question $text: $seen";
	}
      }
    }
  }
}

# We may not have any modules installed
if (-d "$modules_base/$version") {
  &do_modules();
}


# Warn if we are ignoring the old ramdisk setting
if ($ramdisk =~ /\S/) {
    my ($question, $ret, $seen);
    $question = "${package_name}/postinst/ignoring-ramdisk";
    ($ret,$seen) = input('high', "$question");
    die "Error setting debconf question $question: $seen" if $ret && $ret != 30;
    ($ret,$seen) = go();
    die "Error asking debconf question $question: $seen" if $ret && $ret != 30;
}

# Only change the symlinks if we are not being upgraded
if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m/<unknown>/o) {
  image_magic($kimage, $image_dest);
  if ($initrd) {
    image_magic("initrd.img", $image_dest);
  }
}
else {
  if (! -e "$kimage") {
    handle_missing_link($kimage, $image_dest, "$kimage-$version", 
                        $realimageloc);
  }
  if ($initrd && ! -e "initrd.img") {
    handle_missing_link("initrd.img", $image_dest, "initrd.img-$version",
			$realimageloc);
  }
}

# set the env var stem
$ENV{'STEM'} = "linux";
sub run_hook {
  my $type   = shift;
  my $script = shift;

  print STDERR "Running $script.\n";
  system ("$script $version $realimageloc$kimage-$version") &&
    print STDERR "User $type hook script [$script] ";
  if ($?) {
    if ($? == -1) {
      print STDERR "failed to execute: $!\n";
    }
    elsif ($? & 127) {
      printf STDERR "died with signal %d, %s coredump\n",
        ($? & 127),  ($? & 128) ? 'with' : 'without';
    }
    else {
      printf STDERR "exited with value %d\n", $? >> 8;
    }
    exit $? >> 8;
  }
}

my $options;
for (@ARGV) {
	s,','\\'',g;
	$options .= " '$_'";
}
$ENV{'DEB_MAINT_PARAMS'}="$options";

## Run user hook script here, if any
if ($postinst_hook) {
  &run_hook("postinst", $postinst_hook);
}

if (-d "/etc/kernel/postinst.d") {
  print STDERR "Examining /etc/kernel/postinst.d.\n";
  system ("run-parts --verbose --exit-on-error --arg=$version " .
          "--arg=$realimageloc$kimage-$version " .
          "/etc/kernel/postinst.d") &&
            die "Failed to process /etc/kernel/postinst.d";
}

if (-d "/etc/kernel/postinst.d/$version") {
  print STDERR "Examining /etc/kernel/postinst.d/$version.\n";
  system ("run-parts --verbose --exit-on-error --arg=$version " .
          "--arg=$realimageloc$kimage-$version " .
          "/etc/kernel/postinst.d/$version") &&
            die "Failed to process /etc/kernel/postinst.d/$version";
}

exit 0;

__END__
I will try the other after Church this evening....
 
Old 05-19-2013, 11:55 AM   #17
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled
I did the first package and from what I can see it installed ok except for perhaps this one line;

"D000002: vmaintainer_script_installed nonexistent postinst"

Is this line telling me something?

Code:
dpkg --debug=2 -i /var/cache/apt/archives/linux-headers-3.2.0-4-common_3.2.41-2+deb7u2_i386.deb
Code:
root@lenny:/var/cache/apt/archives# dpkg --debug=2 -i /var/cache/apt/archives/linux-headers-3.2.0-4-common_3.2.41-2+deb7u2_i386.deb
Selecting previously unselected package linux-headers-3.2.0-4-common.
(Reading database ... 131885 files and directories currently installed.)
Unpacking linux-headers-3.2.0-4-common (from .../linux-headers-3.2.0-4-common_3.2.41-2+deb7u2_i386.deb) ...
D000002: maintainer_script_new nonexistent preinst '/var/lib/dpkg/tmp.ci/preinst'
D000002: process_archive tmp.ci script/file '..' contains dot
D000002: process_archive tmp.ci script/file '.' contains dot
D000002: process_archive tmp.ci script/file '/var/lib/dpkg/tmp.ci/md5sums' installed as '/var/lib/dpkg/info/linux-headers-3.2.0-4-common.md5sums'
D000002: process_archive tmp.ci script/file '/var/lib/dpkg/tmp.ci/control' is control
Setting up linux-headers-3.2.0-4-common (3.2.41-2+deb7u2) ...
D000002: vmaintainer_script_installed nonexistent postinst
root@lenny:/var/cache/apt/archives#
 
Old 05-19-2013, 12:02 PM   #18
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled
Right or not the error is correct, these are my postinst scripts. As you can see, the skip past headers.

Quote:
/var/lib/dpkg/info/links2.postinst
/var/lib/dpkg/info/linux-base.postinst
/var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.postinst
/var/lib/dpkg/info/linux-support-3.2.0-4.postinst
/var/lib/dpkg/info/linux-tools-3.2.postinst
/var/lib/dpkg/info/liquidsoap.postinst
/var/lib/dpkg/info/lm-sensors.postinst
 
Old 05-19-2013, 12:18 PM   #19
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled
This is the second package... This doesn't look so good but if I'm reading it right it says I need to install linux-headers-3.2.0-4-686-pae first.

Code:
dpkg --debug=2 -i /var/cache/apt/archives/linux-headers-686-pae_3.2+46_i386.deb
Code:
root@lenny:/var/cache/apt/archives# dpkg --debug=2 -i /var/cache/apt/archives/linux-headers-686-pae_3.2+46_i386.deb
Selecting previously unselected package linux-headers-686-pae.
(Reading database ... 135002 files and directories currently installed.)
Unpacking linux-headers-686-pae (from .../linux-headers-686-pae_3.2+46_i386.deb) ...
D000002: maintainer_script_new nonexistent preinst '/var/lib/dpkg/tmp.ci/preinst'
D000002: process_archive tmp.ci script/file '..' contains dot
D000002: process_archive tmp.ci script/file '.' contains dot
D000002: process_archive tmp.ci script/file '/var/lib/dpkg/tmp.ci/md5sums' installed as '/var/lib/dpkg/info/linux-headers-686-pae.md5sums'
D000002: process_archive tmp.ci script/file '/var/lib/dpkg/tmp.ci/control' is control
dpkg: dependency problems prevent configuration of linux-headers-686-pae:
 linux-headers-686-pae depends on linux-headers-3.2.0-4-686-pae; however:
  Package linux-headers-3.2.0-4-686-pae is not installed.

dpkg: error processing linux-headers-686-pae (--install):
 dependency problems - leaving unconfigured
Errors were encountered while processing:
 linux-headers-686-pae
root@lenny:/var/cache/apt/archives#
 
Old 05-19-2013, 12:23 PM   #20
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled
This is the third package, linux-headers-3.2.0-4-686-pae_3.2.41-2+deb7u2_i386.deb. I did it last and as expected it froze with the below. Is there another log I can peak in that might give more information?

Code:
root@lenny:/var/cache/apt/archives# dpkg --debug=2 -i /var/cache/apt/archives/linux-headers-3.2.0-4-686-pae_3.2.41-2+deb7u2_i386.deb
Selecting previously unselected package linux-headers-3.2.0-4-686-pae.
(Reading database ... 135005 files and directories currently installed.)
Unpacking linux-headers-3.2.0-4-686-pae (from .../linux-headers-3.2.0-4-686-pae_3.2.41-2+deb7u2_i386.deb) ...
D000002: maintainer_script_new nonexistent preinst '/var/lib/dpkg/tmp.ci/preinst'
D000002: process_archive tmp.ci script/file '..' contains dot
D000002: process_archive tmp.ci script/file '.' contains dot
D000002: process_archive tmp.ci script/file '/var/lib/dpkg/tmp.ci/md5sums' installed as '/var/lib/dpkg/info/linux-headers-3.2.0-4-686-pae.md5sums'
D000002: process_archive tmp.ci script/file '/var/lib/dpkg/tmp.ci/control' is control
D000002: process_archive tmp.ci script/file '/var/lib/dpkg/tmp.ci/postinst' installed as '/var/lib/dpkg/info/linux-headers-3.2.0-4-686-pae.postinst'
Setting up linux-headers-3.2.0-4-686-pae (3.2.41-2+deb7u2) ...
D000002: fork/exec /var/lib/dpkg/info/linux-headers-3.2.0-4-686-pae.postinst ( configure  )
Examining /etc/kernel/header_postinst.d.
run-parts: executing /etc/kernel/header_postinst.d/dkms 3.2.0-4-686-pae
I was able to kill this install with cntrl +c and got this;

Code:
run-parts: executing /etc/kernel/header_postinst.d/dkms 3.2.0-4-686-pae
Failed to process /etc/kernel/header_postinst.d at /var/lib/dpkg/info/linux-headers-3.2.0-4-686-pae.postinst line 12.
dpkg: error processing linux-headers-3.2.0-4-686-pae (--install):
 subprocess installed post-installation script returned error exit status 255
Errors were encountered while processing:
 linux-headers-3.2.0-4-686-pae

Last edited by Soapm; 05-19-2013 at 12:25 PM.
 
Old 05-19-2013, 01:18 PM   #21
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled
I got the headers installed and here's how. I noticed the errors seem to point to /etc/kernel/header_postinst.d/ which had one file in it, dkms, so I decided to reinstall dkms. I found a git for dkms and when I looked in the folder I noticed it had a dkms file so I moved that file in place of mine in /etc/kernel/header_postinst.d/. I was then able to install the headers.

Here are the old and new files. I don't know what the difference is but changing this one file seems to have solved my problem.

dkms.original

Code:
#!/bin/bash

# We're passed the version of the kernel being installed
inst_kern=$1

uname_s=$(uname -s)

_get_kernel_dir() {
    KVER=$1
    case ${uname_s} in
       Linux)          DIR="/lib/modules/$KVER/build" ;;
       GNU/kFreeBSD)   DIR="/usr/src/kfreebsd-headers-$KVER/sys" ;;
    esac
    echo $DIR
}

_check_kernel_dir() {
    DIR=$(_get_kernel_dir $1)
    case ${uname_s} in
       Linux)          test -e $DIR/include ;;
       GNU/kFreeBSD)   test -e $DIR/kern && test -e $DIR/conf/kmod.mk ;;
       *)              return 1 ;;
    esac
    return $?
}

case "${uname_s}" in
    Linux)
        header_pkg="linux-headers-$inst_kern"
        kernel="Linux"
    ;;
    GNU/kFreeBSD)
        header_pkg="kfreebsd-headers-$inst_kern"
        kernel="kFreeBSD"
    ;;
esac

if [ -x /usr/lib/dkms/dkms_autoinstaller ]; then
    exec /usr/lib/dkms/dkms_autoinstaller start $inst_kern > /dev/null
fi

if ! _check_kernel_dir $inst_kern ; then
    echo "dkms: WARNING: $kernel headers are missing, which may explain the above failures." >&2
    echo "      please install the $header_pkg package to fix this." >&2
fi
I had to attach them, the new dkms file was far too long to post the code.
Attached Files
File Type: txt dkms.new.txt (126.2 KB, 20 views)
File Type: txt dkms.original.txt (1.1 KB, 20 views)
 
Old 05-19-2013, 03:37 PM   #22
EDDY1
LQ Addict
 
Registered: Mar 2010
Location: Oakland,Ca
Distribution: wins7, Debian wheezy
Posts: 6,841

Rep: Reputation: 649Reputation: 649Reputation: 649Reputation: 649Reputation: 649Reputation: 649
Try using synaptic,trhen you can see what your depends are.
 
Old 05-19-2013, 04:28 PM   #23
EDDY1
LQ Addict
 
Registered: Mar 2010
Location: Oakland,Ca
Distribution: wins7, Debian wheezy
Posts: 6,841

Rep: Reputation: 649Reputation: 649Reputation: 649Reputation: 649Reputation: 649Reputation: 649
I just need to know is this thread solved or not, if unsolved then change it to unsolved using the thread tools.
 
Old 05-19-2013, 05:55 PM   #24
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled
No, it's not soolved. This is what I get trying to reinstall the image package. So the problem still exist even though it let me install the headers. This is a headless box so I can't use synaptic.

Code:
dpkg --debug=2 -i /var/cache/apt/archives/linux-image-3.2.0-4-686-pae_3.2.41-2+deb7u2_i386.deb
Code:
root@lenny:~# dpkg --debug=2 -i /var/cache/apt/archives/linux-image-3.2.0-4-686-pae_3.2.41-2+deb7u2_i386.deb
(Reading database ... 140910 files and directories currently installed.)
Preparing to replace linux-image-3.2.0-4-686-pae 3.2.41-2+deb7u2 (using .../linux-image-3.2.0-4-686-pae_3.2.41-2+deb7u2_i386.deb) ...
D000002: fork/exec /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.prerm ( upgrade 3.2.41-2+deb7u2 )
D000002: fork/exec /var/lib/dpkg/tmp.ci/preinst ( upgrade 3.2.41-2+deb7u2 )
Examining /etc/kernel/preinst.d/
run-parts: executing /etc/kernel/preinst.d/intel-microcode 3.2.0-4-686-pae /boot/vmlinuz-3.2.0-4-686-pae
Unpacking replacement linux-image-3.2.0-4-686-pae ...
D000002: fork/exec /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.postrm ( upgrade 3.2.41-2+deb7u2 )
Examining /etc/kernel/postrm.d .
run-parts: executing /etc/kernel/postrm.d/initramfs-tools 3.2.0-4-686-pae /boot/vmlinuz-3.2.0-4-686-pae
run-parts: executing /etc/kernel/postrm.d/zz-update-grub 3.2.0-4-686-pae /boot/vmlinuz-3.2.0-4-686-pae
D000002: process_archive info installed /var/lib/dpkg/tmp.ci/prerm as /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.prerm
D000002: process_archive info installed /var/lib/dpkg/tmp.ci/templates as /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.templates
D000002: process_archive info installed /var/lib/dpkg/tmp.ci/preinst as /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.preinst
D000002: process_archive info installed /var/lib/dpkg/tmp.ci/postinst as /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.postinst
D000002: process_archive info installed /var/lib/dpkg/tmp.ci/md5sums as /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.md5sums
D000002: process_archive info installed /var/lib/dpkg/tmp.ci/postrm as /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.postrm
D000002: process_archive tmp.ci script/file '..' contains dot
D000002: process_archive tmp.ci script/file '.' contains dot
D000002: process_archive tmp.ci script/file '/var/lib/dpkg/tmp.ci/control' is control
Setting up linux-image-3.2.0-4-686-pae (3.2.41-2+deb7u2) ...
D000002: fork/exec /var/lib/dpkg/info/linux-image-3.2.0-4-686-pae.postinst ( configure 3.2.41-2+deb7u2 )
Running depmod.
Examining /etc/kernel/postinst.d.
run-parts: executing /etc/kernel/postinst.d/dkms 3.2.0-4-686-pae /boot/vmlinuz-3.2.0-4-686-pae
 
Old 05-19-2013, 06:28 PM   #25
EDDY1
LQ Addict
 
Registered: Mar 2010
Location: Oakland,Ca
Distribution: wins7, Debian wheezy
Posts: 6,841

Rep: Reputation: 649Reputation: 649Reputation: 649Reputation: 649Reputation: 649Reputation: 649
You can use aptitude to check dependencies
Quote:
#aptitude
 
Old 05-19-2013, 06:53 PM   #26
Hungry ghost
Senior Member
 
Registered: Dec 2004
Posts: 1,222

Rep: Reputation: 667Reputation: 667Reputation: 667Reputation: 667Reputation: 667Reputation: 667
I expected dpkg would give more information about why it's getting stuck. You can try other debug options, like 1 or 1000. There are other debug options, but these are the ones that I think might be give some information. (You can execute dpkg -Dh for more information about the debug options).

Last edited by Hungry ghost; 05-19-2013 at 06:54 PM.
 
Old 05-19-2013, 07:58 PM   #27
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled
I got the image file to install after copying the new dkms file to;

/etc/kernel/postinst.d/
/etc/kernel/prerm.d/

I don't know what's up with the stock dkms file but it seems to be the source of my trouble. One difference I see is this:

Old...

Quote:
_get_kernel_dir() {
KVER=$1
case ${uname_s} in
Linux) DIR="/lib/modules/$KVER/build" ;;
GNU/kFreeBSD) DIR="/usr/src/kfreebsd-headers-$KVER/sys" ;;
esac
echo $DIR
}
New...

Quote:
_get_kernel_dir() {
KVER=$1
case ${current_os} in
Linux) DIR="/lib/modules/$KVER/build" ;;
GNU/kFreeBSD) DIR="/usr/src/kfreebsd-headers-$KVER/sys" ;;
esac
echo $DIR
}
I also noticed the original dkms on my machine is version 2.2.0.3-1.2 whereas the one on the dell site is version 2.2.0.3. It would seem the one that came with wheezy is newer.

http://linux.dell.com/dkms/

Last edited by Soapm; 05-19-2013 at 08:01 PM.
 
Old 05-19-2013, 08:14 PM   #28
widget
Senior Member
 
Registered: Oct 2008
Location: S.E. Montana
Distribution: Debian Testing, Stable, Sid and Manjaro, Mageia 3, LMDE
Posts: 2,628

Rep: Reputation: 497Reputation: 497Reputation: 497Reputation: 497Reputation: 497
If you really need to see the depends;
Code:
apt-cache showpkg <package name>
will show depends and reverse depends of stated package.
 
Old 05-19-2013, 09:06 PM   #29
Soapm
Member
 
Registered: Dec 2012
Posts: 182

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by widget View Post
If you really need to see the depends;
Code:
apt-cache showpkg <package name>
will show depends and reverse depends of stated package.
I didn't know which package you wanted to see the depends for.

This is the depends for dkms

Code:
Package: dkms
Versions: 
2.2.0.3-1.2 (/var/lib/apt/lists/ftp.us.debian.org_debian_dists_wheezy_main_binary-i386_Packages) (/var/lib/dpkg/status)
 Description Language: 
                 File: /var/lib/apt/lists/ftp.us.debian.org_debian_dists_wheezy_main_binary-i386_Packages
                  MD5: b7b6bb6a6b083b2245e0648e7752a459
 Description Language: en
                 File: /var/lib/apt/lists/ftp.us.debian.org_debian_dists_wheezy_main_i18n_Translation-en
                  MD5: b7b6bb6a6b083b2245e0648e7752a459


Reverse Depends: 
  nvidia-kernel-dkms,dkms 2.1.0.0
  sl-modem-dkms,dkms 2.1.0.0
  nvidia-kernel-legacy-96xx-dkms,dkms 2.1.0.0
  nvidia-kernel-legacy-71xx-dkms,dkms 2.1.0.0
  nvidia-kernel-legacy-173xx-dkms,dkms 2.1.0.0
  nvidia-kernel-dkms,dkms 2.1.0.0
  fglrx-modules-dkms,dkms 2.1.0.0
  broadcom-sta-dkms,dkms 2.1.0.0
  xtables-addons-dkms,dkms 2.1.0.0
  west-chamber-dkms,dkms
  virtualbox-guest-dkms,dkms 2.1.0.0
  virtualbox-dkms,dkms 2.1.0.0
  v4l2loopback-dkms,dkms 2.1.0.0
  tp-smapi-dkms,dkms 1.95
  backfire-dkms,dkms 2.1.0.0
  oss4-dkms,dkms 2.1.0.0
  openvswitch-datapath-dkms,dkms 1.95
  openswan-modules-dkms,dkms
  openafs-modules-dkms,dkms 2.1.0.0
  open-vm-dkms,dkms 2.1.0.0
  ndiswrapper-dkms,dkms 2.1.0.0
  iscsitarget-dkms,dkms 1.95
  fuse4bsd-dkms,dkms 2.2.0.1-3
  blktap-dkms,dkms 2.1.0.0
  blcr-dkms,dkms
Dependencies: 
2.2.0.3-1.2 - module-init-tools (0 (null)) gcc (0 (null)) make (16 (null)) build-essential (16 (null)) dpkg-dev (0 (null)) coreutils (2 7.4) patch (0 (null)) fakeroot (0 (null)) menu (16 (null)) sudo (0 (null)) linux-headers-686-pae (16 (null)) linux-headers-amd64 (16 (null)) linux-headers-generic (16 (null)) linux-headers (0 (null)) linux-image (0 (null)) 
Provides: 
2.2.0.3-1.2 - 
Reverse Provides:
Here is the one for the image file.

Code:
Package: linux-image-3.2.0-4-686-pae
Versions: 
3.2.41-2+deb7u2 (/var/lib/apt/lists/security.debian.org_dists_wheezy_updates_main_binary-i386_Packages) (/var/lib/dpkg/status)
 Description Language: 
                 File: /var/lib/apt/lists/ftp.us.debian.org_debian_dists_wheezy_main_binary-i386_Packages
                  MD5: 16ae3e4fbb20ccd905d1bb975445e31d
 Description Language: en
                 File: /var/lib/apt/lists/ftp.us.debian.org_debian_dists_wheezy_main_i18n_Translation-en
                  MD5: 16ae3e4fbb20ccd905d1bb975445e31d

3.2.41-2 (/var/lib/apt/lists/ftp.us.debian.org_debian_dists_wheezy_main_binary-i386_Packages)
 Description Language: 
                 File: /var/lib/apt/lists/ftp.us.debian.org_debian_dists_wheezy_main_binary-i386_Packages
                  MD5: 16ae3e4fbb20ccd905d1bb975445e31d
 Description Language: en
                 File: /var/lib/apt/lists/ftp.us.debian.org_debian_dists_wheezy_main_i18n_Translation-en
                  MD5: 16ae3e4fbb20ccd905d1bb975445e31d


Reverse Depends: 
  ndiswrapper-modules-3.2.0-4-686-pae,linux-image-3.2.0-4-686-pae
  xen-linux-system-3.2.0-4-686-pae,linux-image-3.2.0-4-686-pae 3.2.41-2+deb7u2
  linux-image-3.2.0-4-686-pae-dbg,linux-image-3.2.0-4-686-pae
  nvidia-kernel-3.2.0-4-686-pae,linux-image-3.2.0-4-686-pae
  linux-image-686-pae,linux-image-3.2.0-4-686-pae
  xen-linux-system-3.2.0-4-686-pae,linux-image-3.2.0-4-686-pae 3.2.41-2
  linux-image-3.2.0-4-686-pae-dbg,linux-image-3.2.0-4-686-pae
Dependencies: 
3.2.41-2+deb7u2 - kmod (16 (null)) module-init-tools (0 (null)) linux-base (2 3~) initramfs-tools (18 0.99~) linux-initramfs-tool (0 (null)) debconf (16 (null)) debconf-2.0 (0 (null)) linux-doc-3.2 (0 (null)) debian-kernel-handbook (0 (null)) grub-pc (16 (null)) extlinux (16 (null)) lilo (0 (null)) firmware-linux-free (2 3~) libc6-i686 (0 (null)) at (3 3.1.12-1+squeeze1) initramfs-tools (3 0.99~) 
3.2.41-2 - kmod (16 (null)) module-init-tools (0 (null)) linux-base (2 3~) initramfs-tools (18 0.99~) linux-initramfs-tool (0 (null)) debconf (16 (null)) debconf-2.0 (0 (null)) linux-doc-3.2 (0 (null)) debian-kernel-handbook (0 (null)) grub-pc (16 (null)) extlinux (16 (null)) lilo (0 (null)) firmware-linux-free (2 3~) libc6-i686 (0 (null)) at (3 3.1.12-1+squeeze1) initramfs-tools (3 0.99~) 
Provides: 
3.2.41-2+deb7u2 - linux-modules-3.2.0-4-686-pae linux-image 
3.2.41-2 - linux-modules-3.2.0-4-686-pae linux-image 
Reverse Provides:
 
Old 05-19-2013, 09:35 PM   #30
EDDY1
LQ Addict
 
Registered: Mar 2010
Location: Oakland,Ca
Distribution: wins7, Debian wheezy
Posts: 6,841

Rep: Reputation: 649Reputation: 649Reputation: 649Reputation: 649Reputation: 649Reputation: 649
Can you post your current /etc/apt/sources.list?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Downgrading From Wheezy to Squeeze resuni Debian 9 07-17-2013 05:18 PM
Help! Upgraded remote server from Squeeze to Wheezy, grub install fails neilgunton Linux - Software 1 12-20-2012 04:41 PM
unable to upgrade from squeeze to wheezy(testing) rupeshforu Debian 4 12-07-2012 04:05 AM
unable to upgrade from squeeze to wheezy(testing) rupeshforu Debian 1 12-06-2012 05:30 AM
[SOLVED] Upgrading Squeeze to Wheezy: a nightmare! edbarx Debian 17 03-19-2012 04:49 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Debian

All times are GMT -5. The time now is 04:40 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration