Ever since I started using my current laptop (a ThinkPad E14 Gen 4,
currently running Debian 12), I have had the following issue: when I
connect headphones to the laptop, the audio goes to the headphones as
expected, but when I disconnect the headphones, the audio goes to the
HDMI output instead of going back to the laptop speakers. As it happens,
my external monitor (an Eizo FlexScan EV2360) has audio output, but it’s
pretty low-quality and I don’t use it. But PulseAudio (or is it ALSA?)
assigns higher priority to the HDMI outputs, so as soon as the
headphones are disconnected, it looks for the available device with the
highest priority and picks the HDMI one. You can see the priority of
each audio sink (output) by using pactl
:
$ pactl list sinks | grep priority: [Out] HDMI3: HDMI / DisplayPort 3 Output (type: HDMI, priority: 700, not available) [Out] HDMI2: HDMI / DisplayPort 2 Output (type: HDMI, priority: 600, not available) [Out] HDMI1: HDMI / DisplayPort 1 Output (type: HDMI, priority: 500, available) [Out] Speaker: Speaker (type: Speaker, priority: 100, availability unknown) [Out] Headphones: Headphones (type: Headphones, priority: 200, not available)
In this case, the HDMI1 output is available and has priority 500, whereas the speakers have priority 100.
The solution is to change the HDMI priorities. The problem is
where to set this. In my particular case, this was set in
/usr/share/alsa/ucm2/Intel/sof-hda-dsp/Hdmi.conf
(included
from /usr/share/alsa/ucm2/Intel/sof-hda-dsp/Hdmi.conf
),
which looks like this:
# Use case Configuration for sof-hda-dsp Include.hdmi.File "/codecs/hda/hdmi.conf" If.hdmi1 { Condition { Type AlwaysTrue } True.Macro.hdmi1.HDMI { Number 1 Device 3 Priority 500 } } If.hdmi2 { Condition { Type AlwaysTrue } True.Macro.hdmi1.HDMI { Number 2 Device 4 Priority 600 } } If.hdmi3 { Condition { Type AlwaysTrue } True.Macro.hdmi1.HDMI { Number 3 Device 5 Priority 700 } }
I just changed the values 500, 600, 700 manually to 50, 60, 70 in
this file. This is not a very good solution because this file belongs to
the alsa-ucm-conf
package and will get overridden whenever
I upgrade it, but since this is Debian stable, I don’t have to worry
about this any time soon. There is probably a better way to override
these values, but I don’t know enough about either ALSA or PulseAudio
(and I’m not particularly keen on learning more, unless my fellow
readers know and want to leave a helpful comment), so this will have to
do for now.
* * *
Another recurring issue is getting Bluetooth headphones to become the
selected default device when they are connected. It seems that Bluetooth
devices get created dynamically with a
bunch of hardcoded priorities (and worse, sometimes I get a device
with priority 40
and sometimes 0
, I don’t know
why). But it also seems that the priorities just don’t have any effect
on the selection of the Bluetooth device. I was having a curious issue
where some programs would pick the headphones and some wouldn’t, and the
default device would remain unchanged (which among other things meant that
my multimedia keys set the volume of the wrong device). What seems to be going on is that
PulseAudio remembered the associations of certain programs (e.g., VLC)
with the headphones, but only for those programs where I had at some
point manually changed the output sink manually via
pavucontrol
. The solution here was two-step:
In /etc/pulse/default.pa
, replace the line that
says:
load-module module-stream-restore
with:
load-module module-stream-restore restore_device=false
This will make PulseAudio not try to remember associations between specific programs and devices. From now on, all programs get the default sources/sinks when they connect to PulseAudio.
Set the default sink manually to the Bluetooth headphones. Use
pactl list sinks
to figure out the sink name:
$ pactl list sinks | grep Name: Name: alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink Name: alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink Name: alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink Name: alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink Name: bluez_sink.C8_7B_23_9F_B3_21.a2dp_sink
Then set it (replacing with the appropriate device name):
pactl set-default-sink bluez_sink.C8_7B_23_9F_B3_21.a2dp_sink
The result of this is that PulseAudio will remember the headphones as the default sink device when they are present, but will revert to the built-in sound card when not.
I still don’t know why this works even though the Bluetooth device’s
priority is lower than the built-in sound card. (There is a PulseAudio
module called module-switch-on-connect
that provides
behavior like this, but it is not enabled on my system, and it does not
show up as loaded in the pactl list
output.) But It Works
For Me™.
A couple of days ago, I decided to give Wayland a go. For those of you who live under a rock, Wayland is meant to be the successor of X11, the traditional graphical server/protocol in the GNU/Linux world, responsible for things such as drawing windows on your screen, passing keyboard and mouse events to the correct programs, etc. (I live under a rock too, but sometimes I stretch my head out to see what is going on in the world, only to crawl back not long after.)
Like with most technology transitions, there is a lot of drama going around Wayland vs. X11 and their respective merits and demerits. Reading such discussions can be quite frustrating; not only people can have widely different usage and requirements from graphics functionality – gaming (with different kinds of games), watching videos with varying resolutions and refresh rates, different graphics cards, accessibility settings, desktop environments, etc. –, but people can also differ in how they perceive little functionality changes just because of variation in how their eyes or brains work. A relatively minor glitch (such as screen tearing while playing a video, a couple milliseconds extra delay to process a keystroke in a game, or a font that renders slightly differently) can be a huge annoyance to one person, barely noticeable to another, and literally invisible to a third one. The result is that such discussions feel like people are talking past one another, unable to understand why others would make a different choice from them and insist on being wrong on the internet. People in the GNU/Linux world are also used to enjoying immense freedom to choose, customize and build their own desktop environments, which also contributes to the wide variety of experiences and difficulties in switching from one graphical stack to another.
If you want to understand why Wayland exists, you can watch The real story behind Wayland and X, a Linux.conf.au presentation by Daniel Stone, a Wayland and former X.org developer. Basically, X.org contains a huge number of features that are not used by modern clients but have to be kept around for compatibility, and limit the ways in which problems with X can be solved. Originally, the X server used to be responsible for font rendering, drawing graphical primitives, and a variety of other functions that nowadays are done by the clients themselves; modern clients usually just want to send a fully rendered image for the server to display. All the old cruft accumulated across the four decades of X11’s existence make it hard to maintain for developers.
One thing that is noticeable in these discussions about X11 vs Wayland is that one hears a lot from X11 users defending X11, Wayland users defending Wayland, Wayland developers defending Wayland, but not much from X11 developers. The main reason for this is that X11 developers are Wayland developers by and large. The X.org server is pretty much in maintenance mode, and much if not most of development that still goes on in the xserver repo is related to Xwayland, the compatibility layer that allows X11 clients to run on Wayland. As much as we may like X.org, if developers don’t want to work on it, there’s not much we can do about it (and it seems that it’s pretty hard for new developers to get started on it, due to the accumulated complexity). Granted, X.org isn’t going away any time soon, but it’s also not going anywhere. Regardless of the technical merits of Wayland vs. X11, it seems pretty clear that Wayland is the future going forward.
So far I have stayed in the comfort of my old X11 setup, mainly because I had no reason to put an effort into switching. A reason finally showed up, though: on my current laptop (a ThinkPad E14 4th generation), I see quite a bit more tearing while watching videos than on my previous PCs. Although it is within the range of what I can live with (after all I’ve been using this computer for almost a year like this), all else being equal, it’s something I would like to get rid of.
The first step into switching to Wayland is picking a compositor: the application responsible for managing windows and drawing on the screen. On X11, the window manager and the X server are two different programs; on Wayland, both of these roles are taken by the compositor. The idea here is to cut out the middleman since (1) nowadays the graphics card driver lives in the kernel, which exposes it as a framebuffer device, unlike in the olden days where you would have different X drivers to handle different graphics cards, and (2) most modern window managers do compositing anyway, so instead of having the window manager composite the image of the whole desktop, then give it to X to draw it on the screen, the compositor can write it directly to the graphics card.
This means that there are effectively as many Wayland servers as
there are window managers out there. This is annoying because the
compositor is not only responsible for managing windows, but also
handling input devices, keyboard layouts, accessibility features,
clipboard, and a variety of other things that were traditionally handled
by the X server. Each compositor has to implement these features on its
own, and although there are common libraries that are used by different
compositors to implement some of these features (e.g.,
libinput
), there is often no standard way to access those
features that is portable across different compositors. For
instance:
There is no standard way to change the keyboard layout in
Wayland, the way you can with xkbcomp
or
setxkbmap
in X. In Sway
(the compositor I picked, a Wayland port of i3),
one can use
swaymsg input type:keyboard xkb_file path/to/keymap.xkb
(among other xkb_*
options) to load a new keymap; other
compositors may have other commands.
There is no standard way to control screen resolution and
position (i.e., xrandr
). There is wlr-randr
for wlroots-based compositors (from
reddit), but other compositors use different things.
There is no standard way to get a list of all open windows and
switch focus to one (i.e., wmctrl
). I have a script bound
to Super+g to present a list of windows for selection with
dmenu
and jump to one of them, which will require
adaptation. In Sway, one can use swaymsg -t get_tree
(which
returns a nested tree that requires quite
a bit of contortion to turn into a flat list, at least from a shell
script); other compositors may have other solutions.
Some of these features may end up being standardized as protocol extensions (see wlr-protocols and wayland-protocols), but which protocols will be supported by each compositor will vary. This feels like the situation in Scheme with its various SRFIs that different implementations may or may not support, or XMPP where support for a feature depends on the client and server supporting the desired set of extensions. I suppose the situation will improve in the upcoming years as the set of protocol extensions gets more standardized, but the current situation is this. The thing is that this is a non-issue in X: new window managers don’t need to care about any of this, because the X server handles these the same way regardless of what is your window manager.
As soon as I open the Sway session and start up lxterminal, I notice
an issue: lxterminal on Wayland is not honoring my
FREETYPE_PROPERTIES=
'truetype:interpreter-version=35'
environment variable. This setting changes the font rendering algorithm
such that fonts look crispier, especially in non-HiDPI displays. This is
well within the “some people won’t even notice” category, but for me the
difference is noticeable (particularly in my external display), it took
me ages to figure out this setting existed, and I’m not willing to give
it up easily (at least not until I switch to an HiDPI external display,
something that probably won’t happen within the next couple of years). I
noticed that Emacs did not suffer from this issue, but it turns out
Emacs was running under Xwayland. It’s nice indeed to see that X11 apps
run seamlessly enough under Wayland that it took me some work to realize
that it was running under Xwayland and not natively. (I figured
it out by calling xprop
: it only reacts to clicks on X11
windows.) I installed foot
, a lightweight native Wayland
terminal that is recommended by the sway
package on Debian,
and it also suffers from this issue. So it seems to be a general issue
with Freetype under Wayland, which is weird because font rendering
should be a client-side problem and should be the same under X11 and
Wayland.
Finally, I tried to start up the NetworkManager applet. Just running
nm-applet
won’t show anything, because by default
nm-applet
uses the Xembed protocol to create a tray icon,
which is not supported by Swaybar; you have to run
nm-applet --indicator
instead. However, clicking on the
icon does nothing; it seems that the context menu on tray icons is currently
not supported (as of Sway 1.7). It does work with Waybar (and the context
menu has the same font rendering issue; in fact I’m not even sure it’s
using the same font), but Waybar has a lot more bells and whistles I’m
not interested in, plus I would have to figure out how to adapt my
current status bar script to it (assuming it’s possible), which is
pretty important to me as I use the i3 status bar to display desktop
notifications.
The lack of Xembed tray icon support is a problem for another program I use as well: Thunderbird. As of 2023, I’m still using Thunderbird 52 (released in 2018) because it’s the last version that supports FireTray, which shows me a glorious tray icon with a number of unread messages whenever there are unread messages in selected folders, and no icon otherwise. I know that one day I will probably have to switch to a different mail client and/or workflow, but that day is not going to be now.
It does eliminate screen tearing, though. But also it turns out I
could fix that on X.org by using picom --backend glx
--vsync
. [Update: Actually that doesn't fully fix it,
and sometimes causes other glitches of its own. Wayland wins in this regard.]
In The technical merits of Wayland are mostly irrelevant, Chris Siebenmann argues that everyone who would switch from X to Wayland by virtue of its technical merits has already switched. The people who haven’t done so fall into a bunch of categories, one of which is:
People using desktop environments or custom X setups that don’t (currently) support Wayland. Switching to Wayland is extremely non-transparent for these people because they will have to change their desktop environment (so far, to GNOME or KDE) or reconstruct a Wayland version of it.
I happen to be in this category. Sway can mostly replace i3,
but then I have to find a replacement for nm-applet (or use Waybar and
change my status bar script), a replacement for FireTray, rewrite my
jump-to-window script, figure out what the heck is going on with the
font rendering, change my scripts that currently use
xrandr
, etc. All of this to get a desktop just as
good as my current X11 one; switching to Wayland does not really
bring me any new functionality or improvements. Maybe a few years from
now, as X.org starts to bit-rot and new stuff starts to be developed for
Wayland exclusively, switching will become more compelling. As of 2023,
though, I don’t really have much to gain from it, and I’d rather spend
my time on other adventures, at least for now.
But I don’t share the Wayland hate I see in various places around the interwebs. When the time comes (or when I feel like it), I will make the switch. By then, hopefully some of the issues above will have been fixed (e.g., more standardized protocol extensions, menu support for Swaybar tray icons), hopefully I will have found a replacement for FireTray, and maybe I will have switched to a HiDPI external monitor. Until then, long live X.org.
Computer screens are a complicated business for me: most screens are too bright for my eyes even at the zero brightness setting. I have had some luck with the most recent laptops I used, though – a Dell Latitude 7490 I bought second-hand last year, and an HP Pavillion Gaming Laptop provided by my company, both of which have excellent screens – so I wondered if maybe monitor technology had improved enough lately that I would be able to get an external monitor that won’t burn my eyes after a few hours use. So I decided to try my luck with a Lenovo L22e-20 monitor.
When it arrived, I tried it out and was immediately disappointed. It was just as bad brightness-wise as every other LCD external monitor I had used. Even at the zero brightness setting, the black background was not black, but dark grey, which made the contrast too low. The image quality was really good for watching videos, but for staring at text for extended periods of time, it was just not comfortable to look at; my laptop screen was much better. I was so disappointed that I decided I would return the monitor and order a different one.
A couple of days later, I decided to try it again, and to my great surprise, the monitor did not look bad at all. The black was really black, the brightness was pretty good (though I wish I could lower it a little bit further at night). I wondered if I had just gotten used to the new monitor, but the difference was so great that it was hard to believe it was just a psychological effect.
A few hours later, I wanted to see how i3 would handle workspaces when screens are disconnected or connected to a running session. So I disconnected the Lenovo monitor and connected it again – and to my even greater surprise the screen came back with the awful brightness of the first time. I tried to look at every setting in the monitor, but nothing had changed; I tried disconnecting and connecting again, to no avail; I tried to turn everything off and on again – nothing changed, same awful brightness.
The next day, I decided to look at XRandR settings – maybe it was some software-side gamma or brightness setting or something that was affecting the brightness. I ran xrandr --verbose
, and gamma/brightness values were normal, but I noticed something else: there were five different 1920x1080
modes for the screen. This is the relevant part of the output:
1920x1080 (0xa4) 148.500MHz +HSync +VSync *current +preferred h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.50KHz v: height 1080 start 1084 end 1089 total 1125 clock 60.00Hz 1920x1080 (0xa5) 174.500MHz +HSync -VSync h: width 1920 start 1968 end 2000 total 2080 skew 0 clock 83.89KHz v: height 1080 start 1083 end 1088 total 1119 clock 74.97Hz 1920x1080 (0xa6) 148.500MHz +HSync +VSync h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.50KHz v: height 1080 start 1084 end 1089 total 1125 clock 60.00Hz 1920x1080 (0xa7) 148.500MHz +HSync +VSync h: width 1920 start 2448 end 2492 total 2640 skew 0 clock 56.25KHz v: height 1080 start 1084 end 1089 total 1125 clock 50.00Hz 1920x1080 (0xa8) 148.352MHz +HSync +VSync h: width 1920 start 2008 end 2052 total 2200 skew 0 clock 67.43KHz v: height 1080 start 1084 end 1089 total 1125 clock 59.94Hz
Here, besides the resolution, frequencies, and other characteristics, each mode is identified by a hexadecimal code in parentheses (0xa4
, 0xa5
, etc.). Turns out you can pass those codes to the xrandr --mode
option instead of a resolution such as 1920x1080
to select one among multiple modes with the same resolution.
I decided to try the other modes, just to see what difference it would make – and lo and behold, the second mode made the screen brightness good again! All the other modes left the screen with the bright background. I don’t know what it is specifically about this mode that had an effect on brightness, but I notice two things: it is the mode with the highest frequency, and it is the only one with -VSync
rather than +VSync
(the xorg.conf manpage tells us this is the polarity of the VSync signal, whatever that is). Maybe one (or both) of these elements is involved in the trick.
Actually, even if you run xrandr
without the --verbose
option, it will list potentially multiple modes for each resolution, by showing all available refresh rates for each resolution:
HDMI-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 476mm x 268mm 1920x1080 60.00 + 74.97* 60.00 50.00 59.94 1920x1080i 60.00 50.00 59.94 1680x1050 59.88 1280x1024 75.02 70.00 60.02 1440x900 59.90 1152x864 75.00 1280x720 60.00 60.00 50.00 59.94 1024x768 75.03 70.07 60.00 800x600 72.19 75.00 60.32 720x576 50.00 50.00 50.00 720x480 60.00 60.00 59.94 59.94 59.94 640x480 75.00 72.81 60.00 59.94 59.94 720x400 70.08
I had never paid much attention to this, but you can actually select the specific mode you want by calling, for example, xrandr --output HDMI-1 --mode 1920x1080 --rate 74.97
, specifying both the resolution and the refresh rate. In some cases, though, there are multiple modes with the same refresh rate (for example, the 720x576
line above has three different modes with the same refresh rate 50.00
); in this case, I think the only way to choose a specific mode is to specify the hexadecimal code of the mode listed by the --verbose
option.
If you don’t specify a refresh rate or give a specific mode hex code, XRandR will theoretically select the “preferred” mode, which is the one with a +
sign after it in the output. For this Lenovo monitor, the preferred mode is a bad one, so you have to override it with these options.
The weirdest thing about this story is that, on the day the monitor was suddenly good, Xorg had apparently selected a non-preferred mode by pure chance for some reason. If that had not happened, I would probably have never discovered that the monitor had a good mode at all.
I’ve been using cgit for hosting my Git repositories since about the end of 2018. One minor thing that annoys me about cgit is that the landing page for repositories is not the about page (which shows the readme), but the summary page (which shows the last commits and repository activity). This is a useful default if you are visiting the page of a project you already know (so you can see what’s new), but not so much for someone casually browsing your repos.
There were (at least) two ways I could solve this:
I could change the cgit source code to use the about page as a default. This would require figuring out all parts to change, and keeping my own patched version of cgit. Or…
I could come up with a pile of nginx rules to map the external URLs I want (e.g., /code/<repo-name>/
) into cgit’s own URLs (e.g., /cgit/<repo-name>/about/
).
I went with the second option.
Things are not so simple, however: even if I map my external URLs into cgit’s internal ones, cgit will still generate links pointing to its own version of the URLs. So the evil masterplan is to have two root locations:
/code/
, which exposes the URLs the way I want them, translates them to cgit’s URLs, and passes the translated versions to cgit;/cgit/
, which redirects cgit-style URLs to the corresponding /code/
URLs. This way, cgit can still generate links to its own version of the URLs, and they will get translated back to the external URLs when the user follows the links.In the rest of this post, I will go through the nginx rules I used. You can find them here if you would like to see them all at once.
We will need four different rules for the /code
location. All of them involve passing a translated URL to cgit, which involves setting up a bunch of FastCGI variables, most of which are identical in all rules. So let’s start by creating a file in /etc/nginx/snippets/fastcgi-cgit.conf
which we can reuse in all rules:
fastcgi_pass unix:/run/fcgiwrap.socket; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; # Tell fcgiwrap about the binary we’d like to execute and cgit about # the path we’d like to access. fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi; fastcgi_param DOCUMENT_ROOT /usr/lib/cgit;
These are standard CGI parameters; the only thing specific to cgit here is the SCRIPT_FILENAME
and DOCUMENT_ROOT
variables. Change those according to where you have cgit installed in your system.
/code/
rulesNow come the interesting rules. These go in the server { ... }
nginx section for your website (likely in /etc/nginx/sites-enabled/site-name
, if you are using a Debian derivative). Let’s begin by the rule for the landing page: we want /code/<repo-name>/
to map to cgit’s /<repo-name>/about/
:
location ~ ^/code/([^/]+)/?$ { include snippets/fastcgi-cgit.conf; fastcgi_param SCRIPT_NAME /cgit; fastcgi_param PATH_INFO $1/about/; }
The location
line matches any URL beginning with /code/
, followed by one or more characters other than /
, followed by an optional /
. So it matches /code/foo/
, but not /code/foo/bar
(because foo/bar
has a /
, i.e., it is not “one or more characters other than /
”). The foo
part (i.e., the repo name) will be accessible as $1
inside the rule (because that part of the URL string is captured by the parentheses in the regex).
Inside the rule, we include the snippet we defined before, and then we set two variables: SCRIPT_NAME
, which is the base URL cgit will use for its own links; and PATH_INFO
, which tells cgit which page we want (i.e., the <repo-name>/about
page). Note that the base URL we pass to cgit is not /code
, but /cgit
, so cgit will generate links to URLs like /cgit/<repo-name>/about/
. This is important because later on we will define rules to redirect /cgit
URLs to their corresponding /code
URLs.
The second rule we want is to expose the summary page as /code/<repo-name>/summary/
, which will map to cgit’s repo landing page:
location ~ ^/code/([^/]+)/summary/$ { include snippets/fastcgi-cgit.conf; fastcgi_param SCRIPT_NAME /cgit; fastcgi_param PATH_INFO $1/; }
Again, the principle is the same: we match /code/foo/summary/
, extract the foo
part, and pass a modified URL to cgit. In this case, we just pass foo/
without the summary
, since cgit’s repo landing page is the summary.
The third rule is a catch-all rule for all the other URLs that don’t require translation:
location ~ ^/code/(.*) { include snippets/fastcgi-cgit.conf; fastcgi_param SCRIPT_NAME /cgit; fastcgi_param PATH_INFO $1; }
That is, /code/
followed by anything else not matched by the previous rules is passed as is (removing the /code/
part) to cgit.
/cgit/
rulesNow we need to do the mapping in reverse: we want cgit’s links (e.g., /cgit/<repo-name>/about
) to redirect to our external version of them (e.g., /code/<repo-name>/
). These rules are straightforward: for each of the translation rules we created in the previous session, we add a corresponding redirect here.
location ~ ^/cgit/([^/]+)/about/$ { return 302 /code/$1/; } location ~ ^/cgit/([^/]+)/?$ { return 302 /code/$1/summary/; } location ~ ^/cgit/(.*)$ { return 302 /code/$1$is_args$args; }
[Update (2020-11-05): The last rule must have a $is_args$args
at the end, so that query parameters are passed on in the redirect.]
This set of rules will already work if all you want is to expose cgit’s URLs in a different form. But there is one thing missing: if we go to the cgit initial page (the repository list), all the links to repositories will be of the form /cgit/<repo-name>/
, which our rules will translate to /code/<repo-name>/summary/
. But we don’t want that! We want the links in the repository list to lead to the repo about page (i.e., /code/<repo-name>/
, not /cgit/<repo-name>/
). So what do we do now?
The solution is to pass a different base URL to cgit just for the initial page. So we add a zeroth rule (it has to come before all other /code/
rules so it matches first):
location ~ ^/code/$ { include snippets/fastcgi-cgit.conf; fastcgi_param SCRIPT_NAME /code; fastcgi_param PATH_INFO /; }
The difference between these and the other rules is that we pass SCRIPT_NAME
with the value of /code
instead of /cgit
, so that in the initial page, the links are of the form /code/<repo-name>/
instead of /cgit/<repo-name>/
, which means they will render cgit’s /<repo-name>/about/
page instead of /<repo-name>/
.
Beautiful, huh?
One thing you have to ensure with these rules is that every repo has an about page; cgit only generates about pages for repos with a README, so your links will break if your repo doesn’t have one. One solution for this is to create a default README which cgit will use if the repo does not have a README itself. For this, I have the following settings in my /etc/cgitrc
:
# Use the repo readme if available. readme=:README.md # Default README file. Make sure to put this file in a folder of its own, # because all files in the folder become accessible via cgit. readme=/home/elmord/cgit-default-readme/README.md
That’s all I have for today, folks. If you have comments, feel free to, well, leave a comment.
After almost 3 years using EXWM as my window manager, I decided to give i3 a try. And after two weeks using it, I have to say I'm definitely sticking with it.
I had actually tried i3 years ago, but I had never used a tiling window manager before, and for some reason it didn't click for me at the time. This time, after a long time using EXWM (which I picked up more easily at the time since all the commands were the regular Emacs window/buffer commands I already knew), i3 was quite easy to pick up. So here I am.
EXWM has a lot going for it, mainly from the fact of running in Emacs, and therefore benefitting from the general powers that all things built on Emacs have: it's eminently hackable and customizable (and you can generally see the results of your hacks without even restarting it), and can be integrated in your Emacs workflow in various ways (I gave some examples in my previous EXWM post).
However, it also has some drawbacks. EXWM does not really do much in the way of managing windows: essentially, EXWM just turns all your windows into Emacs buffers, and the window management tasks proper (splitting, deciding which Emacs window will display a new X window, etc.) is the built-in window management Emacs uses for its own windows. Which can of course be customized to death, but is not particularly great for large numbers of windows, in my opinion.
Another problem with EXWM is that if Emacs hangs for any reason (e.g., waiting for TRAMP to open a remote SSH file, or syntax highlighting choking on an overly long line in a JSON file or a Python shell), your whole graphical session freezes, because EXWM does not get an opportunity to react to X events while Emacs is hung doing other stuff. This will happen more or less often depending on the kinds of tasks you do with Emacs. (Also, if you have to kill Emacs for any reason, you kill your entire graphical session, though this can be avoided by starting Emacs like this in your .xsession
:
until emacs; do :; done
an idea I wish I had had earlier.)
Finally, EXWM is glitchy. Those glitches don't manifest too often, and it's hard to separate the glitches that come naturally with it from the ones caused by my own hacks, but the fact is that I got tired of the glitchiness and hanging, and also I was lured by i3's tabs support, so I decided to switch.
The first time you start i3, it presents you with a dialog asking whether you want to use Alt or Win (the 'Windows' key, a.k.a. Super) as the modifier key for i3 shortcuts. I recommend choosing Super here, since it will avoid conflicts with shortcuts from applications. i3 will then generate a config file at ~/.config/i3/config
.
The generated config file contains all the default keybindings; there are no extra keybindings other than those listed in this file. This is good because you can peruse the config file to have a general idea of what keybindings exist and how their corresponding commands are expressed. That being said, the i3 User's Guide is quite good as well, and you should at least skim over it to get an idea of i3's abilities.
One peculiar thing about the standard keybindings is the use of Super+j/k/l/;
to move to the window to the left, down, up, and right, respectively. That's shifted one key to the right of the traditional h/j/k/l
movement commands used by Vim and some other programs. The documentation justifies this as being easier to type without moving away from the home row (and also, Super+h
is used to set horizontal window splitting), but I ended up changing this to Super+h/j/k/l
simply for the convenience of having bindings similar to what other applications use (and then moving horizontal splitting to Super+b
, right beside Super+v
for vertical splitting).
Unlike EXWM or some other window managers, the i3 config file is not a full-fledged programming language, so it's not as flexible as those other WMs. However, i3 has a trick up its sleeve: the i3-msg
program, which allows sending commands to a running i3. Thanks to i3-msg
, you can do tasks that require more of a programming language (e.g., conditional execution) by writing small shell scripts. For example, I have a script called jump-to-terminal.sh
, which is just:
#!/bin/bash i3-msg '[class="terminal"] move container to workspace current, focus' | grep -q true || x-terminal-emulator
i.e., try to find an open terminal window and move it to the current workspace; if the operation does not succeed (because there is no open terminal window), open a new terminal. I can then bind this script to a shortcut in the i3 config file. (I've actually changed script later to not move the window to the current workspace, but it shows how you can string multiple i3 commands together applying to the same window.)
i3 uses the concept of containers to organize windows: windows themselves are containers (containing the actual X11 window), but the whole workspace is itself a container that can be split into multiple subcontainers that can be arbitrarily nested. Containers can either use a split layout (windows are tiled horizontally or vertically within the container), or a tabbed layout (i3 shows a tab bar at the top of the container, and each contained window is a tab), or a stacked layout (which is the same as the tabbed layout but the tab titles are placed in separate lines rather than side-by-side). You can switch the layout of the current container with the shortcuts Super+w
(tabbed), Super+s
(stacked), and Super+e
(split, toggling between horizontal and vertical tiling).
(Note that what i3 calls "horizontal split container" is a split container with horizontal tiling orientation, i.e., windows are laid out side-by-side. This can be confusing if you expect "horizontal split" to mean that the splitting line will be horizontal. This is the same terminology that Emacs uses for window splitting, but the opposite of Vim.)
Containers can be arbitrarily nested, and you can have different layouts in each subcontainer. For example, you could have your workspace divided into two horizontally-tiled containers, and have a tabbed layout in one of the subcontainers. Note that because of this, it's important to know which container you have selected when you use the layout-changing commands. The colors of the borders tell you that, but it takes a while to get used to paying attention to it. i3 comes with a pre-defined binding Super+a
to select the parent of the current container, but not one to select a child; I have found it useful to bind Super+z
to focus child
for this purpose.
The commands Super+v
and Super+h
(Super+b
in my modified keymap) select a tiling orientation for new windows opened in the current container. (Again, the border colors tell you which mode is active.) It implicitly turns the current container into a nested container, so that new windows will become siblings of the current window. It is very easy to create nested containers by accident in this way, especially when you are just starting with i3. Those show up like i3: H[emacs]
in the window title (i.e., a horizontally-tiled container containing just an emacs
window), and you can even get into multiple levels of nested containers with a single window inside. In these situations, it is useful to have a command to move the current window back to its parent container. Surprisingly, i3 does not have a built-in command for that, but it is possible to concoct one from existing commands (based on this StackExchange answer):
# Move container to parent bindsym $mod+Shift+a mark subwindow; focus parent; focus parent; mark parent; [con_mark="subwindow"] focus; move window to mark parent; [con_mark="subwindow"] focus; unmark
What this does is to use i3 marks (which are like Vim marks, allowing you to assign labels to windows) to mark the current window and its parent's parent, and then moving the window to inside its parent's parent (i.e., it becomes a sibling of its current parent).
In EXWM, I had recently implemented a hack to display desktop notifications in the Emacs echo area. I hate desktop notifications appearing on the top of what I'm doing (especially when I'm coding), and I had most of them disabled for this reason until recently, but Slack notifications are useful to see at work. With this hack, I could finally have non-obtrusive desktop notifications. I was only going to switch to i3 if I could find a way to have similar functionality in it.
i3 does not exactly have an echo line, but it does have a desktop bar which shows your workspaces to the left, tray icons to the right, and the output of a status command in the middle. The status command can be any command you want, and the status line shows the last line of output the command has printed so far, so the command can keep updating it. i3bar actually supports two output formats: a plain-text one in which every line is displayed as-is in the status line, and a JSON-based format which allows specifying colors, separators and other features in the output.
This means that you can write a script to listen for D-Bus desktop notifications and print them as they come, together with whatever else you want in the status line (such as a clock and battery status), and blanking them after a while, or when a 'close notification' message is received. I have done just that, and it works like a charm. (It requires python3-pydbus
to be installed.) The only problem with this is that the content of the status line is aligned to the right (because it is meant to be used for a clock and stuff like that), and there is no way to make it aligned to the left, so I actually pad the message to be shown with spaces to a length that happens to fit my monitor. It is sub-optimal, but it works well enough.
I'm pretty happy with the switch to i3. Although I've lost the deep integration with Emacs, it has actually been an improvement even for my Emacs usage, since i3 tabs supplement Emacs's lack of tabs better than any tabbing package I have seen for Emacs. (Having tabs for all programs, including things like Evince, is really nice.) If you are interested in tiling window managers and are willing to spend a few days getting used to it, I definitely recommend it.
I've recently switched from Thunderbird to Liferea as my RSS feed reader. Thunderbird was randomly failing to update feeds at times*, and I thought it might be a good idea to use separate programs for e-mail and RSS for a change, so I went for Liferea. (I considered Elfeed too, but Elfeed does not support folders, only tags. In principle, tags can do everything folders can and more; the problem is that Elfeed cannot show a pane with all tags and the number of unread articles with each tag, the way Thunderbird or Liferea (or your average mail client) can do with folders.)
Liferea is pretty good, although I miss some shortcuts from Thunderbird, and sometimes shortcuts don't work (because focus is on some random widget). Here are some tips and tricks.
Thunderbird can export the feed list in OPML format (right click on the feed folder, click Subscribe…, then Export). You can then import that on Liferea (Subscriptions > Import Feed List). No surprises here.
Liferea comes with a number of plugins (Tools > Plugins). By default, it comes with the Tray Icon (GNOME Classic) plugin enabled, which, unsurprisingly, creates a tray icon for Liferea. The problem with this for me is that whenever the window is 'minimized', Liferea hides the window entirely; you can only bring it back by clicking on the tray icon. I believe the idea is so that the window does not appear in the taskbar and the tray, but this interacts badly with EXWM, where switching workspaces or replacing Liferea with another buffer in the same Emacs 'window' counts as minimizing it, and after that it disappears from the EXWM buffer list. The solution I used is to disable the tray icon plugin.
Liferea has a Media Player plugin to play media attachments/enclosures (such as in podcast feeds). To use it on Debian, you must have the gir1.2-gstreamer-1.0 package installed (it is a 'Recommends' dependency, not a mandatory one).
Alternatively, you can set Liferea to run an arbitrary command to open a media enclosure; the command will receive the enclosure URL as an argument. You can use VLC for that. The good thing about it is that VLC will start playing the stream immediately; you don't have to wait for it to download completely before playing it. The bad thing is that once it finishes playing the stream, the stream is gone; if you play it again, it will start downloading again. Maybe there is a way to configure this in VLC, but the solution I ended up using was to write a small script to start the download, wait a bit, and start VLC on the partially downloaded file. This way, the file will be fully downloaded and can be replayed (and moved elsewhere if you want to preserve it), but you don't have to wait for the download to finish.
#!/bin/bash # download-and-play-media.sh # Save file in a temporary place. file="/tmp/$(date "+%Y%m%d-%H%M%S").media" # Start download in a terminal so we can see the progress. x-terminal-emulator -e wget "$1" -O "$file" & # Wait for the file to be non-empty (i.e, for the download to start). until [[ -s "$file" ]]; do sleep 1 done # Wait a bit for the file to fill. sleep 2 # Play it. vlc "$file"
By default, when you select a folder, Liferea will show all unread items in the folder and all its subfolders. (You can change that in the preferences.) If you select an individual feed, it will show both read and unread items for that feed.
There is also a special Unread folder which shows all unread items anywhere. This is actually a "search folder", showing all items matching given search criteria; you can create your own search folders.
Liferea can show feed comments for feeds that support it. I did not even know this was a feature of feeds; maybe I'll add it to this blog in the future. You can configure whether or not to show comments in the feed options. There are a number of other interesting feed options too; notably, you can set a feed to download media enclosures automatically.
So far I had two UI-related problems with Liferea:
Shortcuts break sometimes, as mentioned before.
There are commands to zoom in and zoom out (the usual Ctrl+[+]; and Ctrl+[-]), but no command to reset zoom back to 100%. You can of course use the zoom in/out commands to undo the zoom, but it actually does not get quite back to the exact 100% zoom, which is noticeable with pixelated images (case in point: Dinosaur Comics).
Overall, I'm pretty satisfied with Liferea. There are a few problems, but so far I like it better than Thunderbird for feed reading.
Update (2020-03-23): After a few months using Liferea, I have to say that Thunderbird is better to use from the keyboard. Liferea is way too sensitive to which invisible thing has focus at a given moment. Were it not for Thunderbird not handling well hundreds of feeds, I think I would switch back.
Update (2020-07-10): I ended up switching to Elfeed.
_____
* I suspect the problem was that Thunderbird was trying to DNS-resolve the domains for a huge number (perhaps all) of feeds at the same time, and some of the requests were being dropped by the network. I did not do a very deep investigation, though.
Pous, nos últimos tempos eu aprendi algumas coisinhas novas sobre o SSH. Neste post relato algumas delas.
O SSH possui duas opções, -L e -R, que permitem encaminhar conexões de uma porta local para um host remoto e vice-versa.
Imagine que você está na sua máquina local, chamada midgard, e há uma máquina remota, chamada asgard, que é acessível por SSH. Você quer acessar um serviço na pora 8000 da máquina asgard a partir da máquina midgard, mas você quer tunelar o acesso por SSH (seja porque você quer que o acesso seja criptografado, ou porque a porta 8000 simplesmente não é acessivel remotamente). Você pode usar o comando:
midgard$ ssh -L 9000:127.0.0.1:8000 fulano@asgard
O resultado disso é que conexões TCP feitas para sua porta local 9000 serão tuneladas através da conexão com fulano@asgard para o endereço 127.0.0.1, porta 8000 na outra ponta. Por exemplo, se asgard tem um servidor web ouvindo na porta 8000, agora você vai poder abrir um browser em midgard, apontar para http://localhost:9000, e a conexão vai cair na porta 8000 de asgard, tudo tunelado por uma conexão SSH.
Note que o 127.0.0.1 é o endereço de destino do ponto de vista do servidor. Você poderia usar outro endereço para acessar outras máquinas na rede do servidor. Por exemplo, se a máquina vanaheim é acessível a partir de asgard, você poderia rodar:
midgard$ ssh -L 9000:vanaheim:8000 fulano@asgard
e agora todos os acessos à porta TCP 9000 da sua máquina local cairão na porta 8000 de vanaheim, tunelados através da conexão SSH com asgard.
Opcionalmente, você pode especificar um "bind address" antes da porta local, para especificar que apenas a porta 9000 de uma interface de rede específica deve ficar ouvindo por conexões. Por exemplo, você pode usar:
midgard$ ssh -L localhost:9000:vanaheim:8000 fulano@asgard
para dizer que a porta deve escutar apenas conexões da própria máquina. (Por padrão, que interfaces serão usadas é decidido pela opção GatewayPorts do cliente SSH, que defaulta para ouvir apenas na interface local de qualquer forma.) Alternativamente, pode-se passar um bind address vazio (i.e., :9000:vanaheim:8000, sem nada antes do primeiro :), para ouvir em todas as interfaces. Dessa maneira, outras máquinas na sua rede local que acessem a porta 9000 de midgard também terão o acesso tunelado para a porta 8000 de asgard. (* também funciona ao invés da string vazia, mas aí você tem que escapar o * para o shell não tentar expandir.)
Também é possível fazer o contrário: instruir o servidor SSH remoto a redirecionar alguma de suas portas para uma máquina e porta acessível a partir da sua máquina local. Para isso, utiliza-se a opção -R. Por exemplo:
midgard$ ssh -R 8000:localhost:22 fulano@asgard
Isso faz com que a porta 8000 em asgard seja tunelada para a porta 22 da máquina local. Agora, se alguém na máquina asgard acessar a porta 8000 (por exemplo, com ssh -p 8000 beltrano@localhost), a conexão vai cair na sua porta 22 local (e a pessoa terá acesso ao seu servidor SSH local). Você pode usar isso se você está atrás de um firewall ou NAT e a máquina remota é acessível pela Internet, mas a sua máquina local não, e você quer dar acesso a algum serviço da sua máquina local à máquina remota. (Já abordamos isso por aqui antes, mas menciono de novo for completeness.)
O SSH é capaz de funcionar como um proxy SOCKS. Para isso, utiliza-se a opção -D ("dynamic forwarding"):
midgard$ ssh -D localhost:8000 fulano@asgard
Isso faz com que o SSH ouça como um servidor SOCKS na porta 8000 da máquina local. Conexões recebidas nessa porta serão tuneladas para a máquina asgard, que funcionará como um proxy. Você pode então apontar o proxy SOCKS do seu browser ou outra aplicação para localhost, porta 8000.
-C habilita compressão da conexão. E útil principalmente com conexões lentas (numa rede local, a compressão não compensa muito).
Por padrão, se você usa um dos comandos de redirecionamento de portas acima, o SSH faz o redirecionamento e abre uma sessão de shell comum. Se você quer apenas fazer o redirecionamento, pode usar as opções -N (não executa comando remoto) e -f (vai para background (forks) depois de pedir a senha). As opções podem ser combinadas em um único argumento (e.g., -CNf).
Em uma sessão SSH, a seqüência ENTER ~ é reconhecida como um prefixo de escape para acessar uma série de comandos especiais. Se você digitar ENTER ~ ?, verá uma lista de todos os comandos disponíveis:
Supported escape sequences: ~. - terminate connection (and any multiplexed sessions) ~B - send a BREAK to the remote system ~C - open a command line ~R - request rekey ~V/v - decrease/increase verbosity (LogLevel) ~^Z - suspend ssh ~# - list forwarded connections ~& - background ssh (when waiting for connections to terminate) ~? - this message ~~ - send the escape character by typing it twice (Note that escapes are only recognized immediately after newline.)
O comando ENTER ~ C abre um prompt onde é possível fazer e cancelar redirecionamentos de porta, com uma sintaxe análoga à das opções vistas anteriormente:
ENTER ~ C ssh> ? Commands: -L[bind_address:]port:host:hostport Request local forward -R[bind_address:]port:host:hostport Request remote forward -D[bind_address:]port Request dynamic forward -KL[bind_address:]port Cancel local forward -KR[bind_address:]port Cancel remote forward -KD[bind_address:]port Cancel dynamic forward
Pasmem.
O uso das opções de redirecionamento pode ser controlado/desabilitado na configuração do servidor. Consulte a man page sshd_config(5) para mais informações.
Recently I started using Xfce/Xfwm instead of IceWM. One of the problems I had after migrating is that Xfwm places new Pidgin conversation windows on the top of existing windows, obstructing whatever I am doing. At least it doesn't give focus to the new window, but ideally the window should be placed in background.
The solution I found was, well, modifying the source code. Fortunately, there is only a single line to be changed.
Download Xfwm 4.12's source code, unpack it (tar -xvf xfwm4-4.12.0.tar.bz2) in a place of your choosing, and enter the xfwm4-4.12.0 directory.
In the file src/focus.c, replace line 232, which says:
clientRaise (c, None);
with:
clientLower (c, None);
Run ./configure. If it complains about missing libraries, you will have to install the corresponding development (header) packages from your distribution. On Debian, Ubuntu and similar, these packages have names ending in -dev. For instance, if ./configure complains that libxfce4ui-1 is missing, you will have to install the package libxfce4ui-1-dev.
Update: You can install all(?) dependencies with:
sudo apt-get install intltool libx11-dev libgtk2.0-dev libxfce4util-dev libxfce4ui-1-dev libwnck-dev
After ./configure succeeds, run make, then make install.
If everything succeeded, test the newly compiled window manager by running xfwm4 --replace. (You may have to specify the full path, e.g., /usr/local/bin/xfwm4 --replace, to make sure you are using the newly compiled Xfwm, not the one that came with your distro.) If the new window manager works, you are done! (If anything goes wrong, you can run make uninstall to undo the installation, then run /usr/bin/xfwm4 --replace to re-run the original Xfwm.)
One day, maybe, I may try to turn this into a configuration option in Xfwm and submit a patch. One day...
Por uma série de acidentes enquanto experimentava window managers hoje,
Você vai precisar de:
Com isso, podemos escrever um pequeno script para apresentar um menu e selecionar a janela escolhida.
#!/bin/bash option="$( wmctrl -xl | # \1 \2 \3 \4 \5 # win-id desktop class hostname title sed -r 's|([^ ]* +)([^ ]* +)([^ ]* +)([^ ]* +)(.*)|\1 \3 \5|' | sort -k 3 | dmenu -i -l 10 )" || exit 1 wmctrl -ia "${option%% *}"
wmctrl -l lista as janelas existentes. A opção -x inclui a classe da janela na listagem. O sed não é estritamente necessário, mas deixa a lista menos poluída removendo campos desnecessários; você pode alterar essa linha para escolher os campos. O ID da janela é meio irrelevante para o usuário, mas precisamos dele para poder passá-lo ao wmctrl para ativar a janela.
sort -k 3 ordena o menu pelo título da janela. Você pode comentar essa linha fora se não quiser ordenar a lista, ou mudar os parâmetros para obter uma ordem diferente (e.g., sort -k 2 para ordenar pela classe).
Quanto ao dmenu, a opção -i faz com que ele ignore maiúsculas vs. minúsculas ao filtrar as opções pelo texto digitado pelo usuário. -l 10 indica que queremos uma opção por linha, e que no máximo 10 linhas devem ser mostradas de cada vez. Por padrão, o dmenu usa apenas uma linha e mostra as opções lado a lado. (Uma coisa meio ruim do dmenu é que ele não dá nenhuma indicação de que é possível scrollar o menu; ele só mostra as primeiras N opções e as demais ficam escondidas.)
wmctrl -a JANELA ativa a primeira janela cujo título contenha a string specificada. Como queremos que a seleção seja inambígua, utilizamos a opção -i, que permite especificar o ID da janela ao invés do título. Para extrair o ID da seleção, removemos tudo depois do primeiro espaço na string ("${option%% *}").
Salve o script no local de sua preferência, dê permissão de execução a ele (chmod +x nome-do-script), e associe-o a alguma tecla de atalho no seu ambiente gráfico favorito. Por exemplo, no IceWM isso pode ser feito adicionando no ~/.icewm/keys uma linha como:
key "Super+Tab" /caminho/do/script
substituindo Super+Tab pelo atalho de sua preferência (Super é a tecla "janelinha").
Para mais informações e possibilidades, consulte a manpage dos programas.
Meia dúzia de dias atrás eu migrei meu / para Btrfs. Hoje eu reformatei a partição como ext4 e recuperei meu backup do / da semana passada.
O causo foi assim. Para usar o Btrfs, eu atualizei meu kernel para o 3.16, já que diversas melhorias foram realizadas no suporte a Btrfs nessa versão. Porém, o driver da minha placa de rede wireless (o broadcom-sta) andava não se comportando muito bem, o iwconfig hoje resolveu não listar nenhuma rede, e eu resolvi bootar com o meu kernel 3.14 anterior para ver se a situação melhorava. (Na verdade, com a atualização do kernel 3.2 para 3.14, que eu fiz para poder usar o Btrfs, eu tive que substituir o broadcom-sta da stable pelo da testing, e desde então ele já andava com uns comportamentos desagradáveis (tais como emitir um trace sempre que a wi-fi era iniciada), mas aparentemente a wi-fi estava funcionando corretamente mesmo assim.) Até aí, tudo transcorreu normalmente. Kernel 3.14 bootado, wi-fi funcionando, todos comemora.
Eis que eu fui abrir o aptitude (já não lembro mais por que motivo), e o módulo do Btrfs capota, emitindo algum erro sobre quotas/qgroups. Reiniciei a máquina com o kernel 3.14, fui abrir o aptitude de novo, mesmo erro. Agora não lembro mais a seqüência exata das ações, mas em algum momento eu desativei o suporte a quotas (btrfs quota disable /), abri o aptitude de novo, e dessa vez ele abriu. Porém, turns out que, no piripaque do filesystem, meu /var/lib/dpkg/status virou um arquivo vazio, e o aptitude abriu me mostrando nenhum pacote instalado e me oferecendo para baixar 3GB de pacotes (i.e., todos os pacotes que eu tinha na máquina). Nesse momento eu me disse "well, fuck", reformatei o / como ext4 e recuperei o backup que eu tinha feito quando fui migrar para Btrfs (que por sorte eu ainda não tinha apagado).
Moral da história: Talvez se eu tivesse me mantido usando o kernel 3.16 eu não tivesse tido esse problema. Porém, depois dessa experiência, e dado que na atual conjuntura eu deveria estar me preocupando com o mestrado e não com a saúde do meu filesystem, eu prefiro esperar mais uns meses para ver se o Btrfs fica mais estável e experimentá-lo de novo. Enquanto isso, eu voltei para o kernel 3.2 da stable, que pode não ser new and shiny, mas é sólido como uma rocha, forte como um touro e pesado como uma porpeta.
Copyright © 2010-2024 Vítor De Araújo
O conteúdo deste blog, a menos que de outra forma especificado, pode ser utilizado segundo os termos da licença Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.
Powered by Blognir.