implements a function to restart the daemon by command or signal

Because sometimes tho communication between daemon and KB is corrupted
after resuming from Standby or suspend, a restart function is
implemented.
It first calls the quit() funtion, then it calls main() again with the
original parameter list.

There are two ways to restart the daemon:
- send the string "restart some-description-as-one-word" to the cmd-pipe
  (normally /dev/input/ckb1/cmd or /dev/input/ckb2/cmd, dependign on
  what device gets what usb number

- sending SIGUSR1 to the daemon-process (as root).

Later on, there may be a user interface in the client
for the first method.
This commit is contained in:
Lutz Eichler
2017-02-26 18:42:55 +01:00
parent 9b234127b9
commit 64bebfef17
7 changed files with 59 additions and 5 deletions
+12
View File
@@ -203,6 +203,18 @@ The latest firmware versions and their URLs can be found in the `FIRMWARE` docum
When the device reconnects you should see the new firmware version in its `fwversion` node; if you see `0000` instead it means that the keyboard did not update successfully and will need another `fwupdate` command in order to function again. If the update fails repeatedly, try connecting the keyboard to a Windows PC and using the official firmware update in CUE.
Restart
-------
Because sometimes tho communication between daemon and KB is corrupted after resuming from Standby or suspend, a restart function is implemented.
It first calls the quit() funtion, then it calls main() again with the original parameter list.
There are two ways to restart the daemon:
- send the string "restart some-description-as-one-word" to the cmd-pipe (normally /dev/input/ckb1/cmd or /dev/input/ckb2/cmd, dependign on what device gets what usb number
- sending SIGUSR1 to the daemon-process (as root).
Later on, there may be a user interface in the client for the first method.
Security
--------
+5 -1
View File
@@ -51,7 +51,8 @@ static const char* const cmd_strings[CMD_COUNT - 1] = {
"notify",
"inotify",
"get"
"get",
"restart"
};
#define TRY_WITH_RESET(action) \
@@ -276,6 +277,9 @@ int readcmd(usbdevice* kb, const char* line){
continue;
}
break;
case RESTART:
vt->do_cmd[command](kb, mode, notifynumber, 0, word);
break;
default:;
}
// For anything else, split the parameter at the colon
+4 -2
View File
@@ -58,14 +58,15 @@ typedef enum {
NOTIFY,
INOTIFY,
GET,
RESTART,
CMD_LAST = GET
CMD_LAST = RESTART
} cmd;
#define CMD_COUNT (CMD_LAST - CMD_FIRST + 2)
#define CMD_DEV_COUNT (CMD_LAST - CMD_VT_FIRST + 1)
// Device command vtable. Most have a standard prototype, but a few are exceptions.
// Not all parameters are used by all commands - they are sometimes repurposed or used as dummy arguemnts. See relevant headers.
// Not all parameters are used by all commands - they are sometimes repurposed or used as dummy arguments. See relevant headers.
typedef void (*cmdhandler)(usbdevice* kb, usbmode* modeidx, int notifyidx, int keyindex, const char* parameter); // Normal command
typedef int (*cmdhandler_io)(usbdevice* kb, usbmode* modeidx, int notifyidx, int keyindex, const char* parameter); // Command with hardware I/O - returns zero on success
typedef void (*cmdhandler_mac)(usbdevice* kb, usbmode* modeidx, int notifyidx, const char* keys, const char* assignment); // Macro command has a different left-side handler
@@ -117,6 +118,7 @@ typedef union devcmd {
cmdhandler notify;
cmdhandler inotify;
cmdhandler get;
cmdhandler restart;
// Extra functions not command-related
// device.h
+3
View File
@@ -59,6 +59,7 @@ const devcmd vtable_keyboard = {
.notify = cmd_notify,
.inotify = cmd_inotify,
.get = cmd_get,
.restart = cmd_restart,
.start = start_dev,
.setmodeindex = int1_void_none,
@@ -105,6 +106,7 @@ const devcmd vtable_keyboard_nonrgb = {
.notify = cmd_notify,
.inotify = cmd_inotify,
.get = cmd_get,
.restart = cmd_restart,
.start = start_kb_nrgb,
.setmodeindex = setmodeindex_nrgb,
@@ -151,6 +153,7 @@ const devcmd vtable_mouse = {
.notify = cmd_notify,
.inotify = cmd_none,
.get = cmd_get,
.restart = cmd_restart,
.start = start_dev,
.setmodeindex = int1_void_none,
+23 -2
View File
@@ -4,11 +4,16 @@
#include "led.h"
#include "notify.h"
static int main_ac;
static char **main_av;
// usb.c
extern volatile int reset_stop;
extern int features_mask;
// device.c
extern int hwload_mode;
static void quit2(char mut);
extern int restart();
// Timespec utility function
void timespec_add(struct timespec* timespec, long nanoseconds){
@@ -17,12 +22,18 @@ void timespec_add(struct timespec* timespec, long nanoseconds){
timespec->tv_nsec = nanoseconds % 1000000000;
}
void quit(){
static void quit(){
quit2(1);
}
// try to close files maybe without locking the mutex
// if mut == true then lock
void quit2(char mut){
// Abort any USB resets in progress
reset_stop = 1;
for(int i = 1; i < DEV_MAX; i++){
// Before closing, set all keyboards back to HID input mode so that the stock driver can still talk to them
pthread_mutex_lock(devmutex + i);
if (mut) pthread_mutex_lock(devmutex + i);
if(IS_CONNECTED(keyboard + i)){
revertusb(keyboard + i);
closeusb(keyboard + i);
@@ -69,6 +80,8 @@ int main(int argc, char** argv){
// Set output pipes to buffer on newlines, if they weren't set that way already
setlinebuf(stdout);
setlinebuf(stderr);
main_ac = argc;
main_av = argv;
printf(" ckb: Corsair RGB driver %s\n", CKB_VERSION_STR);
// If --help occurs anywhere in the command-line, don't launch the program but instead print usage
@@ -189,14 +202,22 @@ int main(int argc, char** argv){
sigdelset(&signals, SIGTERM);
sigdelset(&signals, SIGINT);
sigdelset(&signals, SIGQUIT);
sigdelset(&signals, SIGUSR1);
// Set up signal handlers for quitting the service.
sigprocmask(SIG_SETMASK, &signals, 0);
signal(SIGTERM, sighandler);
signal(SIGINT, sighandler);
signal(SIGQUIT, sighandler);
signal(SIGUSR1, (void (*)())restart);
// Start the USB system
int result = usbmain();
quit();
return result;
}
int restart() {
ckb_err("restart called, running quit without mutex-lock.\n");
quit2(0);
return main(main_ac, main_av);
}
+8
View File
@@ -217,3 +217,11 @@ void cmd_get(usbdevice* kb, usbmode* mode, int nnumber, int dummy, const char* s
_cmd_get(kb, mode, nnumber, setting);
pthread_mutex_unlock(imutex(kb));
}
extern int restart();
void cmd_restart(usbdevice* kb, usbmode* mode, int nnumber, int dummy, const char* content) {
ckb_info("RESTART called with %s\n", content);
nprintf(kb, -1, 0, "RESTART called with %s\n", content);
restart();
}
+4
View File
@@ -24,4 +24,8 @@ void cmd_notify(usbdevice* kb, usbmode* mode, int nnumber, int keyindex, const c
// MUTEXES: Locks imutex during operation. Unlocks on close.
void cmd_get(usbdevice* kb, usbmode* mode, int nnumber, int dummy, const char* setting);
// Just for debugging puposes. Should echo the given string to stderr ([I]) and all open notify channels.
// At last it does a restart of the daemon
void cmd_restart(usbdevice* kb, usbmode* mode, int nnumber, int dummy, const char* content);
#endif // NOTIFY_H