Author Archives: Mark

About Mark

I'm a systems programmer and jack of a few other trades, sharing what I learn along the way. Follow me on Twitter for much more: @offlinemark ๐Ÿ˜Š.

Why do computers reboot multiple times during an update?

Have you every updated your operating system and your computer rebooted multiple times during the process? Why does this happen? Why isn’t one reboot enough?

In general, if you have some running computer system that wants to upgrade itself, it’s easiest to download the new version, exit, and simply restart from scratch.

This is why you usually have to reboot for OS updates to take effect. On a different level, this is also why you usually have to reboot applications for their software updates to be applied.

The alternative to rebooting is hot swapping: the running program dynamically swapping itself out with the new one โ€” while staying running the entire time. This is harder than rebooting and requires the developer to actually write code to implement this. A reboot-based update generally does not require much code beyond downloading the artifact into the place it will be looked for the next time things start.

If you opt for dynamic swapping, you need to make sure that the update applies cleanly and absolutely in memory โ€” such that there are no lingering pieces of state from the old software lurking. You don’t want to be running half old software, half new software. (Or have old data in memory, half new data)

In general, this is not a problem if you reboot. Reboots start from a clean slate, so you can be sure that after reboot, you’re running with 100% the new software, 0% the old.1

These fundamental principles apply to any update on any kind of system: an application, its dependencies, an operating system (including core userspace libraries), or firmware running on a device.

So why would a computer reboot multiple times during an update?

It’s probably because it has updates A, B, and C to make, and they each require a reboot to take effect.

If there are blocking dependencies between then (C requires B first, which requires A first), there’s no way around doing a reboot after applying each.

If there are no dependencies, then it might be technically feasible to try to apply them all at the same time, and have them all apply together on the next reboot. But even so, such mass changes with multiple things updating all at once can be riskier. So it might still be safest to sacrifice update speed and update in a slower, more controlled manner, one update & reboot at a time.

For example:

  • There is a migration to a newer, fancier update server infrastructure
  • Using this new infra requires a newer version of a core library that is in use on the running old system
  • One last update is pushed to the old infrastructure which updates the core library. Reboot once.
  • Now the system can fetch a new update ZZ that’s sitting in the new infrastructure, using its new library support. Reboot again.
  • And then maybe the version ZZ of the software has some init code that downloads a firmware update for hardware component that ZZ needs to run. This update is incompatible with the previous version and is only applied once ZZ is confirmed to be present and working. Download the firmware update and reboot a third time.

One concrete technique I’m aware of that results in multiple boots is a disk image space optimization.

When building a disk image for a device, it’s common to include a data partition for user data which is separate from the system partition. In real use, the data partition will likely be very large, but when initially building a fresh image, the data partition will be all zeros. This is wasteful and makes the disk image occupy must more space than necessary, which slows down file transfers.

An optimization would be to build the disk image with a smaller data partition โ€” just as big as necessary to hold pre-existing files on the partition. Then on the first boot, resize the partition to occupy the full available space. An easy way to apply that change to the system is to then reboot.

* The exception is persistent state. If your system leaves persistent state on disk or elsewhere, you need to be careful that those artifacts are either compatible with the new system, or migrated.


What’s with the name?

I chose “offlinemark” as a handle for a few reasons:

  • I didn’t want to use my real full name as the handle because of privacy and because I don’t consider my last name a 100% stable API. Ideally this username would last a long time.
  • I like adjectives as usernames, but also including my first name makes it feel a bit personal.
  • It’s highly unique. There’s a strong chance I can always get this username.
  • It’s a bit techy, which is on brand.
  • Aesthetics. I dislike numbers in usernames. I like the visual appearance of the text (all on one line, no underhanging characters).
  • It’s an aspirational reminder. A lot of the best things in life are offline.
  • It appeals to my ironic and quirky sense of humor.

How to enable colored compiler output with CMake + VSCode

Assuming you’re using the “CMake Tools” VSCode extension, here’s what works for me.

1 – Set CMAKE_COLOR_DIAGNOSTICS to ON in your environment

This makes CMake pass -fcolor-diagnostics to clang. If you build on the command line, you’ll now have color. But the VSCode “output” pane will still be non-colored.

2 – Install the “Output Colorizer” extension from IBM.

This adds color to the Output pane.

It looks like this:


WIP: Should everyone be a leader?

I’ve been thinking about leadership lately.

Many children’s programs are designed to foster leadership skills. Why? Does this imply that everyone should have leadership skills? That everyone should be a leader?

This interests me because for the longest time, I never felt like a “Leader”. I didn’t have anything in common with “Leaders” I saw. It didn’t resonate.

But I’ve realized the answer is yes. Everyone should learn leadership skills.

Even if you have no aspirations to start a company or lead a nation, leadership is everywhere.

It’s obviously present on smaller scales โ€” in local organizations, communities, and workplaces. And even if you don’t aspire to be at the top, in any non-trivial organization, it’s still leadership all the way down. Even if you explicitly reject managing people, you can still find yourself as a leader โ€” for example, being a skilled individual specialist carries leadership in its own way.

But less obviously, as soon as you start any kind of project or endeavor of any kind โ€” guess what, you’re now a leader. Any kind of pursuit creates an opening for a leader. By default, the creator fills the role.

Examples of endeavors:

  • Starting a family
  • Co-creating a relationship
  • Organizing a party
  • Planning a trip
  • A creative practice

Without leadership, you can only ever be a “leaf” node, at the end of the chain. Without leadership, you can only ever be a consumer, a viewer, an audience member.

Even if you never start any endeavor, at the very least, you are the leader of your own life. (Which, by the way, is a creative project.)

So, yes, everyone should have leadership skills โ€” not because everyone “should” be a leader, but because everyone already is.

Pick an impressive project, then checkout to the first commit

Why I enjoy hanging out with entrepreneurs

I’ve been a regular attendee at the Indie Hackers Berlin meetup lately. I’m not particularly an entrepreneur myself, but I love hanging out with them because they generally have many of the following qualities:

  • High functioning
  • Smart/Clever (to be successfull, you kind of have to be)
  • Ambitious
  • Creative
  • Unconventional thinkers
  • Into self development
  • Leadership

All of which make them very fun and interesting to be around!

Why I write in public

Note to self. I write because:

  • Improved clarity of thought
  • Archive of thought
  • Improves writing skills

In addition, I write in public because:

  • It reinforces a mindset of speaking my mind in public (i.e. courage)
  • Receive valuable feedback and external perspectives
  • Build relationships

Furthermore, I’ve found that it’s addicting to write in public.

  • It feels good to look back on writing and realize you’ve expressed yourself clear and well. And that you understand the topic well know.
  • It feels good to develop a voice.
  • It feels good to watch yourself improve. You can write better, faster with practice.
  • You become more self-observant of your thoughts, and realize that there are so many interesting things to write about.
  • It feels good to get positive feedback on your writing.

A takeaway I often get from exploit writeups

Can we have non-atomic std::shared_ptr in C++?

Turns out, we do have them. libstdc++ contains a heuristic kludge where it checks if libpthread is linked into the process and conditionally executes an atomic add or non-atomic add depending on the result. Post 2020, it doesn’t directly use the libpthread hack, but uses glibc’s native support for this.

These kinds of things always make me sad about C++ (especially compared to how nice and clean things seem to be in Rust world), but at least it’s nice knowing that the committee did consider it and there are good reasons why to not have this in the C++ stdlib. The most compelling reason is that in the absence of a borrow checker, it is all too easy to silently use a non-atomic shared_ptr in multithreaded code.

Full thread: