userui: new option to change VT
Julien Muchembled <[email protected]> Sun, 02 Feb 2014 16:42:56 +0100
| Newsgroups | gmane.linux.swsusp.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello Nigel, What do you think about the attached patch for tuxonice-userui ? For example on Debian: - nothing is done to change VT when hibernation is handled by systemd - I submitted a patch to pm-utils but it looks like http://bugs.debian.org/732948 will be ignored forever - I don't know the status of other PM solutions to hibernate So I think it's safer and simpler to do this inside tuxonice-userui itself. I used this patch without any issue for more than one month. I recently stopped using pm-utils, in favor of systemd. I've just noticed that I didn't touch fbsplash_unprepare, but it's probably better to do nothing if the VT will be trashed at exit, so that the user does not see a black screen for a fraction of second. Apart from that, I am currently adopting packaging of tuxonice-userui on Debian: http://bugs.debian.org/719529 Regard, Julien _______________________________________________ TuxOnIce-devel mailing list [email protected] http://lists.tuxonice.net/listinfo/tuxonice-devel
0001-New-option-to-change-VT.patch
(text/x-diff, 8 KB)
From d6b9b3a7c069ad6c9b4a8e88ef9901fefc8fafdb Mon Sep 17 00:00:00 2001 From: Julien Muchembled <[email protected]> Date: Mon, 23 Dec 2013 06:30:06 +0100 Subject: [PATCH] New option to change VT TOI UI needs its own VT and without such option, it would be required to work around this in every power management hibernation. --- debian/pm-utils.hook | 2 +- fbsplash/cmd.c | 11 ++++---- fbsplash/common.c | 1 - fbsplash/splash.h | 1 - fbsplash/userui_fbsplash_core.c | 22 ---------------- userui.h | 1 + userui_core.c | 56 +++++++++++++++++++++++++++++++++++++---- userui_text.c | 2 -- 8 files changed, 59 insertions(+), 37 deletions(-) diff --git a/debian/pm-utils.hook b/debian/pm-utils.hook index 3de0b24..045cf22 100644 --- a/debian/pm-utils.hook +++ b/debian/pm-utils.hook @@ -11,7 +11,7 @@ SYSFS_PATH="/sys/power/tuxonice/user_interface/program" case $1 in hibernate) - echo "$TUXONICE_USERUI_PROGRAM" > $SYSFS_PATH + echo "$TUXONICE_USERUI_PROGRAM -v63" > $SYSFS_PATH ;; *) exit $NA ;; diff --git a/fbsplash/cmd.c b/fbsplash/cmd.c index 2672d69..0a418df 100644 --- a/fbsplash/cmd.c +++ b/fbsplash/cmd.c @@ -25,6 +25,7 @@ #include <errno.h> #include <linux/fb.h> #include "splash.h" +#include "../userui.h" #ifdef CONFIG_FBSPLASH #include <linux/console_splash.h> @@ -32,7 +33,7 @@ void cmd_setstate(unsigned int state, unsigned char origin) { struct fb_splash_iowrapper wrapper = { - .vc = arg_vc, + .vc = suspend_vt, .origin = origin, .data = &state, }; @@ -46,7 +47,7 @@ void cmd_setstate(unsigned int state, unsigned char origin) void cmd_setpic(struct fb_image *img, unsigned char origin) { struct fb_splash_iowrapper wrapper = { - .vc = arg_vc, + .vc = suspend_vt, .origin = origin, .data = img, }; @@ -60,7 +61,7 @@ void cmd_setcfg(unsigned char origin) { struct vc_splash vc_cfg; struct fb_splash_iowrapper wrapper = { - .vc = arg_vc, + .vc = suspend_vt, .origin = origin, .data = &vc_cfg, }; @@ -82,7 +83,7 @@ void cmd_getcfg() { struct vc_splash vc_cfg; struct fb_splash_iowrapper wrapper = { - .vc = arg_vc, + .vc = suspend_vt, .origin = FB_SPLASH_IO_ORIG_USER, .data = &vc_cfg, }; @@ -97,7 +98,7 @@ void cmd_getcfg() strcpy(vc_cfg.theme, "<none>"); } - printf("Splash config on console %d:\n", arg_vc); + printf("Splash config on console %d:\n", suspend_vt); printf("tx: %d\n", vc_cfg.tx); printf("ty: %d\n", vc_cfg.ty); printf("twidth: %d\n", vc_cfg.twidth); diff --git a/fbsplash/common.c b/fbsplash/common.c index 4450192..f0dd1d6 100644 --- a/fbsplash/common.c +++ b/fbsplash/common.c @@ -38,7 +38,6 @@ char *config_file = NULL; enum TASK arg_task = none; int arg_fb = 0; -int arg_vc = 0; char arg_mode = 'v'; char *arg_theme = NULL; u16 arg_progress = 0; diff --git a/fbsplash/splash.h b/fbsplash/splash.h index 4b37ff1..bd0d100 100644 --- a/fbsplash/splash.h +++ b/fbsplash/splash.h @@ -265,7 +265,6 @@ extern struct fb_fix_screeninfo fb_fix; extern enum ENDIANESS endianess; extern enum TASK arg_task; extern int arg_fb; -extern int arg_vc; extern char *arg_theme; extern char arg_mode; extern u16 arg_progress; diff --git a/fbsplash/userui_fbsplash_core.c b/fbsplash/userui_fbsplash_core.c index d1ff32d..e294a77 100644 --- a/fbsplash/userui_fbsplash_core.c +++ b/fbsplash/userui_fbsplash_core.c @@ -68,27 +68,6 @@ static void silent_off() { show_cursor(); } -static int get_active_vt() { - int vt, fd; - struct vt_stat vt_stat; - - vt = 62; /* default */ - - if ((fd = open("/dev/tty0", O_RDONLY)) == -1) - goto out; - - if (ioctl(fd, VT_GETSTATE, &vt_stat) == -1) - goto out; - - vt = vt_stat.v_active - 1; - -out: - if (fd >= 0) - close(fd); - - return vt; -} - static int fbsplash_load() { fb_fd = -1; last_pos = 0; @@ -104,7 +83,6 @@ static int fbsplash_load() { return 1; } - arg_vc = get_active_vt(); arg_mode = 's'; /* Read theme config file */ diff --git a/userui.h b/userui.h index ca59826..920f704 100644 --- a/userui.h +++ b/userui.h @@ -53,6 +53,7 @@ void printk(char *msg, ...); extern char software_suspend_version[32]; extern int can_use_escape; +extern int suspend_vt; extern volatile __uint32_t console_loglevel; extern volatile __uint32_t suspend_action; extern volatile __uint32_t suspend_debug; diff --git a/userui_core.c b/userui_core.c index 74d7aa6..5e3f713 100644 --- a/userui_core.c +++ b/userui_core.c @@ -96,6 +96,8 @@ static void might_switch_ops(void) } static int netlink_socket_num = 0; +static int saved_vt = 0; +int suspend_vt = 0; static char* descriptions[] = { "General", @@ -373,7 +375,7 @@ int common_keypress_handler(int key) } static void handle_params(int argc, char **argv) { - static char global_optstring[] = "htc:fu"; + static char global_optstring[] = "htc:fuv:"; static struct option global_longopts[] = { {"help", 0, 0, 'h'}, {"test", 0, 0, 't'}, @@ -382,6 +384,7 @@ static void handle_params(int argc, char **argv) { #ifdef USE_USPLASH {"usplash", 0, 0, 'u'}, #endif + {"chvt", 1, 0, 'v'}, {NULL, 0, 0, 0}, }; @@ -437,6 +440,9 @@ static void handle_params(int argc, char **argv) { case 't': test_run++; break; + case 'v': + suspend_vt = atoi(optarg); + break; case 'h': fprintf(stderr, "Usage: %s [options]\n" @@ -445,6 +451,9 @@ static void handle_params(int argc, char **argv) { " Specifying -t once will give an demo of this module.\n" " Specifying -t twice will make the demo run as fast as it can.\n" " (useful for performance testing).\n" +" -v, --chvt=N\n" +" Makes /dev/ttyN the foreground terminal before doing anything else\n" +" and restore previous VT at the end.\n" #ifdef USE_USPLASH " -u\n" " Use usersplash interface by default.\n" @@ -603,6 +612,27 @@ static void enforce_lifesavers() { setrlimit(RLIMIT_CORE, &r); } +static int chvt(int vt) { + return ioctl(console_fd, VT_ACTIVATE, vt) + || ioctl(console_fd, VT_WAITACTIVE, vt) + || close(console_fd) + || (console_fd = open("/dev/console", O_RDWR)) == -1; +} + +static void restore_vt() { + struct rlimit r; + r.rlim_cur = r.rlim_max = console_fd + 1; + setrlimit(RLIMIT_NOFILE, &r); + close(STDOUT_FILENO); + close(STDERR_FILENO); + /* It does not matter whether other files are still opened or not. + * RLIMIT_NOFILE only prevents files from being opened with a fd greater + * or equal than the limit. chvt should reopen console with fd=0 + */ + chvt(saved_vt); + ioctl(console_fd, VT_DISALLOCATE, suspend_vt); +} + static void restore_console() { int result; ioctl(console_fd, KDSKBMODE, K_XLATE); @@ -726,14 +756,30 @@ static void setup_signal_handlers() { } static void open_console() { + struct vt_stat vtstat; + if ((console_fd = open("/dev/console", O_RDWR)) == -1) bail_err("open(\"/dev/console\", O_RDWR)"); - if (dup2(console_fd, STDIN_FILENO) == -1) - bail_err("dup2(fd, STDIN_FILENO)"); - if (!test_run && dup2(console_fd, STDOUT_FILENO) == -1) + if (ioctl(console_fd, VT_GETSTATE, &vtstat)) + bail_err("VT_GETSTATE"); + if (!suspend_vt) + suspend_vt = vtstat.v_active; + else if (suspend_vt != vtstat.v_active) { + if (chvt(suspend_vt)) + bail_err("failed to change VT"); + saved_vt = vtstat.v_active; + atexit(restore_vt); + } + + if (console_fd != STDIN_FILENO) { + if (dup2(console_fd, STDIN_FILENO) == -1 || close(console_fd)) + bail_err("dup2(fd, STDIN_FILENO)"); + console_fd = STDIN_FILENO; + } + if (dup2(console_fd, STDOUT_FILENO) == -1) bail_err("dup2(fd, STDOUT_FILENO)"); - if (!test_run && dup2(console_fd, STDERR_FILENO) == -1) + if (dup2(console_fd, STDERR_FILENO) == -1) bail_err("dup2(fd, STDERR_FILENO)"); } diff --git a/userui_text.c b/userui_text.c index 0b9ff2a..5502f4b 100644 --- a/userui_text.c +++ b/userui_text.c @@ -362,8 +362,6 @@ static void text_cleanup() close(vcsa_fd); ioctl(STDOUT_FILENO, TCSETSF, (long)&termios); - - /* chvt back? */ } static void text_redraw() -- 1.8.5.2.988.g9b015e5.dirty
signature.asc
(application/pgp-signature, 836 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBCAAGBQJS7meFAAoJEEwjvlkacWMkZYAP/RMvPdJAnHDBuRZTEcEvpjjL /qtFFVZFjp5h6Av1x2NkSZT09FIxD8hnHOl89sa8x6c+roes3uLenyD4DE5xu7qB 3DNtICiTF5OKeyES3ZKzE0hW+4iFdgXt/qGV+/ExNSOpV7IZwxy3sd2GmfH1LiU7 mHaEH7fCwB1Mviu4/gLYLNwQKPYJSb/65pZl3U1GbmJH5w8+o9Y6/PPpLfvfwTK2 usbCGKBDWGyZZ8iEPG0Fo59/W8imWpkHYFgGg1En4Wv9VZX9y4EcIpppK/E4Sves qe+L1IR6R/ZReYjykWUxy+JVa8aw0coYS02g0EOzVwqCWGcMiQ+kxKcXZK4cDU9G u4Iyq8KiKFB1YPnxFpUUShH8+p2gpKsHOmN2nLZLAK4DtfEHo06ej5H3Bql02XY/ E2dQahSOGkv09dv2ttEBsMqKemsSgnhMKB0Fxukcd5Wq+AG83ZtpjFe7QOxV4NFx EPKtHuQaspWTtboXWXl5UZtDA6F6W/smLAD3561rPp3vVbwpdn6+r1gzlUmZv93b 2r4d7hsjdf/UhrnAJtw96JXxXh3OFXTfNRsLbIUGLY560PYDXHhCbXYnW3go4+AI SHxEs60goIMhVPEyzKowJjxQdiVU60CI9qqfGfHktC8xp+6E/xMcNbznFJeIEdzY QEtRnuTL5BQ018eFATwr =MwBS -----END PGP SIGNATURE-----