From 461fcb06c04ebe66171c1a4329ac3ef8af55d1aa9e113ac5748263dfd3709edb Mon Sep 17 00:00:00 2001 From: Bruce Rogers Date: Thu, 13 Feb 2014 13:36:37 +0000 Subject: [PATCH] Accepting request 222193 from home:bfrogers:branches:Virtualization Transition kvm package contents to a qemu submodule named qemu-kvm as announced on opensuse-factory ml (see: http://lists.opensuse.org/opensuse-factory/2014-02/msg00206.html) OBS-URL: https://build.opensuse.org/request/show/222193 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=181 --- 60-kvm.rules | 2 + 80-kvm.rules | 1 + kvm_stat | 511 ++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-ifup | 23 +++ qemu-kvm.1.gz | 3 + qemu.changes | 12 ++ qemu.spec | 78 ++++++++ qemu.spec.in | 78 ++++++++ 8 files changed, 708 insertions(+) create mode 100644 60-kvm.rules create mode 100644 80-kvm.rules create mode 100644 kvm_stat create mode 100644 qemu-ifup create mode 100644 qemu-kvm.1.gz diff --git a/60-kvm.rules b/60-kvm.rules new file mode 100644 index 00000000..f7bb40ef --- /dev/null +++ b/60-kvm.rules @@ -0,0 +1,2 @@ +KERNEL=="kvm", MODE="0660", GROUP="kvm" +ACTION=="add|change", SUBSYSTEM=="dmi", KERNEL=="id", RUN+="/bin/sh -c 'grep -q vmx /proc/cpuinfo && /sbin/modprobe kvm-intel; grep -q svm /proc/cpuinfo && /sbin/modprobe kvm-amd'" diff --git a/80-kvm.rules b/80-kvm.rules new file mode 100644 index 00000000..e9afa344 --- /dev/null +++ b/80-kvm.rules @@ -0,0 +1 @@ +KERNEL=="kvm", MODE="0666", GROUP="kvm" diff --git a/kvm_stat b/kvm_stat new file mode 100644 index 00000000..ff636441 --- /dev/null +++ b/kvm_stat @@ -0,0 +1,511 @@ +#!/usr/bin/python +# +# top-like utility for displaying kvm statistics +# +# Copyright 2006-2008 Qumranet Technologies +# Copyright 2008-2011 Red Hat, Inc. +# +# Authors: +# Avi Kivity +# +# This work is licensed under the terms of the GNU GPL, version 2. See +# the COPYING file in the top-level directory. + +import curses +import sys, os, time, optparse + +class DebugfsProvider(object): + def __init__(self): + self.base = '/sys/kernel/debug/kvm' + self._fields = os.listdir(self.base) + def fields(self): + return self._fields + def select(self, fields): + self._fields = fields + def read(self): + def val(key): + return int(file(self.base + '/' + key).read()) + return dict([(key, val(key)) for key in self._fields]) + +vmx_exit_reasons = { + 0: 'EXCEPTION_NMI', + 1: 'EXTERNAL_INTERRUPT', + 2: 'TRIPLE_FAULT', + 7: 'PENDING_INTERRUPT', + 8: 'NMI_WINDOW', + 9: 'TASK_SWITCH', + 10: 'CPUID', + 12: 'HLT', + 14: 'INVLPG', + 15: 'RDPMC', + 16: 'RDTSC', + 18: 'VMCALL', + 19: 'VMCLEAR', + 20: 'VMLAUNCH', + 21: 'VMPTRLD', + 22: 'VMPTRST', + 23: 'VMREAD', + 24: 'VMRESUME', + 25: 'VMWRITE', + 26: 'VMOFF', + 27: 'VMON', + 28: 'CR_ACCESS', + 29: 'DR_ACCESS', + 30: 'IO_INSTRUCTION', + 31: 'MSR_READ', + 32: 'MSR_WRITE', + 33: 'INVALID_STATE', + 36: 'MWAIT_INSTRUCTION', + 39: 'MONITOR_INSTRUCTION', + 40: 'PAUSE_INSTRUCTION', + 41: 'MCE_DURING_VMENTRY', + 43: 'TPR_BELOW_THRESHOLD', + 44: 'APIC_ACCESS', + 48: 'EPT_VIOLATION', + 49: 'EPT_MISCONFIG', + 54: 'WBINVD', + 55: 'XSETBV', +} + +svm_exit_reasons = { + 0x000: 'READ_CR0', + 0x003: 'READ_CR3', + 0x004: 'READ_CR4', + 0x008: 'READ_CR8', + 0x010: 'WRITE_CR0', + 0x013: 'WRITE_CR3', + 0x014: 'WRITE_CR4', + 0x018: 'WRITE_CR8', + 0x020: 'READ_DR0', + 0x021: 'READ_DR1', + 0x022: 'READ_DR2', + 0x023: 'READ_DR3', + 0x024: 'READ_DR4', + 0x025: 'READ_DR5', + 0x026: 'READ_DR6', + 0x027: 'READ_DR7', + 0x030: 'WRITE_DR0', + 0x031: 'WRITE_DR1', + 0x032: 'WRITE_DR2', + 0x033: 'WRITE_DR3', + 0x034: 'WRITE_DR4', + 0x035: 'WRITE_DR5', + 0x036: 'WRITE_DR6', + 0x037: 'WRITE_DR7', + 0x040: 'EXCP_BASE', + 0x060: 'INTR', + 0x061: 'NMI', + 0x062: 'SMI', + 0x063: 'INIT', + 0x064: 'VINTR', + 0x065: 'CR0_SEL_WRITE', + 0x066: 'IDTR_READ', + 0x067: 'GDTR_READ', + 0x068: 'LDTR_READ', + 0x069: 'TR_READ', + 0x06a: 'IDTR_WRITE', + 0x06b: 'GDTR_WRITE', + 0x06c: 'LDTR_WRITE', + 0x06d: 'TR_WRITE', + 0x06e: 'RDTSC', + 0x06f: 'RDPMC', + 0x070: 'PUSHF', + 0x071: 'POPF', + 0x072: 'CPUID', + 0x073: 'RSM', + 0x074: 'IRET', + 0x075: 'SWINT', + 0x076: 'INVD', + 0x077: 'PAUSE', + 0x078: 'HLT', + 0x079: 'INVLPG', + 0x07a: 'INVLPGA', + 0x07b: 'IOIO', + 0x07c: 'MSR', + 0x07d: 'TASK_SWITCH', + 0x07e: 'FERR_FREEZE', + 0x07f: 'SHUTDOWN', + 0x080: 'VMRUN', + 0x081: 'VMMCALL', + 0x082: 'VMLOAD', + 0x083: 'VMSAVE', + 0x084: 'STGI', + 0x085: 'CLGI', + 0x086: 'SKINIT', + 0x087: 'RDTSCP', + 0x088: 'ICEBP', + 0x089: 'WBINVD', + 0x08a: 'MONITOR', + 0x08b: 'MWAIT', + 0x08c: 'MWAIT_COND', + 0x400: 'NPF', +} + +s390_exit_reasons = { + 0x000: 'UNKNOWN', + 0x001: 'EXCEPTION', + 0x002: 'IO', + 0x003: 'HYPERCALL', + 0x004: 'DEBUG', + 0x005: 'HLT', + 0x006: 'MMIO', + 0x007: 'IRQ_WINDOW_OPEN', + 0x008: 'SHUTDOWN', + 0x009: 'FAIL_ENTRY', + 0x010: 'INTR', + 0x011: 'SET_TPR', + 0x012: 'TPR_ACCESS', + 0x013: 'S390_SIEIC', + 0x014: 'S390_RESET', + 0x015: 'DCR', + 0x016: 'NMI', + 0x017: 'INTERNAL_ERROR', + 0x018: 'OSI', + 0x019: 'PAPR_HCALL', +} + +vendor_exit_reasons = { + 'vmx': vmx_exit_reasons, + 'svm': svm_exit_reasons, + 'IBM/S390': s390_exit_reasons, +} + +syscall_numbers = { + 'IBM/S390': 331, +} + +sc_perf_evt_open = 298 + +exit_reasons = None + +for line in file('/proc/cpuinfo').readlines(): + if line.startswith('flags') or line.startswith('vendor_id'): + for flag in line.split(): + if flag in vendor_exit_reasons: + exit_reasons = vendor_exit_reasons[flag] + if flag in syscall_numbers: + sc_perf_evt_open = syscall_numbers[flag] +filters = { + 'kvm_exit': ('exit_reason', exit_reasons) +} + +def invert(d): + return dict((x[1], x[0]) for x in d.iteritems()) + +for f in filters: + filters[f] = (filters[f][0], invert(filters[f][1])) + +import ctypes, struct, array + +libc = ctypes.CDLL('libc.so.6') +syscall = libc.syscall +class perf_event_attr(ctypes.Structure): + _fields_ = [('type', ctypes.c_uint32), + ('size', ctypes.c_uint32), + ('config', ctypes.c_uint64), + ('sample_freq', ctypes.c_uint64), + ('sample_type', ctypes.c_uint64), + ('read_format', ctypes.c_uint64), + ('flags', ctypes.c_uint64), + ('wakeup_events', ctypes.c_uint32), + ('bp_type', ctypes.c_uint32), + ('bp_addr', ctypes.c_uint64), + ('bp_len', ctypes.c_uint64), + ] +def _perf_event_open(attr, pid, cpu, group_fd, flags): + return syscall(sc_perf_evt_open, ctypes.pointer(attr), ctypes.c_int(pid), + ctypes.c_int(cpu), ctypes.c_int(group_fd), + ctypes.c_long(flags)) + +PERF_TYPE_HARDWARE = 0 +PERF_TYPE_SOFTWARE = 1 +PERF_TYPE_TRACEPOINT = 2 +PERF_TYPE_HW_CACHE = 3 +PERF_TYPE_RAW = 4 +PERF_TYPE_BREAKPOINT = 5 + +PERF_SAMPLE_IP = 1 << 0 +PERF_SAMPLE_TID = 1 << 1 +PERF_SAMPLE_TIME = 1 << 2 +PERF_SAMPLE_ADDR = 1 << 3 +PERF_SAMPLE_READ = 1 << 4 +PERF_SAMPLE_CALLCHAIN = 1 << 5 +PERF_SAMPLE_ID = 1 << 6 +PERF_SAMPLE_CPU = 1 << 7 +PERF_SAMPLE_PERIOD = 1 << 8 +PERF_SAMPLE_STREAM_ID = 1 << 9 +PERF_SAMPLE_RAW = 1 << 10 + +PERF_FORMAT_TOTAL_TIME_ENABLED = 1 << 0 +PERF_FORMAT_TOTAL_TIME_RUNNING = 1 << 1 +PERF_FORMAT_ID = 1 << 2 +PERF_FORMAT_GROUP = 1 << 3 + +import re + +sys_tracing = '/sys/kernel/debug/tracing' + +class Group(object): + def __init__(self, cpu): + self.events = [] + self.group_leader = None + self.cpu = cpu + def add_event(self, name, event_set, tracepoint, filter = None): + self.events.append(Event(group = self, + name = name, event_set = event_set, + tracepoint = tracepoint, filter = filter)) + if len(self.events) == 1: + self.file = os.fdopen(self.events[0].fd) + def read(self): + bytes = 8 * (1 + len(self.events)) + fmt = 'xxxxxxxx' + 'q' * len(self.events) + return dict(zip([event.name for event in self.events], + struct.unpack(fmt, self.file.read(bytes)))) + +class Event(object): + def __init__(self, group, name, event_set, tracepoint, filter = None): + self.name = name + attr = perf_event_attr() + attr.type = PERF_TYPE_TRACEPOINT + attr.size = ctypes.sizeof(attr) + id_path = os.path.join(sys_tracing, 'events', event_set, + tracepoint, 'id') + id = int(file(id_path).read()) + attr.config = id + attr.sample_type = (PERF_SAMPLE_RAW + | PERF_SAMPLE_TIME + | PERF_SAMPLE_CPU) + attr.sample_period = 1 + attr.read_format = PERF_FORMAT_GROUP + group_leader = -1 + if group.events: + group_leader = group.events[0].fd + fd = _perf_event_open(attr, -1, group.cpu, group_leader, 0) + if fd == -1: + raise Exception('perf_event_open failed') + if filter: + import fcntl + fcntl.ioctl(fd, 0x40082406, filter) + self.fd = fd + def enable(self): + import fcntl + fcntl.ioctl(self.fd, 0x00002400, 0) + def disable(self): + import fcntl + fcntl.ioctl(self.fd, 0x00002401, 0) + +class TracepointProvider(object): + def __init__(self): + path = os.path.join(sys_tracing, 'events', 'kvm') + fields = [f + for f in os.listdir(path) + if os.path.isdir(os.path.join(path, f))] + extra = [] + for f in fields: + if f in filters: + subfield, values = filters[f] + for name, number in values.iteritems(): + extra.append(f + '(' + name + ')') + fields += extra + self._setup(fields) + self.select(fields) + def fields(self): + return self._fields + def _setup(self, _fields): + self._fields = _fields + cpure = r'cpu([0-9]+)' + self.cpus = [int(re.match(cpure, x).group(1)) + for x in os.listdir('/sys/devices/system/cpu') + if re.match(cpure, x)] + import resource + nfiles = len(self.cpus) * 1000 + resource.setrlimit(resource.RLIMIT_NOFILE, (nfiles, nfiles)) + events = [] + self.group_leaders = [] + for cpu in self.cpus: + group = Group(cpu) + for name in _fields: + tracepoint = name + filter = None + m = re.match(r'(.*)\((.*)\)', name) + if m: + tracepoint, sub = m.groups() + filter = '%s==%d\0' % (filters[tracepoint][0], + filters[tracepoint][1][sub]) + event = group.add_event(name, event_set = 'kvm', + tracepoint = tracepoint, + filter = filter) + self.group_leaders.append(group) + def select(self, fields): + for group in self.group_leaders: + for event in group.events: + if event.name in fields: + event.enable() + else: + event.disable() + def read(self): + from collections import defaultdict + ret = defaultdict(int) + for group in self.group_leaders: + for name, val in group.read().iteritems(): + ret[name] += val + return ret + +class Stats: + def __init__(self, provider, fields = None): + self.provider = provider + self.fields_filter = fields + self._update() + def _update(self): + def wanted(key): + import re + if not self.fields_filter: + return True + return re.match(self.fields_filter, key) is not None + self.values = dict([(key, None) + for key in provider.fields() + if wanted(key)]) + self.provider.select(self.values.keys()) + def set_fields_filter(self, fields_filter): + self.fields_filter = fields_filter + self._update() + def get(self): + new = self.provider.read() + for key in self.provider.fields(): + oldval = self.values.get(key, (0, 0)) + newval = new[key] + newdelta = None + if oldval is not None: + newdelta = newval - oldval[0] + self.values[key] = (newval, newdelta) + return self.values + +if not os.access('/sys/kernel/debug', os.F_OK): + print 'Please enable CONFIG_DEBUG_FS in your kernel' + sys.exit(1) +if not os.access('/sys/kernel/debug/kvm', os.F_OK): + print "Please mount debugfs ('mount -t debugfs debugfs /sys/kernel/debug')" + print "and ensure the kvm modules are loaded" + sys.exit(1) + +label_width = 40 +number_width = 10 + +def tui(screen, stats): + curses.use_default_colors() + curses.noecho() + drilldown = False + fields_filter = stats.fields_filter + def update_drilldown(): + if not fields_filter: + if drilldown: + stats.set_fields_filter(None) + else: + stats.set_fields_filter(r'^[^\(]*$') + update_drilldown() + def refresh(sleeptime): + screen.erase() + screen.addstr(0, 0, 'kvm statistics') + row = 2 + s = stats.get() + def sortkey(x): + if s[x][1]: + return (-s[x][1], -s[x][0]) + else: + return (0, -s[x][0]) + for key in sorted(s.keys(), key = sortkey): + if row >= screen.getmaxyx()[0]: + break + values = s[key] + if not values[0] and not values[1]: + break + col = 1 + screen.addstr(row, col, key) + col += label_width + screen.addstr(row, col, '%10d' % (values[0],)) + col += number_width + if values[1] is not None: + screen.addstr(row, col, '%8d' % (values[1] / sleeptime,)) + row += 1 + screen.refresh() + + sleeptime = 0.25 + while True: + refresh(sleeptime) + curses.halfdelay(int(sleeptime * 10)) + sleeptime = 3 + try: + c = screen.getkey() + if c == 'x': + drilldown = not drilldown + update_drilldown() + if c == 'q': + break + except KeyboardInterrupt: + break + except curses.error: + continue + +def batch(stats): + s = stats.get() + time.sleep(1) + s = stats.get() + for key in sorted(s.keys()): + values = s[key] + print '%-22s%10d%10d' % (key, values[0], values[1]) + +def log(stats): + keys = sorted(stats.get().iterkeys()) + def banner(): + for k in keys: + print '%10s' % k[0:9], + print + def statline(): + s = stats.get() + for k in keys: + print ' %9d' % s[k][1], + print + line = 0 + banner_repeat = 20 + while True: + time.sleep(1) + if line % banner_repeat == 0: + banner() + statline() + line += 1 + +options = optparse.OptionParser() +options.add_option('-1', '--once', '--batch', + action = 'store_true', + default = False, + dest = 'once', + help = 'run in batch mode for one second', + ) +options.add_option('-l', '--log', + action = 'store_true', + default = False, + dest = 'log', + help = 'run in logging mode (like vmstat)', + ) +options.add_option('-f', '--fields', + action = 'store', + default = None, + dest = 'fields', + help = 'fields to display (regex)', + ) +(options, args) = options.parse_args(sys.argv) + +try: + provider = TracepointProvider() +except: + provider = DebugfsProvider() + +stats = Stats(provider, fields = options.fields) + +if options.log: + log(stats) +elif not options.once: + import curses.wrapper + curses.wrapper(tui, stats) +else: + batch(stats) diff --git a/qemu-ifup b/qemu-ifup new file mode 100644 index 00000000..1936e7e2 --- /dev/null +++ b/qemu-ifup @@ -0,0 +1,23 @@ +#!/bin/sh + +echo 'config qemu network with bridge for ' $* + +# If bridge is not specified, try device with default route. +bridge=$2 +if [ -z "$bridge" ]; then + bridge=$(ip route list | awk '/^default / { print $NF }') +fi + +# Exit if $bridge is not a bridge. Exit with 0 status +# so qemu-dm process is not terminated. No networking in +# vm is bad but not catastrophic. The vm could still run +# cpu and disk IO workloads. +# Include an useful error message in qemu-dm log file. +if [ ! -e "/sys/class/net/${bridge}/bridge" ] +then + echo "WARNING! ${bridge} is not a bridge. qemu-ifup exiting. VM may not have a functioning networking stack." + exit 0 +fi + +ifconfig $1 0.0.0.0 up +brctl addif $bridge $1 || true diff --git a/qemu-kvm.1.gz b/qemu-kvm.1.gz new file mode 100644 index 00000000..3bb17393 --- /dev/null +++ b/qemu-kvm.1.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1b92b2e22f846e4f7c692d8466f3865fbb95c2523aee7fc0a06524a39061e94 +size 47 diff --git a/qemu.changes b/qemu.changes index eed1f154..ec472af9 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Wed Feb 12 23:50:30 UTC 2014 - brogers@suse.com + +- Migrate kvm package contents to a new qemu-kvm sub-package, and + move the kvm related udev rules to the qemu package. (The kvm + package is being retired). + Add qemu-ifup + Add qemu-kvm.1.gz + Add kvm_stat + Add 60-kvm.rules + Add 80-kvm.rules + ------------------------------------------------------------------- Mon Feb 3 15:54:06 UTC 2014 - afaerber@suse.de diff --git a/qemu.spec b/qemu.spec index 31ff40d3..213292f2 100644 --- a/qemu.spec +++ b/qemu.spec @@ -31,6 +31,11 @@ Group: System/Emulators/PC Version: 1.7.0 Release: 0 Source: %name-1.7.0.tar.bz2 +Source1: 80-kvm.rules +Source2: qemu-ifup +Source3: kvm_stat +Source4: qemu-kvm.1.gz +Source5: 60-kvm.rules # This patch queue is auto-generated from https://github.com/openSUSE/qemu Patch0001: 0001-XXX-dont-dump-core-on-sigabort.patc.patch Patch0002: 0002-XXX-work-around-SA_RESTART-race-wit.patch @@ -153,6 +158,14 @@ BuildRequires: libspice-server-devel BuildRequires: spice-protocol-devel %endif %endif +%ifarch %ix86 x86_64 s390x +BuildRequires: udev +%if %( echo `rpm -q --queryformat %%{version} udev` ) > 190 +%define _udevrulesdir /usr/lib/udev/rules.d +%else +%define _udevrulesdir /lib/udev/rules.d +%endif +%endif Requires: /usr/sbin/groupadd Requires: pwdutils Requires: qemu-ipxe @@ -171,6 +184,26 @@ binaries for different architectures under your native operating system. It currently emulates x86, ARM, PowerPC and SPARC CPUs as well as PC and PowerMac systems. +%ifarch %ix86 x86_64 s390x +%package kvm +Url: http://www.linux-kvm.org +Summary: Kernel-based Virtual Machine +Group: System/Emulators/PC +Version: 1.7.0 +Release: 0 +BuildArch: noarch +Requires: qemu = 1.7.0 +Recommends: python-curses + +%description kvm +KVM (Kernel-based Virtual Machine) is virtualization software for Linux. +It is designed to leverage the hardware virtualization features included +with various architectures. QEMU uses KVM for CPU virtualization, while +still providing emulation of other system components. This package is +not required for KVM usage, but rather facilitates its usage with tools +derived from the legacy kvm package. +%endif + %if 0%{?suse_version} >= 1210 %package lang Summary: Universal CPU emulator -- Translations @@ -386,6 +419,26 @@ install -D -m 644 %{SOURCE302} $RPM_BUILD_ROOT/%{_sysconfdir}/qemu/bridge.conf %if 0%{?suse_version} >= 1210 %find_lang %name %endif +%ifarch %ix86 x86_64 s390x +cat > %{buildroot}%{_bindir}/qemu-kvm << 'EOF' +%ifarch %s390x +exec /usr/bin/qemu-system-s390x -machine accel=kvm "$@" +%else +exec /usr/bin/qemu-system-x86_64 -machine accel=kvm "$@" +%endif +EOF +chmod 755 %{buildroot}%{_bindir}/qemu-kvm +%ifarch %ix86 x86_64 +%if 0%{?suse_version} >= 1230 +install -D -m 644 %{SOURCE1} %{buildroot}%{_udevrulesdir}/80-kvm.rules +%else +install -D -m 644 %{SOURCE5} %{buildroot}%{_udevrulesdir}/60-kvm.rules +%endif +%endif +install -D -m 755 %{SOURCE2} %{buildroot}/usr/share/qemu/qemu-ifup +install -D -m 755 %{SOURCE3} %{buildroot}%{_bindir}/kvm_stat +install -D -m 644 %{SOURCE4} %{buildroot}%{_mandir}/man1/qemu-kvm.1.gz +%endif %fdupes -s $RPM_BUILD_ROOT %clean @@ -398,6 +451,14 @@ rm -rf ${RPM_BUILD_ROOT} %{_sbindir}/useradd -r -g qemu -G kvm -d / -s /sbin/nologin \ -c "qemu user" qemu +%ifarch %ix86 x86_64 s390x +%post +if [ "$(readlink -f /proc/1/root)" = "/" ]; then + /sbin/udevadm control --reload-rules || : + /sbin/udevadm trigger || : +fi +%endif + %if 0%{?suse_version} >= 1130 %post tools %set_permissions %_libexecdir/qemu-bridge-helper @@ -427,8 +488,25 @@ rm -rf ${RPM_BUILD_ROOT} %exclude %_datadir/%name/pxe-ne2k_pci.rom %exclude %_datadir/%name/pxe-rtl8139.rom %exclude %_datadir/%name/pxe-virtio.rom +%exclude %_datadir/%name/qemu-ifup %dir %_sysconfdir/%name %config %_sysconfdir/%name/target-x86_64.conf +%ifarch %ix86 x86_64 +%if 0%{?suse_version} >= 1230 +%{_udevrulesdir}/80-kvm.rules +%else +%{_udevrulesdir}/60-kvm.rules +%endif +%endif + +%ifarch %ix86 x86_64 s390x +%files kvm +%defattr(-,root,root) +%_bindir/qemu-kvm +%_bindir/kvm_stat +%_datadir/qemu/qemu-ifup +%_mandir/man1/qemu-kvm.1.gz +%endif %if 0%{?suse_version} >= 1210 %files lang -f %name.lang diff --git a/qemu.spec.in b/qemu.spec.in index 14196cad..cd8423da 100644 --- a/qemu.spec.in +++ b/qemu.spec.in @@ -31,6 +31,11 @@ Group: System/Emulators/PC Version: 1.7.0 Release: 0 Source: %name-1.7.0.tar.bz2 +Source1: 80-kvm.rules +Source2: qemu-ifup +Source3: kvm_stat +Source4: qemu-kvm.1.gz +Source5: 60-kvm.rules # This patch queue is auto-generated from https://github.com/openSUSE/qemu PATCH_FILES # Please do not add patches manually here, run update_git.sh. @@ -112,6 +117,14 @@ BuildRequires: libspice-server-devel BuildRequires: spice-protocol-devel %endif %endif +%ifarch %ix86 x86_64 s390x +BuildRequires: udev +%if %( echo `rpm -q --queryformat %%{version} udev` ) > 190 +%define _udevrulesdir /usr/lib/udev/rules.d +%else +%define _udevrulesdir /lib/udev/rules.d +%endif +%endif Requires: /usr/sbin/groupadd Requires: pwdutils Requires: qemu-ipxe @@ -130,6 +143,26 @@ binaries for different architectures under your native operating system. It currently emulates x86, ARM, PowerPC and SPARC CPUs as well as PC and PowerMac systems. +%ifarch %ix86 x86_64 s390x +%package kvm +Url: http://www.linux-kvm.org +Summary: Kernel-based Virtual Machine +Group: System/Emulators/PC +Version: 1.7.0 +Release: 0 +BuildArch: noarch +Requires: qemu = 1.7.0 +Recommends: python-curses + +%description kvm +KVM (Kernel-based Virtual Machine) is virtualization software for Linux. +It is designed to leverage the hardware virtualization features included +with various architectures. QEMU uses KVM for CPU virtualization, while +still providing emulation of other system components. This package is +not required for KVM usage, but rather facilitates its usage with tools +derived from the legacy kvm package. +%endif + %if 0%{?suse_version} >= 1210 %package lang Summary: Universal CPU emulator -- Translations @@ -304,6 +337,26 @@ install -D -m 644 %{SOURCE302} $RPM_BUILD_ROOT/%{_sysconfdir}/qemu/bridge.conf %if 0%{?suse_version} >= 1210 %find_lang %name %endif +%ifarch %ix86 x86_64 s390x +cat > %{buildroot}%{_bindir}/qemu-kvm << 'EOF' +%ifarch %s390x +exec /usr/bin/qemu-system-s390x -machine accel=kvm "$@" +%else +exec /usr/bin/qemu-system-x86_64 -machine accel=kvm "$@" +%endif +EOF +chmod 755 %{buildroot}%{_bindir}/qemu-kvm +%ifarch %ix86 x86_64 +%if 0%{?suse_version} >= 1230 +install -D -m 644 %{SOURCE1} %{buildroot}%{_udevrulesdir}/80-kvm.rules +%else +install -D -m 644 %{SOURCE5} %{buildroot}%{_udevrulesdir}/60-kvm.rules +%endif +%endif +install -D -m 755 %{SOURCE2} %{buildroot}/usr/share/qemu/qemu-ifup +install -D -m 755 %{SOURCE3} %{buildroot}%{_bindir}/kvm_stat +install -D -m 644 %{SOURCE4} %{buildroot}%{_mandir}/man1/qemu-kvm.1.gz +%endif %fdupes -s $RPM_BUILD_ROOT %clean @@ -316,6 +369,14 @@ rm -rf ${RPM_BUILD_ROOT} %{_sbindir}/useradd -r -g qemu -G kvm -d / -s /sbin/nologin \ -c "qemu user" qemu +%ifarch %ix86 x86_64 s390x +%post +if [ "$(readlink -f /proc/1/root)" = "/" ]; then + /sbin/udevadm control --reload-rules || : + /sbin/udevadm trigger || : +fi +%endif + %if 0%{?suse_version} >= 1130 %post tools %set_permissions %_libexecdir/qemu-bridge-helper @@ -345,8 +406,25 @@ rm -rf ${RPM_BUILD_ROOT} %exclude %_datadir/%name/pxe-ne2k_pci.rom %exclude %_datadir/%name/pxe-rtl8139.rom %exclude %_datadir/%name/pxe-virtio.rom +%exclude %_datadir/%name/qemu-ifup %dir %_sysconfdir/%name %config %_sysconfdir/%name/target-x86_64.conf +%ifarch %ix86 x86_64 +%if 0%{?suse_version} >= 1230 +%{_udevrulesdir}/80-kvm.rules +%else +%{_udevrulesdir}/60-kvm.rules +%endif +%endif + +%ifarch %ix86 x86_64 s390x +%files kvm +%defattr(-,root,root) +%_bindir/qemu-kvm +%_bindir/kvm_stat +%_datadir/qemu/qemu-ifup +%_mandir/man1/qemu-kvm.1.gz +%endif %if 0%{?suse_version} >= 1210 %files lang -f %name.lang