All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: Sanidhya Kashyap <sanidhya.iiith@gmail.com>
Cc: qemu list <qemu-devel@nongnu.org>, Juan Quintela <quintela@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v5 2/6] BitmapLog: bitmap dump code
Date: Tue, 12 Aug 2014 12:15:18 +0100	[thread overview]
Message-ID: <20140812111518.GF2384@work-vm> (raw)
In-Reply-To: <1406862751-24008-3-git-send-email-sanidhya.iiith@gmail.com>

* Sanidhya Kashyap (sanidhya.iiith@gmail.com) wrote:
> In this patch, I have incorporated an enum named QemuProcess
> which defines what kind of process is being executed i.e.
> none --> no other process except the VM execution
> migration --> migration is being executed
> bitmap-dump --> bitmap dump process is undergoing

OK, so that's the right idea; I suspect 'process' is probably the wrong
word - and we use it to mean too many things already.  Why don't you
stick with the 'dbu':

instead of:
static QemuProcess dbu = QEMU_PROCESS_NONE;

I'd use:
static QemuDirtyBitmapUser dbu = QEMU_DBU_NONE;

doesn't look too bad to me, and is more explicit about what it's for.

> Besides this, I have tried to incorporate the dynamic change of
> the last_ram_offset, if it gets change. The downside is that I am
> holding lock for a longer period of time and I don't know whether
> that should be done or not. I am also doing some allocation when
> locked.
> I am not sure whether last_ram_offset gets changed when a device
> is hot plugged or hot unplugged.
> 
> I have modified the variables name as:
> current-iteration: for the current iteration under process
> iterations: total iterations that will be done which is constant
> period: the delay in each iteration.
> 
> Signed-off-by: Sanidhya Kashyap <sanidhya.iiith@gmail.com>
> ---
>  hmp-commands.hx         |  16 ++
>  hmp.c                   |  18 +++
>  hmp.h                   |   1 +
>  include/exec/cpu-all.h  |   5 +-
>  include/sysemu/sysemu.h |   5 +
>  migration.c             |  12 ++
>  qapi-schema.json        |  35 +++++
>  qmp-commands.hx         |  34 +++++
>  savevm.c                | 378 ++++++++++++++++++++++++++++++++++++++++++++++++
>  vl.c                    |  24 +++
>  10 files changed, 527 insertions(+), 1 deletion(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index d0943b1..30b553e 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1788,6 +1788,22 @@ STEXI
>  show available trace events and their state
>  ETEXI
>  
> +     {
> +        .name       = "ldb|log_dirty_bitmap",
> +        .args_type  = "filename:s,iterations:i?,period:i?",
> +        .params     = "filename iterations period",
> +        .help       = "dumps the memory's dirty bitmap to file\n\t\t\t"
> +                      "filename: name of the file in which the bitmap will be saved\n\t\t\t"
> +                      "iterations: number of times, the memory will be logged\n\t\t\t"
> +                      "period: time difference in milliseconds between each iteration",
> +        .mhandler.cmd = hmp_log_dirty_bitmap,
> +    },
> +STEXI
> +@item ldb or log_dirty_bitmap @var{filename}
> +@findex log_dirty_bitmap
> +dumps the writable working set of a VM's memory to a file
> +ETEXI
> +
>  STEXI
>  @end table
>  ETEXI
> diff --git a/hmp.c b/hmp.c
> index 4d1838e..d067420 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1318,6 +1318,24 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, &err);
>  }
>  
> +void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict)
> +{
> +    const char *filename = qdict_get_str(qdict, "filename");
> +    bool has_iterations = qdict_haskey(qdict, "iterations");
> +    int64_t iterations = qdict_get_try_int(qdict, "iterations", 3);
> +    bool has_period = qdict_haskey(qdict, "period");
> +    int64_t period = qdict_get_try_int(qdict, "period", 10);
> +    Error *err = NULL;
> +
> +    qmp_log_dirty_bitmap(filename, has_iterations, iterations,
> +                         has_period, period, &err);
> +    if (err) {
> +        monitor_printf(mon, "log_dirty_bitmap: %s\n", error_get_pretty(err));
> +        error_free(err);
> +        return;
> +    }
> +}
> +
>  void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
>  {
>      Error *err = NULL;
> diff --git a/hmp.h b/hmp.h
> index 4fd3c4a..0895182 100644
> --- a/hmp.h
> +++ b/hmp.h
> @@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict);
>  void hmp_object_add(Monitor *mon, const QDict *qdict);
>  void hmp_object_del(Monitor *mon, const QDict *qdict);
>  void hmp_info_memdev(Monitor *mon, const QDict *qdict);
> +void hmp_log_dirty_bitmap(Monitor *mon, const QDict *qdict);
>  void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
>  void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
>  void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index f91581f..179fc5b 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -297,13 +297,16 @@ CPUArchState *cpu_copy(CPUArchState *env);
>  
>  /* memory API */
>  
> +/* global name which is used with both migration and bitmap dump */
> +#define RAMBLOCK_NAME_LENGTH 256
> +
>  typedef struct RAMBlock {
>      struct MemoryRegion *mr;
>      uint8_t *host;
>      ram_addr_t offset;
>      ram_addr_t length;
>      uint32_t flags;
> -    char idstr[256];
> +    char idstr[RAMBLOCK_NAME_LENGTH];
>      /* Reads can take either the iothread or the ramlist lock.
>       * Writes must take both locks.
>       */
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index d8539fd..304a3e1 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -227,4 +227,9 @@ extern QemuOptsList qemu_net_opts;
>  extern QemuOptsList qemu_global_opts;
>  extern QemuOptsList qemu_mon_opts;
>  
> +/* migration vs dirty bitmap process */
> +bool qemu_process_check(QemuProcess user);
> +void qemu_process_set(QemuProcess user);
> +const char *get_qemu_process_as_string(void);
> +
>  #endif
> diff --git a/migration.c b/migration.c
> index 8d675b3..7b61b1e 100644
> --- a/migration.c
> +++ b/migration.c
> @@ -117,6 +117,7 @@ static void process_incoming_migration_co(void *opaque)
>      } else {
>          runstate_set(RUN_STATE_PAUSED);
>      }
> +    qemu_process_set(QEMU_PROCESS_NONE);
>  }
>  
>  void process_incoming_migration(QEMUFile *f)
> @@ -317,6 +318,7 @@ static void migrate_fd_cleanup(void *opaque)
>      }
>  
>      notifier_list_notify(&migration_state_notifiers, s);
> +    qemu_process_set(QEMU_PROCESS_NONE);
>  }
>  
>  void migrate_fd_error(MigrationState *s)
> @@ -326,6 +328,7 @@ void migrate_fd_error(MigrationState *s)
>      s->state = MIG_STATE_ERROR;
>      trace_migrate_set_state(MIG_STATE_ERROR);
>      notifier_list_notify(&migration_state_notifiers, s);
> +    qemu_process_set(QEMU_PROCESS_NONE);
>  }
>  
>  static void migrate_fd_cancel(MigrationState *s)
> @@ -436,6 +439,15 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
>          return;
>      }
>  
> +    if (!qemu_process_check(QEMU_PROCESS_NONE) &&
> +        !qemu_process_check(QEMU_PROCESS_MIGRATION)) {
> +        error_setg(errp, "Migration not possible, since %s "
> +                   "is in progress.\n", get_qemu_process_as_string());

Don't need that '\n'

> +        return;
> +    }
> +
> +    qemu_process_set(QEMU_PROCESS_MIGRATION);
> +
>      s = migrate_init(&params);
>  
>      if (strstart(uri, "tcp:", &p)) {
> diff --git a/qapi-schema.json b/qapi-schema.json
> index b11aad2..dced3c2 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3480,3 +3480,38 @@
>  # Since: 2.1
>  ##
>  { 'command': 'rtc-reset-reinjection' }
> +
> +##
> +# QemuProcess
> +#
> +# @none: no other process is being executed besides a simple VM execution.
> +#
> +# @migration: migration process is going on.
> +#
> +# @bitmap-dump: bitmap dump process is being executed.
> +#
> +# Since 2.2
> +##
> +{ 'enum': 'QemuProcess',
> +  'data': [ 'none', 'migration', 'bitmap-dump' ] }
> +
> +##
> +# @log-dirty-bitmap
> +#
> +# This command will dump the dirty bitmap to a file by logging the
> +# memory for a specified number of times with a defined time difference
> +#
> +# @filename: name of the file in which the bitmap will be saved.
> +#
> +# @iterations: number of times the memory will be logged (optional). The
> +# and max values are 3 and 100000 respectively.
> +#
> +# @period: time difference in milliseconds between each iteration (optional).
> +# The min and max values are 10 and 100000 respectively.
> +#
> +# Since 2.2
> +##
> +{ 'command' : 'log-dirty-bitmap',
> +  'data'    : { 'filename'      : 'str',
> +                '*iterations'   : 'int',
> +                '*period'       : 'int' } }
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 4be4765..2ead2ca 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -3753,5 +3753,39 @@ Example:
>  
>  -> { "execute": "rtc-reset-reinjection" }
>  <- { "return": {} }
> +EQMP
> +
> +    {
> +        .name       = "log-dirty-bitmap",
> +        .args_type  = "filename:s,iterations:i?,period:i?",
> +        .mhandler.cmd_new = qmp_marshal_input_log_dirty_bitmap,
> +    },
> +
> +SQMP
> +log-dirty-bitmap
> +----------------
> +
> +start logging the memory of the VM for writable working set
> +
> +Arguments:
> +
> +- "filename": name of the file, in which the bitmap will be saved.
> +
> +- "iterations": number of times, the memory will be logged (optional).
> +  The min and max values are 3 and 100000 respectively.
> +
> +- "period": time difference in milliseconds between each iteration (optional).
> +   The min and max values are 10 and 100000 respectively.
> +
> +Examples:
> +-> { "execute": "log-dirty-bitmap",
> +     "arguments": {
> +         "filename": "/tmp/fileXXX",
> +         "iterations": 3,
> +         "period": 10 } }
> +
> +<- { "return": {} }
>  
> +Note: The iterations, and period parameters are optional. iterations default
> +value is 3 while that of period is 10.
>  EQMP
> diff --git a/savevm.c b/savevm.c
> index e19ae0a..125e5ed 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -42,6 +42,9 @@
>  #include "qemu/iov.h"
>  #include "block/snapshot.h"
>  #include "block/qapi.h"
> +#include "exec/address-spaces.h"
> +#include "exec/ram_addr.h"
> +#include "qemu/bitmap.h"
>  
>  
>  #ifndef ETH_P_RARP
> @@ -1137,6 +1140,381 @@ void do_savevm(Monitor *mon, const QDict *qdict)
>      }
>  }
>  
> +/*
> + * Adding the functionality of continuous logging of the
> + * dirty bitmap which is almost similar to the migration
> + * thread
> + */
> +
> +enum {
> +    LOG_BITMAP_STATE_ERROR = -1,
> +    LOG_BITMAP_STATE_NONE,
> +    LOG_BITMAP_STATE_ACTIVE,
> +    LOG_BITMAP_STATE_CANCELING,
> +    LOG_BITMAP_STATE_COMPLETED
> +};
> +
> +typedef struct BitmapLogState BitmapLogState;
> +static int64_t MIN_ITERATION_VALUE = 3;
> +static int64_t MIN_PERIOD_VALUE = 10;
> +static int64_t MAX_ITERATION_VALUE = 100000;
> +static int64_t MAX_PERIOD_VALUE = 100000;
> +
> +struct BitmapLogState {
> +    int state;
> +    int fd;
> +    int64_t current_period;
> +    int64_t current_iteration;
> +    int64_t iterations;
> +    unsigned long *log_bitmap_array;
> +    QemuThread thread;
> +};
> +
> +/*
> + * helper functions
> + */
> +
> +static inline void log_bitmap_lock(void)
> +{
> +    qemu_mutex_lock_iothread();
> +    qemu_mutex_lock_ramlist();
> +}
> +
> +static inline void log_bitmap_unlock(void)
> +{
> +    qemu_mutex_unlock_ramlist();
> +    qemu_mutex_unlock_iothread();
> +}
> +
> +static inline void log_bitmap_set_dirty(ram_addr_t addr,
> +                                        unsigned long *log_bitmap_array)
> +{
> +    long nr  = addr >> TARGET_PAGE_BITS;
> +    set_bit(nr, log_bitmap_array);
> +}
> +
> +static bool log_bitmap_set_status(BitmapLogState *b,
> +                                  int old_state,
> +                                  int new_state)
> +{
> +    return atomic_cmpxchg(&b->state, old_state, new_state);
> +}
> +
> +/*
> + * inspired from migration mechanism
> + */
> +
> +static BitmapLogState *log_bitmap_get_current_state(void)
> +{
> +    static BitmapLogState current_bitmaplogstate = {
> +        .state = LOG_BITMAP_STATE_NONE,
> +        .log_bitmap_array = NULL,
> +    };
> +
> +    return &current_bitmaplogstate;
> +}
> +
> +/*
> + * syncing the log_bitmap with the ram_list dirty bitmap
> + */
> +
> +static void log_bitmap_dirty_bitmap_sync(unsigned long *log_bitmap_array)
> +{
> +    RAMBlock *block;
> +    uint64_t counter = 0; /* 0 means log bitmap */
> +    address_space_sync_dirty_bitmap(&address_space_memory);
> +    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
> +        qemu_bitmap_sync_range(block->mr->ram_addr, block->length,
> +                               log_bitmap_array, &counter);
> +    }
> +}
> +
> +static inline bool value_in_range(int64_t value, int64_t min_value,
> +                                  int64_t max_value, const char *str,
> +                                  Error **errp)
> +{
> +    if (value < min_value) {
> +        error_setg(errp, "%s's value must be greater than %ld",
> +                         str, min_value);
> +        return false;
> +    }
> +    if (value > max_value) {
> +        error_setg(errp, "%s's value must be less than %ld",
> +                         str, max_value);
> +        return false;
> +    }
> +    return true;
> +}
> +
> +static inline void log_bitmap_close(BitmapLogState *b)
> +{
> +    log_bitmap_lock();
> +    memory_global_dirty_log_stop();
> +    log_bitmap_unlock();
> +
> +    g_free(b->log_bitmap_array);
> +    b->log_bitmap_array = NULL;
> +    qemu_close(b->fd);
> +    b->fd = -1;
> +}
> +
> +static bool log_bitmap_ram_block_info_dump(int fd, int64_t ram_bitmap_pages,
> +                                           bool dump_blocks_info)
> +{
> +    int block_count = 0;
> +    int block_name_length;
> +    RAMBlock *block;
> +    int ret;
> +
> +    if (qemu_write_full(fd, &ram_bitmap_pages, sizeof(int64_t)) < 0) {
> +        return true;
> +    }
> +
> +    if (dump_blocks_info) {
> +
> +        QTAILQ_FOREACH(block, &ram_list.blocks, next) {
> +            block_count++;
> +        }
> +
> +        ret = qemu_write_full(fd, &block_count, sizeof(int));
> +        if (ret < sizeof(int)) {
> +            return true;
> +        }
> +
> +        QTAILQ_FOREACH(block, &ram_list.blocks, next) {
> +            block_name_length = strlen(block->idstr) + 1;
> +            ret = qemu_write_full(fd, &block_name_length, sizeof(int));
> +            if (ret < sizeof(int)) {
> +                return true;
> +            }
> +
> +            ret = qemu_write_full(fd, &(block->idstr), sizeof(char) *
> +                                  block_name_length);
> +            if (ret < sizeof(char) * block_name_length) {
> +                return true;
> +            }
> +
> +            ret = qemu_write_full(fd, &(block->offset), sizeof(ram_addr_t));
> +            if (ret < sizeof(ram_addr_t)) {
> +                return true;
> +            }
> +
> +            ret = qemu_write_full(fd, &(block->length), sizeof(ram_addr_t));
> +            if (ret < sizeof(ram_addr_t)) {
> +                return true;
> +            }
> +        }
> +    }
> +    return false;
> +}
> +
> +static void log_bitmap_update_status(BitmapLogState *b)
> +{
> +    int s = b->state;
> +    switch (s) {
> +    case LOG_BITMAP_STATE_ACTIVE:
> +    case LOG_BITMAP_STATE_CANCELING:
> +    case LOG_BITMAP_STATE_ERROR:
> +        log_bitmap_set_status(b, s, LOG_BITMAP_STATE_COMPLETED);
> +    }
> +    return;
> +}
> +
> +static void *bitmap_logging_thread(void *opaque)
> +{
> +    /*
> +     * setup basic structures
> +     */
> +
> +    BitmapLogState *b = opaque;
> +    int fd = b->fd;
> +    int64_t current_ram_bitmap_pages, prev_ram_bitmap_pages;
> +    size_t bitmap_size = 0;
> +    unsigned long *temp_log_bitmap_array = NULL;
> +    char marker = 'M';
> +    int ret;
> +
> +    b->current_iteration = 1;
> +    log_bitmap_set_status(b, LOG_BITMAP_STATE_NONE,
> +                             LOG_BITMAP_STATE_ACTIVE);
> +
> +    current_ram_bitmap_pages = 0;
> +    prev_ram_bitmap_pages = 1;
> +
> +    /*
> +     *  start the logging period
> +     */
> +
> +    /*
> +     * need lock for getting the information about the ram pages.
> +     * This does not change on acquiring the lock
> +     */
> +    log_bitmap_lock();
> +    current_ram_bitmap_pages = last_ram_offset() >> TARGET_PAGE_BITS;
> +    bitmap_size = BITS_TO_LONGS(current_ram_bitmap_pages) *
> +                                sizeof(unsigned long);
> +    b->log_bitmap_array = bitmap_new(current_ram_bitmap_pages);
> +    if (b->log_bitmap_array == NULL) {
> +        b->state = LOG_BITMAP_STATE_ERROR;
> +        log_bitmap_unlock();
> +        goto log_thread_end;
> +    }
> +
> +    memory_global_dirty_log_start();
> +    log_bitmap_dirty_bitmap_sync(b->log_bitmap_array);
> +    log_bitmap_unlock();
> +
> +    /*
> +     * sync the dirty bitmap along with saving it
> +     * using the QEMUFile pointer.
> +     */
> +    while (b->current_iteration <= b->iterations) {
> +        if (!runstate_is_running() ||
> +            b->state != LOG_BITMAP_STATE_ACTIVE) {
> +            goto log_thread_end;
> +        }
> +
> +        /*
> +         * Need to calculate the ram pages again as there is a
> +         * possibility of the change in the memory
> +         */
> +        log_bitmap_lock();
> +        current_ram_bitmap_pages = last_ram_offset() >> TARGET_PAGE_BITS;
> +        if (current_ram_bitmap_pages != prev_ram_bitmap_pages) {
> +            temp_log_bitmap_array = bitmap_new(current_ram_bitmap_pages);
> +            if (temp_log_bitmap_array == NULL) {
> +                b->state = LOG_BITMAP_STATE_ERROR;
> +                log_bitmap_unlock();
> +                goto log_thread_end;
> +            }
> +            log_bitmap_dirty_bitmap_sync(temp_log_bitmap_array);
> +        } else {
> +            log_bitmap_dirty_bitmap_sync(b->log_bitmap_array);
> +        }
> +        log_bitmap_unlock();
> +
> +        if (current_ram_bitmap_pages != prev_ram_bitmap_pages) {
> +            prev_ram_bitmap_pages = current_ram_bitmap_pages;
> +            bitmap_size = BITS_TO_LONGS(current_ram_bitmap_pages) *
> +                                        sizeof(unsigned long);
> +            if (b->log_bitmap_array) {
> +                g_free(b->log_bitmap_array);
> +            }
> +            b->log_bitmap_array = temp_log_bitmap_array;
> +            temp_log_bitmap_array = NULL;
> +            if (log_bitmap_ram_block_info_dump(fd, current_ram_bitmap_pages,
> +                                               true)) {
> +                b->state = LOG_BITMAP_STATE_ERROR;
> +                goto log_thread_end;
> +            }
> +        } else {
> +            if (log_bitmap_ram_block_info_dump(fd, current_ram_bitmap_pages,
> +                                               false)) {
> +                b->state = LOG_BITMAP_STATE_ERROR;
> +                goto log_thread_end;
> +            }
> +        }
> +
> +        ret = qemu_write_full(fd, b->log_bitmap_array, bitmap_size);
> +        if (ret < bitmap_size) {
> +            b->state = LOG_BITMAP_STATE_ERROR;
> +            goto log_thread_end;
> +        }
> +
> +        ret = qemu_write_full(fd, &marker, sizeof(char));
> +        if (ret < sizeof(char)) {
> +            b->state = LOG_BITMAP_STATE_ERROR;
> +            goto log_thread_end;
> +        }
> +        g_usleep(b->current_period * 1000);
> +        b->current_iteration++;
> +        bitmap_zero(b->log_bitmap_array, current_ram_bitmap_pages);
> +    }
> +
> +    /*
> +     * stop the logging period.
> +     */
> + log_thread_end:
> +    log_bitmap_close(b);
> +    log_bitmap_update_status(b);
> +    qemu_process_set(QEMU_PROCESS_NONE);
> +    return NULL;
> +}
> +
> +void qmp_log_dirty_bitmap(const char *filename, bool has_iterations,
> +                          int64_t iterations, bool has_period,
> +                          int64_t period, Error **errp)
> +{
> +    int fd = -1;
> +    BitmapLogState *b = log_bitmap_get_current_state();
> +    Error *local_err = NULL;
> +
> +    if (!runstate_is_running()) {
> +        error_setg(errp, "Guest is not in a running state");
> +        return;
> +    }
> +
> +    if (!qemu_process_check(QEMU_PROCESS_NONE) &&
> +        !qemu_process_check(QEMU_PROCESS_BITMAP_DUMP)) {
> +        error_setg(errp, "Dirty bitmap dumping not possible, since %s "
> +                   "is in progress.\n", get_qemu_process_as_string());
> +        return;
> +    }
> +
> +    qemu_process_set(QEMU_PROCESS_BITMAP_DUMP);
> +
> +    if (b->state == LOG_BITMAP_STATE_ACTIVE ||
> +        b->state == LOG_BITMAP_STATE_CANCELING) {
> +        error_setg(errp, "dirty bitmap dump in progress");
> +        return;
> +    }
> +
> +    b->state = LOG_BITMAP_STATE_NONE;
> +
> +    /*
> +     * checking the iteration range
> +     */
> +    if (!has_iterations) {
> +        b->iterations = MIN_ITERATION_VALUE;
> +    } else if (!value_in_range(iterations, MIN_ITERATION_VALUE,
> +                               MAX_ITERATION_VALUE, "iterations", &local_err)) {
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +        }
> +        return;
> +    } else {
> +        b->iterations = iterations;
> +    }
> +
> +    /*
> +     * checking the period range
> +     */
> +    if (!has_period) {
> +        b->current_period = MIN_PERIOD_VALUE;
> +    } else if (!value_in_range(period, MIN_PERIOD_VALUE,
> +                               MAX_PERIOD_VALUE, "period", &local_err)) {
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +        }
> +        return;
> +    }  else {
> +        b->current_period = period;
> +    }
> +
> +    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR);
> +    if (fd < 0) {
> +        error_setg_file_open(errp, errno, filename);
> +        return;
> +    }
> +
> +    b->fd = fd;
> +    qemu_thread_create(&b->thread, "dirty-bitmap-dump",
> +                       bitmap_logging_thread, b,
> +                       QEMU_THREAD_JOINABLE);
> +
> +    return;
> +}
> +
>  void qmp_xen_save_devices_state(const char *filename, Error **errp)
>  {
>      QEMUFile *f;
> diff --git a/vl.c b/vl.c
> index fe451aa..2fa97b3 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -205,6 +205,8 @@ bool qemu_uuid_set;
>  static QEMUBootSetHandler *boot_set_handler;
>  static void *boot_set_opaque;
>  
> +int dirty_bitmap_user;
> +
>  static NotifierList exit_notifiers =
>      NOTIFIER_LIST_INITIALIZER(exit_notifiers);
>  
> @@ -751,6 +753,27 @@ void vm_start(void)
>      qapi_event_send_resume(&error_abort);
>  }
>  
> +/*
> + * A global variable to decide which process will only
> + * execute migration or bitmap dump
> + */
> +
> +static QemuProcess dbu = QEMU_PROCESS_NONE;
> +
> +bool qemu_process_check(QemuProcess user)
> +{
> +    return user == dbu;
> +}
> +
> +void qemu_process_set(QemuProcess user)
> +{
> +    dbu = user;
> +}
> +
> +const char *get_qemu_process_as_string(void)
> +{
> +    return QemuProcess_lookup[dbu];
> +}
>  
>  /***********************************************************/
>  /* real time host monotonic timer */
> @@ -4518,6 +4541,7 @@ int main(int argc, char **argv, char **envp)
>      }
>  
>      if (incoming) {
> +        qemu_process_set(QEMU_PROCESS_MIGRATION);
>          Error *local_err = NULL;
>          qemu_start_incoming_migration(incoming, &local_err);
>          if (local_err) {
> -- 
> 1.9.3
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

  reply	other threads:[~2014-08-12 11:15 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-01  3:12 [Qemu-devel] [PATCH v5 0/6] Obtain dirty bitmap via VM logging Sanidhya Kashyap
2014-08-01  3:12 ` [Qemu-devel] [PATCH v5 1/6] generic function between migration and bitmap dump Sanidhya Kashyap
2014-08-12 10:37   ` Dr. David Alan Gilbert
2014-08-01  3:12 ` [Qemu-devel] [PATCH v5 2/6] BitmapLog: bitmap dump code Sanidhya Kashyap
2014-08-12 11:15   ` Dr. David Alan Gilbert [this message]
2014-08-12 13:12   ` Eric Blake
2014-08-01  3:12 ` [Qemu-devel] [PATCH v5 3/6] BitmapLog: get the information about the parameters Sanidhya Kashyap
2014-08-12 11:20   ` Dr. David Alan Gilbert
2014-08-12 13:53   ` Eric Blake
2014-08-01  3:12 ` [Qemu-devel] [PATCH v5 4/6] BitmapLog: cancel mechanism for an already running dump bitmap process Sanidhya Kashyap
2014-08-12 13:55   ` Eric Blake
2014-08-01  3:12 ` [Qemu-devel] [PATCH v5 5/6] BitmapLog: set the period of the " Sanidhya Kashyap
2014-08-12 13:57   ` Eric Blake
2014-08-01  3:12 ` [Qemu-devel] [PATCH v5 6/6] BitmapLog: python script for extracting bitmap from a binary file Sanidhya Kashyap
2014-08-12 12:36   ` Dr. David Alan Gilbert
2014-08-12 14:04     ` Dr. David Alan Gilbert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140812111518.GF2384@work-vm \
    --to=dgilbert@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=sanidhya.iiith@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.