[maemo-commits] [maemo-commits] r15055 - in projects/haf/trunk/maemo-launcher: . launcher
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Thu Jan 10 23:38:22 EET 2008
- Previous message: [maemo-commits] r15054 - in projects/haf/trunk/maemo-launcher: . launcher
- Next message: [maemo-commits] r15056 - projects/haf/trunk/maemo-launcher/debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: guillem Date: 2008-01-10 23:38:22 +0200 (Thu, 10 Jan 2008) New Revision: 15055 Modified: projects/haf/trunk/maemo-launcher/ChangeLog projects/haf/trunk/maemo-launcher/launcher/Makefile.am projects/haf/trunk/maemo-launcher/launcher/launcher.c Log: Support hot-swapping the in-memory maemo-launcher Add state persistence support and reexectuion of itself on SIGUSR1, to support clean package upgrades. Modified: projects/haf/trunk/maemo-launcher/ChangeLog =================================================================== --- projects/haf/trunk/maemo-launcher/ChangeLog 2008-01-10 21:21:51 UTC (rev 15054) +++ projects/haf/trunk/maemo-launcher/ChangeLog 2008-01-10 21:38:22 UTC (rev 15055) @@ -1,5 +1,26 @@ 2008-01-10 Guillem Jover <guillem.jover at nokia.com> + * launcher/Makefile.am (maemo_launcher_SOURCES): Add 'comm_msg.c' and + 'comm_msg.h'. + * launcher/launcher.c: Include "comm_msg.h". + (LAUNCHER_STATEFILE): New macro. + (statefilename): New variable. + (sigreexec_catched): Likewise. + (clean_daemon): Unlink statefilename. + (LAUNCHER_STATE_SIG): New macro. + (store_state): New function. + (load_state): Likewise. + (sigreexec_handler): Likewise. + (sigs_init): Initialize SIGUSR1 to sigreexec_handler. + (sigs_restore): Restore SIGUSR1. + (sigs_interrupt): Allow SIGUSR1 to interrupt syscalls. + (main): Try to load the state file, and fallback to normal + initialization if that fails. Only daemonize and create a pid file + if not loading the state file. Handle sigreexec_catched in the main + event loop to store the cache, and reexec self. + +2008-01-10 Guillem Jover <guillem.jover at nokia.com> + * launcher/comm_msg.h: New file. * launcher/comm_msg.c: Likewise. * launcher/test_lib.h: Likewise. Modified: projects/haf/trunk/maemo-launcher/launcher/Makefile.am =================================================================== --- projects/haf/trunk/maemo-launcher/launcher/Makefile.am 2008-01-10 21:21:51 UTC (rev 15054) +++ projects/haf/trunk/maemo-launcher/launcher/Makefile.am 2008-01-10 21:38:22 UTC (rev 15055) @@ -41,7 +41,8 @@ maemo_launcher_HEADERS = booster_api.h maemo_launcher_SOURCES = \ launcher.c report.c report.h booster.c booster.h \ - invokelib.c invokelib.h comm_dbus.c comm_dbus.h \ + invokelib.c invokelib.h \ + comm_msg.c comm_msg.h comm_dbus.c comm_dbus.h \ prog.c prog.h maemo_launcher_CPPFLAGS = \ $(DBUS_CFLAGS) \ Modified: projects/haf/trunk/maemo-launcher/launcher/launcher.c =================================================================== --- projects/haf/trunk/maemo-launcher/launcher/launcher.c 2008-01-10 21:21:51 UTC (rev 15054) +++ projects/haf/trunk/maemo-launcher/launcher/launcher.c 2008-01-10 21:38:22 UTC (rev 15055) @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) 2005, 2006, 2007 Nokia Corporation + * Copyright (C) 2005, 2006, 2007, 2008 Nokia Corporation * * Authors: Michael Natterer <mitch at imendio.com> * Guillem Jover <guillem.jover at nokia.com> @@ -43,12 +43,14 @@ #include "report.h" #include "invokelib.h" +#include "comm_msg.h" #include "comm_dbus.h" #include "booster.h" #include "prog.h" /* FIXME: Should go into '/var/run/'. */ #define LAUNCHER_PIDFILE "/tmp/"PROG_NAME".pid" +#define LAUNCHER_STATEFILE "/tmp/"PROG_NAME".state" typedef struct { @@ -65,9 +67,11 @@ } kindergarten_t; static char *pidfilename = LAUNCHER_PIDFILE; +static char *statefilename = LAUNCHER_STATEFILE; static pid_t is_parent = 1; static volatile bool sigchild_catched = false; static volatile bool sighup_catched = false; +static volatile bool sigreexec_catched = false; static bool send_app_died = false; #define OOM_ENABLE "0" @@ -358,6 +362,7 @@ { if (is_parent) { + unlink(statefilename); unlink(pidfilename); unlink(INVOKER_SOCK); killpg(0, signal); @@ -537,6 +542,96 @@ } } +/* Persistence support */ + +#define LAUNCHER_STATE_SIG "MLSF0.0" + +static bool +store_state(kindergarten_t *childs, int invoker_fd) +{ + int i; + int fd; + child_t *list = childs->list; + comm_msg_t *msg; + + unlink(statefilename); + + fd = open(statefilename, O_WRONLY | O_CREAT, 0644); + if (fd < 0) + { + error("opening persistence file '%s'\n", statefilename); + return false; + } + + msg = comm_msg_new(512); + + comm_msg_pack_str(msg, LAUNCHER_STATE_SIG); + comm_msg_pack_int(msg, invoker_fd); + comm_msg_pack_int(msg, childs->used); + + for (i = 0; i < childs->used; i++) + { + comm_msg_pack_int(msg, list[i].pid); + comm_msg_pack_int(msg, list[i].sock); + comm_msg_pack_str(msg, list[i].name); + } + + comm_msg_send(fd, msg); + + close(fd); + + return true; +} + +static kindergarten_t * +load_state(int *invoker_fd) +{ + int i; + int fd; + uint32_t w; + const char *s; + kindergarten_t *childs; + child_t *list; + comm_msg_t *msg; + + fd = open(statefilename, O_RDONLY); + if (fd < 0) + { + if (errno != ENOENT) + error("opening persistence file '%s'\n", statefilename); + return NULL; + } + + msg = comm_msg_new(512); + comm_msg_recv(fd, msg); + + close(fd); + + comm_msg_unpack_str(msg, &s); + if (strcmp(LAUNCHER_STATE_SIG, s) != 0) + { + error("wrong signature on persistence file '%s'\n", statefilename); + return NULL; + } + + comm_msg_unpack_int(msg, invoker_fd); + + comm_msg_unpack_int(msg, &w); + childs = kindergarten_new(w); + childs->used = w; + list = childs->list; + + for (i = 0; i < childs->used; i++) + { + comm_msg_unpack_int(msg, &list[i].pid); + comm_msg_unpack_int(msg, &list[i].sock); + comm_msg_unpack_str(msg, &s); + list[i].name = strdup(s); + } + + return childs; +} + static void sigchild_handler(int sig) { @@ -550,6 +645,12 @@ } static void +sigreexec_handler(int sig) +{ + sigreexec_catched = true; +} + +static void sigs_init(void) { struct sigaction sig; @@ -569,6 +670,9 @@ sig.sa_handler = sighup_handler; sigaction(SIGHUP, &sig, NULL); + + sig.sa_handler = sigreexec_handler; + sigaction(SIGUSR1, &sig, NULL); } static void @@ -585,12 +689,14 @@ sigaction(SIGTERM, &sig, NULL); sigaction(SIGCHLD, &sig, NULL); sigaction(SIGHUP, &sig, NULL); + sigaction(SIGUSR1, &sig, NULL); } static void sigs_interrupt(int flag) { siginterrupt(SIGCHLD, flag); + siginterrupt(SIGUSR1, flag); } static void @@ -694,6 +800,7 @@ int fd; bool daemon = false; bool quiet = false; + bool upgrading = false; /* * Parse arguments. @@ -736,22 +843,32 @@ env_init(); fs_init(); - /* Setup child tracking. */ - kg = kindergarten_new(initial_child_slots); + kg = load_state(&fd); - /* Setup the conversation channel with the invoker. */ - fd = invoked_init(); + if (kg) + upgrading = true; + else + { + /* Setup child tracking. */ + kg = kindergarten_new(initial_child_slots); - if (daemon) - daemonize(); + /* Setup the conversation channel with the invoker. */ + fd = invoked_init(); + if (daemon) + daemonize(); + } + /* Protect us from the oom monster. */ rise_oom_defense(getpid()); if (quiet) console_quiet(); - create_pidfile(); + if (upgrading) + info("restored persitent state\n"); + else + create_pidfile(); /* * Application invokation loop. @@ -781,6 +898,18 @@ sighup_catched = false; } + if (sigreexec_catched) + { + info("storing kindergarten state\n"); + store_state(kg, fd); + + info("reexecuting self\n"); + execv(argv[0], argv); + + error("while trying to reexec self, trying to continue\n"); + sigreexec_catched = false; + } + /* Minimal error handling. */ if (sd < 0) {
- Previous message: [maemo-commits] r15054 - in projects/haf/trunk/maemo-launcher: . launcher
- Next message: [maemo-commits] r15056 - projects/haf/trunk/maemo-launcher/debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]