Icosian Reflections

…a tendency to systematize and a keen sense

that we live in a broken world.

IN  WHICH Ross Rheingans-Yoo—a sometime quantitative trader, economist, expat, EA, artist, educator, and game developer—writes on topics of int­erest.

Adding HTTPS

My Faults My Own (and other rossry.net and r-y.io subdomains) are now available over HTTPS, with certificates from Let's Encrypt. (cf. https://blog.rossry.net/https)

The setup took nontrivial effort, so I've narrated it here for my or your future reference. I don't think there's anything technically novel here, and there may even be an HTTPS-setup guide for 2019 somewhere else that dominates mine for usefulness, but there wasn't one easy-to-find enough that I found it, so here we are.


(0)

First, the dramatis personae:

Let's Encrypt (hereafter "LE"), a project of the nonprofit Internet Security Research Group, issues free TLS (née SSL) certificates; they recommend that site administrators with shell access use the LE client Certbot, a project of the Electronic Frontier Foundation.

My Faults My Own, and other rossry.net and r-y.io subdomain services, are happily hosted by Digital Ocean (this turns out not to matter), running nginx on Ubuntu 14.04. (Certbot supports many other servers and OS setups as well; I'm listing my specifics here just as context for the following narration, especially as this combination specifically has some tricky issues.)

My domain registrar and DNS provider, Namecheap, sadly does not really support Certbot's automated DNS-based authentication (necessary for a "wildcard certificate", which will cover all of *.rossry.net), and I don't want to manually mess with DNS records every 90 days to get new certificates issued.

Fortunately, joohoi/acme-dns is a lightweight DNS server intended specifically to help automate ACME DNS challenges, and even comes with a certbot hook by the author. The dns-01 challenge protocol of the Automatic Certificate Management Environment standard involves setting _acme-challenge.

READ MORE

[Meta] My Faults My Own is now (happily) hosted by Digital Ocean

discount code: If you sign up for Digital Ocean with my referral link, you get $10 of credit and I get $25 of credit after you've spent your first $25. This link should be good indefinitely, and I'm getting no compensation for this review.


Amongst all of the large transitions happening in my life about now, I found it necessary to move my blog server from "some borrowed machine on the Harvard network" to a real-adult location, like "the cloud". After asking a few friends for recommendations, I decided to rent server time from Digital Ocean, at least as a stopgap measure until the end of the summer, when I'd be able to pick out my own internet plan.

I'm glad to report that I couldn't be happier with DO's service. Spinning up a new virtual server and migrating Faults to it was probably the easiest piece of system administration that I've done. I gave them my credit card number, told them that I wanted a $5/mo Ubuntu box, and within two minutes, I had an IP address and login details in my email inbox. Then it was a simple matter of copying RSA keys, an rcp on ~/web/, a separate rcp to handle /etc/nginx/sites-available/, a few apt-get installs and npm installs, a call to node ~/web/ghost/index.js, and a DNS edit at Namecheap (my domain registrar)...and I was done. No gotcha problems. No Google searches that ended up in random Linux users' forums. The experience felt exactly like DO's billing: Simple cloud computing, built for developers.

10/10; would use again.

(It's worth noting that Ghost

READ MORE

[CS161] The Classic CV Error

This is a very technical post, largely for the benefit of the students of CS161: Operating Systems, for which I am a Teaching Fellow this semester. It may be useful to you if you're interested in operating systems for some reason, but if you're not in a CS mood today, maybe just move along.

From what I've seen as a TF for this course, it is very, very normal to write condition-variables code that looks like this:

struct cv {
    struct semaphore *sem;
    volatile int waiters;
}

void cv_wait(struct cv *cv, struct lock *lock) {
    KASSERT(lk_do_i_hold(lock));
    
    cv->waiters++;
    lk_release(lock);
    P(cv->sem);
    lk_acquire(lock);
}

void cv_broadcast(struct cv *cy struct lock *lock) {
    KASSERT(lk_do_i_hold(lock));
    
    for (; cv->waiters > 0; cv->waiters--)
        V(cv->sem);
}

This code is wrong (or, more specifically, badly synchronized). And it is such a common error that I'm choosing to dub it The Classic CV Error. It's subject to a race condition in e.g. the following case:

int before_and_after (int *the_thing, struct cv *thing_changed_cv, struct lock *thing_changed_lock) {
    lk_acquire(thing_changed_lock);
    
    int before = *the_thing;
    cv_wait(thing_changed_cv, thing_changed_lock);
    int after = *the_thing;
    
    KASSERT(before != after);
    
    lk_release(thing_changed_lock);
    return compare_things(before,after);
}

void mess_around (int *the_thing, struct cv *thing_changed_cv, struct lock *thing_changed_lock) {
    lk_acquire(thing_changed_lock);
    mutate(the_thing);
    
    cv_broadcast(thing_changed_cv, thing_changed_lock);
    
    lk_release(thing_changed_lock);
}

This code is properly synchronized (and in particular, protects the KASSERT(before != after)), assuming that your locks and CVs

READ MORE

[CS161] On Scheduling

This is a very technical post, largely for the benefit of the students of CS161: Operating Systems, for which I am a Teaching Fellow this semester. It may be useful to you if you're interested in operating systems for some reason, but if you're not in a CS mood today, maybe just move along.

Why Do We Schedule, Master Bruce?

A scheduler, as you know, is responsible for determining which threads run, for how long, and in what order. As much as possible, it should give the shared illusion that each process is running constantly to completion, using the entire processor. To this end, there are three major desiderata:

  • That interactive threads (in particular, user-interactive threads) are responsive.
  • That no process starves.
  • That the system, on average, runs quickly.

These high-level desiderata factor into the low-level conditions that:

  • Threads which block expecting a response are rescheduled promptly after waking.
  • Time is allocated more-or-less fairly, subject to:
  • Processes closer to completion are prioritized (recall that shortest-time-to-completion-first is provably optimal in total average time)
  • ...but in any case, do not starve even the long-running processes too much (exponentially is a good benchmark -- since that, analytically, places a finite cap on the total runlength of a process).

Many of the designs I've seen from the class in A2 design documents fail in at least one of these respects, so I think it may be useful to go over common design failures and good designs.

indicates a potential issue of which you should be cautious. Check that your system doesn't have this as an issue!


Timeslicing and Timedicing

Not every thread blocks voluntarily; after running a thread for a certain

READ MORE
1 / 1