-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrss.xml
More file actions
784 lines (783 loc) · 80.3 KB
/
Copy pathrss.xml
File metadata and controls
784 lines (783 loc) · 80.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Evgeny Budilovsky - All posts</title>
<link>http://budevg.github.io</link>
<description><![CDATA[Personal blog of Evgeny Budilovsky]]></description>
<atom:link href="http://budevg.github.io/rss.xml" rel="self"
type="application/rss+xml" />
<lastBuildDate>Fri, 20 Jan 2023 00:00:00 UT</lastBuildDate>
<item>
<title>Book review - Rust Atomics and Locks</title>
<link>http://budevg.github.io/posts/2023-01-20-book-review-rust-atomics-and-locks.html</link>
<description><![CDATA[<p><img src="/static/files/posts/2023_01_20/rust-atomics-cover.jpg" style="float:left; margin: 0px 8px 0px 8px;" width="150" height="150" /></p>
<p>The book <a href="https://marabos.nl/atomics/">Rust Atomics and Locks</a> provides an excellent overview of low-level
concurrency in the Rust language. The book covers topics like threads, locks,
reference counts, atomics, mailboxes/channels, and more, and it digs into issues
with CPUs and operating systems with examples of working Rust code. This book is
valuable for both Rust developers wishing to learn concurrency and for
developers of concurrent code in other languages who would like to learn how
best to do so in Rust. Additionally this book is good for Rust skeptics and
Linux-kernel developers who are interested in Rust being included in the Linux
kernel.</p>
<p>The book takes the <code>"Build Our Own X"</code> approach to build common concurrency
primitives from scratch. By using this approach the book allows readers to gain
a thorough understanding of how they work and how they can be used in real-world
scenarios. Additionally, this approach helps readers to understand the
trade-offs and decisions that need to be made when implementing these building
blocks, as they are able to see how different design choices affect the
functionality and performance of the resulting implementation.</p>
<p>I particularly enjoyed <code>Chapter 7 - "Understanding the Processor"</code> where the
author performs a deep dive into the low-level details of how the various
concurrency primitives are implemented at the processor level. To achieve this,
the chapter makes use of the <a href="https://godbolt.org">Compiler Explorer tool</a>. This
tool allows the reader to see the assembly code generated by the compiler for a
given piece of Rust code, and to compare the assembly code across different
architectures, such as x86 and ARM.</p>
<p>This chapter provides a valuable insight into the low-level workings of the
concurrency primitives and how they are implemented in different
architectures. It also highlights the importance of understanding the underlying
hardware when writing concurrent code and the potential performance impact of
different design choices.</p>
<p>I really enjoyed reading <code>"Rust Atomics and Locks"</code> as it provides a comprehensive
and well-written guide to concurrent programming in Rust. The hands-on approach
and the use of the <a href="https://godbolt.org">Compiler Explorer tool</a>, made the book an effective way to
deepen the understanding of the concurrency building blocks.</p>
<p>The book is available for free at <a href="https://marabos.nl/atomics/">https://marabos.nl/atomics/</a> so don’t miss the
opportunity to take a look.</p>]]></description>
<pubDate>Fri, 20 Jan 2023 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2023-01-20-book-review-rust-atomics-and-locks.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>Writing my first program, 28 years after</title>
<link>http://budevg.github.io/posts/2022-11-21-my-first-program.html</link>
<description><![CDATA[<p>If you are a programmer then you probably remember the first time that you wrote
an actual program. It probably wasn’t sophisticated piece of software. Maybe you
just copied some chunk of code and ran it to see the effect. Maybe you changed
some lines or played with variables. The first things we do are the most
influential for our life.</p>
<p>For me the year was 1994 and I had an 486 pc which I used as most other kids to
play games. I think I got the source code on piece of paper from some
programming book or maybe a file from my friend. It was written in QBasic and
after copying line by line all the code and running it, the result was a
sequence of colored dots displayed on my screen. Amazing !!! Let’s try and
recreate this nostalgic experience.</p>
<p>First we need to install msdos. I think I was running msdos 5.0 at that time.</p>
<p>Let’s download <a href="https://winworldpc.com/product/ms-dos/50">msdos 5.0</a>. First link
<a href="https://dl.winworldpc.com/Microsoft%20MS-DOS%205.00%20(3.5-720k).7z">Microsoft MS-DOS 5.00 (3.5-720k)</a>
promises .7z file.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> wget <span class="at">-q</span> <span class="st">'https://dl.winworldpc.com/Microsoft%20MS-DOS%205.00%20(3.5-720k).7z'</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> ls</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="st">'Microsoft MS-DOS 5.00 (3.5-720k).7z'</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> 7z e <span class="st">'Microsoft MS-DOS 5.00 (3.5-720k).7z'</span> <span class="op">></span> /dev/null</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> ls <span class="pp">*</span>.img</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="ex">Disk01.img</span> Disk02.img Disk03.img</span></code></pre></div>
<p>We will use qemu to emulate our hardware. I don’t remember the exact spec of my
pc. But according to this <a href="http://www.dosdays.co.uk/topics/1994.php">1994 pc</a>,
486DX2 was coming with 8MB of RAM and 320 MB disk size.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> qemu-img create <span class="at">-f</span> raw msdos.disk 320M</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ex">Formatting</span> <span class="st">'msdos.disk'</span>, fmt=raw size=335544320</span></code></pre></div>
<p>Now let’s run our system and install msdos5.0</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">qemu-system-i386</span> <span class="at">-m</span> 8M <span class="at">-hda</span> msdos.disk <span class="at">-L</span> . <span class="at">-fda</span> Disk01.img <span class="at">-boot</span> a</span></code></pre></div>
<p>Installing msdos is pretty easy. Just press enter, enter, enter, enter 4 times
(choosing the default options). The msdos will format the disk. It will install
the first floppy from three floppies and ask to insert the second one. To do
this you can switch to qemu monitor (using Ctrl+Alt+2), where you can use the
following command to switch the floppy image.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">(</span><span class="ex">qemu</span><span class="kw">)</span> <span class="ex">change</span> floppy0 Disk02.img</span></code></pre></div>
<p>Then go back to the display (Ctrl+Alt+1) and press enter. Repeat same sequence
for the third disk (<code>change floppy0 Disk03.img</code>). When the prompt asks to remove
all floppy disks you can switch to qemu monitor and run <code>eject floppy0</code>. Then
press enter and the msdos 5.0 will start from hard disk.</p>
<p>You can press <code>Shift+f9</code> to enter the command prompt and then just type
<code>qbasic.exe</code> to enter the qbasic program.</p>
<p>Press ESC to clear screen and then write the program</p>
<pre class="bas"><code>SCREEN 1
FOR x = 0 TO 10
FOR y= 0 TO x
PSET (x * 10, y * 10), RND * 2 + 1
t0 = TIMER
DO
LOOP UNTIL TIMER - t0 > .1
NEXT
NEXT</code></pre>
<p>After that pressing F5 will run the amazing program which will display colorful
dots in the shape of triangular.</p>
<p>This was the start of my programming adventure. First steps always look so
simple after you walked for a long time.</p>
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/D7NJKtSHr-A" frameborder="0" allowfullscreen>
</iframe>
</center>]]></description>
<pubDate>Mon, 21 Nov 2022 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2022-11-21-my-first-program.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>How to focus on technical content</title>
<link>http://budevg.github.io/posts/2022-11-15-focus-technical-content.html</link>
<description><![CDATA[<p>As a software developers we are in a constant race. The world of programming is
constantly changing. There are new technologies, paradigms, frameworks and
tools. To learn new things and stay relevant, true hackers develop a super
skill. The ability to skim information quickly, focus on important things,
filter the rest.</p>
<p><img src="/static/files/posts/2022_11_15/fast.png" style="width:30.0%;height:30.0%" /></p>
<p>This awesome ability allows us to jump into unknown code, start using new
framework or even learn new programming language in matter of hours or days.
And that what is needed to work in industry with high rate of change in
requirements and features required by customers. At the end of the day your
brain is trained to do the <strong>skimming automatically</strong> and this is
<strong>not always good</strong>.</p>
<p>For me the realization of something wrong came out some time ago when I was
trying to read new book on <code>Haskell</code>. I really wanted to enjoy the book and learn
few new things about the language which I already knew. But I’ve found myself
constantly jumping and skipping content. I was not focusing on the language of
the author, that did amazing job and had some deep insights on the language and
the functional programming paradigm.</p>
<p>Instead of focusing on the words and
learning new information, my brain was focusing on cycle of <code>finding</code> new things,
<code>alert</code> me about them, <code>discarding</code> them and repeating the cycle again. Same
experience repeated when I was reading blogs, browsing sites and in general when
I was consuming new technical content.</p>
<p>The solution for me was to <strong>slow down</strong> and reduce the distractions around the
content I consume. I am a long-time emacs user. One of the core principals in
emacs is <code>text as universal interface</code>. This means that you can do almost any
task using powerful text interfaces. Web browsing is one of the things you can
do without moving out from emacs.</p>
<p><img src="/static/files/posts/2022_11_15/neo-slow-down.jpg" style="width:50.0%;height:50.0%" /></p>
<p>The <a href="https://www.gnu.org/software/emacs/manual/html_mono/eww.html">eww package</a>
allows you to browse sites in emacs and to display the textual information
without leaving the emacs editor. It doesn’t run the fancy javascript code,
which between us mostly used to track and collect information about you. I
disabled the display of images by default. Mostly what I get is a clean text
containing information and in case of emergency I can just jump to
firefox/chrome using shortcut key.</p>
<p>Using textual browser allowed me to focus on blogs and articles I consume
without all the visual distractions around them.</p>
<p><img src="/static/files/posts/2022_11_15/browse-lwn.png" /></p>
<p>The second method I discovered was when I wanted to master <strong>touch typing</strong>
technique. I am programming for almost 20 years (ouch !!!) but most of my career
I wasn’t trying to type completely without looking at the keyboard. I was typing
pretty fast and using emacs with all the shortcuts allowed me to stream my code
very efficiently. But I didn’t try to type using the “home row method” and
without looking at the keyboard at all. Then one day it hit me: I am already
spending most of my time using keyboard so why not make an effort and master the
typing techniques.</p>
<p>So I started to learn <code>touch typing</code> and almost every tutorial on this subject
will tell you that you need to practice to build the muscle memory. There are a
lot of good sites like <a href="https://www.keybr.com">keybr.com</a>. But since I am an
emacs user I can just find a package that allows me to practice without leaving
the editor. I took the excellent <a href="https://github.com/hagleitn/speed-type">speed-type</a>
emacs extension and configured it to allow selecting any chunk of text in the
editor and practice typing on it (it will color correct letters in green, and
show me my speed statistics when I want).</p>
<p>Soon I learned that I can use this extension to focus more deeply on text. I
would browse to some interesting article let’s say in
<a href="https://news.ycombinator.com/">hacker news</a> using eww. I will switch to touch
typing practicing mode with the content of the article and I will type it. This
allows to slow down since average touch typing speed (<strong>60-70</strong> words per minute)
is much slower then average reading speed (<strong>250</strong> words per minute). Then you are
reading and typing the article in much slower phase but at the same time your
mind is focusing on the words and your fingers build muscle memory to improve
typing speed. <strong>Win Win.</strong></p>
<p><img src="/static/files/posts/2022_11_15/touch-typing.png" /></p>]]></description>
<pubDate>Tue, 15 Nov 2022 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2022-11-15-focus-technical-content.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>Debugging Makefile</title>
<link>http://budevg.github.io/posts/2019-09-25-make-debug.html</link>
<description><![CDATA[<p>Makefiles can become pretty complicated and you can spend many hours trying to
understand what’s going on in the build systems. Let’s create a basic make file.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode makefile"><code class="sourceCode makefile"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="dt">OBJS </span><span class="ch">:=</span><span class="st"> a.o b.o c.o</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="dt">TARGET </span><span class="ch">:=</span><span class="st"> app</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="dv">%.o:</span><span class="dt"> %.c</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a> gcc -o <span class="ch">$@</span> <span class="ch">$<</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="dv">$(TARGET):</span><span class="dt"> </span><span class="ch">$(</span><span class="dt">OBJS</span><span class="ch">)</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a> ld -o <span class="ch">$@</span> <span class="ch">$^</span></span></code></pre></div>
<p>let’s say we are not sure what’s inside the <code>OBJS</code> variable. We can add the
following target to the makefile</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode makefile"><code class="sourceCode makefile"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="dv">print-%:</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> <span class="ch">@</span><span class="fu">echo </span><span class="st">'</span><span class="ch">$*</span><span class="st">=</span><span class="ch">$($*)</span><span class="st">'</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> <span class="ch">@</span><span class="fu">echo </span><span class="st">' origin = </span><span class="ch">$(</span><span class="kw">origin</span><span class="st"> </span><span class="ch">$*)</span><span class="st">'</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a> <span class="ch">@</span><span class="fu">echo </span><span class="st">' flavor = </span><span class="ch">$(</span><span class="kw">flavor</span><span class="st"> </span><span class="ch">$*)</span><span class="st">'</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a> <span class="ch">@</span><span class="fu">echo </span><span class="st">' value = </span><span class="ch">$(</span><span class="kw">value</span><span class="st"> </span><span class="ch">$*)</span><span class="st">'</span></span></code></pre></div>
<p>and run</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> make print-OBJS</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="va">OBJS</span><span class="op">=</span>a.o <span class="ex">b.o</span> c.o</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a> <span class="ex">origin</span> = file</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">flavor</span> = simple</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">value</span> = a.o b.o c.o</span></code></pre></div>
<p>to get value of the variable.</p>]]></description>
<pubDate>Wed, 25 Sep 2019 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2019-09-25-make-debug.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>Let's talk about development environment</title>
<link>http://budevg.github.io/posts/2019-05-08-dev-environment.html</link>
<description><![CDATA[<p>If you are a developer, then you probably value the software stack that you use
for your daily tasks. I am not talking about specific programming language that you
use to develop the next gen product X in your shiny startup Y. I am talking about
more basic software. The operating system, the desktop GUI environment, the code
editor and a set of productivity tools that you select to make your life easier.</p>
<p>For me the journey to build my software stack was full of tries and errors and I am
still in the middle of it waiting for new adventures.</p>
<p>The first big discovery for me was focusing on <code>Emacs</code> as the one and only editor for me.
I was familiar with <code>Emacs</code> from my lisp studies in university but then I was using
it in vanilla form without any customizations. One day I observed a power user
working in <code>XEmacs</code> (at that time <code>XEmacs</code> project was superior to the gnu <code>Emacs</code> project).
It was amazing. Working in complete state of “flow” without constantly switching windows,
clicking buttons or even moving the mouse. It was fast and powerful and it had
everything inside (terminal, file manager, man pages). I started using <code>XEmacs</code>
first with the power configuration I borrowed from that guy and later
I built my own configuration which I maintain and update to this date. Since then
the gnu <code>Emacs</code> project came back to life and I switched to gnu <code>Emacs</code> which was now
delivering new releases in much faster iterations.</p>
<p>Switching to <code>Emacs</code> gave me great power and full control of my coding workflow. I was
able to overcome any obstacles by programming <code>Emacs</code> in lisp or by searching
for extensions online. Still my desktop environment was not perfect.</p>
<p>When I started programming I was using windows desktop. Since most of my work was
on a linux environment, I was running X server from cygwin on my windows desktop
and then connecting to the linux through ssh and X forwarding <code>Emacs</code> to my windows
desktop. Later I completely switched to linux and started running ubuntu distribution
as my main desktop client both at home and at work.</p>
<p>I started to maintain repository of notes with recipes of how to install ubuntu system
from scratch with all the software I use and all the desktop customization I want.
Installing system from scratch required to walk step by step through my notes and configuring
keyboard shortcuts, fonts, display settings, installing all the programs I use and then
configuring them. At the same time ubuntu was growing and publishing new releases.
The default desktop changed to unity but I didn’t like the new design. The GUI felt heavy and
not responsive on my home pc (which was not the latest and greatest hardware). At first
I switched to gnome classic but in later releases this option was removed and I decided to
try xubuntu which was the same ubuntu distribution but with the light xfce desktop environment.</p>
<p>Working on xubuntu was ok. It was light and fast and I customized it exactly as I wanted.
At the same time I started to learn about functional programming and taking a special
interest in Haskell programming language. As I became more fluent in writing code in Haskell,
I started to explore the Haskell applications ecosystem. I stumbled upon <code>Xmonad</code>,
which is a tilling windows manager which is very customizable and can be programmed in Haskell.
It reminded me <code>Emacs</code> which is also very customizable and can be programmed in Lisp. The concept
of tiling windows manager was new for me but I have always hated the constant need to adjust and
switch between floating windows.</p>
<p>I installed <code>Xmonad</code> and configured it as new xsession on the xubuntu system. I worked with
existing <code>Xmonad</code> configurations that I’ve found on github and modified them to match my own
preferences. The result was fast and customizable desktop experience. With shortcuts and
modifications matching my work flow. Each time I wanted to change something all I needed to do
was to update my <code>Xmonad</code> configuration with several lines of Haskell code.</p>
<p>Installing new software on my dekstop was always big issue for me. I wanted to avoid “polluting”
my distribution, but at the same time I wanted to try new software. The solution was to use
virtual machines through kvm or containers through docker. One day I read about new way to manage
software packages through software called <code>Nix</code> which was very popular among haskell developers.
The idea of <code>Nix</code> is to replace the global installation locations (/lib, /bin, etc.), with per
package unique locations. These locations include unique hash which computed based on the
package dependencies and it’s contents. The bottom line is that you can easily install new versions
of software (even versions that rely on different versions of the same library - no dll hell).
Additionally it allows you to easily revert back if the new package doesn’t work or even try the
new package inside isolated environment (nix-shell).</p>
<p>There are two ways to work with <code>Nix</code>. At first I used it as additional package manager together with
the default apt/dpkg to handle ubuntu packages. But <code>Nix</code> has it’s own linux distribution called
<code>Nixos</code>. It uses <code>Nix</code> package manager to configure the software and boot linux kernel. Everything
can be configured in descriptive way using the <code>Nix</code> expression language and all the advantages
of <code>Nix</code> package manager can be applied to the whole system. For example you can switch to new
kernel by changing configuration line and if the system doesn’t work as expected you can easily
revert to old version. Switching to <code>Nixos</code> solved for me two problems. The first was the problem of
installing all my software including os from scratch in deterministic way. Now I have
configuration of all my software and after bootstrapping <code>Nixos</code> I can just apply my configuration and
I am getting all my software configured and ready. The second problem was of installing new software
without “polluting” the distribution. Since <code>Nix</code> doesn’t have global state and each package can coexist
with each other package, trying new things is easy and after I am done I can invoke nix-collect-garbage
to get rid of leftovers.</p>
<p>So today my development environment is based on <code>Emacs</code>, <code>Xmonad</code> and <code>Nixos</code>. Configuration of each component
is maintained in separate github repository</p>
<ul>
<li><a href="https://github.com/budevg/emacs-conf">emacs-conf</a></li>
<li><a href="https://github.com/budevg/xmonad-conf">xmonad-conf</a></li>
<li><a href="https://github.com/budevg/nix-conf">nix-conf</a></li>
</ul>
<p><img src="/static/files/posts/2019_05_09/emacs-xmonad-nix.png" style="width:90.0%;height:90.0%" /></p>]]></description>
<pubDate>Wed, 08 May 2019 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2019-05-08-dev-environment.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>Cross compiling inside docker</title>
<link>http://budevg.github.io/posts/2018-08-02-docker-cross-compile.html</link>
<description><![CDATA[<p>Recently I needed to compile binaries for arm64 cpu. The fastest
way to do this is to build cross compilation toolchain and to run
x86 gcc that will generate arm64 executables.</p>
<p>Another way to do this is to use qemu’s user emulation. This
feature of qemu allows to run executables that were compiled for
different architecture on the x86 host by emulating the
architecture and translating the system calls abi between the
different architectures.</p>
<p>We can start by getting docker image with aarch64 centos
file system.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> pull aarch64/alpine</span></code></pre></div>
<p>If we try to run our image we will get execution format error</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> run <span class="at">-it</span> aarch64/alpine /bin/sh</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ex">standard_init_linux.go:195:</span> exec user process caused <span class="st">"exec format error"</span></span></code></pre></div>
<p>This is since we are trying to run aarch64 executable on x86 machine. By looking inside the image root file system we can see that the binary is an ARM aarch64 binary.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sudo file <span class="kw">`</span><span class="ex">d</span> inspect aarch64/alpine <span class="at">-f</span> <span class="st">'{{.GraphDriver.Data.RootDir}}'</span><span class="kw">`</span>/bin/busybox</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ex">/docker/overlay/edfece616e612e0aee33cfa5d0efe2b23c563d46ea232b2938d0e9c39a61273c/root/bin/busybox:</span> ELF 64-bit LSB shared object, ARM aarch64, version 1 <span class="er">(</span><span class="ex">SYSV</span><span class="kw">)</span><span class="ex">,</span> dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, stripped</span></code></pre></div>
<p>To help us in running these arm64 binaries we can use the qemu’s user emulation.
Firs we are going to compile static version of qemu’s user emulation for arm64 architecture.</p>
<p>We can use the following docker file to build the statically linked qemu inside docker instance. Edit <code>Dockerfile:</code></p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">FROM</span> centos:7</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="ex">RUN</span> set <span class="at">-x</span> <span class="dt">\</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="ex">yum</span> groupinstall <span class="at">-y</span> development <span class="dt">\</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="ex">yum</span> install <span class="at">-y</span> yum install wget glibc-static zlib-static pcre-static glib2-static</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="ex">RUN</span> set <span class="at">-x</span> <span class="dt">\</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="fu">mkdir</span> /data <span class="dt">\</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="bu">cd</span> /data <span class="dt">\</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="fu">wget</span> https://github.com/qemu/qemu/archive/v2.12.0.tar.gz <span class="dt">\</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="fu">tar</span> xvf <span class="pp">*</span>.tar.gz <span class="dt">\</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="bu">cd</span> qemu-2.12.0 <span class="dt">\</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="ex">./configure</span> <span class="at">--target-list</span><span class="op">=</span>aarch64-linux-user <span class="at">--enable-linux-user</span> <span class="at">--disable-system</span> <span class="at">--disable-tools</span> <span class="at">--static</span> <span class="dt">\</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a> <span class="kw">&&</span> <span class="fu">make</span> <span class="at">-j4</span></span></code></pre></div>
<p>Then we can copy the executable from it using</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> build <span class="at">-t</span> build-env .</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> run <span class="at">--rm</span> <span class="at">--name</span> build-env-instance <span class="at">-dt</span> build-env /bin/bash</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> cp build-env-instance:/data/qemu-2.12.0/aarch64-linux-user/qemu-aarch64 .</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> stop build-env-instance</span></code></pre></div>
<p>Now we have qemu-aarch64 in our current directory. Let’s use it to build docker instance
that can run aarch64 executables. Edit <code>Dockerfile.aarch64</code></p>
<div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">FROM</span> aarch64/alpine</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="ex">ADD</span> qemu-aarch64 /</span></code></pre></div>
<p>Let’s build it and try to run it.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> build <span class="at">-t</span> my-aarch64-env <span class="at">-f</span> Dockerfile.aarch64 .</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> run <span class="at">--rm</span> <span class="at">-it</span> my-aarch64-env /bin/sh</span></code></pre></div>
<p>But we are still getting:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ex">standard_init_linux.go:195:</span> exec user process caused <span class="st">"exec format error"</span></span></code></pre></div>
<p>The last step is to instruct our kernel to apply the qemu-aarch64 interpreter
each time we running arm64 elf file. This can be done using</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="co"># if /proc/sys/fs/binfmt_misc is not mounted</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> mount binfmt_misc <span class="at">-t</span> binfmt_misc /proc/sys/fs/binfmt_misc</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> bash <span class="at">-c</span> <span class="st">"echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register"</span></span></code></pre></div>
<p>And now we can run and compile arm64 code on x86</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> run <span class="at">--rm</span> <span class="at">-it</span> my-aarch64-env /bin/sh</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> uname <span class="at">-m</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="ex">aarch64</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> apk update <span class="at">-q</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> apk add <span class="at">-q</span> file</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> file /bin/busybox</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="ex">/bin/busybox:</span> ELF 64-bit LSB shared object, ARM aarch64, version 1 <span class="er">(</span><span class="ex">SYSV</span><span class="kw">)</span><span class="ex">,</span> dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, stripped</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> apk add gcc libc-dev <span class="at">-q</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> echo <span class="st">'int main() { printf("hello world\n"); }'</span> <span class="op">></span> 1.c</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> gcc 1.c</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="ex">1.c:</span> In function <span class="st">'main'</span>:</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a><span class="ex">1.c:1:14:</span> warning: implicit declaration of function <span class="st">'printf'</span> <span class="pp">[-</span><span class="ss">Wimplicit</span><span class="pp">-</span><span class="ss">function</span><span class="pp">-</span><span class="ss">declaration</span><span class="pp">]</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a> <span class="ex">int</span> main<span class="er">(</span><span class="kw">)</span> <span class="kw">{</span> <span class="bu">printf</span><span class="er">(</span><span class="st">"hello world\n"</span><span class="kw">);</span> <span class="kw">}</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a> <span class="ex">^~~~~~</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a><span class="ex">1.c:1:14:</span> warning: incompatible implicit declaration of built-in function <span class="st">'printf'</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a><span class="ex">1.c:1:14:</span> note: include <span class="st">'<stdio.h>'</span> or provide a declaration of <span class="st">'printf'</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> ./a.out</span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a><span class="ex">hello</span> world</span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> file a.out</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a><span class="ex">a.out:</span> ELF 64-bit LSB shared object, ARM aarch64, version 1 <span class="er">(</span><span class="ex">SYSV</span><span class="kw">)</span><span class="ex">,</span> dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, not stripped</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span></span></code></pre></div>
<p>If we run ps on our host we can see that the /bin/sh in the container is actually executed using the qemu-aarch64 interpreter</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> ps <span class="at">-ef</span> <span class="kw">|</span><span class="fu">grep</span> qemu <span class="kw">|</span><span class="fu">grep</span> <span class="at">-v</span> grep</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="ex">root</span> 16389 16362 0 12:14 pts/0 00:00:00 /qemu-aarch64 /bin/sh</span></code></pre></div>]]></description>
<pubDate>Thu, 02 Aug 2018 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2018-08-02-docker-cross-compile.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>Scratch space using tmpfs and friends</title>
<link>http://budevg.github.io/posts/2018-07-20-scratch-space.html</link>
<description><![CDATA[<p>When programming I tend to generate many files that I don’t want to save persistently on my storage media. Pdf documents I download, github repositories I clone to check something in source code and many other types of files should be stored somewhere but I would be glad to get rid of them when I power off my laptop.</p>
<p>For this purpose I use the following script which creates tmpfs memory backed file system which is mounted at <code>~/scratch</code>. I use this directory to store all temporary files and I know they will disappear after I reboot.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/bin/sh</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> mount <span class="at">-t</span> tmpfs <span class="at">-o</span> size=8G none ~/scratch/</span></code></pre></div>
<p>Another use case is when I want to temporarily install some packages to try new stuff. For example if I want to compile some <code>haskell</code> application using <code>stack</code>. Stack is going to pull and compile many new packages and it will store them at <code>~/.stack</code>. If I don’t want to persistently store all these packages on my storage media, I can do the following trick. Create <code>~/scratch/stack-shadow</code> directory. Use overlayfs to create new file system that mirrors the old directory and stores all modified or newly created files in new directory. Using <code>mount -o bind</code> to bind the overlayfs directory to the <code>~/.stack</code> location</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">mkdir</span> <span class="at">-p</span> ~/scratch/stack-shadow/upperdir <span class="dt">\</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a> ~/scratch/stack-shadow/workdir <span class="dt">\</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a> ~/scratch/stack-shadow/export</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> mount <span class="at">-t</span> overlay overlay <span class="dt">\</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> <span class="at">-olowerdir</span><span class="op">=</span>~/.stack <span class="dt">\</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> <span class="at">-oupperdir</span><span class="op">=</span>~/scratch/stack-shadow/upperdir <span class="dt">\</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> <span class="at">-oworkdir</span><span class="op">=</span>~/scratch/stack-shadow/workdir <span class="dt">\</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a> ~/scratch/stack-shadow/export</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> mount <span class="at">-o</span> bind ~/scratch/stack-shadow/export ~/.stack</span></code></pre></div>
<p>We can build a bash script to automate these commands.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/bin/bash</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> usage</span> <span class="kw">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="st">"usage: </span><span class="va">$0</span><span class="st"> <command> <src> <dst>"</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="st">"commands:"</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="at">-e</span> <span class="st">"\tnew - bind dst to location at src"</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="at">-e</span> <span class="st">"\tshadow - overlay src to dst, bind dst to src"</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="at">-e</span> <span class="st">"\tdup - overlay src to dst"</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="at">-e</span> <span class="st">"\tclear - umount src and dst"</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a> <span class="bu">exit</span> 1</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> new</span> <span class="kw">{</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a> <span class="bu">local</span> <span class="va">src</span><span class="op">=</span><span class="va">$1</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a> <span class="bu">local</span> <span class="va">dst</span><span class="op">=</span><span class="va">$2</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a> <span class="fu">mkdir</span> <span class="at">-p</span> <span class="va">$dst</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a> <span class="fu">sudo</span> mount <span class="at">-o</span> bind <span class="va">$dst</span> <span class="va">$src</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> shadow</span> <span class="kw">{</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a> <span class="bu">local</span> <span class="va">src</span><span class="op">=</span><span class="va">$1</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a> <span class="bu">local</span> <span class="va">dst</span><span class="op">=</span><span class="va">$2</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a> <span class="ex">dup</span> <span class="va">$src</span> <span class="va">$dst</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a> <span class="fu">sudo</span> mount <span class="at">-o</span> bind <span class="va">$dst</span>/export <span class="va">$src</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> dup</span> <span class="kw">{</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a> <span class="bu">local</span> <span class="va">src</span><span class="op">=</span><span class="va">$1</span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a> <span class="bu">local</span> <span class="va">dst</span><span class="op">=</span><span class="va">$2</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a> <span class="fu">mkdir</span> <span class="at">-p</span> <span class="va">$dst</span>/upperdir <span class="va">$dst</span>/workdir <span class="va">$dst</span>/export</span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a> <span class="fu">sudo</span> mount <span class="at">-t</span> overlay overlay <span class="at">-olowerdir</span><span class="op">=</span><span class="va">$src</span> <span class="at">-oupperdir</span><span class="op">=</span><span class="va">$dst</span>/upperdir <span class="at">-oworkdir</span><span class="op">=</span><span class="va">$dst</span>/workdir <span class="va">$dst</span>/export</span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span><span class="fu"> clear</span> <span class="kw">{</span></span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a> <span class="bu">local</span> <span class="va">src</span><span class="op">=</span><span class="va">$1</span></span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a> <span class="bu">local</span> <span class="va">dst</span><span class="op">=</span><span class="va">$2</span></span>
<span id="cb3-37"><a href="#cb3-37" aria-hidden="true" tabindex="-1"></a> <span class="bu">test</span> <span class="at">-d</span> <span class="va">$src</span> <span class="kw">&&</span> <span class="fu">sudo</span> umount <span class="va">$src</span></span>
<span id="cb3-38"><a href="#cb3-38" aria-hidden="true" tabindex="-1"></a> <span class="bu">test</span> <span class="at">-d</span> <span class="va">$dst</span>/export <span class="kw">&&</span> <span class="fu">sudo</span> umount <span class="va">$dst</span>/export</span>
<span id="cb3-39"><a href="#cb3-39" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
<span id="cb3-40"><a href="#cb3-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-41"><a href="#cb3-41" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="bu">[</span> <span class="va">$#</span> <span class="ot">-lt</span> 3 <span class="bu">]</span><span class="kw">;</span> <span class="cf">then</span> <span class="ex">usage</span><span class="kw">;</span> <span class="cf">fi</span></span>
<span id="cb3-42"><a href="#cb3-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-43"><a href="#cb3-43" aria-hidden="true" tabindex="-1"></a><span class="bu">set</span> <span class="at">-x</span></span>
<span id="cb3-44"><a href="#cb3-44" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-45"><a href="#cb3-45" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> <span class="st">"</span><span class="va">$1</span><span class="st">"</span> <span class="kw">in</span></span>
<span id="cb3-46"><a href="#cb3-46" aria-hidden="true" tabindex="-1"></a> <span class="ss">new</span><span class="kw">)</span></span>
<span id="cb3-47"><a href="#cb3-47" aria-hidden="true" tabindex="-1"></a> <span class="ex">new</span> <span class="va">$2</span> <span class="va">$3</span></span>
<span id="cb3-48"><a href="#cb3-48" aria-hidden="true" tabindex="-1"></a> <span class="cf">;;</span></span>
<span id="cb3-49"><a href="#cb3-49" aria-hidden="true" tabindex="-1"></a> <span class="ss">shadow</span><span class="kw">)</span></span>
<span id="cb3-50"><a href="#cb3-50" aria-hidden="true" tabindex="-1"></a> <span class="ex">shadow</span> <span class="va">$2</span> <span class="va">$3</span></span>
<span id="cb3-51"><a href="#cb3-51" aria-hidden="true" tabindex="-1"></a> <span class="cf">;;</span></span>
<span id="cb3-52"><a href="#cb3-52" aria-hidden="true" tabindex="-1"></a> <span class="ss">dup</span><span class="kw">)</span></span>
<span id="cb3-53"><a href="#cb3-53" aria-hidden="true" tabindex="-1"></a> <span class="ex">dup</span> <span class="va">$2</span> <span class="va">$3</span></span>
<span id="cb3-54"><a href="#cb3-54" aria-hidden="true" tabindex="-1"></a> <span class="cf">;;</span></span>
<span id="cb3-55"><a href="#cb3-55" aria-hidden="true" tabindex="-1"></a> <span class="ss">clear</span><span class="kw">)</span></span>
<span id="cb3-56"><a href="#cb3-56" aria-hidden="true" tabindex="-1"></a> <span class="fu">clear</span> <span class="va">$2</span> <span class="va">$3</span></span>
<span id="cb3-57"><a href="#cb3-57" aria-hidden="true" tabindex="-1"></a> <span class="cf">;;</span></span>
<span id="cb3-58"><a href="#cb3-58" aria-hidden="true" tabindex="-1"></a> <span class="pp">*</span><span class="kw">)</span></span>
<span id="cb3-59"><a href="#cb3-59" aria-hidden="true" tabindex="-1"></a> <span class="ex">usage</span></span>
<span id="cb3-60"><a href="#cb3-60" aria-hidden="true" tabindex="-1"></a><span class="cf">esac</span></span></code></pre></div>]]></description>
<pubDate>Fri, 20 Jul 2018 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2018-07-20-scratch-space.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>Virtualization life cycle in Amazon</title>
<link>http://budevg.github.io/posts/2017-12-01-virt-lifecycle.html</link>
<description><![CDATA[<p>During excellent presentation at <a href="https://reinvent.awsevents.com/">AWS re:invent</a>,
Anthony Liguori who was <a href="https://www.qemu.org/">QEMU’s</a> maintainer in the past,
is telling us the story of virtualization infrastructure at Amazon. Ironically
this is a story of hardware problem which starts with software solution and
gradually replaced with hardware to make solution more efficient.</p>
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/LabltEXk0VQ" frameborder="0" allowfullscreen>
</iframe>
</center>]]></description>
<pubDate>Fri, 01 Dec 2017 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2017-12-01-virt-lifecycle.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>RDMA 101 - Buiding virtual setup</title>
<link>http://budevg.github.io/posts/2017-04-29-rdma-101-1.html</link>
<description><![CDATA[<p>We are going to explore RDMA and it’s applications in a series of tutorials
starting with this one.</p>
<p>The first step is to build virtual environment where we can run our applications.
Usually RDMA communication requires special RDMA capable
NIC on your server. Many vendors, such as
<a href="https://www.mellanox.com/">Mellanox</a>, sell this hardware but for
our development effort we are going to build a virtual environment based on
<a href="http://www.qemu-project.org/">qemu</a> and
<a href="https://github.com/zrlio/softiwarp">softiwarp</a> software.</p>
<h1 id="virtual-environment">Virtual environment</h1>
<h2 id="base-image">Base image</h2>
<p>We start with ubuntu 16.04.2 qemu image. It has linux kernel 4.8 installed and
a basic development tools</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sudo apt-get install linux-generic-hwe-16.04 build-essential <span class="dt">\</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> automake autoconf libtool</span></code></pre></div>
<p>Let’s call this image <code>ubuntu-16.04.2-dev</code>. We are going to create another
image based on this image with all the rdma stack installed on it
called <code>ubuntu-rdma.qcow2</code></p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> qemu-img create <span class="at">-f</span> qcow2 <span class="at">-b</span> ubuntu-16.04.2-dev ubuntu-rdma.qcow2</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ex">Formatting</span> <span class="st">'ubuntu-rdma.qcow2'</span> ...</span></code></pre></div>
<p>Let’s start a guest and install RDMA stack inside of it.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">kvm</span> <span class="at">-m</span> 1G <span class="dt">\</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>-netdev user,hostfwd=tcp::5555-:22,id=net0 <span class="dt">\</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>-device virtio-net-pci,netdev=net0 <span class="dt">\</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>-drive if=virtio,file=ubuntu-rdma.qcow2,cache=unsafe</span></code></pre></div>
<p>We can ssh to guest through local port 5555 which is redirected to port
22 on guest.</p>
<h2 id="install-rdma-libraries-and-tools">Install RDMA libraries and tools</h2>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sudo apt-get install libibverbs-dev librdmacm-dev <span class="dt">\</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> rdmacm-utils perftest ibverbs-utils</span></code></pre></div>
<h2 id="install-softiwarp">Install SoftiWARP</h2>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> git clone https://github.com/zrlio/softiwarp.git</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ex">...</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> pushd softiwarp/kernel</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> make</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sudo mkdir <span class="at">-p</span> /lib/modules/<span class="kw">`</span><span class="fu">uname</span> <span class="at">-r</span><span class="kw">`</span>/kernel/extra</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sudo cp siw.ko /lib/modules/<span class="kw">`</span><span class="fu">uname</span> <span class="at">-r</span><span class="kw">`</span>/kernel/extra</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sudo depmod <span class="at">-a</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> popd</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> pushd softiwarp/userlib</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> ./autogen.sh <span class="kw">&&</span> <span class="ex">./configure</span> <span class="at">--prefix</span><span class="op">=</span> <span class="kw">&&</span> <span class="fu">make</span> <span class="kw">&&</span> <span class="fu">sudo</span> make install</span></code></pre></div>
<h2 id="shutdown">Shutdown</h2>
<div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> shutdown <span class="at">-h</span> now</span></code></pre></div>
<h2 id="create-two-guests">Create two guests</h2>
<p>Based on the <code>ubuntu-rdma.qcow2</code> image we just created let’s build two
images <code>vm1.qcow2</code> and <code>vm2.qcow2</code></p>
<div class="sourceCode" id="cb7"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> for i in <span class="dt">{</span><span class="dv">1</span><span class="dt">..</span><span class="dv">2</span><span class="dt">}</span><span class="kw">;</span> <span class="cf">do</span> <span class="ex">qemu-img</span> create <span class="at">-f</span> qcow2 <span class="at">-b</span> ubuntu-rdma.qcow2 vm<span class="va">${i}</span>.qcow2<span class="kw">;</span> <span class="cf">done</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> ls vm<span class="pp">*</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1.qcow2</span> vm2.qcow2</span></code></pre></div>
<p>Now we are going to run both guest. Each of them will have two network interfaces.
The first interface is configured to allow access from the guest to the internet
and to allow access from the host to the guest’s ssh service by connecting to
local port 5551 (or 5552 for second vm). The second network interface will
be used for rdma access we are going to use qemu’s feature to create network
using UDP multicast socket.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> i <span class="kw">in</span> <span class="dt">{</span><span class="dv">1</span><span class="dt">..</span><span class="dv">2</span><span class="dt">}</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="cf">do</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a> <span class="ex">kvm</span> <span class="at">-name</span> vm<span class="va">${i}</span> <span class="at">-m</span> 1G <span class="dt">\</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a> <span class="at">-netdev</span> user,hostfwd=tcp::555<span class="va">${i}</span>-:22,id=net0 <span class="dt">\</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a> <span class="at">-device</span> virtio-net-pci,netdev=net0 <span class="dt">\</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a> <span class="at">-netdev</span> socket,mcast=230.0.0.1:1234,id=net1 <span class="dt">\</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a> <span class="at">-device</span> virtio-net-pci,mac=52:54:00:12:34:0<span class="va">${i}</span>,netdev=net1 <span class="dt">\</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a> <span class="at">-drive</span> if=virtio,file=vm<span class="va">${i}</span>.qcow2,cache=unsafe <span class="kw">&</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="cf">done</span></span></code></pre></div>
<p>Now login to each of the machines and set hostname and ip for the rdma nic:</p>
<ul>
<li>vm1</li>
</ul>
<div class="sourceCode" id="cb9"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ssh</span> <span class="at">-p</span> 5551 localhost</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ sudo bash <span class="at">-c</span> <span class="st">'echo 127.0.0.1 vm1 >> /etc/hosts'</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ sudo hostnamectl set-hostname vm1</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ sudo su</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ cat <span class="op"><< EOF</span> <span class="op">>></span> /etc/network/interfaces</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="st">auto ens4</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="st">iface ens4 inet static</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="st"> address 10.0.0.1</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="st"> netmask 255.255.255.0</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a><span class="op">EOF</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ ifup ens4</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ exit</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ exit</span></code></pre></div>
<ul>
<li>vm2</li>
</ul>
<div class="sourceCode" id="cb10"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ssh</span> <span class="at">-p</span> 5552 localhost</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ sudo bash <span class="at">-c</span> <span class="st">'echo 127.0.0.1 vm2 >> /etc/hosts'</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ sudo hostnamectl set-hostname vm2</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ sudo su</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ cat <span class="op"><< EOF</span> <span class="op">>></span> /etc/network/interfaces</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="st">auto ens4</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="st">iface ens4 inet static</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="st"> address 10.0.0.2</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="st"> netmask 255.255.255.0</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a><span class="op">EOF</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ ifup ens4</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ exit</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ exit</span></code></pre></div>
<p>Make sure that your host firewall is not blocking the udp broadcast over port 1234</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sudo iptables <span class="at">-A</span> INPUT <span class="at">-p</span> udp <span class="at">--dport</span> 1234 <span class="at">-j</span> ACCEPT</span></code></pre></div>
<h2 id="check-tcp-connectivity">Check tcp connectivity</h2>
<div class="sourceCode" id="cb12"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ ping 10.0.0.2</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="ex">PING</span> 10.0.0.2 <span class="er">(</span><span class="ex">10.0.0.2</span><span class="kw">)</span> <span class="ex">56</span><span class="er">(</span><span class="ex">84</span><span class="kw">)</span> <span class="ex">bytes</span> of data.</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="ex">64</span> bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.671 ms</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="ex">64</span> bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.776 ms</span></code></pre></div>
<h2 id="check-rdma-connectivity">Check RDMA connectivity</h2>
<ul>
<li>vm1</li>
</ul>
<div class="sourceCode" id="cb13"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ sudo modprobe <span class="at">-a</span> siw rdma_ucm</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ rping <span class="at">-s</span> <span class="at">-a</span> 10.0.0.1 <span class="at">-v</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="ex">server</span> ping data: rdma-ping-0: ABCDEFGHIJKLMNOPQRSTUVWXYZ[<span class="dt">\]</span>^_<span class="kw">`</span><span class="ex">abcdefghijklmnopqr</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="ex">server</span> ping data: rdma-ping-1: BCDEFGHIJKLMNOPQRSTUVWXYZ[<span class="dt">\]</span>^_<span class="kw">`</span>abcdefghijklmnopqrs</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="ex">server</span> DISCONNECT EVENT...</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a><span class="bu">wait</span> for RDMA_READ_ADV state 10</span></code></pre></div>
<ul>
<li>vm2</li>
</ul>
<div class="sourceCode" id="cb14"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ sudo modprobe <span class="at">-a</span> siw rdma_ucm</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ rping <span class="at">-c</span> <span class="at">-a</span> 10.0.0.1 <span class="at">-C</span> 2 <span class="at">-v</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="fu">ping</span> data: rdma-ping-0: ABCDEFGHIJKLMNOPQRSTUVWXYZ[<span class="dt">\]</span>^_<span class="kw">`</span><span class="ex">abcdefghijklmnopqr</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="fu">ping</span> data: rdma-ping-1: BCDEFGHIJKLMNOPQRSTUVWXYZ[<span class="dt">\]</span>^_<span class="kw">`</span>abcdefghijklmnopqrs</span></code></pre></div>
<h2 id="check-rdma-bandwidth-and-latency">Check RDMA bandwidth and latency</h2>
<h3 id="bandwidth">Bandwidth</h3>
<ul>
<li>vm1</li>
</ul>
<div class="sourceCode" id="cb15"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ ibv_devices</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a> <span class="ex">device</span> node GUID</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a> <span class="ex">------</span> <span class="at">----------------</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">siw_ens3</span> 5254001234560000</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">siw_lo</span> 7369775f6c6f0000</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a> <span class="ex">siw_ens4</span> 5254001234010000</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ sudo su</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ ulimit <span class="at">-l</span> unlimited</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ ib_write_bw <span class="at">-R</span> <span class="at">-d</span> siw_ens4 <span class="at">-i</span> 1 <span class="at">-D</span> 10 <span class="at">-F</span></span></code></pre></div>
<ul>
<li>vm2</li>
</ul>
<div class="sourceCode" id="cb16"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ sudo su</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ ulimit <span class="at">-l</span> unlimited</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ ib_write_bw <span class="at">-R</span> <span class="at">-d</span> siw_ens4 <span class="at">-i</span> 1 <span class="at">-D</span> 10 <span class="at">-F</span> 10.0.0.1</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ex">...</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a> <span class="co">#bytes #iterations BW peak[MB/sec] BW average[MB/sec] MsgRate[Mpps]</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a> <span class="ex">65536</span> 3200 0.00 33.33 0.000533</span></code></pre></div>
<p>The results are really lame but please remember we are using
virtual environment so performance is always bad here</p>
<h3 id="latency">Latency</h3>
<ul>
<li>vm1</li>
</ul>
<div class="sourceCode" id="cb17"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ex">vm1</span> $ ib_write_lat <span class="at">-R</span> <span class="at">-d</span> siw_ens4 <span class="at">-i</span> 1 <span class="at">-D</span> 10 <span class="at">-F</span></span></code></pre></div>
<ul>
<li>vm2</li>
</ul>
<div class="sourceCode" id="cb18"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ex">vm2</span> $ ib_write_lat <span class="at">-R</span> <span class="at">-d</span> siw_ens4 <span class="at">-i</span> 1 <span class="at">-D</span> 10 <span class="at">-F</span> 10.0.0.1</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="ex">...</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a> <span class="co">#bytes #iterations t_avg[usec]</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a> <span class="ex">2</span> 4316 695.11</span></code></pre></div>
<p>Same lame results due to the nature of our virtual setup and the use of
softiwarp instead of real RDMA capable hardware</p>
<h1 id="summary">Summary</h1>
<p>Now we have a working setup of two vm’s which can communicate using RDMA. In
the next posts we are going to explore more interesting RDMA stuff.</p>]]></description>
<pubDate>Sat, 29 Apr 2017 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2017-04-29-rdma-101-1.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
<item>
<title>World Of Podcasts</title>
<link>http://budevg.github.io/posts/2017-03-31-podcast-world.html</link>
<description><![CDATA[<p>There was a time when I was listening to radio on my way to work. When I went for
a jogging I was hearing mostly music and sometimes audio books. Since radio was
mostly boring politics and bad news, I’ve stopped with this waste of time.
I started listening to podcasts.</p>
<p>At first these were mostly podcasts related to my professional interests:
programming, security and startups. Later I subscribed to more and more podcasts
with more general content: science, sci-fi/mystery stories, theory of the mind,
history, entrepreneurs life and more. Below is the list of podcasts that I
currently enjoy the most. The podcasts are in English, Russian and Hebrew.</p>
<h2 id="sci-fimysterythriller">Sci-Fi/Mystery/Thriller</h2>
<ul>
<li><a href="http://theblacktapespodcast.com">The Black Tapes</a></li>
<li><a href="http://www.tanispodcast.com">Tanis</a></li>
<li><a href="https://www.rabbitspodcast.com">Rabbits</a></li>
<li><a href="https://gimletmedia.com/homecoming">Homecoming</a></li>
<li><a href="http://themessagepodcast.com">The Message</a></li>
<li><a href="http://lif-e.af/ter">LifeAfter</a></li>
<li><a href="http://fantaskop.podfm.ru">Фантаскоп</a> (Russian)</li>
<li><a href="https://geeksguideshow.com">Geek’s Guide to the Galaxy</a></li>
<li><a href="https://soundcloud.com/decodingwestworld">Decoding Westworld</a></li>
</ul>
<h2 id="haskell">Haskell</h2>
<ul>
<li><a href="http://www.haskellcast.com">The Haskell Cast</a></li>
<li><a href="https://bananasandlenses.net">Бананы и линзы</a> (Russian)</li>
</ul>
<h2 id="python">Python</h2>
<ul>
<li><a href="https://talkpython.fm">Talk Python To Me</a></li>
</ul>
<h2 id="go">Go</h2>
<ul>
<li><a href="http://golangshow.com">GolangShow</a> (Russian)</li>
<li><a href="https://changelog.com/gotime">Go Time</a></li>
</ul>
<h2 id="cc">C/C++</h2>
<ul>
<li><a href="http://cppcast.libsyn.com">CppCast</a></li>
</ul>
<h2 id="storage">Storage</h2>
<ul>
<li><a href="http://silvertonconsulting.com/gbos2">GreyBeards on Storage</a></li>
<li><a href="http://storageunpacked.com">Storage Unpacked</a></li>
<li><a href="http://www.snia.org/sites/default/files/podcasts/SDC/SDCpodcast.xml">Storage Developer Conference</a></li>
</ul>
<h2 id="kernel">Kernel</h2>
<ul>
<li><a href="http://jcm.libsyn.com">Linux Kernel Podcast</a></li>
</ul>
<h2 id="entrepreneurs">Entrepreneurs</h2>
<ul>
<li><a href="https://awesound.com/@ycombinator/feed/how-to-start-a-startup">How to Start a Startup</a></li>
<li><a href="https://gimletmedia.com/startup">StartUp</a></li>
<li><a href="http://www.shavua.net">השבוע</a> (Hebrew)</li>
<li><a href="http://www.npr.org/podcasts/510313/how-i-built-this">How I Built This</a></li>
<li><a href="http://www.ranlevi.com/biz">עושים עסקים</a> (Hebrew)</li>
<li><a href="http://creative.gimletmedia.com/shows/open-for-business/">Open For Business</a></li>
<li><a href="https://semek.podbean.com">S-Emek</a> (Hebrew)</li>
</ul>
<h2 id="security">Security</h2>
<ul>
<li><a href="https://www.grc.com/securitynow.htm">Security Now</a></li>
</ul>
<h2 id="management">Management</h2>
<ul>
<li><a href="http://www.mngttips.com">טיפים בניהול</a> (Hebrew)</li>
<li><a href="https://files.manager-tools.com/files/public/feeds/manager-tools-podcasts.xml">Manager Tools</a></li>
</ul>
<h2 id="programming-general">Programming general</h2>
<ul>
<li><a href="http://codepodcast.com">Code Podcast</a></li>
<li><a href="https://radio-t.com">Радио-Т</a> (Russian)</li>
<li><a href="https://sdcast.ksdaemon.ru">SDCast</a> (Russian)</li>
<li><a href="https://theartofprogramming.podbean.com">The Art Of Programming</a> (Russian)</li>
<li><a href="http://www.reversim.com">רברס עם פלטפורמה</a> (Hebrew)</li>
<li><a href="http://razbor-poletov.com">Разбор Полетов</a> (Russian)</li>
<li><a href="https://www.functionalgeekery.com">Functional Geekery</a></li>
<li><a href="http://devzen.ru">DevZen Podcast</a> (Russian)</li>
<li><a href="http://testandcode.com">Test and Code</a></li>
<li><a href="https://changelog.com/podcast">The Changelog</a></li>
<li><a href="http://softwareengineeringdaily.com">Software Engineering Daily</a></li>
</ul>
<h2 id="sciencehistorypeople">Science/History/People</h2>
<ul>
<li><a href="http://www.ranlevi.com">עושים היסטוריה</a> (Hebrew)</li>
<li><a href="http://www.cmpod.net">Curious Minds Podcast</a></li>
<li><a href="https://gimletmedia.com/science-vs">Science Vs</a></li>
<li><a href="http://www.radiolab.org">Radiolab</a></li>
<li><a href="https://gimletmedia.com/reply-all">Reply All</a></li>
<li><a href="https://www.bloomberg.com/podcasts/decrypted">Decrypted</a></li>
<li><a href="https://gimletmedia.com/surprisingly-awesome">Surprisingly Awesome</a></li>
<li><a href="https://gimletmedia.com/heavyweight">Heavyweight</a></li>
<li><a href="https://gimletmedia.com/undone">Undone</a></li>
<li><a href="http://www.npr.org/podcasts/510307/invisibilia">Invisibilia</a></li>
<li><a href="https://geekonomy.net">גיקונומי</a> (Hebrew)</li>
<li><a href="https://soundcloud.com/jewish-boys">Two Nice Jewish Boys</a></li>
<li><a href="https://gimletmedia.com/mystery-show">Mystery Show</a></li>
</ul>
<h2 id="mindself-improve">Mind/Self Improve</h2>
<ul>
<li><a href="http://www.npr.org/series/423302056/hidden-brain">Hidden Brain</a></li>
<li><a href="http://metalearn.libsyn.com">MetaLearn</a></li>
</ul>
<h2 id="financial">Financial</h2>
<ul>
<li><a href="http://www.ranlevi.com/shivuk">עושים שיווק</a> (Hebrew)</li>
<li><a href="http://www.npr.org/sections/money">Planet Money</a></li>
<li><a href="http://www.added-value.co">ערך מוסף</a> (Hebrew)</li>
</ul>
<h2 id="travel">Travel</h2>
<ul>
<li><a href="http://www.ranlevi.com/tiuol">עושים טיול</a> (Hebrew)</li>
</ul>]]></description>
<pubDate>Fri, 31 Mar 2017 00:00:00 UT</pubDate>
<guid>http://budevg.github.io/posts/2017-03-31-podcast-world.html</guid>
<dc:creator>Evgeny Budilovsky</dc:creator>
</item>
</channel>
</rss>