2018-11-14 14:59:56 +01:00
/*
Copyright ( C ) 2018 Proxmox Server Solutions GmbH
Copyright : qemumonitor is under GNU GPL , the GNU General Public License .
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; version 2 dated June , 1991.
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 .
Author : Dominik Csapak < d . csapak @ proxmox . com >
*/
2020-10-19 14:18:37 +02:00
# include <sys/syscall.h>
# ifndef __NR_pidfd_open
# define __NR_pidfd_open 434
# endif
# ifndef __NR_pidfd_send_signal
# define __NR_pidfd_send_signal 424
# endif
2020-11-24 15:04:06 +01:00
# define VERBOSE_PRINT(...) do { if (verbose) { printf(__VA_ARGS__); fflush(stdout); } } while (0)
2018-11-14 14:59:56 +01:00
static inline void log_neg ( int errval , const char * msg )
{
if ( errval < 0 ) {
perror ( msg ) ;
}
}
static inline void bail_neg ( int errval , const char * msg )
{
if ( errval < 0 ) {
perror ( msg ) ;
exit ( EXIT_FAILURE ) ;
}
}
2020-10-19 14:18:37 +02:00
static inline int
pidfd_open ( pid_t pid , unsigned int flags )
{
return syscall ( __NR_pidfd_open , pid , flags ) ;
}
static inline int
pidfd_send_signal ( int pidfd , int sig , siginfo_t * info , unsigned int flags )
{
return syscall ( __NR_pidfd_send_signal , pidfd , sig , info , flags ) ;
}
qmeventd: add handling for -no-shutdown QEMU instances
We take care of killing QEMU processes when a guest shuts down manually.
QEMU will not exit itself, if started with -no-shutdown, but it will
still emit a "SHUTDOWN" event, which we await and then send SIGTERM.
This additionally allows us to handle backups in such situations. A
vzdump instance will connect to our socket and identify itself as such
in the handshake, sending along a VMID which will be marked as backing
up until the file handle is closed.
When a SHUTDOWN event is received while the VM is backing up, we do not
kill the VM. And when the vzdump handle is closed, we check if the
guest has started up since, and only if it's determined to still be
turned off, we then finally kill QEMU.
We cannot wait for QEMU directly to finish the backup (i.e. with
query-backup), as that would kill the VM too fast for vzdump to send the
last 'query-backup' to mark the backup as successful and done.
For handling 'query-status' messages sent to QEMU, a state-machine-esque
protocol is implemented into the Client struct (ClientState). This is
necessary, since QMP works asynchronously, and results arrive on the
same channel as events and even the handshake.
For referencing QEMU Clients from vzdump messages, they are kept in a
hash table. This requires linking against glib.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
2020-10-19 14:18:36 +02:00
typedef enum {
CLIENT_NONE ,
CLIENT_QEMU ,
CLIENT_VZDUMP
} ClientType ;
typedef enum {
STATE_HANDSHAKE ,
STATE_IDLE ,
STATE_EXPECT_STATUS_RESP ,
STATE_TERMINATING
} ClientState ;
2018-11-14 14:59:56 +01:00
struct Client {
char buf [ 4096 ] ;
qmeventd: add handling for -no-shutdown QEMU instances
We take care of killing QEMU processes when a guest shuts down manually.
QEMU will not exit itself, if started with -no-shutdown, but it will
still emit a "SHUTDOWN" event, which we await and then send SIGTERM.
This additionally allows us to handle backups in such situations. A
vzdump instance will connect to our socket and identify itself as such
in the handshake, sending along a VMID which will be marked as backing
up until the file handle is closed.
When a SHUTDOWN event is received while the VM is backing up, we do not
kill the VM. And when the vzdump handle is closed, we check if the
guest has started up since, and only if it's determined to still be
turned off, we then finally kill QEMU.
We cannot wait for QEMU directly to finish the backup (i.e. with
query-backup), as that would kill the VM too fast for vzdump to send the
last 'query-backup' to mark the backup as successful and done.
For handling 'query-status' messages sent to QEMU, a state-machine-esque
protocol is implemented into the Client struct (ClientState). This is
necessary, since QMP works asynchronously, and results arrive on the
same channel as events and even the handshake.
For referencing QEMU Clients from vzdump messages, they are kept in a
hash table. This requires linking against glib.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
2020-10-19 14:18:36 +02:00
unsigned int buflen ;
2018-11-14 14:59:56 +01:00
int fd ;
pid_t pid ;
qmeventd: add handling for -no-shutdown QEMU instances
We take care of killing QEMU processes when a guest shuts down manually.
QEMU will not exit itself, if started with -no-shutdown, but it will
still emit a "SHUTDOWN" event, which we await and then send SIGTERM.
This additionally allows us to handle backups in such situations. A
vzdump instance will connect to our socket and identify itself as such
in the handshake, sending along a VMID which will be marked as backing
up until the file handle is closed.
When a SHUTDOWN event is received while the VM is backing up, we do not
kill the VM. And when the vzdump handle is closed, we check if the
guest has started up since, and only if it's determined to still be
turned off, we then finally kill QEMU.
We cannot wait for QEMU directly to finish the backup (i.e. with
query-backup), as that would kill the VM too fast for vzdump to send the
last 'query-backup' to mark the backup as successful and done.
For handling 'query-status' messages sent to QEMU, a state-machine-esque
protocol is implemented into the Client struct (ClientState). This is
necessary, since QMP works asynchronously, and results arrive on the
same channel as events and even the handshake.
For referencing QEMU Clients from vzdump messages, they are kept in a
hash table. This requires linking against glib.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
2020-10-19 14:18:36 +02:00
ClientType type ;
ClientState state ;
// only relevant for type=CLIENT_QEMU
struct {
char vmid [ 16 ] ;
unsigned short graceful ;
unsigned short guest ;
bool term_check_queued ;
bool backup ;
} qemu ;
// only relevant for type=CLIENT_VZDUMP
struct {
// vmid of referenced backup
char vmid [ 16 ] ;
} vzdump ;
2018-11-14 14:59:56 +01:00
} ;
2020-10-19 14:18:37 +02:00
struct CleanupData {
pid_t pid ;
int pidfd ;
} ;
2018-11-14 14:59:56 +01:00
void handle_qmp_handshake ( struct Client * client ) ;
void handle_qmp_event ( struct Client * client , struct json_object * obj ) ;
qmeventd: add handling for -no-shutdown QEMU instances
We take care of killing QEMU processes when a guest shuts down manually.
QEMU will not exit itself, if started with -no-shutdown, but it will
still emit a "SHUTDOWN" event, which we await and then send SIGTERM.
This additionally allows us to handle backups in such situations. A
vzdump instance will connect to our socket and identify itself as such
in the handshake, sending along a VMID which will be marked as backing
up until the file handle is closed.
When a SHUTDOWN event is received while the VM is backing up, we do not
kill the VM. And when the vzdump handle is closed, we check if the
guest has started up since, and only if it's determined to still be
turned off, we then finally kill QEMU.
We cannot wait for QEMU directly to finish the backup (i.e. with
query-backup), as that would kill the VM too fast for vzdump to send the
last 'query-backup' to mark the backup as successful and done.
For handling 'query-status' messages sent to QEMU, a state-machine-esque
protocol is implemented into the Client struct (ClientState). This is
necessary, since QMP works asynchronously, and results arrive on the
same channel as events and even the handshake.
For referencing QEMU Clients from vzdump messages, they are kept in a
hash table. This requires linking against glib.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
2020-10-19 14:18:36 +02:00
void handle_qmp_return ( struct Client * client , struct json_object * data , bool error ) ;
void handle_vzdump_handshake ( struct Client * client , struct json_object * data ) ;
2018-11-14 14:59:56 +01:00
void handle_client ( struct Client * client ) ;
void add_new_client ( int client_fd ) ;
void cleanup_client ( struct Client * client ) ;
qmeventd: add handling for -no-shutdown QEMU instances
We take care of killing QEMU processes when a guest shuts down manually.
QEMU will not exit itself, if started with -no-shutdown, but it will
still emit a "SHUTDOWN" event, which we await and then send SIGTERM.
This additionally allows us to handle backups in such situations. A
vzdump instance will connect to our socket and identify itself as such
in the handshake, sending along a VMID which will be marked as backing
up until the file handle is closed.
When a SHUTDOWN event is received while the VM is backing up, we do not
kill the VM. And when the vzdump handle is closed, we check if the
guest has started up since, and only if it's determined to still be
turned off, we then finally kill QEMU.
We cannot wait for QEMU directly to finish the backup (i.e. with
query-backup), as that would kill the VM too fast for vzdump to send the
last 'query-backup' to mark the backup as successful and done.
For handling 'query-status' messages sent to QEMU, a state-machine-esque
protocol is implemented into the Client struct (ClientState). This is
necessary, since QMP works asynchronously, and results arrive on the
same channel as events and even the handshake.
For referencing QEMU Clients from vzdump messages, they are kept in a
hash table. This requires linking against glib.
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
2020-10-19 14:18:36 +02:00
void terminate_client ( struct Client * client ) ;
void terminate_check ( struct Client * client ) ;