<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Linux on Giedrius Statkevičius</title><link>https://giedrius.blog/categories/linux/</link><description>Recent content in Linux on Giedrius Statkevičius</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Sat, 06 Mar 2021 12:58:55 +0000</lastBuildDate><atom:link href="https://giedrius.blog/categories/linux/feed.xml" rel="self" type="application/rss+xml"/><item><title>Surprising Behavior With inotify And ioutil</title><link>https://giedrius.blog/2021/03/06/surprising-behavior-with-inotify-and-ioutil/</link><pubDate>Sat, 06 Mar 2021 12:58:55 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=844</guid><description>&lt;p&gt;Recently I was working on trying to fix one flaky test of the &amp;ldquo;reloader&amp;rdquo; component in the &lt;a href="https://thanos.io"&gt;Thanos&lt;/a&gt; project. It was quite a long-standing one - almost took a whole year to fix this &lt;a href="https://github.com/thanos-io/thanos/issues/2622"&gt;issue&lt;/a&gt;. It is not surprising as it is quite tricky. But, before zooming into the details, let&amp;rsquo;s talk about what does this test does and what other systems come into play.&lt;/p&gt;
&lt;p&gt;Simply put, Thanos Sidecar works as a sidecar component for Prometheus that not just proxies the requests to it, captures the blocks produced by Prometheus &amp;amp; uploads them to remote object storage, but the Sidecar can also automatically reload your Prometheus instance if some kind of configuration files change. For that, it uses the &lt;code&gt;inotify&lt;/code&gt; mechanism on the Linux kernel. You can read more about inotify itself &lt;a href="https://man7.org/linux/man-pages/man7/inotify.7.html"&gt;here&lt;/a&gt;. Long story short, using it you can watch some files and get notifications when something changes e.g. new data gets written to the files.&lt;/p&gt;</description></item><item><title>Running systemd Units Only If Certain CPU Features Are Available</title><link>https://giedrius.blog/2021/02/19/running-systemd-units-only-if-certain-cpu-features-are-available/</link><pubDate>Fri, 19 Feb 2021 15:13:17 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=823</guid><description>&lt;figure&gt;
&lt;img loading="lazy" src="https://giedrius.blog/wp-content/uploads/2021/02/systemd-logomark.png"
alt="systemd&amp;#39;s logo (C) https://brand.systemd.io/"/&gt; &lt;figcaption&gt;
&lt;p&gt;systemd&amp;rsquo;s logo (C) &lt;a href="https://brand.systemd.io/"&gt;https://brand.systemd.io/&lt;/a&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Do you have some kind of application that should only be executed when the user&amp;rsquo;s CPU has a certain feature? Or maybe your application has horrible performance unless some certain instructions are available? As you might know already, the Linux kernel exposes this information via &lt;code&gt;/proc/cpuinfo&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;processor : &lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vendor_id : AuthenticAMD
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cpu family : &lt;span style="color:#ae81ff"&gt;23&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;model : &lt;span style="color:#ae81ff"&gt;96&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;model name : AMD Ryzen &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt; PRO &lt;span style="color:#ae81ff"&gt;4750&lt;/span&gt;U with Radeon Graphics
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd _apicid aperfmperf pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;dnowprefetch osvw ibs skinit wdt tce to poext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xge tbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif umip rdpid overflow_recov succor smca
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where does this data come from? One source of information is the &lt;code&gt;cpuid&lt;/code&gt; instruction. On the x86 architecture systemd starting from v248 is now able to start or stop an unit based on the features exposed by the &lt;a href="https://en.wikipedia.org/wiki/CPUID"&gt;CPUID&lt;/a&gt; instruction. Enter &lt;code&gt;ConditionCPUFeature&lt;/code&gt;. On CPUs that do not have the CPUID instruction i.e. ARM CPUs, it is assumed that the CPU implements no features and thus any potential &lt;em&gt;CPUFeature&lt;/em&gt; conditions will fail.&lt;/p&gt;</description></item><item><title>Surprising Optimization When Appending Elements to an Array in ZSH</title><link>https://giedrius.blog/2021/01/18/surprising-optimization-when-appending-elements-to-an-array-in-zsh/</link><pubDate>Mon, 18 Jan 2021 19:32:00 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=801</guid><description>&lt;p&gt;Recently I ran into a surprising ZSH performance bottleneck while editing my &lt;code&gt;.zshrc&lt;/code&gt;. Because it gets loaded every time a new shell comes up, I have noticed the issue pretty fast. I quickly started digging into the problem. Apparently, this surprising behavior concerns appending new elements to an array. I did not have a huge file that I was trying to read, only about 6000 elements or so. But still, it had a significant impact on how fast the Z shell was able to start up.&lt;/p&gt;</description></item><item><title>How to solve puppetdb and SIGKILL problems</title><link>https://giedrius.blog/2020/04/22/how-to-solve-puppetdb-and-sigkill-problems/</link><pubDate>Wed, 22 Apr 2020 20:45:17 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=636</guid><description>&lt;p&gt;In this post, I wanted to share some knowledge that I have gained recently. Sometimes your Puppet server might start returning 500 HTTP status codes. You should check &lt;code&gt;puppetserver&lt;/code&gt;&amp;rsquo;s logs first of all, of course, but another thing to check is the &lt;code&gt;puppetdb&lt;/code&gt;. &lt;code&gt;puppetdb&lt;/code&gt; is the component which is responsible for storing Puppet-related data. In this case, there were memory-related problems on the &lt;code&gt;puppetdb&lt;/code&gt; instance. The &lt;code&gt;puppetdb&lt;/code&gt; logs in this case have looked like this:&lt;/p&gt;</description></item><item><title>/etc/nsswitch.conf and /etc/hosts woes with the Alpine (and others) Docker image and Golang</title><link>https://giedrius.blog/2018/11/22/etc-nsswitch-conf-and-etc-hosts-woes-with-the-alpine-and-others-docker-image-and-golang/</link><pubDate>Thu, 22 Nov 2018 17:36:50 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=257</guid><description>&lt;p&gt;By default, the &lt;code&gt;alpine&lt;/code&gt; Docker image which is mostly used for Golang programs does &lt;a href="https://github.com/gliderlabs/docker-alpine/issues/367"&gt;&lt;em&gt;not&lt;/em&gt;&lt;/a&gt; contain &lt;code&gt;/etc/nsswitch.conf&lt;/code&gt;. Golang&amp;rsquo;s &lt;code&gt;net&lt;/code&gt; package used to do a sane thing when that file did not exist back in the day (before April 30, 2015) i.e. they checked the &lt;code&gt;/etc/hosts&lt;/code&gt; file first, and then moved on to trying to query the DNS servers.&lt;/p&gt;
&lt;p&gt;However, it was changed later - now Go&amp;rsquo;s resolver tries to query the local machine as per the manual page of &lt;a href="http://man7.org/linux/man-pages/man5/nsswitch.conf.5.html"&gt;&lt;em&gt;nsswitch.conf(5)&lt;/em&gt;&lt;/a&gt;. You can find the commit &lt;a href="https://go-review.googlesource.com/c/go/+/9380/"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Tutorial: Poor Man's Release/Shipping Process on GitLab</title><link>https://giedrius.blog/2018/10/01/tutorial-poor-mans-release-shipping-process-on-gitlab/</link><pubDate>Mon, 01 Oct 2018 20:15:55 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=278</guid><description>&lt;p&gt;&lt;img alt="Image result for gitlab" loading="lazy" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/GitLab_Logo.svg/2000px-GitLab_Logo.svg.png"&gt;&lt;/p&gt;
&lt;p&gt;Since the recent acquisition of GitHub by Microsoft, a lot of people and companies are migrating to GitLab. The GitLab offering is especially attractive to early-stage start-ups since they offer free 10000 CI minutes or, in other words, 10000 minutes on their CI servers. It is easy to move over the workload to your own Kubernetes cluster once you run out of them - there is an easy-to-use user interface available where you could do that with just a few clicks.&lt;/p&gt;</description></item><item><title>Turbo-charging git-diff and making reviews easier</title><link>https://giedrius.blog/2018/07/23/turbo-charging-git-diff-and-making-reviews-easier/</link><pubDate>Mon, 23 Jul 2018 20:27:04 +0000</pubDate><guid isPermaLink="false">https://giedrius.blog/?p=221</guid><description>&lt;p&gt;&lt;img loading="lazy" src="https://git-scm.com/images/logos/downloads/Git-Logo-2Color.png"&gt;&lt;/p&gt;
&lt;p&gt;Are you working with git repositories in which a lot of code churn is happening? For example, do you have a repository with Puppet hierarchical data and there are a lot of pull requests where code is just being moved around between layers of hieradata? &lt;code&gt;diff(1)&lt;/code&gt; ordinarily only differentiates between added and removed lines with green and red colours (certainly the user controls what are actually those colours) however &lt;code&gt;git-diff(1)&lt;/code&gt; recently, at the end of 2017, got a new functionality where text that is just moved around can be highlighted in different colours. This is my case and this feature was a godsend because I did not want to spend a lot of time reviewing the syntax side of things if the hieradata is just being moved. That is why I wanted to share it with you so that it could help you out and perhaps someone has some even more good tips on how to make the reviewing process more effective.&lt;/p&gt;</description></item><item><title>Why os.move() Sometimes Does Not Work And Why shutil.move() Is The Savior?</title><link>https://giedrius.blog/2018/01/28/why-os-move-sometimes-does-not-work-and-why-shutil-move-is-the-savior/</link><pubDate>Sun, 28 Jan 2018 21:16:30 +0000</pubDate><guid isPermaLink="false">http://giedrius.blog/?p=120</guid><description>&lt;p&gt;Recently I ran into an issue where this, for example, code fails:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; os
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;rename(&lt;span style="color:#e6db74"&gt;&amp;#39;/foo/a.txt&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;/bar/b.txt&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Traceback (most recent call last):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;File &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;, line &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#f92672"&gt;in&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;OSError&lt;/span&gt;: [Errno &lt;span style="color:#ae81ff"&gt;18&lt;/span&gt;] Invalid cross&lt;span style="color:#f92672"&gt;-&lt;/span&gt;device link
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;a href="https://docs.python.org/3/library/os.html"&gt;documentation&lt;/a&gt; for the &lt;em&gt;os&lt;/em&gt; module says that sometimes it might fail when the source and the destination are on different file-systems:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;os.rename&lt;/code&gt;( &lt;em&gt;src&lt;/em&gt;, &lt;em&gt;dst&lt;/em&gt;, &lt;em&gt;*&lt;/em&gt;, &lt;em&gt;src_dir_fd=None&lt;/em&gt;, &lt;em&gt;dst_dir_fd=None&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;Rename the file or directory src to dst. If dst is a directory, &lt;a href="https://docs.python.org/3/library/exceptions.html#OSError" title="OSError"&gt;&lt;code&gt;OSError&lt;/code&gt;&lt;/a&gt; will be raised. On Unix, if dst exists and is a file, it will be replaced silently if the user has permission. &lt;strong&gt;The operation may fail on some Unix flavors if src and dst are on different filesystems.&lt;/strong&gt; If successful, the renaming will be an atomic operation (this is a POSIX requirement). On Windows, if dst already exists, &lt;a href="https://docs.python.org/3/library/exceptions.html#OSError" title="OSError"&gt;&lt;code&gt;OSError&lt;/code&gt;&lt;/a&gt; will be raised even if it is a file.&lt;/p&gt;</description></item><item><title>Tutorial: Automatic, Reproducible Preparation of Virtual Machine templates for your vSphere environment with HashiCorp's Packer</title><link>https://giedrius.blog/2018/01/14/tutorial-automatic-reproducible-preparation-of-virtual-machine-templates-for-your-vsphere-environment-with-hashicorps-packer/</link><pubDate>Sun, 14 Jan 2018 10:45:52 +0000</pubDate><guid isPermaLink="false">http://giedrius.blog/?p=105</guid><description>&lt;h1 id="introduction"&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Let us say that you are using an vSphere (VMWare vCenter + one or more ESXi servers) environment in your company and you are creating virtual machines pretty often. Obviously you are familiar with the virtual machines template functionality but where could you get the templates? Well, one of the options is to look for them somewhere on the internet but that is not a very reliable thing to do since you have to trust a third-party to provide these to you. Most, if not all, operating systems distributors do not provide a VMWare template for their operating system. For example, Canonical only provides Ubuntu in a form of an ISO file. Thus, you have to change your approach and make the templates yourself. However, doing that manually that is tedious and very menial so you will look for solutions to this problem. Packer is something that solves this problem.&lt;/p&gt;</description></item><item><title>Confusion With File Redirection And sudo</title><link>https://giedrius.blog/2017/10/31/confusion-with-file-redirection-and-sudo/</link><pubDate>Tue, 31 Oct 2017 22:00:04 +0000</pubDate><guid isPermaLink="false">http://giedrius.blog/?p=60</guid><description>&lt;h1 id="introduction"&gt;Introduction&lt;/h1&gt;
&lt;p&gt;I have noticed that newbies sometimes fail to understand why, for example, &lt;em&gt;sudo echo “hi” &amp;gt; /tmp/test&lt;/em&gt; will create a file &lt;em&gt;/tmp/test&lt;/em&gt; with whatever effective user ID and effective group ID the command is ran with. They fall into the trap thinking that root:root will be the owner of &lt;em&gt;/tmp/test&lt;/em&gt;. However, that is certainly not true. This blog post will try to clarify why this happens and what the user can do to avoid this issue. This occurs due to peculiar parsing rules defined in POSIX. We will examine the standards which detail this behaviour, the source code of the popular shells bash/zsh, and some methods on how to avoid this problem with, for example, tee(1).&lt;/p&gt;</description></item><item><title>Short tale about proxies and /etc/hosts on GNU/Linux</title><link>https://giedrius.blog/2017/09/02/proxies-and-etc-hosts-on-gnu-linux/</link><pubDate>Sat, 02 Sep 2017 19:14:25 +0000</pubDate><guid isPermaLink="false">http://giedrius.blog/?p=36</guid><description>&lt;p&gt;&lt;img loading="lazy" src="https://giedrius.blog/wp-content/uploads/2017/09/linux-box.png"&gt;&lt;/p&gt;
&lt;p&gt;I encountered an interesting behavior the other day when trying to use HTTP and/or HTTPS proxy on a GNU/Linux machine. cURL and friends read environment variables called &lt;em&gt;http_proxy&lt;/em&gt; and &lt;em&gt;https_proxy&lt;/em&gt;. So, you are thinking, if one wants to have “global” proxy settings, one just has to create a new executable file that is only writable by root in &lt;em&gt;/etc/profile.d&lt;/em&gt; with content like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export http_proxy&lt;span style="color:#f92672"&gt;=&lt;/span&gt;”http://1.2.3.4”
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export https_proxy&lt;span style="color:#f92672"&gt;=&lt;/span&gt;”$http_proxy”
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, you might just notice an confusing occurrence when trying to use hostnames like localhost to refer to your own machine. Unfortunately, the priority is given to the proxy setting regardless if the hostname is static (i.e. it is in &lt;em&gt;/etc/hosts&lt;/em&gt;) and it resolves to a local IP like 127.0.0.1. It could happen that your proxy will be a bit stupid and resolve localhost to its own (or even a different) IP, and then you will get burned because you want to refer to your computer with it, not the proxy IP. It has potential to especially be confusing if the output will be very similar to what you are expecting. This can happen when e.g. you are trying to set up a simple web server on your machine and the proxy responds with a place holder page. I can confess that I fell into this trap but I will not anymore.&lt;/p&gt;</description></item></channel></rss>