<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog blog("Baptiste Wicht"); (Posts about Linux)</title><link>https://baptiste-wicht.com/</link><description></description><atom:link href="https://baptiste-wicht.com/categories/linux.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><lastBuildDate>Sun, 15 Feb 2026 06:57:40 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Budgetwarrior: Track assets and portfolio, savings rates and auto-completion</title><link>https://baptiste-wicht.com/posts/2017/10/budgetwarrior-track-assets-portfolio-savings-rates-auto-completion.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;This last month, I've been reading quite a few blogs about personal finance and
I've decided to integrate more features into budgetwarrior. This post is about
three new features that I've integrated. It's not yet a new release, so if you
want to test this version, you'll have to compile it from the &lt;em&gt;master&lt;/em&gt; branch on
Git.&lt;/p&gt;
&lt;p&gt;As it was last time, the values on my screenshots have all been randomized.&lt;/p&gt;
&lt;p&gt;If you have several assets with different distributions, I believe it is a great
value to have them all shown at the same time. Especially if you want to change
the distribution of your portfolio or if you plan big changes in it.&lt;/p&gt;
&lt;section id="track-assets"&gt;
&lt;h2&gt;Track assets&lt;/h2&gt;
&lt;p&gt;The first feature I've added is a feature to precisely track each of your assets
independently. And you can also track the allocation of your portfolio in terms
of stocks, bonds and cash. The tool also lets you set the desired distribution
of your assets and will compute the difference that you should make in order to
comply to your desired distribution.&lt;/p&gt;
&lt;p&gt;First, you need to define all your asset classes (your accounts, funds, and
stocks, ...) and their distribution with &lt;code&gt;budget asset add&lt;/code&gt;. It also
supports to set a currency. The default currency is now CHF, but you can set it
in the configuration file, for instance &lt;code&gt;default_currency=USD&lt;/code&gt;. You can
see your assets using &lt;code&gt;budget asset&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="View of your assets" src="https://baptiste-wicht.com/images/budgetwarrior_assets.png"&gt;
&lt;p&gt;You can then set the value of your assets using &lt;code&gt;budget asset value add&lt;/code&gt;.
The system will save all the values of your assets. For now, only the last value
is used in the application to display. In the future, I plan to add new reports
for evolution of the portfolio over time. You can see your current net worth
with the &lt;code&gt;budget asset value&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="View of your portfolio" src="https://baptiste-wicht.com/images/budgetwarrior_asset_values.png"&gt;
&lt;p&gt;The different currencies will all be converted to the default currency.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="savings-rate"&gt;
&lt;h2&gt;Savings rate&lt;/h2&gt;
&lt;p&gt;The second change I did is to compute the savings rate of each month and year.
The savings rate is simply the portion of your income that you are able to save
each month. The savings rate for a year is simple the average of the savings
rate of each month.&lt;/p&gt;
&lt;p&gt;The savings rate of the month can be seen with &lt;code&gt;budget overview month&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="Savings rate of the month" src="https://baptiste-wicht.com/images/budgetwarrior_savings_rate.png"&gt;
&lt;p&gt;The saving rates of each month can also be seen in the overview of the year with
&lt;code&gt;budget overview year&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="Savings rate of the year" src="https://baptiste-wicht.com/images/budgetwarrior_savings_rate_year.png"&gt;
&lt;p&gt;This shows the savings rate of each month, the average of the year and the
average of the current year up to the current month.&lt;/p&gt;
&lt;p&gt;The savings rate is a very important metric of your budget. In my case, it's
currently way too low and made me realize I really need to save more. Any
savings rate below 10% is too low. There are no rule as too much it should be,
but I'd like to augment mine to at least 20% next year.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="auto-completion"&gt;
&lt;h2&gt;Auto-completion&lt;/h2&gt;
&lt;p&gt;The last feature is mostly some quality-of-life improvement. Some of the inputs
in the console can now be completed. It's not really auto-completion per se, but
you can cycle through the list of possible values using the UP and DOWN.&lt;/p&gt;
&lt;p&gt;This makes it much easier to set some values such as asset names (in
&lt;code&gt;budget asset value add&lt;/code&gt; for instance), account names and objective types
and sources. I'm trying to make the input of values easier.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I don't know exactly what else will be integrated in this feature, but I may
already improve some visualization for asset values. If I learn something new
about personal finance that I may integrate in the tool, I'll do it as well.&lt;/p&gt;
&lt;p&gt;If you are interested by the sources or want to install this version,
you can download them on Github:
&lt;a class="reference external" href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The new features are in the &lt;em&gt;master&lt;/em&gt; branch.&lt;/p&gt;
&lt;p&gt;If you have a suggestion for a new features or you found a bug, please post an
issue on Github, I'd be glad to help you.&lt;/p&gt;
&lt;p&gt;If you have any comment, don't hesitate to contact me, either by letting a
comment on this post or by email.&lt;/p&gt;
&lt;/section&gt;</description><category>budgetwarrior</category><category>C++</category><category>Linux</category><guid>https://baptiste-wicht.com/posts/2017/10/budgetwarrior-track-assets-portfolio-savings-rates-auto-completion.html</guid><pubDate>Thu, 12 Oct 2017 17:40:14 GMT</pubDate></item><item><title>budgetwarrior 0.4.2 - Budget summary and improved fortune reports</title><link>https://baptiste-wicht.com/posts/2017/09/budgetwarrior-042-budget-summary-improved-fortune-reports.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;Almost three years ago, &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2014/09/budgetwarrior-041-expense-templates-and-year-projection.html"&gt;I published the version 0.4.1 of budgetwarrior&lt;/a&gt;. Since then, I've been using this tool almost every day to manage my personal budget. This is the only tool I use to keep track of my expenses and earnings and it makes a great tool for me. I recently felt that it was missing a few features and added them and polished a few things as well and release a new version with all the new stuff. This new version is probably nothing fancy, but a nice upgrade of the tool.&lt;/p&gt;
&lt;p&gt;Don't pay too much attention to the values in the images since I've randomized
all the data for the purpose of this post (new feature, by the way :P).&lt;/p&gt;
&lt;section id="new-summary-view"&gt;
&lt;h2&gt;New summary view&lt;/h2&gt;
&lt;p&gt;I've added a new report with &lt;code&gt;budget summary&lt;/code&gt;:&lt;/p&gt;
&lt;img alt="/images/budgetwarrior_042_summary.png" src="https://baptiste-wicht.com/images/budgetwarrior_042_summary.png"&gt;
&lt;p&gt;This view gives concise information about the current state of your accounts. It
also gives information about your yearly and monthly objectives. Finally, it
also gives information about the last two fortune values that you've set.
I think this make a great kind of dashboard to view most of the information. If
your terminal is large enough, the three parts will be shown side by side.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="improved-fortune-report"&gt;
&lt;h2&gt;Improved fortune report&lt;/h2&gt;
&lt;p&gt;I've made a few improvements to the &lt;code&gt;budget fortune&lt;/code&gt; view:&lt;/p&gt;
&lt;img alt="/images/budgetwarrior_042_fortune.png" src="https://baptiste-wicht.com/images/budgetwarrior_042_fortune.png"&gt;
&lt;p&gt;It now display the time between the different fortune values and it compute the
average savings (or avg losses) per day in each interval and in average from the
beginning of the first value.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="various-changes"&gt;
&lt;h2&gt;Various changes&lt;/h2&gt;
&lt;p&gt;The balance does not propagate over the years anymore. This should mainly change
the behaviour of &lt;code&gt;budget overview&lt;/code&gt;. I don't think it was very
smart to propagate it all the time. The balance now starts at zero for each
year. If you want the old system, you can use the multi_year_balance=true option
in the .budgetrc configuration file.&lt;/p&gt;
&lt;p&gt;The recurring expenses do not use an internal configuration value. This does not
change anything for the behaviour, but means that if you sync between different
machines, it will avoid a lot of possible conflicts :)&lt;/p&gt;
&lt;p&gt;Fixed a few bugs with inconsistency between the different views and reports.
Another bug that was fixed is that &lt;code&gt;budget report&lt;/code&gt; was not always displaying the
first month of the year correctly, this is now fixed.&lt;/p&gt;
&lt;p&gt;The graphs display in &lt;code&gt;budget report&lt;/code&gt; are now automatically adapted to width of
your terminal. Finally, the &lt;code&gt;budget overview&lt;/code&gt; command also displays more
information about the comparison with the previous month.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;If you are on Gentoo, you can install it using layman:&lt;/p&gt;
&lt;pre class="literal-block"&gt;layman -a wichtounet
emerge -a budgetwarrior&lt;/pre&gt;
&lt;p&gt;If you are on Arch Linux, you can use this &lt;a class="reference external" href="https://github.com/StreakyCobra/aur-budgetwarrior"&gt;AUR repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For other systems, you'll have to install from sources:&lt;/p&gt;
&lt;pre class="literal-block"&gt;git clone --recursive git://github.com/wichtounet/budgetwarrior.git
cd budgetwarrior
make
sudo make install&lt;/pre&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;A brief tutorial is available on Github: &lt;a class="reference external" href="https://github.com/wichtounet/budgetwarrior/wiki/Start-tutorial"&gt;Starting guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you are interested by the sources, you can download them on Github:
&lt;a class="reference external" href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have any suggestion for a new feature or an improvement to the tool or
you found a bug, please post an issue on Github, I'd be glad to help you. You
can post a comment directly on this post :)&lt;/p&gt;
&lt;p&gt;If you have any other comment, don't hesitate to contact me, either by letting a
comment on this post or by email.&lt;/p&gt;
&lt;p&gt;I hope that this application can be useful to some of you command-line adepts :)&lt;/p&gt;
&lt;/section&gt;</description><category>budgetwarrior</category><category>C++</category><category>Gentoo</category><category>Linux</category><category>Releases</category><guid>https://baptiste-wicht.com/posts/2017/09/budgetwarrior-042-budget-summary-improved-fortune-reports.html</guid><pubDate>Thu, 14 Sep 2017 18:42:39 GMT</pubDate></item><item><title>How to fix mdadm RAID5 / RAID6 growing stuck at 0K/s ?</title><link>https://baptiste-wicht.com/posts/2017/08/how-to-fix-mdadm-raid5-raid6-growing-stuck-at-0ks.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I just started growing again my RAID6 array from 12 to 13 disks and
I encountered a new issue. The reshape started, but with a speed of 0K/s. After
some searching, I found a very simple solution:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_261fe30249bd4e418eb46d00b7d53984-1" name="rest_code_261fe30249bd4e418eb46d00b7d53984-1" href="https://baptiste-wicht.com/posts/2017/08/how-to-fix-mdadm-raid5-raid6-growing-stuck-at-0ks.html#rest_code_261fe30249bd4e418eb46d00b7d53984-1"&gt;&lt;/a&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;max&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/sys/block/md0/md/sync_max
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the reshape started directly at 50M/s :)&lt;/p&gt;
&lt;p&gt;The solution is the same if you are growing any type of RAID level with parity
(RAID5, RAID6, ...).&lt;/p&gt;
&lt;p&gt;Normally, the issues I have are related to speed not very good. I've written
a post in the post about
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html"&gt;how to speed up RAID5 / RAID6 growing with mdadm&lt;/a&gt;.
Although RAID5 / RAID6 growing, or another reshape operation, will never be very
fast, you can still speed up the process a lot from a few days to a few hours.
Currently, my reshape is working at 48M/s and I'm looking at around 16 hours of
reshape, but I have 13 disks of 3To, so it's not so bad.&lt;/p&gt;
&lt;p&gt;I hope this very simple tip can be helpful to some of you :)&lt;/p&gt;</description><category>Gentoo</category><category>Hardware</category><category>Home Server</category><category>Linux</category><guid>https://baptiste-wicht.com/posts/2017/08/how-to-fix-mdadm-raid5-raid6-growing-stuck-at-0ks.html</guid><pubDate>Sat, 12 Aug 2017 10:28:43 GMT</pubDate></item><item><title>Migrated from owncloud 5 to Nextcloud 11</title><link>https://baptiste-wicht.com/posts/2017/03/migrated-from-owncloud-5-to-nextcloud-11.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;For several years now I've been using Owncloud running on one of my servers.
I'm using simply using as a simple synchronization, I don't use any of the tons
of fancy features they keep adding. Except from several synchronization issues,
I haven't had too much issues with it.&lt;/p&gt;
&lt;p&gt;However, I have had a very bad time with updates of Owncloud. The last time
I tried, already long ago, was to upgrade from 5.0 to 6.0 and I never succeeded
without losing all the configuration and having to do the resync. Therefore,
I've still an Owncloud 5.0 running. From this time, I had to say that I've been
lazy and didn't try again to upgrade it. Recently, I've received several mails
indicating that this is a security threat.&lt;/p&gt;
&lt;p&gt;Since I was not satisfied with updates in Owncloud and its security has been
challenged recently, I figured it would be a good moment to upgrade to Nextcloud
which is a very active fork of Owncloud that was forked by developers of
Owncloud.&lt;/p&gt;
&lt;p&gt;I haven't even tried to do an upgrade from such an old version to the last
version of Nextcloud, it was doomed to fail. Therefore, I made a new clean
installation. Since I only use the sync feature of the tool, it does not really
matter, it is just some time lost to sync everything again, but nothing too bad.&lt;/p&gt;
&lt;p&gt;I configured a new PostgreSQL on one of my servers for the new database and then
installed Nextcloud 11 on Gentoo. It's a bit a pain to have a working Nginx
configuration for Nextcloud, I don't advice to do it by hand, better take one
from the official documentation, you'll also gain some security. One very bad
thing in the installation process is that you cannot choose the database prefix,
it's set like Owncloud. The problem with that is that you cannot install both
Owncloud and Nextcloud on the same database which would be more practical for
testing purpose. It's a bit retarded in my opinion, but not a big problem in the
end. Other than these two points, everything went well and it was installation
pretty nicely. Then, you should have your user ready to go.&lt;/p&gt;
&lt;img alt="Nextcloud view" class="align-center" src="https://baptiste-wicht.com/images/nextcloud.png"&gt;
&lt;p&gt;As for the interface, I don't think there is a lot to tell here. Most of it is
what you would except from this kind of tool. Moreover, I very rarely use the
web interface or any of the feature that are not the sync feature. One thing
that is pretty cool I think is the monitoring graphs in the Admin section of the
interface. You can the number of users connected, the memory used and the CPU
load. It's pretty useful if you share your Nextcloud between a lot of different
users.&lt;/p&gt;
&lt;p&gt;I didn't have any issue with the sync either. I used the nextcloud-client
package on Gentoo directly and it worked perfectly directly. It took about 10
minutes to sync everything again (about 5GB). I'll have to do the same thing on
my other computer as well, but I don't think I'll have any issue.&lt;/p&gt;
&lt;p&gt;So far, I cannot say that this is better than Owncloud, I just hope the next
upgrade will fare better than they did on Owncloud. Moreover, I also hope that
the security that they promise is really here and I won't have any problem with
it. I'll see in the future!&lt;/p&gt;
&lt;p&gt;For more information about nextcloud and owncloud compared to each other, you
can read &lt;a class="reference external" href="https://civihosting.com/blog/nextcloud-vs-owncloud/"&gt;this in-depth comparison&lt;/a&gt;, by David Feldman.&lt;/p&gt;</description><category>Gentoo</category><category>Linux</category><category>Server</category><category>Tools</category><guid>https://baptiste-wicht.com/posts/2017/03/migrated-from-owncloud-5-to-nextcloud-11.html</guid><pubDate>Fri, 03 Mar 2017 08:08:58 GMT</pubDate></item><item><title>Simplify Deep Learning Library usage on Linux and Windows!</title><link>https://baptiste-wicht.com/posts/2016/04/simplify-deep-learning-library-usage-on-linux-and-windows.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;No, I'm not dead ;) I've been very busy with my Ph.D (and playing Path of Exile,
let's be honest...) and haven't had time to write something here in a long time.&lt;/p&gt;
&lt;p&gt;Until now, there was too way to use my
&lt;a class="reference external" href="https://github.com/wichtounet/dll/"&gt;Deep Learning Library (DLL)&lt;/a&gt; project:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Write a C++ program that uses the library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install DLL and write a configuration file to define your network and the problem to solve&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first version gives you all the features of the tool and allows you to build
exactly what you need. The second version is a bit more limited, but does not
require any C++ knowledge. However, it still does require a recent C++ compiler
and build system.&lt;/p&gt;
&lt;p&gt;Due to the high C++ requirements that are not met by Visual Studio and the fact
that I don't work on Windows, this platform is not supported by the tool. Until
now!&lt;/p&gt;
&lt;p&gt;I've added a third option to use DLL in the form of a Docker image to make the
second option even easier and allow the use of DLL on Windows. All you need is
Docker, which is available on Linux, Mac and Windows. This is still limited to
the second option in that you need to write a configuration describing the
network, but you need to build DLL and don't need to install all its
dependencies.&lt;/p&gt;
&lt;section id="usage"&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;To install the image, you can simply use &lt;cite&gt;docker pull&lt;/cite&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_a3ce2a0542e34166a69e708be695f4a6-1" name="rest_code_a3ce2a0542e34166a69e708be695f4a6-1" href="https://baptiste-wicht.com/posts/2016/04/simplify-deep-learning-library-usage-on-linux-and-windows.html#rest_code_a3ce2a0542e34166a69e708be695f4a6-1"&gt;&lt;/a&gt;docker&lt;span class="w"&gt; &lt;/span&gt;pull&lt;span class="w"&gt; &lt;/span&gt;wichtounet/docker-dll
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, to run it, you have to create a folder containing a &lt;cite&gt;dll.conf&lt;/cite&gt; file and
mount in the container at &lt;cite&gt;/dll/data/&lt;/cite&gt;. There are some examples in the
&lt;a class="reference external" href="https://github.com/wichtounet/docker-dll/"&gt;image repository&lt;/a&gt;.  For instance,
on Linux from the cloned repository:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_48f8e74fdbb64a5b8b80d06d96a77e66-1" name="rest_code_48f8e74fdbb64a5b8b80d06d96a77e66-1" href="https://baptiste-wicht.com/posts/2016/04/simplify-deep-learning-library-usage-on-linux-and-windows.html#rest_code_48f8e74fdbb64a5b8b80d06d96a77e66-1"&gt;&lt;/a&gt;docker&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/rbm_mnist/:/dll/data/&lt;span class="w"&gt; &lt;/span&gt;wichtounet/docker-dll
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;or on Windows:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_6281cd2116f64ae5b3d85bb0deeec891-1" name="rest_code_6281cd2116f64ae5b3d85bb0deeec891-1" href="https://baptiste-wicht.com/posts/2016/04/simplify-deep-learning-library-usage-on-linux-and-windows.html#rest_code_6281cd2116f64ae5b3d85bb0deeec891-1"&gt;&lt;/a&gt;docker&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;/c/Users/Baptiste/rbm_mnist/:/dll/data&lt;span class="w"&gt; &lt;/span&gt;wichtounet/docker-dll
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will automatically run the actions specified in the configuration file and
train your network.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I would really have thought this would be harder, but it turned out that Docker
is a very good solution to deploy multiplatform demo tools :)&lt;/p&gt;
&lt;p&gt;As of now, there is only support for mnist data format in the tool in this
form, but I plan to add basic CSV support as well in the near future.&lt;/p&gt;
&lt;p&gt;I hope that this will help people willing to try the library with a simpler
usage.&lt;/p&gt;
&lt;/section&gt;</description><category>Deep Learning</category><category>dll</category><category>Linux</category><category>Machine Learning</category><category>projects</category><category>Windows</category><guid>https://baptiste-wicht.com/posts/2016/04/simplify-deep-learning-library-usage-on-linux-and-windows.html</guid><pubDate>Fri, 29 Apr 2016 10:48:18 GMT</pubDate></item><item><title>How to speed up RAID (5-6) growing with mdadm ?</title><link>https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;Yesterday, I added my 11th disk to my RAID 6 array. As the last time it took my more than 20 hours, I spent some time investigating how to speed things up and this post contains some tips on how to achieve good grow performances. With these tips, I have been able to reach a speed of about 55K in average during reshape. It did finish in about 13 hours.&lt;/p&gt;
&lt;p&gt;First, take into account that some of these tips may depend on your configuration. In my case, this server is only used for this RAID, so I don't care if the CPU is used a lot during rebuild or if other processes are suffering from the load. This may not be the case with your configuration. Moreover, I speak only of hard disks, if you use SSD RAID, there are probably better way of tuning the rebuild (or perhaps it is fast enough). Finally, you have know that a RAID reshape is going to be slow, there is no way you'll grow a 10+ RAID array in one hour. G&lt;/p&gt;
&lt;p&gt;In the examples, I use /dev/md0 as the raid array, you'll have to change this to your array name.&lt;/p&gt;
&lt;p&gt;The first 3 tips can be used even after the rebuild has started and you should see the differences in real-time. But, these 3 tips will also be erased after each reboot.&lt;/p&gt;
&lt;section id="increase-speed-limits"&gt;
&lt;h2&gt;Increase speed limits&lt;/h2&gt;
&lt;p&gt;The easiest thing to do is to increase the system speed limits on raid. You can see the current limits on your system by using these commands:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_73c0616f189845d593c71590dd8359b9-1" name="rest_code_73c0616f189845d593c71590dd8359b9-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_73c0616f189845d593c71590dd8359b9-1"&gt;&lt;/a&gt;sysctl&lt;span class="w"&gt; &lt;/span&gt;dev.raid.speed_limit_min
&lt;a id="rest_code_73c0616f189845d593c71590dd8359b9-2" name="rest_code_73c0616f189845d593c71590dd8359b9-2" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_73c0616f189845d593c71590dd8359b9-2"&gt;&lt;/a&gt;sysctl&lt;span class="w"&gt; &lt;/span&gt;dev.raid.speed_limit_max
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These values are set in Kibibytes per second (KiB/s).&lt;/p&gt;
&lt;p&gt;You can put them to high values:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_27652c020e9a4297a1670735cca3ac92-1" name="rest_code_27652c020e9a4297a1670735cca3ac92-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_27652c020e9a4297a1670735cca3ac92-1"&gt;&lt;/a&gt;sysctl&lt;span class="w"&gt; &lt;/span&gt;-w&lt;span class="w"&gt; &lt;/span&gt;dev.raid.speed_limit_min&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;100000&lt;/span&gt;
&lt;a id="rest_code_27652c020e9a4297a1670735cca3ac92-2" name="rest_code_27652c020e9a4297a1670735cca3ac92-2" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_27652c020e9a4297a1670735cca3ac92-2"&gt;&lt;/a&gt;sysctl&lt;span class="w"&gt; &lt;/span&gt;-w&lt;span class="w"&gt; &lt;/span&gt;dev.raid.speed_limit_max&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;500000&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At least with these values, you won't be limited by the system.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="increase-stripe-cache-size"&gt;
&lt;h2&gt;Increase stripe cache size&lt;/h2&gt;
&lt;p&gt;By allowing the array to use more memory for its stripe cache, you may improve the performances. In some cases, it can improve performances by up to 6 times. By default, the size of the stripe cache is 256, in pages. By default, Linux uses 4096B pages. If you use 256 pages for the stripe cache and you have 10 disks, the cache would use 10*256*4096=10MiB of RAM. In my case, I have increased it to 4096:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_66e378e68ae847f6874d2c8184f0d8f9-1" name="rest_code_66e378e68ae847f6874d2c8184f0d8f9-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_66e378e68ae847f6874d2c8184f0d8f9-1"&gt;&lt;/a&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/sys/block/md0/md/stripe_cache_size
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The maximum value is 32768. If you have many disks, this may well take all your available memory. I don't think values higher than 4096 will improve performance, but feel free to try it ;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="increase-read-ahead"&gt;
&lt;h2&gt;Increase read-ahead&lt;/h2&gt;
&lt;p&gt;If configured too low, the read-ahead of your array may make things slower.&lt;/p&gt;
&lt;p&gt;You can see get the current read-ahead value with this command:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_cb7b70ae323949c4b2ce5189e109b1c9-1" name="rest_code_cb7b70ae323949c4b2ce5189e109b1c9-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_cb7b70ae323949c4b2ce5189e109b1c9-1"&gt;&lt;/a&gt;blockdev&lt;span class="w"&gt; &lt;/span&gt;--getra&lt;span class="w"&gt; &lt;/span&gt;/dev/md0
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These values are in 512B sector. You can set it to 32MB to be sure:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_b18c162926514167937c27c38b2fc9f3-1" name="rest_code_b18c162926514167937c27c38b2fc9f3-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_b18c162926514167937c27c38b2fc9f3-1"&gt;&lt;/a&gt;blockdev&lt;span class="w"&gt; &lt;/span&gt;--setra&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;65536&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/md0
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This can improve the performances, but don't expect this to be a game-changer unless it was configured really low at the first place.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="tip-reshape-stuck-at-0k-s"&gt;
&lt;h2&gt;Tip: Reshape stuck at 0K/s&lt;/h2&gt;
&lt;p&gt;If reshape starts, but with a speed of 0K/s, you can try to issue this simple
command:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_140aa1cae58d4ad8a610dbca9a603785-1" name="rest_code_140aa1cae58d4ad8a610dbca9a603785-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_140aa1cae58d4ad8a610dbca9a603785-1"&gt;&lt;/a&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;max&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/sys/block/md0/md/sync_max
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the reshape should start directly at your maximum speed.&lt;/p&gt;
&lt;p&gt;The solution is the same if you are growing any type of RAID level with parity
(RAID5, RAID6, ...).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="bonus-speed-up-standard-resync-with-a-write-intent-bitmap"&gt;
&lt;h2&gt;Bonus: Speed up standard resync with a write-intent bitmap&lt;/h2&gt;
&lt;p&gt;Although it won't speed up the growing of your array, this is something that you should do after the rebuild has finished. Write-intent bitmaps is a kind of map of what needs to be resynced. This is of great help in several cases:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When the computer crash (power shutdown for instance)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a disk is disconnected, then reconnected.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In these case, it may totally avoid the need of a rebuild which is great in my opinion. Moreover, it does not take any space on the array since it uses space that is not usable by the array.&lt;/p&gt;
&lt;p&gt;Here is how to enable it:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_fb3debc17f3a441ab6a3b8fef8576a63-1" name="rest_code_fb3debc17f3a441ab6a3b8fef8576a63-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_fb3debc17f3a441ab6a3b8fef8576a63-1"&gt;&lt;/a&gt;mdadm&lt;span class="w"&gt; &lt;/span&gt;--grow&lt;span class="w"&gt; &lt;/span&gt;--bitmap&lt;span class="o"&gt;=&lt;/span&gt;internal&lt;span class="w"&gt; &lt;/span&gt;/dev/md0
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, it may cause some write performance degradation. In my case, I haven't seen any noticeable degradation, but if it is the case, you may want to disable it:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_4311022bcdf74bccb92a3aac7c2a4ac5-1" name="rest_code_4311022bcdf74bccb92a3aac7c2a4ac5-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_4311022bcdf74bccb92a3aac7c2a4ac5-1"&gt;&lt;/a&gt;mdadm&lt;span class="w"&gt; &lt;/span&gt;--grow&lt;span class="w"&gt; &lt;/span&gt;--bitmap&lt;span class="o"&gt;=&lt;/span&gt;none&lt;span class="w"&gt; &lt;/span&gt;/dev/md0
&lt;/pre&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id="bonus-monitor-rebuild-process"&gt;
&lt;h2&gt;Bonus: Monitor rebuild process&lt;/h2&gt;
&lt;p&gt;If you want to monitor the build process, you can use the watch command:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_96fae86c926d4247a8544e7575442672-1" name="rest_code_96fae86c926d4247a8544e7575442672-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_96fae86c926d4247a8544e7575442672-1"&gt;&lt;/a&gt;watch&lt;span class="w"&gt; &lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;/proc/mdstat
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With that you'll see the rebuild going in real-time.&lt;/p&gt;
&lt;p&gt;You can also monitor the I/O statistics:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_3509ad975da34197bc53a32fa894ed4f-1" name="rest_code_3509ad975da34197bc53a32fa894ed4f-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_3509ad975da34197bc53a32fa894ed4f-1"&gt;&lt;/a&gt;watch&lt;span class="w"&gt; &lt;/span&gt;iostat&lt;span class="w"&gt; &lt;/span&gt;-k&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id="bonus-how-to-grow-a-raid-5-6-array"&gt;
&lt;h2&gt;Bonus: How to grow a RAID 5-6 array&lt;/h2&gt;
&lt;p&gt;As a sidenote, this section indicates how to grow an array. If you  want to add the disk /dev/sdl to the array /dev/md0, you'll first have to add it:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_a251a6ac966b4baca93657cef72fcd68-1" name="rest_code_a251a6ac966b4baca93657cef72fcd68-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_a251a6ac966b4baca93657cef72fcd68-1"&gt;&lt;/a&gt;mdadm&lt;span class="w"&gt; &lt;/span&gt;--add&lt;span class="w"&gt; &lt;/span&gt;/dev/md0&lt;span class="w"&gt; &lt;/span&gt;/dev/sdl
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will add the disk as a spare disk. If you had 5 disks before, you'll want to grow it to 6:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_01276e4a1b094bfea76f87b9350bf65b-1" name="rest_code_01276e4a1b094bfea76f87b9350bf65b-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_01276e4a1b094bfea76f87b9350bf65b-1"&gt;&lt;/a&gt;mdadm&lt;span class="w"&gt; &lt;/span&gt;--grow&lt;span class="w"&gt; &lt;/span&gt;--backup-file&lt;span class="o"&gt;=&lt;/span&gt;/root/grow_md0_backup_file&lt;span class="w"&gt; &lt;/span&gt;--raid-devices&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/md0
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The backup file must be on another disk of course. The backup file is optional but improves the chance of success if you have a power shutdown or another form of unexpected shutdown. If you know what you're doing, you can grow it without backup-file:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_658a1b2a7f4e414899657fe7faa63681-1" name="rest_code_658a1b2a7f4e414899657fe7faa63681-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_658a1b2a7f4e414899657fe7faa63681-1"&gt;&lt;/a&gt;mdadm&lt;span class="w"&gt; &lt;/span&gt;--grow&lt;span class="w"&gt; &lt;/span&gt;--raid-devices&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/dev/md0
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This command will return almost instantly, but the actual reshape won't likely be finished for hours (maybe days).&lt;/p&gt;
&lt;p&gt;Once the rebuild is finished, you'll still have to extend the partitions with resize2fs. If you use LVM on top of the array, you'll have to resize the Physical Volume (PV) first:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_d26c05c77a7144e58829b9c8844c3d2d-1" name="rest_code_d26c05c77a7144e58829b9c8844c3d2d-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_d26c05c77a7144e58829b9c8844c3d2d-1"&gt;&lt;/a&gt;pvresize&lt;span class="w"&gt; &lt;/span&gt;/dev/md0
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and then extend the Logical Volume (s) (LV). For instance, if you want to add 1T to a LV named /dev/vgraid/work:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code bash"&gt;&lt;a id="rest_code_fdd699a716b44ac98097dc51db10b87a-1" name="rest_code_fdd699a716b44ac98097dc51db10b87a-1" href="https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html#rest_code_fdd699a716b44ac98097dc51db10b87a-1"&gt;&lt;/a&gt;vgextend&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;-L+1T&lt;span class="w"&gt; &lt;/span&gt;/dev/vgraid/work
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The -r option will automatically resize the underlying filesystem. Otherwise, you'd still have to resize it with resize2fs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;These are the changes I have found that speed up the reshape process. There are others that you may test in your case. For instance, in some systems disabling NCQ on each disk may help.&lt;/p&gt;
&lt;p&gt;I hope that these tips will help you doing fast rebuilds in your RAID array :)&lt;/p&gt;
&lt;/section&gt;</description><category>Gentoo</category><category>Hardware</category><category>Home Server</category><category>Linux</category><category>LVM</category><guid>https://baptiste-wicht.com/posts/2015/03/how-to-speed-up-raid-5-6-growing-with-mdadm.html</guid><pubDate>Sat, 07 Mar 2015 14:01:56 GMT</pubDate></item><item><title>Linux tip: Force systemd networkd to wait for DHCP</title><link>https://baptiste-wicht.com/posts/2014/10/linux-tip-force-systemd-networkd-to-wait-for-dhcp.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;Recently, I started using systemd-networkd to manage my network. It works really
good for static address configuration, but I experienced some problem with DHCP.
There is DHCP client support integrated into systemd, so I wanted to use this
instead of using another DHCP client.&lt;/p&gt;
&lt;p&gt;(If you are not familiar with systemd-networkd, you can have a look at the last
section of this article)&lt;/p&gt;
&lt;p&gt;The problem with that is that services are not waiting for DHCP leases to be
obtained. Most services (sshd for instance), are waiting for network.target,
however, network.target does not wait for the DHCP lease to be obtained from the
server. If you configured ssh on a specific IP and this IP is obtained with
DHCP, it will fail at startup. The same is true for NFS mounts for instance.&lt;/p&gt;
&lt;section id="force-services-to-wait-for-the-network-to-be-configured"&gt;
&lt;h2&gt;Force services to wait for the network to be configured&lt;/h2&gt;
&lt;p&gt;The solution is to make services like sshd waits for network-online.target
instead of network.target. There is a simple way in systemd to override default
service files. For a X.service, systemd will also parse all the
/etc/systemd/X.service.d/*.conf files.&lt;/p&gt;
&lt;p&gt;For instance, to make sshd be started only after DHCP is finished&lt;/p&gt;
&lt;p&gt;/etc/systemd/system/sshd.service.d/network.conf:&lt;/p&gt;
&lt;pre class="literal-block"&gt;[Unit]
Wants=network-online.target
After=network-online.target&lt;/pre&gt;
&lt;p&gt;However, by default, network-online.target does not wait for anything. You'll
have to enable another service to make it work:&lt;/p&gt;
&lt;pre class="literal-block"&gt;systemctl enable systemd-networkd-wait-online&lt;/pre&gt;
&lt;p&gt;And another note, at least on Gentoo, I had to use systemd-216 for it to work:&lt;/p&gt;
&lt;pre class="literal-block"&gt;emerge -a "=sys-apps/systemd-216"&lt;/pre&gt;
&lt;p&gt;And after this, it worked like a charm at startup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="force-nfs-mounts-to-wait-for-the-network"&gt;
&lt;h2&gt;Force NFS mounts to wait for the network&lt;/h2&gt;
&lt;p&gt;There is no service file for nfs mounts, but there is a target remote-fs.target
that groups the remote file systems mounts. You can override its configuration
in the same as a service:&lt;/p&gt;
&lt;p&gt;/etc/systemd/system/remote-fs.target.d/network.conf:&lt;/p&gt;
&lt;pre class="literal-block"&gt;[Unit]
Wants=network-online.target
After=network-online.target&lt;/pre&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Here we are, I hope this tip will be useful to some of you ;)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="appendix-configure-interface-with-dhcp-with-systemd"&gt;
&lt;h2&gt;Appendix. Configure interface with DHCP with systemd&lt;/h2&gt;
&lt;p&gt;To configure an interface with DHCP, you have to create a .network file in
/etc/systemd/network/. For instance, here is my
/etc/systemd/network/local.network file:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_482ea518a17b4891a51e7db29e7dce3b-1" name="rest_code_482ea518a17b4891a51e7db29e7dce3b-1" href="https://baptiste-wicht.com/posts/2014/10/linux-tip-force-systemd-networkd-to-wait-for-dhcp.html#rest_code_482ea518a17b4891a51e7db29e7dce3b-1"&gt;&lt;/a&gt;[Match]
&lt;a id="rest_code_482ea518a17b4891a51e7db29e7dce3b-2" name="rest_code_482ea518a17b4891a51e7db29e7dce3b-2" href="https://baptiste-wicht.com/posts/2014/10/linux-tip-force-systemd-networkd-to-wait-for-dhcp.html#rest_code_482ea518a17b4891a51e7db29e7dce3b-2"&gt;&lt;/a&gt;Name=enp3s0
&lt;a id="rest_code_482ea518a17b4891a51e7db29e7dce3b-3" name="rest_code_482ea518a17b4891a51e7db29e7dce3b-3" href="https://baptiste-wicht.com/posts/2014/10/linux-tip-force-systemd-networkd-to-wait-for-dhcp.html#rest_code_482ea518a17b4891a51e7db29e7dce3b-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_482ea518a17b4891a51e7db29e7dce3b-4" name="rest_code_482ea518a17b4891a51e7db29e7dce3b-4" href="https://baptiste-wicht.com/posts/2014/10/linux-tip-force-systemd-networkd-to-wait-for-dhcp.html#rest_code_482ea518a17b4891a51e7db29e7dce3b-4"&gt;&lt;/a&gt;[Network]
&lt;a id="rest_code_482ea518a17b4891a51e7db29e7dce3b-5" name="rest_code_482ea518a17b4891a51e7db29e7dce3b-5" href="https://baptiste-wicht.com/posts/2014/10/linux-tip-force-systemd-networkd-to-wait-for-dhcp.html#rest_code_482ea518a17b4891a51e7db29e7dce3b-5"&gt;&lt;/a&gt;DHCP=v4
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and you have to enable systemd-networkd:&lt;/p&gt;
&lt;pre class="literal-block"&gt;systemctl enable systemd-networkd&lt;/pre&gt;
&lt;/section&gt;</description><category>Gentoo</category><category>Linux</category><category>Network</category><category>systemd</category><category>Tips</category><guid>https://baptiste-wicht.com/posts/2014/10/linux-tip-force-systemd-networkd-to-wait-for-dhcp.html</guid><pubDate>Wed, 01 Oct 2014 18:18:55 GMT</pubDate></item><item><title>budgetwarrior 0.4.1 - Expense templates and year projection</title><link>https://baptiste-wicht.com/posts/2014/09/budgetwarrior-041-expense-templates-and-year-projection.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I've been able to finish the version 0.4.1 of budgetwarrior before I though :)&lt;/p&gt;
&lt;section id="expense-templates"&gt;
&lt;h2&gt;Expense templates&lt;/h2&gt;
&lt;p&gt;The "most useful" new feature of this release is the ability to create template
for expenses.&lt;/p&gt;
&lt;p&gt;For that, you can give an extra parameter to budget expense add:&lt;/p&gt;
&lt;pre class="literal-block"&gt;budget expense add template name&lt;/pre&gt;
&lt;p&gt;This will works exactly the same as creating a new expense expect that it will
be saved as a template. Then, the next time you do:&lt;/p&gt;
&lt;pre class="literal-block"&gt;budget expense add template name&lt;/pre&gt;
&lt;p&gt;A new expense will be created with the date of the day and with the name and
amount saved into the template. You can create as many templates as you want as
long as they have different names. You can see all the templates you have by
using 'budget expense template'. A template can be deleted the exact same as an
expense with 'budget expense delete id'.&lt;/p&gt;
&lt;p&gt;I think this is very useful for expense that are made several times a month, for
instance a coffee at your workplace. The price should not change a lot and it is
faster to just use the template name rather than entering all the information
again.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="year-prediction"&gt;
&lt;h2&gt;Year prediction&lt;/h2&gt;
&lt;p&gt;You can now see what would be next year if you changed a bit your expenses. For
instance, how much would you still have at the end of the year if you increased
your house expenses by 20% and reduced your insurances by 5% ?&lt;/p&gt;
&lt;p&gt;The 'budget predict' can be used for that purpose. You can enter a multiplier
for each account in your budget and a new year will be "predicted" based on
the expenses of the current year multiplied by the specified multiplier:&lt;/p&gt;
&lt;img alt="/images/budget_041_prediction.png" src="https://baptiste-wicht.com/images/budget_041_prediction.png"&gt;
&lt;p&gt;I think that this feature can be very useful if you want to estimate how your
budget will be for moving to a more expensive house or another insurance for
instance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="various-changes"&gt;
&lt;h2&gt;Various changes&lt;/h2&gt;
&lt;p&gt;Two accounts can be merged together with the 'budget account migrate' command.
This command will move all expenses from an account to another and adapt the
amount of the target account. The source account will be deleted. This supports
migrated accounts.&lt;/p&gt;
&lt;p&gt;The 'budget wish list' command will now display the mean accuracy of your
predictions.&lt;/p&gt;
&lt;p&gt;You don't need Boost anymore for this project. The only remaining dependency is
libuuid. I will perhaps remove it in the next version since the UUID are not
used in the application for now.&lt;/p&gt;
&lt;p&gt;The command 'budget gc' will clean the IDs of all your data in order to fill the
holes and make all the IDs contiguous. It is mostly a feature for order-freaks
like me who do not like to have holes in a sequence of identifiers ;)&lt;/p&gt;
&lt;p&gt;There was a bug in the monthly report causing the scale to be displayed
completely moved, it is now fixed:&lt;/p&gt;
&lt;img alt="https://raw.githubusercontent.com/wichtounet/budgetwarrior/develop/screenshots/budget_report.png" src="https://raw.githubusercontent.com/wichtounet/budgetwarrior/develop/screenshots/budget_report.png"&gt;
&lt;/section&gt;
&lt;section id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;If you are on Gentoo, you can install it using layman:&lt;/p&gt;
&lt;pre class="literal-block"&gt;layman -a wichtounet
emerge -a budgetwarrior&lt;/pre&gt;
&lt;p&gt;If you are on Arch Linux, you can use this &lt;a class="reference external" href="https://github.com/StreakyCobra/aur"&gt;AUR repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For other systems, you'll have to install from sources:&lt;/p&gt;
&lt;pre class="literal-block"&gt;git clone git://github.com/wichtounet/budgetwarrior.git
cd budgetwarrior
make
sudo make install&lt;/pre&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you are interested by the sources, you can download them on Github:
&lt;a class="reference external" href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have a suggestion for a new features or you found a bug, please post an
issue on Github, I'd be glad to help you.&lt;/p&gt;
&lt;p&gt;If you have any comment, don't hesitate to contact me, either by letting a
comment on this post or by email.&lt;/p&gt;
&lt;/section&gt;</description><category>budgetwarrior</category><category>C++</category><category>Gentoo</category><category>Linux</category><category>Releases</category><guid>https://baptiste-wicht.com/posts/2014/09/budgetwarrior-041-expense-templates-and-year-projection.html</guid><pubDate>Sun, 21 Sep 2014 18:53:53 GMT</pubDate></item><item><title>A Mutt journey: Search mails with notmuch</title><link>https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;In the previous installment in the Mutt series, &lt;a class="reference external" href="http://baptiste-wicht.com/posts/2014/07/a-mutt-journey-my-mutt-configuration.html"&gt;I've talked about my Mutt
configuration&lt;/a&gt;.
In this post, I'll talk about notmuch and how to use it to search through mails.&lt;/p&gt;
&lt;p&gt;By default, you can search mails in Mutt by using the / key. By doing that, you
can only search in the current folder. This is very fast, but this is not always
what you want. When you don't know in which folder the mail you are looking for
is, you don't want to test each folder. By default, there are no feature to
achieve global searching in Mutt.&lt;/p&gt;
&lt;p&gt;That is where notmuch comes to the rescue. notmuch is a very simple tool that
allows you to search through your mail. As its name indicates, it does not do
much. It doesn't download your mails, you have to have them locally, which is
perfect &lt;a class="reference external" href="http://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html"&gt;if you use offlineimap&lt;/a&gt;.
It does not provide a user interface, but you can query it from the command line
and it can be used from other tools. It should be available in most of the
distributions.&lt;/p&gt;
&lt;section id="configuration"&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The configuration of notmuch is fairly simple. You can write your
&lt;code&gt;.notmuch-config&lt;/code&gt; directly or run &lt;code&gt;notmuch setup&lt;/code&gt; that will
interactively help you to fill the configuration.&lt;/p&gt;
&lt;p&gt;Here is my configuration:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-1" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-1" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-1"&gt;&lt;/a&gt;[database]
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-2" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-2" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-2"&gt;&lt;/a&gt;path=/data/oi/Gmail/
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-3" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-3" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-4" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-4" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-4"&gt;&lt;/a&gt;[user]
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-5" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-5" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-5"&gt;&lt;/a&gt;name=Baptiste Wicht
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-6" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-6" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-6"&gt;&lt;/a&gt;primary_email=baptiste.wicht@gmail.com
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-7" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-7" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-7"&gt;&lt;/a&gt;
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-8" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-8" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-8"&gt;&lt;/a&gt;[new]
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-9" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-9" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-9"&gt;&lt;/a&gt;tags=inbox
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-10" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-10" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-10"&gt;&lt;/a&gt;ignore=
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-11" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-11" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-11"&gt;&lt;/a&gt;
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-12" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-12" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-12"&gt;&lt;/a&gt;[search]
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-13" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-13" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-13"&gt;&lt;/a&gt;exclude_tags=deleted;
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-14" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-14" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-14"&gt;&lt;/a&gt;
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-15" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-15" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-15"&gt;&lt;/a&gt;[maildir]
&lt;a id="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-16" name="rest_code_0532b396a3fb4dc3ac4366754c38f8ba-16" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_0532b396a3fb4dc3ac4366754c38f8ba-16"&gt;&lt;/a&gt;synchronize_flags=true
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It needs of cours the place where your mails are stored. Then, some information
about you. The next section is to specify which tags you want to add to new
mails. Here, I specified that each new mail must be tagged with &lt;cite&gt;inbox&lt;/cite&gt;. You can
add several tags to new mails. In the &lt;cite&gt;[search]&lt;/cite&gt; section, the excluded tags are
specified.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="usage"&gt;
&lt;h2&gt;Usage&lt;/h2&gt;
&lt;p&gt;Once you have configured notmuch, you can run &lt;cite&gt;notmuch new&lt;/cite&gt; to process all
existing mails. The first run may take some time (in minutes, it is still quite
fast), but the subsequent runs will be very fast. You should run notmuch after
each offlineimap run. I personally run it in a shell script that is run by cron.
You could also use one of the hooks of offlineimap to run notmuch.&lt;/p&gt;
&lt;p&gt;Once indexing has been done, you can start searching your mails. The first
option to search mail is simply to use &lt;cite&gt;notmuch search &amp;lt;query&amp;gt;&lt;/cite&gt; from the command
line. This will directly displays the results. Search is instant on my mails.&lt;/p&gt;
&lt;p&gt;If you use mutt-kz like me, notmuch support is directly integrated. You can type
X, and then type your query like &lt;code&gt;notmuch://?query=X&lt;/code&gt; and the results will
be displayed as a normal Mutt folder. You can open mails directly from here and
you can also edit the mails as if you were in their source folders. This is
really practical.&lt;/p&gt;
&lt;p&gt;If you use mutt, you can have the same experience, by using the &lt;cite&gt;notmuch-mutt&lt;/cite&gt;
patch (&lt;cite&gt;here &amp;lt;http://notmuchmail.org/notmuch-mutt/&amp;gt;&lt;/cite&gt;). In several distributions,
there is an option to build it with this support or another package to add the
feature.&lt;/p&gt;
&lt;p&gt;Another feature of notmuch is its ability to tag mails. It automatically tags
new mails and deleted mails. But you can also explicitely tag messages by using
&lt;code&gt;notmuch tag&lt;/code&gt;. For instance, to tag all messages from the notmuch mailing
list:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_ae433180bd83499b839943721522468a-1" name="rest_code_ae433180bd83499b839943721522468a-1" href="https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html#rest_code_ae433180bd83499b839943721522468a-1"&gt;&lt;/a&gt;notmuch tag +notmuch -- tag:new and to:notmuch@notmuchmail.org
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I personally don't use this feature since I use imapfilter and IMAP folders to
sort my mail, but it can be very useful. You can run these commands in the
cronjob and always have you tags up to date. Tags can then be used in notmuch to
search or to create virtual folder in Mutt.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That is already more or less everything that there is to know about notmuch. It
does not do a lot of thing, but it does them really well.&lt;/p&gt;
&lt;p&gt;That concludes the series of posts on Mutt. If you have any question on my Mutt
configuration, I'd be glad to extend on the comments.&lt;/p&gt;
&lt;/section&gt;</description><category>Gentoo</category><category>Gmail</category><category>Linux</category><category>Mutt</category><guid>https://baptiste-wicht.com/posts/2014/08/a-mutt-journey-search-mails-with-notmuch.html</guid><pubDate>Sat, 02 Aug 2014 15:24:12 GMT</pubDate></item><item><title>A Mutt journey: Mutt configuration</title><link>https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-my-mutt-configuration.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;If you've followed my Mutt posts, you'll know that I'm &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html"&gt;filtering my mails with
imapfilter&lt;/a&gt; and
&lt;a class="reference external" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html"&gt;downloading them with offlineimap&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this post, I'll share my Mutt configuration. I'm not using Mutt directly, but
mutt-kz which is a fork with good notmuch integration. For this post, it won't
change anything.&lt;/p&gt;
&lt;section id="configuration"&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;The complete configuration is made in the .muttrc file. Mutt configuration
supports the source command so that you can put some of your settings in another
files and source them from the .muttrc file. You'll see that the configuration
can soon grow large and therefore, splitting it in several files will save you a
lot of maintenance issues ;)&lt;/p&gt;
&lt;p&gt;First, let's tell Mutt who we are:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set from = "baptiste.wicht@gmail.com"
set realname = "Baptiste Wicht"&lt;/pre&gt;
&lt;/section&gt;
&lt;section id="receive-mail"&gt;
&lt;h2&gt;Receive mail&lt;/h2&gt;
&lt;p&gt;As I'm using offlineimap to get my mails, there is no IMAP settings in my
configuration. But you need to tell Mutt where the mails are:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set folder = /data/oi/

set spoolfile = "+Gmail/INBOX"
set postponed = "+Gmail/drafts"

source ~/.mutt/mailboxes&lt;/pre&gt;
&lt;p&gt;The spoolfile and postponed are specifying the inbox and draft mailboxes. The
.mutt/mailboxes file is generated by offlineimap.&lt;/p&gt;
&lt;p&gt;By default, Mutt will ask you to move read messages from INBOX to another
mailbox (set by mbox). I personally let my read messages in my inbox and move
them myself in a folder. For that, you have to disable the move:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set move = no&lt;/pre&gt;
&lt;p&gt;If you move a mail from a mailbox to another, Mutt will ask for confirmation,
you can disable this confirmation:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set confirmappend = no&lt;/pre&gt;
&lt;p&gt;If you use Mutt, you want to read plaintext messages rather than monstruous
HTML. You can tell Mutt to always open text plain if any:&lt;/p&gt;
&lt;pre class="literal-block"&gt;alternative_order text/plain text/html&lt;/pre&gt;
&lt;p&gt;If the mail has no text/plain part, you can manage to read HTML in Mutt in an
almost sane format. First, you need to tell Mutt to open html messages:&lt;/p&gt;
&lt;pre class="literal-block"&gt;auto_view text/html&lt;/pre&gt;
&lt;p&gt;And then, you need to tell it how to open it. Mutt reads a mailcap file to know
how to open content. You can tell Mutt where it is:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set mailcap_path = ~/.mailcap&lt;/pre&gt;
&lt;p&gt;And then, you have to edit the .mailcap file:&lt;/p&gt;
&lt;pre class="literal-block"&gt;text/html; w3m -I %{charset} -T text/html; copiousoutput;&lt;/pre&gt;
&lt;p&gt;That will use w3m to output the message inside Mutt. It works quite well. You
can also use linx if you prefer.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="send-mail"&gt;
&lt;h2&gt;Send mail&lt;/h2&gt;
&lt;p&gt;You need to indicate Mutt how to send mail:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set smtp_url = "smtp://baptistewicht@smtp.gmail.com:587/"
set smtp_pass = "SECRET"&lt;/pre&gt;
&lt;p&gt;Some people prefer to use another SMTP client instead of Mutt builtin SMTP
support, you can also do that by setting sendmail to the mailer program.&lt;/p&gt;
&lt;p&gt;It is generally a good idea to enforce the charset of sent mail:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set send_charset="utf-8"&lt;/pre&gt;
&lt;p&gt;You can choose another charset if you prefer ;)&lt;/p&gt;
&lt;p&gt;You need to configure vim to correctly handle mail editing:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set editor='vim + -c "set textwidth=72" -c "set wrap" -c "set spell spelllang=en"'&lt;/pre&gt;
&lt;p&gt;It sets the width of the text, enable wrap and configure spelling.&lt;/p&gt;
&lt;p&gt;By default, Mutt will ask you if you want to include the body of the message you
reply to in your answer and the reply subject. You can make that faster by using
these two lines:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set include=yes
set fast_reply&lt;/pre&gt;
&lt;p&gt;Once mail are sent, they are copied in your outgoing mailbox. If you use GMail,
the STMP server already does that for you, therefore you should disable this
behavior:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set copy = no&lt;/pre&gt;
&lt;/section&gt;
&lt;section id="appearance"&gt;
&lt;h2&gt;Appearance&lt;/h2&gt;
&lt;p&gt;Many things can also be configured in the appearance of Mutt. If you like the
threaded view of GMail, you want to configure Mutt in a similar way:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set sort = 'threads'
set sort_aux = 'reverse-last-date-received'&lt;/pre&gt;
&lt;p&gt;It is not as good as the GMail view, but it does the job :)&lt;/p&gt;
&lt;p&gt;You can make reading mail more comfortable using smart wrapping:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set smart_wrap&lt;/pre&gt;
&lt;p&gt;A mail has many many headers and you don't want to see them all:&lt;/p&gt;
&lt;pre class="literal-block"&gt;ignore *
unignore From To Reply-To Cc Bcc Subject Date Organization X-Label X-Mailer User-Agent&lt;/pre&gt;
&lt;p&gt;With that, you just configure which headers you're interested in.&lt;/p&gt;
&lt;p&gt;If you're using the sidebar patch (and you should be ;), you can configure the
sidebar:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set sidebar_visible = yes
set sidebar_width = 35
set sort_sidebar = desc

color sidebar_new yellow default&lt;/pre&gt;
&lt;p&gt;It makes the sidebar always visible with a width of 35 and sort the mailboxes.
The last line makes yellow the mailboxes that have unread mails.&lt;/p&gt;
&lt;p&gt;The index_format allows you to set what will shown for every mail in the index
view:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set index_format = "%4C %Z %{%b %d} %-15.15L %?M?(#%03M)&amp;amp;(%4l)? %?y?{%.20y}? %?g?{%.20g} ?%s (%c)"&lt;/pre&gt;
&lt;p&gt;This is a classical example that display the sender, the flags, the date, the
subject, the size of the mail and so on. You will need to look at the &lt;a class="reference external" href="http://www.mutt.org/doc/manual/manual-6.html"&gt;Reference&lt;/a&gt; to have more information on
what you can do with the format variables. There are plenty of information that
can be shown.&lt;/p&gt;
&lt;p&gt;You can also configure the text that is present on the status bar:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set status_chars  = " *%A"
set status_format = "───[ Folder: %f ]───[%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]───%&amp;gt;─%?p?( %p postponed )?───"&lt;/pre&gt;
&lt;p&gt;The example here displays the current folder, the number of mails in it with
some details on deleted and unread mails and finally the number of postponed
mail. Again, if you want more information, you can read the reference.&lt;/p&gt;
&lt;p&gt;You can configure Mutt so that the index view is always visible when you read
mails. For instance, to always show 8 mails in the index:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set pager_index_lines=8&lt;/pre&gt;
&lt;p&gt;Another important thing you can configure is the colors of Mutt. I'm not gonna
cover everything, since Mutt is very powerful on this part. For instance, here
are some examples from my configuration:&lt;/p&gt;
&lt;p&gt;color index         red             white           "~v~(~F)!~N"                # collapsed thread with flagged, no unread
color index         yellow          white           "~v~(~F~N)"                 # collapsed thread with some unread &amp;amp; flagged
color index_subject brightred       default         "~z &amp;gt;100K"
color header        blue            default         "^(Subject)"&lt;/p&gt;
&lt;p&gt;Unless you are really wanting to spend time on this part, I recommend to pick an
existing theme. I took a Solarized theme &lt;a class="reference external" href="https://github.com/altercation/mutt-colors-solarized"&gt;here&lt;/a&gt;. It looks quite good
and works well. There other themes available, you'll surely find the one that
looks best for you.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="bindings"&gt;
&lt;h2&gt;Bindings&lt;/h2&gt;
&lt;p&gt;Bindings are always very important. If like me, you're a vim aficionado, you'll
want your Mutt bindings to be as close as possible to vim. The default settings
are quite good, but not always close to vim.&lt;/p&gt;
&lt;p&gt;Something that is important to know when you configure Mutt bindings is that
they are relative to the current view open (index, pager,browser,attach, ...).
You can bind a keystroke to a different action in each view. You can also select
several views in which the keystroke is valid.&lt;/p&gt;
&lt;p&gt;If you are using the sidebar patch (and again, you should ;) ), you'll want to
configure fast bindings for it. Here are mine:&lt;/p&gt;
&lt;pre class="literal-block"&gt;bind index,pager \Ck sidebar-prev
bind index,pager \Cj sidebar-next
bind index,pager \Cl sidebar-open
bind index,pager \Cn sidebar-scroll-up
bind index,pager \Cv sidebar-scroll-down
bind index,pager \Ct sidebar-toggle&lt;/pre&gt;
&lt;p&gt;I use Ctrl+j,k to move inside the sidebar. I use Ctrl+l to open a folder and
Ctrl+n,v to scroll up and down. The last one is to toggle between multiple
sidebars for instance if you use notmuch.&lt;/p&gt;
&lt;p&gt;I find l very good to open messages in the index too:&lt;/p&gt;
&lt;pre class="literal-block"&gt;bind index l display-message
bind index gg first-entry
bind index G last-entry
bind index h noop               # Disable h&lt;/pre&gt;
&lt;p&gt;gg and G are used to go to the first and last element. Here I disabled h which
had a not often used command.&lt;/p&gt;
&lt;p&gt;The pager is the view where you read mail:&lt;/p&gt;
&lt;pre class="literal-block"&gt;bind pager h exit
bind pager gg top
bind pager G bottom
bind pager J next-line
bind pager K previous-line&lt;/pre&gt;
&lt;p&gt;In this view, I use h to get out of the pager, gg and G as usual. As I always
let the index open, I already use j and k to move in the index, so I chose J and
K to move in the pager.&lt;/p&gt;
&lt;p&gt;The browser is the view where you select folders for instance:&lt;/p&gt;
&lt;pre class="literal-block"&gt;bind browser l select-entry
bind browser L view-file
bind browser gg first-entry
bind browser G last-entry
bind browser h exit&lt;/pre&gt;
&lt;p&gt;Again, I use l and h to go back and forth and gg and G to go first and last. j
and k are already used here to go up and down.&lt;/p&gt;
&lt;p&gt;In the attach view:&lt;/p&gt;
&lt;pre class="literal-block"&gt;bind attach h exit
bind attach e edit-type # Edit MIME Types
bind attach l view-attach&lt;/pre&gt;
&lt;p&gt;I use h to exit and l to view an attachment.&lt;/p&gt;
&lt;p&gt;That is it for my bindings, but you configure a lot more of them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is the end of this post. I have covered my complete Mutt configuration
here. My .muttrc is available &lt;a class="reference external" href="https://github.com/wichtounet/dotfiles/blob/master/.muttrc"&gt;online&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have comments on my configuration, you're welcome to let a comment on
this post ;)&lt;/p&gt;
&lt;p&gt;In the next blog post about my "Mutt journey", I'll talk about notmuch and this
will likely be the last post on this series.&lt;/p&gt;
&lt;/section&gt;</description><category>Gentoo</category><category>Gmail</category><category>Linux</category><category>Mutt</category><guid>https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-my-mutt-configuration.html</guid><pubDate>Tue, 22 Jul 2014 20:14:32 GMT</pubDate></item><item><title>pm 0.1.1 - A simple workspace manager for Git projects</title><link>https://baptiste-wicht.com/posts/2014/07/pm-011-a-simple-workspace-manager-for-git-projects.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;In the last month, I've developped a very simple tool in Python: &lt;em&gt;pm&lt;/em&gt;. This tool
allows to check the status of all the Git repositories inside a repository. I've
just released the first version of this tool: pm-0.1.1&lt;/p&gt;
&lt;p&gt;Those who are following this blog will perhaps wonder why Python and not C++ :)
The reason is quite simple, I wanted to improve my skills in Python. And what is
better than to develop a project from scratch.&lt;/p&gt;
&lt;section id="features"&gt;
&lt;h2&gt;Features&lt;/h2&gt;
&lt;p&gt;The main feature of this application is to show the status of every projects in
a directory. The status of your projects can be queried by using &lt;code&gt;pm
status&lt;/code&gt;. On my computer this gives something like that:&lt;/p&gt;
&lt;img alt="/images/pm_status.png" src="https://baptiste-wicht.com/images/pm_status.png"&gt;
&lt;p&gt;The state of each branch of each project is shown. There different possible
status (they are cumulative):
* Behind remote: Commits are available on the remote repository
* Ahead of remote: Some local commits are no pushed
* Diverged: Behind and Ahead
* Uncomitted changes: Some changes are not committed
* Clean: Indicates that everything is committed, pushed and pull.&lt;/p&gt;
&lt;p&gt;By default, the directory is ~/dev/ but you can change it by passing the
repository to the command, if you pass a relative directory, it will be relative
to home. For instance, here is the status of my doc repositories:&lt;/p&gt;
&lt;img alt="/images/pm_status_2.png" src="https://baptiste-wicht.com/images/pm_status_2.png"&gt;
&lt;p&gt;Another feature that can be useful is that it is able to check the status of
submodules with the -s option:&lt;/p&gt;
&lt;img alt="/images/pm_status_sm.png" src="https://baptiste-wicht.com/images/pm_status_sm.png"&gt;
&lt;p&gt;As you can see it supports recursive submodules. For each submodule it will
indicate if there are new commits available or not.&lt;/p&gt;
&lt;p&gt;pm is not only able to show status of the projects, it can also fetch the status
of branches from remote by using &lt;code&gt;pm fetch&lt;/code&gt;. All the remote branches are
fetched from remote. It can also automatically update the projects that are
behind remote (equivalent of git pull) with &lt;code&gt;pm update&lt;/code&gt;. Only projects
that can be fast-forwarded are updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;Thanks to &lt;em&gt;pip&lt;/em&gt;, installation of pm is quite simple:&lt;/p&gt;
&lt;pre class="literal-block"&gt;pip install pm&lt;/pre&gt;
&lt;p&gt;If you don't want to use pip, you can install it by hand:&lt;/p&gt;
&lt;pre class="literal-block"&gt;wget https://github.com/wichtounet/pm/archive/0.1.1.tar.gz
tar xf 0.1.1.tar.gz
cd 0.1.1
python setup.py install&lt;/pre&gt;
&lt;p&gt;For those interested, source code is available &lt;a class="reference external" href="https://github.com/wichtounet/pm"&gt;on Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have any suggestion for the tool or on the source code, post a comment to
this post ;)&lt;/p&gt;
&lt;/section&gt;</description><category>Git</category><category>Linux</category><category>Python</category><category>Releases</category><guid>https://baptiste-wicht.com/posts/2014/07/pm-011-a-simple-workspace-manager-for-git-projects.html</guid><pubDate>Sun, 20 Jul 2014 18:52:18 GMT</pubDate></item><item><title>A Mutt Journey: Download mails with offlineimap</title><link>https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;In the series of posts about Mutt, I recently presented how I was &lt;a class="reference external" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html"&gt;filtering my email&lt;/a&gt;. In this
post, I'll show how I download my emails locally using offlineimap. This is the
perfect companion for Mutt.&lt;/p&gt;
&lt;p&gt;With Mutt, you can easily directly query an IMAP server and keep the views up to
date with it. There are a few problem with this approach:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;First, you wont' be able to read your mails when you'are offline. It is
rarely an issue in these days, but it can be useful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Opening an IMAP folder with a large number of mails (&amp;gt;1000) can be quite
slow. I've several large folders and it was a pain opening them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When Mutt synchronizes with the state of the IMAP server, you'll encounter a
freeze. If you want to synchronize often, it is quite boring.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Having your mails offline on your computers solves all these problems. Moreover,
it is also a good way to have a backup of your mails. I'm gonna talk here about
the usage for Mutt, but you can use offlineimap just for backup or for migration
reasons. The downside is that you have to store it locally. My mails takes
around 5GB on my computer.&lt;/p&gt;
&lt;p&gt;offlineimap is a very simple tool to synchronize emails from IMAP servers. It
only supports IMAP, but in those days it is not a limitation. The
synchronization is made both ways, it will upload your local changes to the IMAP
server. It is very powerful when paired with a MUA such as Mutt.&lt;/p&gt;
&lt;p&gt;To use offlineimap, you have to put your configuration in the ~/.offlineimaprc.
You can synchronize several accounts at once, in this post, we'll focus on one,
but the process is the same for several accounts. I'll focus on Gmail too, but
again it is the same with a bit different parameters for other mail accounts.&lt;/p&gt;
&lt;section id="configuration"&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;First, we have to declare the account:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_9fb08201c5cb40fd84976963d86bb79d-1" name="rest_code_9fb08201c5cb40fd84976963d86bb79d-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9fb08201c5cb40fd84976963d86bb79d-1"&gt;&lt;/a&gt;[general]
&lt;a id="rest_code_9fb08201c5cb40fd84976963d86bb79d-2" name="rest_code_9fb08201c5cb40fd84976963d86bb79d-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9fb08201c5cb40fd84976963d86bb79d-2"&gt;&lt;/a&gt;accounts = Gmail
&lt;a id="rest_code_9fb08201c5cb40fd84976963d86bb79d-3" name="rest_code_9fb08201c5cb40fd84976963d86bb79d-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9fb08201c5cb40fd84976963d86bb79d-3"&gt;&lt;/a&gt;
&lt;a id="rest_code_9fb08201c5cb40fd84976963d86bb79d-4" name="rest_code_9fb08201c5cb40fd84976963d86bb79d-4" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9fb08201c5cb40fd84976963d86bb79d-4"&gt;&lt;/a&gt;[Account Gmail]
&lt;a id="rest_code_9fb08201c5cb40fd84976963d86bb79d-5" name="rest_code_9fb08201c5cb40fd84976963d86bb79d-5" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9fb08201c5cb40fd84976963d86bb79d-5"&gt;&lt;/a&gt;localrepository = Gmail-Local
&lt;a id="rest_code_9fb08201c5cb40fd84976963d86bb79d-6" name="rest_code_9fb08201c5cb40fd84976963d86bb79d-6" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9fb08201c5cb40fd84976963d86bb79d-6"&gt;&lt;/a&gt;remoterepository = Gmail-Remote
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;accounts&lt;/strong&gt; is the list of accounts that we have, here only one. Then, in
account, repositories are just names of the repositories we'll declare now.&lt;/p&gt;
&lt;p&gt;The local repository has to be configured:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_e22eaced9014412b9f274a5ad49b7388-1" name="rest_code_e22eaced9014412b9f274a5ad49b7388-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_e22eaced9014412b9f274a5ad49b7388-1"&gt;&lt;/a&gt;[Repository Gmail-Local]
&lt;a id="rest_code_e22eaced9014412b9f274a5ad49b7388-2" name="rest_code_e22eaced9014412b9f274a5ad49b7388-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_e22eaced9014412b9f274a5ad49b7388-2"&gt;&lt;/a&gt;type = Maildir
&lt;a id="rest_code_e22eaced9014412b9f274a5ad49b7388-3" name="rest_code_e22eaced9014412b9f274a5ad49b7388-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_e22eaced9014412b9f274a5ad49b7388-3"&gt;&lt;/a&gt;localfolders = /data/oi/Gmail/
&lt;a id="rest_code_e22eaced9014412b9f274a5ad49b7388-4" name="rest_code_e22eaced9014412b9f274a5ad49b7388-4" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_e22eaced9014412b9f274a5ad49b7388-4"&gt;&lt;/a&gt;sep = /
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first important point is &lt;strong&gt;localfolders&lt;/strong&gt; that sets where the mail will be
put on your computer. &lt;strong&gt;sep&lt;/strong&gt; defines the separator used for nested IMAP
folders. I recommend / since Mutt will nest them automatically if / is used as
separator.&lt;/p&gt;
&lt;p&gt;Then, the remote repository has to be configured:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_9861571406e64145848463989edcea80-1" name="rest_code_9861571406e64145848463989edcea80-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-1"&gt;&lt;/a&gt;[Repository Gmail-Remote]
&lt;a id="rest_code_9861571406e64145848463989edcea80-2" name="rest_code_9861571406e64145848463989edcea80-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-2"&gt;&lt;/a&gt;type = Gmail
&lt;a id="rest_code_9861571406e64145848463989edcea80-3" name="rest_code_9861571406e64145848463989edcea80-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-3"&gt;&lt;/a&gt;remoteuser = USER
&lt;a id="rest_code_9861571406e64145848463989edcea80-4" name="rest_code_9861571406e64145848463989edcea80-4" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-4"&gt;&lt;/a&gt;remotepass = PASSWORD
&lt;a id="rest_code_9861571406e64145848463989edcea80-5" name="rest_code_9861571406e64145848463989edcea80-5" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-5"&gt;&lt;/a&gt;realdelete = no
&lt;a id="rest_code_9861571406e64145848463989edcea80-6" name="rest_code_9861571406e64145848463989edcea80-6" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-6"&gt;&lt;/a&gt;folderfilter = lambda folder: folder not in ['[Gmail]/All Mail',
&lt;a id="rest_code_9861571406e64145848463989edcea80-7" name="rest_code_9861571406e64145848463989edcea80-7" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-7"&gt;&lt;/a&gt;                                             '[Gmail]/Important',
&lt;a id="rest_code_9861571406e64145848463989edcea80-8" name="rest_code_9861571406e64145848463989edcea80-8" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-8"&gt;&lt;/a&gt;                                             '[Gmail]/Starred',
&lt;a id="rest_code_9861571406e64145848463989edcea80-9" name="rest_code_9861571406e64145848463989edcea80-9" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-9"&gt;&lt;/a&gt;                                             ]
&lt;a id="rest_code_9861571406e64145848463989edcea80-10" name="rest_code_9861571406e64145848463989edcea80-10" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_9861571406e64145848463989edcea80-10"&gt;&lt;/a&gt;sslcacertfile = /etc/ssl/certs/ca-certificates.crt
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;remotepass&lt;/strong&gt; and &lt;strong&gt;remoteuser&lt;/strong&gt; are your user names and password. You can also
use &lt;strong&gt;remotepassfile&lt;/strong&gt; to read the password from a file. &lt;strong&gt;realdelete=no&lt;/strong&gt;
indicates that we only want to remove all the labels of deleted mails. For
Gmail, it means that the mail will still be in the All Mail folder. The last
line (sslcacertfile) is mandatory for recent versions of offlineimap. The
&lt;strong&gt;folderfilter&lt;/strong&gt; is a function that filters some folders. In my case, I do not
want to get the "All Mail", "Important" and "Starred" of my Gmail account
because it is only a duplicata of the mails in other labels. What is pretty cool
with offlineimap is that you can write Python directly in it for some of the
configuration options. Here is rule for filter is plain Python, so you can
complicated filtering if you want.&lt;/p&gt;
&lt;p&gt;Last, but not least, offlineimap can generates a list of mailboxes (one for each
folder in every account). It is pretty useful since Mutt can then read this file
and you'll find your mailboxes directly configured in Mutt :)&lt;/p&gt;
&lt;p&gt;This code will generate a file ~/.mutt/mailboxes that you can source in your
Mutt configuration and get the complete list of available mailboxes. This will
be kept up to date if you add new IMAP folders on the server for instance.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_a92cbaee6d934b84864b18c97388988f-1" name="rest_code_a92cbaee6d934b84864b18c97388988f-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_a92cbaee6d934b84864b18c97388988f-1"&gt;&lt;/a&gt;[mbnames]
&lt;a id="rest_code_a92cbaee6d934b84864b18c97388988f-2" name="rest_code_a92cbaee6d934b84864b18c97388988f-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_a92cbaee6d934b84864b18c97388988f-2"&gt;&lt;/a&gt;enabled = yes
&lt;a id="rest_code_a92cbaee6d934b84864b18c97388988f-3" name="rest_code_a92cbaee6d934b84864b18c97388988f-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_a92cbaee6d934b84864b18c97388988f-3"&gt;&lt;/a&gt;filename = ~/.mutt/mailboxes
&lt;a id="rest_code_a92cbaee6d934b84864b18c97388988f-4" name="rest_code_a92cbaee6d934b84864b18c97388988f-4" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_a92cbaee6d934b84864b18c97388988f-4"&gt;&lt;/a&gt;header = "mailboxes "
&lt;a id="rest_code_a92cbaee6d934b84864b18c97388988f-5" name="rest_code_a92cbaee6d934b84864b18c97388988f-5" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_a92cbaee6d934b84864b18c97388988f-5"&gt;&lt;/a&gt;peritem = "+%(accountname)s/%(foldername)s"
&lt;a id="rest_code_a92cbaee6d934b84864b18c97388988f-6" name="rest_code_a92cbaee6d934b84864b18c97388988f-6" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_a92cbaee6d934b84864b18c97388988f-6"&gt;&lt;/a&gt;sep = " "
&lt;a id="rest_code_a92cbaee6d934b84864b18c97388988f-7" name="rest_code_a92cbaee6d934b84864b18c97388988f-7" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_a92cbaee6d934b84864b18c97388988f-7"&gt;&lt;/a&gt;footer = "\n"
&lt;/pre&gt;&lt;/div&gt;
&lt;/section&gt;
&lt;section id="translate-names"&gt;
&lt;h2&gt;Translate names&lt;/h2&gt;
&lt;p&gt;You may have seen in the previous section some weird folder name like
"[Gmail]/All mail", this is how Gmail names folders that are not labels. This is
quite ugly and will create odd looking folders on your computer. You can
configure offlineimap to rename these names to better ones. For that, you'll
need to rule (in Python ;) ), one to translate from remote to local and one to
do the reverse.&lt;/p&gt;
&lt;p&gt;Here is what I did:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code text"&gt;&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-1" name="rest_code_245eec60fddd43928eb0529581c56583-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-1"&gt;&lt;/a&gt;[Repository Gmail-Local]
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-2" name="rest_code_245eec60fddd43928eb0529581c56583-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-2"&gt;&lt;/a&gt;nametrans = lambda folder: {'drafts':   '[Gmail]/Drafts',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-3" name="rest_code_245eec60fddd43928eb0529581c56583-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-3"&gt;&lt;/a&gt;                            'sent':     '[Gmail]/Sent Mail',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-4" name="rest_code_245eec60fddd43928eb0529581c56583-4" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-4"&gt;&lt;/a&gt;                            'important':'[Gmail]/Important',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-5" name="rest_code_245eec60fddd43928eb0529581c56583-5" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-5"&gt;&lt;/a&gt;                            'spam':     '[Gmail]/Spam',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-6" name="rest_code_245eec60fddd43928eb0529581c56583-6" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-6"&gt;&lt;/a&gt;                            'starred':  '[Gmail]/Starred',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-7" name="rest_code_245eec60fddd43928eb0529581c56583-7" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-7"&gt;&lt;/a&gt;                            'trash':    '[Gmail]/Trash',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-8" name="rest_code_245eec60fddd43928eb0529581c56583-8" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-8"&gt;&lt;/a&gt;                            'archive':  '[Gmail]/All Mail',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-9" name="rest_code_245eec60fddd43928eb0529581c56583-9" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-9"&gt;&lt;/a&gt;                            }.get(folder, folder)
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-10" name="rest_code_245eec60fddd43928eb0529581c56583-10" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-10"&gt;&lt;/a&gt;
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-11" name="rest_code_245eec60fddd43928eb0529581c56583-11" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-11"&gt;&lt;/a&gt;[Repository Gmail-Remote]
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-12" name="rest_code_245eec60fddd43928eb0529581c56583-12" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-12"&gt;&lt;/a&gt;nametrans = lambda folder: {'[Gmail]/Drafts':    'drafts',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-13" name="rest_code_245eec60fddd43928eb0529581c56583-13" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-13"&gt;&lt;/a&gt;                            '[Gmail]/Sent Mail': 'sent',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-14" name="rest_code_245eec60fddd43928eb0529581c56583-14" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-14"&gt;&lt;/a&gt;                            '[Gmail]/Starred':   'flagged',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-15" name="rest_code_245eec60fddd43928eb0529581c56583-15" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-15"&gt;&lt;/a&gt;                            '[Gmail]/Important':   'important',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-16" name="rest_code_245eec60fddd43928eb0529581c56583-16" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-16"&gt;&lt;/a&gt;                            '[Gmail]/Spam':   'spam',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-17" name="rest_code_245eec60fddd43928eb0529581c56583-17" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-17"&gt;&lt;/a&gt;                            '[Gmail]/Trash':     'trash',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-18" name="rest_code_245eec60fddd43928eb0529581c56583-18" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-18"&gt;&lt;/a&gt;                            '[Gmail]/All Mail':  'archive',
&lt;a id="rest_code_245eec60fddd43928eb0529581c56583-19" name="rest_code_245eec60fddd43928eb0529581c56583-19" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html#rest_code_245eec60fddd43928eb0529581c56583-19"&gt;&lt;/a&gt;                            }.get(folder, folder)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I simply renamed all "[Gmail]" folders into something more readable and that
makes more sense to me. It is not limited to special Gmail folders of course,
this can also be applied to rename a folder X into a folder Y in the same. As it
is Python, you can do sophisticated stuff if necessary.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="speed-up-things"&gt;
&lt;h2&gt;Speed up things&lt;/h2&gt;
&lt;p&gt;If you happen to sync your mails often, you may want to speed things up. There
are several ways to do that.&lt;/p&gt;
&lt;p&gt;The first thing you can do is use several connections to the server. You can set
maxconnections to a number higher than 1 in the remote repository configuration.
I tested several values and for Gmail 2 was the fastest choice. You can try some
values with your server to see what value is good.&lt;/p&gt;
&lt;p&gt;Instead of plain old text files for the status of the mails, offlineimap can use
a sqlite backend. This is much faster since the complete file is not rewritten
for each update of the flags. For that behaviour, you have to set
&lt;strong&gt;status_backend = sqlite&lt;/strong&gt; in the Account configuration.&lt;/p&gt;
&lt;p&gt;Another thing you can do is reduce the I/O involved during sync by setting
general.fsync to false. With that, offlineimap won't have to wait for disk
operation completion after each operation.&lt;/p&gt;
&lt;p&gt;You can run offlineimap in quick mode with -q option. With this option, change
in flags of remote messages will not be updated locally. Changes on the local
side will be uploaded corectly. It is generally a good idea is to run
offlineimap in quick mode often (every X minutes) and run it in normal mode once
or twice a day.&lt;/p&gt;
&lt;p&gt;You can also specify which folder to sync with the -f option. Sometimes it is
enough to sync INBOX for instance. It may be much faster.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Now that you have fully configured offlineimap, you can make it run by hand or
in a cron job. I personally run it every 5 minutes, you can choose your
favourite frequency according to your workflow. I think I'll reduce the
frequency further, it is more comfortable to get mails only by batch and not
too much of them.&lt;/p&gt;
&lt;p&gt;If you're interested, you can take a look at &lt;a class="reference external" href="https://github.com/wichtounet/dotfiles/blob/master/.offlineimaprc"&gt;my .offlineimaprc configuration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want more information about this awesome tool, you can take a look at the
&lt;a class="reference external" href="http://docs.offlineimap.org/en/latest/"&gt;reference documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is it for this part of this series. In the next post, I'll present my Mutt
configuration and how I use it.&lt;/p&gt;
&lt;/section&gt;</description><category>Gentoo</category><category>Gmail</category><category>Linux</category><category>Mutt</category><category>Python</category><guid>https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-download-mails-with-offlineimap.html</guid><pubDate>Wed, 16 Jul 2014 17:54:40 GMT</pubDate></item><item><title>A Mutt Journey: Filter mails with imapfilter</title><link>https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;About a month ago, I decided to switch to Mutt to read my emails. I kept my
GMail account, but I don't use the web interface anymore. It took me a long time
to prepare a complete enviromnent.&lt;/p&gt;
&lt;p&gt;Currently, i'm using:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;imapfilter to filter mails&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;offlineimap to download my mails&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;notmuch to quickly search all my mails&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And of course Mutt. To be precise, I use mutt-kz, a fork of mutt with very good
notmuch integration.&lt;/p&gt;
&lt;p&gt;I'll try to explain each part of my environment in a series of articles on this
blog. The first one will be about imapfilter.&lt;/p&gt;
&lt;p&gt;imapfilter is a mail filtering utility. It connects to a remote server using
IMAP and is then able to move, copy or delete mails around. You can use it for
several tasks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Delete unwanted mail&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move mails into folders according to rules&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What is pretty cool is that the configuration is entirely made in Lua. It is
quite easy to write rules and then apply them to several mailboxes as if you
were programming.&lt;/p&gt;
&lt;p&gt;Another advantage of imapfilter is that it works at the server level. Therefore,
even if you use your web client from time to time or check your mail on your
phone, the changes will still be viewable.&lt;/p&gt;
&lt;p&gt;The configuration is done in the ~/.imapfilter/config.lua file. The
configuration is quite easy, you have to declare an IMAP object as the account.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code lua"&gt;&lt;a id="rest_code_7807a6f0641048789df68ccaa0436054-1" name="rest_code_7807a6f0641048789df68ccaa0436054-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_7807a6f0641048789df68ccaa0436054-1"&gt;&lt;/a&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;IMAP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_7807a6f0641048789df68ccaa0436054-2" name="rest_code_7807a6f0641048789df68ccaa0436054-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_7807a6f0641048789df68ccaa0436054-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'imap_sever'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_7807a6f0641048789df68ccaa0436054-3" name="rest_code_7807a6f0641048789df68ccaa0436054-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_7807a6f0641048789df68ccaa0436054-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_7807a6f0641048789df68ccaa0436054-4" name="rest_code_7807a6f0641048789df68ccaa0436054-4" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_7807a6f0641048789df68ccaa0436054-4"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_7807a6f0641048789df68ccaa0436054-5" name="rest_code_7807a6f0641048789df68ccaa0436054-5" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_7807a6f0641048789df68ccaa0436054-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;ssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'ssl3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_7807a6f0641048789df68ccaa0436054-6" name="rest_code_7807a6f0641048789df68ccaa0436054-6" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_7807a6f0641048789df68ccaa0436054-6"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As the configuration is in Lua, you can easily get the password from another
file. For instance, here is my account declaration:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code lua"&gt;&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-1" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-1"&gt;&lt;/a&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;IMAP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-2" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-2"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'imap.gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-3" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-3"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'baptiste.wicht@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-4" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-4" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-4"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;get_imap_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;".password.offlineimaprc"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-5" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-5" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-5"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;ssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'ssl3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-6" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-6" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-6"&gt;&lt;/a&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-7" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-7" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-7"&gt;&lt;/a&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-8" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-8" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-8"&gt;&lt;/a&gt;&lt;span class="c1"&gt;-- Utility function to get IMAP password from file&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-9" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-9" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-9"&gt;&lt;/a&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;get_imap_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-10" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-10" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-10"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;home&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;os.getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"HOME"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-11" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-11" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-11"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;home&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-12" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-12" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-12"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;io.open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-13" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-13" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-13"&gt;&lt;/a&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;a id="rest_code_ae01d1a888734f458e9a1439bc672fd8-14" name="rest_code_ae01d1a888734f458e9a1439bc672fd8-14" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_ae01d1a888734f458e9a1439bc672fd8-14"&gt;&lt;/a&gt;&lt;span class="kr"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It gets the password by reading a file in the home directory.&lt;/p&gt;
&lt;p&gt;Once, you have the account, you can check the status of a folder with the
check_status() function. For instance:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code lua"&gt;&lt;a id="rest_code_598a8cc4171047cdb2ab53817aec2202-1" name="rest_code_598a8cc4171047cdb2ab53817aec2202-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_598a8cc4171047cdb2ab53817aec2202-1"&gt;&lt;/a&gt;&lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;INBOX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;check_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_598a8cc4171047cdb2ab53817aec2202-2" name="rest_code_598a8cc4171047cdb2ab53817aec2202-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_598a8cc4171047cdb2ab53817aec2202-2"&gt;&lt;/a&gt;&lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'[Gmail]/Trash'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="nf"&gt;check_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can run imapfilter simply by launching imapfilter on the command line. Once
imapfilter is run, it will print the status of the folder you choses:&lt;/p&gt;
&lt;pre class="literal-block"&gt;38 messages, 0 recent, 6 unseen, in baptiste.wicht@gmail.com@imap.gmail.com/INBOX.
70 messages, 0 recent, 67 unseen, in baptiste.wicht@gmail.com@imap.gmail.com/[Gmail]/Trash.&lt;/pre&gt;
&lt;p&gt;Several functions are important:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;select_all() on a folder allows you to get messages from an account to them
perform action on them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;contain_subject('subject') on a list of mails allows you to keep only the mails
that contains 'subject' in their subject&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;contain_from('from') on a list of mails allows you to keep only the mails
that comes from 'from'&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;contain_to('to') on a list of mails allows you to keep only the mails
that are addressed to 'to'&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete_messages() on a collection of mails deletes all of them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;move_messages(folder) on a collection of mails moves all of them to another
folder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also mix different IMAP accounts, you don't have to use only one.&lt;/p&gt;
&lt;p&gt;For instance, if you would delete all the mail coming from me, you could do:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code lua"&gt;&lt;a id="rest_code_3b09e01b94354a239a37b35108c0c7d1-1" name="rest_code_3b09e01b94354a239a37b35108c0c7d1-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_3b09e01b94354a239a37b35108c0c7d1-1"&gt;&lt;/a&gt;&lt;span class="nv"&gt;mails&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;INBOX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;select_all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_3b09e01b94354a239a37b35108c0c7d1-2" name="rest_code_3b09e01b94354a239a37b35108c0c7d1-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_3b09e01b94354a239a37b35108c0c7d1-2"&gt;&lt;/a&gt;&lt;span class="nv"&gt;filtered&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;mails&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;contains_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"baptiste.wicht@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_3b09e01b94354a239a37b35108c0c7d1-3" name="rest_code_3b09e01b94354a239a37b35108c0c7d1-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_3b09e01b94354a239a37b35108c0c7d1-3"&gt;&lt;/a&gt;&lt;span class="nv"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;delete_messages&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or you could move all the mails containing Urgent in the subject line to an IMAP
folder:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code lua"&gt;&lt;a id="rest_code_cd123bd4438b4a55b6ac257fdcc38c37-1" name="rest_code_cd123bd4438b4a55b6ac257fdcc38c37-1" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_cd123bd4438b4a55b6ac257fdcc38c37-1"&gt;&lt;/a&gt;&lt;span class="nv"&gt;mails&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;INBOX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;select_all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;a id="rest_code_cd123bd4438b4a55b6ac257fdcc38c37-2" name="rest_code_cd123bd4438b4a55b6ac257fdcc38c37-2" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_cd123bd4438b4a55b6ac257fdcc38c37-2"&gt;&lt;/a&gt;&lt;span class="nv"&gt;filtered&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;mails&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;contains_subject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Urgent"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a id="rest_code_cd123bd4438b4a55b6ac257fdcc38c37-3" name="rest_code_cd123bd4438b4a55b6ac257fdcc38c37-3" href="https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html#rest_code_cd123bd4438b4a55b6ac257fdcc38c37-3"&gt;&lt;/a&gt;&lt;span class="nv"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;move_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"urgent_mails"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want some more examples, you can take a look at &lt;a class="reference external" href="https://github.com/wichtounet/dotfiles/blob/master/.imapfilter/config.lua"&gt;my imapfilter
configuration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The best way to start using it is to look at examples, there are plenty of them
in the internet, especially in Github dotfiles repositories.&lt;/p&gt;
&lt;p&gt;The reference documentation is available using 'man imapfilter_config', there is
plenty more to see.&lt;/p&gt;
&lt;p&gt;For more information, you can also consult the &lt;a class="reference external" href="https://github.com/lefcha/imapfilter"&gt;offical site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That is it for this part of the mutt series. In the next post about mutt, I'll
talk about how I use offlineimap to get my mails.&lt;/p&gt;</description><category>Gentoo</category><category>Gmail</category><category>Linux</category><category>Mutt</category><guid>https://baptiste-wicht.com/posts/2014/07/a-mutt-journey-filter-mails-with-imapfilter.html</guid><pubDate>Tue, 08 Jul 2014 18:58:32 GMT</pubDate></item><item><title>budgetwarrior 0.4 - Enhanced wish list and aggregate</title><link>https://baptiste-wicht.com/posts/2014/07/budgetwarrior-04-enhanced-wish-list-and-aggregate.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I've just released a new version of my command-line budget manager:
budgetwarrior 0.4.&lt;/p&gt;
&lt;section id="enhanced-aggregate-overview"&gt;
&lt;h2&gt;Enhanced aggregate overview&lt;/h2&gt;
&lt;p&gt;The aggregate overviews have been greatly improved. First, there is now a
&lt;em&gt;budget overview month&lt;/em&gt; command that groups all expenses of amonth together.
Here is a possible output:&lt;/p&gt;
&lt;img alt="/images/budget_04_aggregate_month.png" src="https://baptiste-wicht.com/images/budget_04_aggregate_month.png"&gt;
&lt;p&gt;It also possible to use &lt;em&gt;--full&lt;/em&gt; option to also aggregate together the different
accounts:&lt;/p&gt;
&lt;img alt="/images/budget_04_aggregate_month_full.png" src="https://baptiste-wicht.com/images/budget_04_aggregate_month_full.png"&gt;
&lt;p&gt;Another new option is &lt;em&gt;--no-group&lt;/em&gt; that disables the grouping by categories:&lt;/p&gt;
&lt;img alt="/images/budget_04_aggregate_month_full_ng.png" src="https://baptiste-wicht.com/images/budget_04_aggregate_month_full_ng.png"&gt;
&lt;p&gt;Moreover, the separator of categories can now be configured with &lt;em&gt;--separator=&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;All these options can also be set in the configuration with these options:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;aggregate_full : If set to true, does the same as the --full option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;aggregate_no_group : If set to true, does the same as the --no-group option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;aggregate_separator : Sets the separator for grouping.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="enhanced-wish-list"&gt;
&lt;h2&gt;Enhanced wish list&lt;/h2&gt;
&lt;p&gt;The wishes management has also been improved.&lt;/p&gt;
&lt;p&gt;First, each wish can now be set an Urgency and Importance level. This is now
shown in wish status as simple indicators:&lt;/p&gt;
&lt;img alt="/images/budget_04_wish_status.png" src="https://baptiste-wicht.com/images/budget_04_wish_status.png"&gt;
&lt;p&gt;Moreover, the accuracy of the estimation compared to the paid amount is shown in
&lt;em&gt;wish list&lt;/em&gt;:&lt;/p&gt;
&lt;img alt="/images/budget_04_wish_list.png" src="https://baptiste-wicht.com/images/budget_04_wish_list.png"&gt;
&lt;/section&gt;
&lt;section id="various-changes"&gt;
&lt;h2&gt;Various changes&lt;/h2&gt;
&lt;p&gt;Objective status now shows more information about the status of the objectives:&lt;/p&gt;
&lt;img alt="/images/budget_04_objective_status.png" src="https://baptiste-wicht.com/images/budget_04_objective_status.png"&gt;
&lt;p&gt;The versioning module has been improved. The &lt;em&gt;versioning sync&lt;/em&gt; does now perform
a commmit as well as pull/push. &lt;em&gt;versioning push&lt;/em&gt;, &lt;em&gt;versioning pull&lt;/em&gt; and
&lt;em&gt;versioning status&lt;/em&gt; commands have been added.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;budget version&lt;/em&gt; command shows the version of budgetwarrior.&lt;/p&gt;
&lt;p&gt;Aliases a now available to make shorted commands:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;budget sync -&amp;gt; budget versioning sync&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;budget aggregate -&amp;gt; budget overview aggregate&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;If you are on Gentoo, you can install it using layman:&lt;/p&gt;
&lt;pre class="literal-block"&gt;layman -a wichtounet
emerge -a budgetwarrior&lt;/pre&gt;
&lt;p&gt;If you are on Arch Linux, you can use this &lt;a class="reference external" href="https://github.com/StreakyCobra/aur"&gt;AUR repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For other systems, you'll have to install from sources:&lt;/p&gt;
&lt;pre class="literal-block"&gt;git clone git://github.com/wichtounet/budgetwarrior.git
cd budgetwarrior
make
sudo make install&lt;/pre&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you are interested by the sources, you can download them on Github:
&lt;a class="reference external" href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have a suggestion or you found a bug, please post an issue on Github.&lt;/p&gt;
&lt;p&gt;If you have any comment, don't hesitate to contact me, either by letting a
comment on this post or by email.&lt;/p&gt;
&lt;/section&gt;</description><category>budgetwarrior</category><category>C++</category><category>Gentoo</category><category>Git</category><category>Linux</category><category>Releases</category><guid>https://baptiste-wicht.com/posts/2014/07/budgetwarrior-04-enhanced-wish-list-and-aggregate.html</guid><pubDate>Sun, 06 Jul 2014 08:59:55 GMT</pubDate></item><item><title>Software Reliability Presentation</title><link>https://baptiste-wicht.com/posts/2014/06/software-reliability-presentation.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;section id="software-reliability"&gt;
&lt;h2&gt;Software Reliability&lt;/h2&gt;
&lt;p&gt;In behalf of my school (College of Engineering and Architecture of Fribourg), I
presented a shoft presentation about Software Reliability. In this presentation,
I outline the main issues about the subject and propose some solutions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Software Validation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defensive Programming&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Software Analysis Tools&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the Software Analysis Tools, I present three tools: cppcheck, Valgrind and
the Clang Static analyzer. Several examples are presented for each tools as well
as some recommendations for using them. A short presentation of SonarQube is
also performed.&lt;/p&gt;
&lt;p&gt;I thought that it could be of some interest to some of the readers, so here it
is:&lt;/p&gt;
&lt;div style="text-align:center;"&gt;&lt;iframe src="http://www.slideshare.net/slideshow/embed_code/35576524" width="597" height="486" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px 1px 0; margin-bottom:5px; max-width: 100%;" allowfullscreen&gt; &lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Don't hesitate if you have any comments or questions about the presentation ;)&lt;/p&gt;
&lt;p&gt;The source code for the examples is available &lt;a class="reference external" href="https://github.com/wichtounet/analysis-examples"&gt;on Github&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;</description><category>clang</category><category>Gentoo</category><category>Linux</category><category>Programming</category><category>Reliability</category><category>Tools</category><guid>https://baptiste-wicht.com/posts/2014/06/software-reliability-presentation.html</guid><pubDate>Sat, 07 Jun 2014 14:45:33 GMT</pubDate></item><item><title>budgetwarrior 0.3.1 - Git versioning and easier creation</title><link>https://baptiste-wicht.com/posts/2014/05/budgetwarrior-031-git-versioning-easier-creation.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I've finished a new version of budgetwarrior: budgetwarrior 0.3.1&lt;/p&gt;
&lt;h3&gt;Changes&lt;/h3&gt;
&lt;p&gt;The most interesting change is the ability to estimate the date when it is a good time to buy something from the wish list. This is done with the &lt;em&gt;budget wish estimate&lt;/em&gt; command: &lt;/p&gt;
&lt;p&gt;&lt;img alt="budget wish estimate" src="https://baptiste-wicht.com/images/budget_031_wish_estimate.jpg"&gt;&lt;/p&gt;
&lt;p&gt;This command gives you two dates for each wish in your list. The first is the date wating for each yearly objectives to be fullfilled. The second one considers only the monthly objectives. For now on, no estimation of expenses is made for the future months. It means that the estimation is made as if there were no expenses in the future months. I'll try to improve that by considering averages of expenses in the previous months to make it more reliable. &lt;/p&gt;
&lt;p&gt;Still on the wish module, you can now mark your wishes as paid instead of deleting them. This helps you keep track of the prices of your wishes. This is done with the &lt;em&gt;budget wish paid id&lt;/em&gt; command. Finally, the totals of the unpaid wishes and of the paid wishes is displayed in &lt;em&gt;budget wish list&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Another helpful change is the ability to set a date relative to today's date when creating an expense or an earning. For instance, you can create an expense one month before (-1m) or in one year ((+1y) or yesterday (-1d): &lt;/p&gt;
&lt;p&gt;&lt;img alt="new date selection mechanism" src="https://baptiste-wicht.com/images/budget_031_date_selection.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Of course, you can also still set the date manually. &lt;/p&gt;
&lt;p&gt;The last major change is the addition of a new module: &lt;em&gt;budget versioning&lt;/em&gt;. This module helps you manipulate you budget directory with Git. There are two new commands: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;budget versioning save&lt;/em&gt;: Commit the current changes with a default message (Update). &lt;/li&gt;
&lt;li&gt;&lt;em&gt;budget versioning sync&lt;/em&gt;: Pull the changes from the remote directory and push the local changes. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will only works if you have already configured your budget directory to use Git. &lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I hope you'll found these changes interesting :)&lt;/p&gt;
&lt;p&gt;If you are interested by the tool, you can download it on Github: &lt;a href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you have a suggestion or you found a bug, please post an issue on the github project: &lt;a href="https://github.com/wichtounet/budgetwarrior"&gt;https://github.com/wichtounet/budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have any comment, don't hesitate to contact me, either by letting a comment on this post or by email.&lt;/p&gt;</description><category>budgetwarrior</category><category>C++</category><category>Git</category><category>Linux</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2014/05/budgetwarrior-031-git-versioning-easier-creation.html</guid><pubDate>Sat, 10 May 2014 14:45:43 GMT</pubDate></item><item><title>budgetwarrior 0.3.0 - Objective and wish management</title><link>https://baptiste-wicht.com/posts/2014/02/budgetwarrior-0-3-0-objective-wish-management.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I'm pleased to announce the release of another budgetwarrior release, the version 0.3.0.&lt;/p&gt;
&lt;h3&gt;Changes&lt;/h3&gt;
&lt;p&gt;This version contains several important changes.&lt;/p&gt;
&lt;p&gt;The first one is the addition of a new module to manage objectives. You can add objective with &lt;em&gt;budget objective add). &lt;/em&gt;For instance, you can add an objective saying you want to save 10000$ a year or 200$ a month. When you set your objectives, budget warrior computes how well you complete them. For instance, here is the status of my objectives:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://baptiste-wicht.com/wp-content/uploads/2014/02/Screenshot-from-2014-02-02-113057-e1391337197470.png"&gt;&lt;img alt="Objective Status" src="https://baptiste-wicht.com/wp-content/uploads/2014/02/Screenshot-from-2014-02-02-113057-e1391337197470-300x83.png" title="Objective Status"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another module has been added to manage wishes. You can add wishes to budgetwarrior (&lt;em&gt;budget wish add&lt;/em&gt;) and then budgetwarrior will tell you if it is a good time to buy them. Here is an example of wish status:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.baptiste-wicht.com/wp-content/uploads/2014/02/Screenshot-from-2014-02-02-113814.png"&gt;&lt;img class="size-medium wp-image-2665" alt="Wish Status" src="https://baptiste-wicht.com/wp-content/uploads/2014/02/Screenshot-from-2014-02-02-113814-e1391337576857-300x96.png" width="300" height="96"&gt;&lt;/a&gt; Wish Status&lt;/p&gt;
&lt;p&gt;The diagnostics tells you where the money will be taken: On savings, on year savings or on month savings (ideal case). It also checks the objectives to see if the payment doesn't break the fulfillment of some of them.&lt;/p&gt;
&lt;p&gt;For complete diagnostics, it is necessary to you register your fortune (&lt;em&gt;budget fortune check&lt;/em&gt;), ideally once a month.&lt;/p&gt;
&lt;p&gt;Of course, this is only a tool, you should not only use that to decide when to buy something, but it may have a good point of view ;)&lt;/p&gt;
&lt;p&gt;Moreover, the version also have other smaller changes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When you make an error when creating a new item (expense, earning, ...), the tool now lets you retry without losing what you typed before.&lt;/li&gt;
&lt;li&gt;Confirmation messages are now shown after each modification command (delete, add and edit).&lt;/li&gt;
&lt;li&gt;The license has been changed from Boost to MIT. The sense is almost the same, but the MIT is more well known and I thought it would be easier for people to know what this means.&lt;/li&gt;
&lt;li&gt;There have several changes to the code base, but that doesn't impact the usage of the tool.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I hope you'll found these changes interesting :)&lt;/p&gt;
&lt;p&gt;If you are interested by the tool, you can download it on Github: &lt;a title="budgetwarrior repository" href="https://github.com/wichtounet/budgetwarrior"&gt;budgetwarrior&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is now Gentoo and Arch Linux installation packages available for ease of installation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have a suggestion or you found a bug, please post an issue on the github project: &lt;a title="https://github.com/wichtounet/budgetwarrior" href="https://github.com/wichtounet/budgetwarrior"&gt;https://github.com/wichtounet/budgetwarrior&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have any comment, don't hesitate to contact me, either by letting a comment on this post or by email.&lt;/p&gt;</description><category>budgetwarrior</category><category>C++</category><category>Linux</category><category>projects</category><guid>https://baptiste-wicht.com/posts/2014/02/budgetwarrior-0-3-0-objective-wish-management.html</guid><pubDate>Mon, 03 Feb 2014 08:21:29 GMT</pubDate></item><item><title>budgetwarrior 0.2.1 - Minor changes and Gentoo ebuild</title><link>https://baptiste-wicht.com/posts/2014/01/budgetwarrior-0-2-1-minor-changes-gentoo-ebuild.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I've released a new version of budgetwarrior, the release 0.2.1. budgetwarrior is a simple command line application to manage a personal budget.&lt;/p&gt;
&lt;p&gt;The version 0.2.1 contains several bug fixes about archived accounts and bug fixes for budget across several years.&lt;/p&gt;
&lt;p&gt;The application as well as the source code is available online: &lt;a href="https://github.com/wichtounet/budgetwarrior"&gt;https://github.com/wichtounet/budgetwarrior&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I've created Gentoo ebuilds for this application. They are available on my Portage overlay: &lt;a href="https://github.com/wichtounet/portage-overlay"&gt;https://github.com/wichtounet/portage-overlay&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Gentoo Installation&lt;/h4&gt;

&lt;ul&gt;
    &lt;li&gt;Edit overlays section of /etc/layman/layman.cfg. Here's an example:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;overlays: http://www.gentoo.org/proj/en/overlays/repositories.xml
           http://github.com/wichtounet/portage-overlay/raw/master/repository.xml&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Sync layman&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;layman -S&lt;/pre&gt;

&lt;ul&gt;
    &lt;li&gt;Add the overlay:&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;layman -a wichtounet&lt;/pre&gt;

&lt;ul&gt;
    &lt;li&gt;Install budgetwarrior&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;emerge budgetwarrior&lt;/pre&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;If you find any issues with the tool, don't hesitate to post an issue on Github. If you have comments about it, you can post a comment on this post or contact me by email.&lt;/p&gt;</description><category>budgetwarrior</category><category>Gentoo</category><category>Linux</category><category>Tools</category><guid>https://baptiste-wicht.com/posts/2014/01/budgetwarrior-0-2-1-minor-changes-gentoo-ebuild.html</guid><pubDate>Thu, 16 Jan 2014 11:41:00 GMT</pubDate></item><item><title>Zabbix - Low Level Discovery of cores, CPUs and Hard Disk</title><link>https://baptiste-wicht.com/posts/2013/12/zabbix-low-level-discovery-cores-cpus-hard-disk.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;&lt;a href="https://baptiste-wicht.com/wp-content/uploads/2013/12/Screenshot-from-2013-12-29-165743-e1388332859892.png"&gt;&lt;img src="https://baptiste-wicht.com/wp-content/uploads/2013/12/Screenshot-from-2013-12-29-165743-e1388332859892-300x151.png" alt="Zabbix SSD Status, configured with Low Level Discovery" width="300" height="151" class="size-medium wp-image-2644"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At home, I'm using Zabbix to monitor my servers, it has plenty of interesting features and can be extended a lot by using User Parameter.&lt;/p&gt;
&lt;p&gt;In this post, I'm gonna talk about Low Level Discovery (LLD). If you are only interested in the final result, go the Conclusion section, you can download my template containing all the rules ;)&lt;/p&gt;
&lt;h4&gt;Low Level Discovery (LLD)&lt;/h4&gt;

&lt;p&gt;LLD is a feature to automatically discover some properties of the monitored host and create items, triggers and graphs.&lt;/p&gt;
&lt;p&gt;By default, Zabbix support three types of item discovery:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Mounted filesystems&lt;/li&gt;
    &lt;li&gt;Network interface&lt;/li&gt;
    &lt;li&gt;SNMP's OIDs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first two are very useful, since they will give you by default, for instance, the free space of each mounted file system or the bandwith going in and out of each network interface. As I only monitor Linux servers, I don't use the last one, but it will eventually interest other people.&lt;/p&gt;
&lt;p&gt;Another very interesting thing about this feature is that you can extend it by discovering more items. In this article, I will show how to discover CPUs, CPU Cores and Hard Disk.&lt;/p&gt;
&lt;p&gt;The most important part of custom discovery is to create a script on the monitored machines that can "discover" something. It can be any executable, the only thing important is that it outputs data in the correct format. I have to say that the format is quite ugly, but that is probably not very important ;) Here is the output of my hard disk discovery script:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"{#DISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/dev/sda"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"{#SHORTDISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sda"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"{#DISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/dev/sdb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"{#SHORTDISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sdb"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"{#DISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/dev/sdc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"{#SHORTDISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sdc"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"{#DISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/dev/sdd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"{#SHORTDISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sdd"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"{#DISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/dev/sde"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"{#SHORTDISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sde"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"{#DISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/dev/sdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"{#SHORTDISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sdf"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"{#DISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"/dev/sdg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"{#SHORTDISKNAME}"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"sdg"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can have as many keys for each discovered items, but the format must remains the same. In the item, trigger and graph prototypes, you will then use {#DISKNAME} or {#SHORTDISKNAME} to use the discovered values. &lt;/p&gt;
&lt;p&gt;Once you have created your scripts, you have to register it in the zabbix configuration as a user parameter. For instance, if you use the zabbix daemon, you need these lines in /etc/zabbix/zabbix_agentd.conf: &lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;EnableRemoteCommands&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
...
&lt;span class="nv"&gt;UnsafeUserParameters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
...
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;discovery.hard_disk,/scripts/discover_hdd.sh
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, when you will create the discovery rule, you can use discovery.hard_disk as the key. &lt;/p&gt;
&lt;p&gt;A discovery rule in itself is useful without prototypes, you can create three types of prototypes: &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Item Prototype: This will create a new item for each discovered entity&lt;/li&gt;
    &lt;li&gt;Trigger Prototype: This will create a new trigger for each discovered entity. &lt;/li&gt;
    &lt;li&gt;Graph Prototype: This will create a graph for each discovered entity. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most useful are by far the item and trigger prototypes. The biggest problem with graphs is that you cannot create an aggregate graph of each discovered items. For instance, if you record the temperature of your CPU cores, you cannot automatically create a graph with the temperature of each discovered cores. For that, you have to create the graph in each host. Which makes, imho, graph prototypes pretty useless. Anyway...&lt;/p&gt;
&lt;p&gt;In the next section, I'll show how I have created discovery rules for Hard Disk, CPU and CPU cores. &lt;/p&gt;
&lt;h4&gt;Discover Hard Disk&lt;/h4&gt;

&lt;p&gt;The discovery script is really simple: &lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;disks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;/dev/sd*&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $NF}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'s/[0-9]//g'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;uniq&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\"data\":["&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;disk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$disks&lt;/span&gt;
&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"    {\"{#DISKNAME}\":\"&lt;/span&gt;&lt;span class="nv"&gt;$disk&lt;/span&gt;&lt;span class="s2"&gt;\",\"{#SHORTDISKNAME}\":\"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;5&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\"},"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"]"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"}"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It just lists all the /dev/sdX devices, remove the partition number and remove the duplicates, to have only the hard disk at the end. &lt;/p&gt;
&lt;p&gt;I've created several item prototypes for each hard disk. Here are some examples using S.M.A.R.T. (you can download the template with all the items in the Conclusion section): &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Raw Read Error Rate&lt;/li&gt;
    &lt;li&gt;Spin Up Time&lt;/li&gt;
    &lt;li&gt;SSD Life Left&lt;/li&gt;
    &lt;li&gt;Temperature&lt;/li&gt;
    &lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may notice that some of them only make sense for SSD (SSD Life Left) and some others do not make any sense for SSD (Spin Up Time). This is not a problem since they will just be marked as Not Supported by Zabbix. &lt;/p&gt;
&lt;p&gt;All these datas are collected using the smartctl utility. &lt;/p&gt;
&lt;p&gt;I've also created some trigger to indicate the coming failure of an hard disk: &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;SSD Life Left too low&lt;/li&gt;
    &lt;li&gt;Reallocated Sector Count too low&lt;/li&gt;
    &lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've just used the threshold reported by smartctl, they may be different from one disk manufacturers to another. I don't put a lot of faith on these values, since disk generally fail before going to threshold, but it could be a good indicator anyway. &lt;/p&gt;
&lt;h4&gt;Discover CPUs&lt;/h4&gt;

&lt;p&gt;Here is the script to discover CPUs: &lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;cpus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;lscpu&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CPU(s):"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $NF}'&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="nv"&gt;cpus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="nv"&gt;$cpus&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\"data\":["&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cpu&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;seq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$cpus&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"    {\"{#CPUID}\":\"&lt;/span&gt;&lt;span class="nv"&gt;$cpu&lt;/span&gt;&lt;span class="s2"&gt;\"},"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"]"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"}"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It just uses lscpu and parses its output to find the number of CPU and then create an entry for each CPUs. &lt;/p&gt;
&lt;p&gt;I just have one item for each CPU: The CPU Utilization. &lt;/p&gt;
&lt;p&gt;I haven't created any trigger here. &lt;/p&gt;
&lt;h4&gt;Discover CPU Cores&lt;/h4&gt;

&lt;p&gt;Just before, we discovered the CPUs, but it is also interesting to discover the cores. If you don't have Hyperthreading, the result will be the same. It is especially interesting to get the temperature of each core. Here is the script: &lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;cores&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;lscpu&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Core(s) per socket:"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $NF}'&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="nv"&gt;cores&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="nv"&gt;$cores&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\"data\":["&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;core&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;seq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$cores&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"    {\"{#COREID}\":\"&lt;/span&gt;&lt;span class="nv"&gt;$core&lt;/span&gt;&lt;span class="s2"&gt;\"},"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"]"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"}"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It works in the same way as the previous script. &lt;/p&gt;
&lt;p&gt;I've only created one item prototype, to get the temperature of each core with lm_sensors. &lt;/p&gt;
&lt;h4&gt;Wrap-Up&lt;/h4&gt;

&lt;p&gt;Here are all the UserParameter necessary to make the discovery and the items works: &lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="c1"&gt;### System Temperature ###&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;system.temperature.core&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,sensors&lt;span class="p"&gt;|&lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;Core&lt;span class="se"&gt;\ &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"("&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;-4
&lt;span class="c1"&gt;### DISK I/O###&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom.vfs.dev.read.ops&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,cat&lt;span class="w"&gt; &lt;/span&gt;/proc/diskstats&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$4}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom.vfs.dev.read.ms&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,cat&lt;span class="w"&gt; &lt;/span&gt;/proc/diskstats&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$7}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom.vfs.dev.write.ops&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,cat&lt;span class="w"&gt; &lt;/span&gt;/proc/diskstats&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$8}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom.vfs.dev.write.ms&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,cat&lt;span class="w"&gt; &lt;/span&gt;/proc/diskstats&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$11}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom.vfs.dev.io.active&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,cat&lt;span class="w"&gt; &lt;/span&gt;/proc/diskstats&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$12}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom.vfs.dev.io.ms&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,cat&lt;span class="w"&gt; &lt;/span&gt;/proc/diskstats&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;y&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$13}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom.vfs.dev.read.sectors&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,cat&lt;span class="w"&gt; &lt;/span&gt;/proc/diskstats&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$6}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom.vfs.dev.write.sectors&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,cat&lt;span class="w"&gt; &lt;/span&gt;/proc/diskstats&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$10}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;system.smartd_raw&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,sudo&lt;span class="w"&gt; &lt;/span&gt;smartctl&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tail&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;xargs&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$10}'&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;system.smartd_value&lt;span class="o"&gt;[&lt;/span&gt;*&lt;span class="o"&gt;]&lt;/span&gt;,sudo&lt;span class="w"&gt; &lt;/span&gt;smartctl&lt;span class="w"&gt; &lt;/span&gt;-A&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;egrep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;tail&lt;span class="w"&gt; &lt;/span&gt;-1&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;xargs&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{print $$4}'&lt;/span&gt;
&lt;span class="c1"&gt;### Discovery ###&lt;/span&gt;
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;discovery.hard_disk,/scripts/discover_hdd.sh
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;discovery.cpus,/scripts/discover_cpus.sh
&lt;span class="nv"&gt;UserParameter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;discovery.cores,/scripts/discover_cores.sh
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(it must be set in zabbix_agentd.conf)&lt;/p&gt;
&lt;p&gt;You also need to give zabbix the right to use sudo with smartctl. For that, you have to edit your /etc/sudoers file and add this line: &lt;/p&gt;
&lt;pre&gt;ALL ALL=(ALL)NOPASSWD: /usr/sbin/smartctl&lt;/pre&gt;

&lt;h4&gt;Conclusion and Download&lt;/h4&gt;

&lt;p&gt;I hope that this helps some people to use Low Level Discovery in their Zabbix Monitoring Installation. &lt;/p&gt;
&lt;p&gt;LLD eases a lot the creation of multiple items discovery for hosts with different hardware or configuration. However, it has some problems for which I have not yet found a proper solution. First, you have to duplicate the client scripts on each host (or at least have them on a share available from each of them). Then, the configuration of each agent is also duplicated in the configuration of each host. The biggest problem I think is the fact that you cannot automatically create graph with the generated items of each discovered entities. For instance, I had to create a CPU Temperature graph in each of my host. If you have few hosts, like many, it is acceptable, but if you have hundreds of hosts, you just don't do it. &lt;/p&gt;
&lt;p&gt;All the scripts and the template export file are available in the &lt;a href="https://github.com/wichtounet/zabbix-lld" title="zabbix-lld repository"&gt;zabbix-lld&lt;/a&gt; repository. For everything to work, you need the lscpu, lm_sensors and smartmontools utilities. &lt;/p&gt;
&lt;p&gt;If you have any question or if something doesn't work (I don't offer any guarantee, but it should work on most recent Linux machines), don't hesitate to comment on this post.&lt;/p&gt;</description><category>Linux</category><category>Others</category><category>Server</category><category>zabbix</category><guid>https://baptiste-wicht.com/posts/2013/12/zabbix-low-level-discovery-cores-cpus-hard-disk.html</guid><pubDate>Mon, 30 Dec 2013 08:12:31 GMT</pubDate></item><item><title>Gentoo Tips: Avoid Gnome 3.8 from being emerged automatically</title><link>https://baptiste-wicht.com/posts/2013/12/gentoo-tips-avoid-gnome-3-8-emerged-automatically.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;Since Gnome 3.8 has been out in the portage tree, a lot of problems arise when you try to emerge something. If it was only when you update the system, it would be OK, but this arises every time you try to install something.&lt;/p&gt;
&lt;p&gt;For instance, if I try to update vim on my system, it tries to update empathy to version 3.8 and then pulls some other dependencies causing blocks and other USE problems. I personally don't think empathy should be emerged when emerging vim. Fortunately, you can disable this behavior by using emerge in this way:&lt;/p&gt;
&lt;pre&gt;emerge --ignore-built-slot-operator-deps=y ...&lt;/pre&gt;

&lt;p&gt;With that, when you emerge vim, it doesn't emerge Gnome 3.8. It is very useful if you want to stay with Gnome 3.6 for the moment.&lt;/p&gt;
&lt;p&gt;I already used this tip several times. I hope that this will be useful to other people.&lt;/p&gt;</description><category>Gentoo</category><category>Linux</category><category>Tips</category><guid>https://baptiste-wicht.com/posts/2013/12/gentoo-tips-avoid-gnome-3-8-emerged-automatically.html</guid><pubDate>Sat, 07 Dec 2013 05:24:17 GMT</pubDate></item><item><title>Why and how I completely left Windows for Linux</title><link>https://baptiste-wicht.com/posts/2013/07/why-how-left-windows-for-linux.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;For years now, I always kept a dual-boot at home with a Linux system (currently Gentoo) and a Windows system. At work, I only use Gentoo. This week-end, I decided to completely remove it and migrate the applications I used on Windows to my Gentoo system.&lt;/p&gt;
&lt;h4&gt;Why Windows ?&lt;/h4&gt;

&lt;p&gt;So first things first, why was I keeping the Windows system ? For several reasons:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Games :) Unfortunately, most of the games I play are not natively compatible with Linux.&lt;/li&gt;
    &lt;li&gt;Office. I always liked Microsoft Office. As I hate OpenOffice/LibreOffice, I never wanted to remove it For schools we always had several teachers forcing us to use Microsoft document formats.&lt;/li&gt;
    &lt;li&gt;Hardware support. I always found that hardware support in Windows was great. Most of the time when you add new peripheral, there is nothing, it just works, which is great.&lt;/li&gt;
    &lt;li&gt;Applications. I always had some applications that I didn't found good enough Linux equivalents for. For instance, Newsleecher, iTunes or TaggedFrog.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On the other hand, I work on Linux for years now and I would like to have to work on Windows again.&lt;/p&gt;
&lt;h4&gt;What Changed ?&lt;/h4&gt;

&lt;p&gt;This weekend I upgraded my hardware configuration (Motherboard, CPU and RAM). I was afraid that I had to reinstall my Linux configurations (because of Gentoo compiled with march=native), but I never thought that I would have to reinstall Windows. I turned out the contrary: my Gentoo installation worked just fine and my Windows totally crashed (BSOD at each startup). I finally made it through Windows after disabled AHCI mode on my motherboard, but then activation was invalidated (of course...) and online activation was not working. I decided to install the new chipset drivers and launch the Windows update and after that, Windows decided to boot without any USB support (WTF...). After that, I decided that Windows what not so great at all for   hardware support...&lt;/p&gt;
&lt;p&gt;Another reason I left Windows is Windows 8. I find that Window 7 was really great, but I really don't like Windows 8 and I would never have upgraded my Seven to it. Moreover, I recently bought Microsoft Office 2013 and it turned that I had to create an account at Microsoft to install it... Seriously ??? And moreover, it turned out to be worse thant Office 2010 (which, again, was great).&lt;/p&gt;
&lt;p&gt;So all these reasons made me remove Windows.&lt;/p&gt;
&lt;h4&gt;How to migrate everything to Linux ?&lt;/h4&gt;

&lt;p&gt;First, I had no problem with my data. Most of my data are on a personal NAS and the remaining is on Dropbox, so no problem on this side.&lt;/p&gt;
&lt;p&gt;I still had some problems to resolve. First of all, I needed my games to run on Linux. I currently play only Diablo III. As I had received a year free of &lt;a title="Crossover" href="http://www.codeweavers.com/products/"&gt;Crossover&lt;/a&gt;, I decided to give it a try. Crossover is based on Wine and ensures that some software are running correctly under it and provide technical support. After some tuning, Diablo III was running almost flawlessly on my Gentoo machine :) Problem 1 solved. I will totally buy a license of Crossover, once my free year is over.&lt;/p&gt;
&lt;p&gt;I still add some applications to replace. I use iTunes as my main music player and library manager. Some time ago, I tried a lot of programs like Amarok/Rythmbox/Banshee, but I didn't liked them a lot and they were not running very well on large library of music files. This time, I tried &lt;a title="Clementine" href="http://www.clementine-player.org/"&gt;Clementine&lt;/a&gt;. Even if not very beautiful, it had all the features I needed and worked very well. I decided to stick with it. Another program I like a lot on Windows is TaggedFrog. It is a very simple program allowing to put tags on any file on the system and then search by tag on them. I haven't found a total equivalent. I first tried Tracker that is a Gnome project, but I was not satisfied with the search interface. After that, I tried the very simple &lt;a title="TMSU" href="http://tmsu.org/"&gt;TMSU&lt;/a&gt;. It is a command-line based tagging manager. All the tagging must be done in command line. In my case, it is not a problem, as I don't mind using the command-line and I don't tag files very often. What is very interesting about TMSU is that it can create a virtual file system (based on FUSE). In this file system, you have all your tags  as folder and you can see directly all the files of each tag. Moreover, you can directly make cross search (has tag X and Y and Z) by just going down in the tag folder. It is really great and has everything I needed. Finally, I also needed something to replace Newsleecher. I haven't found something as great (especially no replacement for the Supersearch function), but I installed &lt;a title="Sabnzbd" href="http://sabnzbd.org/"&gt;Sabnzbd&lt;/a&gt; which works really well and is very simple. For now, I just use the web interface and haven't installed any other front-end, but that will perhaps change in the future.&lt;/p&gt;
&lt;p&gt;I haven't replaced Office for now on. It occurred to me that since I left school, I haven't used it a lot, so that will probably not be a problem anymore. I will change to write the few letters I have to write on Latex and if I have Office documents, I'll probably read them on Google Drive.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;

&lt;p&gt;Even if I lost a lot of time with all that, I think it is a great think. It makes one less configuration to maintain and some less costs on the future. Moreover, I will save some time, because I won't have to switch between Linux and Windows for different tasks. And now, I have a second SSD ready for something else, either for RAID 1 to ensure redundancy on Linux or to mount on a server, I'll see later.&lt;/p&gt;
&lt;p&gt;I will probably have some more problems in the future, but I'm convinced that there will be Linux solutions to it :)&lt;/p&gt;</description><category>Gentoo</category><category>Linux</category><category>Others</category><category>Personal</category><category>Windows</category><guid>https://baptiste-wicht.com/posts/2013/07/why-how-left-windows-for-linux.html</guid><pubDate>Mon, 01 Jul 2013 06:24:25 GMT</pubDate></item><item><title>CMakeLatex 1.0.2 - Support for nomenclature and better filters</title><link>https://baptiste-wicht.com/posts/2012/11/cmakelatex-1-0-2-nomenclature-filters.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I released a new version of CMakeLatex, the version 1.0.2. &lt;/p&gt;
&lt;p&gt;First of all, this version restore the support for nomenclature. Then, it also adds filters for makeindex (including makeglossaries and makenomenclature). The filters will hides all the information of the output stream but the errors. The filters for pdflatex are also improved. &lt;/p&gt;
&lt;p&gt;CMakeLatex is a CMake script to build Latex documents using CMake / Make. It supports glossary, indexes, bibliographies and nomenclature. It can automatically converts your images to the right format using imagemagick or cairosvg (for SVG to PDF conversion). &lt;/p&gt;
&lt;p&gt;You can download it on Github: &lt;a href="https://github.com/wichtounet/CMakeLatex" title="CMakeLatex Github repository" target="_blank"&gt;CMakeLatex Github repository&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you have any idea for improvement, don't hesitate to contact me or to create a Feature Request on Github.&lt;/p&gt;</description><category>cmake</category><category>Latex</category><category>Linux</category><guid>https://baptiste-wicht.com/posts/2012/11/cmakelatex-1-0-2-nomenclature-filters.html</guid><pubDate>Mon, 05 Nov 2012 08:02:19 GMT</pubDate></item><item><title>eddic compiles with CLang 3.1</title><link>https://baptiste-wicht.com/posts/2012/11/eddic-compiles-with-clang-3-1.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;I finally added support for compiling eddic with LLVM CLang 3.1 !&lt;/p&gt;
&lt;p&gt;The current development version can be completely compiled with CLang. Starting with the version 1.1.4, all versions of eddic will be support GCC and CLang. &lt;/p&gt;
&lt;p&gt;The changes have not been as painful as I first thought. &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;The main problem that I has was about a static const variable of a class that had no user-constructor. GCC allows that, but it is not standard compliant and CLang was complaining. &lt;/li&gt;
    &lt;li&gt;Another problem that I encountered was about the used of bit flags and Template Meta Programming. I simplified that by the use of a simple type traits and it worked. I don't really know why this does not worked at first. &lt;/li&gt;
    &lt;li&gt;The remaining effort was to fix the several warnings that CLang had. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CLang also fixed a bug in my code with a warning on a assignment that was not supposed to be an assignment, thanks CLang. &lt;/p&gt;
&lt;p&gt;The most interesting fact about CLang is that &lt;strong&gt;is it twice faster to build eddic than GCC&lt;/strong&gt;. I think I'm gonna use it during development to fasten the compile time. Moreover, even if I only worked two days with it, it seems that the error messages are indeed better than the GCC's ones. &lt;/p&gt;
&lt;p&gt;I haven't tried to compare the performances of eddic in both cases, but I will do that in the future, soon after the 1.1.4 version is released. &lt;/p&gt;
&lt;p&gt;I tried the CLang static analyzer on eddic but it didn't found any bugs. Moreover, it crashed on several of my files. I didn't found why for now, but I will continue to investigate, perhaps I'm not using it correctly. &lt;/p&gt;
&lt;p&gt;I expect to publish the next version of eddic in the next two weeks. This version has much more improvements that I thought at first and I have less time to work now that &lt;a href="http://www.baptiste-wicht.com/2012/09/back-in-berkeley-california/" title="Back in Berkeley, California" target="_blank"&gt;I'm working on my Master thesis&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;More informations on CLang: &lt;a href="http://clang.llvm.org/" title="CLang official site"&gt;The official site&lt;/a&gt;.&lt;/p&gt;</description><category>clang</category><category>Compilers</category><category>EDDI</category><category>gcc</category><category>Linux</category><guid>https://baptiste-wicht.com/posts/2012/11/eddic-compiles-with-clang-3-1.html</guid><pubDate>Thu, 01 Nov 2012 08:11:05 GMT</pubDate></item><item><title>Linux symbolic links (soft) and hard links</title><link>https://baptiste-wicht.com/posts/2012/09/linux-symbolic-links-hard-links.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;On Linux, it is possible to create &lt;strong&gt;links to existing file&lt;/strong&gt;. These links can be either &lt;strong&gt;symbolic links&lt;/strong&gt; or &lt;strong&gt;hard links&lt;/strong&gt;. Each of them having advantages and drawbacks. In this small post, we will see the differences between the two kinds of links and how to use them.&lt;/p&gt;
&lt;h3&gt;Hard Link&lt;/h3&gt;

&lt;p&gt;An hard link refers directly to the physical location of another file (an inode to be precise).&lt;/p&gt;
&lt;p&gt;A hard link has some limitations: it cannot refer to a directory and cannot cross file system boundaries. It means that you can only create hard links to the same file system where the hard link is located.&lt;/p&gt;
&lt;p&gt;When the source of the link is moved or removed, the hard link still refer to the source.&lt;/p&gt;
&lt;p&gt;Symbolic link are created with the &lt;strong&gt;ln&lt;/strong&gt; command. For instance, to create a link to source_file: &lt;/p&gt;
&lt;pre&gt;ln source_file link&lt;/pre&gt;

&lt;h3&gt;Symbolic Link&lt;/h3&gt;

&lt;p&gt;A symbolic link refers to a symbolic path indicating the location of the source file. You can see it as a link to a path (itself refering to an inode).&lt;/p&gt;
&lt;p&gt;A symbolic link is less limited. It can refer to a directory and can cross file system boundaries.&lt;/p&gt;
&lt;p&gt;However, when the source of the link is moved or removed, the symbolic link is not updated.&lt;/p&gt;
&lt;p&gt;Symbolic link are created with the &lt;strong&gt;ln&lt;/strong&gt; command. For instance, to create a symbolic link to source_file:&lt;/p&gt;
&lt;pre&gt;ln -s source_file link&lt;/pre&gt;

&lt;h3&gt;Deletion&lt;/h3&gt;

&lt;p&gt;The deletion of a link (hard or symbolic) can be achieved with the &lt;strong&gt;rm&lt;/strong&gt; or &lt;strong&gt;unlink&lt;/strong&gt; commands: &lt;/p&gt;
&lt;pre&gt;rm link
unlink link&lt;/pre&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;And that's it!&lt;/p&gt;
&lt;p&gt;Symbolic and hard links are very useful tools and are very easy to use. &lt;/p&gt;
&lt;p&gt;I hope that this blog post helped you understand a little better the differences between the two types of links and how to use them.&lt;/p&gt;</description><category>Linux</category><guid>https://baptiste-wicht.com/posts/2012/09/linux-symbolic-links-hard-links.html</guid><pubDate>Fri, 21 Sep 2012 07:16:37 GMT</pubDate></item><item><title>Memory Manager in 64bits Intel Assembly on Linux</title><link>https://baptiste-wicht.com/posts/2012/08/memory-manager-intel-assembly-64-linux.html</link><dc:creator>Baptiste Wicht</dc:creator><description>&lt;p&gt;For &lt;a title="EDDI Compiler 1.1.1 – Dynamic Memory Allocation and Constructors/Destructors" href="http://www.baptiste-wicht.com/2012/07/eddi-compiler-1-1-1-dynamic-memory-allocation-constructors-destructors/"&gt;the last version of the EDDI Compiler&lt;/a&gt;, it has been necessary to extend the dynamic memory allocator, to support free memory. In this post, we will see how to write a simple Memory Manager in Intel Assembly for Linux.&lt;/p&gt;
&lt;p&gt;In the past, we've seen &lt;a title="Dynamic memory allocation in Intel Assembly on Linux" href="http://www.baptiste-wicht.com/2011/11/dynamic-memory-allocation-intel-assembly-linux/"&gt;how to write a basic memory allocator&lt;/a&gt;, this time, we will write a more complete version.&lt;/p&gt;
&lt;p&gt;The implementation is made in 64bits Intel Assembly.&lt;/p&gt;
&lt;h4&gt;Memory Manager specification&lt;/h4&gt;

&lt;p&gt;The memory will be allocated by blocks. Each block will contain a header with two information:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;A boolean flag indicating if the block is free or not&lt;/li&gt;
    &lt;li&gt;The size of the block (including the header)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each time some memory is asked, the blocks are tested one by one until an available one is found. If no available block is found, a new block is allocated after the last one and this block is returned.&lt;/p&gt;
&lt;p&gt;The memory manager consists of three functions:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;memory_init: Init the memory manager&lt;/li&gt;
    &lt;li&gt;memory_alloc: Allocate the given number of bytes of memory&lt;/li&gt;
    &lt;li&gt;memory_free: Release the given block&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The parameter is passed in the &lt;strong&gt;r14&lt;/strong&gt; register. The return value is returned in the &lt;strong&gt;rax&lt;/strong&gt; register.&lt;/p&gt;
&lt;h4&gt;Global State&lt;/h4&gt;

&lt;p&gt;This implementation needs two global variables. One for the start address of memory and the other one for the last:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.data&lt;/span&gt;
&lt;span class="nf"&gt;mem_last&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nf"&gt;mem_start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;Init memory Manager&lt;/h4&gt;

&lt;p&gt;The init function is very simple to implement:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nl"&gt;init:&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsp&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="nf"&gt;xor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="nf"&gt;syscall&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;mem_start&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;mem_last&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;
&lt;span class="nf"&gt;leave&lt;/span&gt;
&lt;span class="nf"&gt;ret&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We just have to call sys_brk in order to get the location of &lt;em&gt;program break&lt;/em&gt;. Then, the start and the last addresses are the same.&lt;/p&gt;
&lt;h4&gt;Free memory&lt;/h4&gt;

&lt;p&gt;The free function is the simplest one:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nl"&gt;free:&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsp&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;qword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nf"&gt;leave&lt;/span&gt;
&lt;span class="nf"&gt;ret&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The address to free is passed in the &lt;strong&gt;r14&lt;/strong&gt; register. We have to go back 16 bytes (size of the control block) to go to the start of the block. The availability flag is set to 1 (the block is free).&lt;/p&gt;
&lt;h4&gt;The alloc function&lt;/h4&gt;

&lt;p&gt;The alloc function is the most complex:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nl"&gt;alloc:&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rbp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsp&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r10&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r13&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;
&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;mem_start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;mem_last&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nl"&gt;.start:&lt;/span&gt;
&lt;span class="nf"&gt;cmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r13&lt;/span&gt;
&lt;span class="nf"&gt;je&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.alloc&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;cmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nf"&gt;jne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.move&lt;/span&gt;
&lt;span class="nf"&gt;cmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;
&lt;span class="nf"&gt;jl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.move&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;qword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nf"&gt;lea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r13&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r10&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="nf"&gt;leave&lt;/span&gt;
&lt;span class="nf"&gt;ret&lt;/span&gt;

&lt;span class="nl"&gt;.move:&lt;/span&gt;
&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;
&lt;span class="nf"&gt;jmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.start&lt;/span&gt;

&lt;span class="nl"&gt;.alloc:&lt;/span&gt;
&lt;span class="nf"&gt;lea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="nf"&gt;syscall&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;mem_last&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;qword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;qword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;
&lt;span class="nf"&gt;lea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r13&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r10&lt;/span&gt;
&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="nf"&gt;leave&lt;/span&gt;
&lt;span class="nf"&gt;ret&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As the function is a bit complex, I will detail it in part:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;mem_start&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;mem_last&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nl"&gt;.start:&lt;/span&gt;
&lt;span class="nf"&gt;cmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r13&lt;/span&gt;
&lt;span class="nf"&gt;je&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.alloc&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;cmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nf"&gt;jne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.move&lt;/span&gt;
&lt;span class="nf"&gt;cmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;
&lt;span class="nf"&gt;jl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.move&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;qword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nf"&gt;lea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The necessary number of bytes is passed in the &lt;strong&gt;r14&lt;/strong&gt; register. We add 16 bytes (size of the control group) to the size as we also need some place for the header. Then, we load the start and last addresses. If both addresses are equal, we need to allocate more memory (detailed later). Then, we check the size and the availability of the current block. If the size is enough to fit the needs and the block is available, we set it to unavailable. We return the address past the control block (16 bytes).&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nl"&gt;.move:&lt;/span&gt;
&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r11&lt;/span&gt;
&lt;span class="nf"&gt;jmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.start&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To move to the next block, we just have to add the size of the current block to the current block address.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nl"&gt;.alloc:&lt;/span&gt;
&lt;span class="nf"&gt;lea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="nf"&gt;syscall&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;V_mem_last&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;qword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;qword&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;r14&lt;/span&gt;
&lt;span class="nf"&gt;lea&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;r12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To allocate memory, we compute the new &lt;em&gt;program break&lt;/em&gt; and call &lt;em&gt;sys_brk&lt;/em&gt; again to set the new &lt;em&gt;program break&lt;/em&gt;. The block is then set to not available and the size is set. We return the address past the control block (16 bytes).&lt;/p&gt;
&lt;p&gt;The rest of the program is just here to save and restore the registers and compute the stack frames.&lt;/p&gt;
&lt;h4&gt;Wrap-Up&lt;/h4&gt;

&lt;p&gt;In this article, we saw how to implement a very simple memory manager in 64bits Intel Assembly on Linux. This memory manager is very simple, but has several drawbacks:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;The overhead for small blocks is important. For example, allocating an 8 bytes integer needs a 24 bytes block, thrice the size of the int.&lt;/li&gt;
    &lt;li&gt;In the worst-case scenario, all of the process memory need to be walked across to find a new free block&lt;/li&gt;
    &lt;li&gt;The functions are not thread-safe&lt;/li&gt;
    &lt;li&gt;This algorithm can lead to a lot of memory fragmentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the future I will try to make a more powerful version of this memory manager.&lt;/p&gt;
&lt;h4&gt;Download&lt;/h4&gt;

&lt;p&gt;All the functions are available online on the Github Repository:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://github.com/wichtounet/eddic/blob/develop/functions/x86_64_alloc.s"&gt;alloc&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://github.com/wichtounet/eddic/blob/develop/functions/x86_64_free.s"&gt;free&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://github.com/wichtounet/eddic/blob/develop/functions/x86_64_init.s"&gt;init&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are also available in 32bits Intel Assembly:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="https://github.com/wichtounet/eddic/blob/develop/functions/x86_32_alloc.s"&gt;alloc&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://github.com/wichtounet/eddic/blob/develop/functions/x86_32_free.s"&gt;free&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="https://github.com/wichtounet/eddic/blob/develop/functions/x86_32_init.s"&gt;init&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><category>Assembly</category><category>Intel</category><category>Linux</category><guid>https://baptiste-wicht.com/posts/2012/08/memory-manager-intel-assembly-64-linux.html</guid><pubDate>Thu, 02 Aug 2012 06:05:30 GMT</pubDate></item></channel></rss>