qemu: fd: Add a distinct set of APIs for 'direct' fd passing mode

Originally I envisioned a common set of APIs for both FD passing
approaches but it turns out they are not really compatible enough for it
to make sense to use one set of APIs.

As of such introduce a distinct set of APIs for the 'direct' mode, which
will later be used to convert all places that currently use
'qemuFDPassNewDirect' and later clean up the existing APIs.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2022-05-16 14:57:57 +02:00
parent e04acdf39d
commit bca9047906
2 changed files with 151 additions and 0 deletions

View File

@ -324,3 +324,132 @@ qemuFDPassGetPath(qemuFDPass *fdpass)
return fdpass->path; return fdpass->path;
} }
struct _qemuFDPassDirect {
int fd;
char *path;
char *name;
bool passed; /* passed to qemu via monitor */
};
void
qemuFDPassDirectFree(qemuFDPassDirect *fdpass)
{
if (!fdpass)
return;
VIR_FORCE_CLOSE(fdpass->fd);
g_free(fdpass->name);
g_free(fdpass->path);
g_free(fdpass);
}
/**
* qemuFDPassDirectNew:
* @name: Name of the fd (for monitor passing use-case)
* @fd: The FD, cleared when passed.
*
* The qemuFDPassDirect helper returned by this helper is used to hold a FD
* passed to qemu either direcly via FD number when used on commandline or the
* 'getfd' QMP command.
*/
qemuFDPassDirect *
qemuFDPassDirectNew(const char *name,
int *fd)
{
qemuFDPassDirect *fdpass = g_new0(qemuFDPassDirect, 1);
fdpass->name = g_strdup(name);
fdpass->fd = *fd;
*fd = -1;
return fdpass;
}
/**
* qemuFDPassDirectTransferCommand:
* @fdpass: The fd passing helper struct
* @cmd: Command to pass the filedescriptors to
*
* Pass the fds in @fdpass to a commandline object @cmd. @fdpass may be NULL
* in which case this is a no-op.
*/
void
qemuFDPassDirectTransferCommand(qemuFDPassDirect *fdpass,
virCommand *cmd)
{
if (!fdpass)
return;
virCommandPassFD(cmd, fdpass->fd, VIR_COMMAND_PASS_FD_CLOSE_PARENT);
fdpass->path = g_strdup_printf("%d", fdpass->fd);
fdpass->fd = -1;
}
/**
* qemuFDPassDirectTransferMonitor:
* @fdpass: The fd passing helper struct
* @mon: monitor object
*
* Pass the fds in @fdpass to qemu via the monitor. @fdpass may be NULL
* in which case this is a no-op. Caller needs to enter the monitor context.
*/
int
qemuFDPassDirectTransferMonitor(qemuFDPassDirect *fdpass,
qemuMonitor *mon)
{
if (!fdpass)
return 0;
if (qemuMonitorSendFileHandle(mon, fdpass->name, fdpass->fd) < 0)
return -1;
fdpass->path = g_strdup(fdpass->name);
VIR_FORCE_CLOSE(fdpass->fd);
fdpass->passed = true;
return 0;
}
/**
* qemuFDPassDirectTransferMonitorRollback:
* @fdpass: The fd passing helper struct
* @mon: monitor object
*
* Rolls back the addition of @fdpass to @mon if it was added originally.
*/
void
qemuFDPassDirectTransferMonitorRollback(qemuFDPassDirect *fdpass,
qemuMonitor *mon)
{
if (!fdpass || !fdpass->passed)
return;
ignore_value(qemuMonitorCloseFileHandle(mon, fdpass->name));
}
/**
* qemuFDPassDirectGetPath:
* @fdpass: The fd passing helper struct
*
* Returns the path/fd name that is used in qemu to refer to the passed FD.
* Note that it's only valid to call this function after @fdpass was already
* transferred to the command or monitor.
*/
const char *
qemuFDPassDirectGetPath(qemuFDPassDirect *fdpass)
{
if (!fdpass)
return NULL;
return fdpass->path;
}

View File

@ -53,3 +53,25 @@ qemuFDPassTransferMonitorRollback(qemuFDPass *fdpass,
const char * const char *
qemuFDPassGetPath(qemuFDPass *fdpass); qemuFDPassGetPath(qemuFDPass *fdpass);
typedef struct _qemuFDPassDirect qemuFDPassDirect;
void
qemuFDPassDirectFree(qemuFDPassDirect *fdpass);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuFDPassDirect, qemuFDPassDirectFree);
qemuFDPassDirect *
qemuFDPassDirectNew(const char *name,
int *fd);
void
qemuFDPassDirectTransferCommand(qemuFDPassDirect *fdpass,
virCommand *cmd);
int
qemuFDPassDirectTransferMonitor(qemuFDPassDirect *fdpass,
qemuMonitor *mon);
void
qemuFDPassDirectTransferMonitorRollback(qemuFDPassDirect *fdpass,
qemuMonitor *mon);
const char *
qemuFDPassDirectGetPath(qemuFDPassDirect *fdpass);