Daniel P. Berrangé <berra...@redhat.com> writes:

> On Mon, Oct 23, 2023 at 05:35:58PM -0300, Fabiano Rosas wrote:
>> Allow multifd to open file-backed channels. This will be used when
>> enabling the fixed-ram migration stream format which expects a
>> seekable transport.
>> 
>> The QIOChannel read and write methods will use the preadv/pwritev
>> versions which don't update the file offset at each call so we can
>> reuse the fd without re-opening for every channel.
>> 
>> Note that this is just setup code and multifd cannot yet make use of
>> the file channels.
>> 
>> Signed-off-by: Fabiano Rosas <faro...@suse.de>
>> ---
>>  migration/file.c      | 64 +++++++++++++++++++++++++++++++++++++++++--
>>  migration/file.h      | 10 +++++--
>>  migration/migration.c |  2 +-
>>  migration/multifd.c   | 14 ++++++++--
>>  migration/options.c   |  7 +++++
>>  migration/options.h   |  1 +
>>  6 files changed, 90 insertions(+), 8 deletions(-)
>> 
>> diff --git a/migration/file.c b/migration/file.c
>> index cf5b1bf365..93b9b7bf5d 100644
>> --- a/migration/file.c
>> +++ b/migration/file.c
>> @@ -17,6 +17,12 @@
>
>> +void file_send_channel_create(QIOTaskFunc f, void *data)
>> +{
>> +    QIOChannelFile *ioc;
>> +    QIOTask *task;
>> +    Error *errp = NULL;
>> +
>> +    ioc = qio_channel_file_new_path(outgoing_args.fname,
>> +                                    outgoing_args.flags,
>> +                                    outgoing_args.mode, &errp);
>> +    if (!ioc) {
>> +        file_migration_cancel(errp);
>> +        return;
>> +    }
>> +
>> +    task = qio_task_new(OBJECT(ioc), f, (gpointer)data, NULL);
>> +    qio_task_run_in_thread(task, qio_channel_file_connect_worker,
>> +                           (gpointer)data, NULL, NULL);
>> +}
>> +
>>  void file_start_outgoing_migration(MigrationState *s, const char *filespec,
>>                                     Error **errp)
>>  {
>> -    g_autofree char *filename = g_strdup(filespec);
>>      g_autoptr(QIOChannelFile) fioc = NULL;
>> +    g_autofree char *filename = g_strdup(filespec);
>>      uint64_t offset = 0;
>>      QIOChannel *ioc;
>> +    int flags = O_CREAT | O_TRUNC | O_WRONLY;
>> +    mode_t mode = 0660;
>>  
>>      trace_migration_file_outgoing(filename);
>>  
>> @@ -50,12 +105,15 @@ void file_start_outgoing_migration(MigrationState *s, 
>> const char *filespec,
>>          return;
>>      }
>>  
>> -    fioc = qio_channel_file_new_path(filename, O_CREAT | O_WRONLY | O_TRUNC,
>> -                                     0600, errp);

By the way, we're experimenting with add-fd to flesh out the interface
with libvirt and I see that the flags here can conflict with the flags
set on the fd passed through `virsh --pass-fd ...` due to this at
monitor_fdset_dup_fd_add():

    if ((flags & O_ACCMODE) == (mon_fd_flags & O_ACCMODE)) {
        fd = mon_fdset_fd->fd;
        break;
    }

We're requiring the O_RDONLY, O_WRONLY, O_RDWR flags defined here to
match the fdset passed into QEMU. Should we just sync the code of the
two projects to use the same flags? That feels a little clumsy to me.

>> +    fioc = qio_channel_file_new_path(filename, flags, mode, errp);
>
> So this initially opens the file with O_CREAT|O_TRUNC which
> makes sense.
>
>>      if (!fioc) {
>>          return;
>>      }
>>  
>> +    outgoing_args.fname = g_strdup(filename);
>> +    outgoing_args.flags = flags;
>> +    outgoing_args.mode = mode;
>
> We're passing on O_CREAT|O_TRUNC to all the multifd threads too. This
> doesn't make sense to me - the file should already exist and be truncated
> by the time the threads open it. I would think they should only be using
> O_WRONLY and no mode at all.
>

Ok.

Reply via email to