Rust 💙 GNOME Hackfest: Day 1

Hello everyone,

This is a report of the first day of the Rust 💙 GNOME Hackfest that we are having in Madrid at the moment. During the first day we had a round of introductions and starting outlining the state of the art.

IMG_20180418_095328
A great view of Madrid’s skyline from OpenShine’s offices

At the moment most of the focus is around the gobject_gen! macro, the one that allows us to inherit GObjects. We already have basic inheritance support, private structure, signals and methods. The main outstanding issues are:

  • Properties support, which danigm is working on
  • Improve compiler errors for problems within the macro, which antonyo and federico worked on
  • Interface implementation and declaration
  • Cover more Rust<->GObject/GLib/C type conversion coverage

I’ve been focusing mostly on improving the support for the private structure of GObject classes. At the moment this is how you do it:

struct MyPrivateStruct {
        val: Cell<u32>,
}

gobject_gen! {
    class Foo {
        type InstancePrivate = MyPrivateStruct;
    }

    pub fn my_method(&self) {
        self.get_priv().val.set(30);
    }
}

Which I find rather cumbersome, I’m aiming at doing something like this:

gobject_gen! {
    class Foo {
        val: Cell<u32>;
    }

    pub fn my_method(&self) {
        self.val.set(30);
    }
}

Which is a bit more intuitive and less verbose. The private struct is generated behind the scenes and the de-referencing is done through the Deref trait. The challenge now is how to allow for default values for the private structure. This was done through the Default trait on the current implementation, but I’m not sure this is the best way forward to make this easy to use.

By the way, the hackfest is being kindly hosted by our friends at OpenShine, which besides being free software enthusiasts and supporters, are great at deploying kubernetes, Big Data and analytics solutions.
logo-alta-alpha1

Advertisements

1+ year of Fedora and GNOME hardware enablement

A year and a couple of months ago, Christian Schaller asked me to pivot a little bit from working full time on Fleet Commander to manage a new team we were building to work on client hardware enablement for Fedora and GNOME with an emphasis on upstream. The idea was to fill the gap in the organization where nobody really owned the problem of bringing up new client hardware features vertically across the stack (from shell down to the kernel), or rather, ensure Fedora and GNOME both work great on modern laptops. Part of that deal was to take over the bootloader and start working closer to customers and hardware manufacturing parnters.

15525894974_17d28e4e5c_z.jpg
Sound Blaster 16 PnP, Danipuntocom @ Flickr, CC BY-NC 2.0

At first I hesitated as I wasn’t sure I could do a good job, y’all know how the impostor syndrome works specially outside of the comfort zone, also had very little engineering experience on the kernel or hardware related fields outside the hardware design I did at uni.

However after some thinking I thought this was a terribly exciting prospect and I had some ideas as to how to go about it and do a decent job.

Fast forward 16 months and I’m loving it, in a relatively short period of time we’ve been able to build an amazing team that have been able to execute quite a few important highlights to make Fedora and GNOME work better on laptops:

  • Peter Jones and Javier Martinez are taking care of the bootloader stack for Fedora, from GRUB2 to the UEFI tooling, including the secure boot and the low level bits of the firmware update mechanisms. Our current efforts revolve around http boot, enabling TPM2 in the bootloader for Trusted Boot and implement the Boot Loader Spec in Fedora across the supported architectures to improve reliability when updating kernels, BLS prevents you from needing to generate a GRUB configuration file every time a kernel is installed or removed.
  • Hans de Goede has been working on some neglected areas hardware support wise. When he was transferred he was still working on improving optimus support for NVIDIA hardware. You’ve probably seen two major highlights from Hans’ work lately, one is us spending some time to help VirtualBox upstream their guest drivers since we wanted to make Fedora and the Linux ecosystem at large work out of the box (pun not intended), this is really important as VirtualBox is the first approach many Windows and Mac users have to a Linux operating system and desktop, so we’ve decided to treat it as an important hardware platform for us as we do with KVM/QEMU/GNOME Boxes. He has also been working  and most recently he has hit headlines with his amazing and thorough work on improving battery life in Fedora by trying to gather data on which power saving defaults we can enable safely on which devices.
  • Christian Kellner has been doing tons of vertical integration, first he revamped GNOME Battery Bench, to improve battery teststing and gather better data about consumption  when we try new laptops. He has also been looking at fingerprint, bluetooth and pulseaudio issues. But more recently he has taken the torch to implement Thunderbolt 3 Security levels. This is a pretty big deal and has required a ton of design work with jimmac and Bastien. For those unaware, this is a feature enabled by default in modern laptops that will prevent Thuderbolt devices to be enabled just by plugging them and it will require some sort of authorization from the user. This is important as Thunderbolt is basically a PCI-e bus slave that has access to your entire system so malicious peripherals or cables could access sensitive data.
  • Last but not least, Benjamin Berg has been doing a lot of work behind the scenes to improve laptop testing and coming up with a testing suite people can use to test a laptop and bring back a standardized results to Fedora to keep track of regressions and gaps on specific laptop models. We’re trying to automate as much as we can but we still have to write a lot of manual tests for this. This is ongoing work but I think it’s going to help Fedora and the larger Linux ecosystem to be more thorough when it comes to testing hardware and preventing regressions.

Beyond the engineering efforts, we are working with OEMs and silicon vendors as well to try to educate them in the difficult transition from the proprietary OS model to contribute upstream. Some of them are doing really great work and others need improvement. While I can’t share any specific details of these conversations, I must say it’s an incredibly exciting moment for Linux on laptops/workstations and if we are able to push enough silicon vendors to have a more fluent relationship with upstream I think we really have a chance to reduce the problems people have with newer hardware at least on the enterprise offerings at first.

I have to say, it is an incredibly humbling experience to work with this team, I’m learning a lot about the space and I’m excited about the things we’re planning for the next couple of years and the opportunities those efforts could bring for the free software desktop.

Fleet Commander is looking for a GSoC student to help us take over the world

Fleet Commander has seen quite a lot of progress recently, of which I should blog about soon. For those unaware, Fleet Commander is an effort to make GNOME great for IT administrators in large deployments, allowing them to deploy desktop and application configuration profiles across hundreds of machines with ease through a web administration UI based on Cockpit. It is mostly implemented in Python.

One important aspect of large deployments is their identity management systems to handle large numbers of users, groups and hosts. On the free software end, FreeIPA is the project that we’ve integrated Fleet Commander with. FreeIPA is an administrative interface and sets of APIs that integrates LDAP directory, DNS and other related services together. Another way to describe FreeIPA is as the Linux’s counterpart of Microsoft’s Active Directory.
logoactivedirectory.png
And that’s precisely what the GSoC idea we want a student for is about, we think that the best way to encourage GNOME usage in large organizations is to have tools that ease the migration, many organizations may have an existing Microsoft Windows deployment managed by Active Directory, so we want Fleet Commander to be able to use Active Directory as well as FreeIPA as the identity management system and data store for the profile data (by using Group Policy Objects).

This project would be mostly implemented in Python and it will require talking to AD’s LDAP server and CIFS/Samba storage, we are fairly confident that it can be achieved during the GSoC term.

If you are looking for a fun GSoC project, you’re skilled in Python and are interested in becoming a GNOME contributor by helping it reach a larger user base and take it one step closer to world domination and make some money in the process you should apply!

We’re hanging around in the #fleet-commander IRC channel in irc.freenode.net if you want to approach us to get a better understanding of the idea, look for ogutierrez, fidencio and aruiz if you have any questions.

GUADEC 2017: GNOME’s Renaissance

NOTE: This is a blog post I kept as a draft right after GUADEC to reflect on it and the GNOME project but failed to finish and publish until now. Forgive any outdated information though I think the post is mostly relevant still.

I’m on my train back to London from Manchester, where I just spent 7 amazing days with my fellow GNOME community members. Props to the local team for an amazing organization, everything went smoothly and people seemed extremely pleased with the setup as far as I can tell and the venues seemed to have worked extremely well. I mostly want to reflect on a feeling that I have which is that GNOME seems to be experiencing a renaissance in the energy and focus of the community as well as the broader interest from other players.

35538262073_de005dfb31_z
Source: kitty-kat @ flickr CC BY-SA 4.0

Peak attendance and sponsorship

Our attendance numbers have gone up considerably from the most recent years, approximately 260 registrations, minus a bunch of people who could not make it in the end. That is an increase of ~50-60 attendants which is really encouraging.

On top of that this years’ sponsorships went up both in the number of companies sponsoring and supporting the event, this is really encouraging as it shows that there is an increased interest in the project and acknowledgement that GUADEC

Comebacks

There are two comebacks that were actually very encouraging, first, Canonical and Ubuntu community members are back, and it was really encouraging to see them participating. Additionally, members of the Solaris Desktop team showed up too. Also, having Andrew Walton from VMWare around was encouraging too.

Balance was brought back to the force

Historically Red Hat would have a prominent presence at GUADEC and in GNOME in general, it was really amazing to see that Endless is now a Foundation AdBoard member, but also, that the amount of Endless crew at GUADEC matched that of Red Hat.

Contrary of what people may think, Red Hat does not generally enjoy being the only player in any given free software community, however since Nokia and Sun/Oracle retreated their heavy investment in GNOME, Red Hat was probably the most prominent player in the community until now. While Red Hat is still investing as heavily as ever in GNOME, we’re not the only major player anymore, and that is something to celebrate and to look forward to see expanded to other organizations.

It was particularly encouraging to see the design sessions packed with people from Endless, Canonical and Red Hat as well as many other interested individuals.

Flathub

It feels to me that Flatpak, and specially the current efforts around Flathub have helped focused the community towards a common vision for the developer and the user story and you can feel the common excitement that we’re onto something and its implications across the stack and our infrastructure.

Obviously, not everybody shares this enthusiasm around flatpak itself, but the broad consensus is that the model around it is worth pursuing and that it has the potential to raise considerably the viability of the Free Software desktop and personal devices, not to mention, it gives a route towards monetization of free software and Linux apps.

GitLab, Meson and BuildStream

Another batch of modernization in our stack and infrastructure. First and foremost, the GitLab migration which we believe it will not only improve the interaction of newcomers and early testers as well as improving our Continuous Integration pipeline.

Consensus around Meson and leaving autotools behind is another big step and many other relevant free software projects are jumping to the bandwagon. And last but not least, Tristan and Codethink are leading an effort to consolidate continuous and jhbuild into BuildStream, a better way to build a collection of software from multiple source repositories.

Looking ahead

I think that the vibe at GUADEC and the current state of GNOME is really exciting, there are a lot of things to look forward to as well. My main take away is that the project is in an incredibly healthy state, with a rich ecosystem of people committing entire companies on products based on what the GNOME community writes and a commitment to solve some of the very hard remaining problems left to make the Free Desktop a viable contender to what the industry offers right now.

Promising times ahead.

Fleet Commander: production ready!

It’s been awhile since I last wrote any updates about Fleet Commander, that’s not to say that there hasn’t been any progress since 0.8. In many senses we (Oliver and I) feel like we should present Fleet Commander as a shiny new project now as many changes have gone through and this is the first release we feel is robust enough to call it production ready.

What is Fleet Commander?

For those missing some background, let me introduce Fleet Commander for you, Fleet Commander is an integrated solution for large Linux desktop deployments that provides a configuration management interface that is controlled centrally and that covers desktop, applications and network configuration. For people familiar with Group Policy Objects in Active Directory in Windows, it is very similar.

Many people ask why not use other popular Linux configuration management tools like Ansible or Puppet, the answer is simple, those are designed for servers that run in a controlled environment like a data center or the cloud, it follows a push model where the configuration changes happen as a series of commands run in the server. If something goes wrong it is easy to audit and rollback if you have access to that server. However desktop machines in large corporate environments can run many times behind a NAT on a public WiFi, think a laptop owned by an on-site support engineer that roams from site to site. Fleet Commander pulls a bunch of configuration data and makes it available to apps without running intrusive shell scripts or walking in into users’ $HOME directory. Ansible and puppet did not solve the core problems of desktop session configuration management so we had to create something new.

At Red Hat we talk to many enterprise desktop customers with a mixed environment of Windows, Macs and Linux desktops and our interaction with them has helped us identify this gap in the GNOME ecosystem and motivated us to roll up our sleeves and try to come up with an answer.

How to build a profile

The way Fleet Commander works when building profiles is somewhat interesting compared to its competitors. We’ve inspired our solution on the good old Sabayon tool. On our admin web UI you get a VM desktop session where you run and configure your apps, Fleet Commander will record those changes and list them. The user will select them and the final selection will get bound together as part of the profile.

You can then apply the profile to individual users, groups, hosts or host groups.

07_live_session_change_review-94862769.png

Supported apps/settings

Right now we support anything dconf based (GSettings), GNOME Online Accounts, LibreOffice and NetworkManager. In the near future we plan to tackle our main problem which is giving support to browsers, we’re probably going to start just with bookmarks as it is the most demanded use case.

Cockpit integration

02_fc_loading_screen-ecb820e0

The Fleet Commander UI runs on top of the Cockpit admin UI. Cockpit has given us a lot of stuff for free (a basic UI framework, a web service, built-in websocket support for our SPICE javascript client, among many other things).

FreeIPA Integration

A desktop configuration management solution has to be tightly tied to an identity management solution, (like in Active Directory), FreeIPA is the best Free Software corporate identity management project out there and integrating with it allowed us to remove quite a bit of complexity from our code base while improving security. FreeIPA now stores the profile data and the assignments to users, groups and hosts.

SSSD

SSSD is the client daemon that enrolls and authenticates a Linux machine in a FreeIPA or Active Directory domain, having fleet commander hooking into it was a perfect fit for us and also allowed us to remove a bunch of code from previous versions while having a much more robust implementation. SSSD now retrieves and stores the profile data from FreeIPA.

fleet-commander.org

Our new website is live! We have updated introduction materials and documentation and jimmac has put together a great design and layout. Check it out!
I’d like to thank Alexander Bokovoy and Fabiano Fidencio for their invaluable help extending FreeIPA and SSSD to integrate with Fleet Commander and Jakub for his help on the website design. If you want to know more, join us on our IRC channel (#fleet-commander @ freenode) and our GitHub project page.

It is currently available in Fedora 26 and we are in the process of releasing EPEL packages for CentOS/RHEL.

gnome-class: Integrating Rust and the GNOME object system

(this is a re-post from Niko Matsaki’s blog that I’m sharing here for the benefit of the Planet GNOME readers, you can read the original post here)

I recently participated in the GNOME / Rust “dev sprint” in Mexico City. (A thousand thanks to Federico and Joaquin for organizing!) While there I spent some time working on the gnome-class plugin. The goal of gnome-class was to make it easy to write GObject implementations in Rust which would fully interoperate with C code.

Roughly speaking, my goal was that you should be able to write code that looked and felt like Vala code, but where the method bodies (and types, and so forth) are in Rust. The plugin is in no way done, but I think it’s already letting you do some pretty nice stuff. For example, this little snippet defines a Counterclass offering two methods (add() and get()):

gobject_gen! {
    class Counter {
        struct CounterPrivate {
            f: Cell<u32>
        }

        fn add(&self, x: u32) -> u32 {
            let private = self.private();
            let v = private.f.get() + x;
            private.f.set(v);
            v
        }

        fn get(&self) -> u32 {
            self.private().f.get()
        }
    }
}

You can access these classes from Rust code in a natural way:

let c = Counter::new();
c.add(2);
c.add(20);

Under the hood, this is all hooked up to the GNOME runtime. So, for example, Counter::new()translates to a call to g_object_new(), and the c.add() calls translate into virtual calls passing through the GNOME class structure. We also generate extern "C" functions so you should be able to call the various methods from C code.

Let’s go through this example bit-by-bit and I’ll show you what each part works. Along the way, we can discuss the GNOME object model. Finally, we can cover some of the alternative designs that I considered and discarded, and a few things we could change in Rust to make everything smoother.

Mapping between GNOME and Rust ownership

The basic GNOME object model is that every object is ref-counted. In general, if you are given a Foo*pointer, it is assumed you are borrowing that ref, and it you want to store that Foo* value somewhere, you should increment the ref-count for yourself. However, there are other times when ownership transfer is assumed. (In general, the GNOME has strong conventions here, which is great.)

I’ve debating about how best to mirror this in Rust. My current branch works as follows, using the type Counter as an example.

  • Counter represents an owned reference to a Counter object. This is implicitly heap-allocated and reference-counted, per the object model.
    • Counter implements Clone, which will simply increment the reference count but return the same object.
    • Counter implements Drop, which will decrement the reference count.
    • In terms of its representation, Counter is a newtype’d *mut GObject.
  • &Counter is used for functions that wish to “borrow” a counter; if they want to store a version for themselves, they can call clone().
    • Hence the methods like add() are &self methods.
    • This works more-or-less exactly like passing around an &Rc<T> or &Arc<T> (which, incidentally, is the style I’ve started using all of the time for working with ref-counted data).

Note that since every Counter is implicitly ref-counted data, there isn’t much point to working with an &mut Counter. That is, you may have a unique reference to a single handle, but you can’t really know how many aliases are of Counter are out there from other sources. As a result, when you use gnome_gen!, all of the methods and so forth that you define are always going to be &selfmethods. In other words, you will always get a shared reference to your data.

Because we have only shared references, the fields in your GNOME classes are going to be immutable unless you package them up Cell and RefCell. This is why the counter type, for example, stores its count in a field f: Cell<u32> – the Cell type allows the counter to be incremented and decremented even when aliased. It does imply that it would be unsafe to share the Counter across multiple threads at once; but this is roughly the default in GNOME (things cannot be shared across threads unless they’ve been designed for that).

Private data in GNOME

When it comes to data storage, the GNOME object model works a bit differently than a “traditional” OO language like Java or C++. In those more traditional languages, an object is laid out with the vtable first, and then the fields from each class, concatenated in order:

object --> +-------------------+
           | vtable            |
           | ----------------- |
           | superclass fields |
           | ----------------- |
           | subclass fields   |
           +-------------------+

The nice thing about this is that the object pointer can safely be used as either a Superclasspointer or a Subclass pointer. But there is a catch. If new fields are added to the superclass, then the offset of all my subclass fields will change – this implies that all code using my object as a Subclasshas to be recompiled. What’s worse, this is true even if all I wanted to do is to add a private field to the superclass. In other words, adding fields in this scheme is an ABI-incompatible change – meaning that we have to recompile all downstream code, even if we know that this compilation cannot fail.

Therefore, the GNOME model works a bit differently. While you can have fields allocated inline as I described, the recommendation is instead to use a facility called “private data”. With private data, you define a struct of fields accessible only to your class; these fields are not stored “inline” in your object at some statically predicted offset. Instead, when you allocate your object, the GNOME memory manage will also allocate space for the private data each class needs, and you can ask (dynamically) for the offset. (Appendix A goes into details on the actual memory layout.)

The gobject_gen! macro is setup to always use private data in the recommended fashion. If take another look at the header, we can see the private data struct for the Counter class is defined in the very beginning, and given the name CounterPrivate:

gobject_gen! {
    class Counter {
        struct CounterPrivate {
            f: Cell<u32>
        }
        
        ...
    }
}

In the code, when we want to access the “private” data, we use the private() method. This will return to us a &CounterPrivate reference that we can use. For example, defining the get()method on our counter looks like this:

fn get(&self) -> u32 {
    self.private().f.get()
}

Although the offset of the private data for a particular class is not known statically, it is still always constant in any given execution. It’s just that it can change from run to run if different versions of libraries are in use. Therefore, in C code, most classes will inquire once, during creation time, to find the offset of their private data, and then store this result in a global variable. The current Rust code just inquires dynamically every time.

Object construction

gobject_gen! does not expose traditional OO-style constructors. Instead, you can define a function that produces the initial values for your private struct – if you do not provide anything, then we will usethe Rust Default trait.

The Counter example, in fact, provided no initialization function, and hence it was using the Default trait to initialize the field f to zero. If we wanted to write this explicitly, we could have added an init { } block. For example, the following variant will initialize the counter to 22, not 0:

gobject_gen! {
    class Counter {
        struct CounterPrivate {
            f: Cell<u32>
        }

        init {
            CounterPrivate {
                f: Cell::new(22)
            }
        }
        
        ...
    }
}    

Note that init blocks take no parameters – at the time when it executes, the object’s memory is still not fully initialized, and hence we can’t safely give access it. (Unlike in Java, we don’t necessarily have a “null” value for all types.)

The general consensus at the design sprint was that the Best Practices for writing a GNOME object was to avoid a “custom constructor” but instead to define public properties and have creators specify those properties at construction time. I did not yet model properties, but it seems like that would fit nicely with this initialization setup.There is also a hook that one can define that will execute once all the “initial set” of properties have been initialized – I’d like to expose this too, but didn’t get around to it. This would be similar to init, presumably, except that it would give access to a &self pointer.

Similarly, we could extend gobject_gen! to offer a more “traditional” OO constructor model, similar to the one that Vala offers. This too would layer on top of the existing code: so your init() function would run first, to generate the initial values for the private fields, but then you could come afterwards and update them, making use of the parameters. (You can model this today just by defining an fn initialize(&self) method, effectively.)

What still needs work?

So we’ve seen what does work (or what kind of works, in the case of subclassing). What work is left? Lots, it turns out. =)

Private data support could be smoother

I would prefer if you did not have to type self.private() to access private data. I would rather if you could just do self.f to get access to a private field f. For that to work, though, we’d need to have something like the fields in traits RFC – and probably an expanded version that has a few additional features. In particular, we’d need the ability to map through derefs, or possibly through custom code; read-only fields would likely help too. Now that this blog post is done, I plan to post a comment on that RFC with some observations and try to get it moving again.

Interfacing with C

I haven’t really implemented this yet, but I wanted to sketch how I envision that this macro could interface with C code. We already handle the “Rust” side of this, which is that we generate C-compatible functions for each method that do the ceorrect dispatch; these follow the GNOME naming conventions (e.g., Counter_add() and Counter_get()). I’d also to have the macro to generate a .h file for you (or perhaps this should be done by a build.rs script, I’m not yet sure), so that you can easily have C code include that .h file and seamlessly use your Rust object.

Interfacing with gtk-rs

There has already been a lot of excellent work mirroring the various GNOME APIs through the gtk-rs crates. I’m using some of those APIs already, but we should do some more work to make the crates more intercompatible. I’d love it if you easily subclass existing classes from the GNOME libraries using gnome_gen!. It should be possible to make this work, it’ll just take some coordination.

Making it more convenient to work with shared, mutable data

Since all GNOME objects are shared, it becomes very important to have ergonomic libraries for working with shared, mutable data. The existing types in the standard library – Cell and RefCell – are very general but not always the most pleasant to work with.

If nothing else, we could use some convenient types for other scenarios, such as a Final<T> that corresponds to a “write-once” variable (the name is obviously inspired by final fields in Java, though ivars is another name commonly used in the parallel programming community). Final<T> would be nice for fields that start out as null but which are always initialized during construction and then never changed again. The nice thing would be that Final<T> could implement Deref (it would presumably panic if the value has not yet been assigned).

Supporting more of the GNOME object model

There are also many parts of GNOME that we don’t model yet.

We don’t really support subclassing yet. I have a half-executed plan for supporting it, but this is a topic worthy of a post of its own, so I’ll just leave it at that.

Properties are probably the biggest thing; they are fairly simple conceptually, but there are lots of knobs and whistles to get right.

We don’t support constructing an object with a list of initial property values nor do we support the post-initialization hook. In C code, when constructing a GNOME object, once can use a var-args style API to supply a bunch of initial values:

g_object_new(TYPE_MEDIA,
             "inventory-id", 42,
             "orig-package", FALSE,
             NULL); 

I imagine modeling this in Rust using a builder pattern:

Media::with()
    .inventory_id(42)
    .orig_package(false)
    .new()

We don’t support signals, which are a kind of message bus system that I don’t really understand very well. =)

Procedural macro support on Rust is young

There is still a long ways to before the gnome_gen! plugin is really usable. For one thing, it relies on a number of unstable Rust language features – not the least of them being the new procedural macro system. It also inherits one very annoying facet of the current procedural macros, which is that all source location information is lost. This means that if you have type errors in your code it just gives you an error like “somewhere in this usage of the gnome_gen! macro”, which is approximately useless since that covers the entire class definition. This is obviously something we aim to improve through PRs like #40939.

Conclusion

Overall, I really enjoyed the sprint. It was great to meet so many GNOME contributors in person. I was very impressed with how well thought out the GNOME object system is.

Obviously, this macro is in its early days, but I’m really excited about its current state nonetheless. I think there is a lot of potential for GNOME and Rust to have a truly seamless integration, and I look forward to seeing it come together.

I don’t know how much time I’m going to have to devote to hacking on the macro, but I plan to open up various issues on the repository over the next little while with various ideas for expansions and/or design questions, so if you’re interested in seeing the work proceed, please get involved!

Finally, I want to take a moment to give a shoutout to jseyfried and dtolnay, who have done excellent work pushing forward with procedural macro support in rustc and the quote! libraries. Puttinggobject_gen! together was really an altogether pleasant experience. I can’t wait to see those APIs evolve more: support for spans, first and foremost, but proper hygiene would be nice too, sincegobject_gen! has to generate various names as part of its mapping.


Appendix A: Memory layout of private data

My understanding is that the private data feature evolved over time. When the challenges around ABI compatibility were first discovered, a convention developed of having each object have just a single “inline” field. Each class would then malloc a separate struct for its private fields. So you wound up with something like this:

object --> +--------------------+
           | vtable             |
           | ------------------ |
           | SuperclassPrivate* | ---> +-------------------+
           | ------------------ |      | superclass fields |
           | SubclassPrivate*   | --+  +-------------------+
           +--------------------+   |
                                    +--> +-----------------+
                                         | subclass fields |
                                         +-----------------+

Naturally any class can now add private fields without changing the offset of others’ fields. However, making multiple allocations per object is inefficient, and it’s easy to mess up the manual memory management involved as well. So the GNOME runtime added the “private” feature, which allows each class to request that some amount of additional space be allocated, and provides an API for finding the offset of that space from the main object. The exact memory layout is (I presume) not defined, but as I understand it things are currently laid out with the private data stored at a negative offset:

           +--------------------+
           | subclass fields    |
           | ------------------ |
           | superclass fields  |
object --> + ------------------ +
           | vtable             |
           +--------------------+

Although no longer necessary, it is also still common to include a single “inline” field that points to the private data, setup during initialization time:

           +--------------------+ <---+
           | subclass fields    |     |
           | ------------------ | <-+ |
           | superclass fields  |   | |
object --> + ------------------ +   | |
           | vtable             |   | |
           + ------------------ +   | |
           | SuperclassPrivate* | --+ |
           | ------------------ |     |
           | SubclassPrivate*   | ----+
           +--------------------+

Fedora: Laptop Hardware Enablement (hint: we’re hiring)

So, since September I have transitioned to a new job, from working on Fleet Commander full time with Oliver, to managing a team whose job is to make sure that a number of laptops (to be defined) are well supported in Fedora, and therefore upstream kernel, Wayland, MESA and GNOME. I’m honored to be working among great people in this space: Hans de Goede, Peter Jones, Christian Kellner and Benjamin Berg.

If you want more details as to the plans of the team, please watch the talk Hans gave at DevConf that you can watch on YouTube.

Of course, I’ll still be managing the Fleet Commander project, which is coming along pretty nicely. Currently Oliver is focusing on the FreeIPA integration.

By the way, I’m hiring a Senior Software Engineer for the team, we’re looking for someone with consumer & enterprise  hardware enablement related skills to help with TPM2 support for x86_64, POWER and ARM in Fedora, people willing to work from Munich are preferred, but we’re open to strong candidates working remotely, if you think this is for you get in touch with me and/or apply.