/* * QEMU host block devices * * Copyright (c) 2003-2008 Fabrice Bellard * * This work is licensed under the terms of the GNU GPL, version 2 or * later. See the COPYING file in the top-level directory. * * This file incorporates work covered by the following copyright and * permission notice: * * Copyright (c) 2003-2008 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "qemu/osdep.h" #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "hw/block/block.h" #include "block/blockjob.h" #include "block/throttle-groups.h" #include "monitor/monitor.h" #include "qemu/error-report.h" #include "qemu/option.h" #include "qemu/config-file.h" #include "qapi/qmp/types.h" #include "qapi-visit.h" #include "qapi/qmp/qerror.h" #include "qapi/qmp-output-visitor.h" #include "qapi/util.h" #include "sysemu/sysemu.h" #include "block/block_int.h" #include "qmp-commands.h" #include "trace.h" #include "sysemu/arch_init.h" #include "qemu/cutils.h" #include "qemu/help_option.h" static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states = QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states); static const char *const if_name[IF_COUNT] = { [IF_NONE] = "none", [IF_IDE] = "ide", [IF_SCSI] = "scsi", [IF_FLOPPY] = "floppy", [IF_PFLASH] = "pflash", [IF_MTD] = "mtd", [IF_SD] = "sd", [IF_VIRTIO] = "virtio", [IF_XEN] = "xen", }; static int if_max_devs[IF_COUNT] = { /* * Do not change these numbers! They govern how drive option * index maps to unit and bus. That mapping is ABI. * * All controllers used to imlement if=T drives need to support * if_max_devs[T] units, for any T with if_max_devs[T] != 0. * Otherwise, some index values map to "impossible" bus, unit * values. * * For instance, if you change [IF_SCSI] to 255, -drive * if=scsi,index=12 no longer means bus=1,unit=5, but * bus=0,unit=12. With an lsi53c895a controller (7 units max), * the drive can't be set up. Regression. */ [IF_IDE] = 2, [IF_SCSI] = 7, }; /** * Boards may call this to offer board-by-board overrides * of the default, global values. */ void override_max_devs(BlockInterfaceType type, int max_devs) { BlockBackend *blk; DriveInfo *dinfo; if (max_devs <= 0) { return; } for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { dinfo = blk_legacy_dinfo(blk); if (dinfo->type == type) { fprintf(stderr, "Cannot override units-per-bus property of" " the %s interface, because a drive of that type has" " already been added.\n", if_name[type]); g_assert_not_reached(); } } if_max_devs[type] = max_devs; } /* * We automatically delete the drive when a device using it gets * unplugged. Questionable feature, but we can't just drop it. * Device models call blockdev_mark_auto_del() to schedule the * automatic deletion, and generic qdev code calls blockdev_auto_del() * when deletion is actually safe. */ void blockdev_mark_auto_del(BlockBackend *blk) { DriveInfo *dinfo = blk_legacy_dinfo(blk); BlockDriverState *bs = blk_bs(blk); AioContext *aio_context; if (!dinfo) { return; } if (bs) { aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); if (bs->job) { block_job_cancel(bs->job); } aio_context_release(aio_context); } dinfo->auto_del = 1; } void blockdev_auto_del(BlockBackend *blk) { DriveInfo *dinfo = blk_legacy_dinfo(blk); if (dinfo && dinfo->auto_del) { monitor_remove_blk(blk); blk_unref(blk); } } /** * Returns the current mapping of how many units per bus * a particular interface can support. * * A positive integer indicates n units per bus. * 0 implies the mapping has not been established. * -1 indicates an invalid BlockInterfaceType was given. */ int drive_get_max_devs(BlockInterfaceType type) { if (type >= IF_IDE && type < IF_COUNT) { return if_max_devs[type]; } return -1; } static int drive_index_to_bus_id(BlockInterfaceType type, int index) { int max_devs = if_max_devs[type]; return max_devs ? index / max_devs : 0; } static int drive_index_to_unit_id(BlockInterfaceType type, int index) { int max_devs = if_max_devs[type]; return max_devs ? index % max_devs : index; } QemuOpts *drive_def(const char *optstr) { return qemu_opts_parse_noisily(qemu_find_opts("drive"), optstr, false); } QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file, const char *optstr) { QemuOpts *opts; opts = drive_def(optstr); if (!opts) { return NULL; } if (type != IF_DEFAULT) { qemu_opt_set(opts, "if", if_name[type], &error_abort); } if (index >= 0) { qemu_opt_set_number(opts, "index", index, &error_abort); } if (file) qemu_opt_set(opts, "file", file, &error_abort); return opts; } DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit) { BlockBackend *blk; DriveInfo *din
# Copyright (c) 2017 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pkg_resources
import pip.req
import sys
def get_pkg_license(pkg):
"""
Given a package reference (as from requirements.txt),
return license listed in package metadata.
NOTE: This function does no error checking and is for
demonstration purposes only.
can-pip-or-setuptools-distribute-etc-list-the-license-used-by-each-install
https://stackoverflow.com/a/19086260
https://stackoverflow.com/users/308066/dkamins
"""
try:
pkgs = pkg_resources.working_set.resolve(pkg, replace_conflicting=True)
# pkgs = pkg_resources.require(pkg)
except pkg_resources.DistributionNotFound as e:
sys.stderr.write("%s\n" % e)
return None
pkg = pkgs[0]
try:
info = pkg.get_metadata_lines('METADATA')
except IOError:
try:
info = pkg.get_metadata_lines('PKG-INFO')
except IOError:
info = []
licenses = []
for line in info:
if "License:" in line:
lic = line.split(': ', 1)[1]
if "UNKNOWN" not in lic:
# try this type first
licenses.append(lic)
# break
elif "License ::" in line:
licenses.append(" ".join(line.split(':: ')[1:3]))
return "; ".join(licenses)
# quick and dirty hack
def main():
reqs = list(pip.req.parse_requirements("../../requirements.txt", session='hack'))
lines = []
for req in reqs:
pkg = pkg_resources.parse_requirements([req.name])
lic = get_pkg_license(pkg)
markers = req.markers
if markers:
mark = "; " + str(req.markers)
else:
mark = ""
line = "{0}{1}\t\t# {2}\n".format(req.req, mark, lic)
sys.stdout.write(line)
lines.append(line)
with open("requirements.txt", "w") as rrr:
rrr.writelines(lines)
if __name__ == '__main__':
main()