summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Vignaud <thierry.vignaud@gmail.com>2013-12-21 02:05:57 +0100
committerThierry Vignaud <thierry.vignaud@gmail.com>2013-12-21 03:30:35 +0100
commit858573ca6bf57cae345d2047c7a79e2da6a7d345 (patch)
treeb2fbdf3859bc41e224677ae842867b3cab750060
parent1455583f43808bc43fb0ade94aa770e84f62276f (diff)
downloadmgaonline-858573ca6bf57cae345d2047c7a79e2da6a7d345.tar
mgaonline-858573ca6bf57cae345d2047c7a79e2da6a7d345.tar.gz
mgaonline-858573ca6bf57cae345d2047c7a79e2da6a7d345.tar.bz2
mgaonline-858573ca6bf57cae345d2047c7a79e2da6a7d345.tar.xz
mgaonline-858573ca6bf57cae345d2047c7a79e2da6a7d345.zip
split mgaapplet-update-checker
since we cannot prevent glib/gtk to spawn threads behind our back, we can at least try to prevent segfaults due to mixing threads with secular forks by exec()ing immediately
-rw-r--r--Makefile2
-rw-r--r--NEWS3
-rwxr-xr-xmgaapplet95
-rwxr-xr-xmgaapplet-update-checker111
4 files changed, 117 insertions, 94 deletions
diff --git a/Makefile b/Makefile
index 182e8429..25416351 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,7 @@ clean:
install: all
install -d $(PREFIX)/usr/{bin,libexec,share/{mime/packages,$(NAME)/pixmaps,autostart,gnome/autostart,icons/{mini,large}},lib/libDrakX/drakfirsttime}
install -m755 $(MGAUPDATE) $(MGAAPPLET)-config $(MGAAPPLET)-upgrade-helper $(LIBEXECDIR)
- install -m755 $(MGAAPPLET) $(BINDIR)
+ install -m755 $(MGAAPPLET) $(MGAAPPLET)-update-checker $(BINDIR)
install -d $(SYSCONFDIR)
install -m644 mgaapplet.conf $(SYSCONFDIR)/mgaapplet
install -m644 icons/$(NAME)16.png $(ICONSDIR)/mini/$(NAME).png
diff --git a/NEWS b/NEWS
index 099a8b99..4e4f72d0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+- split mgaapplet-update-checker
+ (prevents segfault due to mixing glib threads with secular forks)
+
Version 3.2 - 16 December 2013, Thierry Vignaud
- fix crashing when displaying about dialog (mga#12009)
diff --git a/mgaapplet b/mgaapplet
index 77b6f6dd..ede55a51 100755
--- a/mgaapplet
+++ b/mgaapplet
@@ -552,22 +552,6 @@ sub installUpdates() {
silentCheck(); gtkflush();
}
-sub checker_exit {
- my ($state) = @_;
- POSIX::_exit($comm_codes{$state}{code});
-}
-
-sub update_backport_media {
- my ($urpm) = @_;
- # update inactive backport media:
- my @inactive_backport_media = Rpmdrake::open_db::get_inactive_backport_media($urpm);
- return if !@inactive_backport_media;
- log::explanations("updating inactive backport media " . join(', ', @inactive_backport_media));
- foreach (@inactive_backport_media) {
- run_program::run('urpmi.update', if_($root, "--urpmi-root=$root"), $_);
- }
-}
-
sub silentCheck() {
state $check_time;
my $new_time = time();
@@ -583,83 +567,8 @@ sub silentCheck() {
# are there any updates ?
- $checker_pid = fork();
- if (defined $checker_pid) {
- return if $checker_pid; # parent
-
- # immediate exit, else forked gtk+ object destructors will badly catch up parent applet
- my $_safe = before_leaving {
- my $err = $@;
- log::explanations("mgaapplet check crashed: $err ");
- warn "Error: $err\n" . common::backtrace();
- POSIX::_exit(0);
- };
-
- # be nice with other processes:
- setpriority(0, $$, 7); # 0 is PRIO_PROCESS
-
- my $will_not_update_media;
- require urpm;
- require urpm::lock;
- # so that get_inactive_backport_media() doesn't vivify $urpm->{media}:
- my $urpm = Rpmdrake::open_db::fast_open_urpmi_db();
- {
- local $urpm->{fatal} = sub {
- print "Fatal: @_\n";
- $will_not_update_media = 1;
- };
- local $urpm->{error} = $urpm->{fatal};
-
- urpm::lock::urpmi_db($urpm, 'exclusive', 1);
- }
- checker_exit('locked') if $will_not_update_media;
-
- my $is_it_a_devel_distro = is_it_a_devel_distro();
-
- my $media = $is_it_a_devel_distro ? '-a' : '--update';
- if (!run_program::run('urpmi.update', $media, if_($root, "--urpmi-root=$root"))) {
- checker_exit('error_updating') if $will_not_update_media;
- }
-
- update_backport_media($urpm);
-
- require urpm::select;
- require urpm::media;
- # this eats 52Mb of RAM on 64bit:
- # (hence we do it in the forked helper so that the applet doesn't eat too much RAM)
- urpm::media::configure($urpm, if_(!$is_it_a_devel_distro, update => 1));
-
- my @update_medias = get_update_medias($urpm);
-
- if (!@update_medias) {
- checker_exit('no_update_medium');
- } elsif (!any { ! $_->{ignore} } @update_medias) {
- checker_exit('no_enabled_medium');
- }
-
- if (my $_db = urpm::db_open_or_die($urpm)) {
- my $requested = {};
- my $state = {};
- my $need_restart = urpm::select::resolve_dependencies(
- $urpm, $state, $requested,
- callback_choices => sub { 0 },
- priority_upgrade => $urpm->{options}{'priority-upgrade'},
- auto_select => 1,
- );
- my @requested_strict = map { scalar $_->fullname } @{$urpm->{depslist}}[keys %{$state->{selected}}];
-
- if ($need_restart || @requested_strict) {
- # FIXME: log first found pkgs?
- warn ">> need_restart=$need_restart, updates=" . join(', ', @requested_strict) . "\n";
- checker_exit('updates');
- } else {
- checker_exit('uptodate');
- }
- } else {
- checker_exit('db_not_open');
- }
- checker_exit('updates');
- } else {
+ $checker_pid = fork_exec('mgaapplet-update-checker', $root);
+ if (!$checker_pid) {
log::explanations("cannot fork: %s", "update checker ($!)");
go2State('critical');
}
diff --git a/mgaapplet-update-checker b/mgaapplet-update-checker
new file mode 100755
index 00000000..bb852150
--- /dev/null
+++ b/mgaapplet-update-checker
@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+################################################################################
+# Mandriva Online #
+# #
+# Copyright (C) 2003-2010 Mandriva #
+# #
+# Daouda Lo #
+# Thierry Vignaud <thierry.vignaud at gmail dot com> #
+# #
+# This program is free software; you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License Version 2 as #
+# published by the Free Software Foundation. #
+# #
+# This program 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 program; if not, write to the Free Software #
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+################################################################################
+use lib qw(/usr/lib/libDrakX /usr/lib/libDrakX/drakfirsttime);
+use standalone; # for explanations
+use MDK::Common;
+use Rpmdrake::open_db;
+use mgaapplet;
+
+# be nice with other processes:
+setpriority(0, $$, 7); # 0 is PRIO_PROCESS
+
+my $root = $ARGV[0];
+
+my $will_not_update_media;
+require urpm;
+require urpm::lock;
+# so that get_inactive_backport_media() doesn't vivify $urpm->{media}:
+my $urpm = Rpmdrake::open_db::fast_open_urpmi_db();
+{
+ local $urpm->{fatal} = sub {
+ print "Fatal: @_\n";
+ $will_not_update_media = 1;
+ };
+ local $urpm->{error} = $urpm->{fatal};
+
+ urpm::lock::urpmi_db($urpm, 'exclusive', 1);
+}
+checker_exit('locked') if $will_not_update_media;
+
+my $is_it_a_devel_distro = is_it_a_devel_distro();
+
+my $media = $is_it_a_devel_distro ? '-a' : '--update';
+if (!run_program::run('urpmi.update', $media, if_($root, "--urpmi-root=$root"))) {
+ checker_exit('error_updating') if $will_not_update_media;
+}
+
+update_backport_media($urpm);
+
+require urpm::select;
+require urpm::media;
+# this eats 52Mb of RAM on 64bit:
+# (hence we do it in the forked helper so that the applet doesn't eat too much RAM)
+urpm::media::configure($urpm, if_(!$is_it_a_devel_distro, update => 1));
+
+my @update_medias = get_update_medias($urpm);
+
+if (!@update_medias) {
+ checker_exit('no_update_medium');
+} elsif (!any { ! $_->{ignore} } @update_medias) {
+ checker_exit('no_enabled_medium');
+}
+
+if (my $_db = urpm::db_open_or_die($urpm)) {
+ my $requested = {};
+ my $state = {};
+ my $need_restart = urpm::select::resolve_dependencies(
+ $urpm, $state, $requested,
+ callback_choices => sub { 0 },
+ priority_upgrade => $urpm->{options}{'priority-upgrade'},
+ auto_select => 1,
+ );
+ my @requested_strict = map { scalar $_->fullname } @{$urpm->{depslist}}[keys %{$state->{selected}}];
+
+ if ($need_restart || @requested_strict) {
+ # FIXME: log first found pkgs?
+ warn ">> need_restart=$need_restart, updates=" . join(', ', @requested_strict) . "\n";
+ checker_exit('updates');
+ } else {
+ checker_exit('uptodate');
+ }
+} else {
+ checker_exit('db_not_open');
+}
+checker_exit('updates');
+
+sub checker_exit {
+ my ($state) = @_;
+ POSIX::_exit($comm_codes{$state}{code});
+}
+
+sub update_backport_media {
+ my ($urpm) = @_;
+ # update inactive backport media:
+ my @inactive_backport_media = Rpmdrake::open_db::get_inactive_backport_media($urpm);
+ return if !@inactive_backport_media;
+ log::explanations("updating inactive backport media " . join(', ', @inactive_backport_media));
+ foreach (@inactive_backport_media) {
+ run_program::run('urpmi.update', if_($root, "--urpmi-root=$root"), $_);
+ }
+}
+