All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Peter Crosthwaite" <peter.crosthwaite@xilinx.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Daniel P. Berrangé" <berrange@redhat.com>,
	"Eduardo Habkost" <eduardo@habkost.net>
Subject: Ugly QOM property names: paths within paths
Date: Mon, 14 Nov 2022 10:24:17 +0100	[thread overview]
Message-ID: <87iljh51oe.fsf@pond.sub.org> (raw)

I noticed this the other day:

    (qemu) info qom-tree 
    /machine (pc-i440fx-7.2-machine)
      /fw_cfg (fw_cfg_io)
        /\x2from@etc\x2facpi\x2frsdp[0] (memory-region)b
        /\x2from@etc\x2facpi\x2ftables[0] (memory-region)
        /\x2from@etc\x2ftable-loader[0] (memory-region)
        /fwcfg.dma[0] (memory-region)
        /fwcfg[0] (memory-region)
    [...]

It took me a minute to realize that the "\x2" in these property names
are escaped forms of '/'.  I.e. the unescaped path components of the
first property path are

    machine
    fw_cfg
    /from@etc/facpi/frsdp[0]

We're embedding paths within paths.  Ugh!

The escaping happens in memory_region_init():

    static bool memory_region_need_escape(char c)
    {
        return c == '/' || c == '[' || c == '\\' || c == ']';
    }

    static char *memory_region_escape_name(const char *name)
    {
        const char *p;
        char *escaped, *q;
        uint8_t c;
        size_t bytes = 0;

        for (p = name; *p; p++) {
            bytes += memory_region_need_escape(*p) ? 4 : 1;
        }
        if (bytes == p - name) {
           return g_memdup(name, bytes + 1);
        }

        escaped = g_malloc(bytes + 1);
        for (p = name, q = escaped; *p; p++) {
            c = *p;
            if (unlikely(memory_region_need_escape(c))) {
                *q++ = '\\';
                *q++ = 'x';
                *q++ = "0123456789abcdef"[c >> 4];
                c = "0123456789abcdef"[c & 15];
            }
            *q++ = c;
        }
        *q = 0;
        return escaped;
    }

    static void memory_region_do_init(MemoryRegion *mr,
                                      Object *owner,
                                      const char *name,
                                      uint64_t size)
    {
        mr->size = int128_make64(size);
        if (size == UINT64_MAX) {
            mr->size = int128_2_64();
        }
        mr->name = g_strdup(name);
        mr->owner = owner;
        mr->ram_block = NULL;

        if (name) {
            char *escaped_name = memory_region_escape_name(name);
            char *name_array = g_strdup_printf("%s[*]", escaped_name);

            if (!owner) {
                owner = container_get(qdev_get_machine(), "/unattached");
            }

            object_property_add_child(owner, name_array, OBJECT(mr));
            object_unref(OBJECT(mr));
            g_free(name_array);
            g_free(escaped_name);
        }
    }

    void memory_region_init(MemoryRegion *mr,
                            Object *owner,
                            const char *name,
                            uint64_t size)
    {
        object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION);
        memory_region_do_init(mr, owner, name, size);
    }

Goes back to

    commit b4fefef9d52003b6d09866501275a9a57995c6b0
    Author: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
    Date:   Thu Jun 5 23:15:52 2014 -0700

        memory: MemoryRegion: QOMify

        QOMify memory regions as an Object. The former init() and destroy()
        routines become instance_init() and instance_finalize() resp.

        memory_region_init() is re-implemented to be:
        object_initialize() + set fields

        memory_region_destroy() is re-implemented to call unparent().

        Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
        [Add newly-created MR as child, unparent on destruction. - Paolo]
        Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

No mention of the escapery.

Questions:

1. Do we really want to embed slash-separated paths into slash-separated
   paths?

2. As far as I can tell, object.c does not guard against "funny"
   characters such as '/' in path components.  Should it?  For what it's
   worth, the kernel doesn't permit '/' in filenames.

3. Should the escapery live in object.c instead of memory.c?



                 reply	other threads:[~2022-11-15  0:34 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=87iljh51oe.fsf@pond.sub.org \
    --to=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=eduardo@habkost.net \
    --cc=pbonzini@redhat.com \
    --cc=peter.crosthwaite@xilinx.com \
    --cc=qemu-devel@nongnu.org \
    /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.