All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Laszlo Ersek <lersek@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Eduardo Habkost <ehabkost@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	qemu-devel@nongnu.org, Markus Armbruster <armbru@redhat.com>,
	qemu-arm@nongnu.org, Paolo Bonzini <pbonzini@redhat.com>,
	Igor Mammedov <imammedo@redhat.com>,
	Richard Henderson <rth@twiddle.net>
Subject: Re: [PATCH 1/5] hw/smbios: support loading OEM strings values from a file
Date: Wed, 9 Sep 2020 10:10:34 +0100	[thread overview]
Message-ID: <20200909091034.GL1011023@redhat.com> (raw)
In-Reply-To: <c7ecee55-64a3-5a46-26d9-6a1cc4c7889c@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 3661 bytes --]

On Wed, Sep 09, 2020 at 10:18:47AM +0200, Laszlo Ersek wrote:
> On 09/08/20 18:54, Daniel P. Berrangé wrote:
> > Some applications want to pass quite large values for the OEM strings
> > entries. Rather than having huge strings on the command line, it would
> > be better to load them from a file, as supported with -fw_cfg.
> > 
> > This introduces the "valuefile" parameter allowing for:
> > 
> >   $ echo -n "thisthing" > mydata.txt
> >   $ qemu-system-x86_64 \
> >     -smbios type=11,value=something \
> >     -smbios type=11,valuefile=mydata.txt \
> >     -smbios type=11,value=somemore \
> >     ...other args...
> > 
> > Now in the guest
> > 
> > $ dmidecide -t 11
> > Getting SMBIOS data from sysfs.
> > SMBIOS 2.8 present.
> > 
> > Handle 0x0E00, DMI type 11, 5 bytes
> > OEM Strings
> > 	String 1: something
> > 	String 2: thisthing
> > 	String 3: somemore
> > 
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> > ---
> >  hw/smbios/smbios.c | 72 +++++++++++++++++++++++++++++++++++++---------
> >  1 file changed, 59 insertions(+), 13 deletions(-)
> 
> (gearing up to test this / look into the edk2 problem, just one question
> in passing: could we / would we simplify this with g_file_get_contents()?)

BTW, to test this, I'm doing the following.

See the attached 'make-tiny-initrd.py' script. It expects "busybox" on
the host OS and builds a tiny initrd containing busybox.

It can optionally copy in arbitrary other commands, and shared libraries
they link to.  By default it will launch an interactive shell in the
guest, but you can tell it to run a specific command, after which it
will poweroff.

I want to run dmidecode, so I'm using

 $ make-tiny-image.py --run "dmidecode" dmidecode

which both copies dmidecode into the initrd, and also runs it by
default.

It creates 'tiny-initrd.img'

Then I simply boot the host OS kernel using this initrd.


  ./build/qemu-system-x86_64  \
      -kernel /boot/vmlinuz-5.7.14-200.fc32.x86_64 \
      -initrd tiny-initrd.img
      -append 'console=ttyS0'
      -m 1000
      -serial stdio
      -display none
      -blockdev '{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}'
      -blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}'
      -blockdev '{"driver":"file","filename":"/home/berrange/src/virt/qemu/OVMF_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}'
      -blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}'
      -machine pc-q35-4.0,accel=kvm,usb=off,smm=on,dump-guest-core=off,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,smbios-ep=3_0
      -chardev file,path=firmware.log,id=firmwarelog
      -device isa-debugcon,iobase=0x402,chardev=firmwarelog
      -smbios type=11,path=smallfile.txt


I have a file 'bigfile.txt' that contains 14 MB of plain text.

I then create 'smallfile.txt' from this

  $ dd if=bigfile.txt of=littlefile.txt bs=1 count=130863

If count=130863 or smaller than EDK2 succesfully boots the guest.

If count=130864 or larger then AFAICT it gets stuck in EDK2 or
very early boot - the guest OS never runs.

If smbios-ep=2_1 (or is omitted), then the size limit is smaller of course
but QEMU validates that for you.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

[-- Attachment #2: make-tiny-image.py --]
[-- Type: text/plain, Size: 3653 bytes --]

#!/usr/bin/env python3

import re
import sys
import glob
import argparse
import os
import os.path
import stat
import subprocess
from tempfile import TemporaryDirectory
from shutil import copy

def make_busybox(tmpdir, runcmd):
    usrsbin = os.path.join(tmpdir, "usr/sbin")
    bin = os.path.join(tmpdir, "bin")
    os.makedirs(usrsbin, exist_ok=True)
    os.makedirs(bin, exist_ok=True)

    busyboxin = "/usr/sbin/busybox"
    busyboxout = os.path.join(tmpdir, usrsbin, "busybox")
    copy(busyboxin, busyboxout)
    subprocess.check_call([busyboxin, "--install", "-s", bin])

    init = os.path.join(tmpdir, "init")
    with open(init, "w") as fh:
        print("""#!/bin/sh

mkdir /proc /sys
mount -t proc none /proc
mount -t sysfs none /sys

mount -n -t tmpfs none /dev
mknod -m 622 /dev/console c 5 1
mknod -m 666 /dev/null c 1 3
mknod -m 666 /dev/zero c 1 5
mknod -m 666 /dev/ptmx c 5 2
mknod -m 666 /dev/tty c 5 0
mknod -m 666 /dev/ttyS0 c 4 64
mknod -m 444 /dev/random c 1 8
mknod -m 444 /dev/urandom c 1 9

%s
poweroff -f
""" % runcmd, file=fh)
    os.chmod(init, stat.S_IRWXU)

def get_deps(binary):
    out = subprocess.check_output(["ldd", binary]).decode("utf8")
    deps = []
    for line in out.split("\n"):
        m = re.search("=> (/[^ ]+)", line)
        if m is not None:
            deps.append(m.group(1))
        else:
            m = re.match("\s*(/[^ ]+)\s+\(.*\)\s*$", line)
            if m is not None:
                deps.append(m.group(1))
    return deps
    
def make_binaries(tmpdir, binaries):
    bindir = os.path.join(tmpdir, "bin")

    seen = {}
    libs = []
    for binary in binaries:
        if binary[0] == '/':
            src = binary
            dst = os.path.join(tmpdir, binary[1:])
        else:
            src = os.path.join("/usr/bin", binary)
            if not os.path.exists(src):
                src = os.path.join("/usr/sbin", binary)
            dst = os.path.join(bindir, binary)
        if os.path.exists(dst):
            os.unlink(dst)
        copy(src, dst)

        libs.extend(get_deps(src))

    while len(libs):
        print("Pass libs")
        todo = libs
        libs = []
        for lib in todo:
            if lib in seen:
                continue

            dir = os.path.dirname(lib)
            libdir = os.path.join(tmpdir, dir[1:])
            os.makedirs(libdir, exist_ok=True)
            dst = os.path.join(tmpdir, lib[1:])
            copy(lib, dst)
            print(lib)
            seen[lib] = True
            libs.extend(get_deps(lib))

                              

def make_image(tmpdir, output, binaries, runcmd):
    make_busybox(tmpdir, runcmd)
    make_binaries(tmpdir, binaries)

    files = glob.iglob(tmpdir + "/**", recursive=True)
    prefix=len(tmpdir) + 1
    files = [f[prefix:] for f in files]
    files = files[1:]
    filelist = "\n".join(files).encode("utf8")

    with open(output, "w") as fh:
        subprocess.run(["cpio", "--quiet", "-o", "-H", "newc"],
                       cwd=tmpdir, input=filelist, stdout=fh)

parser = argparse.ArgumentParser(description='Build a tiny initrd image')
parser.add_argument('--output', default="tiny-initrd.img",
                    help='Filename of output file')
parser.add_argument('--run', default="exec setsid cttyhack /bin/sh",
                    help='Command to execute in guest (default: "exec setsid cttyhack /bin/sh")')
parser.add_argument('binary', nargs="*",
                    help='List of binaries to include')

args = parser.parse_args()

print (args.output)

with TemporaryDirectory(prefix="make-tiny-image") as tmpdir:
    make_image(tmpdir, args.output, args.binary, args.run)

  parent reply	other threads:[~2020-09-09  9:11 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-08 16:54 [PATCH 0/5] Add support for loading SMBIOS OEM strings from a file Daniel P. Berrangé
2020-09-08 16:54 ` [PATCH 1/5] hw/smbios: support loading OEM strings values " Daniel P. Berrangé
2020-09-08 18:24   ` Philippe Mathieu-Daudé
2020-09-09  7:35     ` Daniel P. Berrangé
2020-09-09  8:33       ` Philippe Mathieu-Daudé
2020-09-09  8:18   ` Laszlo Ersek
2020-09-09  9:00     ` Daniel P. Berrangé
2020-09-09  9:10     ` Daniel P. Berrangé [this message]
2020-09-09  8:24   ` Laszlo Ersek
2020-09-08 16:54 ` [PATCH 2/5] hw/smbios: report error if table size is too large Daniel P. Berrangé
2020-09-08 18:25   ` Philippe Mathieu-Daudé
2020-09-14  8:02   ` Igor Mammedov
2020-09-08 16:54 ` [PATCH 3/5] qemu-options: document SMBIOS type 11 settings Daniel P. Berrangé
2020-09-08 18:27   ` Philippe Mathieu-Daudé
2020-09-08 16:54 ` [PATCH 4/5] hw/smbios: use qapi for SMBIOS entry point type enum Daniel P. Berrangé
2020-09-08 18:29   ` Philippe Mathieu-Daudé
2020-09-09  7:36     ` Daniel P. Berrangé
2020-09-08 18:37   ` Philippe Mathieu-Daudé
2020-12-09 17:56   ` Eduardo Habkost
2020-09-08 16:54 ` [PATCH 5/5] hw/i386: expose a "smbios_ep" PC machine property Daniel P. Berrangé
2020-09-08 18:38   ` Philippe Mathieu-Daudé
2020-09-09  8:28   ` Laszlo Ersek
2020-09-09  9:44 ` [PATCH 0/5] Add support for loading SMBIOS OEM strings from a file Laszlo Ersek
2020-09-09  9:50   ` Daniel P. Berrangé
2020-09-09 10:58     ` Laszlo Ersek

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=20200909091034.GL1011023@redhat.com \
    --to=berrange@redhat.com \
    --cc=armbru@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=lersek@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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.