/* * Block driver for Hyper-V VHDX Images * * Copyright (c) 2013 Red Hat, Inc., * * Authors: * Jeff Cody * * This is based on the "VHDX Format Specification v1.00", published 8/25/2012 * by Microsoft: * https://www.microsoft.com/en-us/download/details.aspx?id=34750 * * This file covers the functionality of the metadata log writing, parsing, and * replay. * * This work is licensed under the terms of the GNU LGPL, version 2 or later. * See the COPYING.LIB file in the top-level directory. * */ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu-common.h" #include "block/block_int.h" #include "qemu/error-report.h" #include "qemu/module.h" #include "block/vhdx.h" typedef struct VHDXLogSequence { bool valid; uint32_t count; VHDXLogEntries log; VHDXLogEntryHeader hdr; } VHDXLogSequence; typedef struct VHDXLogDescEntries { VHDXLogEntryHeader hdr; VHDXLogDescriptor desc[]; } VHDXLogDescEntries; static const MSGUID zero_guid = { 0 }; /* The log located on the disk is circular buffer containing * sectors of 4096 bytes each. * * It is assumed for the read/write functions below that the * circular buffer scheme uses a 'one sector open' to indicate * the buffer is full. Given the validation methods used for each * sector, this method should be compatible with other methods that * do not waste a sector. */ /* Allow peeking at the hdr entry at the beginning of the current * read index, without advancing the read index */ static int vhdx_log_peek_hdr(BlockDriverState *bs, VHDXLogEntries *log, VHDXLogEntryHeader *hdr) { int ret = 0; uint64_t offset; uint32_t read; assert(hdr != NULL); /* peek is only supported on sector boundaries */ if (log->read % VHDX_LOG_SECTOR_SIZE) { ret = -EFAULT; goto exit; } read = log->read; /* we are guaranteed that a) log sectors are 4096 bytes, * and b) the log length is a multiple of 1MB. So, there * is always a round number of sectors in the buffer */ if ((read + sizeof(VHDXLogEntryHeader)) > log->length) { read = 0; } if (read == log->write) { ret = -EINVAL; goto exit; } offset = log->offset + read; ret = bdrv_pread(bs->file->bs, offset, hdr, sizeof(VHDXLogEntryHeader)); if (ret < 0) { goto exit; } vhdx_log_entry_hdr_le_import(hdr); exit: return ret; } /* Index increment for log, based on sector boundaries */ static int vhdx_log_inc_idx(uint32_t idx, uint64_t length) { idx += VHDX_LOG_SECTOR_SIZE; /* we are guaranteed that a) log sectors are 4096 bytes, * and b) the log length is a multiple of 1MB. So, there * is always a round number of sectors in the buffer */ return idx >= length ? 0 : idx; } /* Reset the log to empty */ static void vhdx_log_reset(BlockDriverState *bs, BDRVVHDXState *s) { MSGUID guid = { 0 }; s->log.read = s->log.write = 0; /* a log guid of 0 indicates an empty log to any parser of v0 * VHDX logs */ vhdx_update_headers(bs, s, false, &guid); } /* Reads num_sectors from the log (all log sectors are 4096 bytes), * into buffer 'buffer'. Upon return, *sectors_read will contain * the number of sectors successfully read. * * It is assumed that 'buffer' is already allocated, and of sufficient * size (i.e. >= 4096*num_sectors). * * If 'peek' is true, then the tail (read) pointer for the circular buffer is * not modified. * * 0 is returned on success, -errno otherwise. */ static int vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log, uint32_t *sectors_read, void *buffer, uint32_t num_sectors, bool peek) { int ret = 0; uint64_t offset; uint32_t read; read = log->read; *sectors_read = 0; while (num_sectors) { if (read == log->write) { /* empty */ break; } offset = log->offset + read; ret = bdrv_pread(bs->file->bs, offset, buffer, VHDX_LOG_SECTOR_SIZE); if (ret < 0) { goto exit; } read = vhdx_log_inc_idx(read, log->length); *sectors_read = *sectors_read + 1; num_sectors--; } exit: if (!peek) { log->read = read; } return ret; } /* Writes num_sectors to the log (all log sectors are 4096 bytes), * from buffer 'buffer'. Upon return, *sectors_written will contain * the number of sectors successfully written. * * It is assumed that 'buffer' is at least 4096*num_sectors large. * * 0 is returned on success, -errno otherwise */ static int vhdx_log_write_sectors(BlockDriverState *bs, VHDXLogEntries *log, uint32_t *sectors_written, void *buffer, uint32_t num_sectors) { int ret = 0; uint64_t offset; uint32_t write; void *buffer_tmp; BDRVVHDXState *s = bs->opaque; ret = vhdx_user_visible_write(bs, s); if (ret < 0) { goto exit; } write = log->write; buffer_tmp = buffer; while (num_sectors) { offset = log->offset + write; write = vhdx_log_inc_idx(write, log->length); if (write == log->read) { /* full */ break; } ret = bdrv_pwrite(bs->file->bs, offset, buffer_tmp, VHDX_LOG_SECTOR_SIZE); if (ret < 0) { goto exit; } buffer_tmp += VHDX_LOG_SECTOR_SIZE; log->write = write; *sectors_written = *sectors_written + 1; num_sectors--; } exit: return ret; } /* Validates a log entry header */ static bool vhdx_log_hdr_is_valid(VHDXLogEntries *log, VHDXLogEntryHeader *hdr, BDRVVHDXState *s) { int valid = false; if (hdr->signature != VHDX_LOG_SIGNATURE) { goto exit; } /* if the individual entry length is larger than the whole log * buffer, that is obviously invalid */ if (log->length < hdr->entry_length) { goto exit; } /* length of entire entry must be in units of 4KB (log sector size) */ if (hdr->entry_length % (VHDX_LOG_SECTOR_SIZE)) { goto exit; } /* per spec, sequence # must be > 0 */ if (hdr->sequence_number == 0) { goto exit; } /* log entries are only valid if they match the file-wide log guid * found in the active header */ if (!guid_eq(hdr->log_guid, s->headers[s->curr_header]->log_guid)) { goto exit; } if (hdr->descriptor_count * sizeof(VHDXLogDescriptor) > hdr->entry_length) { goto exit; } valid = true; exit: return valid; } /* * Given a log header, this will validate that the descriptors and the * corresponding data sectors (if applicable) * * Validation consists of: * 1. Making sure the sequence numbers matches the entry header * 2. Verifying a valid signature ('zero' or 'desc' for descriptors) * 3. File offset field is a multiple of 4KB * 4. If a data descriptor, the corresponding data sector * has its signature ('data') and matching sequence number * * @desc: the data buffer containing the descriptor * @hdr: the log entry header * * Returns true if valid */ static bool vhdx_log_desc_is_valid(VHDXLogDescriptor *desc, VHDXLogEntryHeader *hdr) { bool ret = false; if (desc->sequence_number != hdr->sequence_number) { goto exit; } if (desc->file_offset % VHDX_LOG_SECTOR_SIZE) { goto exit; } if (desc->signature == VHDX_LOG_ZERO_SIGNATURE) { if (desc->zero_length % VHDX_LOG_SECTOR_SIZE == 0) { /* valid */ ret = true; } } else if (desc->signature == VHDX_LOG_DESC_SIGNATURE) { /* valid */ ret = true; } exit: return ret; } /* Prior to sector data for a log entry, there is the header * and the descriptors referenced in the header: * * [] = 4KB sector * * [ hdr, desc ][ desc ][ ... ][ data ][ ... ] * * The first sector in a log entry has a 64 byte header, and * up to 126 32-byte descriptors. If more descriptors than * 126 are required, then subsequent sectors can have up to 128 * descriptors. Each sector is 4KB. Data follows the descriptor * sectors. * * This will return the number of sectors needed to encompass * the passed number of descriptors in desc_cnt. * * This will never return 0, even if desc_cnt is 0. */ static int vhdx_compute_desc_sectors(uint32_t desc_cnt) { uint32_t desc_sectors; desc_cnt += 2; /* account for header in first sector */ desc_sectors = desc_cnt / 128; if (desc_cnt % 128) { desc_sectors++; } return desc_sectors; } /* Reads the log header, and subsequent descriptors (if any). This * will allocate all the space for buffer, which must be NULL when * passed into this function. Each descriptor will also be validated, * and error returned if any are invalid. */ static int vhdx_log_read_desc(BlockDriverState *bs, BDRVVHDXState *s, VHDXLogEntries *log, VHDXLogDescEntries **buffer, bool convert_endian) { int ret = 0; uint32_t desc_sectors; uint32_t sectors_read; VHDXLogEntryHeader hdr; VHDXLogDescEntries *desc_entries = NULL; VHDXLogDescriptor desc; int i; assert(*buffer == NULL); ret = vhdx_log_peek_hdr(bs, log, &hdr); if (ret < 0) { goto exit; } if (vhdx_log_hdr_is_valid(log, &hdr, s) == false) { ret = -EINVAL; goto exit; } desc_sectors = vhdx_compute_desc_sectors(hdr.descriptor_count); desc_entries = qemu_try_blockalign(bs->file->bs, desc_sectors * VHDX_LOG_SECTOR_SIZE); if (desc_entries == NULL) { ret = -ENOMEM; goto exit; } ret = vhdx_log_read_sectors(bs, log, §ors_read, desc_entries, desc_sectors, false); if (ret < 0) { goto free_and_exit; } if (sectors_read != de
##############################################################################
# Copyright (c) 2015 Ericsson AB and others.
# jonas.bjurel@ericsson.com
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################

############################################################################### # Description:
# This .yaml configuration file defines the configuration of the fuel
# deployment and is passed as an argument to deploy.sh
# eg. deploy.sh -c https://artifact.opnfv.org/fuel/config
# This will make build.sh fetch this configuration file and configure the
# deployment accordingly.
# After the deployment, a copy of this file gets uploaded to fuel:
# /root/deploy-config.yaml, as well as the sha-1 sum of this file:
# /root/deploy-config.sha1
##############################################################################

##############################################################################
# deployment configuration meta-data
deployment-scenario-metadata:
   title: ODL-L3 HA deployment
   version: 0.0.4
   created: Jan 28 2016
   comment: Rebased to Fuel8

##############################################################################
# Stack extentions are opnfv added value features in form of a fuel-plugin
# plug-ins listed below will be enabled and configured according to the
# <module-config-base-uri>/<module-config-name>_<module-config-version>.yaml
# It does so by copying the config file to the local plugin config directory
# Note that the module substitionion does not support arrays
# This is a quick fix
stack-extensions:
#   - module: opendaylight
#     module-config-name: fuel-odl
#     module-config-version: 0.0.2
#     module-config-override:
#       # Module config overrides
#       rest_api_port:
#         value: '8282'
#       enable_gbp:
#         value: false
#       enable_l3_odl:
#         value: true
#       enable_sfc:
#         value: false

##############################################################################
# By editing the override-config sections below, you can override arbitrary
# configuration name-space settings
dea-override-config:
  nodes:
  - id: 1
    interfaces: interfaces_1
    role: controller,opendaylight
    transformations: transformations_1
  - id: 2
    interfaces: interfaces_1
    role: mongo,controller
    transformations: transformations_1
  - id: 3
    interfaces: interfaces_1
    role: ceph-osd,controller
    transformations: transformations_1
  - id: 4
    interfaces: interfaces_1
    role: ceph-osd,compute
    transformations: transformations_1
  - id: 5
    interfaces: interfaces_1
    role: ceph-osd,compute
    transformations: transformations_1
  settings:
    editable:
      public_network_assignment:
        assign_to_all_nodes:
          value: true
      opendaylight:
        metadata:
          # chosen_id: Assigned during installation
          class: plugin
          default: false
          enabled: true
          label: OpenDaylight plugin
          toggleable: true
          versions:
          - enable_gbp:
              label: GBP features
              type: checkbox
              value: false
              weight: 14
            enable_l3_odl:
              label: Use ODL to manage L3 traffic
              restrictions:
              - networking_parameters:segmentation_type == 'vlan': Use tunneling segmentation type.
              - settings:public_network_assignment.assign_to_all_nodes.value == false: Assign public network to all nodes
              type: checkbox
              value: true
              weight: 12
            enable_sfc:
              label: SFC features
              type: checkbox
              value: false
              weight: 13
            metadata:
              always_editable: false
              odl_features:
                default:
                - config
                - standard
                - region
                - package
                - kar
                -