Search Results: "ema"

12 October 2012

Russell Coker: Cheap Bulk Storage

The Problem Some of my clients need systems that store reasonable amounts of data. This is enough data that we can expect some data corruption on disk such that traditional RAID doesn t work, that old fashioned filesystems like Ext3/4 will have unreasonable fsck fimes, and that the number of disks in a small server isn t enough. NetApp is a really good option for bulk reliable storage, but their products are very expensive. BTRFS has a lot of potential, but the currently released versions (as supported in distributions such as Debian/Wheezy) lack significant features. One significant lack in current BTRFS releases is something equivalent to the ZFS send/receive functionality for remote backups, this was a major factor when I analysed the options for hard drive based backup [1], and you should always think about backup before deploying a new system. Currently ZFS is the best choice for bulk storage which is reliable if you can t afford NetApp. Any storage system needs a minimum level of reliability if only to protect it s own metadata and a basic RAID array doesn t protect against media corruption with current data volumes. The combination of performance, lack of fsck (which is a performance feature), large storage support, backup, and significant real-world use makes ZFS a really good option. Now I need to get some servers for more than 8.1TiB of storage (the capacity of a RAID-Z array of 4*3TB disks). One of my clients needs significantly more, probably at least 10 disks in a RAID-Z array so none of the cheaper servers will do. Basically the issue that some of my clients are dealing with (and which I have to solve) is how to provide a relatively cheap ZFS system for storing reasonable amounts of data. For some systems I need to start with about 10 disks and be able to scale to 24 disks or more without excessive expense. Also to make things a little easier and cheaper 24*7 operation is not required, so instead of paying for hot-swap disks we can just schedule down-time outside business hours. The Problem with Dell Dell is really good for small systems, the PowerEdge tower servers that support 2*3.5 or 4*3.5 disks and which have space for an SSD or two are really affordable and easy to order. But even in the mid-size Dell tower servers (which are small by server standards) you have problems with just getting a few disks operating outside a RAID array [2]. The Dell online store is really great for small servers, any time I m buying a server for less than $2500 I check the Dell online store first and usually their price is good enough that there is no need to get a quote from another company. Unfortunately all the servers with bigger storage involve disks that are unreasonably expensive (it seems that Dell makes their profit on the parts) and prices are not available online. I gave my email address and phone number to the Dell web site on Wednesday and they haven t cared to get back to me yet. This is the type of service that makes me avoid IBM and HP for any server deployment where the Dell online store sells something suitable! BackBlaze For some time BackBlaze have been getting interest by describing how they store lots of data in a small amount of space by tightly stacking SATA disks. They don t think that ZFS on Linux is ready for production, but their hardware ideas are useful. They have recently described their latest architecture [3]. They describe it as 135TB for $7,384. Of course the 135TB number is based on the idea of getting the full 3TB capacity out of each disk which they can do as they have redundancy over multiple storage pods. But anyone who wants a single fileserver needs some internal redundancy to cover disk failure. One option might be to have three RAID-Z2 arrays of 15 disks which gives a usable capacity of 42*3TB==126TB==113TiB. Note that while the ZFS documentation recommends between 3 and 9 disks per zpool for performance I don t expect performance problems, when you only have a gigabit Ethernet connection there shouldn t be a problem with three ZFS zpools making the network the bottleneck. For this option the way to go would be to start with an array of 15 disks and then buy a second set of 15 disks when the first storage pool becomes full. It seems likely that 4TB disks will become cheap before a 35TiB array is filled so we can get more efficiency by delaying purchases. The BackBlaze pod isn t cheap, they are sold as a complete system without storage disks for $US5,395 by Protocase [4]. That gives a markup of $US3,411 over the BackBlaze cost which isn t too bad given that BackBlaze are quoting the insane bulk discount hardware prices that I could never get. Protocase also offer the case on it s own for anyone who wants to build a system around it. It seems like the better option is to buy the system from Protocase, but that would end up being over $6,000 when Australian import duty is added and probably close to $7,000 when shipping etc is included. Norco Norco offers a case that takes 24 hot-swap SATA/SAS disks and a regular PC motherboard for $US399 [5]. It s similar to the BackBlaze pod but smaller, cheaper, and there s no obvious option to buy a configured and tested system. 24 disks would allow two RAID-Z2 arrays of 12 disks, the first array could provide 27TiB and the second array could provide something bigger when new disks are released. SuperMicro SuperMicro has a range of storage servers that support from 12 to 36 disks [6]. They seem good, but I d have to deal with a reseller to buy them which would involve pain at best and at worst they wouldn t bother getting me a quote because I only want one server at a time. Conclusion Does anyone know of any other options for affordable systems suitable for running ZFS on SATA disks? Preferably ones that don t involve dealing with resellers. At the moment it seems that the best option is to get a Norco case and build my own system as I don t think that any of my clients needs the capacity of a BackBlaze pod at the moment. Supermicro seems good but I d have to deal with a reseller. In my experience the difference between the resellers of such computer systems and used car dealers is that used car dealers are happy to sell one car at a time and that every used car dealer at least knows how to drive. Also if you are an Australian reader of my blog and you want to build such storage servers to sell to my clients in Melbourne then I d be interested to see an offer. But please make sure that any such offer includes a reference to your contributions to the Linux community if you think I won t recognise your name. If you don t contribute then I probably don t want to do business with you. As an aside, I was recently at a camera store helping a client test a new DSLR when one of the store employees started telling me how good ZFS is for storing RAW images. I totally agree that ZFS is the best filesystem for storing large RAW files and this is what I am working on right now. But it s not the sort of advice I expect to receive at a camera store, not even one that caters to professional photographers. Related posts:
  1. Cheap SATA Disks in a Dell PowerEdge T410 A non-profit organisation I support has just bought a Dell...
  2. ZFS vs BTRFS on Cheap Dell Servers I previously wrote about my first experiences with BTRFS [1]....
  3. Flash Storage and Servers In the comments on my post about the Dell PowerEdge...

9 October 2012

David Welton: Fast, Light and Asynchronous

I am a big fan of Ruby on Rails: it does a lot of things, and it does most of them pretty well. When starting a new web project, it's the first thing I would reach for: most of the time, your problem is going to be figuring out a good product/market fit, or whipping up some internal tool without wasting a lot of programmer time. Once you've got a firm grasp of the problem, then maybe you can consider optimizing. Who cares if you do something that no one wants really really fast? However, Ruby on Rails is not beautiful in terms of being particularly fast or lightweight. No complaints from me: most of the time, I'm happy to have something that does so much for me, leaving me to work on the actual problem at hand. Once in a while, though, you do need fast and relatively lightweight, and that space has been getting more interesting over the past few years, at least in terms of the web. First of all, technologies like "Comet", utilizing web sockets or some other always-on connection are becoming more common, where a socket with the server remains open in order to quickly exchange data from the server to the client - and back. That seems to be a poor fit for something like Rails, where it can tie up a lot of resources if one isn't careful. And while computing costs continue to decline, no one minds getting more for less in terms of what their server can do. Furthermore, with frameworks like Backbone.js, pushing more and more code to the client, the server can afford to be a bit simpler and do less, so it may as well be snappy to boot. Java has long been fairly popular for "heavy lifting" types of applications, partially because it does end up being reasonably fast. But it's not something I've ever had much fun using and is usually kind of wordy, and makes you feel like you need a crew of people in Palo Alto, one in Bangalore, and one in Stockholm just to churn out all the code. And it certainly is no lightweight in terms of memory either. So... while it can certainly do pretty much anything you need, I don't see it as being the strongest player when someone needs "real time web" code, and needs it to be reasonably light weight. Ruby, outside of standard Rails stuff like Passenger, seems to offer some interesting possibilities for this kind of work, like Reel but they don't seem to have the traction other solutions do. Python is in a similar situation: the Twisted framework has been around for a while, and while it has some success stories, never seems to have really 'caught fire'. Neither of these languages was built for "concurrency" from the ground up, and that seems to have, to date, inhibited people from using them extensively for this kind of job. My gut feeling is that the need for speed and "concurrency" (or at least handling a lot of concurrent users) will drive adoption of languages heretofore not so popular on the server. Let's have a look at them. Erlang: This is by no means a new language, having been developed in Ericsson in the late 1980ies; and it implements several interesting concepts. First and foremost, concurrency is handled in the form of many small "processes", which are not actually Unix processes at all, but processes internal to the Erlang VM. The Erlang system contains a scheduler that allocates resources to all of these processes, so even if one of them dies or behaves badly, it's not a problem: the system as a whole can continue to function well. The way Erlang is built, the scheduler is preemptive: the internal "processes" don't need to yield to let other processes run. Beyond the scheduler and simple processes, Erlang gives you the tools to create elaborate trees of supervisors and workers that are quite robust to failures in any one portion of the system, as well as giving you the tools to set up a system to run on multiple, distributed computers. This kind of thinking is necessary when you write applications, such as phone switches, where downtime is really, really not ok. Erlang processes comunicate almost exclusively via message passing, meaning that state is not shared. Altogether, this makes for a fast, rock solid system that can easily handle thousands of concurrent connections without breaking a sweat. The computing world being what it is though, Erlang is likely to be more of a Lisp or Smalltalk: it's a trailblazer that did many things years before their time in other languages, but I don't see it as ever quite catching on amongst 'the masses'. It has a wonky syntax, it's a functional programming language, and because it is used in environments where too much experimentation is not good, it does not have a lot of room to break with its own past and innovate in terms of the language itself: it's slow to change and improve, even where the need to is clearly perceived. Node.js: is the opposite, in some ways: being based on Javascript, it draws on a huge number of potential programmers - orders of magnitude more than Erlang. And thanks to design decisions enforcing the use of asynchronous code and callbacks for anything that could block, it deals quite well with concurrent connections, even if the language and libraries don't really give you much in terms of "true" concurrency. This is a simple model that works pretty well, even if, theoretically, all it would take is one "while (1)" loop in a callback to block the entire system. In practice, this doesn't seem to be a big problem, though. More of a problem is writing maintainable code, when everything is a callback. Keeping the network of callbacks straight can be a bit of a chore, and is probably not an optimal model in terms of programmer productivity. That said, people seem to do make due with it, although Node is young enough that we haven't seem projects that are 5 or 6 years old and maintained by people who didn't write them. One of the advantages of being such a popular language is that lots of people have a strong interest in seeing Javascript being very, very performant. That need begat the V8 Javascript engine, from Google, which they were kind enough to release as free software. So one of the advantages that Node has is that the underlying implementation is extremely fast for a dynamic language. For many people who know Javascript, picking up Node.js is also an easy choice, even though people used to browser side programming with Javascript will have to adjust their way of thinking to succesfully tackle server projects. Go language: this is an interesting one, written by some luminaries who work at Google. It can best be described as something akin to C with some updated features, such as garbage collection, that make it more suitable for working on large projects, where things like memory leaks are going to make life very frustrating. It has the feel of a "real language, for real programmers" in that it doesn't stray far too far from what people are used to - it's not going to cause the "what the hell is this?!" reactions that Erlang might in more close-minded circles. Between the big company backing it, and the approachable syntax and concepts, Go looks like it has a good shot at the mainstream. Where it gets interesting is their concurrency model, which is apparently based on something called "communicating sequential processes" which, superficially at least, looks like it has some things in common with Erlang's "actor model" of concurrency. Under the hood, Go apparently hives off its "goroutines" to different OS level threads, but does not have a preemptive scheduler like Erlang: http://code.google.com/p/go/issues/detail?id=543 - although according to this, they may change that in the future. I'm not enough of a computer science guy to comment much on the details of CSP vs Actors, but both seem like valid models with strengths compared to trying to keep threads straight, which always seems to be a source of problems for programmers. Conclusions So, what's actually going to happen? I see Node.js as the clear front runner. It takes a worse-is-better approach that seems to work well enough as people get started. If they encounter difficulties later, they can always rewrite in something else, if needs be, but by "luring people in", Node.js has gathered a large group of users who continue, in turn, to churn out more code for use with the system, making it more attractive to new users. Programming languages are not winner-take-all markets though, so perhaps there is room for a few more languages to have decent followings in this space. Hopefully the competition will lead to ever better tools for those of us utilizing them! What do you think?

Stefano Zacchiroli: bits from the DPL for September 2012

Just posted to d-d-a, bits from the DPL for Septemer 2012.
Heya,
here is the periodic report of DPL activities, this time related to September 2012 (posted here with some delay, as I've been traveling oversea on behalf of Debian for the past few days). Help needed: Google Code-In The Google Code-In (GCI) initiative is about to start again. We don't have a great track record of participating into it, and that's a pity. The initiative revolves around small tasks that other Free Software projects have come to call "easy hacks", showing how effective they're in attracting new volunteers. To participate, we need both mentors and admins. If you're interested see Ana's call for help and please volunteer on the soc-coordination list. Related to this, you've probably seen the report of our participation in GSoC 2012. I'd like to thank all students, mentors, and admins for a very well organized edition. Logo relicensing & other assets The DFSG-relicensing of the Debian logo, which I've mentioned in recent updates, has now happened. The so called Debian "Open Use" logo, in both variants (with and without "Debian") is now dually licensed under LGPL3+ / CC-BY-SA 3.0. The change has been made effective with a resolution of the SPI Board of Directors. Note that the so called "official" logo, which we seem to use very little, is still released under the terms of a non-free license. Discussion is ongoing on -project to stop promoting it. If you're using it or if you've arguments in favor of against that, please participate in the discussion. I've got from SFLC an updated draft of the new proposed trademark policy, implementing most of the changes requested during related August discussions on -project. I'll post it for review there shortly. The Japanese Trademark Office (JPO) has sent us the final confirmation that trademark transfer request (from individuals Debian contributors in the area to SPI) has happened. We've paid the needed fee of 457 CHF to conclude the transaction. We finally settled a domain transfer agreement with the current owner of the debian.eu. Technically, the domain will be transferred to FFIS in the coming weeks. Core teams (non-)news Quite some core teams are in the process of changing their formations these weeks, but most are still pending proper delegation (or equivalent). So here are just a few "teasers": I hope to finalize all the pending tasks above this month. Future events I've spent quite some time to plan my participation in events I'll be attending during October on behalf of Debian, such as the ACM Reflections conference in Urbana-Champaign (at the time of writing, this has already happened), the Ubuntu Developer Summit in Copenhagen, and the LinuxDay event in Turin. Cheers.
PS the day-to-day activity log for September 2012 is available at the usual place master:/srv/leader/news/bits-from-the-DPL.txt.201209

8 October 2012

Luke Faraone: Where I've gone off to

For those of you back at my university, you may have noticed I'm not there this semester.

Google's 2012 FEP team

I spent this past summer at Google, Inc, developing internal tools for the AdSense team, specifically Google Programmable Ads. Being at Google was great; I loved my team and my intern cohort, the rest of the interns in the Freshman Engineering Practicum.

I'm not currently at Google; my internship ended at the beginning of August. Although it was a blast, all good things must come to an end.

I'm not at Mason, either. I was super excited to return to university, and was just about to buy my books and get ready to move in when I got an email from a former coworker at Ksplice, a startup Oracle acquired while I interned there last year. He was starting a new company which would focus on business communications. I'd be working with a bunch of my former coworkers, and based on what I had heard of the company's plans I was confident in their ability to make an awesome product.

Needless to say, when they decided to offer me a position working there full time, I jumped on it.

From an academic point of view, Mason didn't really have much of a mechanism to support this. Co-ops are uncommon there, and not really supported for more than one semester; a full year away had never been done, according to our career services. My department was fully supportive, however, so we managed to find a way to make it work. This involved filling out some oddly-named forms, such as Special Registration for Graduation Request, which the registrar asserted was the right form, trust us on this one.

Myself and Obey Arthur Liu
at a SIPB hackathon
But that's all neither here nor there. I'm now up in Cambridge, MA, working with awesome people (including but not limited to tabbott, wdaher, jesstess, and keegan), and exploring the city. I'm hanging out with MIT SIPB, helping with the maintenance of Sugar Labs' servers in E15 and spending more time working on various open source projects.

To my friends at Mason: I miss you all. I know regardless of how the next year+ turns out, it'll be one one hell of a ride.

Craig Small: NTP control messages

I have had an opportunity to rework some code to query NTP servers directly in python rather than running ntpq -pn and scraping the result. The over-the-wire protocol format is reasonably straight forward and my little module is now passing all of its nosetests which is wonderful. While its only a single table, ntpq actually does multiple requests to get its results. NTP control messages are all mode 6 which tells the client and server its not time sort of things, but more about queries. A control packet has a sequence number which the server responds with so you can line up your requests with responses. For large responses, the more, offset and count fields work together to knit up a large block of data. The first packet of the response will have the offset field of 0. The count is the size of the data payload in bytes. If the response is too big, the more bit will be set to 1 to say there is more coming. The second packet will have an offset that is the same value as the previous packets count value, so you can stitch them together. The first query is a READSTAT which uses opcode 1. This returns a list of 4 byte responses with the association ID taking the first two bytes and the peer status taking the second. If you look at the output of ntpq you will notice a character in the first column which is the peer selection. The important one for us is asterix, which equates to 110 in the lower 3 bits of the first status byte. This is the system peer which is the main one. There may be others, up to 2, (usually symbol +) which are compared to the system peer. ntpq doesn t really care about the different peers and just displays the status but I want to know what peer the server is synchronised to. Next we need more details about the system peer (or all peers in ntpq). To do this a READVAR or opcode 2 is sent to the server. The association ID is set to the association or peer we are interested in. The response for my setup is sent over two packets which need to be reassembled and it is all in plain ascii which is a comma-separated list with a key=value pair. I use the following python line to split it up.
self.assoc_data.update(dict([tuple(ad.strip().split("=")) for ad in data[header_len:].split(",") if ad.find("=") > -1]))
I m sure people that know python better than I will say I am doing it wrong (it looks a bit klunky to me too) but it does work. From that I can query the various values that are returned by the server about its peers, including the source of its clock.

6 October 2012

Matthew Garrett: The importance of trustworthy power structures

Direct harassment and overt sexism are certainly a significant part of why the gender ratios in the Linux community[1] are so skewed, but they're not the whole story. Part of feeling comfortable with a community is the knowledge that those in positions of power can be relied upon to engage in appropriate action when undesirable situations arise - no matter how compelling your code of conduct, no matter how detailed your diversity policy, if someone contravenes them and nothing happens, those documents are worthless and your community is unwelcoming. You can't rely on enforcement unless the community can trust its leadership.

Setting a good example in terms of behaviour is obviously vital, but it's not sufficient. Leaders who engage in sexist behaviour or who harass community members are clearly untrustworthy and undermine any attempts the rest of the community may be making. Failing to step in when they see examples of unacceptable behaviour is as bad. But less obvious is that it's possible to destroy that community trust without clearly contravening those community standards.

An example of this is Todd Akin, a candidate for the upcoming US Senate elections. In August he justified his support for making abortion illegal even in cases of rape, on the basis that women can't become pregnant through being victims of "legitimate rape". Of course, this had little to do with his fiscal or wider social policies, positions that are more directly relevant to most of his potential constituents, and in an election year that's primarily about the economy and healthcare it might be expected that a single issue would have little effect on the election standings. Instead, there was a huge uproar and a previously safe victory has now turned into a real chance of a loss.

Why? A significant part of it is because many people now have difficulty believing that they can trust him to represent them. If he understands women so little that he's willing to make entirely spurious justifications for his positions, how could any woman trust him to consider any other problems they may face? If he's willing to use fake science to back himself up, how could anyone trust him to consider any issue involving science? Through a single statement to a journalist he demonstrated to many that he was unsuited to be their representative in government. Many people who would otherwise have voted for him simply don't feel that they can rely on him to be there for them. Whether he wins his election or not, that distrust is going to remain and it's going to compromise his ability to work with his constituents.

It's the same in technical communities. If a member of a project's technical leadership frequently and loudly expresses their disdain for Python coders, anyone advocating for increased use of Python in that project is unlikely to feel that they can get unbiased opinions from that leader. If the project as a whole is uninterested in adopting Python then that's probably for the best, but if the rest of the project is open to using Python then there's a problem. People working with Python are less likely to join the project, and perhaps the project will lose out as a result.

But it's worth remembering that technical communities are still communities. If a member of a project's technical leadership vociferously argues that slavery benefited minority groups in the long run, members of those minority groups are going to feel that they're not going to be well represented by that leader. If they blog about how homosexuality is a lifestyle choice then homosexuals are unlikely to flock to the project. Likewise, if they downplay the prevalence or impact of rape, women are going to feel marginalised and find something better to do with their time.

It's impossible to separate these things. No matter how technically competent a community leader is, no matter how much code review they perform or how much mentorship they provide, if they're expressing unacceptable social opinions then they're diminishing the community. People I know and respect have left technical communities simply because people in positions of responsibility have engaged in this kind of behaviour without it causing them any problems.

We shouldn't be willing to give people a pass simply because they aren't actually groping anyone or because they're not members of the KKK. Those who drive people away from the community on the basis of race, gender or sexual orientation deserve vocal condemnation, and if they're unwilling to change their behaviour then the community should instead act to drive them away.

We're pretty bad at that in the Linux world at the moment. Too many people have behaved in this way and are left with positions of power or responsibility. There's no easy solution to the problem, but the Ada Initiative is continuing to work to improve awareness and work with communities to reduce the alienation that results from this kind of behaviour. If you want this to be anything other than a straight white male dominated community, you should give them money.

[1] (and computing in general, though to a lesser extent)

comment count unavailable comments

Lars Wirzenius: Obnam 1.2 (backup software)

I've just made release 1.2 of Obnam, my backup program. The NEWS file entry: Bug fixes: This release has been uploaded to my own apt repository on code.liw.fi, for squeeze and unstable. Due to the Debian freeze, I am not uploading this to Debian at this time, though some changes may eventually be uploaded there.

5 October 2012

Keith Packard: fd-passing

FD passing for DRI.Next Using the DMA-BUF interfaces to pass DRI objects between the client and server, as discussed in my previous blog posting on DRI-Next, requires that we successfully pass file descriptors over the X protocol socket. Rumor has it that this has been tried and found to be difficult, and so I decided to do a bit of experimentation to see how this could be made to work within the existing X implementation. (All of the examples shown here are licensed under the GPL, version 2 and are available from git://keithp.com/git/fdpassing) Basics of FD passing The kernel internals that support FD passing are actually quite simple POSIX already require that two processes be able to share the same underlying reference to a file because of the semantics of the fork(2) call. Adding some ability to share arbitrary file descriptors between two processes then is far more about how you ask the kernel than the actual file descriptor sharing operation. In Linux, file descriptors can be passed through local network sockets. The sender constructs a mystic-looking sendmsg(2) call, placing the file descriptor in the control field of that operation. The kernel pulls the file descriptor out of the control field, allocates a file descriptor in the target process which references the same file object and then sticks the file descriptor in a queue for the receiving process to fetch. The receiver then constructs a matching call to recvmsg that provides a place for the kernel to stick the new file descriptor. A helper API for testing I first write a stand-alone program that created a socketpair, forked and then passed an fd from the parent to the child. Once that was working, I decided that some short helper functions would make further testing a whole lot easier. Here s a function that writes some data and an optional file descriptor:
ssize_t
sock_fd_write(int sock, void *buf, ssize_t buflen, int fd)
 
    ssize_t     size;
    struct msghdr   msg;
    struct iovec    iov;
    union  
        struct cmsghdr  cmsghdr;
        char        control[CMSG_SPACE(sizeof (int))];
      cmsgu;
    struct cmsghdr  *cmsg;
    iov.iov_base = buf;
    iov.iov_len = buflen;
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    if (fd != -1)  
        msg.msg_control = cmsgu.control;
        msg.msg_controllen = sizeof(cmsgu.control);
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_len = CMSG_LEN(sizeof (int));
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
        printf ("passing fd %d\n", fd);
        *((int *) CMSG_DATA(cmsg)) = fd;
      else  
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
        printf ("not passing fd\n");
     
    size = sendmsg(sock, &msg, 0);
    if (size < 0)
        perror ("sendmsg");
    return size;
 
And here s the matching receiver function:
ssize_t
sock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd)
 
    ssize_t     size;
    if (fd)  
        struct msghdr   msg;
        struct iovec    iov;
        union  
            struct cmsghdr  cmsghdr;
            char        control[CMSG_SPACE(sizeof (int))];
          cmsgu;
        struct cmsghdr  *cmsg;
        iov.iov_base = buf;
        iov.iov_len = bufsize;
        msg.msg_name = NULL;
        msg.msg_namelen = 0;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = cmsgu.control;
        msg.msg_controllen = sizeof(cmsgu.control);
        size = recvmsg (sock, &msg, 0);
        if (size < 0)  
            perror ("recvmsg");
            exit(1);
         
        cmsg = CMSG_FIRSTHDR(&msg);
        if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int)))  
            if (cmsg->cmsg_level != SOL_SOCKET)  
                fprintf (stderr, "invalid cmsg_level %d\n",
                     cmsg->cmsg_level);
                exit(1);
             
            if (cmsg->cmsg_type != SCM_RIGHTS)  
                fprintf (stderr, "invalid cmsg_type %d\n",
                     cmsg->cmsg_type);
                exit(1);
             
            *fd = *((int *) CMSG_DATA(cmsg));
            printf ("received fd %d\n", *fd);
          else
            *fd = -1;
      else  
        size = read (sock, buf, bufsize);
        if (size < 0)  
            perror("read");
            exit(1);
         
     
    return size;
 
With these two functions, I rewrote the simple example as follows:
void
child(int sock)
 
    int fd;
    char    buf[16];
    ssize_t size;
    sleep(1);
    for (;;)  
        size = sock_fd_read(sock, buf, sizeof(buf), &fd);
        if (size <= 0)
            break;
        printf ("read %d\n", size);
        if (fd != -1)  
            write(fd, "hello, world\n", 13);
            close(fd);
         
     
 
void
parent(int sock)
 
    ssize_t size;
    int i;
    int fd;
    fd = 1;
    size = sock_fd_write(sock, "1", 1, 1);
    printf ("wrote %d\n", size);
 
int
main(int argc, char **argv)
 
    int sv[2];
    int pid;
    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) < 0)  
        perror("socketpair");
        exit(1);
     
    switch ((pid = fork()))  
    case 0:
        close(sv[0]);
        child(sv[1]);
        break;
    case -1:
        perror("fork");
        exit(1);
    default:
        close(sv[1]);
        parent(sv[0]);
        break;
     
    return 0;
 
Experimenting with multiple writes I wanted to know what would happen if multiple writes were made, some with file descriptors and some without. So I changed the simple example parent function to look like:
void
parent(int sock)
 
    ssize_t size;
    int i;
    int fd;
    fd = 1;
    size = sock_fd_write(sock, "1", 1, -1);
    printf ("wrote %d without fd\n", size);
    size = sock_fd_write(sock, "1", 1, 1);
    printf ("wrote %d with fd\n", size);
    size = sock_fd_write(sock, "1", 1, -1);
    printf ("wrote %d without fd\n", size);
 
When run, this demonstrates that the reader gets two bytes in the first read along with a file descriptor followed by one byte in a second read, without a file descriptor. This demonstrates that a file descriptor message forms a barrier within the socket; multiple messages will be merged together, but not past a message containing a file descriptor. Reading without accepting a file descriptor What happens when the reader isn t expecting a file descriptor? Does it just get lost? Does the reader not get the message until it asks for the file descriptor? What about the boundary issue described above? Here s my test case:
void
child(int sock)
 
    int fd;
    char    buf[16];
    ssize_t size;
    sleep(1);
    size = sock_fd_read(sock, buf, sizeof(buf), NULL);
    if (size <= 0)
        return;
    printf ("read %d\n", size);
    size = sock_fd_read(sock, buf, sizeof(buf), &fd);
    if (size <= 0)
        return;
    printf ("read %d\n", size);
    if (fd != -1)  
        write(fd, "hello, world\n", 13);
        close(fd);
     
 
void
parent(int sock)
 
    ssize_t size;
    int i;
    int fd;
    fd = 1;
    size = sock_fd_write(sock, "1", 1, 1);
    printf ("wrote %d without fd\n", size);
    size = sock_fd_write(sock, "1", 1, 2);
    printf ("wrote %d with fd\n", size);
 
This shows that the first passed file descriptor is picked up by the first sockfdread call, but the file descriptor is closed. The second file descriptor passed is picked up by the second sockfdread call. Zero-length writes Can a file descriptor be passed without sending any data?
void
parent(int sock)
 
    ssize_t size;
    int i;
    int fd;
    fd = 1;
    size = sock_fd_write(sock, "1", 1, -1);
    printf ("wrote %d without fd\n", size);
    size = sock_fd_write(sock, NULL, 0, 1);
    printf ("wrote %d with fd\n", size);
    size = sock_fd_write(sock, "1", 1, -1);
    printf ("wrote %d without fd\n", size);
 
And the answer is clearly no the file descriptor is not passed when no data are included in the write. A summary of results
  1. read and recvmsg don t merge data across a file descriptor message boundary.
  2. failing to accept an fd in the receiver results in the fd being closed by the kernel.
  3. a file descriptor must be accompanied by some data.
Make X pass file descriptors I d like to get X to pass a file descriptor without completely rewriting the internals of both the library and the X server. Ideally, without making any changes to the existing code paths for regular request processing at all. On the sending side, this seems pretty straightforward we just need to get the X connection file descriptor and call sendmsg directly, passing the desired file descriptor along. In XCB, this could be done by using the xcbtakesocket interface to temporarily hijack the protocol as Xlib does. It s the receiving side where things are messier. Because a bare read will discard any delivered file descriptor, we must make sure to use recvmsg whenever we want to actually capture the file descriptor. Kludge X server fd receiving Because a passed fd creates a barrier in the bytestream, when the X server reads requests from a client, the read will stop sending data after the message with the file descriptor is consumed. Of course, this process consumes the passed file descriptor, and if that call isn t made with recvmsg set up to receive it, the fd will be lost. As a simple kludge, if we pass a meaningless fd with the X request and then the real fd with a following XNoOperation request, the existing request reading code will get the request, discard the meaningless fd and then stop reading at that point due to the barrier. Once into the request processing code, recvmsg can be called to get the real file descriptor and the associated XNoOperation request. I wrote a test for this that demonstrates how this works:
static void
child(int sock)
 
    uint8_t xreq[1024];
    uint8_t xnop[4];
    uint8_t req;
    int i, reqlen;
    ssize_t size, fdsize;
    int fd = -1, *fdp;
    int j;
    sleep (1);
    for (j = 0;; j++)  
        size = sock_fd_read(sock, xreq, sizeof (xreq), NULL);
        printf ("got %d\n", size);
        if (size == 0)
            break;
        i = 0;
        while (i < size)  
            req = xreq[i];
            reqlen = xreq[i+1];
            i += reqlen;
            switch (req)  
            case 0:
                break;
            case 1:
                if (i != size)  
                    fprintf (stderr, "Got fd req, but not at end of input %d < %d\n",
                         i, size);
                 
                fdsize = sock_fd_read(sock, xnop, sizeof (xnop), &fd);
                if (fd == -1)  
                    fprintf (stderr, "no fd received\n");
                  else  
                    FILE    *f = fdopen (fd, "w");
                    fprintf(f, "hello %d\n", j);
                    fflush(f);
                    fclose(f);
                    close(fd);
                    fd = -1;
                 
                break;
            case 2:
                fprintf (stderr, "Unexpected FD passing req\n");
                break;
             
         
     
 
int
tmp_file(int j)  
    char    name[64];
    sprintf (name, "tmp-file-%d", j);
    return creat(name, 0666);
 
static void
parent(int sock)
 
    uint8_t xreq[32];
    uint8_t xnop[4];
    int i, j;
    int fd;
    for (j = 0; j < 4; j++)  
        /* Write a bunch of regular requests */
        for (i = 0; i < 8; i++)  
            xreq[0] = 0;
            xreq[1] = sizeof (xreq);
            sock_fd_write(sock, xreq, sizeof (xreq), -1);
         
        /* Write our 'pass an fd' request with a 'useless' FD to block the receiver */
        xreq[0] = 1;
        xreq[1] = sizeof(xreq);
        sock_fd_write(sock, xreq, sizeof (xreq), 1);
        /* Pass an fd */
        xnop[0] = 2;
        xnop[1] = sizeof (xnop);
        fd = tmp_file(j);
        sock_fd_write(sock, xnop, sizeof (xnop), fd);
        close(fd);
     
 
Fixing XCB to receive file descriptors Multiple threads may be trying to get replies and events back from the X server at the same time, which means the kludge of having the real fd follow the message will likely lead to the wrong thread getting the file descriptor. Instead, I suspect the best plan will be to fix XCB to internally capture passed file descriptors and save them with the associated reply. Because the file descriptor message will form a barrier in the read stream, xcb can associate any received file descriptor with the last reply in the read data. The X server would then send the reply with an explicit sendmsg call to pass both reply and file descriptor together. Next steps The next thing to do is code up a simple fd passing extension and try to get it working, passing descriptors back and forth to the X server. Once that works, design of the rest of the DRM-Next extension should be pretty straightforward.

2 October 2012

Tim Retout: The Library - a challenge

I visited my local library at the weekend, on a whim. (The weekend before, I'd been to the British Library for the first time, so I guess this inspired me.) The computing sections at public libraries do not tend to inspire me, on the whole. Southampton's is actually relatively good - there are four tall bookcases assigned to computing, although one is introductory IT (Word and Excel), and another seems to be assigned to graphic design (Photoshop). Still, the two in the middle do have some programming texts - you just have to work around "Red Hat Linux 7 for Dummies" and the like. I think the trouble is, computing books become obsolete so quickly; you don't get point releases of Shakespeare every six months. I also suspect the low demand for serious computing texts creates a vicious circle, where the type of people who might want that sort of thing know better than to look in the library for it. It got me thinking - could this be changed? Could I change it?

Andrea Veri: An interview with Allan Day

A few days ago I had the great pleasure to interview Allan Day, GNOME designer and enthusiastic contributor. Me: Hello Allan, mind presenting yourself? Allan: I m a designer working on the GNOME Project. I ve been involved for quite a few years now. Last year I was lucky to be hired by Red Hat to work in their Desktop Team. Me: Can you tell us something more about GNOME 4? Can we alias it GNOME OS? Allan: GNOME 4 isn t something that is being seriously considered right now, at least as far as I m aware. Those of us in the GNOME Project are thinking about the future though, and have been setting some big goals for the next few years. Who knows, maybe those things will lead to a big new version? It s probably too soon to tell though. Me: Which new features will be introduced in the incoming GNOME 3.6, and what about GNOME 3.8? Allan: 3.6 is already out, so you can read the release notes if you want to find out about it. I was really happy with it, and the last release had quite a lot of new features. My personal favourites where the input sources work, the Lock Screen and the work we need on notifications and the Message Tray. Oh, and I m really pleased with the new Clocks application that we released a preview of. Members of the community are still proposing features for 3.8, so it s a little early to say what we will be working on for the next six months. I think I d be happy if we can continue to polish the core user experience, and hopefully get some more new applications off the ground. Me: GNOME Fallback is due to be completely dropped, are you in favor of that choice and why? Allan: I think that s mostly a technical discussion, and I m not a developer. Also, GNOME needs to have an open discussion about that question as a community which is something we might be doing at this year s Boston
Summit. What I would say is that it is important for us to deliver high quality user experiences, so if fallback mode isn t good enough, or if it is holding back the primary GNOME 3 UX, then we obviously need to think about what needs to happen. Me: Ubuntu has recently released the first two Alphas of the Ubuntu GNOME Remix, do you think this will strengthen the cooperation between GNOME and Canonical as in the past? Allan: As far as I understand it, the GNOME Remix is a community effort, and isn t coming from Canonical itself. That said, we always want to see more involvement in GNOME by Canonical and Ubuntu. Me: Do you see anything in the current GNOME 3 that would require an improvement? and can you add a few words about the brand new login screen recently introduced? Allan: GNOME 3 is getting better all the time, and I m particularly pleased with the latest version. That said, there is plenty of work still to do. I think the big area for us right now is to filling the missing blanks in our application story, so we have a suite of consistent core applications. That will enable people to access content more easily, and will serve as a springboard for other new GNOME applications. What to say about the Lock Screen?! Well, it was originally conceived as something that is like a screensaver, but is really really useful (rather than just looking pretty). We wanted something that looks cool when the machine is locked, but we also wanted to add plenty of features on top, like having media playback controls and built-in notifications. The idea is to make some things possible without having to enter a password, like pausing your music or checking to see if you have received any emails. Me: Many have argued new contributors most of the times aren t redirected correctly to their area of interest, thus they lose interest in contributing and leave. Do you feel anything could be improved in how GNOME welcomes new contributors? Allan: That s a good observation. I agree that one of the hardest things about contributing to open source projects is finding the right place to start. In GNOME we are working to help with this, such as through new mentoring schemes, but there is certainly more that we could do. One thing would be to run more online events, like bug days. Another thing is advertising good tasks for newcomers; we do some of that, but we could be better at it. Me: Anything else you would like to add? Allan: Just that anyone is always welcome in GNOME! That s what we re about really creating opportunities for people, having fun and making great technologies.

Andrea Veri: An interview with Allan Day

A few days ago I had the great pleasure to interview Allan Day, GNOME designer and enthusiastic contributor. Me: Hello Allan, mind presenting yourself? Allan: I m a designer working on the GNOME Project. I ve been involved for quite a few years now. Last year I was lucky to be hired by Red Hat to work in their Desktop Team. Me: Can you tell us something more about GNOME 4? Can we alias it GNOME OS? Allan: GNOME 4 isn t something that is being seriously considered right now, at least as far as I m aware. Those of us in the GNOME Project are thinking about the future though, and have been setting some big goals for the next few years. Who knows, maybe those things will lead to a big new version? It s probably too soon to tell though. Me: Which new features will be introduced in the incoming GNOME 3.6, and what about GNOME 3.8? Allan: 3.6 is already out, so you can read the release notes if you want to find out about it. I was really happy with it, and the last release had quite a lot of new features. My personal favourites where the input sources work, the Lock Screen and the work we need on notifications and the Message Tray. Oh, and I m really pleased with the new Clocks application that we released a preview of. Members of the community are still proposing features for 3.8, so it s a little early to say what we will be working on for the next six months. I think I d be happy if we can continue to polish the core user experience, and hopefully get some more new applications off the ground. Me: GNOME Fallback is due to be completely dropped, are you in favor of that choice and why? Allan: I think that s mostly a technical discussion, and I m not a developer. Also, GNOME needs to have an open discussion about that question as a community which is something we might be doing at this year s Boston
Summit. What I would say is that it is important for us to deliver high quality user experiences, so if fallback mode isn t good enough, or if it is holding back the primary GNOME 3 UX, then we obviously need to think about what needs to happen. Me: Ubuntu has recently released the first two Alphas of the Ubuntu GNOME Remix, do you think this will strengthen the cooperation between GNOME and Canonical as in the past? Allan: As far as I understand it, the GNOME Remix is a community effort, and isn t coming from Canonical itself. That said, we always want to see more involvement in GNOME by Canonical and Ubuntu. Me: Do you see anything in the current GNOME 3 that would require an improvement? and can you add a few words about the brand new login screen recently introduced? Allan: GNOME 3 is getting better all the time, and I m particularly pleased with the latest version. That said, there is plenty of work still to do. I think the big area for us right now is to filling the missing blanks in our application story, so we have a suite of consistent core applications. That will enable people to access content more easily, and will serve as a springboard for other new GNOME applications. What to say about the Lock Screen?! Well, it was originally conceived as something that is like a screensaver, but is really really useful (rather than just looking pretty). We wanted something that looks cool when the machine is locked, but we also wanted to add plenty of features on top, like having media playback controls and built-in notifications. The idea is to make some things possible without having to enter a password, like pausing your music or checking to see if you have received any emails. Me: Many have argued new contributors most of the times aren t redirected correctly to their area of interest, thus they lose interest in contributing and leave. Do you feel anything could be improved in how GNOME welcomes new contributors? Allan: That s a good observation. I agree that one of the hardest things about contributing to open source projects is finding the right place to start. In GNOME we are working to help with this, such as through new mentoring schemes, but there is certainly more that we could do. One thing would be to run more online events, like bug days. Another thing is advertising good tasks for newcomers; we do some of that, but we could be better at it. Me: Anything else you would like to add? Allan: Just that anyone is always welcome in GNOME! That s what we re about really creating opportunities for people, having fun and making great technologies.

1 October 2012

Craig Small: Anti-Spam Fails

A day or two ago I tried sending an email to a friend who happens to use the Road Runner ISP for his mail service. Now this ISP doesn t like dynamic IP addresses (using the increasing inaccurately named Dial Up List) so I have to punt the email through my ISP s mailserver first. Now that server is telling me this:
The reason for the problem: 4.3.2 Not accepting messages at this time 554- 5.7.1 ERROR: Mail refused <150.101.137.131> See http://sendersupport.senderscore.net
So their ISP mailserver is refusing connections from my ISP s mailserver for some reason, probably on some spam list. There s a URL to look up the problem, so going there gives you three things:
  1. A redirection to https://sendersupport.senderscore.net/
  2. A badly configured webserver that uses the above URL with a certificate for www.senderscore.net
  3. A page that says It works
Either Road Runner or Senderscore, preferably both, need to get a clue. Oh and going to https://www.senderscore.net/ gives connection refused. A bit of digging around shows the correct URL is https://senderscore.org/ Now I just realized that my SSL certificate for https://enc.com.au/ expired on the weekend so I know these things can happen, but I m one person (who was away for a while), why can t companies get their act together?

Craig Small: Anti-Spam Fails

A day or two ago I tried sending an email to a friend who happens to use the Road Runner ISP for his mail service. Now this ISP doesn t like dynamic IP addresses (using the increasing inaccurately named Dial Up List) so I have to punt the email through my ISP s mailserver first. Now that server is telling me this:
The reason for the problem: 4.3.2 Not accepting messages at this time 554- 5.7.1 ERROR: Mail refused <150.101.137.131> See http://sendersupport.senderscore.net
So their ISP mailserver is refusing connections from my ISP s mailserver for some reason, probably on some spam list. There s a URL to look up the problem, so going there gives you three things:
  1. A redirection to https://sendersupport.senderscore.net/
  2. A badly configured webserver that uses the above URL with a certificate for www.senderscore.net
  3. A page that says It works
Either Road Runner or Senderscore, preferably both, need to get a clue. Oh and going to https://www.senderscore.net/ gives connection refused. A bit of digging around shows the correct URL is https://senderscore.org/ Now I just realized that my SSL certificate for https://enc.com.au/ expired on the weekend so I know these things can happen, but I m one person (who was away for a while), why can t companies get their act together?

Andrew Pollock: [opinion] On helicopter parenting and strangers in day care facilities

It appears that a recent incident at a different campus of the "preschool" (I call it day care) that Zoe goes to has gotten the attention of the Free-Range Kids blog. Firstly, I need to say that on the parenting spectrum, I definitely self-identify closer to the free-range end than the helicopter end. I'm not sure that I'd let an 8 year old ride the New York subway on their own, but Zoe's not 8 yet, so I really can't say. Sarah and I received the same email that is reprinted on the blog, on Friday night, and we were both (very) mildly alarmed at the situation, but not particularly concerned, mostly because it wasn't the facility that Zoe goes to. I'm not sure I'd be that much more concerned if it was, to be honest. I did like the statistics that the parent quoted in response. I thought that that put things into perspective, but didn't really take abductions by estranged parents into consideration. My one reaction to reading the email was, "why did they wait until after the incident to escalate it?" but then, from my own experiences in dropping off or picking up Zoe, I could totally understand not all the staff knowing on sight all the parents or guardians that do pickups and drop offs. This does lead to one asking how they know who to buzz in, but that's another can of worms. Anyway, I read the 50 or so varyingly indignant comments on the Free Range Kids blog, and since they were talking about the company that I give a not inconsequential amount of money to, I feel the need to write a response. The whole episode raises the question: who was this person and what were they doing there? Some of the commentators hypothesize that they were casing the joint for a future incident, or just giving themselves an impromptu tour before placing their child there (Zoe and I toured before we signed up, but that was an official, prearranged thing). It really is unfortunate that the staff didn't challenge this person, but as I said, they probably all had to review the video surveillance footage together to ascertain that none of them knew who the person was. I consider this a bit of a deficiency itself, but I don't really expect them to all have photographic memory, especially if one parent mostly does drop off and pick up. The other (expensive) option would be to issue each authorized person with an electronically revocable proximity card, so they can let themselves in, but I feel that that's taking things to the extreme. They staff all carry portable radios. If they don't have a discreet "code" they can call when one of them sees a person they don't know, I'm sure they will have after this incident. I personally found the majority of the comments on the Free Range Kids blog to be on the extreme overreaction side of things. As much as I'm a believer in Free Range parenting, I think the day care provider has mostly reacted appropriately. Do I agree with their "locked facility" policy? It's my first experience with a commercial day care facility, so I don't have anything to compare it with. As I said earlier, I can totally understand where they're coming from in terms of limiting their liability. Previously, Zoe was in a "home day care" facility, without any locks, and I for one wasn't constantly worrying about someone wandering into that provider's home and abducting my daughter, so I guess the whole "locked facility" thing is on the more extreme end of the scale for me in the first place, but like I said, I'm uncalibrated for commercial day care centres. I'd certainly like to see the primary school environment that Zoe goes to not be such a locked down affair.

Vasudev Kamath: Weekly Log - 01102012

Well this weeks log comes bit late as my week got extended till today ;-). I had working day at office on Saturday and Sunday due to 2nd Quarter end and instead today is declared as compensatory holiday and tomorrow any how is Gandhi Jayanti. So here it goes. Debian Related Most of my work this week was done for Debian-IN team Well most of this weeks work involved KGB ;-) Personal Works Misc Played Cricket after very long time (Guess after 10 long years). Well it was not official match or anything it was just another Gully Cricket. After the match it came to mind that I need regular physical workout :-P. Well that's it Cya till next week :-)

Jonas Smedegaard: How I (don't) use Facebook

Dear Facebook friend, I like you and I want to chat with you, just not on Facebook! My Facebook account is there to reach you where you are, but I do not hang out there. Please join me at Free and Open spaces instead - via email, IRC or Jabber

Good old email If you cannot be bothered with change, then simply email me! My email address is dr@jones.dk like always :-)

Simple webchat If you are in a hurry and do not use Jabber yet, then try use my Simple Groupchat. Use guest login if you are not a user at jones.dk.

Proper Jabber Jabber is similar to email: You need 1) an account somewhere, 2) some client application setup to use that account, and 3) the address of those you want to connect.
  1. Register an account at e.g. Indonesian http://jabin.org/ or some other server.
  2. Install a Jabber client program :
    • on Windows try install Gajim from http://gajim.org/.
    • on smartphone try app from https://imo.im/.
    • on Ubuntu try use the Me menu in top right corner.
    • on Debian try install Pidgin: aptitude install pidgin.
  3. Invite me as your friend/buddy: my Jabber ID is jonas@jones.dk
  4. Tell your friends to do the same! :-D

Geeky IRC Many computer geeks hang out on IRC. I find it ugly and clumsy to use, but most of my techie friends are there, so I recommend going there to discuss technical matters. On OFTC my nickname is jonas, and I often hang out at the chatroom #debian-devel (plus a few others).

Why not Facebook? Facebook is a closed system: all activities happen at one central place. Email, Jabber and IRC are open protocols, exchanging between many Free systems (and some non-free ones as well).
Imagine having an overprotecting mother, who allow you only to meet your friends at one spot in town - where she can look after you. You maybe have no secrets from your mom, but probably still appreciate the option of being alone - to have some privacy.
Facebook is that one spot in town. Jabber is "let's go meet somewhere". Regards, Jonas

Jonas Smedegaard: Building a remote-control for real cars

SMS is used to lock car doors Copenhagen Carpool soon receive a new batch of electric cars. The new cars will contain a cellphone tied to the door locks, to only let into the car the member who booked its current timeslot. I am setting up the system to connect the cars with their booking calendar. The general idea is to
  1. Connect a standard cellphone to a computer.
  2. Forward sms messages received on the phone to the calendar.
  3. Send messages from the calendar through the phone.
  4. Leave the system in a corner, turned on 24/7.
Most of my work is in trying to avoid ways things might go wrong which so often happens when computers are involved. What if
  • messages are delayed or lost?
  • a chain of messages arrive out of order?
  • messages are sent faster than they can be delivered?

Reliable conversation Human conversation is most reliable when using plain speak. Slang, sarcasm or jokes raise the risk of misunderstandings. This is quite similar in computer conversation. When surfing the Web, you normally "GET" a web page or "POST" new data like a search query. The words "GET" and "POST" are "plain speak" of the World Wide Web defined as a principle called "REST" or "RESTful design". I use the Kannel tool to talk directly to the phones. When an sms arrives on the phone, Kannel "GET"s it to the calendar. That's weakly expressed better if it had "POST"ed the message instead. Kannel is a quite reliable tool, but not RESTful in conversations. That requires extra attention at other parts of the setup to avoid breakage in special situations. That worries me.

Each car has a blog So I setup a gateway from Kannel to RESTful conversation. And choose classic blogging as style of conversation:
  • The carpool fleet is a blogroll
  • each car has a blog
  • each sms emitted from a car is a blog entry
Blogging comes in two flavors, RSS and Atom. Both cover distribution of messages. I use Atom because it is newest and coolest, and because it also covers creating and editing meesages with the AtomPub extension. AtomPub allows the calendar to create an empty message which then triggers an sms from the car which "fills it in." AtomPub also let the calendar "PUT" tags onto existing messages, to mark them as processed, read etc., and let an admin or a cleanup script "DELETE" outdated entries or blogs. The words "PUT" and "DELETE" are RESTful conversation as well.

The system is dancing! My sms-to-blog gateway is written in Perl, using the Dancer toolkit. Dancer makes it simple to setup a RESTful web conversation, and when I contacted the authors on IRC, they swiftly added support for the non-RESTful quirk that I needed. My sms-to-blog gateway is not yet ready, but basic routines work. The project is public, and code is Free Software.

29 September 2012

Paul Tagliamonte: OLF (Ohio LinuxFest) 2012

Heyya, World! I ve just got to OLF, and I m looking forward to another weekend packed full of great talks, awesome friends and late-night hacking. At some point on Saturday, I ll try to organize a Debian BSP with anyone else who s interested. If you re here, feel free to email me / say hi!

28 September 2012

Keith Packard: DRI-Next

Thoughts about DRI.Next On the way to the X Developer s Conference in Nuremberg, Eric and I chatted about how the DRI2 extension wasn t really doing what we wanted. We came up with some fairly rough ideas and even held an informal presentation about it. We didn t have slides that day, having come up with the content for the presentation in the hours just before the conference started. This article is my attempt to capture both that discussion and further conversations held over roast pork dinners that week. A brief overview of DRI2 Here s a list of the three things that DRI2 currently offers. Application authentication. The current kernel DRM authentication mechanism restricts access to the GPU to applications connected to the DRM master. DRI2 implements this by having the application request the DRM cookie from the X server which can then be passed to the kernel to gain access to the device. This is fairly important because once given access to the GPU, an application can access any flink d global buffers in the system. Given that the application sends screen data to the X server using flink d buffers, that means all screen data is visible to any GPU-accessing application. This bypasses any GPU hardware access controls. Allocating buffers. DRI2 defines a set of attachment points for buffers which can be associated with an X drawable. An application needing a specific set of buffers for a particular rendering operation makes a request of the X server which allocates the buffers and passes back their flink names. The server automatically allocates new buffers when window sizes change, sending an event to the application so that it knows to request the new buffers at some point in the future. Presenting data to the user. The original DRI2 protocol defined only the DRI2CopyRegion request which copied data between the allocated buffers. SwapBuffers was implemented by simply copy data from the back buffer to the front buffer. This didn t provide any explicit control over frame synchronization, so a new request, DRI2SwapBuffers, was added to expose controls for that. This new request only deals with the front and back buffers, and either copies from back to front or exchanges those two buffers. Along with DRI2SwapBuffers, there are new requests that wait for various frame counters and expose those to GL applications through the OMLsynccontrol extension What s wrong with DRI2? DRI2 fixed a lot of the problems present with the original DRI extension, and made reliable 3D graphics on the Linux desktop possible. However, in the four years since it was designed, we ve learned a lot, and the graphics environment has become more complex. Here s a short list of some DRI2 issues that we d like to see fixed. Proposed changes for DRI.Next Given the three basic DRI2 operations (authentication, allocation, presentation), how can those be improved? Eliminate DRI/DRM magic-cookie based authentication Kristian H gsberg, Martin Peres, Timoth e Ravier & Daniel Vetter gave a talk on DRM2 authentication at XDC this year that outlined the problems with the current DRM access control model and proposed some fairly simple solutions, including using separate device nodes one for access to the GPU execution environment and a separate, more tightly controlled one, for access to the display engine. Combining that with the elimination of flink for communicating data between applications and there isn t a need for the current magic-cookie based authentication mechanism; simple file permissions should suffice to control access to the GPU. Of course, this ignores the whole memory protection issue when running on a GPU that doesn t provide access control, but we already have that problem today, and this doesn t change that, other than to eliminate the global uncontrolled flink namespace. Allocate all buffers in the application DRI2 does buffer allocation in the X server. This ensures that that multiple (presumably cooperating) applications drawing to the same window will see the same buffers, as is required by the GLX extension. We suspected that this wasn t all that necessary, and it turns out to have been broken several years ago. This is the traditional way in X to phase out undesirable code, and provides an excellent opportunity to revisit the original design. Doing buffer allocations within the client has several benefits: Present buffers through DMA-buf The new DMA-buf infrastructure provides a cross-driver/cross-process mechanism for sharing blobs of data. DMA-buf provides a way to take a chunk of memory used by one driver and pass it to another. It also allows applications to create file descriptors that reference these objects. For our purposes, it s the file descriptor which is immediately useful. This provides a reliable and secure way to pass a reference from an underlying graphics buffer from the client to the X server by sending the file descriptor over the local X socket. An additional benefit is that we get automatic integration of data from other devices in the system, like video decoders or non-primary GPUs. The Prime support added in DRI version 2.8 hacks around this by sticking a driver identifier in the driverType value. Once the buffer is available to the X server, we can create a request much like the current DRI2SwapBuffers request, except instead of implicitly naming the back and front buffers, we can pass an arbitrary buffer and have those contents copied or swapped to the drawable. We also need a way to copy a region into the drawable. I don t know if that needs the same level of swap control, but it seems like it would be nice. Perhaps the new SwapBuffers request could take a region and offset as well, copying data when swapping isn t possible. Managing buffer allocations One trivial way to use this new buffer allocation mechanism would be to have applications allocate a buffer, pass it to the X server and then simply drop their reference to it. The X server would keep a reference until the buffer was no longer in use, at which point the buffer memory would be reclaimed. However, this would eliminate a key optimization in current drivers the ability to re-use buffers instead of freeing and allocating new ones. Re-using buffers takes advantage of the work necessary to setup the buffer, including constructing page tables, allocating GPU memory space and flushing caches. Notifying the application of idle buffers Once the X server is finished using a buffer, it needs to notify the application so that the buffer can be re-used. We could send these notifications in X events, but that ends up in the twisty mess of X client event handling which has already caused so much pain with Invalidate events. The obvious alternative is to send them back in a reply. That nicely controls where the data are delivered, but causes the application to block waiting for the X server to send the reply. Fortunately, applications already want to block when swapping buffers so that they get throttled to the swap buffers rate. That is currently done by having them wait for the DRI2SwapBuffers reply. This provides a nice place to stick the idle buffer data. We can simply list buffers which have become idle since the last SwapBuffers reply was delivered. Releasing buffer memory Applications which update only infrequently end up with a back buffer allocated after their last frame which can t be freed by the system. The fix for this is to mark the buffer purgable, but that can only be done after all users of the buffer are finished with it. With this new buffer management model, the application effectively passes ownership of its buffers to the X server, and the X server knows when all use of the buffer are finished. It could mark buffers as purgable at that point. When the buffer was sent back in the SwapBuffers reply, the application would be able to ask the kernel to mark it un-purgable again. A new extension? Or just a new DRI2 version? If we eliminate the authentication model and replace the buffer allocation and presentation interfaces, what of the existing DRI2 protocol remains useful? The only remaining bits are the other synchronization requests: DRI2GetMSC, DRI2WaitMSC, DRI2WaitSBC and DRI2SwapInterval. Given this, does it make more sense to leave DRI2 as it is and plan on deprecating, and eventually eliminating, it? Doing so would place a support burden on existing applications, as they d need to have code to use the right extension for the common requests. They ll already need to support two separate buffer management versions though, so perhaps this burden isn t that onerous?

Joachim Breitner: The might applicative left fold

Just about three years ago, I created the automatic rule-based time tracker (arbtt), a tool that quietly runs in the background, records your current windows and their titles, and allows you to later process this data using, well, rules. By now, I have almost half a million records, spanning 317 days of me working at the computer. Processing this amount of data has become very memory-hungry: It takes 1G of RAM to process my data. Other users, with a presumably higher sampling rate, report even worse performance, which finally made me approach the problem again. Naturally, one wonders why it is such a memory hog, after all it takes just one run over the data to produce a report. The data itself is a lazy list so the garbage collector should the be able to drop the seen elements immediately. But arbtt is able to print several reports in one run; there is even an option (--each-category) that creates a number of reports based on the data itself. The code was structured that first a number of values that are possibly used by several reports are first created one and then re-used by the reports. And then there is the issue of the filters: The user specifies a what predicates are interesting (e.g., those where he was active) and some reports need to know not only which samples were matched, but also distinguish the consecutive runs of selected samples. Lots of reasons that made it hard to not use the list of of samples several times, which causes it to be completely retained in memory. The idea of completely rewriting everything in a much more imperative way was not appealing. But luckily Haskell s good abstraction possibilities can help here. What is the correct way to traverse a lazy list and calculate some information about it? It is a strict left fold, i.e. an algorithm that can be represented as arguments to
foldl' :: (s -> x -> s) -> s -> [x] -> s
For those who are new to folds: The first argument is a function that processes one element from the list, returning the new state of the processing. The second argument is the initial state. And foldl' can apply such an algorithm to a list to return a final state. So obviously I had to express my reports as left folds. To think clearer about it, I gave them a name. I also added a finishing step to the mix, which is handy:
data LeftFold x a = forall s. LeftFold  
  start :: s,
  process :: s -> x -> s,
  finish :: s -> a
   
A value of type LeftFold x a is then an algorithm that traverses a list of xes and returns something of type a. The forall s. means that the user of such a processor must not make any assumptions about the type of the state. I also have a function that runs such a list processor, simply by invoking foldl' with the arguments stored in the LeftFold constructor:
runLeftFold :: LeftFold x a -> [x] -> a
runLeftFold (LeftFold st1 p1 f1) xs = f1 (foldl' p1 st1 xs)
Now, as a Haskell programmer, I am searching for monads everywhere, and it really would have been nice if this were a monad, as they are very easy to compose. But unfortunately, they do not form a monad. If they did then I could decide after running one processor and looking at the result how I would want to process the list now, but this obviously contradicts with the desire to traverse the list only once. But there is the monad s smaller ugly sibling, the applicative functor. One can still somewhat nicely compose them to form more complex algorithms, just with more restrictions. Here is my instance:
instance Functor (LeftFold x) where
  fmap f (LeftFold st1 p1 f2) = LeftFold st1 p1 (f . f2)
instance Applicative (LeftFold x) where
  pure x = LeftFold () const (const x)
  LeftFold st1 p1 f1 <*> LeftFold st2 p2 f2 = LeftFold  
  start  =  st1 :!: st2,
  process = \(s1 :!: s2) x -> p1 s1 x :!: p2 s2 x,
  finish  = \(s1 :!: s2)  -> f1 s1 (f2 s2)
   
The :!: operator is a strict tuple constructor. This is important, as otherwise the fold would be come a lazy one, I would be building up huge numbers of thunks and performance would be very bad. For the same reason every list processor should make sure that its state does not build thunks once it is in weak head normal form. Now I am at a abstraction level that I feel comfortable working in, by writing functions that combine the list processors in various ways. Probably the most important one for me is already present in the libraries (here with a specialized type):
sequenceA :: [LeftFold x a] -> LeftFold x [a]
This is the whole trick: Now I can, based on the user input, run any number and selection of reports in one single list traversal. I find it very elegant that under the hood , the strict tuples are nested at precisely the right depth depending on the length of the list. As hinted at before, I do some interesting stuff that was previously represented as lists of lists of values. Expressing these as left folds was a bit tricky, but again, the complexity is contained in the combinators that I wrote (although it still gets confusing, check out processIntervalReport in Stats.hs):
monoidFold :: Monoid m => LeftFold m m
mapElems :: LeftFold y a -> (x -> y) -> LeftFold x a 
filterWith :: (x -> Bool) -> LeftFold (Bool :!: x) a -> LeftFold x a
onSelected :: LeftFold x a -> LeftFold (Bool :!: x) a
onJusts :: LeftFold x a -> LeftFold (Maybe x) a
onAll :: LeftFold x a -> LeftFold (Bool :!: x) a
runOnGroups :: (x -> x -> Bool) -> LeftFold x y -> LeftFold y z -> LeftFold x z
runOnIntervals :: LeftFold x y -> LeftFold y z -> LeftFold (Bool :!: x) z
lfLength :: LeftFold x Int
lfFirst :: LeftFold x (Maybe x)
lfLast :: LeftFold x (Maybe x)
toList :: LeftFold x [x]
concatFold :: LeftFold [x] [x]
As a result, the program now only requires 10MB and runs 18% faster. If you wonder why, in the definition of runLeftFold, I do not apply the finish function strictly: That is intentional; I am actually passing the result of a processor that calculates some often required data (e.g. total time recorded) as an argument to all the list processors. (Near the end of the main function in stats-main.hs) This loop works fine as long as I am using these only in the finish functions.
There is one downside to this approach: I cannot easily calculate stuff on demand and share it between two reports. Previously, I could just bind this to a variable, pass it to all reports, only if at least one is interested it would be evaluated and if several are interested, the result would be shared. I do not have a good solution for this yet. The code above is in the self-contained module LeftFold.hs in the arbtt sources.
Several People have had this idea before, here is one blog post by Max Rabkin.
Flattr this post

Next.

Previous.