<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="http://surajms.com/feed.xml" rel="self" type="application/atom+xml" /><link href="http://surajms.com/" rel="alternate" type="text/html" /><updated>2026-02-06T10:49:45+00:00</updated><id>http://surajms.com/feed.xml</id><title type="html">Devbytes</title><subtitle>BITS AND BYTES FUEL THE LIFE DRIVE</subtitle><author><name>Suraj Shirvankar</name><email></email></author><entry><title type="html">Google Summer of Code 2024</title><link href="http://surajms.com/2024/11/gsoc2024/" rel="alternate" type="text/html" title="Google Summer of Code 2024" /><published>2024-11-02T12:50:00+00:00</published><updated>2024-11-02T12:50:00+00:00</updated><id>http://surajms.com/2024/11/gsoc2024</id><content type="html" xml:base="http://surajms.com/2024/11/gsoc2024/"><![CDATA[<p>Mentors: Jonathan Balkind and Nils Wistoff <br />
Organization:  Free and Open Source Silicon Foundation <br />
Project Page: <a href="https://fossi-foundation.org/gsoc/gsoc24-ideas#architectural-improvements-to-openpitonariane">https://fossi-foundation.org/gsoc/gsoc24-ideas</a></p>

<h3 id="synopsis">Synopsis</h3>

<p>The growing demand for High-Performance Computing (HPC) requires open-source solutions to meet modern application performance needs. Different open-source architecture frameworks have been developed by the community, such as OpenPiton. However, these frameworks often have performance limitations that hinder their ability to execute compute-intensive tasks.</p>

<p>OpenPiton is an open-source noc designed for many-core processors, which is compatible with different core architectures (RISC-V 32-bit, RISC-V 64-bit, x86, and SPARCv9).In this work, we will focus on implementing the RISC-V cache management operation (CMO) extensions.</p>

<p>The architecture of OpenPiton comprises one chipset and one or more tiles. The chipset houses modules used to communicate the tiles with the peripherals, such as the UART. The tile is used to build the mesh for many-core designs. In these designs, the tiles are interconnected by three NoC routers to generate the mesh. Each tile comprises the three NoC routers, the Ariane core, and the cache hierarchy, which consists of private L1 data and instruction caches, a private L1.5 cache, and a shared distributed L2 cache.</p>

<h3 id="project-idea">Project Idea</h3>
<p>The project aims to integrate RISC-V Cache Management Operation (CMO) extensions into the OpenPiton processor framework. This integration will improve cache coherency and management, resulting in enhanced performance and efficiency for systems built on the OpenPiton platform. The project will involve understanding the RISC-V CMO specifications, modifying the OpenPiton cache subsystem, and extensive testing to ensure compatibility and performance improvements.</p>

<p><img src="/wp-contents/uploads/2024/11/openpiton_ariane_blockdiag.png" alt="OpenPiton diagram" /></p>

<h4 id="cmo-operations">CMO operations:</h4>
<ul>
  <li>
    <p>Cache Clean: (cbo.clean) Writes back modified data to the main memory but retains the cache entries. This ensures data coherence between the cache and main memory without discarding the cache contents.</p>
  </li>
  <li>
    <p>Cache Flush:(cbo.flush) Involves writing back all modified (dirty) data from the cache to the main memory and invalidating (clearing) the cache entries.</p>
  </li>
  <li>
    <p>Cache Invalidate: (cbo.inval) Marks cache entries as invalid without writing back any modified data.</p>
  </li>
</ul>

<h4 id="progress-report">Progress Report</h4>
<ul>
  <li>
    <p>Update Ariane to the latest version <a href="https://github.com/h0lyalg0rithm/cva6/tree/make_it_work">Link</a></p>

    <p>The goal is to update the ariane version to the latest version.Ariane/CVA6 is updated regularly and the new version has changed the interfaces which between the cache subsystem.I had to update the l1.5 adapter to conform to the new interface.</p>
  </li>
  <li>Support write-through cache</li>
  <li>
    <p>CMO core fsm <a href="https://github.com/h0lyalg0rithm/openpiton/tree/rvcmo_upstream">Link</a></p>

    <p>Created a new functional unit which is responsible to handle the different CMO instructions and ensure that correct signals are generated and sent to the cache.</p>
  </li>
  <li>Forward CMO request to L1.5 cache</li>
  <li>
    <p>Forward CMO request from L1.5 to L2 cache</p>

    <p>Setup additional encoding/decoding of cmo requests to identify and apply it on the caches.</p>
  </li>
  <li>
    <p>Receive return signal from l1.5 to core cache</p>

    <p>Update core cache based on the return signal from the L1.5 cache</p>
  </li>
</ul>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[Mentors: Jonathan Balkind and Nils Wistoff Organization: Free and Open Source Silicon Foundation Project Page: https://fossi-foundation.org/gsoc/gsoc24-ideas]]></summary></entry><entry><title type="html">Autoupdate bricked my phone</title><link href="http://surajms.com/2024/02/autoupdate-bricked-my-phone/" rel="alternate" type="text/html" title="Autoupdate bricked my phone" /><published>2024-02-02T16:22:00+00:00</published><updated>2024-02-02T16:22:00+00:00</updated><id>http://surajms.com/2024/02/autoupdate-bricked-my-phone</id><content type="html" xml:base="http://surajms.com/2024/02/autoupdate-bricked-my-phone/"><![CDATA[<p>Starting from this year I decided not to spend time building and running my own infrastructure.
Until the end of Jan 2023 I would always build the rom from scratch rather than depending on the maintainer to release a new build of the rom.</p>

<p>Today morning I allowed my phone to be updated to the latest build of ArrowOS, what I didnt know was that it was an automatic monthly build.This ended up bricking my phone.</p>

<p><img src="/wp-contents/uploads/2024/02/phone_dead.gif" alt="My phone is dead" /></p>

<p>My first action was trying to revert it back to an older build.Checking the ArrowOS download website for previous builds, resulted in nothing.Looks like older build links were removed from the website. I checked my machine for an older build and I found one however do the mismatch in the security patch level prevented recovery from sideloading the older build.</p>

<p>Looking on the telegram group, I didnt see much activity from the maintainer. I decided to pull up my sleeves and built the rom from scratch.
This time I setup a machine on <a href="https://clouding.io">clouding.io</a>, they are a local(Spain) cloud hosting service which is fairly priced.The best part about them is that they have fast NVMe disks, must have for building roms and their snapshot pricing is much lower than others even 5-10x cheaper than the big guys like Google, DigitalOcean etc.</p>

<p>I ended up building the rom, I removed the offending commit which resulted in the issue.Seems like those commits did not have any side-effects as I am running the rom now without any issues.</p>

<p>One of the reasons to write this post was to document my steps so I dont need to spend as much time.</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre># Install bare essentials
sudo apt-get update
sudo apt install -y git jq

git config --global user.email &quot;surajshirvankar@gmail.com&quot;
git config --global user.name &quot;Suraj Shirvankar&quot;


# Install scripts has all of the AOSP depedencies
cd ~/
git clone https://github.com/akhilnarang/scripts
cd scripts
./setup/android_build_env.sh

# Create bin file to download repo
mkdir -p ~/bin
# fetch repo from google
curl https://storage.googleapis.com/git-repo-downloads/repo &gt; ~/bin/repo
chmod a+x ~/bin/repo
</pre></div>
</div>
</div>
<p>Need to add repo to the search path</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>if [ -d &quot;$HOME/bin&quot; ] ; then
    PATH=&quot;$HOME/bin:$PATH&quot;
fi
</pre></div>
</div>
</div>
<p>Time to fetch all the code</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>mkdir arrow
cd arrow
# Depth reduces disk and network requirements by fetching only the latest commit
repo init --depth=1 -u https://github.com/ArrowOS/android_manifest.git -b arrow-13.1
# Download all of the git repos. Takes some time
repo sync -c -j$(nproc --all) --force-sync --no-clone-bundle --no-tags
source build/envsetup.sh

# Fetch relevant device repos.Python script might fail
lunch arrow_apollo-userdebug
</pre></div>
</div>
</div>
<p>Since the script failed for me I had to manually comment out the offending lines from 202 to 207</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>         if exists_in_tree(mlm, repo_target) != None:
             existing_m_project = exists_in_tree(mlm, repo_target)
         elif exists_in_tree(arrowm, repo_target) != None:
             existing_m_project = exists_in_tree(arrowm, repo_target)
         elif exists_in_tree(halm, repo_target) != None:
             existing_m_project = exists_in_tree(halm, repo_target)
</pre></div>
</div>
</div>

<p>Since the repo configuration was built for the maintainer he had decided to use repo which were private and only visible to him.Device specific repos are stored in the <code>.repo/local_manifests/roomservice.xml</code>.We can change them in this file to point to my repos.</p>

<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;manifest&gt;
  &lt;project path=&quot;device/xiaomi/apollo&quot; remote=&quot;ArrowOS-Devices&quot; name=&quot;android_device_xiaomi_apollo&quot; revision=&quot;arrow-13.1&quot; /&gt;
  &lt;project path=&quot;device/xiaomi/sm8250-common&quot; remote=&quot;github&quot; name=&quot;ArrowOS-Devices/android_device_xiaomi_sm8250-common&quot; revision=&quot;arrow-13.1-apollo&quot; /&gt;
  &lt;project path=&quot;vendor/xiaomi&quot; remote=&quot;github&quot; name=&quot;ArrowOS-Devices/android_vendor_xiaomi_apollo&quot; revision=&quot;arrow-13.1&quot; /&gt;
  &lt;project path=&quot;kernel/xiaomi/sm8250&quot; remote=&quot;github&quot; name=&quot;PixelExperience-Devices/kernel_xiaomi_sm8250&quot; revision=&quot;thirteen&quot; /&gt;
  &lt;project path=&quot;hardware/xiaomi&quot; remote=&quot;github&quot; name=&quot;Dobsgw/android_hardware_xiaomi&quot; revision=&quot;arrow-13.1&quot; /&gt;
  &lt;project path=&quot;packages/apps/GCamGOPreBuilt&quot; remote=&quot;github&quot; name=&quot;ArrowOS-Devices/android_packages_apps_GCamGOPrebuilt&quot; revision=&quot;arrow-13.1&quot; /&gt;
  &lt;project path=&quot;vendor/xiaomi-firmware/apollo&quot; remote=&quot;gitlab&quot; name=&quot;h0lyalg0rithm/vendor_xiaomi-firmware_apollo&quot; revision=&quot;arrow-13.1&quot; /&gt;
&lt;/manifest&gt;

</pre></div>
</div>
</div>
<p>The configuration about the build is present in <code>vendor/arrow/config/version.mk</code>.Here is where you can setup the build config like including google apps, updater etc</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre># Time to build the rom
repo sync -c -j48 --force-sync --no-clone-bundle --no-tags
export ARROW_GAPPS=true
export ARROW_OFFICIAL=true
# You should see the build file name(ARROW_VERSION) contain OFFICIAL and GAPPS
lunch arrow_apollo-userdebug
mka bacon -j60 # This machine is pretty beafy
</pre></div>
</div>
</div>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[Starting from this year I decided not to spend time building and running my own infrastructure. Until the end of Jan 2023 I would always build the rom from scratch rather than depending on the maintainer to release a new build of the rom.]]></summary></entry><entry><title type="html">Using LD_PRELOAD to hijack library calls</title><link href="http://surajms.com/2024/01/using-ld-preload-to-hijack-library-calls/" rel="alternate" type="text/html" title="Using LD_PRELOAD to hijack library calls" /><published>2024-01-20T22:02:00+00:00</published><updated>2024-01-20T22:02:00+00:00</updated><id>http://surajms.com/2024/01/using-ld-preload-to-hijack-library-calls</id><content type="html" xml:base="http://surajms.com/2024/01/using-ld-preload-to-hijack-library-calls/"><![CDATA[<p>My masters project was based on writing a allocator which would allocate memory to either the DRAM or a persistent memory device(Intel Optane), which is controlled at compile time.It was supposed to be an alternative to an existing runtime based allocator.
This runtime allocator makes use of a feature of the dynamic linker which tries to resolve the symbol (function names/external variables etc) and connect it to the function calls in the application.</p>

<p>Using this feature you can track all of the malloc/free calls used by the application and decide where the memory needs to be allocated.
Here is how you can hijack all the malloc calls made by the application.</p>

<div class="language-C highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre><span style="color:#777">// _GNU_SOURCE enables the RLD_NEXT handle used in the dlsym</span>
<span style="color:#579">#DEFINE</span> _GNU_SOURCE

<span style="color:#777">// Provides the prototype for dlsym</span>
<span style="color:#579">#include</span> <span style="color:#B44;font-weight:bold">&lt;dlfcn.h&gt;</span>
<span style="color:#579">#include</span> <span style="color:#B44;font-weight:bold">&lt;stddef.h&gt;</span>

<span style="color:#777">// Create a function pointer to hold the location of the malloc call</span>
<span style="color:#088;font-weight:bold">static</span> <span style="color:#088;font-weight:bold">void</span>* (*real_malloc)(size_t size);

<span style="color:#777">// __attribute__((constructor)) tells the loader to run this function once the library is loaded</span>
<span style="color:#088;font-weight:bold">void</span>* __attribute__((constructor)) lib_init() {

    <span style="color:#777">// dlsym looks for the symbol malloc which appears after</span>
    real_malloc = (<span style="color:#088;font-weight:bold">void</span>*(*)(size_t))dlsym(RLD_NEXT, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">malloc</span><span style="color:#710">&quot;</span></span>);
}

<span style="color:#777">// We hijack all the malloc calls from the application</span>
<span style="color:#088;font-weight:bold">void</span>* malloc(size_t size) {
    <span style="color:#080;font-weight:bold">return</span> real_malloc(size);
}
</pre></div>
</div>
</div>
<p>We then need to build the code as a shared library using <code>gcc -shared -fPIC -o libmalloc.so main.c</code></p>

<p>Then to use the library all you need to do is <code>LD_PRELOAD=libmalloc.so ./app</code> where app is the application you want to hijack</p>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[My masters project was based on writing a allocator which would allocate memory to either the DRAM or a persistent memory device(Intel Optane), which is controlled at compile time.It was supposed to be an alternative to an existing runtime based allocator. This runtime allocator makes use of a feature of the dynamic linker which tries to resolve the symbol (function names/external variables etc) and connect it to the function calls in the application.]]></summary></entry><entry><title type="html">Github pages without limits</title><link href="http://surajms.com/2024/01/github-pages-without-limits/" rel="alternate" type="text/html" title="Github pages without limits" /><published>2024-01-01T22:22:00+00:00</published><updated>2024-01-01T22:22:00+00:00</updated><id>http://surajms.com/2024/01/github-pages-without-limits</id><content type="html" xml:base="http://surajms.com/2024/01/github-pages-without-limits/"><![CDATA[<p>I decided to upgrade my jekyll theme for the blog to the latest version of the theme.The new version is based on the new version of jekyll wwhich is not supported by github pages, even though I would try to use the newer versions of the theme.Github pages would replace it with their an older version of the theme resulting in a broken links throughout the website.</p>

<p>To get around this I decided to fork the github <a href="https://github.com/actions/jekyll-build-pages">action</a>.
It took me a while to understand how actions are released and deployed to the github marketplace.Luckily the repository already contained  auatomated workflows to build and release new versions of the github action.</p>

<p>The github action is configured to download the github-pages ruby gem which contains the restrictions like allows themes and plugins which can be used with the github pages platform, since these restrictions were just validations added before the action of building the jekyll static html pages, all I had to do was get rid of those restrictions.</p>

<p>I have updated the action which can be just like the original github action.All you have to do is replace the github workflow name from <code>actions/jekyll-build-pages@v1</code> to <code>h0lyalg0rithm/jekyll-build-pages@v1</code></p>

<p>As you can see this website now supports dark mode :rocket: .</p>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[I decided to upgrade my jekyll theme for the blog to the latest version of the theme.The new version is based on the new version of jekyll wwhich is not supported by github pages, even though I would try to use the newer versions of the theme.Github pages would replace it with their an older version of the theme resulting in a broken links throughout the website.]]></summary></entry><entry><title type="html">IR replacement with LLVM passes</title><link href="http://surajms.com/2023/12/ir-replacement-with-llvm-passes/" rel="alternate" type="text/html" title="IR replacement with LLVM passes" /><published>2023-12-22T23:58:00+00:00</published><updated>2023-12-22T23:58:00+00:00</updated><id>http://surajms.com/2023/12/ir-replacement-with-llvm-passes</id><content type="html" xml:base="http://surajms.com/2023/12/ir-replacement-with-llvm-passes/"><![CDATA[<p>For the last few weeks I have been trying to understand how graphics code (shaders) are compiled in to assembly that the graphics cards understand.This was part of open source contribution to the RISCV Graphics group.The team at the graphics group were looking for people who would be willing to work on the different stacks of the RISCV graphics stack.Currently the project I am working on is at a very early stage.</p>

<p>The goal of the project is to convert SPIRV graphics code to RISCV assembly.SPIRV is a widely used IR and it supported by most common shading languages like HLSL and GLSL.The khronous group wants to make this IR a universal IR to also support more than just graphics related operations.</p>

<p>Since was already some on going work by the LLVM team to convert SPIRV to LLVM, we decided to take a look at it, however it didnt support GLSL compiled SPIRV.We then decided to look at AMDs compiler which ended up supporting it.</p>

<p>My first go was writing a quick transformation pass and added it at the end of the first stage of the compiler.
Here is how I implemented the Pass.</p>

<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>class SpirvSamplerLowering : public llvm::PassInfoMixin&lt;SpirvSamplerLowering&gt; {
public:
  llvm::PreservedAnalyses run(llvm::Function &amp;function, llvm::FunctionAnalysisManager &amp;analysisManager) {
    LLVM_DEBUG(dbgs() &lt;&lt; &quot;Run the pass Spirv-Sampler-Lower\n&quot;);
    m_builder = std::make_unique&lt;IRBuilder&lt;&gt;&gt;(function.getContext());
    for (auto &amp;bb : function) {
      for (auto &amp;inst : bb) {
        if (auto *ci = llvm::dyn_cast&lt;llvm::CallInst&gt;(&amp;inst)) {
          if (ci-&gt;getCalledFunction()-&gt;getName().starts_with(&quot;lgc.create.image.sample&quot;)) {
            IRBuilder&lt;&gt; Builder(ci);
            std::vector&lt;Value *&gt; Args(ci-&gt;arg_begin(), ci-&gt;arg_end());
            llvm::FunctionCallee newCallee = function.getParent()-&gt;getOrInsertFunction(&quot;llvm.riscv.image.sample&quot;, ci-&gt;getFunctionType());
            llvm::CallInst *newCallInst = Builder.CreateCall(newCallee, Args);
            ci-&gt;replaceAllUsesWith(newCallInst);
            m_instsToErase.push_back(ci);
          }
          LLVM_DEBUG(dbgs() &lt;&lt; ci-&gt;getCalledFunction()-&gt;getName() &lt;&lt; &quot;\n&quot;);
        }
      }
    }
  
    const bool changed = !m_instsToErase.empty();
    for (Instruction *const inst : m_instsToErase) {
      inst-&gt;eraseFromParent();
    }
    m_instsToErase.clear();
  
    return changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
  }

    const bool changed = !m_instsToErase.empty();
    for (Instruction *const inst : m_instsToErase) {
      inst-&gt;eraseFromParent();
    }
    m_instsToErase.clear();

    return changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
  }

  static llvm::StringRef name() { return &quot;Lower LLPC sampler to LLVM sampler IR&quot;; }

private:
  std::unique_ptr&lt;llvm::IRBuilder&lt;&gt;&gt; m_builder;
  llvm::SmallVector&lt;llvm::Instruction *, 8&gt; m_instsToErase;
}
</pre></div>
</div>
</div>

<p>The run function executes when it run the pass.We then iterate over the function and its basic blocks to find the instruction that calls the lgc instrinsic we are trying to replace.
Once we have a reference to the intrinsic we copy the arguments passed to the instrinsic and create a new instruction with the passed arguments.We then store the reference to the instruction in a vector to be delted later.</p>

<p>Writing this pass was pretty simple and it mostly felt like a fancy regex on the IR.</p>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[For the last few weeks I have been trying to understand how graphics code (shaders) are compiled in to assembly that the graphics cards understand.This was part of open source contribution to the RISCV Graphics group.The team at the graphics group were looking for people who would be willing to work on the different stacks of the RISCV graphics stack.Currently the project I am working on is at a very early stage.]]></summary></entry><entry><title type="html">Extending Proxmox terraform module to support iso images</title><link href="http://surajms.com/2023/08/extending-proxmox-terraform-module-to-support-iso-images/" rel="alternate" type="text/html" title="Extending Proxmox terraform module to support iso images" /><published>2023-08-04T20:38:00+00:00</published><updated>2023-08-04T20:38:00+00:00</updated><id>http://surajms.com/2023/08/extending-proxmox-terraform-module-to-support-iso-images</id><content type="html" xml:base="http://surajms.com/2023/08/extending-proxmox-terraform-module-to-support-iso-images/"><![CDATA[<p>Today I was trying to setup my kubernetes cluster from scratch.This time I decided to write down all of the steps as a terraform plan rather than regular bash scripts.</p>

<p>To start I looked up for the terraform provider on github and came across this <a href="https://github.com/Telmate/terraform-provider-proxmox">Telmate/terraform-provider-proxmox</a>
Looking at the documentation I didnt come across a way to upload an iso to proxmox, so I decided to work on this feature for the provider.</p>

<p>This was the first time I wrote an extension for proxmox, so I had to deep a lot deeper into the code and <a href="https://developer.hashicorp.com/terraform/plugin/sdkv2">documentation</a>.</p>

<p>First thing I had to do was define how the user api was going to be.
I decided on the following</p>

<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>resource &quot;proxmox_storage_iso&quot; &quot;unique_resource_name&quot; {
  storage  = &quot;local&quot;                        // Where should this be stored in proxmox
  filename = &quot;image.iso&quot;                    // Name of the image
  pve_node = &quot;pve&quot;                          // Target node where the storage points too
  url      = &quot;http://example.com/image.iso&quot; // URL to the image iso
}
</pre></div>
</div>
</div>

<p>Next was time to build the Resource to TF State integration.</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>func resourceStorageIso() *schema.Resource {
        return &amp;schema.Resource{
                Create: resourceStorageIsoCreate,
                Read:   resourceStorageIsoRead,
                Delete: resourceStorageIsoDelete,
        Schema: map[string]*schema.Schema{
                &quot;filename&quot;: {
                        Type:     schema.TypeString,
                        Required: true,
                }
        }
    }
}
</pre></div>
</div>
</div>

<p>The Proxmox plugin has callbacks for the different actions that a resource might have to work with.
These callbacks are pretty straight forward as their meaning maps to their verb.
The schema on the other hand are the different fields that can be provided to the resource.</p>

<p>Terraform resources also have a special ResourceData field called Id which is used to uniquely identity a resource.</p>

<p>In the create callback, we call the proxmox-go-api library to create an ISO resource.One of the things I had to do was fetch the iso and store it in a temporary file and then upload it using the api.
Once the iso is created in proxmox, we call the api again to validate if the image has been saved correctly.I then set the <code>Id</code> field to the <code>volId</code> field from the api response which is the unique identifier 
from proxmox.</p>

<p>The delete callback was a bit tricky since the proxmox-go-api didnt have a delete api, so I called it using the generic client delete method present in the library.
Since proxmox doesnt let you update a given iso, I didn’t have to implement the update callback.</p>

<p>Here is the <a href="https://github.com/Telmate/terraform-provider-proxmox/compare/master...h0lyalg0rithm:terraform-provider-proxmox:add_resource_storage_iso">link</a> to the final PR for this feature</p>

<p>Update(07-08-2023): One of the things I forgot to mention was setting up the development environment for the provider.One of things that took a lof of my time was the setup itself.
I created a <code>.terraformrc</code> file in my $HOME directory</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>provider_installation {
  dev_overrides {
    &quot;telmate/proxmox&quot; = &quot;&lt;path to terraform-provider-proxmox&gt;&quot;
  }
}
</pre></div>
</div>
</div>
<p>I created a <code>main.tf</code> to test out the feature.Running terraform init would result in error as it cannot find the provider.
Just run <code>terraform plan</code> to execute the action.</p>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[Today I was trying to setup my kubernetes cluster from scratch.This time I decided to write down all of the steps as a terraform plan rather than regular bash scripts.]]></summary></entry><entry><title type="html">Yet another bootloader fail</title><link href="http://surajms.com/2023/07/yet-another-bootloader-fail/" rel="alternate" type="text/html" title="Yet another bootloader fail" /><published>2023-07-28T23:05:00+00:00</published><updated>2023-07-28T23:05:00+00:00</updated><id>http://surajms.com/2023/07/yet-another-bootloader-fail</id><content type="html" xml:base="http://surajms.com/2023/07/yet-another-bootloader-fail/"><![CDATA[<p>Last week I ended up hard bricking my Pixel 2 XL with a stupid mistake,I ended up locking my bootloader with an invalid partition.This was a hard brick and the only ones who can unlock is google.I tried to schedule a repair through the google store.Their cost estimator returned a cost to repair nearly the price of a new google pixel.
So I decided to switch back to my old Xiaomi A2.I turned on the device after a while and the operating system on the device was more than 3 years old.</p>

<p>I decided to build PixelExperience rom for my device, It took a while as my HDD was pretty slow.However it completed in 2 hours.
This is how I got the rom installed on my device.</p>

<ul>
  <li>I first booted into the bootloader using adb. <code>adb reboot bootloader</code></li>
  <li>I then flashed the bootloader on both the partitions
    <div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>fastboot --set-active=a
fastboot flash boot recovery.img
fastboot --set-active=b
fastboot flash boot recovery.img
</pre></div>
</div>
    </div>
  </li>
  <li>I then  ran <code>fastboot reboot recovery</code> to boot into recovery.</li>
  <li>I then had to flash the following <a href="https://github.com/PixelExperience-Devices/blobs/raw/main/copy-partitions-20210323_1922.zip">zip</a> which sets up the new partition scheme required for newer versions of android, using the adb sideload option in recovery <code>adb sideload copy-partitions-20210323_1992.zip</code></li>
  <li>Next I had to reboot into recovery again using the ui.</li>
  <li>To support dynamic partitions I had to flash the following <a href="https://gitlab.pixelexperience.org/android/vendor-blobs/wiki_blobs_jasmine_sprout/-/raw/main/android-13/super_empty.img?inline=false">img</a>, however the way to flash it is a bit different.</li>
  <li>I had to switch to fastboot using the recovery screen and then run the following <code>fastboot wipe-super super_empty.img</code></li>
  <li>I then performed a factory reset on the phone.</li>
  <li>The active partition was set to <code>b</code> so that the inactive partition is <code>a</code> where the recovery would install the operating system.</li>
  <li>Once that was complete I had to switch back to recovery and sideload the final rom <code>adb sideload pixelexperience_jasmine_sprout.zip</code></li>
  <li>Another factory reset on the phone just to be safe.</li>
</ul>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[Last week I ended up hard bricking my Pixel 2 XL with a stupid mistake,I ended up locking my bootloader with an invalid partition.This was a hard brick and the only ones who can unlock is google.I tried to schedule a repair through the google store.Their cost estimator returned a cost to repair nearly the price of a new google pixel. So I decided to switch back to my old Xiaomi A2.I turned on the device after a while and the operating system on the device was more than 3 years old.]]></summary></entry><entry><title type="html">Writing my first linux module</title><link href="http://surajms.com/2023/07/writing-my-first-linux-module/" rel="alternate" type="text/html" title="Writing my first linux module" /><published>2023-07-25T22:56:00+00:00</published><updated>2023-07-25T22:56:00+00:00</updated><id>http://surajms.com/2023/07/writing-my-first-linux-module</id><content type="html" xml:base="http://surajms.com/2023/07/writing-my-first-linux-module/"><![CDATA[<p>Last year I was watching an online course on operating systems on youtube,and one of the videos was on writing a kernel module.
I have been using a linux box for a while now but whenever I heard about a kernel, I always assumed that it was something complicated and way out of my league.</p>

<p>However since I had some time, I decided to give it a try.To write a barebones kernel module, here I how I went about it.</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>#include &lt;linux/init.h&gt;
#include &lt;linux/module.h&gt;
#include &lt;linux/kernel.h&gt;

MODULE_DESCRIPTION(&quot;Simple module&quot;);
MODULE_AUTHOR(&quot;Suraj Shirvankar&quot;);
MODULE_LICENSE(&quot;GPL&quot;);

static int init_module(void) {
  printk(&quot;Loaded kernel module&quot;);
  return 0;
}

static void exit_module(void) {
}

module_init(init_module);
module_exit(exit_module);
</pre></div>
</div>
</div>
<p>Then I had to create a <code>Makefile</code> to build the final kernel module</p>

<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>obj-m += test.o

all:
  make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
  make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
</pre></div>
</div>
</div>
<p>I had to make sure that the name of the object file matched the name of the file which contained the kernel code.
All this kernel module does is to print out in the log that it was loaded.</p>

<p>Next I tried to create a kernel module that would create a new proc file which would let us know the number of processes that are running.
This would allow us to run the following in the terminal.</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>#bash cat /proc/proc_count
40
</pre></div>
</div>
</div>

<p>Here is how I went about writting it.</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>#include &lt;linux/module.h&gt;
#include &lt;linux/init.h&gt;
#include &lt;linux/kernel.h&gt;
#include &lt;linux/proc_fs.h&gt;
#include &lt;linux/seq_file.h&gt;
#include &lt;linux/sched.h&gt;

MODULE_DESCRIPTION(&quot;Process count module&quot;);
MODULE_LICENSE(&quot;GPL&quot;);
MODULE_AUTHOR(&quot;Suraj Shirvankar&quot;);

struct proc_dir_entry *proc_entry;

static int proc_count(struct seq_file *seq, void *offset) {
        printk(&quot;Couting processes&quot;);
        struct task_struct *task_struct;
        int process_count = 0;
        for_each_process(task_struct){
                process_count += 1;
        }
        seq_printf(seq, &quot;%d\n&quot;, process_count);
        return 0;
}
static int init_mod(void){
        printk(&quot;Loaded module to count processes&quot;);
        proc_entry = proc_create_single(&quot;proc_count&quot;, 0, NULL, proc_count);
        return 0;
}

static void exit_mod(void) {
    proc_remove(proc_entry);
}

module_init(init_mod);
module_exit(exit_mod);
</pre></div>
</div>
</div>
<p>Now if i run the following I get this as the result</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>cat /proc/proc_count 
625
</pre></div>
</div>
</div>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[Last year I was watching an online course on operating systems on youtube,and one of the videos was on writing a kernel module. I have been using a linux box for a while now but whenever I heard about a kernel, I always assumed that it was something complicated and way out of my league.]]></summary></entry><entry><title type="html">Pthread setspecific segfault</title><link href="http://surajms.com/2023/04/pthread-set-specific-segfault-md/" rel="alternate" type="text/html" title="Pthread setspecific segfault" /><published>2023-04-26T22:24:00+00:00</published><updated>2023-04-26T22:24:00+00:00</updated><id>http://surajms.com/2023/04/pthread-set-specific-segfault-md</id><content type="html" xml:base="http://surajms.com/2023/04/pthread-set-specific-segfault-md/"><![CDATA[<p>During the last week I was stuck trying to figure out why openfoam was segfaulting when I run the application with the shared library that I built.
The shared library that I built would interpose itself over all the memory allocation calls that were made by the application.The library then decides to allocate the object to the appropriate memory device.
However to acheive this, the library depends on <code>dlsym</code> which looks for the next symbol for malloc/realloc/calloc and it returns the function pointer to allow us to invoke later.</p>

<p>Here is the error I encountered while running gdb.</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>_dlerror_run (operate=operate@entry=0x7ffff7bd20b0 &lt;dlsym_doit&gt;, args=args@entry=0x7fffffffbfe0)
    at dlerror.c:154
154          if (result-&gt;errstring != NULL)
Missing separate debuginfos, use: dnf debuginfo-install libunwind-1.2.1-3.fc27.x86_64 libxml2-2.9.8-4.fc27.x86_64 numactl-libs-2.0.11-5.fc27.x86_64 xz-libs-5.2.3-4.fc27.x86_64 zlib-1.2.11-4.fc27.x86_64
(gdb) backtrace
#0  _dlerror_run (operate=operate@entry=0x7ffff7bd20b0 &lt;dlsym_doit&gt;, args=args@entry=0x7fffffffbfe0)
    at dlerror.c:154
#1  0x00007ffff7bd2141 in __dlsym (handle=handle@entry=0xffffffffffffffff, 
    name=name@entry=0x7ffff7878bf0 &quot;malloc&quot;) at dlsym.c:70
#2  0x00007ffff77bdb6c in xxxxx::uninitialized_malloc (size=168) at ../../xxxxx.cxx:44
#3  0x00007ffff77bf14d in malloc (size=168) at ../../xxxxx.cxx:225
</pre></div>
</div>
</div>
<p>When we look at the source of glibc we see the following block</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>int
internal_function
_dlerror_run (void (*operate) (void *), void *args)
{
  struct dl_action_result *result;

  /* If we have not yet initialized the buffer do it now.  */
  __libc_once (once, init);

  /* Get error string and number.  */
  if (static_buf != NULL)
    result = static_buf;
  else
    {
      /* We don't use the static buffer and so we have a key.  Use it
         to get the thread-specific buffer.  */
      result = __libc_getspecific (key);
      if (result == NULL)
        {
          result = (struct dl_action_result *) calloc (1, sizeof (*result));
          if (result == NULL)
            /* We are out of memory.  Since this is no really critical
               situation we carry on by using the global variable.
               This might lead to conflicts between the threads but
               they soon all will have memory problems.  */
            result = &amp;last_result;
          else
            /* Set the tsd.  */
            __libc_setspecific (key, result);
        }
    }

  if (result-&gt;errstring != NULL)
    {
      /* Free the error string from the last failed command.  This can
         happen if `dlerror' was not run after an error was found.  */
      if (result-&gt;malloced)
        free ((char *) result-&gt;errstring);
      result-&gt;errstring = NULL;
    }

  result-&gt;errcode = _dl_catch_error (&amp;result-&gt;objname, &amp;result-&gt;errstring,
                                     &amp;result-&gt;malloced, operate, args);

  /* If no error we mark that no error string is available.  */
  result-&gt;returned = result-&gt;errstring == NULL;

  return result-&gt;errstring != NULL;
}
</pre></div>
</div>
</div>
<p>Looking at the following line <code>result = __libc_getspecific (key);</code> we see that result is set to the value based on the value in the thread.
While debugging with gdb the value of <code>key</code> was 0 and the value returned from _libc_getspecific was not NULL but the value returned was not a valid <code>dl_action_result</code>, resulting in the segfault in the following line <code>if (result-&gt;errstring != NULL)</code>.</p>

<p>With the help of my colleague in BSC I was able to debug why the value was invalid.In the library we used a thread specific value for each pthread using the following api.
<code>int pthread_setspecific(pthread_key_t key, const void *value); </code>
The main issue with the usage of this api was that I didnt initialize the pthread_key_t struct, hence libc would set the key to value of 0 and the value was set to the second argument passed.</p>

<p>Looking back at the libc internal we can now see that value returned to <code>__libc_getspecific(key)</code> returned the value based earlier resulting in the segfault.</p>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[During the last week I was stuck trying to figure out why openfoam was segfaulting when I run the application with the shared library that I built. The shared library that I built would interpose itself over all the memory allocation calls that were made by the application.The library then decides to allocate the object to the appropriate memory device. However to acheive this, the library depends on dlsym which looks for the next symbol for malloc/realloc/calloc and it returns the function pointer to allow us to invoke later.]]></summary></entry><entry><title type="html">Submitting code patches by email</title><link href="http://surajms.com/2023/04/submitting-code-patches-by-email/" rel="alternate" type="text/html" title="Submitting code patches by email" /><published>2023-04-14T20:12:00+00:00</published><updated>2023-04-14T20:12:00+00:00</updated><id>http://surajms.com/2023/04/submitting-code-patches-by-email</id><content type="html" xml:base="http://surajms.com/2023/04/submitting-code-patches-by-email/"><![CDATA[<p>Last month I have been working on FFmpeg the swiss army knife for video.While most of the open source repositories manage their code using Git or are directly hosted on Github, FFmpeg has their own hosted git repository and they accept code changes through email.</p>

<p>After trying to share my large PR code to their email address using the process described in their contributions <a href="https://ffmpeg.org/developer.html#toc-Submitting-patches-1">page</a>, I assumed the issue was on my setup as it was the first time I was sending code patches via email.</p>

<p>However today I was contributing a smaller change to project and I tried the patch using the following command
<code>git format-patch -s -o "outputfolder" --add-header "X-Unsent: 1" --suffix .eml --to ffmpeg-devel@ffmpeg.org -1 1a2b3c4d</code></p>

<p>It failed once again as the build system could not apply the patch.
Then I started to dig further into this and came to realize that git comes with a built in feature to send email patches, however it comes part of a seperate package from the git project.
Since my machine was based on Ubuntu, I was able to install it with the following.</p>

<p><code>sudo apt-get install git-email sendmail</code></p>

<p>Once that is installed I had to set the following in my <code>~/.gitconfig</code>.</p>
<div class="language-plaintext highlighter-coderay"><div class="CodeRay">
  <div class="code"><pre>[sendemail]
        smtpserver = smtp.gmail.com
        smtpuser = surajshirvankar@gmail.com
        smtpencryption = ssl
        smtpserverport = 587
</pre></div>
</div>
</div>
<p>Then I generated the email and sent it using the following</p>

<p><code>git send-email --to="ffmeg-devel@ffmpeg.org -3</code> where it sends an email with last 3 commits.</p>

<p>Since I was using my gmail account to send the patch, I had to generate a Google App Password which will be used as the password to login in behalf of my email account.</p>]]></content><author><name>Suraj Shirvankar</name></author><summary type="html"><![CDATA[Last month I have been working on FFmpeg the swiss army knife for video.While most of the open source repositories manage their code using Git or are directly hosted on Github, FFmpeg has their own hosted git repository and they accept code changes through email.]]></summary></entry></feed>