mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
qemu-ga: use key-value store to avoid recycling fd handles after restart
Hosts hold on to handles provided by guest-file-open for periods that can span beyond the life of the qemu-ga process that issued them. Since these are issued starting from 0 on every restart, we run the risk of issuing duplicate handles after restarts/reboots. As a result, users with a stale copy of these handles may end up reading/writing corrupted data due to their existing handles effectively being re-assigned to an unexpected file or offset. We unfortunately do not issue handles as strings, but as integers, so a solution such as using UUIDs can't be implemented without introducing a new interface. As a workaround, we fix this by implementing a persistent key-value store that will be used to track the value of the last handle that was issued across restarts/reboots to avoid issuing duplicates. The store is automatically written to the same directory we currently set via --statedir to track fsfreeze state, and so should be applicable for stable releases where this flag is supported. A follow-up can use this same store for handling fsfreeze state, but that change is cosmetic and left out for now. Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> Cc: qemu-stable@nongnu.org * fixed guest_file_handle_add() return value from uint64_t to int64_t
This commit is contained in:
parent
c5dcb6ae23
commit
39097daf15
3 changed files with 204 additions and 6 deletions
|
@ -129,14 +129,22 @@ static struct {
|
|||
QTAILQ_HEAD(, GuestFileHandle) filehandles;
|
||||
} guest_file_state;
|
||||
|
||||
static void guest_file_handle_add(FILE *fh)
|
||||
static int64_t guest_file_handle_add(FILE *fh, Error **errp)
|
||||
{
|
||||
GuestFileHandle *gfh;
|
||||
int64_t handle;
|
||||
|
||||
handle = ga_get_fd_handle(ga_state, errp);
|
||||
if (error_is_set(errp)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
gfh = g_malloc0(sizeof(GuestFileHandle));
|
||||
gfh->id = fileno(fh);
|
||||
gfh->id = handle;
|
||||
gfh->fh = fh;
|
||||
QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static GuestFileHandle *guest_file_handle_find(int64_t id, Error **err)
|
||||
|
@ -158,7 +166,7 @@ int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, E
|
|||
{
|
||||
FILE *fh;
|
||||
int fd;
|
||||
int64_t ret = -1;
|
||||
int64_t ret = -1, handle;
|
||||
|
||||
if (!has_mode) {
|
||||
mode = "r";
|
||||
|
@ -184,9 +192,14 @@ int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, E
|
|||
return -1;
|
||||
}
|
||||
|
||||
guest_file_handle_add(fh);
|
||||
slog("guest-file-open, handle: %d", fd);
|
||||
return fd;
|
||||
handle = guest_file_handle_add(fh, err);
|
||||
if (error_is_set(err)) {
|
||||
fclose(fh);
|
||||
return -1;
|
||||
}
|
||||
|
||||
slog("guest-file-open, handle: %d", handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void qmp_guest_file_close(int64_t handle, Error **err)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue