<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Mohit Choudhary - Notes</title>
    <link rel="self" type="application/atom+xml" href="https://ms-choudhary.github.io/notes/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-09-17T00:00:00+00:00</updated>
    <id>https://ms-choudhary.github.io/notes/atom.xml</id>
    <entry xml:lang="en">
        <title>Gmail Tricks</title>
        <published>2026-09-17T00:00:00+00:00</published>
        <updated>2026-09-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/email/gmail-tricks/"/>
        <id>https://ms-choudhary.github.io/notes/email/gmail-tricks/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/email/gmail-tricks/">&lt;h3 id=&quot;plus-trick&quot;&gt;Plus trick&lt;&#x2F;h3&gt;
&lt;p&gt;You can create custom email address with plus sign to classify senders and create blocks. For eg,&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ms.choudhary+netflix@gmail.com
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Some websites block this.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dot-trick&quot;&gt;Dot trick&lt;&#x2F;h3&gt;
&lt;p&gt;You can have any number of dots in the email address, for cases, where plus is blocked.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;m.s.choud.hary@gmail.com
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Global Internet Routing</title>
        <published>2026-09-09T00:00:00+00:00</published>
        <updated>2026-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/internet-routing/"/>
        <id>https://ms-choudhary.github.io/notes/networking/internet-routing/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/internet-routing/">&lt;p&gt;As a end user, we&#x27;ve very simplistic view of internet, we send a packet and it magically lands at google.com for example. &quot;There&#x27;s no real cloud, only other people&#x27;s computers&quot;.&lt;&#x2F;p&gt;
&lt;p&gt;Bulk of internet is still physically connected, with cables under the sea connecting continents. It uses a special cable known as &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Submarine_communications_cable&quot;&gt;submarine communication cable&lt;&#x2F;a&gt; , see the &lt;a href=&quot;https:&#x2F;&#x2F;www.submarinecablemap.com&#x2F;&quot;&gt;map&lt;&#x2F;a&gt; for the interconnections.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;level-of-connections&quot;&gt;Level of connections&lt;&#x2F;h3&gt;
&lt;p&gt;If you connect, two computers together, it&#x27;s a point to point connection.&lt;&#x2F;p&gt;
&lt;p&gt;If you connect multiple computers via LAN, they are part of same network in the broadcast domain.&lt;&#x2F;p&gt;
&lt;p&gt;You use router to connect multiple such L2 networks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;autonomous-systems&quot;&gt;Autonomous Systems&lt;&#x2F;h3&gt;
&lt;p&gt;At high level, AS, is a bunch of networks grouped together. It could have multiple internal networks with independent IP address space.&lt;&#x2F;p&gt;
&lt;p&gt;An AS can control a set of IP address.&lt;&#x2F;p&gt;
&lt;p&gt;Autonomous Systems Number (ASN) is assigned by IANA along with &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;ip-allocation&#x2F;&quot;&gt;ip-allocation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;peering&quot;&gt;Peering&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;internet.png&quot; alt=&quot;&quot; &#x2F;&gt;
Peering connects multiple such networks (AS) physically. This allows sharing routing info via bgp. Such connections are called peering points or internet exchange points (IXPs). These are strategically located in data warehouses across the globe. The central stars in above diagrams are the IXPs.&lt;&#x2F;p&gt;
&lt;p&gt;Peering and ASN are public information available at &lt;a href=&quot;https:&#x2F;&#x2F;www.peeringdb.com&#x2F;net&#x2F;1903&quot;&gt;peeringdb&lt;&#x2F;a&gt;. Useful when you&#x27;re planning to setup a datacenter. &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;hardware&#x2F;building-datacenter&#x2F;&quot;&gt;building-datacenter&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Not every network directly peers with others at public IXP, there&#x27;re private connection as well.&lt;&#x2F;p&gt;
&lt;p&gt;Also check &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;List_of_Internet_exchange_points&quot;&gt;list of internet exchange points&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>IP Allocation</title>
        <published>2026-09-09T00:00:00+00:00</published>
        <updated>2026-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/ip-allocation/"/>
        <id>https://ms-choudhary.github.io/notes/networking/ip-allocation/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/ip-allocation/">&lt;p&gt;Internet Assigned Numbers Association (IANA) (administered by ICANN) oversees:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;global ip address allocation&lt;&#x2F;li&gt;
&lt;li&gt;autonomous systems number allocation&lt;&#x2F;li&gt;
&lt;li&gt;root zone management&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;rir&quot;&gt;RIR&lt;&#x2F;h3&gt;
&lt;p&gt;Except the private address space &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;subnets&#x2F;#ipv4-address-blocks&quot;&gt;IPv4 Address blocks&lt;&#x2F;a&gt;, it assigns large blocks of address space to Regional Internet Registry (RIR). Ex:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;AFRINIC&lt;&#x2F;li&gt;
&lt;li&gt;APNIC&lt;&#x2F;li&gt;
&lt;li&gt;ARIN (Americas)&lt;&#x2F;li&gt;
&lt;li&gt;LACNIC (Latin America)&lt;&#x2F;li&gt;
&lt;li&gt;RIPE NCC (Europe)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;RIRs further assigns blocks to Local Internet Registries, which assign it to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Internet Service Providers (ISPs)&lt;&#x2F;li&gt;
&lt;li&gt;Large Education Institutions&lt;&#x2F;li&gt;
&lt;li&gt;Large Enterprises&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;ISPs can further delegate to other entities as they see fit.&lt;&#x2F;p&gt;
&lt;p&gt;If you see an ip from AFRINIC, it can be misleading to infer that it originates from africa. Ip address are not bound by physical location, it just means the administrative ownership lies with AFRINIC.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;address-assignment&quot;&gt;Address Assignment&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&#x2F;8 = RIR&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;16, &#x2F;17, &#x2F;18, &#x2F;19 = LIR, ISPs, Large business&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;20 = Small ISPs, Large business&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;24 = LAN&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Link Local Address</title>
        <published>2026-09-09T00:00:00+00:00</published>
        <updated>2026-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/link-local-address/"/>
        <id>https://ms-choudhary.github.io/notes/networking/link-local-address/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/link-local-address/">&lt;p&gt;Address in IPv4 169.254.0.0&#x2F;16 block are used for Link Local Adderss. These addresses are automatically assigned by the host, using known standard algorithm, used when no DHCP is found. Not forwarded by the router.&lt;&#x2F;p&gt;
&lt;p&gt;Used for networking configuration in devices (like Printer) on the network without DHCP.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Traceroute&#x2F; MTR</title>
        <published>2026-09-09T00:00:00+00:00</published>
        <updated>2026-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/traceroute-mtr/"/>
        <id>https://ms-choudhary.github.io/notes/networking/traceroute-mtr/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/traceroute-mtr/">&lt;p&gt;Traceroute uses incremental TTLs on IP packets to figure out hops on the network. TTL is decremented by one on every hop. Once TTL is zero, router sends back ICMP time exceeded.&lt;&#x2F;p&gt;
&lt;p&gt;MTR is traceroute + ping.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;perform-as-number-lookup&quot;&gt;Perform AS number lookup&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mtr --aslookup yahoo.com
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Whois</title>
        <published>2026-09-09T00:00:00+00:00</published>
        <updated>2026-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/whois/"/>
        <id>https://ms-choudhary.github.io/notes/networking/whois/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/whois/">&lt;p&gt;Use whois to figure out public details about a IP block&#x2F; domain name.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;custom-server&quot;&gt;Custom server&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ whois -h whois.cymru.com 142.250.182.46
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;AS      | IP               | AS Name
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;15169   | 142.250.182.46   | GOOGLE - Google LLC, US
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best Practices</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/claude-code/best-practices/"/>
        <id>https://ms-choudhary.github.io/notes/claude-code/best-practices/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/claude-code/best-practices/">&lt;p&gt;The most critical resource when working with agents is context window. It holds entire conversation, every message, every file claude reads, every command output. It fills up quite fast. And performance starts degrading after that, with symptoms like forgetting earlier work or making mistakes.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;&#x2F;clear&lt;&#x2F;code&gt; to clear context when starting unrelated&#x2F;new work.&lt;&#x2F;li&gt;
&lt;li&gt;Use subagents&lt;&#x2F;li&gt;
&lt;li&gt;Add statusline via &lt;code&gt;&#x2F;statusline&lt;&#x2F;code&gt; to always show model name and context&lt;&#x2F;li&gt;
&lt;li&gt;Use &lt;code&gt;&#x2F;insights&lt;&#x2F;code&gt; to generate a html detailing things that work, that needs improvement in your CC usage&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;use-right-model&quot;&gt;Use Right Model&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Sonnet - good with coding&lt;&#x2F;li&gt;
&lt;li&gt;Opus - use for complex architectural decisions, and planning&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Hooks - run specific command at steps in claude code.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>CLAUDE.md, Auto memory</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/claude-code/claude-md/"/>
        <id>https://ms-choudhary.github.io/notes/claude-code/claude-md/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/claude-code/claude-md/">&lt;p&gt;CLAUDE.md (or AGENTS.md for open standard) are instructions you write to give persistent context for agents.&lt;&#x2F;p&gt;
&lt;p&gt;Auto memory are the notes claude writes itself based on corrections and preferences of the user. You can enable or disable auto memory and other settings at &lt;code&gt;&#x2F;memory&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Both are loaded automatically in every session. Check &lt;code&gt;&#x2F;context all&lt;&#x2F;code&gt; to show what claude has loaded.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;things-to-add&quot;&gt;Things to add&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Coding standards to follow&lt;&#x2F;li&gt;
&lt;li&gt;Workflows for eg: how to invoke tests etc&lt;&#x2F;li&gt;
&lt;li&gt;Project architecture&lt;&#x2F;li&gt;
&lt;li&gt;Project specific gotchas&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;when-to-add-to-claude-md&quot;&gt;When to add to CLAUDE.md&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Claude makes repeated mistakes&lt;&#x2F;li&gt;
&lt;li&gt;Learnings from a session you want to persist&lt;&#x2F;li&gt;
&lt;li&gt;Context info required to get up to speed for a new member&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Since it&#x27;s loaded on every run, it good idea to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;keep it to facts&lt;&#x2F;li&gt;
&lt;li&gt;should hold in every session, if not, you can create a skill&lt;&#x2F;li&gt;
&lt;li&gt;have specific concrete instructions instead of being vague. for eg,
&lt;ul&gt;
&lt;li&gt;&quot;Use 2 space indentation&quot; instead of &quot;Format code properly&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;review the changes periodically and ensure that no conflicting instructions are present.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Prompts</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/claude-code/prompts/"/>
        <id>https://ms-choudhary.github.io/notes/claude-code/prompts/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/claude-code/prompts/">&lt;h4 id=&quot;learning&quot;&gt;Learning&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;I trying to learn about [topic], do deep search and try to find blogs, books, courses, papers, articles, talks on this topics.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;research&quot;&gt;Research&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;read this folder in depth, understand how it works deeply, what it does and all its specificities. when that’s done, write a detailed report of your learnings and findings in research.md&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;plan&quot;&gt;Plan&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;I want to build a new feature [name and description] that extends the system to perform [business outcome]. write a detailed plan.md document outlining how to implement this. include code snippets&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;annotate&quot;&gt;Annotate&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;I added a few comments to the document, address all the comments and update the document accordingly. don’t implement yet&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;add-a-todo-list-for-longer-tasks&quot;&gt;Add a todo list (for longer tasks)&lt;&#x2F;h4&gt;
&lt;blockquote&gt;
&lt;p&gt;add a detailed todo list to the plan, with all the phases and individual tasks necessary to complete the plan - don’t implement yet&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h4 id=&quot;implement&quot;&gt;Implement&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;with-todo&quot;&gt;With todo&lt;&#x2F;h5&gt;
&lt;blockquote&gt;
&lt;p&gt;implement it all. when you’re done with a task or phase, mark it as completed in the plan document. do not stop until all tasks and phases are completed. do not add unnecessary comments or jsdocs, do not use any or unknown types. continuously run typecheck to make sure you’re not introducing new issues.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h5 id=&quot;without-todo&quot;&gt;Without todo&lt;&#x2F;h5&gt;
&lt;blockquote&gt;
&lt;p&gt;implement it all. do not stop until all tasks and phases are completed. do not add unnecessary comments or jsdocs, do not use any or unknown types. continuously run typecheck to make sure you’re not introducing new issues.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Skills</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/claude-code/skills-md/"/>
        <id>https://ms-choudhary.github.io/notes/claude-code/skills-md/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/claude-code/skills-md/">&lt;p&gt;Extends what claude does. Use when you paste same instructions over again.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Subagents</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/claude-code/subagents/"/>
        <id>https://ms-choudhary.github.io/notes/claude-code/subagents/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/claude-code/subagents/">&lt;p&gt;Use subagents when side tasks would flood main conversation. Works in it&#x27;s own context and returns only the summary.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why&quot;&gt;Why&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Preserve context&lt;&#x2F;li&gt;
&lt;li&gt;Control costs by routing to cheaper models&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;advisor-tool&quot;&gt;Advisor tool&lt;&#x2F;h3&gt;
&lt;p&gt;Set &lt;code&gt;&#x2F;advisor&lt;&#x2F;code&gt;, which lower models can consult for architectural and other complex decisions.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Nginx</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/http/nginx/"/>
        <id>https://ms-choudhary.github.io/notes/http/nginx/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/http/nginx/">&lt;h3 id=&quot;template-envsubst&quot;&gt;Template Envsubst&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;nginx:alpine&lt;&#x2F;code&gt; sources &lt;code&gt;&#x2F;docker-entrypoint.d&#x2F;20-envsubst-on-templates.sh&lt;&#x2F;code&gt; which allows you substitute environment variables in the template dir at runtime. Example,&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;services:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  marquee:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    image: nginx:alpine
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    container_name: marquee
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    restart: unless-stopped
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    environment:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      - TMDB_API_KEY=[secret]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      - NGINX_ENVSUBST_FILTER=^TMDB_
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      - NGINX_ENVSUBST_OUTPUT_DIR=&#x2F;usr&#x2F;share&#x2F;nginx&#x2F;html
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    volumes:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      - .&#x2F;site.html:&#x2F;etc&#x2F;nginx&#x2F;templates&#x2F;index.html.template:ro
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      - .&#x2F;nginx-default.conf:&#x2F;etc&#x2F;nginx&#x2F;conf.d&#x2F;default.conf:ro
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Keeping up in tech</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/learning/keeping-up-in-tech/"/>
        <id>https://ms-choudhary.github.io/notes/learning/keeping-up-in-tech/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/learning/keeping-up-in-tech/">&lt;h3 id=&quot;learning-pipeline&quot;&gt;Learning pipeline&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Explore blogs, articles, talks for finding new stuff&lt;&#x2F;li&gt;
&lt;li&gt;Find resources to learn specific thing &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;claude-code&#x2F;claude-code-workflow&#x2F;#learning&quot;&gt;Learning Prompt&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Filter the resources by quality&lt;&#x2F;li&gt;
&lt;li&gt;Put the resources in right sequence&lt;&#x2F;li&gt;
&lt;li&gt;Integrate everything&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;time-management&quot;&gt;Time management&lt;&#x2F;h3&gt;
&lt;p&gt;Exploring, planning &amp;amp; doing each require different mindset. It&#x27;s better to schedule a separate time for each of these.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;breadth-vs-depth&quot;&gt;Breadth vs Depth&lt;&#x2F;h3&gt;
&lt;p&gt;Diving too deep in a topic has diminishing returns after a point. Also things get outdated quickly in the dynamic tech landscape.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;skill-knowledge-levels.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It should be like letter &#x27;T&#x27;. You should know a lot of topics at high level, which you can easily pick up if required. And pick one or two silos in which you&#x27;ll specialise and dive deep.&lt;&#x2F;p&gt;
&lt;p&gt;Focus should more be on computer science fundamentals rather than tools and libs which change quite frequently.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;you-cannot-keep-up&quot;&gt;You cannot keep up&lt;&#x2F;h3&gt;
&lt;p&gt;You&#x27;ll never be able to keep up with all the things. So prioritise:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Need to know&lt;&#x2F;li&gt;
&lt;li&gt;Should know&lt;&#x2F;li&gt;
&lt;li&gt;Nice to know&lt;&#x2F;li&gt;
&lt;li&gt;Edge case (only applies in specific scenarios)&lt;&#x2F;li&gt;
&lt;li&gt;Useless&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;codecapsule.com&#x2F;2021&#x2F;01&#x2F;05&#x2F;how-to-keep-your-tech-skills-sharp-in-a-leadership-role&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Income Tax Return (ITR)</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/itr/"/>
        <id>https://ms-choudhary.github.io/notes/money/itr/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/itr/">&lt;h2 id=&quot;income-tax-return-itr&quot;&gt;Income Tax Return (ITR)&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;important-terms&quot;&gt;Important Terms&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;FY: Financial Year. April to April cycle in which government functions&lt;&#x2F;li&gt;
&lt;li&gt;AY: Assessment Year. Starts after FY has ended. Tax is assessed on previous FY. For e.g., AY 2018-2019 assess the tax collection in FY 2017-2018.&lt;&#x2F;li&gt;
&lt;li&gt;Form16: Provided by employer. Shows taxable income (after deductions from HRA exemption, 80C, 80D). Tax deducted at source (TDS) for each quarter. Whether you&#x27;ll get refund or not.&lt;&#x2F;li&gt;
&lt;li&gt;Form26AS: Employer gives to IT (Government) showcasing total salary provided &amp;amp; TDS deducted by employer.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;important-dates&quot;&gt;Important Dates&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Feb 15. Few months before FY end. Provide investment proof of investment declaration.&lt;&#x2F;li&gt;
&lt;li&gt;April 1. Investment declaration. Standard. 1.5 lacs in 80C. Medical Insurance in 80D.&lt;&#x2F;li&gt;
&lt;li&gt;July 31. File Income Tax Return.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;e-filing-returns&quot;&gt;e-filing returns&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;User name is your pan card no.&lt;&#x2F;li&gt;
&lt;li&gt;ITR-1 is for individual&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;s quite simple. It&#x27;s just tallying figures with your Form16. IT cell already has Form26as, which means they already know your total income, total tax paid by you as TDS.&lt;&#x2F;li&gt;
&lt;li&gt;Income in ITR is not total income, but rather &quot; Income chargeable under the head &#x27;salaries&#x27;&quot; in your Form16&lt;&#x2F;li&gt;
&lt;li&gt;Sum all investments in each category. For e.g., for 80C, add ELSS + PF&lt;&#x2F;li&gt;
&lt;li&gt;If you&#x27;ve switched jobs, you&#x27;ll get Form16 from both employers. In such case, you&#x27;ve to sum income from both form16 and enter &amp;amp; likewise for other fields as well.&lt;&#x2F;li&gt;
&lt;li&gt;Add all associated bank accounts&lt;&#x2F;li&gt;
&lt;li&gt;Mention any additional income.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;income-tax&#x2F;&quot;&gt;income-tax&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>IPv6</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/ipv6/"/>
        <id>https://ms-choudhary.github.io/notes/networking/ipv6/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/ipv6/">&lt;p&gt;IPv6 uses 128 bits for addressing (compared to 32 bits of IPv4). To give an idea of how vast that is, you can give every atom in human body for the whole world population &lt;a href=&quot;https:&#x2F;&#x2F;www.wolframalpha.com&#x2F;input?i=2%5E128+%2F+%28world+population+*+atoms+in+human+body%29+&quot;&gt;6 address&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;representation&quot;&gt;Representation&lt;&#x2F;h3&gt;
&lt;p&gt;Instead of dotted notation used by IPv4, IPv6 are represented as 8 16 bit fields of case insensitive hexadecimal colon separated words.&lt;&#x2F;p&gt;
&lt;p&gt;Eg,&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;2001:4998:0124:1507:0000:0000:0000:F000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To shorten this further,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can drop leading zeros&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;2001:4998:124:1507:0:0:0:F000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;You can replace successive zeros by &lt;code&gt;::&lt;&#x2F;code&gt;, but only once per address,&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;2001:4998:124:1507::F000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Loopback address are represented as: &lt;code&gt;::1&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In dual stack hosts, you can also have IPv4 mapped address, where last part is also the ipv4 address of the interface, eg:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;::ffff:74.6.143.25
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ports are represented as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[2001:4998:124:1507::F000]:443
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;address-scopes&quot;&gt;Address scopes&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;link-local-address&quot;&gt;Link local address&lt;&#x2F;h4&gt;
&lt;p&gt;All IPv6 interfaces always has a link local scope address. Its generated on the host, using standard algorithm for the lower 64 bits, without requiring DHCP or any other network configuration. Packets with link local source&#x2F;destination is not forwarded to other links.&lt;&#x2F;p&gt;
&lt;p&gt;Within:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;fe80::&#x2F;10
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;See &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;link-local-address&#x2F;&quot;&gt;link-local-address&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;private-unique-local-address&quot;&gt;Private Unique Local Address&lt;&#x2F;h4&gt;
&lt;p&gt;Private IPv6 networks similar to &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;subnets&#x2F;#ipv4-address-blocks&quot;&gt;IPv4 Address blocks&lt;&#x2F;a&gt;. Not globally routed&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;fc00::&#x2F;7 or fd00::&#x2F;8
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;global-address&quot;&gt;Global Address&lt;&#x2F;h4&gt;
&lt;p&gt;Globally unique and routed by the internet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sipcalc&quot;&gt;Sipcalc&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ sipcalc fe80::&#x2F;10
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;-[ipv6 : fe80::&#x2F;10] - 0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[IPV6 INFO]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Expanded Address        - fe80:0000:0000:0000:0000:0000:0000:0000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Compressed address      - fe80::
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Subnet prefix (masked)  - fe80:0:0:0:0:0:0:0&#x2F;10
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Address ID (masked)     - 0:0:0:0:0:0:0:0&#x2F;10
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Prefix address          - ffc0:0:0:0:0:0:0:0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Prefix length           - 10
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Address type            - Link-Local Unicast Addresses
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Network range           - fe80:0000:0000:0000:0000:0000:0000:0000 -
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                          febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Subnets</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/subnets/"/>
        <id>https://ms-choudhary.github.io/notes/networking/subnets/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/subnets/">&lt;p&gt;IPv4 Address is 32 bit number, which is divided into network and host parts&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[192.168.10] + [.98]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;network      + host
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Network part is also represented as: 192.168.10.0&#x2F;24, &lt;code&gt;&#x2F;24&lt;&#x2F;code&gt; represents the network bits also known as subnet mask.&lt;&#x2F;p&gt;
&lt;p&gt;Hosts in same network are part of broadcast domain, meaning they don&#x27;t require a router to communicate. They can communicate directly at L2 using switch.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ipv4-address-blocks&quot;&gt;IPv4 Address blocks&lt;&#x2F;h3&gt;
&lt;p&gt;Whole of address space is divided into specific address blocks, by IETF &amp;amp; IANA, namely&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;private address spaces - 10.0.0.0&#x2F;8, 192.168.0.0&#x2F;16, 172.16.0.0&#x2F;12&lt;&#x2F;li&gt;
&lt;li&gt;Loopback addresses to localhost - 127.0.0.0&#x2F;8&lt;&#x2F;li&gt;
&lt;li&gt;Others&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;netmask&quot;&gt;Netmask&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;&#x2F;24&lt;&#x2F;code&gt; contains 2^8 = 256 address&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ ipcalc 192.168.10.0&#x2F;24
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Address:   192.168.10.0         11000000.10101000.00001010. 00000000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;=&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Network:   192.168.10.0&#x2F;24      11000000.10101000.00001010. 00000000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMin:   192.168.10.1         11000000.10101000.00001010. 00000001
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMax:   192.168.10.254       11000000.10101000.00001010. 11111110
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Broadcast: 192.168.10.255       11000000.10101000.00001010. 11111111
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Hosts&#x2F;Net: 254                   Class C, Private Internet
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of these first and last address cannot be assigned to a host. First address represents the network itself. And last address is broadcast address, used for broadcasting to all hosts in the network.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;carve-smaller-subnets&quot;&gt;Carve smaller subnets&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ ipcalc -s 24 64 48 192.168.10.0&#x2F;24
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Address:   192.168.10.0         11000000.10101000.00001010. 00000000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Netmask:   255.255.255.0 = 24   11111111.11111111.11111111. 00000000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Wildcard:  0.0.0.255            00000000.00000000.00000000. 11111111
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;=&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Network:   192.168.10.0&#x2F;24      11000000.10101000.00001010. 00000000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMin:   192.168.10.1         11000000.10101000.00001010. 00000001
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMax:   192.168.10.254       11000000.10101000.00001010. 11111110
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Broadcast: 192.168.10.255       11000000.10101000.00001010. 11111111
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Hosts&#x2F;Net: 254                   Class C, Private Internet
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;1. Requested size: 24 hosts
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Netmask:   255.255.255.224 = 27 11111111.11111111.11111111.111 00000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Network:   192.168.10.192&#x2F;27    11000000.10101000.00001010.110 00000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMin:   192.168.10.193       11000000.10101000.00001010.110 00001
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMax:   192.168.10.222       11000000.10101000.00001010.110 11110
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Broadcast: 192.168.10.223       11000000.10101000.00001010.110 11111
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Hosts&#x2F;Net: 30                    Class C, Private Internet
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;2. Requested size: 64 hosts
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Netmask:   255.255.255.128 = 25 11111111.11111111.11111111.1 0000000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Network:   192.168.10.0&#x2F;25      11000000.10101000.00001010.0 0000000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMin:   192.168.10.1         11000000.10101000.00001010.0 0000001
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMax:   192.168.10.126       11000000.10101000.00001010.0 1111110
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Broadcast: 192.168.10.127       11000000.10101000.00001010.0 1111111
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Hosts&#x2F;Net: 126                   Class C, Private Internet
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;3. Requested size: 48 hosts
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Netmask:   255.255.255.224 = 27 11111111.11111111.11111111.111 00000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Network:   192.168.10.128&#x2F;27    11000000.10101000.00001010.100 00000
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMin:   192.168.10.129       11000000.10101000.00001010.100 00001
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;HostMax:   192.168.10.158       11000000.10101000.00001010.100 11110
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Broadcast: 192.168.10.159       11000000.10101000.00001010.100 11111
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Hosts&#x2F;Net: 30                    Class C, Private Internet
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Needed size:  224 addresses.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Used network: 192.168.10.0&#x2F;24
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Unused:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;192.168.10.224&#x2F;27
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Man pages</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/shell/man-pages/"/>
        <id>https://ms-choudhary.github.io/notes/shell/man-pages/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/shell/man-pages/">&lt;ul&gt;
&lt;li&gt;Search man page title and description&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;man -k syslog
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Search for arbitrary text in man pages&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;man -K &amp;quot;syslog&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Config</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/ssh/config/"/>
        <id>https://ms-choudhary.github.io/notes/ssh/config/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/ssh/config/">&lt;h3 id=&quot;remotecommand&quot;&gt;RemoteCommand&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;Host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; homelab&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;HostName&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; homelab&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; If the remote command requires a TTY&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;RequestTTY&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; yes&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; -A attaches to an existing session, if no session it creates one&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; -s specifies the session name &amp;#39;work&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;  &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;RemoteCommand&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; tmux new-session&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;s&lt;&#x2F;span&gt; work&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Gotcha, you cannot run other command while specifying RemoteCommand. For eg &lt;code&gt;ssh homelab ls&lt;&#x2F;code&gt; fails with &lt;code&gt;Cannot execute command-line and remote command&lt;&#x2F;code&gt;. Can also affect other tools using ssh, like rsync, scp etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Find device name by disk id</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/find-dev-name-by-disk-id/"/>
        <id>https://ms-choudhary.github.io/notes/storage/find-dev-name-by-disk-id/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/find-dev-name-by-disk-id/">&lt;p&gt;&lt;code&gt;&#x2F;dev&#x2F;disk&lt;&#x2F;code&gt; contains symlinks to actual device name:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;by-id&lt;&#x2F;li&gt;
&lt;li&gt;by-diskseq&lt;&#x2F;li&gt;
&lt;li&gt;by-label&lt;&#x2F;li&gt;
&lt;li&gt;by-partuuid&lt;&#x2F;li&gt;
&lt;li&gt;by-path&lt;&#x2F;li&gt;
&lt;li&gt;by-uuid&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ ls -l &#x2F;dev&#x2F;disk&#x2F;by-id&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;total 0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;lrwxrwxrwx 1 root root  9 May  7 06:32 ata-INTEL_SSDSC2BX200G4R_BTHC629105S3200TGN -&amp;gt; ..&#x2F;..&#x2F;sdb
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;lrwxrwxrwx 1 root root 10 May  7 06:32 ata-INTEL_SSDSC2BX200G4R_BTHC629105S3200TGN-part1 -&amp;gt; ..&#x2F;..&#x2F;sdb1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;lrwxrwxrwx 1 root root 10 May  7 06:32 ata-INTEL_SSDSC2BX200G4R_BTHC629105S3200TGN-part2 -&amp;gt; ..&#x2F;..&#x2F;sdb2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;storage&#x2F;find-dev-name-by-disk-id&#x2F;inbox&#x2F;in-progress&#x2F;linux-dev-naming.md&quot;&gt;linux-dev-naming&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux File IO Buffering</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/linux-file-io-buffering/"/>
        <id>https://ms-choudhary.github.io/notes/storage/linux-file-io-buffering/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/linux-file-io-buffering/">&lt;p&gt;When you read or write to files via read&#x2F;write syscalls, it doesn&#x27;t directly initiate access to disk. Instead, first the data is copied to in memory kernel buffer, known as buffer cache. Then at some later point, kernel writes (flushes) the buffer to disk. If in between, some other process reads the same file, kernel provides it from the buffer cache.&lt;&#x2F;p&gt;
&lt;p&gt;Reads are buffered to cache as well, so kernel first reads the data from disk to buffer cache. Calls to reads are served from the buffer cache. Kernel performs read ahead for sequential reads.&lt;&#x2F;p&gt;
&lt;p&gt;The aim of this to make read&#x2F;write be performant and return fast, rather than waiting for slow I&#x2F;O.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s no upper limit on the size of the buffer cache. It solely depends on:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;availability of physical memory&lt;&#x2F;li&gt;
&lt;li&gt;demand for other purposes&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Even though reads and writes are buffered in kernel, every time you invoke syscall, there&#x27;s a performance penalty, to overcome this, the data is also buffered in stdio c library.&lt;&#x2F;p&gt;
&lt;p&gt;Data is buffered in large blocks to reduce number of sys calls. You can force the data in stdio to be written to kernel buffer, by calling &lt;code&gt;fflush()&lt;&#x2F;code&gt; lib call.
&lt;img src=&quot;&#x2F;_images&#x2F;linux-file-buffering.jpeg&quot; alt=&quot;&quot; &#x2F;&gt;
To flush the kernel buffer to disk, use &lt;code&gt;fsync()&lt;&#x2F;code&gt; call. It returns only when all the data &amp;amp; metadata is flushed to the disk. Used by databases for journaling operations.&lt;&#x2F;p&gt;
&lt;p&gt;For direct IO (without buffer) specify &lt;code&gt;O_DIRECT&lt;&#x2F;code&gt; flag when opening file.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;system-design&#x2F;gfs&#x2F;&quot;&gt;gfs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>&#x2F;proc filesystem</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/proc-fs/"/>
        <id>https://ms-choudhary.github.io/notes/storage/proc-fs/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/proc-fs/">&lt;p&gt;It&#x27;s a virtual filesystem which provides interface to kernel internal data structures, which looks like traditional files and dirs. It&#x27;s created on the fly by the kernel as process access them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;important-files&quot;&gt;Important files&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;proc&quot;&gt;&#x2F;proc&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&#x2F;proc&#x2F;version - kernel version&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;self - a process can access it&#x27;s own proc pid dir at &#x2F;proc&#x2F;self&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;net - status info about networking &amp;amp; sockets&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;sys&#x2F;fs - settings related to filesystems&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;sys&#x2F;kernel - kernel settings&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;sys&#x2F;net  - networking settings&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;sys&#x2F;vm - memory management settings&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;proc-pid&quot;&gt;&#x2F;proc&#x2F;PID&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;status - contains runtime info about the process&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;cmdline - command line arguments used to invoke&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;cwd - current working dir of the process&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;environ - environment variables&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;exe - symlink to executable binary&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;fd  - symlink to files opened&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;maps - memory mapping&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;mem - process virtual memory&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;mounts - mountpoints for this process&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;root - symlink to the root dir&lt;&#x2F;li&gt;
&lt;li&gt;&#x2F;proc&#x2F;PID&#x2F;task - one subdir per thread&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;proc-fs-files.jpeg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building a datacenter</title>
        <published>2026-08-24T00:00:00+00:00</published>
        <updated>2026-09-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/hardware/building-datacenter/"/>
        <id>https://ms-choudhary.github.io/notes/hardware/building-datacenter/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/hardware/building-datacenter/">&lt;p&gt;You&#x27;ve following on-prem choices, if you decide to go with deploying to datacenter:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Greenfield buildout - Buy or lease whole datacenter yourself&lt;&#x2F;li&gt;
&lt;li&gt;Cage colocation - Lease space inside a datacenter (enclosed by mesh walls)&lt;&#x2F;li&gt;
&lt;li&gt;Rack colocation - Lease racks in a data center&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In a co located datacenter, cost of power is generally greater than the cost of leasing the space. So you&#x27;ve to decide the compute based on how much power you want to draw.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre requisites&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;power&quot;&gt;Power&lt;&#x2F;h3&gt;
&lt;p&gt;Power is the single most critical resource in a datacenter. It takes a long time to recover from an outage. Hence, redundancy is critical. You need two independent power feeds per rack.&lt;&#x2F;p&gt;
&lt;p&gt;PDU (Power Distribution Unit), ranges from glorified extension cables to advanced with full management features like control and metered individual sockets.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;network&quot;&gt;Network&lt;&#x2F;h3&gt;
&lt;p&gt;After power, network is 2nd most critical resource. You need a tier 1 ISP and peering with internet exchanges (IX) for low latency. &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;internet-routing&#x2F;&quot;&gt;internet-routing&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cooling&quot;&gt;Cooling&lt;&#x2F;h3&gt;
&lt;p&gt;Airflow and cooling will be required.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inventory&quot;&gt;Inventory&lt;&#x2F;h2&gt;
&lt;p&gt;You&#x27;ve bought the inventory: servers with dual redundant NICs, multiple redundant NVME drives, PDUs, network switches etc.&lt;&#x2F;p&gt;
&lt;p&gt;Neat cabling requires professional experience. Cabling matrix and rack elevation are the docs which communicate how to rack and wire up. This step is closer to building a house than to deploying a terraform stack. Every place is different with different challenges and different solutions, hard to maintain uniformity. Common problem at this stage: &quot;Cables are too short&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deployment&quot;&gt;Deployment&lt;&#x2F;h2&gt;
&lt;p&gt;Next steps:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;network devices needs configuring
&lt;ul&gt;
&lt;li&gt;installing sonic os&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;router config needs writing&lt;&#x2F;li&gt;
&lt;li&gt;RIR (Regional Internet Registry) records needs updating&lt;&#x2F;li&gt;
&lt;li&gt;redfish api to connect to BMC&lt;&#x2F;li&gt;
&lt;li&gt;pxe booting&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;blog.railway.com&#x2F;p&#x2F;data-center-build-part-one&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Agentic Engineering</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/ai/agentic-engineering/"/>
        <id>https://ms-choudhary.github.io/notes/ai/agentic-engineering/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/ai/agentic-engineering/">&lt;p&gt;Our engineering habits were built around the fact that writing code is hard. Writing code is cheap now. If AI writes the code, what&#x27;s left to do? There&#x27;s so much stuff:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;figuring out what code to write&lt;&#x2F;li&gt;
&lt;li&gt;every problem has many solutions, and each of them comes with it&#x27;s own tradeoff&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Good code still has a cost. Big part of the skill in building software is understanding what&#x27;s possible &amp;amp; what isn&#x27;t. Invest time in learning. Many of them small proof of concepts that demonstrate a key idea. Then combine few of them to build something new.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;tips-on-using-agents&quot;&gt;Tips on using agents&lt;&#x2F;h3&gt;
&lt;p&gt;Give the agents right tools to solve the problem&lt;&#x2F;p&gt;
&lt;p&gt;Specify the problem in right level of detail&lt;&#x2F;p&gt;
&lt;p&gt;Give them examples of things you want them to do&lt;&#x2F;p&gt;
&lt;p&gt;Verify &amp;amp; iterate on the results, until you&#x27;re confident that it solves the problem reliably&lt;&#x2F;p&gt;
&lt;p&gt;Agents can learn from past mistakes, provided we deliberately update instructions and tools harness to account for what we learn.&lt;&#x2F;p&gt;
&lt;p&gt;If agents drop the quality of output, figure out what aspects of the process is hurting the quality and fix them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Technical debt&lt;&#x2F;strong&gt;: Doing things the right way will take too long, so work with the time constraints and hope that the project will survive long enough to pay the debt later.&lt;&#x2F;p&gt;
&lt;p&gt;With AI agents, always avoid the technical debt, go to extra length. It&#x27;s cheap now.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;api refactor&lt;&#x2F;li&gt;
&lt;li&gt;poor inconsistent naming&lt;&#x2F;li&gt;
&lt;li&gt;duplicate functionality&lt;&#x2F;li&gt;
&lt;li&gt;1000s of lines in function
Fire the prompt away, and decide later. Agents are good for these tasks.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The best way to make confident tech choices, to prove it&#x27;s fit for the purpose, is to make a working prototype. Wire up the simulation, run load test &amp;amp; see what breaks.&lt;&#x2F;p&gt;
&lt;p&gt;The biggest anti-pattern: not reviewing the code.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;claude-code&#x2F;claude-code-workflow&#x2F;&quot;&gt;claude-code-workflow&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Java</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/java/java/"/>
        <id>https://ms-choudhary.github.io/notes/java/java/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/java/java/">&lt;h3 id=&quot;thread-dump-sigquit-kill-3&quot;&gt;Thread dump SIGQUIT (kill -3)&lt;&#x2F;h3&gt;
&lt;p&gt;Request thread dump on a running java server. Does not terminate the server, useful for troubleshooting issues:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;kill -3 &amp;lt;pid&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cluster API</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/kubernetes/cluster-api/"/>
        <id>https://ms-choudhary.github.io/notes/kubernetes/cluster-api/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/kubernetes/cluster-api/">&lt;h3 id=&quot;cluster&quot;&gt;Cluster&lt;&#x2F;h3&gt;
&lt;p&gt;Represents kubernetes cluster whose lifecycle is managed by CAPI. Provider specific custom resources are referenced by &lt;code&gt;infrastructureRef&lt;&#x2F;code&gt; or &lt;code&gt;controlPlanRef&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;apiVersion: cluster.x-k8s.io&#x2F;v1beta2
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;kind: Cluster
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;metadata:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  name: my-cluster
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;spec:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  clusterNetwork:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    pods:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      cidrBlocks:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      - 192.168.0.0&#x2F;16
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  infrastructureRef:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    apiGroup: infrastructure.cluster.x-k8s.io
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    kind: VSphereCluster
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    name: my-cluster-infrastructure
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  controlPlaneRef:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    apiGroup: controlplane.cluster.x-k8s.io
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    kind: KubeadmControlPlane
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    name: my-control-plane
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;clusterclass&quot;&gt;ClusterClass&lt;&#x2F;h3&gt;
&lt;p&gt;Allows managing multiple cluster objects.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;machine&quot;&gt;Machine&lt;&#x2F;h3&gt;
&lt;p&gt;Immutable objects representing kubernetes node. Never updated (other than labels, annotations &amp;amp; status) can only be deleted. Provider specific resources are referenced via &lt;code&gt;infrastructureRef&lt;&#x2F;code&gt;. Provider specific controller provisions a new host to register as new node matching the machine spec. If machine is deleted, underlying infrastructure and node is deleted. Imm&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;apiVersion: cluster.x-k8s.io&#x2F;v1beta2
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;kind: Machine
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;metadata:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  name: my-machine
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;spec:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  clusterName: my-cluster
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  version: v1.35.0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  infrastructureRef:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    apiGroup: infrastructure.cluster.x-k8s.io
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    kind: VSphereMachineTemplate
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    name: my-machine-infrastructure
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  bootstrap:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    configRef:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      apiGroup: bootstrap.cluster.x-k8s.io
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      kind: KubeadmConfigTemplate
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      name: my-bootstrap-config
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;status:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  nodeRef:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    name: the-node-running-on-my-machine
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;machine-deployment&quot;&gt;Machine Deployment&lt;&#x2F;h4&gt;
&lt;p&gt;Similar to pod deployment, creates machine set, which creates machines.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;machine-pool&quot;&gt;Machine Pool&lt;&#x2F;h4&gt;
&lt;p&gt;Infrastructure specific group of machines&lt;&#x2F;p&gt;
&lt;h4 id=&quot;machine-set&quot;&gt;Machine Set&lt;&#x2F;h4&gt;
&lt;p&gt;Similar to pod replica set.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;machine-healthcheck&quot;&gt;Machine Healthcheck&lt;&#x2F;h4&gt;
&lt;p&gt;Automatically initiate remediation for missing&#x2F;unhealthy nodes, by replacing them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;infrastructure-provider&quot;&gt;Infrastructure Provider&lt;&#x2F;h3&gt;
&lt;p&gt;Component responsible for provisioning compute machines required by cluster or machines.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bootstrap-provider&quot;&gt;Bootstrap Provider&lt;&#x2F;h3&gt;
&lt;p&gt;Turn the server into kubernetes node using machine&#x2F;node role specific init (using cloud-init) known as BootstrapData. BootStrapData is used by infrastructure provider to bootstrap machine into node.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;control-plane-provider&quot;&gt;Control Plane Provider&lt;&#x2F;h3&gt;
&lt;p&gt;Can either be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Self provisioned, wholly managed by single Cluster-API deployment&lt;&#x2F;li&gt;
&lt;li&gt;Pod based, require external hosting cluster, where control plane components are running as pod, exposed by service.&lt;&#x2F;li&gt;
&lt;li&gt;External or managed, controlled by service other than CAPI (eg GKE, AKS, EKS etc)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;kubeadmcontrolplane&quot;&gt;KubeAdmControlPlane&lt;&#x2F;h4&gt;
&lt;p&gt;Manage set of machines as control plane nodes using kubeadm.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Launchd</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/macos/launchd/"/>
        <id>https://ms-choudhary.github.io/notes/macos/launchd/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/macos/launchd/">&lt;h3 id=&quot;list-services&quot;&gt;List services&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;launchctl list
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;stop-service&quot;&gt;Stop service&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;launchctl bootout system&#x2F;&amp;lt;name&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;start-service&quot;&gt;Start service&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;launchctl bootstrap system&#x2F;&amp;lt;name&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setup socat proxy to remote host</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/socat-tcp-proxy/"/>
        <id>https://ms-choudhary.github.io/notes/networking/socat-tcp-proxy/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/socat-tcp-proxy/">&lt;p&gt;TCP request on port 6443 is forwarded to remote-host:6443&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;docker run -d --name proxy6443 --restart unless-stopped -p 6443:6443 \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  alpine&#x2F;socat \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  TCP-LISTEN:6443,fork,reuseaddr \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  TCP:remote-host:6443
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;socat-tcp-proxy&#x2F;inbox&#x2F;in-progress&#x2F;network-load-balancing.md&quot;&gt;network-load-balancing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>sqlite3</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/sqlite3/sqlite3/"/>
        <id>https://ms-choudhary.github.io/notes/sqlite3/sqlite3/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/sqlite3/sqlite3/">&lt;h3 id=&quot;read-and-apply-sql-file&quot;&gt;Read and apply sql file&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sqlite3 file.db
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;gt; .read path&#x2F;migration.sql
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>fstrim</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/fstrim/"/>
        <id>https://ms-choudhary.github.io/notes/storage/fstrim/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/fstrim/">&lt;p&gt;Discard unused blocks on a mounted filesystems. Useful for reducing the image size on a VM. Must be supported by the device. Check:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ lsblk --discard&#x2F;-D
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;vda           0      512B      64G         0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├─vda1        0      512B      64G         0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├─vda2        0      512B      64G         0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;└─vda3        0      512B      64G         0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to check discarding capabilities of each block device.&lt;&#x2F;p&gt;
&lt;p&gt;DISC-ALN: Disk alignment
DISC-GRAN: Disk granularity, smallest chunk which can be discarded
DISC-MAX: Largest amount which can be discarded in a single request&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re using packer with qemu&#x2F;kvm, use newer devices &lt;code&gt;q35&lt;&#x2F;code&gt; over &lt;code&gt;pc&lt;&#x2F;code&gt; (outdated intel), which might not support discard.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;fstrim &#x2F;path&#x2F;to&#x2F;mount
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ostree</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/ostree/"/>
        <id>https://ms-choudhary.github.io/notes/storage/ostree/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/ostree/">&lt;p&gt;ostree is git for filesystems. It enables versioning, distribution &amp;amp; atomic deployment of linux systems.&lt;&#x2F;p&gt;
&lt;p&gt;It stores complete system snapshot, making updates &amp;amp; rollbacks easier.&lt;&#x2F;p&gt;
&lt;p&gt;Based on composefs, relies on EROFS (Enhanced Read Only Filesystem), which guarantees against data corruption, and natively performs data deduplication &amp;amp; LZ4 compression.&lt;&#x2F;p&gt;
&lt;p&gt;Data is in &lt;code&gt;&#x2F;sysroot&#x2F;ostree&#x2F;repo&#x2F;objects&lt;&#x2F;code&gt;.
Similar to git, allows creating commits, versions &amp;amp; switch between them.&lt;&#x2F;p&gt;
&lt;p&gt;Only &#x2F;var is mutable, other mutable dirs are symlinked to var. &#x2F;etc is special overlay, it intelligently merges new changes with old. #question explore this more.&lt;&#x2F;p&gt;
&lt;p&gt;It uses rpm-ostree package manager. #question what can it do&#x2F;not do compared to dnf?&lt;&#x2F;p&gt;
&lt;p&gt;Which creates new commits but changes are not affected until reboot.&lt;&#x2F;p&gt;
&lt;p&gt;Can use &lt;code&gt;rpm-ostree rollback&lt;&#x2F;code&gt; to rollback to previous commit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;581811&#x2F;&quot;&gt;https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;581811&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;blog.verbum.org&#x2F;2014&#x2F;01&#x2F;21&#x2F;ostree-in-action-rpm-ostree-and-switching-trees&#x2F;&quot;&gt;https:&#x2F;&#x2F;blog.verbum.org&#x2F;2014&#x2F;01&#x2F;21&#x2F;ostree-in-action-rpm-ostree-and-switching-trees&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;coreos&#x2F;rpm-ostree&#x2F;blob&#x2F;main&#x2F;docs&#x2F;background.md&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;coreos&#x2F;rpm-ostree&#x2F;blob&#x2F;main&#x2F;docs&#x2F;background.md&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>partprobe</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/partprobe/"/>
        <id>https://ms-choudhary.github.io/notes/storage/partprobe/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/partprobe/">&lt;h3 id=&quot;load-partition-table-changes&quot;&gt;Load partition table changes&lt;&#x2F;h3&gt;
&lt;p&gt;Inform the kernel of partition table changes&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;partprobe
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;storage&#x2F;partprobe&#x2F;inbox&#x2F;in-progress&#x2F;uefi.md#GUID%20Partition%20Table%20(GPT)&quot;&gt;GUID Partition Table (GPT)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>smartctl</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/smartctl/"/>
        <id>https://ms-choudhary.github.io/notes/storage/smartctl/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/smartctl/">&lt;p&gt;Monitors the Self Monitoring Analysis &amp;amp; Reporting Technology (SMART) built in most of ATA&#x2F;SATA &amp;amp; SCSI&#x2F;SAS hard drives.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;health&quot;&gt;health&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;smartctl --health &#x2F;dev&#x2F;sda1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;all&quot;&gt;all&lt;&#x2F;h3&gt;
&lt;p&gt;health is sometimes superficial, check all:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;smartctl -a &#x2F;dev&#x2F;sda1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wipe software raid</title>
        <published>2026-08-21T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/wipe-software-raid/"/>
        <id>https://ms-choudhary.github.io/notes/storage/wipe-software-raid/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/wipe-software-raid/">&lt;p&gt;Wipe the filesystem on the raided drive, then stop raid&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ wipefs -a &#x2F;dev&#x2F;md127
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ mdadm --stop -f &#x2F;dev&#x2F;md127
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Finally wipe the partitions&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;wipefs -a &#x2F;dev&#x2F;sda
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;wipefs -a &#x2F;dev&#x2F;sdb
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Google Search AI Overview</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/ai/google-search-ai/"/>
        <id>https://ms-choudhary.github.io/notes/ai/google-search-ai/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/ai/google-search-ai/">&lt;p&gt;When you search in google, it also summarises the answer in it&#x27;s AI overview tab. I&#x27;ve generally observed that it&#x27;s a summary of the top links in the search. Something like you feed the data of top links into AI and generate response. Explore how this works more #question&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Certificate management using step-cli</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/certificates/certificate-management-using-step-cli/"/>
        <id>https://ms-choudhary.github.io/notes/certificates/certificate-management-using-step-cli/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/certificates/certificate-management-using-step-cli/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;install-step-cli&quot;&gt;Install step-cli&lt;&#x2F;h3&gt;
&lt;p&gt;https:&#x2F;&#x2F;smallstep.com&#x2F;docs&#x2F;step-cli&#x2F;installation&#x2F;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;create-a-new-root-ca-then-create-a-new-certificate-and-private-key-using-step-cli&quot;&gt;Create a new root CA, then create a new certificate and private key using step cli&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ step certificate create root-ca root-ca.crt root-ca.key --profile root-ca
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ step certificate create foo foo.crt foo.key --profile leaf \
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            --ca root-ca.crt --ca-key root-ca.key --san 10.230.32.1 --san 10.230.32.2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;certificates&#x2F;openssl&#x2F;&quot;&gt;openssl&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;shell&#x2F;set-time-on-linux&#x2F;&quot;&gt;set-time-on-linux&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;certificates&#x2F;pki-certificates&#x2F;&quot;&gt;pki-certificates&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OpenSSL Command</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/certificates/openssl/"/>
        <id>https://ms-choudhary.github.io/notes/certificates/openssl/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/certificates/openssl/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;inspect-certificate&quot;&gt;Inspect certificate&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;openssl x509 -in input.crt -noout -text
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;inspect-certificate-from-url&quot;&gt;Inspect certificate from URL&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo | openssl s_client -connect burrow.test.indexexchange.com:443 | openssl x509 -noout -text
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;remove-passphrase-from-a-private-key&quot;&gt;Remove passphrase from a private key&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;openssl ec -in input.key -out output.key
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;certificates&#x2F;certificate-management-using-step-cli&#x2F;&quot;&gt;certificate-management-using-step-cli&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;shell&#x2F;set-time-on-linux&#x2F;&quot;&gt;set-time-on-linux&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;certificates&#x2F;pki-certificates&#x2F;&quot;&gt;pki-certificates&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>PKI &amp; Certificates</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/certificates/pki-certificates/"/>
        <id>https://ms-choudhary.github.io/notes/certificates/pki-certificates/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/certificates/pki-certificates/">&lt;h3 id=&quot;terminology&quot;&gt;Terminology&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Entity&lt;&#x2F;strong&gt;: anything that exists! your computer, your code&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Identity&lt;&#x2F;strong&gt;: attributes which define an entity&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Claim&lt;&#x2F;strong&gt;: Entities can claim they&#x27;ve certain name, Authentication, then, is the process of asserting that claim&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Subscriber&lt;&#x2F;strong&gt;: Server which participates in PKI, subject of the certificate&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Issuer or Certificate Authority (CA)&lt;&#x2F;strong&gt;: Entity that issues certificates to subscribers.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Relying Party (your browser):&lt;&#x2F;strong&gt; Entity which uses certificates&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;symmetric-cryptography&quot;&gt;Symmetric cryptography&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Uses one-way hash functions(eg HMAC), which accepts message &amp;amp; pre-shared secret key as input and generate signature. Client can then ensure message integrity following same steps&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;asymmetric-cryptography-public-key-cryptography&quot;&gt;Asymmetric cryptography &#x2F; Public key cryptography&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Uses public&#x2F;private keys to
&lt;ul&gt;
&lt;li&gt;either encrypt data with public key. This can then only be decrypted using private key&lt;&#x2F;li&gt;
&lt;li&gt;sign some data with private key. Anyone who has public key can verify this signature&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;certificates&quot;&gt;Certificates&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In simple terms: &quot;bind names to public key&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Allows computer to see who it&#x27;s communicating with&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In other words, it&#x27;s a data structure of public key and name, which is signed by &lt;em&gt;issuer&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;But what does it actually contain?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Public key&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Name (Subject Alternative Name - SAN)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Issued at, expires at dates&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Crptographic signature&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;pki-x509-certificate.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;SSH has it&#x27;s own format of certificate&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;when you edit &lt;code&gt;~&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;code&gt; you configure a way of certificate less way of PKI to bind public key to name&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;X.509&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The kind of certificate which browsers understand and use for HTTPS or almost always used for internal PKI setup&lt;&#x2F;li&gt;
&lt;li&gt;Originally built for telcos to build global telephone dir in 1980s. Still reeks of that design. Most fields are out dated, hence not required to be filled&lt;&#x2F;li&gt;
&lt;li&gt;Builds on ASN (Abstract Syntax Notation) for defining types, similar to JSON&lt;&#x2F;li&gt;
&lt;li&gt;Most common encoding, DER (Distinguished Encoding Rules) consists of binary data, packaged as PEM files (base64 payload sandwiched between headers)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;-----BEGIN&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; CERTIFICATE-----&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;MIIBwzCCAWqgAwIBAgIRAIi5QRl9kz1wb+SUP20gB1kwCgYIKoZIzj0EAwIwGzEZ&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;MBcGA1UEAxMQTDVkIFRlc3QgUm9vdCBDQTAeFw0xODExMDYyMjA0MDNaFw0yODEx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;MDMyMjA0MDNaMCMxITAfBgNVBAMTGEw1ZCBUZXN0IEludGVybWVkaWF0ZSBDQTBZ&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;MBMGByqGSM49AgEGCCqGSM49AwEHA0IABAST8h+JftPkPocZyuZ5CVuPUk3vUtgo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cgRbkYk7Ong7ey&#x2F;fM5fJdRNdeW6SouV5h3nF9JvYKEXuoymSNjGbKomjgYYwgYMw&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;DgYDVR0PAQH&#x2F;BAQDAgGmMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;BgNVHRMBAf8ECDAGAQH&#x2F;AgEAMB0GA1UdDgQWBBRc+LHppFk8sflIpm&#x2F;XKpbNMwx3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;SDAfBgNVHSMEGDAWgBTirEpzC7&#x2F;gexnnz7ozjWKd71lz5DAKBggqhkjOPQQDAgNH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;ADBEAiAejDEfua7dud78lxWe9eYxYcM93mlUMFIzbWlOJzg+rgIgcdtU9wIKmn5q&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;FU3iOiRP5VyLNmrsQD3&#x2F;ItjUN1f1ouY&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;-----END&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; CERTIFICATE-----&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Sometimes certificate is wrapped fancier packaging, which can contain multiple certificates (bundle). These are part of standards called &lt;strong&gt;PKCS&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;public-key-infrastructure-pki&quot;&gt;Public Key Infrastructure (PKI)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;umbrella term used for store, use, verify, revoke of certificates &amp;amp; keys. as vague as &quot;database infrastructure&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Web&#x2F;Internet PKI
&lt;ul&gt;
&lt;li&gt;works by default with browsers and TLS&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Internal PKI
&lt;ul&gt;
&lt;li&gt;Why can&#x27;t we use web PKI for internal workloads as well?
&lt;ul&gt;
&lt;li&gt;to have better control on certificate attributes (like issue&#x2F;expiry date)&lt;&#x2F;li&gt;
&lt;li&gt;there might be rate limit or availability issues with CA&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;root-certificates&quot;&gt;Root certificates&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Relying parties has pre-installed list of root certificates&lt;&#x2F;li&gt;
&lt;li&gt;Root certificate is self signed &lt;code&gt;Mike says Mike is blah blah blah&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Root CAs are regulated via various programs (like apple root certificate, microsoft root certificate, mozilla&#x27;s root certificate)&lt;&#x2F;li&gt;
&lt;li&gt;OS&#x27;s are shipped with it&#x27;s own trust stores (these are what are used when you use &lt;code&gt;curl&lt;&#x2F;code&gt; or some programming library for TLS)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;intermediate-certificates&quot;&gt;Intermediate certificates&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;CAs can be online or offline, based on whether they provide an APIs to issue certificates&lt;&#x2F;li&gt;
&lt;li&gt;Root CAs are always offline&lt;&#x2F;li&gt;
&lt;li&gt;Root private key is used infrequently to sign intermediate certificates (which are easier to revoke&#x2F;rotate)&lt;&#x2F;li&gt;
&lt;li&gt;Intermediate certificates are validated in same steps as leaf certificate&lt;&#x2F;li&gt;
&lt;li&gt;When certificate are exchanged in TLS (Web PKI), it&#x27;s passed as bundle (leaf certificate, is signed by layers of intermediate cert, which is signed by root cert)&lt;&#x2F;li&gt;
&lt;li&gt;When you&#x27;re setting up proxy (like nginx) you need to specify this bundle instead of leaf certificate&lt;&#x2F;li&gt;
&lt;li&gt;These bundles are encoded as simple line separated PEM objects (eg)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;pki-certificate-chain.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Relying parties then verify all certificates in the bundle (certificate path validation)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;certificate-management&quot;&gt;Certificate management&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;naming&quot;&gt;Naming&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Historically, DNs was used to name the subject of certificate (&lt;em&gt;subscriber&lt;&#x2F;em&gt;). This was deprecated, and DN is now optional.&lt;&#x2F;li&gt;
&lt;li&gt;SAN (Subject Alternative Name) is now used for subject. 4 sort of SANs are in common use: DNS, Email address, IP address &amp;amp; URI&lt;&#x2F;li&gt;
&lt;li&gt;SAN can have multiple names (&lt;code&gt;smallstep.com&lt;&#x2F;code&gt;, &lt;a href=&quot;http:&#x2F;&#x2F;www.smallstep.com&quot;&gt;&lt;code&gt;www.smallstep.com&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;, &lt;code&gt;*.smallstep.com&lt;&#x2F;code&gt; )&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;generating-key-pairs&quot;&gt;Generating key pairs&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;If using RSA, use at least 2048 bits&lt;&#x2F;li&gt;
&lt;li&gt;If using ECDSA, P-256 curve is probably best (&lt;code&gt;secp256kl&lt;&#x2F;code&gt; or &lt;code&gt;prime256v1&lt;&#x2F;code&gt; in openssl) eg in openssl:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;openssl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ecparam&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;name&lt;&#x2F;span&gt; prime256v1&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;genkey&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;out&lt;&#x2F;span&gt; k.prv&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;openssl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ec&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;in&lt;&#x2F;span&gt; es256.key&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;pubout&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;out&lt;&#x2F;span&gt; k.pub&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;issuance&quot;&gt;Issuance&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Next step after name &amp;amp; key pair is to obtain leaf certificate from CA&lt;&#x2F;li&gt;
&lt;li&gt;CA will check two things:
&lt;ul&gt;
&lt;li&gt;public key which will be part of cert, is subscriber&#x27;s public key, done by Certificate signing request (CSR)&lt;&#x2F;li&gt;
&lt;li&gt;name in the cert, is subscriber&#x27;s name, done by Identity proofing&#x2F;registration&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Certificate signing request (CSR)
&lt;ul&gt;
&lt;li&gt;Like cert, contains public key, name &amp;amp; signature. It&#x27;s self signed by subscriber&#x27;s private key&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Identity proofing
&lt;ul&gt;
&lt;li&gt;Kinds of certificates for Web PKI
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Domain Validation (DV)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;DV certificates bind DNS name, issued based on proof of control over domain name&lt;&#x2F;li&gt;
&lt;li&gt;Traditionally it sends a confirm email to administrative contacts list in WHOIS records&lt;&#x2F;li&gt;
&lt;li&gt;ACME protocol (developed by Let&#x27;s Encrypt) automates this process. It issues a challenge that subscriber must complete to prove control of domain (common challenge include serving random number at given URL(http challenge) or placing random number in DNS TXT record(dns challenge)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Organization Validation (OV), Extended Validation (EV)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;These build on DV they bind not just domain name but also legal entity (organization) that controls it.&lt;&#x2F;li&gt;
&lt;li&gt;OV is deprecated in favour of EV&lt;&#x2F;li&gt;
&lt;li&gt;EV process takes long time (days or week), can include physical application&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;pki-ov-cert.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;expiry&quot;&gt;Expiry&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;New certificate should be replaced with the expiry cert&lt;&#x2F;li&gt;
&lt;li&gt;For internal PKI, you should use shorter expiry times&lt;&#x2F;li&gt;
&lt;li&gt;For internal PKI, you can automate expiry by requesting new cert (with longer expiry) by giving older cert&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;revocation&quot;&gt;Revocation&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;There are provisions to revoke a compromised certificate, but acceptance by relying parties are not uniform&lt;&#x2F;li&gt;
&lt;li&gt;To revoke you can add in Certificate Revocation List (CRLs) or Online Certificate Signing Protocol (OCSP)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;smallstep.com&#x2F;blog&#x2F;everything-pki&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;certificates&#x2F;certificate-management-using-step-cli&#x2F;&quot;&gt;certificate-management-using-step-cli&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;certificates&#x2F;openssl&#x2F;&quot;&gt;openssl&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;security&#x2F;data-encoding&#x2F;#base64&quot;&gt;data-encoding#base64&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;security&#x2F;totp&#x2F;&quot;&gt;totp&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Claude code Workflow</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/claude-code/claude-code-workflow/"/>
        <id>https://ms-choudhary.github.io/notes/claude-code/claude-code-workflow/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/claude-code/claude-code-workflow/">&lt;h3 id=&quot;potential-use-cases&quot;&gt;Potential use cases&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Implement features&lt;&#x2F;li&gt;
&lt;li&gt;Refactor this subsystem&lt;&#x2F;li&gt;
&lt;li&gt;Research this library&lt;&#x2F;li&gt;
&lt;li&gt;Set up this service&lt;&#x2F;li&gt;
&lt;li&gt;Write tests, run them, fix failures&lt;&#x2F;li&gt;
&lt;li&gt;Compare approaches , and propose a plan&lt;&#x2F;li&gt;
&lt;li&gt;Troubleshoot issues and fix them&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;tips&quot;&gt;Tips&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Always use better model for planing: Opus &amp;gt; Sonnet.&lt;&#x2F;li&gt;
&lt;li&gt;If you’re working with some data, first run do some data sanity runs (with ai) and resolve inconsistencies before proceeding with plan.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;skills-tools&quot;&gt;Skills&#x2F;Tools&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;juliusbrussee&#x2F;caveman&quot;&gt;Caveman&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.github.com&#x2F;spec-kit&#x2F;&quot;&gt;spec-kit&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;For larger features, enable  CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
&lt;ul&gt;
&lt;li&gt;1 reviewer agent&lt;&#x2F;li&gt;
&lt;li&gt;1 QE agent writes tests&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nilbuild&#x2F;diffity&quot;&gt;diffity&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Containers</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/container/containers/"/>
        <id>https://ms-choudhary.github.io/notes/container/containers/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/container/containers/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what&quot;&gt;What?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;container is a group of linux processes running isolated in separate namespace&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;simple-container-in-bash&quot;&gt;Simple container in bash&lt;&#x2F;h3&gt;
&lt;p&gt;(Only works on linux) &lt;a href=&quot;http:&#x2F;&#x2F;bit.ly&#x2F;containers-arent-magic&quot;&gt;bit.ly&#x2F;containers-arent-magic&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; download the image&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;wget&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; bit.ly&#x2F;fish-container&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;O&lt;&#x2F;span&gt; fish.tar&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;mkdir&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; container-root&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-continue z-shell&quot;&gt;;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-cd z-shell&quot;&gt;cd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; container-root&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; unpack image to directory&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;tar&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;xf&lt;&#x2F;span&gt; ..&#x2F;fish.tar&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; generate random cgroup name&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;cgroup_id&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;cgroup_&lt;span class=&quot;z-meta z-group z-expansion z-command z-parens z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;shuf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;i&lt;&#x2F;span&gt; 1000-2000&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;n&lt;&#x2F;span&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; make a cgroup &amp;amp; set CPU&#x2F;mem limits&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cgcreate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;g&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;cpu,cpuacct,memory:&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;cgroup_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cgset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;r&lt;&#x2F;span&gt; cpu.shares=512 &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;cgroup_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cgset&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;r&lt;&#x2F;span&gt; memory.limit_in_bytes=1000000000 &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;cgroup_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; use the cgroup&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; make + use some namespaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; change root dir&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; use the right &#x2F;proc&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; change hostname&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; &amp;amp; start fish&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cgexec&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;g&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;cpu,cpuacct,memory:&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;cgroup_id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;  unshare&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;fmuipn&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;mount-proc&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;  chroot &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;PWD&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;  &#x2F;bin&#x2F;sh&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;c&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;bin&#x2F;mount -t proc proc &#x2F;proc &amp;amp;&amp;amp; hostname container-fun-times &amp;amp;&amp;amp; &#x2F;usr&#x2F;bin&#x2F;fish&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;image&quot;&gt;Image&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Image is a tarball of a filesystem&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;container-image-is-tarball.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Image can have multiple layers (to save common files from being downloaded again)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Each layer is a directory of files&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Writes, when the container is run, goes to a temporary layer (which get&#x27;s deleted when container is stopped, so to persist writes you need to mount a volume from outside)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Overlay filesystems&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Linux supports a filesystem comprising of different layers, known as Overlay Filesystem&lt;&#x2F;li&gt;
&lt;li&gt;How it works?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; lowerdir list of all readonly dirs&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; upperdir list of dir where writes should go&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; workdir internal use, empty&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; &#x2F;merged target merged directory&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; overlay overlay&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;o&lt;&#x2F;span&gt; lowerdir=&#x2F;lower,upperdir=&#x2F;upper,workdir=&#x2F;work &lt;span class=&quot;z-punctuation z-separator z-continuation z-line z-shell&quot;&gt;\
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &#x2F;merged&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;container-registry&quot;&gt;Container Registry&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;It&#x27;s a HTTP server which serves images&lt;&#x2F;li&gt;
&lt;li&gt;It lets you download only layers you need&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;linux-kernel-features-which-make-containers-work&quot;&gt;Linux kernel features which make containers work&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;pivot-root&quot;&gt;pivot_root&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;set&#x27;s process&#x27;s root directory to directory which contains image files&lt;&#x2F;li&gt;
&lt;li&gt;chroot, which is typically used to change the root directory, is less secure, because original files are still there (you can access if you&#x27;re root)&lt;&#x2F;li&gt;
&lt;li&gt;containers generally use &lt;code&gt;pivot_root&lt;&#x2F;code&gt; instead. with this you can unmount old filesystem, so it&#x27;s impossible to access them&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;cgroups&quot;&gt;cgroups&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;One problem with traditional systems, is if you club different application in a instance, one application could end up using all resources thus throttling the other.&lt;&#x2F;li&gt;
&lt;li&gt;cgroup is a group of process, all process in a container belong to same cgroup&lt;&#x2F;li&gt;
&lt;li&gt;cgroup can have memory&#x2F;CPU limits per group (all process in a container share those resources)&lt;&#x2F;li&gt;
&lt;li&gt;If a process uses more memory then limit, it&#x27;s OOM killed&lt;&#x2F;li&gt;
&lt;li&gt;If a process uses more CPU then limit, it&#x27;s throttled&lt;&#x2F;li&gt;
&lt;li&gt;cgroups track these resources &lt;code&gt;&#x2F;sys&#x2F;fs&#x2F;cgroup&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;namespaces&quot;&gt;namespaces&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Is how you isolate the containers from the host&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Default namespace (host) is where things run outside a container&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Each process can have any combination of namespaces (eg, using host network namespace but it&#x27;s own mount namespaces)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;To list namespaces for a process (&lt;code&gt;lsns -p &amp;lt;PID&amp;gt;&lt;&#x2F;code&gt;) or (&lt;code&gt;ls -l &#x2F;proc&#x2F;&amp;lt;PID&amp;gt;&#x2F;ns&lt;&#x2F;code&gt; )&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;How to create namespace&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Child processes inherit the namespace from it&#x27;s parent&lt;&#x2F;li&gt;
&lt;li&gt;Tools&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; run in new network namespace&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;unshare&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;net&lt;&#x2F;span&gt; COMMAND&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; list all namespaces&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; lsns&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;p&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;PID&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; or ls&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;l&lt;&#x2F;span&gt; &#x2F;proc&#x2F;PID&#x2F;ns&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; run a command in PID&amp;#39;s ns&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;nsenter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; PID&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;all&lt;&#x2F;span&gt; COMMAND&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Different types of namespace (each ns has a man page, eg, &lt;code&gt;man network_namespaces&lt;&#x2F;code&gt;)&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;pid&quot;&gt;pid&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;same process has different PIDs in different ns&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;container-pid-ns.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if PID 1 gets killed, every process in the ns is killed&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;user&quot;&gt;user&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;it&#x27;s a security feature, where you can map root user inside container to unprivileged user in host&lt;&#x2F;li&gt;
&lt;li&gt;in user namespace, UIDs are mapped to host UIDs, unmapped users are shown as &lt;code&gt;nobody&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h5 id=&quot;network&quot;&gt;network&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;created by&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ip netns add &amp;lt;name&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;has separate virtual interfaces for containers (usually two, loopback &amp;amp; normal)&lt;&#x2F;li&gt;
&lt;li&gt;physical network card is in host network namespace&lt;&#x2F;li&gt;
&lt;li&gt;other namespaces are connected to the host via bridge&lt;&#x2F;li&gt;
&lt;li&gt;containers are assigned private IPs&lt;&#x2F;li&gt;
&lt;li&gt;cloud providers have systems to make containers IPs work (&quot;elastic network interface&quot;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;capabilities&quot;&gt;capabilities&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;process needs to have capabilities (in addition of being root) to get work done&lt;&#x2F;li&gt;
&lt;li&gt;check&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;man capabilities
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CAP_SYS_ADMIN&lt;&#x2F;code&gt; is like admin&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;CAP_NET_ADMIN&lt;&#x2F;code&gt; allow changes to network settings&lt;&#x2F;li&gt;
&lt;li&gt;list capabilities for a PID&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;getpcaps PID
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getcap&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;setcap&lt;&#x2F;code&gt; system calls to set&#x2F;get capabilities&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;seccomp-bpf&quot;&gt;seccomp-bpf&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;used to block certain system calls that process can execute (docker does this)&lt;&#x2F;li&gt;
&lt;li&gt;seccomp-bpf lets you run a function before each system call&lt;&#x2F;li&gt;
&lt;li&gt;this function decides if the sys call is allowed&lt;&#x2F;li&gt;
&lt;li&gt;you can set a whitelist for a process&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;things-you-can-configure-while-starting-a-container&quot;&gt;Things you can configure while starting a container&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;map a port inside container to the host&lt;&#x2F;li&gt;
&lt;li&gt;mount directories from the host&lt;&#x2F;li&gt;
&lt;li&gt;set capabilities&lt;&#x2F;li&gt;
&lt;li&gt;add seccomp-bpf filters&lt;&#x2F;li&gt;
&lt;li&gt;set memory &amp;amp; CPU limits&lt;&#x2F;li&gt;
&lt;li&gt;use host network namespace&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;container-security&quot;&gt;Container security&lt;&#x2F;h3&gt;
&lt;p&gt;Containers are advisable only for trusted workloads. Security failure in containers happen due to following:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;mis-configuration&quot;&gt;Mis configuration&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;Running as privileged containers, effectively removes all guard rails. It basically runs as root.&lt;&#x2F;li&gt;
&lt;li&gt;Mounting docker socket in containers (&lt;code&gt;&#x2F;var&#x2F;run&#x2F;docker.socket&lt;&#x2F;code&gt;), allows it to create privileged containers, hence gives access to root.&lt;&#x2F;li&gt;
&lt;li&gt;Writable sys and &#x2F;proc&#x2F;sys, these expose kernel controls&lt;&#x2F;li&gt;
&lt;li&gt;Writable dir, bind mounted inside containers.&lt;&#x2F;li&gt;
&lt;li&gt;Adding broad capabilities, eg &lt;code&gt;CAP_SYS_ADMIN&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Joining host namespaces, eg &lt;code&gt;--pid=host&lt;&#x2F;code&gt; or &lt;code&gt;--net=host&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Device passthrough (for eg like gpu), can expose raw kernel interfaces.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;shared-host-kernel&quot;&gt;Shared host kernel&lt;&#x2F;h4&gt;
&lt;p&gt;Containers share the same kernel as host. Even if there&#x27;s no misconfiguration, any kernel bug in the allowed syscalls, filesystem path or netstack behaviour can be triggered from inside the container. For eg, ioctl syscall has huge attack surface.&lt;&#x2F;p&gt;
&lt;p&gt;Apart from misconfiguration and kernel bugs, bugs in container runtime also impact security.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;container-networking&#x2F;&quot;&gt;container-networking&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Docker Multiarch Images</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/container/docker-multiarch-images/"/>
        <id>https://ms-choudhary.github.io/notes/container/docker-multiarch-images/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/container/docker-multiarch-images/">&lt;p&gt;Docker image is specific for os + host architecture (eg linux + arm64 or linux + amd64).&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt; $ docker image inspect miniflux&#x2F;miniflux | jq &amp;#39;.[] | &amp;quot;\(.Os)\&#x2F;\(.Architecture)&amp;quot;&amp;#39;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;quot;linux&#x2F;arm64&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Same image can be built for different architectures. Running non multi arch image on incorrect platform will fail. Docker pulls correct image from registry based on os&#x2F;arch set in docker engine.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ docker version
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  OS&#x2F;Arch:          linux&#x2F;arm64
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Image listing on dockerhub generally shows if it&#x27;s a multiarch image (os&#x2F;arch) for each tag.&lt;&#x2F;p&gt;
&lt;p&gt;Image manifests files contains all individual multi arch images links. This is part of docker&#x2F;OCI  registry spec.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ docker manifest inspect alpine:latest
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;   &amp;quot;schemaVersion&amp;quot;: 2,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;   &amp;quot;mediaType&amp;quot;: &amp;quot;application&#x2F;vnd.oci.image.index.v1+json&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;   &amp;quot;manifests&amp;quot;: [
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         &amp;quot;mediaType&amp;quot;: &amp;quot;application&#x2F;vnd.oci.image.manifest.v1+json&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         &amp;quot;size&amp;quot;: 1022,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         &amp;quot;digest&amp;quot;: &amp;quot;sha256:59855d3dceb3ae53991193bd03301e082b2a7faa56a514b03527ae0ec2ce3a95&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         &amp;quot;platform&amp;quot;: {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &amp;quot;architecture&amp;quot;: &amp;quot;amd64&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &amp;quot;os&amp;quot;: &amp;quot;linux&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;         }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;      },
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pulling &lt;code&gt;alpine:latest&lt;&#x2F;code&gt; in this case will fetch the image mainfest file, it then matches the local os&#x2F;arch and pulls the corresponding image sha. Image spec contains individual layers, which are pulled next.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ docker image inspect alpine:latest
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        &amp;quot;RootFS&amp;quot;: {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &amp;quot;Type&amp;quot;: &amp;quot;layers&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            &amp;quot;Layers&amp;quot;: [
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                &amp;quot;sha256:0b83d017db6efafadf6b3f18d087d2ce1d67d8f0e927dc7254b0ad088074cd3a&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                &amp;quot;sha256:1c2824e33c7138199cf5b48c29289ceb30179b427bf1cee68cf2f502b537ae82&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;                &amp;quot;sha256:f19172968839067b8298f671f9d192997f1e8cc7b79604b4df72793197668477&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;            ]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        },
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Non multiarch images manifest just link a single image.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;build&quot;&gt;Build&lt;&#x2F;h3&gt;
&lt;p&gt;To build a multi arch image, you can build and push the image separately for each arch on a build farm (set of machines with different arch). Each of these image exists as a separate manifest. Finally create a common manifest file linking all previous images, and push that to registry.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ docker manifest create alpine:latest alpine:arm64-latest alpine:amd64-latest
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ docker manifest push alpine:latest
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In dockerfile, if base image is multi arch, you don&#x27;t need to do anything else. It should pull correct image and build your app for correct platform. If, however, base is not multi arch, you need to create and maintain separate dockerfile for each architecture.&lt;&#x2F;p&gt;
&lt;p&gt;In recent docker (with buildx), you can run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ docker build --platform linux&#x2F;amd64, linux&#x2F;arm64 image .
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to automate all these separate steps, i.e, building and pushing individual images and creating manifest.&lt;&#x2F;p&gt;
&lt;p&gt;It requires emulation via qemu, that must be separately configured.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=cDJrQ4IzZ_M&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Explore qemu emulation and binfmt_misc #question&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;container&#x2F;containers&#x2F;#image&quot;&gt;containers#Image&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Common git commands</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/git/common-git-commands/"/>
        <id>https://ms-choudhary.github.io/notes/git/common-git-commands/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/git/common-git-commands/">&lt;h3 id=&quot;list-remotes&quot;&gt;List Remotes&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;git remote -v
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;add-remote&quot;&gt;Add remote&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;git remote add &amp;lt;name&amp;gt; &amp;lt;url&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;show-current-head&quot;&gt;Show current head&lt;&#x2F;h3&gt;
&lt;p&gt;Used in scripting:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;git rev-parse HEAD
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;visualize-history-as-dag&quot;&gt;Visualize history as DAG&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;git log --all --graph --decorate
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;interactive-staging&quot;&gt;Interactive staging&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;git add -p .
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note: this doesn&#x27;t consider untracked changes (new files not added yet). To add them:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;git add -N .
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;-N&lt;&#x2F;code&gt; = &lt;code&gt;--intent-to-add&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interactive-rebase&quot;&gt;Interactive rebase&lt;&#x2F;h3&gt;
&lt;p&gt;Used for squashing commits:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;git rebase -i origin main
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# Commands:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# p, pick &amp;lt;commit&amp;gt; = use commit
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# r, reword &amp;lt;commit&amp;gt; = use commit, but edit the commit message
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# e, edit &amp;lt;commit&amp;gt; = use commit, but stop for amending
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# s, squash &amp;lt;commit&amp;gt; = use commit, but meld into previous commit
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Git&#x27;s data model as psuedo code</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/git/git-data-model-as-psuedo-code/"/>
        <id>https://ms-choudhary.github.io/notes/git/git-data-model-as-psuedo-code/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/git/git-data-model-as-psuedo-code/">&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;type blob = array&amp;lt;byte&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; name of file&#x2F;dir =&amp;gt; it&amp;#39;s contents
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;type tree = map&amp;lt;string, tree | blob&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; commits can have multiple parents, and top level tree
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;type commit = struct {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  parent: array&amp;lt;commit&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  author: string
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  message: string
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  snapshot: tree
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; all blob&#x2F;tree&#x2F;commit are unified as objs
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;type object = blob | tree | commit
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; all objs are hashed and stored. key is the hash
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;objects = map&amp;lt;string, object&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;def store(object):
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  id = sha1(object)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  objects[id] = object
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;def load(id):
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  return objects[id]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; human readable name (eg, master) =&amp;gt; objects hash
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;references = map&amp;lt;string, string&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;def update_reference(name, id):
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  references[name] = id
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;def read_reference(name):
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  return references[name]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;def load_reference(name_or_id):
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  if name_or_id in references:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    return load(references[name_or_id])
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  else:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    return load(name_or_id)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;All folders are tree in git&lt;&#x2F;li&gt;
&lt;li&gt;All files are blobs&lt;&#x2F;li&gt;
&lt;li&gt;Commit is like snapshot of all files. They can be linked with multiple parents, which forms history.&lt;&#x2F;li&gt;
&lt;li&gt;All blobs&#x2F;tree&#x2F;commits are represented as objects&lt;&#x2F;li&gt;
&lt;li&gt;All objects are represented by SHA-1 hash of it&#x27;s content, so it&#x27;s easy to know when files change.&lt;&#x2F;li&gt;
&lt;li&gt;References then are human readable translation of hash of these objects (eg master&#x2F;feature-fix-auth)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;HEAD&lt;&#x2F;code&gt; is a reference of latest&#x2F;current commit sha in the project&lt;&#x2F;li&gt;
&lt;li&gt;All git objects except references are immutable (all that you do with destructive commands like &lt;code&gt;reset —hard&lt;&#x2F;code&gt; is just point to different references). Thus it&#x27;s hard to lose any data in git.&lt;&#x2F;li&gt;
&lt;li&gt;Git objects and references defines all the data inside git dir&lt;&#x2F;li&gt;
&lt;li&gt;All git commands does is manipulate this DAG by adding objects, adding&#x2F;updating references&lt;&#x2F;li&gt;
&lt;li&gt;Use command: &lt;code&gt;git cat-file -p &amp;lt;hash&amp;gt;&lt;&#x2F;code&gt; to decode and print what git obj with hash contains&lt;&#x2F;li&gt;
&lt;li&gt;Staged &#x2F; Unstaged changes
&lt;ul&gt;
&lt;li&gt;When you make any change, git will show the change made, but this change is not yet tracked (ie, you can lose the changes)&lt;&#x2F;li&gt;
&lt;li&gt;To track the changes with git, you&#x27;ve add them by &lt;code&gt;git add &amp;lt;files&amp;gt;&lt;&#x2F;code&gt; . This stores all these changes in index (which is like a tree and keeps track of all changes added)&lt;&#x2F;li&gt;
&lt;li&gt;On commit, git uses this index to create current snapshot of project&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Three ways git merge
&lt;ul&gt;
&lt;li&gt;Checkout branch &lt;code&gt;b&lt;&#x2F;code&gt; from master, update a file and commit. Checkout back to master. What happens when you run &lt;code&gt;git merge b&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;Git checks two commits of refs &lt;code&gt;master&lt;&#x2F;code&gt; &amp;amp; &lt;code&gt;b&lt;&#x2F;code&gt; and sees one is a parent of other, it just updates &lt;code&gt;master&lt;&#x2F;code&gt; to new commit &amp;amp; calls it a day&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Checkout &lt;code&gt;b&lt;&#x2F;code&gt; , update a file &lt;code&gt;foo.txt&lt;&#x2F;code&gt;, while in a separate flow, master also updates file &lt;code&gt;bar.txt&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;Git now sees two different commits, it traces back in history to a common commit. Checks what changed in these two new commits. Since changes are in separate files. It creates a new commit, with all changes, and sets the parent as the two commits.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Update same file as in master
&lt;ul&gt;
&lt;li&gt;Follow steps similar as above, but now it sees that commits in question have conflicting changes. It seeks developer assistance in resolving it, instead of being over smart.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;missing.csail.mit.edu&#x2F;2026&#x2F;version-control&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Merge Strategies</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/git/merge-strategies/"/>
        <id>https://ms-choudhary.github.io/notes/git/merge-strategies/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/git/merge-strategies/">&lt;p&gt;If there&#x27;re too many conflicts, and you just want to either accept our&#x2F;their code, you can use flag &lt;code&gt;-X theirs&lt;&#x2F;code&gt; or &lt;code&gt;-X ours&lt;&#x2F;code&gt; with all git commands doing either merge&#x2F;rebase.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Currently on&lt;&#x2F;th&gt;&lt;th&gt;Command&lt;&#x2F;th&gt;&lt;th&gt;Strategy&lt;&#x2F;th&gt;&lt;th&gt;Outcome&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;master&lt;&#x2F;td&gt;&lt;td&gt;git merge feature&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;-Xtheirs&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Keep changes from feature branch&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;master&lt;&#x2F;td&gt;&lt;td&gt;git merge feature&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;-Xours&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;keep changes from master branch&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;feature&lt;&#x2F;td&gt;&lt;td&gt;git rebase master&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;-Xtheirs&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;Keep changes from feature branch&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;feature&lt;&#x2F;td&gt;&lt;td&gt;git rebase master&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;-Xours&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;keep changes from master branch&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Oh shit git!</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/git/oh-shit-git/"/>
        <id>https://ms-choudhary.github.io/notes/git/oh-shit-git/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/git/oh-shit-git/">&lt;h3 id=&quot;i-committed-but-forgot-to-make-a-small-change-wrong-commit-message&quot;&gt;I committed but forgot to make a small change&#x2F;wrong commit message&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; add .&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commit&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;amend&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;no-edit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;accidentally-committed-to-master-when-it-should-ve-been-to-new-branch&quot;&gt;Accidentally committed to master, when it should&#x27;ve been to new branch&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; branch new-branch&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; removes last commit from master&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; reset HEAD&lt;span class=&quot;z-meta z-group z-expansion z-tilde&quot;&gt;&lt;span class=&quot;z-variable z-language z-tilde z-shell&quot;&gt;~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;hard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; this branch still contains the commit though!&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; checkout new-branch&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;accidentally-committed-to-wrong-branch&quot;&gt;Accidentally committed to wrong branch&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; checkout correct-branch&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; get the last commit to master&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; cherry-pick master&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; checkout master&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; reset HEAD&lt;span class=&quot;z-meta z-group z-expansion z-tilde&quot;&gt;&lt;span class=&quot;z-variable z-language z-tilde z-shell&quot;&gt;~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;hard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;undo-a-commit-from-like-5-commits-ago&quot;&gt;Undo a commit from like 5 commits ago&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; find the commit&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; log&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; revert &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;hash&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;undo-my-changes-to-a-file&quot;&gt;Undo my changes to a file&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; find hash before the file was changed&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; log&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; set&amp;#39;s old version in index&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; checkout &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;hash&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-terminator z-file-descriptor z-shell&quot;&gt;-&lt;&#x2F;span&gt;- &lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;path&#x2F;to&#x2F;file&lt;span class=&quot;z-keyword z-operator z-assignment z-redirection z-shell&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; commit&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;m&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;you can do this smartly too&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go build</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/go/go-build/"/>
        <id>https://ms-choudhary.github.io/notes/go/go-build/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/go/go-build/">&lt;h3 id=&quot;cross-compilation&quot;&gt;Cross compilation&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;env GOOS=target-OS GOARCH=target-architecture go build package-import-path
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;where target-os can be: &lt;code&gt;linux, darwin, android, windows, freebsd, netbsd, openbsd, dragonfly, plan9&lt;&#x2F;code&gt;&lt;br &#x2F;&gt;
where target-architecture can be: &lt;code&gt;arm, arm64, amd64&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;static-build&quot;&gt;Static build&lt;&#x2F;h3&gt;
&lt;p&gt;Using static build, go skips linking to libc&#x2F;musl libraries. Instead implements it&#x27;s own library calling syscall directly.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;CGO_ENABLED=0 go build -a -ldflags &amp;#39;-extldflags &amp;quot;-static&amp;quot;&amp;#39; .
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;go-always-builds-binaries-with-versioning&quot;&gt;Go always builds binaries with versioning&lt;&#x2F;h3&gt;
&lt;p&gt;If you run go build from a git repository, it versions the binary by default.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ go version -m gmail2gullak | grep vcs
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        build   vcs=git
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        build   vcs.revision=a952a27dab46dfe460bb209a9b39a1bae6b15ffd
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        build   vcs.time=2026-04-24T12:08:34Z
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ go version gmail2gullak
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;gmail2gullak: go1.25.0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This also prints which go toolchain was used to build the binary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;go&#x2F;go-compilation-tools&#x2F;&quot;&gt;go-compilation-tools&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go compilation tools</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/go/go-compilation-tools/"/>
        <id>https://ms-choudhary.github.io/notes/go/go-compilation-tools/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/go/go-compilation-tools/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=qPIB3STWXVk&lt;&#x2F;p&gt;
&lt;h3 id=&quot;flow&quot;&gt;Flow&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;mermaid&quot; class=&quot;language-mermaid z-code&quot;&gt;&lt;code class=&quot;language-mermaid&quot; data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;flowchart TD;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A[*.go]--&amp;gt; |Compiler| B[*.a];
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;B--&amp;gt; C[Linker];
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;C--&amp;gt; D[Binary];
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If go files are unmodified, there&#x27;s no need to compile them again. This makes rebuild faster.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compilation&quot;&gt;Compilation&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;mermaid&quot; class=&quot;language-mermaid z-code&quot;&gt;&lt;code class=&quot;language-mermaid&quot; data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;flowchart TD;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;A[Code]--&amp;gt; |Lexing &amp;amp; Parsing| B[AST];
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;B--&amp;gt; |Transformations on AST| C[SSA];
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;C--&amp;gt; |Optimizations| D[Machine code];
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;SSA is platform agnostic&lt;&#x2F;p&gt;
&lt;h3 id=&quot;go-build-flags&quot;&gt;go build flags&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-a&lt;&#x2F;code&gt; = force rebuild after clearing cache&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-v&lt;&#x2F;code&gt; = shows list of packages used in the build&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-x&lt;&#x2F;code&gt; = shows internal tooling invocation&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-n&lt;&#x2F;code&gt; = same as &lt;code&gt;-x&lt;&#x2F;code&gt; but dry run options, just shows the plan what will be done&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-work&lt;&#x2F;code&gt; = print and keep the work dir (where all intermediate artifacts are stored)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;explore-compilation-internal-steps&quot;&gt;Explore compilation internal steps&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;GOSSAFUNC=main go build -a # generates ssa html for going into depth 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is fun interactive way to check the intermediate compilation steps.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compiler-flags&quot;&gt;Compiler flags&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-gcflags=&quot;-S&quot;&lt;&#x2F;code&gt; = shows intermediate assembly&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This is different from platform specifc assembly, if you want to see platform specific code:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;go tool objdump -S main.main &amp;lt;bin_name&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-gcflags=&quot;-N&quot;&lt;&#x2F;code&gt; = disable compiler optimization&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-gcflags=&quot;-m&quot;&lt;&#x2F;code&gt; = shows escape analysis (explains what goes in heap vs stack) &lt;code&gt;-m=2&lt;&#x2F;code&gt; for verbose, useful to see how much garbage is generated&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-gcflags=&quot;-live&quot;&lt;&#x2F;code&gt; = shows liveness analysis. calculate live variables at each point in program.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-gcflags=&quot;-bench=bench.out&quot;&lt;&#x2F;code&gt; = shows benchmark&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-gcflags=&quot;-race&quot;&lt;&#x2F;code&gt; = race detection&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-gcflags=&quot;-memprofile=profile.out&quot;&lt;&#x2F;code&gt; = shows memory profile in lifetime of build&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;go tool pprof -http :7070 profile.out&lt;&#x2F;code&gt; to open in webui&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;-gcflags=&quot;-traceprofile=trace.out&quot;&lt;&#x2F;code&gt;= shows execution trace&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;go-list&quot;&gt;go list&lt;&#x2F;h2&gt;
&lt;p&gt;Shows meta information about gocode. See &lt;a href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;cmd&#x2F;go&#x2F;internal&#x2F;list&quot;&gt;docs&lt;&#x2F;a&gt; for all fields available in templating.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;list-all-go-files-that-go-in-the-build&quot;&gt;List all go files that go in the build&lt;&#x2F;h4&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;go list -f {{.GoFiles}} 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;GOOS=windows go list -f {{.GoFiles}} # includes main_windows.go (windows specific files)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;nm-tool&quot;&gt;nm tool&lt;&#x2F;h2&gt;
&lt;p&gt;Shows all symbols used by the binary. Useful for figuring out dynamic libararies used etc.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;go tool nm &amp;lt;binname&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;While this does go in depth on practical tools, need more indepth understanding of compilation process #question
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=uTMvKVma5ms&amp;amp;t=10s&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Need to explore go runtime as well #question&lt;&#x2F;li&gt;
&lt;li&gt;How does this integrate with gdb and other debuggers ? #question&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;go&#x2F;go-build&#x2F;&quot;&gt;go-build&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go HTTP</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/go/go-http/"/>
        <id>https://ms-choudhary.github.io/notes/go/go-http/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/go/go-http/">&lt;h2 id=&quot;mux&quot;&gt;Mux&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func main() {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    mux := http.NewServeMux()
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    mux.HandleFunc(&amp;quot;GET &#x2F;posts&amp;quot;,          listPosts)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    mux.HandleFunc(&amp;quot;POST &#x2F;posts&amp;quot;,         createPost)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    mux.HandleFunc(&amp;quot;GET &#x2F;posts&#x2F;{id}&amp;quot;,     getPost)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    mux.HandleFunc(&amp;quot;PUT &#x2F;posts&#x2F;{id}&amp;quot;,     updatePost)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    mux.HandleFunc(&amp;quot;DELETE &#x2F;posts&#x2F;{id}&amp;quot;,  deletePost)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    http.ListenAndServe(&amp;quot;:8080&amp;quot;, mux)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;path-values&quot;&gt;Path values&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mux.HandleFunc(&amp;quot;GET &#x2F;users&#x2F;{id}&amp;quot;, func(w http.ResponseWriter, r *http.Request) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    id := r.PathValue(&amp;quot;id&amp;quot;)  &#x2F;&#x2F; new in 1.22
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    fmt.Fprintf(w, &amp;quot;User ID: %s&amp;quot;, id)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;})
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;http-middleware&quot;&gt;HTTP Middleware&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;pattern&quot;&gt;Pattern&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func exampleMiddleware(next http.Handler) http.Handler {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		&#x2F;&#x2F; Your middleware logic goes here...
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		next.ServeHTTP(w, r)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	})
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func fooHandler(w http.ResponseWriter, r *http.Request) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	w.Write([]byte(&amp;quot;foo&amp;quot;))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func main() {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	mux := http.NewServeMux()
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	mux.Handle(&amp;quot;&#x2F;foo&amp;quot;, exampleMiddleware(http.HandleFunc(fooHandler)))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	log.Fatal(http.ListenAndServe(&amp;quot;:3000&amp;quot;, mux))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To add middleware for all routes, add it on http.ServeMux() (since it implements http.Handler interface).&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;log.Fatal(http.ListenAndServe(&amp;quot;:3000&amp;quot;, myMiddleware(mux)))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;chain&quot;&gt;Chain&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;type chain []func(http.Handler) http.Handler
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func (c chain) thenFunc(h http.HandlerFunc) http.Handler {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    return c.then(h)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func (c chain) then(h http.Handler) http.Handler {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    for _, mw := range slices.Backward(c) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        h = mw(h)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    return h
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Usage:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mux := http.NewServeMux()
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; Create a base middleware chain. 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;baseChain := chain{requestID, logRequest}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; Extend the base chain with auth middleware for admin-only routes.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;adminChain := append(baseChain, authenticateUser, requireAdminUser)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mux.Handle(&amp;quot;GET &#x2F;static&#x2F;&amp;quot;, spaHandler(http.FileServerFS(ui.Files)))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mux.Handle(&amp;quot;GET &#x2F;&amp;quot;, baseChain.thenFunc(home))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mux.Handle(&amp;quot;GET &#x2F;article&#x2F;{id}&amp;quot;, baseChain.thenFunc(showArticle))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mux.Handle(&amp;quot;GET &#x2F;admin&amp;quot;, adminChain.thenFunc(showAdminDashboard))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;use-cases&quot;&gt;Use cases&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Check if user is authenticated&lt;&#x2F;li&gt;
&lt;li&gt;Check for headers like &lt;code&gt;Content-Type&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Implement rate limit logic&lt;&#x2F;li&gt;
&lt;li&gt;Add http headers in response&lt;&#x2F;li&gt;
&lt;li&gt;Log request &amp;amp; response automatically using &lt;code&gt;log&#x2F;slog&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.alexedwards.net&#x2F;blog&#x2F;making-and-using-middleware&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.alexedwards.net&#x2F;blog&#x2F;organize-your-go-middleware-without-dependencies&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;go&#x2F;handling-spa-go&#x2F;&quot;&gt;handling-spa-go&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Golang Language</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/go/go-language/"/>
        <id>https://ms-choudhary.github.io/notes/go/go-language/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/go/go-language/">&lt;h2 id=&quot;array-slices&quot;&gt;Array, Slices&lt;&#x2F;h2&gt;
&lt;p&gt;Source: https:&#x2F;&#x2F;go.dev&#x2F;blog&#x2F;slices&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Array is the building block of contingous items, contains size as part of it&#x27;s definition. eg &lt;code&gt;var buffer [256]byte&lt;&#x2F;code&gt;. Arrays are always fixed size.&lt;&#x2F;li&gt;
&lt;li&gt;Slice is a datastructure which describes a contiguous section of array: &lt;code&gt;var slice []byte = buffer[100:150]&lt;&#x2F;code&gt;. Behind the scenes, it contains the pointer to array, length and capacity (maximum length to which slice can extend).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;string-rune-character-byte&quot;&gt;String, Rune, Character, Byte&lt;&#x2F;h2&gt;
&lt;p&gt;Source: https:&#x2F;&#x2F;go.dev&#x2F;blog&#x2F;strings&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;String in golang is slice of bytes&lt;&#x2F;li&gt;
&lt;li&gt;String literals are always utf-8 encoded. (Go source code) eg &lt;code&gt;const nihongo = &quot;日本語&quot;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;In unicode standard, each character is represented by &quot;code point&quot; eg, U+2318 represents &lt;code&gt;⌘&lt;&#x2F;code&gt; , in golang this code point is referred as rune (aliased to int32)&lt;&#x2F;li&gt;
&lt;li&gt;When you range through a loop, it decodes 1 utf-8 length rune on each loop&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;time&quot;&gt;Time&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;time@go1.23.2#Time.Format&quot;&gt;Layout string in time&lt;&#x2F;a&gt;.Parse and time.Format expects this date (reference date): 01&#x2F;02&#x2F;2006  &lt;code&gt;Jan 2 15:04:05 2006 MST&lt;&#x2F;code&gt; (Note the date should be this specific date and time for it to parse successfully). Following shows some example:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;time.Parse(&amp;quot;01&#x2F;02&#x2F;2006&amp;quot;, &amp;quot;10&#x2F;02&#x2F;2024&amp;quot;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;time.Parse(&amp;quot;02 of 01 2006&amp;quot;, &amp;quot;02 of 10 2024&amp;quot;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;embed-files-in-binary&quot;&gt;Embed files in binary&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;embed&lt;&#x2F;code&gt; package to add files to binary at compile time&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;use-local-dependency&quot;&gt;Use local dependency&lt;&#x2F;h2&gt;
&lt;p&gt;To use local version of the dependency, you can clone the deps in dir $DEP, then use replace directive in go mod&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;$ go mod edit -replace github.com&#x2F;google&#x2F;go-cmp=$DEP&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;import-local-modules&quot;&gt;Import local modules&lt;&#x2F;h2&gt;
&lt;p&gt;Import other packages rather than main package&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import (
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  &amp;quot;noc-manager&#x2F;pkg&#x2F;models&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Run &lt;code&gt;go mod edit -replace noc-manager=..&#x2F;..&#x2F;noc-manager&lt;&#x2F;code&gt; to add a local dependency &amp;amp; run &lt;code&gt;go mod tidy&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Tip: Name modules as simple names rather than git urls unless you&#x27;re planning on publishing them. Otherwise you might get weird issues.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;commandline&quot;&gt;CommandLine&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;After parsing flags you can get other arguments via: &lt;code&gt;flag.Args()&lt;&#x2F;code&gt; (array) or &lt;code&gt;flag.Arg(i)&lt;&#x2F;code&gt; specific arg. &lt;code&gt;flag.Narg&lt;&#x2F;code&gt; = number of args&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;run-debugger&quot;&gt;Run debugger&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ go install github.com&#x2F;go-delve&#x2F;delve&#x2F;cmd&#x2F;dlv@latest
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; in root dir
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ dlv debug
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sql&quot;&gt;Sql&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;For database sql, checkout &lt;a href=&quot;https:&#x2F;&#x2F;go.dev&#x2F;wiki&#x2F;SQLInterface&quot;&gt;this wiki&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;slog&quot;&gt;Slog&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;slog.Info(msg, k1, v1, k2, v2)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Log consists of log level, message, and key value pairs (it is assumed that key will follow value in above example).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;levels&quot;&gt;Levels&lt;&#x2F;h4&gt;
&lt;p&gt;Some common levels include Info, Warn, Debug, Error. But since, log levels are integers, you can define your own custom levels.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;handlers&quot;&gt;Handlers&lt;&#x2F;h4&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;logger := slog.NewTextHandler()
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;logger.Info(msg, user, os.Getenv(USER))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;slog supports multiple handlers, you can even write your own custom handler. Some common handlers include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;slog.NewTextHandler (prints key=value in text)&lt;&#x2F;li&gt;
&lt;li&gt;slog.NewJSONHandler (prints key value in json)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Out of Box, if you don&#x27;t use specific handler, it uses default Logger instance.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For more info, checkout docs: &lt;a href=&quot;https:&#x2F;&#x2F;pkg.go.dev&#x2F;log&#x2F;slog&quot;&gt;slog&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;tostring-equivalent&quot;&gt;ToString equivalent&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;type Transaction struct {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  Amount          float64 `json:&amp;quot;amount&amp;quot;`
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  Description     string  `json:&amp;quot;description&amp;quot;`
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  TransactionDate string  `json:&amp;quot;transaction_date&amp;quot;`
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func (t Transaction) String() string {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  return fmt.Sprintf(&amp;quot;Amount: %f, Description: %s, Date: %s&amp;quot;, t.Amount, t.Description, t.TransactionDate)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;regexp&quot;&gt;Regexp&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;package main
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;import (
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	&amp;quot;fmt&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	&amp;quot;regexp&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func main() {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	re := regexp.MustCompile(`Rs\.(\d+(?:\.\d+)?) has been debited`)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	fmt.Printf(&amp;quot;%q\n&amp;quot;, re.FindStringSubmatch(&amp;quot;Dear Customer, Rs.396.00 has been debited from account&amp;quot;))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[&amp;quot;Rs.396.00 has been debited&amp;quot; &amp;quot;396.00&amp;quot;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;get-error-in-string&quot;&gt;Get error in string&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;s := err.Error()
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;json-or-yaml-omitempty-or-ignore&quot;&gt;JSON or YAML omitempty or ignore&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;type T struct {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    F int `yaml:&amp;quot;a,omitempty&amp;quot;`
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    B int `yaml:&amp;quot;-&amp;quot;` &#x2F;&#x2F; this field will be ignored from rendering
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;type T struct {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    F int `json:&amp;quot;a,omitempty&amp;quot;`
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    B int `json:&amp;quot;-&amp;quot;` &#x2F;&#x2F; this field will be ignored from rendering
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;json-encoder-decoder&quot;&gt;Json Encoder&#x2F;Decoder&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;encodings&#x2F;json&lt;&#x2F;code&gt; package has Encoder&#x2F;Decoder, can be used as:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;err := json.NewDecoder(resp.Body).Decode(&amp;amp;var)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;it accepts any input which implements interfaces io.Reader or io.Writer (basically streaming data). Some core data sources which implement it are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;os.File (read from file on disk)&lt;&#x2F;li&gt;
&lt;li&gt;strings.Reader (allows to read string)&lt;&#x2F;li&gt;
&lt;li&gt;http.Response.Body (http response)&lt;&#x2F;li&gt;
&lt;li&gt;bytes.Buffer (similar to string, in memory buffer)&lt;&#x2F;li&gt;
&lt;li&gt;net.Conn (allows reading from socket, tcp or udp)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go project layout</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/go/go-project-layout/"/>
        <id>https://ms-choudhary.github.io/notes/go/go-project-layout/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/go/go-project-layout/">&lt;h3 id=&quot;project-layout&quot;&gt;Project Layout&lt;&#x2F;h3&gt;
&lt;p&gt;Code is structured in golang using &lt;strong&gt;files, packages &amp;amp; modules&lt;&#x2F;strong&gt;. Each new dir indicates a new package.&lt;&#x2F;p&gt;
&lt;p&gt;Only create a new package if you see demonstrable need for it. It&#x27;s okay for files to be longer. Focus should be on reusability. Package should be standalone, isolated and should enforce boundaries with other code.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;simple&quot;&gt;Simple&lt;&#x2F;h4&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── main.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── foo.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── bar.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── go.mod
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;└── README.md
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;small-with-supporting-packages&quot;&gt;Small with supporting packages&lt;&#x2F;h4&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── internal
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│   └── foo
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│       └── foo.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── main.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── bar.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── go.mod
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;└── README.md
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;large&quot;&gt;Large&lt;&#x2F;h4&gt;
&lt;p&gt;Consists of lots of non go assets (eg templates, database migration etc). Also multiple binaries like (server, client etc).&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── cmd
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│   └── foo
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│       ├── main.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│       └── bar.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── internal
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│   └── baz
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│       └── baz.go
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── go.mod
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├── Makefile
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;└── README.md
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.alexedwards.net&#x2F;blog&#x2F;11-tips-for-structuring-your-go-projects&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;go&#x2F;go-language&#x2F;&quot;&gt;go-language&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fixing 404s When Serving SPA from a Go Binary</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/go/handling-spa-go/"/>
        <id>https://ms-choudhary.github.io/notes/go/handling-spa-go/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/go/handling-spa-go/">&lt;p&gt;This is a sample go code I was using to host frontend UI directly from golang:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F;go:embed ui&#x2F;dist&#x2F;*
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;var frontendFS embed.FS
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func main() {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	distFS, err := fs.Sub(frontendFS, &amp;quot;ui&#x2F;dist&amp;quot;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	if err != nil {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		log.Fatal(err)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	frontendHandler := http.FileServer(http.FS(distFS))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	http.HandleFunc(&amp;quot;&#x2F;&amp;quot;, func(w http.ResponseWriter, r *http.Request) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		frontendHandler.ServeHTTP(w, r)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	})
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	log.Printf(&amp;quot;listening on: localhost:9876&amp;quot;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	log.Fatal(http.ListenAndServe(&amp;quot;:9876&amp;quot;, nil))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the frontend, I was using Vue.js (I don&#x27;t have much experience in frontend), which compiles everything after &lt;code&gt;npm run build&lt;&#x2F;code&gt; into &lt;code&gt;ui&#x2F;dist&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We then embed &lt;code&gt;ui&#x2F;dist&#x2F;&lt;&#x2F;code&gt; directory in go binary. And finally, we use &lt;code&gt;http.FileServer&lt;&#x2F;code&gt;  to serve files from the go server, which defaults to serving &lt;code&gt;ui&#x2F;dist&#x2F;index.html&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted the Vue.js framework to handle &lt;code&gt;&#x2F;custom&lt;&#x2F;code&gt; URL path, to show a different page. I had implemented UI changes, and they were working fine when tested separately. But when accessing them via go server, I was getting &lt;code&gt;404 page not found&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;After little bit of fiddling, I figured out it was because &lt;code&gt;http.FileServer&lt;&#x2F;code&gt; was trying to serve a file called &lt;code&gt;custom&lt;&#x2F;code&gt; and when it couldn&#x27;t find, it returned 404.&lt;&#x2F;p&gt;
&lt;p&gt;The fix was to serve &lt;code&gt;index.html&lt;&#x2F;code&gt; for any path where file doesn&#x27;t exist and let Vue handle the routing:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	  indexHTML, err := fs.ReadFile(distFS, &amp;quot;index.html&amp;quot;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	  if err != nil {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		  log.Fatal(err)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	  }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	  
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &#x2F;&#x2F; serve index.html for any path that does not exists
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &#x2F;&#x2F; and let vue handle the routing
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    _, err = distFS.Open(path)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    if err != nil {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			w.Header().Set(&amp;quot;Content-Type&amp;quot;, &amp;quot;text&#x2F;html; charset=utf-8&amp;quot;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			if _, err := w.Write(indexHTML); err != nil {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;				log.Printf(&amp;quot;failed to write index.html fallback: %v&amp;quot;, err)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;			return
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;go&#x2F;go-http&#x2F;&quot;&gt;go-http&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Performance benchmark</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/hardware/performance-benchmark/"/>
        <id>https://ms-choudhary.github.io/notes/hardware/performance-benchmark/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/hardware/performance-benchmark/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;it-notes.dragas.net&#x2F;2025&#x2F;09&#x2F;19&#x2F;freebsd-vs-smartos-whos-faster-for-jails-zones-bhyve&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;manpages.debian.org&#x2F;testing&#x2F;sysbench&#x2F;sysbench.1.en.html&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;cpu-performance&quot;&gt;CPU performance&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sysbench --test=cpu --cpu-max-prime=20000 run
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;memory-performance&quot;&gt;Memory performance&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sysbench --test=memory run
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Silicon Transistor Gallium</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/hardware/silicon-transistor-gallium/"/>
        <id>https://ms-choudhary.github.io/notes/hardware/silicon-transistor-gallium/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/hardware/silicon-transistor-gallium/">&lt;h3 id=&quot;silicon-semi-conductor&quot;&gt;Silicon, semi-conductor&lt;&#x2F;h3&gt;
&lt;p&gt;Silicon is a semi conductor, something in between a conductor (like metal) or insulator (like rubber). Pure silicon doesn&#x27;t conduct electricity. However, when you can add some impurities, i.e, tiny amounts of other elements, it starts conducting electricity, this is known as &lt;strong&gt;doping&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;N type (N for negative), adds tiny amount of phosphorus. This creates some free electrons.&lt;&#x2F;p&gt;
&lt;p&gt;P type (P for positive), adds tiny amount of boron. This creates extra holes (positive).&lt;&#x2F;p&gt;
&lt;p&gt;If you bring these together, some electrons from N type flow to holes in P type at the junction.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;transistor&quot;&gt;Transistor&lt;&#x2F;h3&gt;
&lt;p&gt;Transistors are switch or amplifiers. A small current from emitter to base, drives a big current from emitter to collector.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;transistor.png&quot; alt=&quot;transistor|300&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;npn-transistor.png&quot; alt=&quot;npn-transistor|400&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-it-works&quot;&gt;How it works&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;When you sandwich NPN silicon together, some electrons from the N type side neutralises holes in P type at the junction, this is known as &lt;strong&gt;depletion region&lt;&#x2F;strong&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Since, N side loses electrons, it becomes positively charged and base becomes negatively charged.&lt;&#x2F;li&gt;
&lt;li&gt;Things stabilises after a bit, and no current flows through. Transistor is said to be in switched off state, even if there is potential difference ( the battery in Emitter to Collector circuit).&lt;&#x2F;li&gt;
&lt;li&gt;When you apply small current or ~0.7 V between emitter and base. Extra electrons enter emitter side, this shrinks the depletion region between emitter and base.&lt;&#x2F;li&gt;
&lt;li&gt;However, because of positively charged collector, most of these electrons move to collector directly, rather than moving out of base (99%). This switches on the transistor.&lt;&#x2F;li&gt;
&lt;li&gt;This is helped by the fact that emitters are heavily doped (more free electrons) and base is very thin.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;silicon-ceiling-gallium&quot;&gt;Silicon ceiling, gallium&lt;&#x2F;h3&gt;
&lt;p&gt;Electrons exists in 2 different states:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Locked in bonds that tie atom together, this is known as valence band&lt;&#x2F;li&gt;
&lt;li&gt;Others are free to move around, known as conduction band&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Band gap is the energy an electron requies in valence band to jump over to conduction band. For silicon, this is 1.1 electron volts (eV).&lt;&#x2F;p&gt;
&lt;p&gt;With technical advancements, we can now place billions of transistor in a small chip in your iphone. This leads to increased heat, and it&#x27;s becomes feasible to jump the bands. After 150° C, silicon stops being a reliable switch.&lt;&#x2F;p&gt;
&lt;p&gt;In general for traditional computing, you work around this constraint, by adding cooling fans etc.&lt;&#x2F;p&gt;
&lt;p&gt;But there&#x27;re are cases like 5G base stations, which has to constantly transmit at 3 GHz frequencies, sometimes to 30 GHz for millimeter wave 5G. Silicon based chips struggle beyond 5 GHz, so the quality of stations degrade.&lt;&#x2F;p&gt;
&lt;p&gt;Enter gallium, gallium by itself, is not a semi conductor. But, Gallium Arsenide &amp;amp; Gallium Nitride has some interesting electronic properties. Gallium Arsenide (GaAs) has bandgap of 3.4 eV. It can operate till a temperature of 400° C. Also it switches faster than silicon based chip. This leads to less energy waste as heat, and needs less cooling.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Trusted Platform Module (TPM)</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/hardware/trusted-platform-module/"/>
        <id>https://ms-choudhary.github.io/notes/hardware/trusted-platform-module/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/hardware/trusted-platform-module/">&lt;p&gt;TPM is a secure crypto processor on the motherboard. Used for&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;verifying that the boot process starts from trusted combination of hardware and software&lt;&#x2F;li&gt;
&lt;li&gt;storing disk encryption keys&lt;&#x2F;li&gt;
&lt;li&gt;provides hardware random number generator &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;booting-linux-on-x86-64&#x2F;#kaslr-kernel-address-space-layout-randomisation&quot;&gt;KASLR (Kernel Address Space Layout Randomisation)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;secure generation of cryptographic keys&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It creates a unforgeable hash key summary of hardware &amp;amp; software configuration. Sealed storage protects the private info by binding it to the platform with this hash key. This is used for DRM enforcement. &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;security&#x2F;drm&#x2F;&quot;&gt;drm&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;UEFI can use TPM to form root of trust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;booting-linux-on-x86-64&#x2F;&quot;&gt;booting-linux-on-x86-64&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Common Commands</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/kubectl/common-commands/"/>
        <id>https://ms-choudhary.github.io/notes/kubectl/common-commands/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/kubectl/common-commands/">&lt;h3 id=&quot;whoami&quot;&gt;whoami&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;kubectl auth whoami
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Booting Linux on x86_64</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/linux/booting-linux-on-x86-64/"/>
        <id>https://ms-choudhary.github.io/notes/linux/booting-linux-on-x86-64/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/linux/booting-linux-on-x86-64/">&lt;p&gt;When you power on a PC, a intricate handshake happens between several programs and literal CPU before you see the familiar screen.&lt;&#x2F;p&gt;
&lt;p&gt;When power stabilises, CPU does a reset into a 16 bit real mode. Real mode is for backward compatibility to mimic older 8086 chip. All x86 processors (intel, amd etc) do this.&lt;&#x2F;p&gt;
&lt;p&gt;CPU then jumps to reset vector at location: 0xFFFFFFF0 (special hardcode address). This is hardwired so every time a CPU resets, it always start here, like a permanent bookmark. This contains far jump to firmware on motherboard.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bios-uefi&quot;&gt;BIOS&#x2F;UEFI&lt;&#x2F;h3&gt;
&lt;p&gt;Firmware is software baked into the board. Stored on read only chip on motherboard.&lt;&#x2F;p&gt;
&lt;p&gt;BIOS (Basic Input Output System) is the firmware, manufacture developed primitive software, which does:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;health check via POST (Power On Self Test), makes sure all critical hardware is working before booting into OS&lt;&#x2F;li&gt;
&lt;li&gt;If there are any problems at this stage, machine beeps&lt;&#x2F;li&gt;
&lt;li&gt;Looks at the boot order, and tries to load 1st stage boot.
&lt;ul&gt;
&lt;li&gt;Any disk whose first sector (512 bytes), ends with 0x55 0xAA (magic bytes) is considered bootable (MBR).&lt;&#x2F;li&gt;
&lt;li&gt;GUID Partition table (GPT for UEFI)&lt;&#x2F;li&gt;
&lt;li&gt;Net booting (for PXE)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Copies that sector to memory at 0x7C00 address and jumps there.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;1 sector (512 bytes) boot loader is tiny, and it only knows how to load 2nd stage boot loader.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;uefi&quot;&gt;UEFI&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;booting-linux-on-x86-64&#x2F;inbox&#x2F;in-progress&#x2F;uefi.md&quot;&gt;uefi&lt;&#x2F;a&gt; is a modern firmware, overcomes the limitation of multi stage boot loading. It understand filesystems (FAT32) and can directly load bigger programs (can technically boot kernel without boot loader) without the limitation of 512 bytes. It can pass richer info to OS.&lt;&#x2F;p&gt;
&lt;p&gt;UEFI also handles the steps of setup program below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Setup GDT, IDT, switch to protected mode&lt;&#x2F;li&gt;
&lt;li&gt;Setup paging&lt;&#x2F;li&gt;
&lt;li&gt;Switching to long mode&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;sme&quot;&gt;SME&lt;&#x2F;h3&gt;
&lt;p&gt;Some AMD CPUs has encrypt RAM feature called Secure Memory Encryption.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;segment-offset&quot;&gt;Segment &amp;amp; Offset&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;physical address = (segment &amp;lt;&amp;lt; 4) + offset
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;grub&quot;&gt;Grub&lt;&#x2F;h3&gt;
&lt;p&gt;Grub boot loader understands filesystems, it loads the kernel into memory. Kernel file consists of:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Small setup program, which runs in real mode (only in x86_64, non UEFI, for switching cpu from real -&amp;gt; protected -&amp;gt; long mode)&lt;&#x2F;li&gt;
&lt;li&gt;Larger compressed kernel&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Grub fills up setup headers like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Where kernel is placed&lt;&#x2F;li&gt;
&lt;li&gt;Where command line lives&lt;&#x2F;li&gt;
&lt;li&gt;Where is init rd etc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Finally it jumps to the setup program.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interrupts&quot;&gt;Interrupts&lt;&#x2F;h3&gt;
&lt;p&gt;Interrupts can be hardware or software for handling real time events. On interrupt, CPU pauses the work and runs then handler in Interrupt Descriptor Table (IDT). Examples include, when key is pressed etc. It can be maskable, meaning temporary blocked to prevent firing during delicate moments. And Non Maskable (NMI) which always interrupt, it can indicate serious hardware issues. If you don&#x27;t have handler entry in IDT, handler lookup fails, CPU gives up (triple fault) and resets silently.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;cpu-control-registers&quot;&gt;CPU control registers&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;CR0
&lt;ul&gt;
&lt;li&gt;Turns on the protected mode&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;CR3
&lt;ul&gt;
&lt;li&gt;Holds the address of top of page table&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;CR4
&lt;ul&gt;
&lt;li&gt;Enables extended features, for larger page table.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;EFER
&lt;ul&gt;
&lt;li&gt;Switch to long mode&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;setup-program&quot;&gt;Setup Program&lt;&#x2F;h3&gt;
&lt;p&gt;Setup program, first creates a predictable workspace:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lines up segment registers, so memory copy behave the same way every time. It also sets &quot;direction flag&quot; CPU bit, so copy instructions auto moves the pointer forward through memory.&lt;&#x2F;li&gt;
&lt;li&gt;Creates stack, LIFO workbench, where functions store data temporarily. SS says which segment the stack uses and SP points to the top of the stack.&lt;&#x2F;li&gt;
&lt;li&gt;Clears BSS (where global variables reside), C code ensures that global variable will be initialised to zero. So it sets that area to 0.&lt;&#x2F;li&gt;
&lt;li&gt;Programs serial port to print early message, before graphics is setup&lt;&#x2F;li&gt;
&lt;li&gt;Asks firmware for usable and reserved RAM ranges (there can be holes). On old BIOS this call is nick named e820.&lt;&#x2F;li&gt;
&lt;li&gt;Finally it calls the first c function literally called main.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;protected-mode&quot;&gt;Protected mode&lt;&#x2F;h4&gt;
&lt;p&gt;Modern linux runs in long mode: 64 bit in x86_64. But you can&#x27;t go directly to that, you first transition from 32 bit real mode to 32 bit protected mode, finally to long mode.&lt;&#x2F;p&gt;
&lt;p&gt;Protected mode consists of following ideas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Global Descriptor Table (GDT): list of segments with descriptions, for eg a segment starts here, covers this much and allowed to do these.&lt;&#x2F;li&gt;
&lt;li&gt;Interrupt Descriptor Table (IDT), aka phone numbers for emergency, when a interrupt arrives, CPU looks up entry in IDT for handler to call.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Here&#x27;s how setup program switches CPU into protected mode:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Disables maskable interrupts, other than what&#x27;s needed&lt;&#x2F;li&gt;
&lt;li&gt;Loads the tiny GDT &amp;amp; IDT&lt;&#x2F;li&gt;
&lt;li&gt;Sets single bit PE in control register, CR0.&lt;&#x2F;li&gt;
&lt;li&gt;Does a far jump. That jump reloads code segment from GDT, and locks it into protected mode. It reloads the data &amp;amp; stack segments.
We&#x27;re now in protected mode.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;paging&quot;&gt;Paging&lt;&#x2F;h3&gt;
&lt;p&gt;Finally we need to enable paging before we can switch to long mode.&lt;&#x2F;p&gt;
&lt;p&gt;Programs use virtual address, while hardware reads and writes physical address. A page table translates virtual address into physical address, in fixed size chunks call pages. A typical page size is 4KB, earlier boot uses larger 2MB pages to layout low memory quickly.&lt;&#x2F;p&gt;
&lt;p&gt;Initially, we build a small page table in 32 bit mode, called identity map, which means for this specific region, virtual address equals physical one. So we can flip on paging.&lt;&#x2F;p&gt;
&lt;p&gt;Next it enables PAE bit in CR4 register so larger entries are used and builds a minimal table for lower memory. Writes the address of the top table in CR3. Paging is now ready.&lt;&#x2F;p&gt;
&lt;p&gt;Finally we set LME bit in special register EFER, this switches the CPU in long mode.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;elf&quot;&gt;ELF&lt;&#x2F;h3&gt;
&lt;p&gt;ELF short for Executable &amp;amp; Linkable Format, is both a file format and a map, which says what chunks are code, data etc and exactly where each chunk wants to live.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;decompressing-kernel&quot;&gt;Decompressing kernel&lt;&#x2F;h3&gt;
&lt;p&gt;We now have CPU running in 64 bit long mode with paging enabled, and compressed kernel in memory.&lt;&#x2F;p&gt;
&lt;p&gt;Now, 64 bit small stub code takes over. First it figures out where it&#x27;s running. Early code is linked as if it starts at address 0, it computes it real base at runtime. It relocates itself if it can overlap with uncompressed kernel (with KASLR).&lt;&#x2F;p&gt;
&lt;p&gt;It loads a minimal IDT:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Page fault handler: Page fault happens when CPU can&#x27;t find the mapping for virtual address, in identity mapped world, handler adds the mapping on the fly.&lt;&#x2F;li&gt;
&lt;li&gt;NMI handler, so it doesn&#x27;t crash the machine, while we&#x27;re bringing things up.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;C func &lt;code&gt;extract_kernel&lt;&#x2F;code&gt; takes over and unpacks the kernel using algorithm it was built with (gzip, xz, zstd, lzo etc).&lt;&#x2F;p&gt;
&lt;p&gt;Kernel itself like other binaries are packaged as ELF file. When bytes are out, decompressor reads the kernel&#x27;s ELF headers. It copies the chunks to memory where it belongs.&lt;&#x2F;p&gt;
&lt;p&gt;Next it jumps to real kernel &lt;code&gt;start_kernel&lt;&#x2F;code&gt;, and big initialisations begins.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;kaslr-kernel-address-space-layout-randomisation&quot;&gt;KASLR (Kernel Address Space Layout Randomisation)&lt;&#x2F;h4&gt;
&lt;p&gt;If attacker don&#x27;t know where the kernel actually lives in memory, a lot of attacks get harder.&lt;&#x2F;p&gt;
&lt;p&gt;If KASLR is enabled, decompressor choses 2 bases at random:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Physical base&lt;&#x2F;li&gt;
&lt;li&gt;Virtual base&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It first builds a do not touch list, which includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;decompressor itself&lt;&#x2F;li&gt;
&lt;li&gt;compressed kernel image&lt;&#x2F;li&gt;
&lt;li&gt;initial ram disk&lt;&#x2F;li&gt;
&lt;li&gt;boot params&lt;&#x2F;li&gt;
&lt;li&gt;command line buffers&lt;&#x2F;li&gt;
&lt;li&gt;also includes ranges reserved using &lt;code&gt;memmap=&lt;&#x2F;code&gt; option on command line&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Scans memory map received earlier from the firmware and finds the ranges where everything can fit. It draws random number using the best early entropy source. On modern CPUs, it&#x27;s &lt;code&gt;rand&lt;&#x2F;code&gt; instruction on hardware. &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;hardware&#x2F;trusted-platform-module&#x2F;&quot;&gt;trusted-platform-module&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;start-kernel&quot;&gt;Start Kernel&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;verify_cpu&lt;&#x2F;code&gt;, checks long mode support, verifies sse2, validates other cpu features. It fails here, to prevent running 64 bit kernel on 32 bit hardware.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;booting-linux-on-x86-64&#x2F;#microcode-patching&quot;&gt;Microcode patching&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;resets the early identity mapped page tables&lt;&#x2F;li&gt;
&lt;li&gt;clears bss, zeros out &lt;code&gt;.bss&lt;&#x2F;code&gt; section&lt;&#x2F;li&gt;
&lt;li&gt;setups KASAN (Kernel Address Sanitizer)&lt;&#x2F;li&gt;
&lt;li&gt;Copies bootloader data into kernel owned structs, to prevent overwriting.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;setup_arch()&lt;&#x2F;code&gt;
&lt;ul&gt;
&lt;li&gt;what can cpu do? Asks the chip directly using CPUID instructions. Dumps the data into boot_cpu_data struct for later lookups, for eg, do we&#x27;ve feature x? Helps in deciding if to use AVX512 memcpy instruction or fall back to slower one.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Cleans up the E820 memory map obtained from firmware. Feeds it into memblock, starts tracking free and reserved ranges, i.e., early memory allocator, before kmalloc or vmalloc.&lt;&#x2F;li&gt;
&lt;li&gt;If &lt;code&gt;earlyprintk=serial,ttyS0&lt;&#x2F;code&gt; command line flag passed, it sets up minimal serial driver.&lt;&#x2F;li&gt;
&lt;li&gt;Collects info about the machine
&lt;ul&gt;
&lt;li&gt;efi_init() hooks up UEFI runtime services&lt;&#x2F;li&gt;
&lt;li&gt;dmi_setup() firmware tables, describes motherboard, vendor, bios version etc&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;init_hypervisor_platform()&lt;&#x2F;code&gt; - checks if we&#x27;re on real hardware or VM. If so, which hypervisor: kvm, xen etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;multi-processors-boot&quot;&gt;Multi processors boot&lt;&#x2F;h3&gt;
&lt;p&gt;In case of multiple processor cores, one of the processor is designated as Bootstrap Processor (BSP). It runs the firmware, reset vector, starts kernel. All other cores AP (Application Processor) start later.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;microcode-patching&quot;&gt;Microcode patching&lt;&#x2F;h3&gt;
&lt;p&gt;x86 instructions are interface contract. Internally they get translated into microcode by the decoder, from read only array on CPU die. Microcode internals are proprietary stuff.&lt;&#x2F;p&gt;
&lt;p&gt;Microcodes can be patched, for eg, in case of vulnerabilities like spectre, meltdown etc. You load the patch onto the RAM array first (ROM array are out of touch). When decoder decodes, it&#x27;ll check the RAM array, and if entry is found, it&#x27;ll use that.&lt;&#x2F;p&gt;
&lt;p&gt;Patches can be done at two places:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Firmware update automatically takes care of this.&lt;&#x2F;li&gt;
&lt;li&gt;OS patch at early boot, primary channel for end users without updating the firmware.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each physical core has to be patched separately. The patch is prepended to initramfs file.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;initramfs = [uncompressed cpio microcode blob] + [compressed cpio rootfs]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It has to be loaded early in the boot (to prevent attacks), at the time when there&#x27;s no filesystem available. It uses a neat trick of reading the patch prepended to initramfs, available from the boot loader at &lt;code&gt;boot_params.hdr.ramdisk_img&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It can also be loaded later by:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo 1 &amp;gt; &#x2F;sys&#x2F;devices&#x2F;system&#x2F;cpu&#x2F;microcode&#x2F;reload
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;but it&#x27;s risky.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.0xkato.xyz&#x2F;linux-boot&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;docs.kernel.org&#x2F;arch&#x2F;x86&#x2F;microcode.html&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;internals-for-interns.com&#x2F;posts&#x2F;linux-kernel-startup&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;wake-on-lan&#x2F;&quot;&gt;wake-on-lan&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;grub&#x2F;&quot;&gt;grub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;initrd&#x2F;&quot;&gt;initrd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;anaconda&#x2F;&quot;&gt;anaconda&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Dynamic kernel modules</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/linux/dynamic-kernel-modules/"/>
        <id>https://ms-choudhary.github.io/notes/linux/dynamic-kernel-modules/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/linux/dynamic-kernel-modules/">&lt;h3 id=&quot;dynamic-kernel-module-support-dkms&quot;&gt;Dynamic Kernel Module Support (DKMS)&lt;&#x2F;h3&gt;
&lt;p&gt;DKMS allows building kernel modules whose source reside outside the kernel source tree.&lt;&#x2F;p&gt;
&lt;p&gt;It auto recompiles all DKMS modules if a new kernel version is installed.&lt;&#x2F;p&gt;
&lt;p&gt;This allows drives to continue working after kernel upgrade. Also allows installation of new drivers on existing system without any need for manual compilation.&lt;&#x2F;p&gt;
&lt;p&gt;Supports rpm &amp;amp; deb packages out of the box.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;akmods-fedora&quot;&gt;Akmods (fedora)&lt;&#x2F;h3&gt;
&lt;p&gt;kmod package contains precompiled modules for a kernel version. It doesn&#x27;t work if the kernel version is different.&lt;&#x2F;p&gt;
&lt;p&gt;Akmods allows rebuilding the modules for a different kernel.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;akmodsd&lt;&#x2F;code&gt; daemon starts at the init, and checks if all kmods are present and compatible. It auto rebuilds missing&#x2F;incompatible kmods, and installs into the running kernel.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;rpmfusion.org&#x2F;Packaging&#x2F;KernelModules&#x2F;Akmods&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dynamic_Kernel_Module_Support&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;package-management&#x2F;&quot;&gt;package-management&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Package Management</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/linux/package-management/"/>
        <id>https://ms-choudhary.github.io/notes/linux/package-management/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/linux/package-management/">&lt;h3 id=&quot;debian-dpkg&quot;&gt;Debian dpkg&lt;&#x2F;h3&gt;
&lt;p&gt;Debian &lt;code&gt;.deb&lt;&#x2F;code&gt; package is an &lt;code&gt;ar&lt;&#x2F;code&gt; archive consisting of 2-3 nested tar archives, along with maintainer scripts (eg, &lt;code&gt;preinst&lt;&#x2F;code&gt;, &lt;code&gt;postinst&lt;&#x2F;code&gt;, &lt;code&gt;prerm&lt;&#x2F;code&gt;, &lt;code&gt;postrm&lt;&#x2F;code&gt;) which runs arbitrary shell scripts.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# list inventory of packages and their version installed
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ dpkg -l
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# List file contents of a package
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ dpkg -L tcpdump
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# Reverse lookup, which package provides this file
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ dpkg-query -S &#x2F;usr&#x2F;bin&#x2F;dig
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Packaging systems can keep track of dependencies only if all softwares are installed via package management. If for eg, awscli was installed outside package management, dpkg won&#x27;t know if upgrading python will break awscli.&lt;&#x2F;p&gt;
&lt;p&gt;gpg keys are used to check the signature to validate if package was signed by trusted entity.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fedora-rpm&quot;&gt;Fedora rpm&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# list inventory
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ rpm -qa
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# list content 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ rpm -ql tcpdump
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# verify integrity of a package; if it was modified
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ sudo rpm -V sudo
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ sudo rpm -Va  # all packages
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;netbsd-vulnerability-for-packages&quot;&gt;Netbsd vulnerability for packages&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ pkg_admin -V -v fetch-pkg-vulnerabilities
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ pkg_admin audit
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;alpine-apk&quot;&gt;Alpine apk&lt;&#x2F;h3&gt;
&lt;p&gt;APK is both a package manager for alpine and format of package on the disk. It&#x27;s simple gzipped tarball consisting of control segment, data segment &amp;amp; signature.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# Plain text file with list of packages installed
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ cat &#x2F;etc&#x2F;apk&#x2F;world
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# Repository file
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ cat &#x2F;etc&#x2F;apk&#x2F;repositories
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# DB of installed packages
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ cat &#x2F;lib&#x2F;apk&#x2F;db&#x2F;installed
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# list installed packages
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ apk list --installed
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# Full info about a package
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ apk info -a busybox
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# Files owned by package
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ apk info -L busybox
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# Dependencies of a package
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ apk info -R busybox
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# Which package owns a file
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ apk info --who-owns &#x2F;bin&#x2F;ls
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;dynamic-kernel-modules&#x2F;&quot;&gt;dynamic-kernel-modules&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Terminal</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/linux/terminal/"/>
        <id>https://ms-choudhary.github.io/notes/linux/terminal/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/linux/terminal/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Terminal is a pair master and slave devices. Slave devices are like dumb clients without any intelligence just relaying what user types to the server and showing back the response.&lt;&#x2F;p&gt;
&lt;p&gt;Now when you type text on the terminal, it&#x27;s relayed back to master device, which gives the information to program running. There&#x27;re escape sequences to display text in bold or color, cursor movement etc. When you type &lt;code&gt;Ctrl-C&lt;&#x2F;code&gt; or &lt;code&gt;Ctrl-Z&lt;&#x2F;code&gt; it sends a ascii signal &lt;code&gt;\x03&lt;&#x2F;code&gt; and &lt;code&gt;26&lt;&#x2F;code&gt;. This is intercepted by kernel (and not userspace program like shell), and it sends &lt;code&gt;SIGINT&lt;&#x2F;code&gt; signal to process group in the terminal.&lt;&#x2F;p&gt;
&lt;p&gt;When the master device starts, it makes this sys call:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;syscall.Syscall(
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    syscall.SYS_IOCTL,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    tty.Fd(),
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    syscall.TIOCSWINSZ,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    uintptr(unsafe.Pointer(&amp;amp;resizeMessage)),
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;this calls the ioctl system call. To check terminal parameters, you can type:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;stty -a
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;or
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tputs cols # for columns 
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;when you change the window size of the terminal, kernel sends a signal &lt;code&gt;SIGWINCH&lt;&#x2F;code&gt; which resets the stty cols etc. The side effect of this not being correctly set will result in overwriting of text of same line and not changing to next line on inputting long text in the terminal.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;shell&#x2F;shell-commands&#x2F;&quot;&gt;shell-commands&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Macos</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/macos/macos/"/>
        <id>https://ms-choudhary.github.io/notes/macos/macos/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/macos/macos/">&lt;h3 id=&quot;keyboard&quot;&gt;Keyboard&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Settings -&amp;gt; Keyboard -&amp;gt; Key repeat rate&lt;&#x2F;code&gt; controls at what speed when pressing a key the input is sent, if you make it high, cursor will move faster when you press let&#x27;s say down key etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;safe-mode-boot&quot;&gt;Safe mode boot&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;To boot in safe mode, shutdown the mac&lt;&#x2F;li&gt;
&lt;li&gt;Keep pressing the power button till, it loads startup option&lt;&#x2F;li&gt;
&lt;li&gt;Select the drive and continue&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;clear-dns-cache&quot;&gt;Clear DNS cache&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;directories&quot;&gt;Directories&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~&#x2F;Library&#x2F;Caches&lt;&#x2F;code&gt; all system wide caches for applications&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;~&#x2F;Library&#x2F;Preferences&lt;&#x2F;code&gt; plist files used for storing configuration, preferences etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;type-degree-deg-symbol&quot;&gt;Type degree (°) symbol&lt;&#x2F;h3&gt;
&lt;p&gt;Option + Shift + 8 =&amp;gt; °&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rebuild-spotlight-index&quot;&gt;Rebuild spotlight index&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;For a specific dir, for eg Applications:
&lt;ul&gt;
&lt;li&gt;Setting -&amp;gt; Spotlight -&amp;gt; Search Privacy
&lt;ul&gt;
&lt;li&gt;Add and remove the directory&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;For all dirs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	sudo mdutil -Eai off
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	sudo mdutil -Eai on
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Bonds</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/bonds/"/>
        <id>https://ms-choudhary.github.io/notes/money/bonds/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/bonds/">&lt;p&gt;Bonds are debt instruments in which you borrow money from market by promising fixed interest annually, along with repayment of principle later.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>E-Mandate on cards</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/emandate-on-cards/"/>
        <id>https://ms-choudhary.github.io/notes/money/emandate-on-cards/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/emandate-on-cards/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;www.sc.com&#x2F;in&#x2F;bank-with-us&#x2F;recurring-e-mandates&#x2F;faqs&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;E-mandate is signed by users when opting for a recurring payment via card to a online website&#x2F;app.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;re RBI guidelines that banks and merchant has to follow.&lt;&#x2F;p&gt;
&lt;p&gt;Additional Factor Authentication, generally OTP, is required:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;on e-mandate registration&lt;&#x2F;li&gt;
&lt;li&gt;if amount is greater than 15000 rs, (no OTP on amount less than 15k)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If user doesn&#x27;t authorise this, for eg, if foreign site doesn&#x27;t implement it, bank fails the transaction.&lt;&#x2F;p&gt;
&lt;p&gt;On bank side:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;bank has to give notification to users before deduction&lt;&#x2F;li&gt;
&lt;li&gt;have a way to opt out of it&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It is generally handled by payment gateways.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;How does this differ from e-mandate for SIPs NACH? #question&lt;&#x2F;li&gt;
&lt;li&gt;How does this apply to UPI&#x27;s autopay? #question&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;tcs&#x2F;&quot;&gt;tcs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Employee Provident Fund (EPF)</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/epf/"/>
        <id>https://ms-choudhary.github.io/notes/money/epf/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/epf/">&lt;p&gt;EPF (Employee Provident Fund) is a &lt;strong&gt;mandatory&lt;&#x2F;strong&gt; government scheme for all private and government sector employees. It has two components,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;employee contribution, 12% of his Basic + Dearance Allowance (DA) salary&lt;&#x2F;li&gt;
&lt;li&gt;employer contribution, same 12% but divided into:
&lt;ul&gt;
&lt;li&gt;EPS: 8.33% of 15000 = 1250&lt;&#x2F;li&gt;
&lt;li&gt;EPF: remaining amount&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;EPS is available as a pension after age of 58 years. It requires at least 10 years of service.
EPF on the other hand can be withdrawn completely in one of these scenarios:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;No job
&lt;ul&gt;
&lt;li&gt;After 2 months: 75% of the corpus can be withdrawn&lt;&#x2F;li&gt;
&lt;li&gt;After 12 months: remaining 25%&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;It&#x27;ll be linked with UPI, can be withdrawn like a normal bank account (what caps? #question)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There&#x27;s an additional component in EPF, EDLI, this is a term insurance for employee, paid for by employer. In case of death, at maximum of 7.5L can be availed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interest&quot;&gt;Interest&lt;&#x2F;h3&gt;
&lt;p&gt;Rate of interest hovers around 8%.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;uan-pf-transfer&quot;&gt;UAN, PF transfer&lt;&#x2F;h3&gt;
&lt;p&gt;Each user has unique UAN number linked to PAN. On changing organisation, UAN remains same, but you get new PF number. And you&#x27;ve to transfer your amount from old to new PF account. Ensure your &lt;em&gt;Date of Exit&lt;&#x2F;em&gt; (DOE) is marked by previous employer. And that it doesn&#x27;t overlap with &lt;em&gt;Date of Joining&lt;&#x2F;em&gt; (DOJ) at the new organisation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;youtu.be&#x2F;y0OhXSjcbkI?si=_C8tQRymXuskPaME&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;income-tax&#x2F;#pf-tax&quot;&gt;PF Tax&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;nps&#x2F;&quot;&gt;nps&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Income tax</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/income-tax/"/>
        <id>https://ms-choudhary.github.io/notes/money/income-tax/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/income-tax/">&lt;p&gt;In new regime, you taxed 30% on salary &amp;gt; 24L, whereas in old it&#x27;s salary &amp;gt; 10L. Apart from the usual tax slabs, surcharge is also applicable if salary is greater than 50L.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;possible-deductions&quot;&gt;Possible deductions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;[only in old] Car: transport, maintainence, driver bills&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] Professional Tax&lt;&#x2F;li&gt;
&lt;li&gt;[both] Standard deduction: 50k in old, 75k in new (available by default, requires no documentation)&lt;&#x2F;li&gt;
&lt;li&gt;[in both] food&#x2F;meal 200&#x2F;meal&lt;&#x2F;li&gt;
&lt;li&gt;[in both] gift 15k&lt;&#x2F;li&gt;
&lt;li&gt;[in both] telephone bills&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] LTA
&lt;ul&gt;
&lt;li&gt;can be claimed for 2 journeys in 4 years gap&lt;&#x2F;li&gt;
&lt;li&gt;covers self + family&lt;&#x2F;li&gt;
&lt;li&gt;air, rail, bus for travel in india&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] HRA
&lt;ul&gt;
&lt;li&gt;check changes recently&lt;&#x2F;li&gt;
&lt;li&gt;requires relationship with landlord, aadhar, pan etc&lt;&#x2F;li&gt;
&lt;li&gt;2% TDS included in rent&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;[both] relocation charges&lt;&#x2F;li&gt;
&lt;li&gt;[both] conveyance allowance (commuting to work etc)&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] helper&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] child education upto 3k per month per child&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] life insurance upto 1.5k under 80c&lt;&#x2F;li&gt;
&lt;li&gt;[both] NPS: upto 10% in old (additional 50k&#x2F;yr), upto 14% in new&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] Health insurance&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] education loan - no limit&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] home loan for self - 2L limit&lt;&#x2F;li&gt;
&lt;li&gt;[only in old] home loan for let out - no limit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;pf-tax&quot;&gt;PF Tax&lt;&#x2F;h3&gt;
&lt;p&gt;If employer contribution &amp;gt; 7.5L annually, it&#x27;ll be taxable.
If interest amount &amp;gt; 2.5L tax is applicable.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;taxation-in-esops-and-rsus&quot;&gt;Taxation in ESOPs and RSUs&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;RSUs are actual free shares available after vesting. No cost for holding. On selling it&#x27;s taxed as per income slab.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;ESOPs gives an options for employee to buy share at fixed discounted price, requires paying exercise amount. It is taxed twice, once when it&#x27;s exercised, based on difference between FMV (Fair Market Value) and exercise price. And then again on selling based on capital gains tax.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;foriegn-assets-disclosure&quot;&gt;Foriegn assets disclosure&lt;&#x2F;h3&gt;
&lt;p&gt;According to new IT rules, you&#x27;re required to share all foriegn assets, i.e, RSUs &amp;amp; ESOPs for public shares, including overseas mutual&#x2F;index fund. This doesn&#x27;t apply pre IPO, if there&#x27;s no valuation. If foriegn assets are greater than 20L and not declared, it attracts a penalty of 10L.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;business&quot;&gt;Business&lt;&#x2F;h3&gt;
&lt;p&gt;If you&#x27;ve business income, you can&#x27;t switch tax regime once selected. Really? #question&lt;&#x2F;p&gt;
&lt;h3 id=&quot;form-26as&quot;&gt;Form 26AS&lt;&#x2F;h3&gt;
&lt;p&gt;It&#x27;s a consolidated tax statement for all taxes which are deducted, like TDS, TCS for a PAN.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;tcs&#x2F;&quot;&gt;tcs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;epf&#x2F;&quot;&gt;epf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;nps&#x2F;&quot;&gt;nps&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;mutual-fund-taxation&#x2F;&quot;&gt;mutual-fund-taxation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;itr&#x2F;&quot;&gt;itr&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Loan Against Securities</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/loan-against-securities/"/>
        <id>https://ms-choudhary.github.io/notes/money/loan-against-securities/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/loan-against-securities/">&lt;p&gt;You can take loan against stocks&#x2F;mutual funds via Zerodha Capital, at rate of interest 11% (for loan amounts 25K to 50L).&lt;&#x2F;p&gt;
&lt;p&gt;This covers most mutual funds as &lt;a href=&quot;https:&#x2F;&#x2F;zerodhacapital.com&#x2F;approved-list&quot;&gt;listed here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Haircut of 55% is applicable for equity based funds. For eg, if you assets are valued at 50 L, you can take a loan of only 22.5L on the remaining 45% after removing haircut.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Liberalised Remittance Scheme (LRS)</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/lrs/"/>
        <id>https://ms-choudhary.github.io/notes/money/lrs/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/lrs/">&lt;p&gt;By virtue of LRS scheme by RBI, a citizen of india can remit (send money) $2,50,000 (2.3 Crore) to a foreign entity per financial year.&lt;&#x2F;p&gt;
&lt;p&gt;The purpose of this remittance can be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Investment, stocks or us treasury bonds&lt;&#x2F;li&gt;
&lt;li&gt;Real estate investment&lt;&#x2F;li&gt;
&lt;li&gt;Traveling abroad expenditure (business as well as leisure)&lt;&#x2F;li&gt;
&lt;li&gt;Traveling for education&lt;&#x2F;li&gt;
&lt;li&gt;Sending money to family overseas&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Cost of transaction: money exchange cost (as facilitated by bank) + 18% GST on the exchange cost.&lt;&#x2F;p&gt;
&lt;p&gt;TCS is applicable on this over limit of 10L.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;for-investments&quot;&gt;For investments&lt;&#x2F;h3&gt;
&lt;p&gt;Under International Financial Services Centres Authority (IFSCA), Global Access Provider (GAP) in GIFT city act as India&#x27;s global investing gateway.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.indmoney.com&#x2F;blog&#x2F;us-stocks&#x2F;liberalised-remittance-scheme&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;tcs&#x2F;&quot;&gt;tcs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;income-tax&#x2F;&quot;&gt;income-tax&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mutual Fund Taxation</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/mutual-fund-taxation/"/>
        <id>https://ms-choudhary.github.io/notes/money/mutual-fund-taxation/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/mutual-fund-taxation/">&lt;h2 id=&quot;equity&quot;&gt;Equity&lt;&#x2F;h2&gt;
&lt;p&gt;Must have minimum 65% equity investment for it to be applicable for equity taxation.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt; 1 yr&lt;&#x2F;code&gt; - STCG - 20%&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;&amp;gt; 1 yr&lt;&#x2F;code&gt; - LTCG - 12.5% - upto 1.25 Lakh exempt per annum&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;non-equity&quot;&gt;Non Equity&lt;&#x2F;h2&gt;
&lt;p&gt;Debt, Gold ETF etc, are taxed on income slab rates.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fifo-withdrawal&quot;&gt;FIFO Withdrawal&lt;&#x2F;h2&gt;
&lt;p&gt;In case of SIPs, oldest lots are redeemed first incase of withdrawal. Each lot is calculated separately for taxes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;income-tax&#x2F;&quot;&gt;income-tax&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>National Pension Scheme (NPS)</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/nps/"/>
        <id>https://ms-choudhary.github.io/notes/money/nps/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/nps/">&lt;p&gt;NPS is available in&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Tier I
&lt;ul&gt;
&lt;li&gt;Tax free 14% of Basic + DA salary, limited to 7.5L annually&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Tier II
&lt;ul&gt;
&lt;li&gt;This is just a cheap mutual fund (ie lower expense ratio)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;features&quot;&gt;Features&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;You can opt for auto scheme which changes allocation based on age, i.e, shifts assets from equity to debt etc.&lt;&#x2F;li&gt;
&lt;li&gt;It has the lowest expense ratio in the industry&lt;&#x2F;li&gt;
&lt;li&gt;Allows you to change Fund Manager, once a year, without any tax&lt;&#x2F;li&gt;
&lt;li&gt;Allows you to change your asset allocation, once every quarter&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;multi-scheme&quot;&gt;Multi scheme&lt;&#x2F;h3&gt;
&lt;p&gt;With multi scheme you can decide explicitly the funds you want to allocate. Also you can go 100% equity with this.  The only drawback is once a amount is invested in a fund, you have to stay invested for entire duration (15 years). You can change allocation for next month. But old amount cannot be rebalanced. Although, you can shift the entire amount back to auto schemes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;withdrawal&quot;&gt;Withdrawal&lt;&#x2F;h3&gt;
&lt;p&gt;With recent changes, you can withdraw from the scheme after 15 years or at age 60, which ever is earlier.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;80% of the amount is available as Lump Sum&lt;&#x2F;li&gt;
&lt;li&gt;For the remaining 20% you&#x27;ve to purchase annuity&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There&#x27;s also a scope of withdrawing via SWP instead of entire amount at once.&lt;&#x2F;p&gt;
&lt;p&gt;You can take loan against your NPS corpus.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;youtu.be&#x2F;y0OhXSjcbkI?si=_C8tQRymXuskPaME&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;income-tax&#x2F;&quot;&gt;income-tax&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;epf&#x2F;&quot;&gt;epf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tax Collected at Source (TCS)</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/money/tcs/"/>
        <id>https://ms-choudhary.github.io/notes/money/tcs/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/money/tcs/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Tax collected at source (TCS) is applicable on transactions with foreign merchants. It is collected by bank facilitating such transaction, and it&#x27;s linked back to user by PAN.&lt;&#x2F;p&gt;
&lt;p&gt;You can verify how much TCS was deducted in Form 26AS, which is comprehensive tax statement. It can be claimed back while filing the Income Tax Return (ITR).&lt;&#x2F;p&gt;
&lt;p&gt;TCS is exempted till limit of 10 Lakh rs annually, rotated every financial year (apr) . After that, it&#x27;s collected as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;5% on medical or education bills&lt;&#x2F;li&gt;
&lt;li&gt;20% on other transactions&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;emandate-on-cards&#x2F;&quot;&gt;emandate-on-cards&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;income-tax&#x2F;#form-26as&quot;&gt;Form 26AS&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;income-tax&#x2F;#foriegn-assets-disclosure&quot;&gt;Foriegn assets disclosure&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;money&#x2F;lrs&#x2F;&quot;&gt;lrs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Grafana Alloy</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/monitoring/grafana-alloy/"/>
        <id>https://ms-choudhary.github.io/notes/monitoring/grafana-alloy/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/monitoring/grafana-alloy/">&lt;h3 id=&quot;http-static-endpoint-discovery&quot;&gt;HTTP static endpoint discovery&lt;&#x2F;h3&gt;
&lt;p&gt;You can define static &lt;a href=&quot;https:&#x2F;&#x2F;grafana.com&#x2F;docs&#x2F;alloy&#x2F;latest&#x2F;reference&#x2F;components&#x2F;discovery&#x2F;discovery.http&#x2F;&quot;&gt;http&lt;&#x2F;a&gt; endpoint for discovery of targets.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        discovery.http &amp;quot;va&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          url = &amp;quot;https:&#x2F;&#x2F;nexus3.indexexchange.com&#x2F;repository&#x2F;blackbox_targets&#x2F;VA_targets_icmp.json&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        }
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Container Networking</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/container-networking/"/>
        <id>https://ms-choudhary.github.io/notes/networking/container-networking/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/container-networking/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=6v_BDHIgOY8&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Check &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;container&#x2F;containers&#x2F;#network&quot;&gt;network&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;All containers have virtual ethernet(&lt;code&gt;veth&lt;&#x2F;code&gt;)interface attached&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;veth&lt;&#x2F;code&gt; &#x27;s are created in pair&#x27;s. For container networking, one part of the veth is in network namespace.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;bridge&lt;&#x2F;code&gt; interface is common connecting link. In a bridge, one part of it remains in host, other&#x27;s are connected with multiple veth interfaces(container&#x27;s). Bridge generally has a range of IP addresses (equivalent to each container&#x27;s ip).&lt;&#x2F;li&gt;
&lt;li&gt;Apart from above connections &lt;code&gt;veth&lt;&#x2F;code&gt; &amp;amp; &lt;code&gt;bridge&lt;&#x2F;code&gt; all other connection depend on routing&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;how-connection-works-for-two-containers-on-same-host&quot;&gt;How connection works for two containers on same host?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Hint: it uses bridge&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;All communications from containers are routed via bridge to host&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;All host communications are routed to containers via bridge&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;container-networking-same-host.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Creating the namespaces&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns add &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns add &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Creating the veth pairs&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link add veth10 type veth peer name veth11&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link add veth20 type veth peer name veth21&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Adding the veth pairs to the namespaces&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link set veth11 netns &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link set veth21 netns &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Configuring the interfaces in the network namespaces with IP address&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns exec &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; ip addr add &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;IP1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&#x2F;24 dev veth11 &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns exec &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; ip addr add &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;IP2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&#x2F;24 dev veth21 &lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Enabling the interfaces inside the network namespaces&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns exec &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; ip link set dev veth11 up&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns exec &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; ip link set dev veth21 up&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Creating the bridge&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link add name br0 type bridge&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Adding the network namespaces interfaces to the bridge&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link set dev veth10 master br0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link set dev veth20 master br0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Assigning the IP address to the bridge&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip addr add &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;BRIDGE_IP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&#x2F;24 dev br0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Enabling the bridge&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link set dev br0 up&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Enabling the interfaces connected to the bridge&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link set dev veth10 up&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip link set dev veth20 up&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Setting the loopback interfaces in the network namespaces&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns exec &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; ip link set lo up&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns exec &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; ip link set lo up&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Setting the default route in the network namespaces&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns exec &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; ip route add default via &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;BRIDGE_IP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; dev veth11&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ip netns exec &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CON2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; ip route add default via &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;BRIDGE_IP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; dev veth21&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;how-connection-works-between-two-containers-on-different-host-but-same-subnet&quot;&gt;How connection works between two containers on different host but same subnet?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Hint: It uses static ip routes&lt;&#x2F;li&gt;
&lt;li&gt;Prerequisite: Host and containers are able to communicate&lt;&#x2F;li&gt;
&lt;li&gt;Bridge on a host is allocated range of IP address (subnet)&lt;&#x2F;li&gt;
&lt;li&gt;If request is for bridge on other node, request is forwarded to the node&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;container-networking-diff-host-same-subnet.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-connection-works-between-two-containers-on-different-host-on-different-subnet&quot;&gt;How connection works between two containers on different host on different subnet?&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Case of overlay networks&lt;&#x2F;li&gt;
&lt;li&gt;In this case, nodes are linked but not on same network. Could be on internet. Could be different zones, etc&lt;&#x2F;li&gt;
&lt;li&gt;If other node is not next hop(i.e., different subnet), routing rules just on nodes won&#x27;t work, unless applied to all routers in between.&lt;&#x2F;li&gt;
&lt;li&gt;Prerequisite: Node should be able to communicate to each other&lt;&#x2F;li&gt;
&lt;li&gt;Hint: Use &lt;code&gt;tun&lt;&#x2F;code&gt; interface to hide a proxy, such that, data routed to &lt;code&gt;tun&lt;&#x2F;code&gt; is packaged in udp packet and send to appropriate node. Same process is followed on other node &amp;amp; data out from &lt;code&gt;tun&lt;&#x2F;code&gt; is fed to &lt;code&gt;bridge&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;container-networking-diff-host-diff-subnet.png&quot; alt=&quot;Container Networking Diff Host Diff Subnet&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;container&#x2F;containers&#x2F;&quot;&gt;containers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;iptables-command&#x2F;&quot;&gt;iptables-command&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;ip-command&#x2F;&quot;&gt;ip-command&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ip command</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/ip-command/"/>
        <id>https://ms-choudhary.github.io/notes/networking/ip-command/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/ip-command/">&lt;h3 id=&quot;manually-assign-ip-address-to-interface&quot;&gt;Manually assign ip address to interface&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ip addr add 10.118.16.4&#x2F;26 dev eno1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;&#x2F;24&lt;&#x2F;code&gt; is important, if not provided it&#x27;ll default to &lt;code&gt;&#x2F;32&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bring-up-down-a-link&quot;&gt;Bring up&#x2F;down a link&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ip link set eno1 down
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ip link set eno1 up
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;show-the-route-taken-for-ip&quot;&gt;Show the route taken for ip&lt;&#x2F;h3&gt;
&lt;p&gt;Helpful when there&#x27;re multiple interfaces&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ip route get &amp;lt;ip&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;iptables-command&#x2F;&quot;&gt;iptables-command&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;container-networking&#x2F;&quot;&gt;container-networking&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>iptables command</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/iptables-command/"/>
        <id>https://ms-choudhary.github.io/notes/networking/iptables-command/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/iptables-command/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;show-iptables-stats&quot;&gt;Show iptables stats&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;iptables -nvL [chain]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;or
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;iptables --numeric --verbose --list [chain]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;dump-rules-to-stdout&quot;&gt;Dump rules to stdout&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;iptables-save
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;show-dropped-packets-by-iptable-rules&quot;&gt;Show dropped packets by iptable rules&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ iptables -A INPUT -j LOG --log-prefix &amp;quot;IPT-DROP-INPUT: &amp;quot; --log-level 4
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ journalctl -f | grep &amp;quot;IPT-DROP-INPUT&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Apr 07 08:36:37 ops-fr-1.dcaux.indexww.com kernel: IPT-DROP-INPUT: IN=bond0 OUT= MAC=4c:d9:8f:3d:7c:f3:00:2c:c8:7a:69:bf:08:00 SRC=85.217.140.29 DST=185.80.39.238 LEN=52 TOS=0x00 PREC=0x00 TTL=54 ID=62016 PROTO=TCP SPT=41560 DPT=38472 WINDOW=65535 RES=0x00 SYN URGP=0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;make-permanent-changes-to-iptables&quot;&gt;Make permanent changes to iptables&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;on-rhel&quot;&gt;On RHEL&lt;&#x2F;h4&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ vim &#x2F;etc&#x2F;sysconfig&#x2F;iptables
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ systemctl restart iptables
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;ip-command&#x2F;&quot;&gt;ip-command&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;container-networking&#x2F;&quot;&gt;container-networking&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Keepalived</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/keepalived/"/>
        <id>https://ms-choudhary.github.io/notes/networking/keepalived/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/keepalived/">&lt;p&gt;It&#x27;s a linux daemon which provides high availability and load balancing for a backend group of servers. It&#x27;s built on top of VRRP (Virtual Router Redundancy Protocol) and IPVS (IP Virtual Server).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;vrrp&quot;&gt;VRRP&lt;&#x2F;h3&gt;
&lt;p&gt;The main objective of VRRP is to provide &lt;strong&gt;high availability&lt;&#x2F;strong&gt; of service to clients. Instead of exposing IP of a single server to users, VIP (virtual IP) is exposed which is shared by multiple servers.&lt;&#x2F;p&gt;
&lt;p&gt;One of the server is elected as Master (based on priority set in configuration), and all the traffic is routed through it. Periodically, master sends heartbeat to other backup servers. In case, a heartbeat is skipped, one of the other backup server is elected as master, and starts serving the traffic via the same virtual IP. The failed server is removed from the pool. The client&#x2F;user is unaware of this change, since it still connects on the same IP.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ipvs&quot;&gt;IPVS&lt;&#x2F;h3&gt;
&lt;p&gt;IPVS is a kernel mechanism to distribute connections to backend servers, basically a &lt;strong&gt;L4 load balancer&lt;&#x2F;strong&gt;. It supports scheduling based on round robin, least connections or weighted traffic to backend servers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;load-balancing-algorithms&#x2F;&quot;&gt;load-balancing-algorithms&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Load Balancing Algorithms</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/load-balancing-algorithms/"/>
        <id>https://ms-choudhary.github.io/notes/networking/load-balancing-algorithms/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/load-balancing-algorithms/">&lt;p&gt;Things you care about in load balancing, least packets drops, and low latency.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;request-queues-on-servers&quot;&gt;Request Queues on servers&lt;&#x2F;h2&gt;
&lt;p&gt;Different servers work differently, they start listening on port. Some create a fixed set of workers (process) at bootstrap, others create new process&#x2F;threads per request. They can implement request queues where packets arrive, and workers pick it from. Packet is dropped if queue is full. This increases per request latency, as packets have to wait in queue before they can be processed.&lt;&#x2F;p&gt;
&lt;p&gt;In golang, a new go routine is created for every request. In this case, server is limited by resources rather than queue length.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;centralised-algorithms&quot;&gt;Centralised algorithms&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;round-robin&quot;&gt;Round Robin&lt;&#x2F;h3&gt;
&lt;p&gt;Most common default. Requests are routed to backend servers in uniform round robin fashion.&lt;&#x2F;p&gt;
&lt;p&gt;Drawbacks: In real world, all backend servers are &lt;strong&gt;not equally powerful&lt;&#x2F;strong&gt; and all request are &lt;strong&gt;not equally expensive&lt;&#x2F;strong&gt;, namely request &amp;amp; server variance.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;weighted-round-robin-wrr&quot;&gt;Weighted Round Robin (WRR)&lt;&#x2F;h3&gt;
&lt;p&gt;Humans tag each server with specific weight, and requests are served based on that weight. This &lt;strong&gt;handles server variance&lt;&#x2F;strong&gt;, but not request. This has better latency.&lt;&#x2F;p&gt;
&lt;p&gt;Drawbacks: It&#x27;s hard to come up with single digit number. It requires extensive benchmarking of servers. Adding human to the loop for every weight change can be a recipe for disaster. It doesn&#x27;t account for request variance.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;dynamic-weighted-round-robin&quot;&gt;Dynamic Weighted Round Robin&lt;&#x2F;h3&gt;
&lt;p&gt;Variant of WRR, it calculates the weights dynamically based on server metrics like latency. Since LB sits between client and server, it can track request latency from server. Weight is calculated dynamically based on that.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Works only on centralized load balancer&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;least-connection&quot;&gt;Least Connection&lt;&#x2F;h3&gt;
&lt;p&gt;LB sits between client and server, knows server statistics like active connections, latency per server. In least connection, it prioritises servers with least active connections. Simple to calculate&#x2F;maintain and quite effective. This &lt;strong&gt;handles both server &amp;amp; request variance&lt;&#x2F;strong&gt;. Hence it&#x27;s a great default for most workloads.&lt;&#x2F;p&gt;
&lt;p&gt;Requests are only dropped, when all of backend servers are overloaded. However it has slightly higher latency compared to WRR.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Works only on centralized load balancer&lt;&#x2F;strong&gt;. In distributed load balancers, no single LB has full info of how many active connections are open on backend.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;peak-exponentially-weighted-moving-average-pewma&quot;&gt;Peak Exponentially Weighted Moving Average (PEWMA)&lt;&#x2F;h3&gt;
&lt;p&gt;Mix of Least connection &amp;amp; Dynamic Weighted RR. Tries to optimise for lower latency &amp;amp; better overload.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;drawbacks-of-centralised-load-balancing&quot;&gt;Drawbacks of centralised load balancing&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Single point of failures&lt;&#x2F;li&gt;
&lt;li&gt;Scaling is only vertical, and can be very costly&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;distributed-algorithms&quot;&gt;Distributed algorithms&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;dns-round-robin&quot;&gt;DNS Round Robin&lt;&#x2F;h3&gt;
&lt;p&gt;No load balancer required. Endpoint resolves differently for each client. Works well in large system with homogenous requests.&lt;&#x2F;p&gt;
&lt;p&gt;Drawbacks: No health checks, backends cannot go down. Clients can override TTL and cache results for much longer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;power-of-two-random-choices&quot;&gt;Power of two random choices&lt;&#x2F;h3&gt;
&lt;p&gt;Perfect distributed load balancing requires sharing current server loads with all load balancers. Overhead of constantly sharing this info is high. If this info is cached and synced periodically, it leads to herding of connections on a quiet backend for much longer, then cool down. So servers move from quiet -&amp;gt; busy -&amp;gt; quiet etc.&lt;&#x2F;p&gt;
&lt;p&gt;In best of 2, you pick two backends randomly. Then, pick the one with low load. This works effectively even with cached info.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;samwho.dev&#x2F;load-balancing&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;brooker.co.za&#x2F;blog&#x2F;2012&#x2F;01&#x2F;17&#x2F;two-random.html&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;keepalived&#x2F;&quot;&gt;keepalived&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tcpdump</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/tcpdump/"/>
        <id>https://ms-choudhary.github.io/notes/networking/tcpdump/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/tcpdump/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;list-interfaces&quot;&gt;List interfaces&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tcpdump -D
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;expression&quot;&gt;Expression&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Check &lt;code&gt;man pcap-filter&lt;&#x2F;code&gt; for tcpdump expression syntax and fields&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;capture-file&quot;&gt;Capture file&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tcpdump -w capture.pcap -i any host google.com
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;capture-dhcp-packets&quot;&gt;Capture DHCP packets&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tcpdump -i any -vv -n port 67 or port 68
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;capture-packets-from-specific-mac-address&quot;&gt;Capture packets from specific mac address&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tcpdump -i bond0.101 -n -vvv -e ether host 2c:ea:7f:89:d5:95
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;dhcpd&#x2F;&quot;&gt;dhcpd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Wake On Lan (WOL)</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/networking/wake-on-lan/"/>
        <id>https://ms-choudhary.github.io/notes/networking/wake-on-lan/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/networking/wake-on-lan/">&lt;p&gt;Wake on LAN (WOL) is a protocol that enables you to wake up a computer&#x2F;server remotely by a sending a ethernet packet.&lt;&#x2F;p&gt;
&lt;p&gt;This has to be enabled in BIOS. Find where this is on our asrock minipc #question.
For this, the NIC card has to constantly listen to all broadcast messages for magic packet.&lt;&#x2F;p&gt;
&lt;p&gt;Since this works on hardware layer, it works regardless of OS etc. Only ethernet supports this feature.&lt;&#x2F;p&gt;
&lt;p&gt;Works on a server in standby mode, ie, OS shut down normally with power supply still connected. Goes into ACPI S5 state, and it still receives standby power to listen on ethernet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;magic-packet&quot;&gt;Magic packet&lt;&#x2F;h3&gt;
&lt;p&gt;Magic packet is broadcasted on UDP ports 0, 7, 9 etc. Magic packet consists of 6 bytes of 0xFF followed target MAC address to wake up (repeated 16 times). This is because NIC receives stream of bytes without start and end. And checking for this pattern allows it to reliably and efficiently identify the MAC address.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;limitations&quot;&gt;Limitations&lt;&#x2F;h3&gt;
&lt;p&gt;Packet has to originate from the network the server is in.  Doesn&#x27;t really matter on what layer the packet is received, data link or ip, all the NIC hardware cares for is magic packet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;booting-linux-on-x86-64&#x2F;&quot;&gt;booting-linux-on-x86-64&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Anaconda</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/os-install/anaconda/"/>
        <id>https://ms-choudhary.github.io/notes/os-install/anaconda/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/os-install/anaconda/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;anaconda-installer.readthedocs.io&#x2F;en&#x2F;latest&#x2F;user-guide&#x2F;boot-options.html&lt;&#x2F;p&gt;
&lt;p&gt;Anaconda is the OS installer for RHEL based systems.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;ssh-to-server-for-troubleshooting&quot;&gt;SSH to server for troubleshooting&lt;&#x2F;h3&gt;
&lt;p&gt;(This only works if kernel arg: &lt;code&gt;inst.sshd&lt;&#x2F;code&gt; was set while live booting OS)&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh root@server-ip
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tmux attach
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;check ks logs: &#x2F;var&#x2F;run&#x2F;install&#x2F;ks.cfg
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;retry-anaconda-installer-from-failed-server&quot;&gt;Retry anaconda installer from failed server&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;anaconda --kickstart &#x2F;path&#x2F;to&#x2F;ks.cfg
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;cobbler&#x2F;&quot;&gt;cobbler&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;dhcpd&#x2F;&quot;&gt;dhcpd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;initrd&#x2F;&quot;&gt;initrd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;booting-linux-on-x86-64&#x2F;&quot;&gt;booting-linux-on-x86-64&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cobbler</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/os-install/cobbler/"/>
        <id>https://ms-choudhary.github.io/notes/os-install/cobbler/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/os-install/cobbler/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;p&gt;Cobbler is a tool used for provisioning bare metal servers.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;add-cobbler-system&quot;&gt;Add cobbler system&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cobbler system add --name=&amp;quot;k8s1ny-w-19.indexww.com&amp;quot; --hostname=&amp;quot;k8s1ny-w-19.indexww.com&amp;quot; --profile=&amp;quot;K8S-CP-R9&amp;quot; --interface=p1p1 --ip-address=10.129.0.22 --mac=64:9D:99:B2:2F:C8 --static=1 --netmask=255.255.255.0 --gateway=10.129.0.250 --name-servers=&amp;quot;192.40.39.191 1.1.1.1&amp;quot;  --name-servers-search=&amp;quot;indexexchange.com casalemedia.com indexww.com&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;anaconda&#x2F;&quot;&gt;anaconda&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;initrd&#x2F;&quot;&gt;initrd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;dhcpd&#x2F;&quot;&gt;dhcpd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;idrac-racadm&#x2F;&quot;&gt;idrac-racadm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>DHCPD</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/os-install/dhcpd/"/>
        <id>https://ms-choudhary.github.io/notes/os-install/dhcpd/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/os-install/dhcpd/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;leases&quot;&gt;Leases&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;leases are stored at path: &lt;code&gt;&#x2F;var&#x2F;lib&#x2F;dhcpd&#x2F;dhcpd.leases&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;configuration&quot;&gt;Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;DHCPD (isc-dhcpd) sample configuration:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ddns-update-style interim;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;allow booting;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;allow bootp;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ignore client-updates;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;set vendorclass = option vendor-class-identifier;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;option system-arch code 93 = unsigned integer 16;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;subnet 10.203.32.64 netmask 255.255.255.192 {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     option routers             10.203.32.126;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     option domain-name-servers 10.199.1.240;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     option subnet-mask         255.255.255.192;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     range dynamic-bootp        10.203.32.65 10.203.32.100 ;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     default-lease-time         1800;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     max-lease-time             3600;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     next-server                $next_server_v4;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     class &amp;quot;pxeclients&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          match if substring (option vendor-class-identifier, 0, 9) = &amp;quot;PXEClient&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          # Legacy
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          if option system-arch = 00:00 {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              filename &amp;quot;grub&#x2F;grub.0&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          # UEFI-32-2
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          if option system-arch = 00:02 {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              # Not supported, no 32 bit UEFI grub executable
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              filename &amp;quot;unsupported&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          # UEFI-64-1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          else if option system-arch = 00:07 {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              filename &amp;quot;grub&#x2F;grubx64.efi&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          # UEFI-64-2
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          else if option system-arch = 00:08 {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              filename &amp;quot;grub&#x2F;grubx64.efi&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          # UEFI-64-3
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          else if option system-arch = 00:09 {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              filename &amp;quot;grub&#x2F;grubx64.efi&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          # armv7   (aka arm 32 bit)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          else if option system-arch = 00:0a {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              filename &amp;quot;grub&#x2F;armv7.efi&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          # aarch64 (aka arm 64 bit)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          else if option system-arch = 00:0b {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              filename &amp;quot;grub&#x2F;grubaa64.efi&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          else
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              # This will be used when Bootmode is set to Legacy Bios
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;              filename &amp;quot;pxelinux.0&amp;quot;;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;     }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;&#x2F;h3&gt;
&lt;p&gt;DHCPD config consists of subnet definitions it looks out for. If a packet arrives from one of these subnets, it responds with DORA flow.
It only listens on interfaces for which subnets are defined in configuration. If there&#x27;s no subnet definition for interfaces, it fails to come up.&lt;&#x2F;p&gt;
&lt;p&gt;If you don&#x27;t see a packet arriving, ensure you&#x27;ve interface subnet added along with target subnet.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;cobbler&#x2F;&quot;&gt;cobbler&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;anaconda&#x2F;&quot;&gt;anaconda&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;tcpdump&#x2F;#capture-dhcp-packets&quot;&gt;Capture DHCP packets&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Grub</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/os-install/grub/"/>
        <id>https://ms-choudhary.github.io/notes/os-install/grub/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/os-install/grub/">&lt;h3 id=&quot;update-kernel-options-via-grub&quot;&gt;Update kernel options via grub&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Edit file &lt;code&gt;&#x2F;etc&#x2F;default&#x2F;grub&lt;&#x2F;code&gt; with necessary change&lt;&#x2F;li&gt;
&lt;li&gt;Finally run &lt;code&gt;grub2-mkconfig -o &#x2F;boot&#x2F;grub2&#x2F;grub.cfg&lt;&#x2F;code&gt; (on rhel, centos) or &lt;code&gt;update-grub&lt;&#x2F;code&gt; on debian, ubuntu
&lt;ul&gt;
&lt;li&gt;if it doesn&#x27;t work try adding option &lt;code&gt;--update-bls-cmdline&lt;&#x2F;code&gt; to grub2-mkconfig&lt;&#x2F;li&gt;
&lt;li&gt;for efi the path could be different:&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;initrd&#x2F;&quot;&gt;initrd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;booting-linux-on-x86-64&#x2F;&quot;&gt;booting-linux-on-x86-64&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>IDrac Racadm</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/os-install/idrac-racadm/"/>
        <id>https://ms-choudhary.github.io/notes/os-install/idrac-racadm/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/os-install/idrac-racadm/">&lt;p&gt;iDRAC is a separate BMC chip, on dell, which integrates on the motherboard, and provides users to control a server remotely. You could build a similar feature with piKVM, &lt;a href=&quot;https:&#x2F;&#x2F;docs.pikvm.org&#x2F;v2&#x2F;&quot;&gt;diy&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Connect the video cable.&lt;&#x2F;li&gt;
&lt;li&gt;Integrate circuit to motherboard power supply&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With serial over lan, you can get serial console remotely for troubleshooting purposes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;alias&quot;&gt;Alias&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;alias myracadm=&amp;quot;racadm -r 10.118.16.27 -u root -p calvin --nocertwarn&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;check-sel-logs&quot;&gt;Check sel logs&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;opt&#x2F;ix&#x2F;ops-bin&#x2F;rracadm.sh -v bh2-prod-data-1407.ix1.indexww.com getsel -o
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;check-cpu-reset&quot;&gt;Check cpu reset&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;opt&#x2F;ix&#x2F;ops-bin&#x2F;rracadm.sh bh2-prod-data-674.ix1.indexww.com lclog view -n 10 -k CPU
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;set-first-boot-to-pxe&quot;&gt;Set first boot to pxe&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm -r 10.118.16.3 -u root -p calvin set idrac.serverboot.firstbootdevice PXE
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;pxe-device&quot;&gt;pxe device&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;.&#x2F;racadm get BIOS.PxeDev1Settings.PxeDev1Interface
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;.&#x2F;racadm set BIOS.PxeDev1Settings.PxeDev1Interface &amp;lt;interface name, something like NIC.Slot.1-1&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;powercycle&quot;&gt;Powercycle&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm -r 10.118.16.3 -u root -p calvin serveraction powercycle
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;jobqueue&quot;&gt;Jobqueue&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;myracadm jobqueue create BIOS.Setup.1-1 -r pwrcycle
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;racreset&quot;&gt;racreset&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm racreset soft
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;pre-requisites-for-ssh-ipmi-or-webconsole&quot;&gt;Pre-requisites for ssh, ipmi or webconsole&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm set idrac.ipmilan.enable Enabled
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm  set idrac.ssh.enable Enabled
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm set iDRAC.WebServer.HostHeaderCheck Disabled
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;via-ssh&quot;&gt;Via ssh&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh root@idrac_ip
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh -o KexAlgorithms=curve25519-sha256 root@idrac_ip
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;console com2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ctrl + \ to exit
ctrl + f12 = to access boot menu (not verified yet)&lt;&#x2F;p&gt;
&lt;h3 id=&quot;system-info&quot;&gt;System info&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm getsysinfo
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;virtual-media&quot;&gt;Virtual media&lt;&#x2F;h3&gt;
&lt;p&gt;Check &lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;redfish&#x2F;#attach-virtual-media&quot;&gt;Attach virtual media&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Requires license. Although you can get trail enterprise license from dell website. Trial license can only be loaded once per server. After expiry you cannot add any other trial license.&lt;&#x2F;p&gt;
&lt;p&gt;Connect&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;myracadm remoteimage -c -l http:&#x2F;&#x2F;10.40.16.10:8080&#x2F;bootc-almalinux-10.2-bootc-generic-iso-x86_64&#x2F;bootc-almalinux-10.2-bootc-generic-iso-x86_64.iso
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Set first boot device to Virtual CD:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm set iDRAC.ServerBoot.FirstBootDevice VCD-DVD
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Check status:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;myracadm remoteimage -s
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Disconnect:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;myracadm remoteimage -d
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;connectivity-from-bmc&quot;&gt;Connectivity from BMC&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm ping 10.40.16.10
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;racadm traceroute 10.40.16.10
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;cobbler&#x2F;&quot;&gt;cobbler&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;dhcpd&#x2F;&quot;&gt;dhcpd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;redfish&#x2F;&quot;&gt;redfish&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Initrd</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/os-install/initrd/"/>
        <id>https://ms-choudhary.github.io/notes/os-install/initrd/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/os-install/initrd/">&lt;h2 id=&quot;extract&quot;&gt;Extract&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;xzcat initrd.img | cpio -id
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;-i extract
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;-d create dirs
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;check-content&quot;&gt;Check content&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# show content of initramfs of current kernel
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;lsinitrd
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# show content of specific initramfs file
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;lsinitrd path&#x2F;to&#x2F;initramfs.img
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;cobbler&#x2F;&quot;&gt;cobbler&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;anaconda&#x2F;&quot;&gt;anaconda&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;virtualization&#x2F;inspect-vm-filesystem&#x2F;&quot;&gt;inspect-vm-filesystem&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;storage&#x2F;dd&#x2F;&quot;&gt;dd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;grub&#x2F;&quot;&gt;grub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;booting-linux-on-x86-64&#x2F;&quot;&gt;booting-linux-on-x86-64&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Redfish</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/os-install/redfish/"/>
        <id>https://ms-choudhary.github.io/notes/os-install/redfish/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/os-install/redfish/">&lt;h3 id=&quot;attach-virtual-media&quot;&gt;Attach virtual media&lt;&#x2F;h3&gt;
&lt;p&gt;You can attach an ISO to virtual media (like CDROM) on the server via redfish virtual media API. Generally requires license. BMC will download &amp;amp; present it as virtual CD ROM to the host OS&#x2F;bios.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;uefi-http-boot&quot;&gt;UEFI HTTP boot&lt;&#x2F;h3&gt;
&lt;p&gt;Uses reliable TCP connection, instead of UDP (TFTP). Thus enables scalability &amp;amp; performance using http load balancer. Still requires functional DNS, DHCP, http servers. Just uses HTTP over TFTP.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;idrac-racadm&#x2F;&quot;&gt;idrac-racadm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Check progress of restic backup</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/restic/check-progress-of-restic-backup/"/>
        <id>https://ms-choudhary.github.io/notes/restic/check-progress-of-restic-backup/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/restic/check-progress-of-restic-backup/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;restic.readthedocs.io&#x2F;en&#x2F;latest&#x2F;manual_rest.html&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re running restic in a non interactive setup (like in cron&#x2F;systemd timer etc), there are two ways to show current backup progress:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;set env &lt;code&gt;RESTIC_PROGRESS_FPS&lt;&#x2F;code&gt;  to 1 for printing progress every second,  &lt;code&gt;1&#x2F;60 = 0.016667&lt;&#x2F;code&gt; for every min&lt;&#x2F;li&gt;
&lt;li&gt;invoking &lt;code&gt;SIGUSR1&lt;&#x2F;code&gt; signal to running restic process should shows current progress in stdout logs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;kill -SIGUSR1 $(pgrep restic)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Data encoding</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/security/data-encoding/"/>
        <id>https://ms-choudhary.github.io/notes/security/data-encoding/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/security/data-encoding/">&lt;h2 id=&quot;base32&quot;&gt;base32&lt;&#x2F;h2&gt;
&lt;p&gt;base32 encodes binary data into set of ASCII chars, 26 letters (A-Z) &amp;amp; 2-7 numerals.&lt;&#x2F;p&gt;
&lt;p&gt;It takes 5 bit of input and converts it into a char. Since data is generally represented in 8-bits byte, it processes a 5 byte input chunk (40 bit) and generates a 8 chars of output. Padding &#x27;=&#x27; is added at the end if input is not a multiple of 5. Padding is extra, and data can be decoded (although with errors) without it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;use-cases&quot;&gt;Use cases&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;TOTP&lt;&#x2F;li&gt;
&lt;li&gt;case insensitive systems like dns, filesystem etc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;base64&quot;&gt;base64&lt;&#x2F;h2&gt;
&lt;p&gt;base64 encodes binary data into 64 ASCII chars:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A-Z&lt;&#x2F;li&gt;
&lt;li&gt;a-z&lt;&#x2F;li&gt;
&lt;li&gt;0-9&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;&#x2F; (2 special chars)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;= (padding at the end)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Processes a 6 bit input to one char. Takes 3 bytes (24 bit) to produce 4 chars. If input is not a multiple of 3 bytes, padding is added at the end.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;use-cases-1&quot;&gt;Use cases&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;converts binary data into representable text
&lt;ul&gt;
&lt;li&gt;email attachments&lt;&#x2F;li&gt;
&lt;li&gt;image css in html&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;url-encoding&quot;&gt;URL encoding&lt;&#x2F;h2&gt;
&lt;p&gt;URL encoding replaces unsafe chars with % followed by 2 digit hex value. Almost all chars are unsafe except few.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Digitial Rights Management (DRM)</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/security/drm/"/>
        <id>https://ms-choudhary.github.io/notes/security/drm/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/security/drm/">&lt;p&gt;DRM takes control of the digital content from the users to a software program. It helps prevent unauthorised sharing or modification of IP. Used by services like Netflix, PrimeVideo etc.&lt;&#x2F;p&gt;
&lt;p&gt;Some popular DRM systems include, also known as, Content Decryption Module (CDM):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Widevine (Google) - included with all browsers&lt;&#x2F;li&gt;
&lt;li&gt;Fair Play (Apple) - Safari, iOS - perhaps why the player is different&lt;&#x2F;li&gt;
&lt;li&gt;Playready (MS)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Typical flow involves, a movie or stream is encrypted. When you hit play, device requests the decryption key. The request includes, user credentials, device info (used for selecting decryption layer) and DRM type (widevine etc). Companies package content in multiple DRMs and serve the right one based on what the browser supports. If everything checks out, it sends a decryption key. Video is only decrypted in real time.&lt;&#x2F;p&gt;
&lt;p&gt;W3C Encrypted Media Extensions (EME) spec is the browser API which all browsers implement. They might use different CDM underneath (For eg apple uses Fair play, chrome&#x2F;android - widevine etc).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;l1-hardware-level-security&quot;&gt;L1 - Hardware level security&lt;&#x2F;h3&gt;
&lt;p&gt;Decryption &amp;amp; processing happens entirely with TEE (Trusted Execution Environment). Requires device support. For eg, netflix allows playing 4k only on devices which support L1.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;l2-mix-of-hardware-and-software&quot;&gt;L2 - Mix of hardware and software&lt;&#x2F;h3&gt;
&lt;p&gt;Uses some features of hardware and software. Limited to 1080p.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;l3-software-only&quot;&gt;L3 - Software only&lt;&#x2F;h3&gt;
&lt;p&gt;Decryption happens in memory (RAM). Handled at OS&#x2F;Browser level. Susceptible to theft from RAM by compromised kernel or privildged process. Limited to 480p to 720p resolution for the same reason. All decrypted videos have a invisible watermark, with user info, useful to find the culprit if a video is copied and leaked.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;hardware&#x2F;trusted-platform-module&#x2F;&quot;&gt;trusted-platform-module&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Openid Connect (OIDC)</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/security/oidc/"/>
        <id>https://ms-choudhary.github.io/notes/security/oidc/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/security/oidc/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;dexidp.io&#x2F;docs&#x2F;openid-connect&#x2F;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;oauth2&quot;&gt;Oauth2&lt;&#x2F;h3&gt;
&lt;p&gt;Popular single sign on workflow, for eg with google:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You login to application via google&lt;&#x2F;li&gt;
&lt;li&gt;It is redirected to google login form&lt;&#x2F;li&gt;
&lt;li&gt;You authenticate to google using your google creds&lt;&#x2F;li&gt;
&lt;li&gt;You&#x27;re redirected back to application with token, and are now authenticated to the application&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;id-tokens&quot;&gt;ID Tokens&lt;&#x2F;h3&gt;
&lt;p&gt;Tokens provided in oauth2 are generally opaque to client and provider specific. OIDC standardises the flow including the tokens as Json Web Token (JWT). Token consists of well known fields: header, payload and signature (of the first two fields).&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;   # header
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;alg&amp;quot;: &amp;quot;RS256&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;kid&amp;quot;: &amp;quot;9151f75528677cd0c33a635340053dfd77f8d13f&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  },
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # payload
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;iss&amp;quot;: &amp;quot;https:&#x2F;&#x2F;ixdev.mschoudhary.site&#x2F;&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;sub&amp;quot;: &amp;quot;CgcxODQxMTIzEgZnaXRodWI&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;aud&amp;quot;: &amp;quot;kubernetes&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;exp&amp;quot;: 1775038239,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;iat&amp;quot;: 1774951839,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;jti&amp;quot;: &amp;quot;37d5ef0e-ba82-4824-9c1c-58c06bf5fca9&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;nonce&amp;quot;: &amp;quot;gfInD0FryxFUqfzmdFRd8JKfe9j2U8XPWkxQMLEyFmI&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;auth_time&amp;quot;: 1774951838,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;at_hash&amp;quot;: &amp;quot;Kax3OY7scPt7souT8r1KSg&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;c_hash&amp;quot;: &amp;quot;bF1DxR19BltzjxvUjELSUg&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;email&amp;quot;: &amp;quot;ms.choudhary2000@gmail.com&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;email_verified&amp;quot;: true,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;name&amp;quot;: &amp;quot;Mohit Choudhary&amp;quot;,
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    &amp;quot;preferred_username&amp;quot;: &amp;quot;ms-choudhary&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  #signature
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  ....
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;iss - the oidc server who issued this token&lt;&#x2F;li&gt;
&lt;li&gt;sub - unique end user id&lt;&#x2F;li&gt;
&lt;li&gt;aud - client for which this token was issued for&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While authenticating clients can request extra scopes (all supported scopes are listed in discovery endpoint), and server provides the same as additional claims (email, profile etc) in the token.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;discovery&quot;&gt;Discovery&lt;&#x2F;h3&gt;
&lt;p&gt;All OIDC implement a well known discovery url: &lt;code&gt;&#x2F;.well-known&#x2F;openid-configuration&lt;&#x2F;code&gt;, which shows all configurations of OIDC server.&lt;&#x2F;p&gt;
&lt;p&gt;Other endpoints:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;authorization_endpoint&lt;&#x2F;code&gt; used for authenticating&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;jwks_uri&lt;&#x2F;code&gt; provides public keys of the server, used to verify the signature.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;claims_supported&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;scope_supported&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;flow&quot;&gt;Flow&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Connect to &lt;code&gt;authorization_endpoint&lt;&#x2F;code&gt; (in wellknown configuration endpoint)&lt;&#x2F;li&gt;
&lt;li&gt;Authenticate with the identity provider (like google, github, jumpcloud etc)&lt;&#x2F;li&gt;
&lt;li&gt;You&#x27;re redirected back to the redirect_url configured in IDP.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;tokens&quot;&gt;Tokens&lt;&#x2F;h3&gt;
&lt;p&gt;In response, you get three tokens:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ID token&lt;&#x2F;strong&gt;, this is the identity token used to authenticate the user. (Like government id in concert, you show this just once)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Access token&lt;&#x2F;strong&gt;, this is the token used to interact with the apis. (Like wrist band in concert). This is has minimal fields.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Refresh token&lt;&#x2F;strong&gt; (optional), token used to refresh all of these tokens if they expire etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;refresh-token&quot;&gt;Refresh Token&lt;&#x2F;h4&gt;
&lt;p&gt;Generally in OIDC, you don&#x27;t get refresh token by default. You&#x27;ve to request an additional scope &lt;code&gt;offline_access&lt;&#x2F;code&gt; when making the first request, thereby you authorising the client app to refresh tokens on your behalf. IDP should support this scope.&lt;&#x2F;p&gt;
&lt;p&gt;You can exchange a refresh token with new valid tokens. For security reasons, any refresh token can only be used once, it returns all new tokens (id, access &amp;amp; refresh).&lt;&#x2F;p&gt;
&lt;p&gt;This facilitates functionalities, like relogin after 24 hours of inactivity. For eg, if client is active, it can refresh tokens automatically. However, if client is inactive and refresh token expires, you&#x27;ve to reauthenticate again.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;scopes-claims&quot;&gt;Scopes &amp;amp; Claims&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;Scope&lt;&#x2F;strong&gt; is what you request when you initiate the flow.
For eg, I&#x27;m interested in these category of information.
&lt;strong&gt;Claims&lt;&#x2F;strong&gt; is what you receive&lt;&#x2F;p&gt;
&lt;p&gt;Scope unlocks claims. Some standard scopes and claims:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;openid =&amp;gt; sub, iss, aud, exp, iat&lt;&#x2F;li&gt;
&lt;li&gt;email =&amp;gt; email, email_verified&lt;&#x2F;li&gt;
&lt;li&gt;profile =&amp;gt; name, given_name, family_name etc&lt;&#x2F;li&gt;
&lt;li&gt;groups =&amp;gt; groups&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All supported scopes are listed in discovery endpoint. You can implement custom scopes as well, and introduce custom claims, specific to your app.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;shell&#x2F;jq&#x2F;#decoding-jwt-using-jq&quot;&gt;Decoding JWT using jq&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;security&#x2F;query-ldap-schema&#x2F;&quot;&gt;query-ldap-schema&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Query LDAP schema</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/security/query-ldap-schema/"/>
        <id>https://ms-choudhary.github.io/notes/security/query-ldap-schema/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/security/query-ldap-schema/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;dexidp.io&#x2F;docs&#x2F;connectors&#x2F;ldap&#x2F;#getting-started&lt;&#x2F;p&gt;
&lt;p&gt;Generally when you&#x27;re configuring LDAP authentication for an application, you&#x27;ve to discover&#x2F;map certain fields to application configuration. Following tools are helpful in that.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;install-ldapsearch&quot;&gt;Install ldapsearch&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;dnf install openldap-clients
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;lt;or&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;apt-get install ldap-utils
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;user-group-schema-mapping&quot;&gt;User&#x2F;group schema mapping&lt;&#x2F;h3&gt;
&lt;p&gt;If directory is small, you can dump all entries by:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ldapsearch -x -H ldap:&#x2F;&#x2F;ldap.example.org -b &amp;#39;dc=example,dc=org&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;First find user entry&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;dn: uid=jdoe,cn=users,cn=compat,dc=example,dc=org
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cn: Jane Doe
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;objectClass: posixAccount
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;objectClass: ipaOverrideTarget
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;objectClass: top
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;gidNumber: 200015
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;gecos: Jane Doe
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;uidNumber: 200015
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;loginShell: &#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;homeDirectory: &#x2F;home&#x2F;jdoe
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mail: jane.doe@example.com
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;uid: janedoe
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which can be mapped like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;userSearch:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # The directory directly above the user entry.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  baseDN: cn=users,cn=compat,dc=example,dc=org
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  filter: &amp;quot;(objectClass=posixAccount)&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # Expect user to enter &amp;quot;janedoe&amp;quot; when logging in.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  username: uid
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # Use the full DN as an ID.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  idAttr: DN
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # When an email address is not available, use another value unique to the user, like uid.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  emailAttr: mail
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  nameAttr: gecos
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then find group entry:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;dn: cn=developers,cn=groups,cn=compat,dc=example,dc=org
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;memberUid: janedoe
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;memberUid: johndoe
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;gidNumber: 200115
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;objectClass: posixGroup
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;objectClass: ipaOverrideTarget
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;objectClass: top
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cn: developers
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Group search must match a user attribute to group attribute. For eg, user&#x27;s uid is matched to group&#x27;s memberUid.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;groupSearch:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # The directory directly above the group entry.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  baseDN: cn=groups,cn=compat,dc=example,dc=org
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  filter: &amp;quot;(objectClass=posixGroup)&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # The group search needs to match the &amp;quot;uid&amp;quot; attribute on
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # the user with the &amp;quot;memberUid&amp;quot; attribute on the group.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  userMatchers:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  - userAttr: uid
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    groupAttr: memberUid
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  # Unique name of the group.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  nameAttr: cn
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;security&#x2F;oidc&#x2F;&quot;&gt;oidc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>TOTP</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/security/totp/"/>
        <id>https://ms-choudhary.github.io/notes/security/totp/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/security/totp/">&lt;p&gt;TOTP is Time based One Time Password.&lt;&#x2F;p&gt;
&lt;p&gt;Server generates a base32 secret (without padding &#x27;=&#x27;), and shares to client via QR. QR code encodes a link of format: &lt;code&gt;otpauth:&#x2F;&#x2F;totp&#x2F;github:john@example.com?secret=xyz&amp;amp;issuer=github&amp;amp;algo=sha1&lt;&#x2F;code&gt;. Client stores the secret.&lt;&#x2F;p&gt;
&lt;p&gt;The other thing shared between server &amp;amp; client is time. 30s interval window is selected, so it&#x27;s easy for user to add the code, and it nullifies millisecond and microsecond differences between client and server&#x27;s clock.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;currTimeInS := currentTimestamp in unix secs
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;counter := currTimeInS&#x2F;30 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;code := hash.Sha1(secret, counter) &#x2F;&#x2F; generates a 20-byte hash
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;opt := truncateTo6Digits(code)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&#x2F;&#x2F; dynamic truncate
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Last hex for eg 0x5a =&amp;gt; integer, eg 10 =&amp;gt; get 4 bytes from offset =&amp;gt; integer =&amp;gt; truncate
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Client and server performs the same computation over 30s intervals, and should match for success.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=HFu3CUtrOQ8&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;security&#x2F;data-encoding&#x2F;#base32&quot;&gt;base32&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;certificates&#x2F;pki-certificates&#x2F;&quot;&gt;pki-certificates&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>jq command</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/shell/jq/"/>
        <id>https://ms-choudhary.github.io/notes/shell/jq/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/shell/jq/">&lt;h3 id=&quot;decoding-jwt-using-jq&quot;&gt;Decoding JWT using jq&lt;&#x2F;h3&gt;
&lt;p&gt;JWT token can be decoded using jq:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;jwt-decode () {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;        jq -R &amp;#39;split(&amp;quot;.&amp;quot;) |.[0:2] | map(@base64d) | map(fromjson)&amp;#39; &amp;lt;&amp;lt;&amp;lt; $1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--raw-input&#x2F;-R&lt;&#x2F;code&gt; = don&#x27;t parse input as json instead pass as string&lt;&#x2F;li&gt;
&lt;li&gt;map(x), map_values(x)
For any filter x, map(x) will run that filter for each element of the input array, and return the outputs in a new array.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;@base64d&lt;&#x2F;code&gt; = base64 decode&lt;&#x2F;li&gt;
&lt;li&gt;Convert to&#x2F;from JSON
The  tojson  and  fromjson builtins dump values as JSON texts or parse JSON texts into values, respectively.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;print-fields-as-string&quot;&gt;Print fields as string&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt; $ docker image inspect miniflux&#x2F;miniflux | jq &amp;#39;.[] | &amp;quot;\(.Os)\&#x2F;\(.Architecture)&amp;quot;&amp;#39;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;quot;linux&#x2F;arm64&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;has string in quotes&lt;&#x2F;li&gt;
&lt;li&gt;escape special chars&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;security&#x2F;oidc&#x2F;&quot;&gt;oidc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Set time on linux</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/shell/set-time-on-linux/"/>
        <id>https://ms-choudhary.github.io/notes/shell/set-time-on-linux/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/shell/set-time-on-linux/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;set-systemwide-timezone-on-linux&quot;&gt;Set systemwide timezone on linux&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;&#x2F;etc&#x2F;localtime&lt;&#x2F;code&gt; symlinks to timezone file in &#x2F;usr&#x2F;share&#x2F;zoneinfo. Changing the link to different timezone changes the systemwide timezone info.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;msc@debian:~$ ls -l &#x2F;etc&#x2F;localtime
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;lrwxrwxrwx 1 root root 32 Nov 15 10:39 &#x2F;etc&#x2F;localtime -&amp;gt; &#x2F;usr&#x2F;share&#x2F;zoneinfo&#x2F;Asia&#x2F;Kolkata
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;set-system-time-on-linux&quot;&gt;Set system time on linux&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;date -s &amp;#39;Sat Nov 23 15:12:58 IST 2024&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Shell Commands</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/shell/shell-commands/"/>
        <id>https://ms-choudhary.github.io/notes/shell/shell-commands/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/shell/shell-commands/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reverse-a-file&quot;&gt;Reverse a file&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tac
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;or
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tail -r
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;show-file-with-linenumber&quot;&gt;Show file with linenumber&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cat -n filename
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;less -N filename or type -N in less window
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;vim file =&amp;gt; :set number
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;match-unmatch-patterns-from-file&quot;&gt;Match&#x2F;unmatch patterns from file&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Find entries which are present in all but missing in processed to left_over (does not require sorting):&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;grep -vxFf processed all &amp;gt; left_over
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;-v = invert search
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;-x = match whole lines
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;-F = treat patterns literally (no regex)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;how-to-create-multiple-incremented-nos-directory&quot;&gt;How to create multiple incremented nos directory&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mkdir -p pre{00..14}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mkdir -p pre{00,12,13}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;keyboard-shortcuts&quot;&gt;Keyboard Shortcuts&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;code&gt;CTRL-A&lt;&#x2F;code&gt; = go to the begining of the line&lt;br &#x2F;&gt;
&lt;code&gt;CTRL-E&lt;&#x2F;code&gt; = go to the end of the line&lt;br &#x2F;&gt;
&lt;code&gt;CTRL-U&lt;&#x2F;code&gt; = delete everything till begining&lt;br &#x2F;&gt;
&lt;code&gt;CTRL-K&lt;&#x2F;code&gt; = delete everyting till end&lt;&#x2F;p&gt;
&lt;h3 id=&quot;job-control&quot;&gt;Job control&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;disown - removes the job from list of running jobs, so it doesn&#x27;t get killed when you exit the terminal, &lt;strong&gt;ensure it doesn&#x27;t write into terminal window&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;some_long_command &amp;gt; &#x2F;tmp&#x2F;log 2&amp;gt;&amp;amp;1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;CTRL-Z
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;bg
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;disown %1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nohup command&lt;&#x2F;code&gt; - same as above&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;readlink&quot;&gt;Readlink&lt;&#x2F;h3&gt;
&lt;p&gt;Get path to actual file to which a symlink points&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;readlink -f path
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;linux&#x2F;terminal&#x2F;&quot;&gt;terminal&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;shell&#x2F;vim&#x2F;&quot;&gt;vim&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Vim</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/shell/vim/"/>
        <id>https://ms-choudhary.github.io/notes/shell/vim/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/shell/vim/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;no-paste&quot;&gt;No paste&lt;&#x2F;h3&gt;
&lt;p&gt;To ignore indenting while pasting text in vim&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;:set paste
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;:set nopaste
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;open-at-line-number&quot;&gt;Open at line number&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;vim +13 &#x2F;root&#x2F;.ssh&#x2F;known_hosts
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;shell&#x2F;shell-commands&#x2F;#show-file-with-linenumber&quot;&gt;Show file with linenumber&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Slack</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/slack/slack/"/>
        <id>https://ms-choudhary.github.io/notes/slack/slack/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/slack/slack/">&lt;p&gt;Slack is a maze of endpoints, and I always get confused, how to configure a new app or change some aspect of existing custom apps. There&#x27;re so many pages titled &quot;Your apps configuration&quot;, I&#x27;ve lost my way many a time, hence, this documentation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;manage-custom-slack-apps&quot;&gt;Manage custom slack apps&lt;&#x2F;h3&gt;
&lt;p&gt;Manage your custom slack apps at URL: https:&#x2F;&#x2F;api.slack.com&#x2F;apps&#x2F;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;post-to-a-channel&quot;&gt;Post to a channel&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Create a new slack app at above endpoint&lt;&#x2F;li&gt;
&lt;li&gt;Add oauth scopes &lt;code&gt;chat:write&lt;&#x2F;code&gt; for posting new messages to channel&lt;&#x2F;li&gt;
&lt;li&gt;Generate bot token, export that as env &lt;code&gt;SLACK_TOKEN&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;C0AUQ88NCAZ&lt;&#x2F;code&gt; is channel id&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func postSlackMessage(message string) error {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	token := envOrFatal(&amp;quot;SLACK_TOKEN&amp;quot;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	client := slack.New(token)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	_, _, err := client.PostMessage(&amp;quot;C0AUQ88NCAZ&amp;quot;, slack.MsgOptionText(message, false))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	if err != nil {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		return err
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	return nil
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;func envOrFatal(key string) string {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	v := os.Getenv(key)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	if v == &amp;quot;&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;		log.Fatal(&amp;quot;missing %s&amp;quot;, key)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;	return v
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>SSH</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/ssh/ssh/"/>
        <id>https://ms-choudhary.github.io/notes/ssh/ssh/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/ssh/ssh/">&lt;h3 id=&quot;forward-tunnel&quot;&gt;Forward tunnel&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;ssh-forward-tunnel.png&quot; alt=&quot;SSH forward tunnel|600&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Service is &lt;strong&gt;running on remote server&lt;&#x2F;strong&gt;, and you&#x27;re connecting to localhost on the client.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh -L [bindaddress:]port:host:hostport target
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;eg
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh -L 8000:localhost:8000 ixdev
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;host is resolved on the target server. In this case, any request on port 8000 on the client is forwarded to localhost:8000 on ixdev.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh -L 8000:randomhost:8000 ixdev
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case, any request on port 8000 on the client is forwarded to randomhost (resolved on ixdev) via ixdev.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-this-works&quot;&gt;How this works?&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;When you run the ssh forward port-forward command, a tcp socket is open on client side for the port 8000. Nothing happens on the remote side yet.&lt;&#x2F;li&gt;
&lt;li&gt;When a new request comes for localhost:8000, it&#x27;s multiplexed on the ssh encrypted tcp connection via different channel number. (eg, channel 1 etc)&lt;&#x2F;li&gt;
&lt;li&gt;On the remote side, sshd receives handles the packets from channel 1, and forwards them to localhost:8000.&lt;&#x2F;li&gt;
&lt;li&gt;To the remote service (running on port 8000), it appears as if packet has arrived from localhost. To client service, it appears as if it&#x27;s interacting with a local service. And tunnel is invisible to both.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;reverse-tunnel&quot;&gt;Reverse Tunnel&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;_images&#x2F;ssh-reverse-tunnel.png&quot; alt=&quot;Reverse tunnel&quot; &#x2F;&gt;
Service is &lt;strong&gt;running on local client&lt;&#x2F;strong&gt;, and you&#x27;re connecting to localhost on the vm.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh -R [bindaddress:]port:host:hostport target
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh -R 8000:localhost:8000 ixdev
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Any request on port 8000 on remote VM is forwarded via secure channel to localhost:8000 running on local client. host is resolved on the local client.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-this-works-1&quot;&gt;How this works?&lt;&#x2F;h4&gt;
&lt;ul&gt;
&lt;li&gt;A tcp socket on port 8000 is open on the remote side.&lt;&#x2F;li&gt;
&lt;li&gt;Whenever any packets comes locally to 8000, it&#x27;s multiplexed via secure channel to client side.&lt;&#x2F;li&gt;
&lt;li&gt;On the client side, it proxies the packet to service running on localhost:8000&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;remote-connection-hung&quot;&gt;Remote Connection Hung&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;If your connection to remote server is hung and you can&#x27;t do anything: &lt;code&gt;Enter&lt;&#x2F;code&gt; &lt;code&gt;~&lt;&#x2F;code&gt; &lt;code&gt;.&lt;&#x2F;code&gt; This forces the client to close the connection.
&lt;ul&gt;
&lt;li&gt;This doesn&#x27;t work on nested ssh connections!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Explore how connection is established and a terminal is spawn in ssh. #question&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;storage&#x2F;sshfs&#x2F;&quot;&gt;sshfs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>dd command</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/dd/"/>
        <id>https://ms-choudhary.github.io/notes/storage/dd/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/dd/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;if &#x27;if=&#x27; not present it reads from stdin&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;if &#x27;of=&#x27; not present it writes to stdout&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;bs = block size, default 512 bytes, change to 1 byte if you want to write single byte&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;count = no. of block size bytes to write for eg if bs=1, count=4 will write 4 bytes&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;seek = &lt;strong&gt;write&lt;&#x2F;strong&gt; at seek position to block size * number&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;skip = skip block size * number while &lt;strong&gt;reading&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ printf &amp;#39;🐱&amp;#39; | dd of=&#x2F;dev&#x2F;xvd1 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ dd if=&#x2F;dev&#x2F;xvd1 count=1 2&amp;gt; &#x2F;dev&#x2F;null | hexdump -C
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ printf &amp;quot;$(dd if=&#x2F;dev&#x2F;xvd1 bs=1 count=4 2&amp;gt; &#x2F;dev&#x2F;null)\n&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ printf &amp;#39;🐱&amp;#39; | dd of=&#x2F;dev&#x2F;xvd1 bs=1 seek=4
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ printf &amp;quot;$(dd if=&#x2F;dev&#x2F;xvd1 bs=1 count=8 2&amp;gt; &#x2F;dev&#x2F;null)\n&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;storage&#x2F;sshfs&#x2F;&quot;&gt;sshfs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;virtualization&#x2F;inspect-vm-filesystem&#x2F;&quot;&gt;inspect-vm-filesystem&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;container&#x2F;containers&#x2F;&quot;&gt;containers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;os-install&#x2F;initrd&#x2F;&quot;&gt;initrd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Explore remote drive via SSHFS</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/storage/sshfs/"/>
        <id>https://ms-choudhary.github.io/notes/storage/sshfs/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/storage/sshfs/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man1&#x2F;sshfs.1.html&lt;&#x2F;p&gt;
&lt;p&gt;Lately I wanted to explore the external hard drive connected to my homelab mini pc for some photos I wanted to upload to immich.  Instead of manually unplugging and replugging the drive to my mac, I decided to use sshfs.&lt;&#x2F;p&gt;
&lt;p&gt;From the manpage,&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;SSHFS allows you to mount a remote filesystem using SSH (more precisely, the SFTP subsystem). Most SSH servers support and enable this SFTP access by default, so SSHFS is very simple to use - there&#x27;s nothing to do on the server-side.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;It is based on FUSE filesystem.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;debian-ubuntu&quot;&gt;Debian&#x2F;Ubuntu&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;apt install sshfs
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;macos&quot;&gt;MacOS&lt;&#x2F;h3&gt;
&lt;p&gt;Install Macfuse and sshfs from &lt;a href=&quot;https:&#x2F;&#x2F;macfuse.github.io&quot;&gt;macfuse&lt;&#x2F;a&gt; site. It&#x27;ll prompt to allow a system extension in system settings. Also a restart is required.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h2&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sshfs homelab:&#x2F;var&#x2F;homelab ~&#x2F;Documents&#x2F;mnt
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Loads &lt;code&gt;&#x2F;var&#x2F;homelab&lt;&#x2F;code&gt; remote dir to &lt;code&gt;~&#x2F;Documents&#x2F;mnt&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can then explore the files in finder. Finally to unmount:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;umount ~&#x2F;Documents&#x2F;mnt
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Explore fuse fs #question&lt;&#x2F;li&gt;
&lt;li&gt;This reduces the iops on the backup drive, and you&#x27;ve to remount it again #question&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;storage&#x2F;dd&#x2F;&quot;&gt;dd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;ssh&#x2F;ssh&#x2F;&quot;&gt;ssh&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Google File System</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-09-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/system-design/gfs/"/>
        <id>https://ms-choudhary.github.io/notes/system-design/gfs/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/system-design/gfs/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: &lt;a href=&quot;https:&#x2F;&#x2F;drive.google.com&#x2F;file&#x2F;d&#x2F;1gWF-JCvqmaQrJcDQBe6CSqpJnep1q96a&#x2F;view?usp=sharing&quot;&gt;Paper by Sanjay Ghemawat, Howard Gobioff, and Shun-Tak Leung Google&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Google File System (GFS) is a distributed file system developed at google. Other than conventional goals of any distributed system : performance, scalability, reliability &amp;amp; availability, its design was driven chiefly by key observations of existing workloads and usage patterns at google.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;assumptions&quot;&gt;Assumptions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;It is build mostly for commodity hardware, were failure is norm rather than exception. With hundreds of machines and thousands of disks, disk failure and data corruption happens on a daily basis. System should be tolerant towards such failures.&lt;&#x2F;li&gt;
&lt;li&gt;Bigger multi GB files are more common than smaller ones.&lt;&#x2F;li&gt;
&lt;li&gt;Files are written mostly in append only fashion. Random writes are rare. Small random writes are supported by system, but it doesn&#x27;t have to be efficient.&lt;&#x2F;li&gt;
&lt;li&gt;Files are read in large streaming in order rather than small random reads.&lt;&#x2F;li&gt;
&lt;li&gt;For performance, we need to allow multiple clients concurrently appending to the same file.&lt;&#x2F;li&gt;
&lt;li&gt;Overall data bandwidth is more important than latency. Processing data in bulk at high rate is more important than response time for each write.&lt;&#x2F;li&gt;
&lt;li&gt;Since all clients of GFS are internal to google, design was heavily biased by internal infrastructure and based on the assumption that client libraries could be developed in sync with FS APIs.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;interface&quot;&gt;Interface&lt;&#x2F;h2&gt;
&lt;p&gt;GFS doesn&#x27;t implement standard POSIX API for file system. Although it provides a familiar interface, files are organized hierarchically in directories. Standard operations allowed on the files are: create, delete, open, close, read, write &amp;amp; record append. Record append allows multiple concurrent clients to append data atomically to same file, that is, either the write is completely written in the file or not. Low cost snapshotting of a file or directory is supported.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;architecture&quot;&gt;Architecture&lt;&#x2F;h2&gt;
&lt;p&gt;GFS mainly consists of three components: single master, multiple chunkservers and multiple clients.&lt;&#x2F;p&gt;
&lt;p&gt;Files are divided into uniform sized chunks of 64 MB size, identified by immutable chunk handle. Master stores metadata, namely, files in namespace, mapping of files to chunks, and it&#x27;s location on chunk servers. Chunkservers stores the chunks locally as linux file. Chunks are replicated per region in file namespace on different chunkservers, with default replication of 3. Master periodically exchanges heart beats with chunkservers and re-replicates chunks incase of chunkserver failures. Clients implement FS API and interacts with master and chunkserver. Client fetches metadata from master, and caches it locally. It reaches out to chunkserver directly for all data communication.&lt;&#x2F;p&gt;
&lt;p&gt;GFS does not implement POSIX API, so there&#x27;s no need for integration with linux v-node. Chunks are stored locally as linux files and OS buffer cache suffices the caching needs. No additional data caches are maintained either on client or chunkserver.&lt;&#x2F;p&gt;
&lt;p&gt;Client caches the metadata information for short interval, till expiry or file gets reopened. Since chunksize is fixed, client calculates chunk index based on filename and offset. Master sends chunk handle &amp;amp; locations of all replicas which contain the chunk. For reads, client reaches out to closed replica. For performance reasons, client can request information about multiple chunks in the same request. Master generally sends information about subsequent chunks in the same response.&lt;&#x2F;p&gt;
&lt;p&gt;Chunks are stored as 64 MB size plain linux file, which is larger than traditional file system. To make efficient use of disk, it&#x27;s space is allocated lazily (lazy space allocation), ie, space is not allocated on disk if there&#x27;s no data. There are many advantages of using a big chunk size - there&#x27;s less interaction with master, persistent TCP connection with chunkserver, instead of frequently connecting new chunkservers, size of metadata on master is small, and clients themselves can cache multi TB file metadata in memory easily.&lt;&#x2F;p&gt;
&lt;p&gt;One major disadvantage of using big block is, if there is a small file (size less than chunksize), it could face contention if multiple clients request the same file. In general, this is not the common, since files generally span multiple chunks, and client streams data from multiple servers. A way to mitigate could be to increase replication of such files, so request could span to different chunkservers and distribute load.&lt;&#x2F;p&gt;
&lt;p&gt;There is single master, which stores all it&#x27;s metadata in memory. Metadata stored by master includes:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Mutations to file namespace&lt;&#x2F;li&gt;
&lt;li&gt;Mapping of files to chunks&lt;&#x2F;li&gt;
&lt;li&gt;Mapping of chunks to location of chunk replicas
The first two are persisted to disk as operational log (WAL). Last one is not persisted to disk, but fetched on startup and everytime a chunkserver rejoins. The reason for this is, a chunkserver has sole ownership over which chunks it has locally. Chunks could get corrupted or disks could fail, and keeping this info in sync with master is futile.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Storing metadata in memory allows master to do quick scans for various needs. And also serialize critical operations.&lt;&#x2F;p&gt;
&lt;p&gt;Limitation is that file system is limited by how much data can be stored in RAM. In reality, data stored is effectively compressed, only 64B is stored per 64MB chunk. And it&#x27;s not a serious limitation. And RAM can be increased very easily if required.&lt;&#x2F;p&gt;
&lt;p&gt;For fault tolerance, master&#x27;s operational logs are replicated on remote server as well. And each request is successfully only if log was written on all the servers.  In case of master failures, we can easily promote any of these servers as master, since they have the same data. To minimize the startup time, logs are checkpointed in background, so that on restart, it just have to read logs from last checkpoint. Checkpoints are B+ tree, which can be directly mapped to memory.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;guarantees&quot;&gt;Guarantees&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;strong&gt;Consistent&lt;&#x2F;strong&gt;: a file region is said to be consistent if all client read the same data from all replicas
&lt;strong&gt;Defined&lt;&#x2F;strong&gt;: a file region is said to be defined if after mutation, the file is consistent and has the mutation performed entirely&lt;&#x2F;p&gt;
&lt;p&gt;Guarantees provided by GFS:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Writes by single client are defined&lt;&#x2F;li&gt;
&lt;li&gt;Concurrent writes by multiple clients are consistent (same data on all replicas), but can be undefined (writes by other clients can be interleaved in between)&lt;&#x2F;li&gt;
&lt;li&gt;Failed writes make the region inconsistent (different replicas may store different data). Leads to data duplication.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All replicas must write the record at same offset for the operation to be success.&lt;&#x2F;p&gt;
&lt;p&gt;The onus on recovering from failed write is on client. Client can retry again, but the data may get duplicated. On reads, client has to account for:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;extra space, padding&lt;&#x2F;li&gt;
&lt;li&gt;duplicate records (if write fails)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each record written contains checksum, so client can recover from such failures.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;leases&quot;&gt;Leases&lt;&#x2F;h2&gt;
&lt;p&gt;For writes, master grants a lease (expiry 60s) to one of the replica (primary), the serial order of writes to be applied is decided by primary replica. The expiry of lease is 60s, but replica can extend it indefinitely by piggybacking on heartbeat call. Master can revoke lease before it expires, for eg, when doing snapshotting to ensure no writes happen.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sequence-diagram&quot;&gt;Sequence Diagram&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Client requests master for replicas (including lease owner) of a chunk. If no lease owner found, master grants lease to a replica.&lt;&#x2F;li&gt;
&lt;li&gt;Client caches the metadata provided for a short interval&lt;&#x2F;li&gt;
&lt;li&gt;Client pushes data to nearest replica, which in turn pushes data to next closest replica and so on.&lt;&#x2F;li&gt;
&lt;li&gt;Once all replicas acks that data is received, client sends write request to primary. Request identifies data written earlier. Primary assigns serial order all writes (can be from multiple clients), it applies mutations in that order.&lt;&#x2F;li&gt;
&lt;li&gt;Primary requests secondaries to apply mutation in same serial order&lt;&#x2F;li&gt;
&lt;li&gt;Secondaries responds write completed.&lt;&#x2F;li&gt;
&lt;li&gt;Primary replies to client, Any error encountered is propagated to client, and means write has failed. Client can retry the failed mutation again.&lt;&#x2F;li&gt;
&lt;li&gt;If mutation will overstep the current chunks boundary, primary pads the current chunk with space. It instructs the secondaries to do the same. And returns client to retry again with new chunk.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;data-flow&quot;&gt;Data flow&lt;&#x2F;h2&gt;
&lt;p&gt;Data and control requests are separated, as the goal is to fully utilize the available bandwidth. Machines have full duplex, allowing them to send and receive at the same time at rate without any throttling. TCP pipelining is used, to start sending immediately the data is received instead of waiting for whole record to be received.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;snapshot&quot;&gt;Snapshot&lt;&#x2F;h2&gt;
&lt;p&gt;GFS provides ability to take a quick snapshot of a file or directory. Uses the copy on write technique. When a snapshot is requested:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Master revokes all leases for the chunks, to prevent any further writes&lt;&#x2F;li&gt;
&lt;li&gt;Duplicates the metadata, pointing to the same chunks&lt;&#x2F;li&gt;
&lt;li&gt;Master intercepts any writes on the region performs clone operation. It instructs the replicas to clone C to C&#x27; locally. Since data is copied locally rather than over network, this is highly performant.&lt;&#x2F;li&gt;
&lt;li&gt;Any changes are handled in usual fashion&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;master-operations&quot;&gt;Master Operations&lt;&#x2F;h2&gt;
&lt;p&gt;Unlike traditional FS, GFS does not maintain per dir data structure. It maintains a global lookup table, mapping a path to metadata. Read write locks per path node are used to serialize operations. For eg, if reading &lt;code&gt;&#x2F;d1&#x2F;d2...&#x2F;dn&#x2F;leaf&lt;&#x2F;code&gt;, it acquires, read locks on d1 to dn and write lock on leaf. Read lock prevents node deletion, renaming or snapshoting. This way master can be highly concurrent and work on multiple requests simulatenously. To prevent deadlocks, locks are acquired in same order in ns tree &amp;amp; lexicographical at same level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;replica-placement&quot;&gt;Replica Placement&lt;&#x2F;h2&gt;
&lt;p&gt;For new replicas, chunkservers which has below average disk space are chosen. This equalizes disk utilization for the whole cluster. Servers are distributed over mutiple racks, to account for power and switch failures on a rack. On chunk server failures, master rereplicates the chunks on new servers, instructs them to clone from primary. Master does periodic rebalancing to keep cluster in good shape.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;garbage-collection&quot;&gt;Garbage Collection&lt;&#x2F;h2&gt;
&lt;p&gt;When a file or dir, is deleted:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;master logs the operation&lt;&#x2F;li&gt;
&lt;li&gt;file is renamed to a hidden file with deletion timestamp&lt;&#x2F;li&gt;
&lt;li&gt;during regular scan, it removes metadata for hidden files older than 3 days&lt;&#x2F;li&gt;
&lt;li&gt;On every heartbeat, chunkserver, replies the chunks it has. Master replies chunks that are free to be deleted.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each chunk has a version number. The highest version is considered up to date. All other stale replicas are gc&#x27;d.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;high-availability&quot;&gt;High Availability&lt;&#x2F;h2&gt;
&lt;p&gt;Master logs are replicated on remote servers for each request. Due to checkpointing, master can be restarted within seconds. If machine&#x2F;disk failure happen, a new master can be started on one of the remote servers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-integrity&quot;&gt;Data Integrity&lt;&#x2F;h2&gt;
&lt;p&gt;Each 64 KB block in chunk is checksummed. If chunkserver detects corruption, it doesn&#x27;t propagate the corrupted data, and reports error.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;storage&#x2F;linux-file-io-buffering&#x2F;&quot;&gt;linux-file-io-buffering&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Configuring systemd-resolved for DNS</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/systemd/configuring-systemd-resolved-for-dns/"/>
        <id>https://ms-choudhary.github.io/notes/systemd/configuring-systemd-resolved-for-dns/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/systemd/configuring-systemd-resolved-for-dns/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Install&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;apt install systemd-resolved
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Global options &lt;code&gt;&#x2F;etc&#x2F;systemd&#x2F;resolved.conf&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;DNS=1.1.1.1 100.100.100.100
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Domains=taildace6.ts.net
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;DNSStubListener=no
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Symlink &lt;code&gt;&#x2F;run&#x2F;systemd&#x2F;resolve&#x2F;stub-resolv.conf&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;etc&#x2F;resolv.conf&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ln -s &#x2F;run&#x2F;systemd&#x2F;resolve&#x2F;stub-resolv.conf &#x2F;etc&#x2F;resolv.conf
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;Restart systemd-resolved&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl restart systemd-resolved
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;What&#x27;s the difference between different types of dns configuration tools in linux? #question
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;tailscale.com&#x2F;blog&#x2F;sisyphean-dns-client-linux&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;What are the implications of setting dns config via systemd? #question
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man8&#x2F;systemd-resolved.service.8.html&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>For each and count meta argument</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/terraform/for-each-count-meta-argument/"/>
        <id>https://ms-choudhary.github.io/notes/terraform/for-each-count-meta-argument/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/terraform/for-each-count-meta-argument/">&lt;p&gt;Ideally each block maps to one infrastructure component. There&#x27;re two ways to create map multipe by just one block.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;count&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;resource &amp;quot;aws_instance&amp;quot; &amp;quot;server&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  count = 4 # create four similar EC2 instances
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  ami           = &amp;quot;ami-a1b2c3d4&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  instance_type = &amp;quot;t2.micro&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  tags = {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    Name = &amp;quot;Server ${count.index}&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;for_each&lt;&#x2F;code&gt; - accepts a map, list or set&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;resource &amp;quot;azurerm_resource_group&amp;quot; &amp;quot;rg&amp;quot; {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  for_each = tomap({
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    a_group       = &amp;quot;eastus&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    another_group = &amp;quot;westus2&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  })
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  name     = each.key
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  location = each.value
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Networking Modes in UTM</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/utm/networking-modes-in-utm/"/>
        <id>https://ms-choudhary.github.io/notes/utm/networking-modes-in-utm/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/utm/networking-modes-in-utm/">&lt;p&gt;You can run apple virtualization VMs in two networking modes on UTM:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Bridged networking
&lt;ul&gt;
&lt;li&gt;This adds the VM on the same network as your mac, although this works, there&#x27;re few problems:
&lt;ul&gt;
&lt;li&gt;if you&#x27;re connected to wifi, mac bridge might silently drop ARP packets leading to lossed connectivity intermittently.&lt;&#x2F;li&gt;
&lt;li&gt;You&#x27;re now dependent on the wifi, if you disconnect wifi, you mysteriously lose connectivity&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Shared networking
&lt;ul&gt;
&lt;li&gt;despite what this name suggest, you cannot reach VM1 to VM2&lt;&#x2F;li&gt;
&lt;li&gt;adding forwarding config on mac doesn&#x27;t work&lt;&#x2F;li&gt;
&lt;li&gt;and this is how this is supposed to be, refs:
&lt;ul&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;utmapp&#x2F;UTM&#x2F;issues&#x2F;4448&lt;&#x2F;li&gt;
&lt;li&gt;https:&#x2F;&#x2F;github.com&#x2F;utmapp&#x2F;UTM&#x2F;issues&#x2F;6975&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;This needs more details to trust the information listed. #question&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;networking&#x2F;container-networking&#x2F;#how-connection-works-for-two-containers-on-same-host&quot;&gt;How connection works for two containers on same host?&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Taking VM snapshots in UTM</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/utm/taking-vm-snapshots-in-utm/"/>
        <id>https://ms-choudhary.github.io/notes/utm/taking-vm-snapshots-in-utm/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/utm/taking-vm-snapshots-in-utm/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;h3 id=&quot;snapshots&quot;&gt;Snapshots&lt;&#x2F;h3&gt;
&lt;p&gt;You can locate the UTM data disk for a VM: &lt;code&gt;~&#x2F;Library&#x2F;Containers&#x2F;com.utmapp.UTM&#x2F;Data&#x2F;Documents&#x2F;Linux.utm&#x2F;Data&lt;&#x2F;code&gt;, which is generally a qcow2 image.&lt;&#x2F;p&gt;
&lt;p&gt;Take a snapshot with compression:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;qemu-img snapshot F89035CE-DEF9-49D7-97F8-7EC0C2F3F9D9.qcow2 -c snapshot1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;qemu-img snapshot F89035CE-DEF9-49D7-97F8-7EC0C2F3F9D9.qcow2 -l
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To revert back the disk:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;qemu-img snapshot F89035CE-DEF9-49D7-97F8-7EC0C2F3F9D9.qcow2 -a snapshot1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;virtualization&#x2F;inspect-vm-filesystem&#x2F;&quot;&gt;inspect-vm-filesystem&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Inspect VM filesystem</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/virtualization/inspect-vm-filesystem/"/>
        <id>https://ms-choudhary.github.io/notes/virtualization/inspect-vm-filesystem/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/virtualization/inspect-vm-filesystem/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;linux.die.net&#x2F;man&#x2F;1&#x2F;guestfish&lt;&#x2F;p&gt;
&lt;p&gt;To inspect files inside VM disk (qcow2, img or other kinds), install guestfish:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;apt install libguestfs-tools
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;guestfish 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;gt; add-ro debian.qcow2
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;gt; run
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;&amp;gt; help mount-ro
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Type help gives you what you should do next. You can copy files to host via &lt;code&gt;copy-out &#x2F;file&#x2F;in&#x2F;qcow2 &#x2F;host&#x2F;dir&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;There&#x27;s a way to install os by using qcow2 image (without running the installer). How does that work? #question&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;storage&#x2F;dd&#x2F;&quot;&gt;dd&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;utm&#x2F;taking-vm-snapshots-in-utm&#x2F;&quot;&gt;taking-vm-snapshots-in-utm&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>qemu-guest-agent</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/virtualization/qemu-guest-agent/"/>
        <id>https://ms-choudhary.github.io/notes/virtualization/qemu-guest-agent/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/virtualization/qemu-guest-agent/">&lt;p&gt;qemu-guest-agent runs inside VM, and basically is a communication channel between host and guest. It enables things like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Set guests system time&lt;&#x2F;li&gt;
&lt;li&gt;Get information from the guests&lt;&#x2F;li&gt;
&lt;li&gt;Read&#x2F;write file&lt;&#x2F;li&gt;
&lt;li&gt;Sync&#x2F;freeze filesystems&lt;&#x2F;li&gt;
&lt;li&gt;Suspend guests&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It uses a virtio-serial channel, ie, a virtual serial port exposed to guest as a character device, this by passes the normal network stack entirely. On hosts side this is exposed as unix domain socket.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;qemu-guest-agent-configuration-sample&quot;&gt;qemu-guest-agent configuration sample&lt;&#x2F;h3&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;[general]
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;daemonize = 0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;pidfile = &#x2F;var&#x2F;run&#x2F;qemu-ga.pid
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;verbose = 0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;method = virtio-serial
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;path = &#x2F;dev&#x2F;virtio-ports&#x2F;org.qemu.guest_agent.0
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;statedir = &#x2F;var&#x2F;run
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;[[]]&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to read a paper</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/writing/how-to-read-paper/"/>
        <id>https://ms-choudhary.github.io/notes/writing/how-to-read-paper/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/writing/how-to-read-paper/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: Paper: &lt;a href=&quot;https:&#x2F;&#x2F;drive.google.com&#x2F;file&#x2F;d&#x2F;1h64i39ioSkV8kXbZBQ1hvf25c5DDv74v&#x2F;view?usp=share_link&quot;&gt;How to read a paper&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-you-should-read-research-papers&quot;&gt;Why you should read research papers&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;To keep up to date with latest developments in your field&lt;&#x2F;li&gt;
&lt;li&gt;Generally a great learning, enhances your system design skills, and help you become more creative problem solver&lt;&#x2F;li&gt;
&lt;li&gt;Do a literature survey of new field you&#x27;re interested in&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;three-pass-approach&quot;&gt;Three pass approach&lt;&#x2F;h2&gt;
&lt;p&gt;Instead of reading a research paper end to end, consider reading it in passes to grasp the most out of it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;first-pass&quot;&gt;First Pass&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Generally takes 5-10 mins&lt;&#x2F;li&gt;
&lt;li&gt;Gives a high level overview of what it&#x27;s about and helps you decide if it&#x27;s really worth your time&lt;&#x2F;li&gt;
&lt;li&gt;First, carefully read abstract &amp;amp; introduction&lt;&#x2F;li&gt;
&lt;li&gt;Read section &amp;amp; sub-section headings, glance at figures, ignore everything else&lt;&#x2F;li&gt;
&lt;li&gt;Read conclusion&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;second-pass&quot;&gt;Second pass&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Should take about an hour or so&lt;&#x2F;li&gt;
&lt;li&gt;Read much more carefully this time, highlighting what you think are the main points. Also free free to add comments&#x2F;notes in the margin.&lt;&#x2F;li&gt;
&lt;li&gt;You can chose to ignore the proofs&lt;&#x2F;li&gt;
&lt;li&gt;After this, you should be able to summarize what the paper is about&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;second-and-half-pass&quot;&gt;Second and half pass&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;Re-read your highlights from previous step, take hand written notes of what you think are the main points&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;third-pass&quot;&gt;Third pass&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;(Use your notes rather than paper itself)&lt;&#x2F;li&gt;
&lt;li&gt;Virtually reimplement the paper, that is, making same assumptions as author try to recreate the work&lt;&#x2F;li&gt;
&lt;li&gt;Identify and challenge each assumption in every statement&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;literature-survey&quot;&gt;Literature survey&lt;&#x2F;h2&gt;
&lt;p&gt;Some tips on finding important papers in a field:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Start with public search engines (google research or arxiv), based on key-words find 3-5 recent papers&lt;&#x2F;li&gt;
&lt;li&gt;From the references, find shared citations &amp;amp; repeated authors, these are key research papers &amp;amp; researchers in the area&lt;&#x2F;li&gt;
&lt;li&gt;Go to the researchers website, find the conferences where they published their work&lt;&#x2F;li&gt;
&lt;li&gt;Go to conferences website, it should contain list of important papers&lt;&#x2F;li&gt;
&lt;li&gt;Iterate&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;writing&#x2F;how-to-take-smart-notes&#x2F;&quot;&gt;how-to-take-smart-notes&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;writing&#x2F;tips-on-technical-writing&#x2F;&quot;&gt;tips-on-technical-writing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to take smart notes</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/writing/how-to-take-smart-notes/"/>
        <id>https://ms-choudhary.github.io/notes/writing/how-to-take-smart-notes/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/writing/how-to-take-smart-notes/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: Book: &lt;a href=&quot;https:&#x2F;&#x2F;read.amazon.in&#x2F;?asin=B09V5M8FR5&amp;amp;ref_=kwl_kr_iv_rec_1&quot;&gt;How to take smart notes - Sönke Ahrens&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Always keep a slip of paper, or your trusted pocket notebook, and a pen with you whenever you&#x27;re either&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reading an article, book etc&lt;&#x2F;li&gt;
&lt;li&gt;In a meeting&lt;&#x2F;li&gt;
&lt;li&gt;Working on a project&lt;&#x2F;li&gt;
&lt;li&gt;Etc
And take a note of any worthwhile idea you come across. On the back of that note, write the reference details (for eg, page x in book, or article etc).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Notes should be taken in a handwritten form, in your own words. Target brevity, just jot down few keywords that&#x27;ll help you reconstruct it later on when you add permanent notes. Hand writing notes help here, since you&#x27;re limited by the speed. Copying or highlighting text digitally is less effective, since you take the text out of the context, and it might not strengthen your understanding the way handwriting does.&lt;&#x2F;p&gt;
&lt;p&gt;Next go through your handwritten notes, preferably daily, before you start losing context and start forgetting it. And convert them into permanent notes with full details and necessary context, so that when you comeback to it in future ignorant of what it is, you can still understand them. Note that your note is written from your point of view. People with different interest read same text with different views and focus on different things. That&#x27;s fine and exactly how it should be.&lt;&#x2F;p&gt;
&lt;p&gt;Your note should discuss one idea&#x2F;thing at a time. Keep the note concise so it ideally fits on a single screen.&lt;&#x2F;p&gt;
&lt;p&gt;Reflect on the note, and try to find connections with your other existing notes in your notebook. Think about questions and problems to which this note contributes. Ask things which are not stated. Try to find contradictions. Your notebook isn&#x27;t an archival system where you just dump things and forget, instead make it your thinking. Do you really understand the thing at hand? Try to explain it in your own words. Look for things you can&#x27;t explain. That&#x27;s your feedback, work on that. Also connect it with your other notes. Have a dialogue with your notebook. Your focus should be on understanding.&lt;&#x2F;p&gt;
&lt;p&gt;For adding keywords&#x2F;tags, instead of picking it from the text, use a topic your working on or interested in. It should reflect the circumstances will you stumble on this note.&lt;&#x2F;p&gt;
&lt;p&gt;Add links, on the note to other relevant notes, also on other notes linking back to this one. These interlinks is how you should discover information&#x2F;connections.&lt;&#x2F;p&gt;
&lt;p&gt;Add a index entry if needed, which acts as entrypoint to your notes about a topic. You shouldn&#x27;t add every note to index, instead just 3-4 notes. And then you discover other information through interlinks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;writing&#x2F;how-to-read-paper&#x2F;&quot;&gt;how-to-read-paper&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;writing&#x2F;tips-on-technical-writing&#x2F;&quot;&gt;tips-on-technical-writing&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Some tips on technical writing</title>
        <published>2026-08-19T00:00:00+00:00</published>
        <updated>2026-08-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://ms-choudhary.github.io/notes/writing/tips-on-technical-writing/"/>
        <id>https://ms-choudhary.github.io/notes/writing/tips-on-technical-writing/</id>
        
        <content type="html" xml:base="https://ms-choudhary.github.io/notes/writing/tips-on-technical-writing/">&lt;p&gt;&lt;strong&gt;Source&lt;&#x2F;strong&gt;: https:&#x2F;&#x2F;www.netmeister.org&#x2F;book&#x2F;principles-of-system-administration.pdf&lt;&#x2F;p&gt;
&lt;p&gt;Writing is communication. And in tech field, it is one of the crucial skills to master. If you want to share your ideas to wider audience, you need to write blogs, write proposals for conferences, and publish technical papers.&lt;&#x2F;p&gt;
&lt;p&gt;There are two fundamental questions that needs to be asked, before you start writing:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Who your audience will be&lt;&#x2F;li&gt;
&lt;li&gt;What you wish to communicate (What is your objective)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Other things (like structure and content) generally follow these decisions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;know-your-audience&quot;&gt;Know your audience&lt;&#x2F;h2&gt;
&lt;p&gt;Technical writing is in some sense similar to software engineering, just like you need to understand the who the users for your product will be, you need to know your audience will be.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the times the audience is our future selves. Where documentation written today serves as a point of reference in future.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s always better to state the assumptions made before hand. And not place any assumption on reader&#x27;s prior knowledge.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;online-documentation&quot;&gt;Online Documentation&lt;&#x2F;h2&gt;
&lt;p&gt;Most of the stuff we write is meant to be read online in a web browser. There are certain tendencies in web readers, they generally tend to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;skim through the content&lt;&#x2F;li&gt;
&lt;li&gt;extract the important parts&lt;&#x2F;li&gt;
&lt;li&gt;ignore the rest&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In such cases, you should jump to heart of matter quickly. Keep the sentences short. And use lots of smaller paragraphs rather than a lengthy blocks, generally it doesn&#x27;t put a lot of cognitive load on the reader. Make good use of sections with appropriate headings, bullet points etc.&lt;&#x2F;p&gt;
&lt;p&gt;Resist the temptation to use illustrations, they should be used as supplements rather than for information. If you are struggling to explain the concept in simpler understandable terms, maybe you do not understand it properly.&lt;&#x2F;p&gt;
&lt;p&gt;If you find it complex to explain something, follow a similar approach to programming and break it into multiple smaller parts. And try to explain each of them individually.&lt;&#x2F;p&gt;
&lt;p&gt;Some in general tips,&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;if you&#x27;re documenting command invocation, it&#x27;s good idea to include actual command and it&#x27;s output rather than fictiously fabricated one.&lt;&#x2F;li&gt;
&lt;li&gt;if you&#x27;re writing a FAQ style document, include questions which your reader might want to ask, rather than what you think they might ask.&lt;&#x2F;li&gt;
&lt;li&gt;for project README, it&#x27;s good to include:
&lt;ul&gt;
&lt;li&gt;Short summary of what the tool does&lt;&#x2F;li&gt;
&lt;li&gt;Installation steps&lt;&#x2F;li&gt;
&lt;li&gt;Example invocations with expected output&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;questions&quot;&gt;Questions&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;related&quot;&gt;Related&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;writing&#x2F;how-to-read-paper&#x2F;&quot;&gt;how-to-read-paper&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;ms-choudhary.github.io&#x2F;notes&#x2F;writing&#x2F;how-to-take-smart-notes&#x2F;&quot;&gt;how-to-take-smart-notes&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
</feed>
