<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ruslan Kh.</title>
    <description>The latest articles on DEV Community by Ruslan Kh. (@xakrume).</description>
    <link>https://dev.to/xakrume</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1012514%2Fa9791f47-8fc8-40d6-b2da-e7ea7313034b.jpg</url>
      <title>DEV Community: Ruslan Kh.</title>
      <link>https://dev.to/xakrume</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xakrume"/>
    <language>en</language>
    <item>
      <title>SWAP: Guide about swap and swappiness</title>
      <dc:creator>Ruslan Kh.</dc:creator>
      <pubDate>Mon, 23 Sep 2024 11:41:25 +0000</pubDate>
      <link>https://dev.to/xakrume/guide-about-swap-and-swappiness-2bfg</link>
      <guid>https://dev.to/xakrume/guide-about-swap-and-swappiness-2bfg</guid>
      <description>&lt;p&gt;If you're tired of seeing the same old instructions on setting up SWAP in Linux, especially the ones that insist on using &lt;code&gt;dd&lt;/code&gt;, you're not alone. This isn't just another tutorial on enabling SWAP; it's a practical guide that goes beyond the basics, addressing better and more efficient ways to manage your system's memory. We'll explore why &lt;code&gt;fallocate&lt;/code&gt; might be a smarter choice and dive into optimizing &lt;code&gt;swappiness&lt;/code&gt; for better performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is SWAP?
&lt;/h3&gt;

&lt;p&gt;SWAP is a designated area on your disk that serves as overflow space for your system's RAM. When your system runs out of physical memory (RAM), it moves inactive data from RAM to the SWAP space, freeing up memory for other tasks. This process is known as "swapping."&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is SWAP important?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Increased Virtual Memory&lt;/strong&gt;: SWAP allows the system to use more memory than is physically available in RAM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System Stability&lt;/strong&gt;: Without SWAP, running out of RAM could lead to system crashes, as the system wouldn't be able to handle new memory allocation requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory Management Flexibility&lt;/strong&gt;: SWAP is useful in systems with limited RAM or under heavy load, where temporary expansion of available memory is needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Types of SWAP:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SWAP Partition&lt;/strong&gt;: A dedicated partition on the disk used exclusively for SWAP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SWAP File&lt;/strong&gt;: A file within the filesystem that can be used as SWAP space.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6h455nr1wgg248nfvp2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6h455nr1wgg248nfvp2.jpg" alt="Image description" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up SWAP:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Creating a SWAP Partition:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;fdisk&lt;/code&gt; or &lt;code&gt;parted&lt;/code&gt; to create a new partition on your disk, and set the partition type to "Linux swap" (code 82).&lt;/li&gt;
&lt;li&gt;Apply the changes to update the partition table.&lt;/li&gt;
&lt;li&gt;Format the partition as SWAP using the command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mkswap /dev/sdXn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Activate the SWAP partition:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swapon /dev/sdXn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To make the SWAP permanent after reboot, add an entry to &lt;code&gt;/etc/fstab&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/dev/sdXn swap swap defaults 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Creating a SWAP File:
&lt;/h3&gt;

&lt;p&gt;Instead of using &lt;code&gt;dd&lt;/code&gt;, you can use &lt;code&gt;fallocate&lt;/code&gt;, which is faster and simpler for creating SWAP files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a SWAP file of the desired size (e.g., 2 GB):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fallocate -l 2G /swapfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set the correct permissions for the file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /swapfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initialize the file as SWAP:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mkswap /swapfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enable the SWAP file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swapon /swapfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To ensure the SWAP file is mounted automatically after a reboot, add an entry to &lt;code&gt;/etc/fstab&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/swapfile swap swap defaults 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Use &lt;code&gt;fallocate&lt;/code&gt; Instead of &lt;code&gt;dd&lt;/code&gt;?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: &lt;code&gt;fallocate&lt;/code&gt; allocates space instantly without writing zeros across the file, unlike &lt;code&gt;dd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;: The command is straightforward and does not require specifying block size or count.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;When to Prefer &lt;code&gt;dd&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compatibility&lt;/strong&gt;: &lt;code&gt;fallocate&lt;/code&gt; may not be supported on all filesystems, particularly older or non-standard ones, where &lt;code&gt;dd&lt;/code&gt; might be necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Physical Block Reservation&lt;/strong&gt;: If you need to create a file with physically reserved blocks, &lt;code&gt;dd&lt;/code&gt; is useful because it fills the file with data, ensuring that disk space is reserved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Testing&lt;/strong&gt;: &lt;code&gt;dd&lt;/code&gt; can create files with specific content patterns, useful for performance testing or when a file needs to be filled with a specific data template.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Checking SWAP Status:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To check the current SWAP status, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swapon &lt;span class="nt"&gt;--show&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;free &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding Multiple SWAP Files:**
&lt;/h3&gt;

&lt;p&gt;If your system needs more SWAP space, you don't need to expand an existing SWAP file. Instead, you can add additional SWAP files. Each new SWAP file can be created and activated separately, and the system will manage them automatically. This approach is flexible and allows you to scale your SWAP space as needed without modifying existing files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating Additional SWAP Files:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new SWAP file (e.g., 1 GB):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fallocate &lt;span class="nt"&gt;-l&lt;/span&gt; 10G /swapfile_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set the appropriate permissions:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 600 /swapfile_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initialize it as SWAP:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mkswap /swapfile_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enable the new SWAP file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swapon /swapfile_2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Managing SWAP Priorities:
&lt;/h3&gt;

&lt;p&gt;Each SWAP file can have a different priority, which determines the order in which the system uses them. The priority is set when you activate the SWAP file using the &lt;code&gt;swapon&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;swapon /swapfile_2 &lt;span class="nt"&gt;-p&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;/swapfile_2&lt;/code&gt; has a higher priority than other SWAP files with the default priority (0). The system will use the higher-priority SWAP space first.&lt;/p&gt;

&lt;p&gt;Example with multiple swap files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~&lt;span class="nv"&gt;$ &lt;/span&gt;swapon &lt;span class="nt"&gt;-s&lt;/span&gt; 
Filename       Type    Size        Used         Priority
/swapfile_1    file    67108860    51176372     &lt;span class="nt"&gt;-2&lt;/span&gt;
/swapfile_2    file    67108860    12404496     &lt;span class="nt"&gt;-3&lt;/span&gt;
/swapfile_3    file    134217724   186348       &lt;span class="nt"&gt;-4&lt;/span&gt;
/swapfile_4    file    134217724   0            &lt;span class="nt"&gt;-5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tuning SWAP Parameters: Understanding &lt;code&gt;swappiness&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Swappiness is a kernel parameter that controls how aggressively your Linux system will move data from RAM to SWAP. It is expressed as a value between 0 and 100.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Low Swappiness (e.g., 10)&lt;/strong&gt;: Tells the system to avoid swapping unless absolutely necessary, keeping most of the data in RAM. This is useful when you have a large amount of RAM and you want to minimize disk I/O, because accessing data in RAM is much faster than accessing it on disk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High Swappiness (e.g., 60 or higher)&lt;/strong&gt;: Makes the system more eager to use SWAP space, even when RAM is still available. This can be useful in environments where you want to keep more free RAM for caching or if the SWAP space is on a fast SSD, making the performance hit less noticeable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default value of swappiness is usually set to 60, which provides a balanced approach. However, depending on your specific use case and system resources, you might want to adjust it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To temporarily change the swappiness value:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sysctl vm.swappiness&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To make the change permanent across reboots, add the following to &lt;code&gt;/etc/sysctl.conf&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vm.swappiness&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why Adjust Swappiness?
&lt;/h3&gt;

&lt;p&gt;Adjusting swappiness allows you to fine-tune how your system manages its memory, optimizing for performance, reducing disk wear on systems with SSDs, or ensuring better utilization of available RAM. By lowering the swappiness value, you can prioritize keeping active data in RAM, which is useful for workloads that are sensitive to latency. Conversely, increasing swappiness might be beneficial in systems with constrained memory, where offloading to SWAP earlier can help maintain system responsiveness.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>swap</category>
      <category>memorymanagement</category>
      <category>optimization</category>
    </item>
    <item>
      <title>The Evolution and Impact of MLOps: understanding MLOps</title>
      <dc:creator>Ruslan Kh.</dc:creator>
      <pubDate>Sat, 27 May 2023 14:00:58 +0000</pubDate>
      <link>https://dev.to/xakrume/the-evolution-and-impact-of-mlops-understanding-mlops-1dpo</link>
      <guid>https://dev.to/xakrume/the-evolution-and-impact-of-mlops-understanding-mlops-1dpo</guid>
      <description>&lt;p&gt;Machine Learning Operations, or MLOps, is the missing bridge between machine learning, data science, and data engineering. It has emerged as the link that unifies these functions more seamlessly than ever before. So what is MLOps, and why does it matter? In this article, we'll dive into the MLOps Hierarchy of Needs, a fundamental concept that illustrates how MLOps supports, enhances, and optimizes the machine learning workflow within an organization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3gsy3vpu729hecf1db4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3gsy3vpu729hecf1db4.png" alt="MLOps structure hierarchy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  DevOps: The Foundation of MLOps
&lt;/h3&gt;

&lt;p&gt;To understand MLOps, we must first understand the structure of this hierarchy, which can be visualized as a pyramid. At the base of this pyramid is DevOps, the practice that enables continuous delivery and automated provisioning of environments. Without a solid DevOps foundation, there's no way an organization can successfully implement MLOps. Key components of DevOps include infrastructure as code and a robust build system that allows services to be deployed in the staging environment and automatically propagated to production.&lt;/p&gt;

&lt;p&gt;DevOps, a combination of "development" and "operations," is a collaborative approach that streamlines the software development process. It bridges the gap between development and operations teams, facilitating continuous integration and delivery. This methodology is essential for an organization to dive into MLOps.&lt;/p&gt;

&lt;p&gt;Key components of DevOps include Infrastructure as Code (IaC), continuous delivery, and a design based on a robust build system. IaC enables automated provisioning of environments that can be integrated with your build system, providing significant flexibility and reproducibility. Similarly, continuous delivery ensures that microservices are systematically updated in the staging environment and propagated to production, increasing speed and efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Operations: The Next Level
&lt;/h3&gt;

&lt;p&gt;Once the foundational level of DevOps is established, the next step is to focus on data operations. This involves setting up data management platforms such as Google BigQuery, Databricks, Snowflake, or Amazon Athena. These platforms facilitate serverless query and visualization workflows, making data processing easier. They also support data jobs and tasks to ensure efficient data operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  MLOps Platforms: Essential tools for machine learning
&lt;/h3&gt;

&lt;p&gt;The third layer is the implementation of an MLOps platform. This layer emphasizes the use of specialized tools rather than building everything from scratch, which can take a lot of time away from core business objectives. Building on the data operations layer, it's time to integrate MLOps platforms. These are specialized tools designed to streamline the machine learning process, including feature stores, model serving platforms, and experiment tracking tools. Feature stores store pre-curated features for reuse, while model serving platforms manage the deployment of ML models. Experiment tracking tools help track various metrics and explanatory techniques, and also monitor data drift, allowing you to measure the impact of a model in production and observe how the underlying data changes over time. They help monitor different metrics, training techniques, and data drift - a concept that describes how the performance of an ML model can degrade over time as the underlying data changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  The MLOps layer: Workflow Automation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwdek5xhu048hyui93nk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwdek5xhu048hyui93nk.png" alt="MLOps tasks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we reach the top of the pyramid - the MLOps layer itself. Here, the focus is on business value. It's important to ensure that the machine learning models being created are delivering value to the organization. This value can be tracked and quantified, providing visibility that is useful for the health, security, and reputation of the organizations using the models. Getting the problem right is also critical at this stage - solving the wrong problem can lead to wasted resources and missed opportunities.&lt;/p&gt;

&lt;p&gt;MLOps is not just about process, it is also about transforming people and technology. Successful MLOps implementation requires the participation of people from different levels and departments in an organization, creating a culture of best practices.&lt;/p&gt;

&lt;p&gt;There are several trends and predictions for MLOps in 2023. One key trend is the continued investment in machine learning, driven by the rapid evolution of MLOps and the machine learning industry. However, the integration of MLOps continues to present challenges. The onboarding and deployment of AI and ML algorithms can be complex, requiring careful workload orchestration and server balancing.&lt;/p&gt;

&lt;p&gt;A growing number of organizations are adopting tools like Metaflow, open-sourced by Netflix and AWS, to design, run, and deploy their workflows at scale, automatically versioning and tracking all experiments and data. There is no consensus on a single MLOps tool or application, and the growing number of libraries and packages in MLOps is expected to have a significant impact on enterprises.&lt;/p&gt;

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

&lt;p&gt;The MLOps Hierarchy of Needs is a structured approach to implementing MLOps in an organization. By starting with DevOps and gradually building up to data operations, MLOps platforms, and finally the MLOps layer itself, organizations can streamline their ML workflows and maximize their business value. The goal of MLOps isn't just about automation; it's about driving efficiency and accelerating business outcomes.&lt;/p&gt;

&lt;p&gt;Implementing MLOps can enable capabilities such as accurate inventory forecasting and the discovery of new patterns through unsupervised machine learning. But remember, the journey to MLOps is not a sprint; it's a marathon. It requires consistent effort, constant learning, and the right resources to successfully implement and manage MLOps in an organization.&lt;/p&gt;

</description>
      <category>mlops</category>
      <category>devops</category>
      <category>dataoperations</category>
      <category>continuousdelivery</category>
    </item>
    <item>
      <title>React 18 server components deep dive</title>
      <dc:creator>Ruslan Kh.</dc:creator>
      <pubDate>Sun, 21 May 2023 19:50:21 +0000</pubDate>
      <link>https://dev.to/xakrume/react-server-components-deep-dive-29af</link>
      <guid>https://dev.to/xakrume/react-server-components-deep-dive-29af</guid>
      <description>&lt;p&gt;React Server Components (RSC) is a promising feature that can have a significant impact on page load performance, bundle size, and the way we write React applications. This feature is still experimental in React 18, but it's worth understanding how it works under the hood.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separation of server and client components
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvyhy8fge3fpor9hhj8pc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvyhy8fge3fpor9hhj8pc.png" alt="A diagram that illustrates the rules that apply to server and client components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Server Components allows the server and client (browser) to work together to render your React application. Some components in the React element tree are rendered by the server, and some are rendered by the browser. This is not the same as server-side rendering (SSR). SSR simulates an environment for rendering a React tree into raw HTML, but it does not distinguish between server and client components.&lt;/p&gt;

&lt;p&gt;The React team has defined server and client components based on the extension of the file in which the component is written: if the file ends in .server.jsx, it contains server components; if it ends in .client.jsx, it contains client components. If it ends in neither, it contains components that can be used as both server and client components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Life of an RSC Render
&lt;/h3&gt;

&lt;p&gt;The life of a page using RSC always begins on the server, in response to an API call to render a React component. The server then serializes the root component element into JSON. The end goal here is to render the initial root server component into a tree of basic HTML tags and client component placeholders.&lt;/p&gt;

&lt;p&gt;The server then sends this serialized tree to the browser, and the browser can do the work of deserializing it, filling the client placeholders with the actual client components, and rendering the end result.&lt;/p&gt;

&lt;h3&gt;
  
  
  RSC and Suspense
&lt;/h3&gt;

&lt;p&gt;Suspense plays an important role in RSC. Suspense allows you to throw promises from your React components when they need something that is not yet ready (fetching data, lazily importing components, etc). These promises are captured at the suspense boundary. When a promise is thrown from rendering a Suspense subtree, React stops rendering that subtree until the promise is resolved, and then tries again.&lt;/p&gt;

&lt;h3&gt;
  
  
  RSC Wire Format
&lt;/h3&gt;

&lt;p&gt;The server outputs a simple format with a JSON blob on each line, tagged with an ID. This format is very streamable - once the client has read a full line, it can parse a snippet of JSON and make some progress.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consuming the RSC Format
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;react-server-dom-webpack&lt;/code&gt; package contains the entrypoints that take the RSC response and rebuild the React element tree. When the server finishes loading the data, it outputs the rows for the module reference - which defines the module reference to the component - and the React element tree that should be swapped into where the reference is.&lt;/p&gt;

&lt;h3&gt;
  
  
  RSC vs. Fetching Data from Client Components
&lt;/h3&gt;

&lt;p&gt;Whether RSC is better than fetching data from client components depends on what you are rendering to the screen. With RSC, you get denormalized, "processed" data that maps directly to what you are showing to the user. If the rendering requires multiple data fetches that depend on each other in a waterfall, then it is better to do the fetching on the server - where data latency is much lower - than from the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  RSC and SSR
&lt;/h3&gt;

&lt;p&gt;With React 18, it is possible to combine both SSR and RSC, so you can generate HTML on the server and then hydrate that HTML with RSC in the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server-Side Rendering (SSR)
&lt;/h3&gt;

&lt;p&gt;Server-side rendering (SSR) is a technique where a React application is rendered on the server into a static HTML string, which is then sent to the client. This can improve performance and SEO by allowing the page to be displayed before all the JavaScript has been loaded and parsed.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOMServer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOMServer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    &amp;lt;!DOCTYPE html&amp;gt;
    &amp;lt;html&amp;gt;
      &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;My App&amp;lt;/title&amp;gt;
      &amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;div id="root"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;appString&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
        &amp;lt;script src="/bundle.js"&amp;gt;&amp;lt;/script&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, the App component is rendered to a string on the server, and that string is inserted into the HTML response. The client then "hydrates" this static HTML into a fully interactive React application.&lt;/p&gt;

&lt;h3&gt;
  
  
  React Server Components (RSC)
&lt;/h3&gt;

&lt;p&gt;React Server Components (RSC) allow the server and client to work together to render a React application. Some components render on the server, and others render on the client. This can improve performance by reducing the amount of JavaScript sent to the client and allowing the server to fetch and render data directly.&lt;/p&gt;

&lt;p&gt;Here's a simple example of RSC:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// Message.server.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./db.server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// App.client.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Message.server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSelectedId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setSelectedId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Next
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, the Message server component retrieves and renders a message based on an id prop. The App client component maintains a piece of state (selectedId) and renders the Message server component with the current id.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Recommendations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Understand the difference between server and client components:&lt;/strong&gt; Understanding which components are rendered by the server and which are rendered by the client is critical to using RSC effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Suspense with RSC:&lt;/strong&gt; Suspense allows you to handle promises in your React components, which is integral to the functioning of RSC&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimize for performance:&lt;/strong&gt; RSC can significantly improve page load performance and reduce bundle size. However, it's important to measure and monitor these metrics to ensure that you're getting the expected benefits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consider the tradeoffs:&lt;/strong&gt; While RSC offers many benefits, it also comes with tradeoffs. For example, server components cannot use states or effects, which can limit their use in certain scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Experiment with RSC in non-critical parts of your application:&lt;/strong&gt; Given the experimental nature of RSC, it may be a good idea to start experimenting with it in non-critical parts of your application. This will give you a better understanding of how it works and how it can be used effectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Combine RSC with other React features:&lt;/strong&gt; RSC can be combined with other React features like Suspense and Concurrent Mode to build more efficient and user-friendly applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Examples.
&lt;/h2&gt;

&lt;p&gt;Let's look at some code examples to illustrate how React Server Components (RSC) work.&lt;/p&gt;

&lt;p&gt;First, let's define a server component. Server components are identified by the .server.js extension:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// Message.server.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./db.server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, Message is a server component that fetches a message from a database based on an id prop. Notice that we're directly importing a server module (db.server) and using it to fetch data. You can't do this in a client component.&lt;/p&gt;

&lt;p&gt;Next, let's define a client component that uses this server component:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// App.client.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Message.server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSelectedId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setSelectedId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Next
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;selectedId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this example, App is a client component that maintains a piece of state (selectedId) and renders the Message server component with the current id. When the Next button is clicked, the selectedId is incremented, causing the Message component to be rendered again with the new id.&lt;/p&gt;

&lt;p&gt;This is a simple example, but it illustrates the key idea behind RSC: server components can be used to fetch and render data on the server, while client components maintain interactivity on the client.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison
&lt;/h3&gt;

&lt;p&gt;While both SSR and RSC involve rendering on the server, they serve different purposes and have different tradeoffs:&lt;/p&gt;

&lt;p&gt;SSR is primarily concerned with improving performance and SEO by sending static HTML to the client. However, it requires sending all JavaScript to the client, which can be large and slow to parse.&lt;br&gt;
RSC, on the other hand, allows the server and client to collaborate on rendering, which can reduce the amount of JavaScript sent to the client and improve performance. However, server components cannot use states or effects, which can limit their use in certain scenarios.&lt;br&gt;
In summary, both SSR and RSC are powerful techniques for rendering React applications, each with its own strengths and tradeoffs. Understanding these differences can help you make more informed decisions about which technique to use in your projects.&lt;/p&gt;

&lt;p&gt;Links:&lt;br&gt;
&lt;a href="https://react.dev/blog/2022/03/29/react-v18" rel="noopener noreferrer"&gt;https://react.dev/blog/2022/03/29/react-v18&lt;/a&gt;&lt;br&gt;
&lt;a href="https://react.dev/blog/2020/12/21/data-fetching-with-react-server-components" rel="noopener noreferrer"&gt;https://react.dev/blog/2020/12/21/data-fetching-with-react-server-components&lt;/a&gt;&lt;br&gt;
&lt;a href="https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components" rel="noopener noreferrer"&gt;https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#react-server-components&lt;/a&gt;&lt;br&gt;
&lt;a href="https://shopify.github.io/hydrogen-v1/tutorials/react-server-components" rel="noopener noreferrer"&gt;https://shopify.github.io/hydrogen-v1/tutorials/react-server-components&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.plasmic.app/blog/how-react-server-components-work" rel="noopener noreferrer"&gt;https://www.plasmic.app/blog/how-react-server-components-work&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Enhancing Directory Navigation with pushd</title>
      <dc:creator>Ruslan Kh.</dc:creator>
      <pubDate>Fri, 14 Apr 2023 10:51:59 +0000</pubDate>
      <link>https://dev.to/xakrume/enhancing-directory-navigation-with-pushd-2bh4</link>
      <guid>https://dev.to/xakrume/enhancing-directory-navigation-with-pushd-2bh4</guid>
      <description>&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Efficient directory navigation is crucial when working with the command line. In Bash, you can use the pushd command to simplify and improve your directory navigation. pushd allows you to store directories on a stack so that you can switch between them quickly and efficiently. In this article, we will explore the use of pushd and how it can improve your command-line workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using pushd
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;pushd&lt;/code&gt; command is used to change the current working directory while pushing the previous directory onto a stack called the directory stack. This stack is managed by three commands: pushd, popd, and dirs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pushd&lt;/code&gt;: Adds a directory to the stack and changes the current working directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;popd&lt;/code&gt;: Removes the top directory from the stack and changes the current working directory to the new top directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dirs&lt;/code&gt;: Displays the contents of the directory stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Basic pushd usage
&lt;/h2&gt;

&lt;p&gt;To start using &lt;code&gt;pushd&lt;/code&gt;, simply run the command followed by the directory you want to navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pushd&lt;/span&gt; /path/to/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command adds the specified directory to the stack and changes the current working directory. The previous working directory is also stored on the stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Navigating between directories
&lt;/h2&gt;

&lt;p&gt;You can use &lt;code&gt;pushd&lt;/code&gt; to navigate between directories by specifying the directory to switch to. The current directory is pushed to the stack, and the specified directory becomes the new current working directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pushd&lt;/span&gt; /another/path/to/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Going Back to the Previous Directory
&lt;/h2&gt;

&lt;p&gt;To revert to the previous directory, use the pushd command without arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pushd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command swaps the top two directories on the stack and changes the current working directory to the new top directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing the Directory Stack
&lt;/h2&gt;

&lt;p&gt;To view the contents of the directory stack, use the dirs command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;dirs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command displays the directories stored on the stack, with the top directory on the left and the bottom directory on the right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Removing directories from the stack
&lt;/h2&gt;

&lt;p&gt;To remove the top directory from the stack and navigate to the new top directory, use the &lt;code&gt;popd&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;popd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command removes the current directory from the stack and changes the current working directory to the new top directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflow example
&lt;/h2&gt;

&lt;p&gt;Here's an example of how &lt;code&gt;pushd&lt;/code&gt;, &lt;code&gt;popd&lt;/code&gt;, and dirs are used in a typical workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pushd&lt;/span&gt; /path/to/directory1
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pushd&lt;/span&gt; /path/to/directory2
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;dirs&lt;/span&gt; &lt;span class="c"&gt;# Display the directory stack&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;pushd&lt;/span&gt; &lt;span class="c"&gt;# Switch back to the previous directory (/path/to/directory1)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;popd&lt;/span&gt; &lt;span class="c"&gt;# Remove the current directory from the stack and switch to the next one (/path/to/directory2)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;dirs&lt;/span&gt; &lt;span class="c"&gt;# Display the directory stack&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;popd&lt;/span&gt; &lt;span class="c"&gt;# Remove the current directory from the stack and switch to the next one (original directory)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Example 1 : Navigating to different project directories
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Navigate to the first project directory&lt;/span&gt;
&lt;span class="nb"&gt;pushd&lt;/span&gt; /path/to/project1

&lt;span class="c"&gt;# Run commands specific to project1&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running tasks for project1..."&lt;/span&gt;
&lt;span class="c"&gt;# Your commands for project1 here&lt;/span&gt;

&lt;span class="c"&gt;# Navigate to the second project directory&lt;/span&gt;
&lt;span class="nb"&gt;pushd&lt;/span&gt; /path/to/project2

&lt;span class="c"&gt;# Run commands specific to project2&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running tasks for project2..."&lt;/span&gt;
&lt;span class="c"&gt;# Your commands for project2 here&lt;/span&gt;

&lt;span class="c"&gt;# Return to the first project directory&lt;/span&gt;
&lt;span class="nb"&gt;popd&lt;/span&gt;

&lt;span class="c"&gt;# Run cleanup tasks for project1&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Cleaning up project1..."&lt;/span&gt;
&lt;span class="c"&gt;# Your cleanup commands for project1 here&lt;/span&gt;

&lt;span class="c"&gt;# Return to the original directory&lt;/span&gt;
&lt;span class="nb"&gt;popd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Example 2: Temporarily navigating to a subdirectory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Navigate to a subdirectory&lt;/span&gt;
&lt;span class="nb"&gt;pushd&lt;/span&gt; ./subdir

&lt;span class="c"&gt;# Run commands in the subdirectory&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running tasks in subdir..."&lt;/span&gt;
&lt;span class="c"&gt;# Your commands for subdir here&lt;/span&gt;

&lt;span class="c"&gt;# Return to the original directory&lt;/span&gt;
&lt;span class="nb"&gt;popd&lt;/span&gt;

&lt;span class="c"&gt;# Continue executing the script in the original directory&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running tasks in the original directory..."&lt;/span&gt;
&lt;span class="c"&gt;# Your commands for the original directory here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Example 3: Looping through multiple directories
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# An array of directories to process&lt;/span&gt;
&lt;span class="nv"&gt;directories&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;
  &lt;span class="s2"&gt;"/path/to/directory1"&lt;/span&gt;
  &lt;span class="s2"&gt;"/path/to/directory2"&lt;/span&gt;
  &lt;span class="s2"&gt;"/path/to/directory3"&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;dir &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;directories&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c"&gt;# Navigate to the directory&lt;/span&gt;
  &lt;span class="nb"&gt;pushd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="c"&gt;# Run commands specific to the current directory&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Processing directory: &lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="c"&gt;# Your commands for the current directory here&lt;/span&gt;

  &lt;span class="c"&gt;# Return to the original directory&lt;/span&gt;
  &lt;span class="nb"&gt;popd
&lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By using the &lt;code&gt;pushd&lt;/code&gt;, &lt;code&gt;popd&lt;/code&gt;, and &lt;code&gt;dirs&lt;/code&gt; commands, you can greatly improve your command line directory navigation experience. These commands allow you to store directories on a stack and quickly switch between them, making it easier to manage multiple directories and improving your workflow.&lt;/p&gt;

</description>
      <category>bash</category>
      <category>linux</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>ESXiArgs encryption malware launches massive attacks against VMware ESXi servers</title>
      <dc:creator>Ruslan Kh.</dc:creator>
      <pubDate>Mon, 06 Feb 2023 13:07:26 +0000</pubDate>
      <link>https://dev.to/xakrume/esxiargs-encryption-malware-launches-massive-attacks-against-vmware-esxi-servers-pfe</link>
      <guid>https://dev.to/xakrume/esxiargs-encryption-malware-launches-massive-attacks-against-vmware-esxi-servers-pfe</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8plwtl0ip9ytjfrj5g3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8plwtl0ip9ytjfrj5g3.jpg" alt="Image description" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hosting providers and &lt;a href="https://www.cert.ssi.gouv.fr/alerte/CERTFR-2023-ALE-015" rel="noopener noreferrer"&gt;CERT-FR&lt;/a&gt; warn: A new ransomware named ESXiArgs has compromised more than 3,200 VMware ESXi servers in a recent massive hacking campaign. The attackers are exploiting a two-year-old vulnerability (&lt;a href="https://www.zerodayinitiative.com/blog/2021/3/1/cve-2020-3992-amp-cve-2021-21974-pre-auth-remote-code-execution-in-vmware-esxi" rel="noopener noreferrer"&gt;CVE-2021-21974&lt;/a&gt;) in OpenSLP (port 427) that allows them to execute remote commands on the vulnerable servers. The vulnerability is related to a dynamic memory overflow in OpenSLP that can be exploited by unauthenticated attackers. This vulnerability affects ESXi version 7.x, ESXi version 6.7.x, and ESXi version 6.5.x.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7btgogat3y0xwho4i69v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7btgogat3y0xwho4i69v.png" alt="Censys.io results" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once inside the victim's system, the ransomware encrypts the files on the ESXi server and leaves a ransom note demanding $50,000 in bitcoins to decrypt the data. The encrypted files have extensions like &lt;code&gt;.vmxf&lt;/code&gt;, &lt;code&gt;.vmx&lt;/code&gt;, &lt;code&gt;.vmdk&lt;/code&gt;, &lt;code&gt;.vmsd&lt;/code&gt;, and &lt;code&gt;.nvram&lt;/code&gt;. An analysis by experts at OVHcloud suggests that the Nevada encryption engine was responsible for the attacks.&lt;/p&gt;

&lt;p&gt;CERT-FR experts recommend installing patches that have been available for a while and checking all vulnerable systems for signs of compromise. As a last resort, they recommend disabling &lt;a href="https://kb.vmware.com/s/article/76372" rel="noopener noreferrer"&gt;OpenSLP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;An analysis of the malware by IS expert Michael Gillespie shows that the encryptor has no weaknesses that would allow victims to recover files without paying the ransom. The malware uses the Sosemanuk encryption algorithm. Although the malware operators claim to steal data before encrypting it, victims refute this information and their traffic statistics show no signs of data theft.&lt;/p&gt;

&lt;p&gt;It is worth noting that an &lt;a href="https://straightblast.medium.com/my-poc-walkthrough-for-cve-2021-21974-a266bcad14b9" rel="noopener noreferrer"&gt;exploit&lt;/a&gt; for this problem has been available since spring 2021 and appeared shortly after the bug was disclosed. It is not at all clear why attackers would wait until now to exploit this bug.&lt;/p&gt;

&lt;p&gt;CERT-FR experts strongly recommend everyone to install the patches that have long been available as soon as possible and to check all vulnerable systems for signs of compromise. As a last resort, the experts recommend at least disabling OpenSLP.&lt;/p&gt;

&lt;p&gt;An analysis by experts at cloud service provider &lt;a href="https://blog.ovhcloud.com/ransomware-targeting-vmware-esxi/" rel="noopener noreferrer"&gt;OVHcloud&lt;/a&gt; blamed the recent Nevada encryption engine for the massive attacks. The experts wrote that "attacks primarily target ESXi servers up to version 7.0 U3i via the OpenSLP port (427)".&lt;/p&gt;

&lt;p&gt;At the same time, other experts speculated that a version of the Cheerscrypt ransomware, based on leaked sources of the Babuk crypto-ransomware, could be behind the attacks.&lt;/p&gt;

&lt;p&gt;Bleeping Computer reports that victims are actively communicating and asking for help on its &lt;a href="https://www.bleepingcomputer.com/forums/t/782193/esxi-ransomware-help-and-support-topic-esxiargs-args-extension/" rel="noopener noreferrer"&gt;forums&lt;/a&gt;. According to the data collected, most of the affected organizations were using ESXi servers leased from cloud providers.&lt;/p&gt;

&lt;p&gt;The ransomware encrypts files with .vmxf, .vmx, .vmdk, .vmsd, and .nvram extensions on compromised servers, and creates an .args file with metadata for each encrypted document (presumably needed for decryption).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;volume &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\n'&lt;/span&gt; esxcli storage filesystem list | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"/vmfs/volumes/"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;'  ''{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"START VOLUME: &lt;/span&gt;&lt;span class="nv"&gt;$volume&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;file_e &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt; find &lt;span class="s2"&gt;"/vmfs/volumes/&lt;/span&gt;&lt;span class="nv"&gt;$volume&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.vmdk"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.Vmx"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.vmxf"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.vmsd"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.vmsn"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*‚vswp"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"* vmss"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"* .nvram"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"* . vmem"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;do
        if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file_e&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then 
            &lt;/span&gt;&lt;span class="nv"&gt;size_kb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="nv"&gt;$file_e&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$size_kb&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
                &lt;/span&gt;&lt;span class="nv"&gt;size_kb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
            &lt;span class="k"&gt;fi
            &lt;/span&gt;&lt;span class="nv"&gt;size_step&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="nv"&gt;$size_kb&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 128 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
                &lt;/span&gt;&lt;span class="nv"&gt;size_step&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$size_kb&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="o"&gt;)-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;fi 
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"START ENCRYPT: &lt;/span&gt;&lt;span class="nv"&gt;$file_e&lt;/span&gt;&lt;span class="s2"&gt; SIZE: &lt;/span&gt;&lt;span class="nv"&gt;$size_kb&lt;/span&gt;&lt;span class="s2"&gt; STEP SIZE: &lt;/span&gt;&lt;span class="nv"&gt;$size_step&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$file_e&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$size_step&lt;/span&gt;&lt;span class="s2"&gt; 1 &lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;size_kb&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
            &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$size_step&lt;/span&gt; 1 &lt;span class="k"&gt;$((&lt;/span&gt;size_kb&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file_e&lt;/span&gt;&lt;span class="s2"&gt;.args"&lt;/span&gt;
            &lt;span class="nb"&gt;nohup&lt;/span&gt; &lt;span class="nv"&gt;$CLEAN_DIR&lt;/span&gt;/encrypt &lt;span class="nv"&gt;$CLEAN_DIR&lt;/span&gt;/public.pem &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file_e&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;$size_step&lt;/span&gt; 1 &lt;span class="k"&gt;$((&lt;/span&gt;size_kb&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1&amp;amp;
        &lt;span class="k"&gt;fi
    done
    &lt;/span&gt;IFS-&lt;span class="s2"&gt;$" "&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although malware operators claim to steal data before encrypting it, victims refute this information: Victim's traffic statistics show no signs of data theft.&lt;/p&gt;

&lt;p&gt;French cloud provider OVH and the French CERT were the first to report the incident, as most of the affected servers are located in France. According to &lt;a href="https://search.censys.io/search?resource=hosts&amp;amp;sort=RELEVANCE&amp;amp;per_page=25&amp;amp;virtual_hosts=EXCLUDE&amp;amp;q=services.http.response.body%3A+%22How+to+Restore+Your+Files%22+and+services.http.response.html_title%3A%22How+to+Restore+Your+Files%22" rel="noopener noreferrer"&gt;Censys&lt;/a&gt; (ransom note file search), more than 3,200 servers have been encrypted so far, and about a third of them are located in France.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqa7mgmwm9op66bqwnghg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqa7mgmwm9op66bqwnghg.png" alt="ransom note demanding $50,000 in bitcoins to decrypt the data" width="800" height="726"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>career</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Configure Touch ID for sudo access in Terminal.app without prompting for a password to authenticate.</title>
      <dc:creator>Ruslan Kh.</dc:creator>
      <pubDate>Sun, 05 Feb 2023 18:24:59 +0000</pubDate>
      <link>https://dev.to/xakrume/configure-touch-id-for-sudo-access-in-terminalapp-without-prompting-for-a-password-to-authenticate-4ijd</link>
      <guid>https://dev.to/xakrume/configure-touch-id-for-sudo-access-in-terminalapp-without-prompting-for-a-password-to-authenticate-4ijd</guid>
      <description>&lt;p&gt;Devices listed below have fingerprint scanner (Touch ID) to simplify login process but this is not exposed in &lt;strong&gt;Terminal.app&lt;/strong&gt;. So each time you run commands with elevated privileges you need to type in your password.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compatibility list:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MacBook Air (13-inch, M3, 2024)&lt;/li&gt;
&lt;li&gt;MacBook Air (15-inch, M3, 2024)&lt;/li&gt;
&lt;li&gt;MacBook Air (15-inch, M2, 2023)&lt;/li&gt;
&lt;li&gt;MacBook Air (13-inch, M2, 2022)&lt;/li&gt;
&lt;li&gt;MacBook Air (M1, 2020)&lt;/li&gt;
&lt;li&gt;MacBook Pro (13‑inch, M2, 2022)&lt;/li&gt;
&lt;li&gt;MacBook Pro (13-inch, M1, 2020)&lt;/li&gt;
&lt;li&gt;MacBook Pro (14‑inch, 2023)&lt;/li&gt;
&lt;li&gt;MacBook Pro (14‑inch, 2021)&lt;/li&gt;
&lt;li&gt;MacBook Pro (16‑inch, 2023)&lt;/li&gt;
&lt;li&gt;MacBook Pro (16-inch, 2021)&lt;/li&gt;
&lt;li&gt;iMac (24-inch, M3, 2023)&lt;/li&gt;
&lt;li&gt;iMac (24-inch, M1, 2021)&lt;/li&gt;
&lt;li&gt;Mac Studio (2023)&lt;/li&gt;
&lt;li&gt;Mac Studio (2022)&lt;/li&gt;
&lt;li&gt;Mac mini (2023)&lt;/li&gt;
&lt;li&gt;Mac mini (M1, 2020)&lt;/li&gt;
&lt;li&gt;Mac Pro (2023)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzqf186ide3u383w49kr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzqf186ide3u383w49kr.png" alt="Magic Keyboard with Touch ID for Mac models with Apple silicon" width="768" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Magic Keyboard's &lt;strong&gt;Touch ID&lt;/strong&gt; functionality is compatible with the following MacBook/iMac models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MacBook Air (M1, 2020)&lt;/li&gt;
&lt;li&gt;MacBook Pro (13", M1, 2020)&lt;/li&gt;
&lt;li&gt;MacBook Pro (14", 2021)&lt;/li&gt;
&lt;li&gt;MacBook Pro (16", 2021)&lt;/li&gt;
&lt;li&gt;iMac (24", M1, 2021)&lt;/li&gt;
&lt;li&gt;Mac mini (M1, 2020)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note that the keyboard will still pair and function with devices older than those listed, but that &lt;strong&gt;Touch ID&lt;/strong&gt; functionality will not be enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup PAM module to use Touch ID:
&lt;/h2&gt;

&lt;p&gt;To allow &lt;strong&gt;Touch ID&lt;/strong&gt; on your Mac to authenticate you for sudo access instead of a password prompt you need to do the following simple changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open Spotlight:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hdbjskfr2yd7nppwhuh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hdbjskfr2yd7nppwhuh.png" alt="Open Spotlight system application" width="800" height="246"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwi40ryo5pemlimsuxsy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwi40ryo5pemlimsuxsy.png" alt="Spotlight application" width="800" height="166"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Type &lt;code&gt;terminal&lt;/code&gt; in &lt;code&gt;Spotlight&lt;/code&gt; input field and open it:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zwztgiht7pp8dcqq0eb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zwztgiht7pp8dcqq0eb.png" alt="Type " width="800" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Open Terminal:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F939eu9jbi588od5pnnys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F939eu9jbi588od5pnnys.png" alt="Terminal.app" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Switch to the root user.
&lt;/h3&gt;

&lt;p&gt;Switch to the root user by typing the command &lt;code&gt;sudo su -&lt;/code&gt; and enter the password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;su -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3lo8nhqeuvswtf769rx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3lo8nhqeuvswtf769rx.png" alt="switching to root user" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Edit &lt;code&gt;/etc/pam.d/sudo&lt;/code&gt;:
&lt;/h3&gt;

&lt;p&gt;Open the &lt;code&gt;/etc/pam.d/sudo&lt;/code&gt; file with you favorite editor such as &lt;code&gt;vim&lt;/code&gt; or &lt;code&gt;nano&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /etc/pam.d/sudo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafc36097gmik4vpjot35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fafc36097gmik4vpjot35.png" alt="Open /etc/pam.d/sudo" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The contents of this file should look like one of the following example:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3iyb7e1uly6aey8uinm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3iyb7e1uly6aey8uinm.png" alt="/etc/pam.d/sudo file contents" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the following line to the top of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="err"&gt;auth&lt;/span&gt;       &lt;span class="err"&gt;sufficient&lt;/span&gt;     &lt;span class="err"&gt;pam_tid.so&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The modified contents of &lt;code&gt;/etc/pam.d/sudo&lt;/code&gt; file should look like following example:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frbxfay269zctnd39oge5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frbxfay269zctnd39oge5.png" alt="Modified /etc/pam.d/sudo file contents" width="800" height="539"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Save the file:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;for nano, press the specified combination (with sign “+”) of keys simultaneously:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CTRL+o 
CTRL+x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;for vim:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;ESC&amp;gt;
:wq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Allow the system to save the changes.
&lt;/h3&gt;

&lt;p&gt;Press OK button:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cj1umo4ltt4cby8zyj5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cj1umo4ltt4cby8zyj5.png" alt="Allow to modify system settings" width="744" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Also note that pam_smartcard.so may not be present on older MacOS versions. Tested with macOS Ventura (13.1).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Exit from the shell.
&lt;/h3&gt;

&lt;p&gt;Exit from the &lt;code&gt;root&lt;/code&gt; shell by typing command: &lt;code&gt;exit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Try to use &lt;code&gt;sudo&lt;/code&gt;, and you should be prompted to authenticate with &lt;strong&gt;Touch ID&lt;/strong&gt; as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo echo&lt;/span&gt; &lt;span class="s2"&gt;"Check Touch ID"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8oa107ab6idf7qos5wer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8oa107ab6idf7qos5wer.png" alt="Running Touch ID with sudo comand" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click ‘Cancel,’ you can just enter your password at the terminal prompt. If you click ‘Use Password’ you can enter your password in the dialog box.&lt;/p&gt;

&lt;p&gt;If you connect to your macOS via SSH, it will revert to using your password, since you cannot send &lt;strong&gt;Touch ID&lt;/strong&gt; fingerprints over SSH.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Recent MacOS updates may remove the entry. If &lt;strong&gt;Touch ID&lt;/strong&gt; stops working for &lt;code&gt;sudo&lt;/code&gt; then check if the entry was removed and add it back in, following these instructions again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  F.A.Q.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does it work with &lt;a href="https://www.warp.dev" rel="noopener noreferrer"&gt;Warp terminal&lt;/a&gt;?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Yes, additional settings are &lt;strong&gt;not required&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpmcq8ycalqzkhch94gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpmcq8ycalqzkhch94gg.png" alt="Warp terminal and Touch ID" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Does it work with &lt;a href="https://iterm2.com" rel="noopener noreferrer"&gt;iTerm2&lt;/a&gt;?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Yes, but additional settings may be &lt;strong&gt;required&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82po3sd1n12khycr918k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82po3sd1n12khycr918k.png" alt="iTerm2 terminal and Touch ID" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are using &lt;strong&gt;iTerm2&lt;/strong&gt; (v3.2.8+), you may have noticed that &lt;strong&gt;Touch ID&lt;/strong&gt; does not work with &lt;code&gt;sudo&lt;/code&gt; in the terminal, even though you have done the &lt;code&gt;pam_tid.so&lt;/code&gt; modification above and it worked in earlier versions. This is due to an &lt;a href="https://gitlab.com/gnachman/iterm2/issues/7608#note_153123852" rel="noopener noreferrer"&gt;advanced feature&lt;/a&gt; that seems to be enabled by default now - it needs to be disabled here: &lt;strong&gt;iTerm2-&amp;gt;Preferences &amp;gt; Advanced &amp;gt; Allow sessions to survive logouts and logins&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23h208a0rgl3yrcrqpos.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F23h208a0rgl3yrcrqpos.png" alt="Set to " width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devto</category>
      <category>announcement</category>
      <category>offers</category>
    </item>
    <item>
      <title>Identifying Disks in Dedicated Servers</title>
      <dc:creator>Ruslan Kh.</dc:creator>
      <pubDate>Sun, 05 Feb 2023 17:58:40 +0000</pubDate>
      <link>https://dev.to/xakrume/identifying-disks-in-dedicated-servers-298e</link>
      <guid>https://dev.to/xakrume/identifying-disks-in-dedicated-servers-298e</guid>
      <description>&lt;p&gt;Maintaining a server's health is crucial for ensuring smooth operation of a business or organization's IT infrastructure. One of the tasks involved in maintaining a server's health is replacing failed or failing disks. However, identifying which disk needs to be replaced can be a difficult and dangerous task if the correct procedures are not followed.&lt;/p&gt;

&lt;p&gt;It is often necessary to identify disks for a number of reasons, including replacing a failed disk, searching for a specific disk, or upgrading to faster or larger disks. &lt;/p&gt;

&lt;p&gt;If there is a large number of servers located in different data centers, it is not always possible to independently replace the disk in the server, in this case the replacement is performed by data center engineers, who should be prepared, which drive must be replaced, indicating the rack and the unit in which the server is located.&lt;/p&gt;

&lt;p&gt;To reduce the risks, it is important to have a clear method of indicating which drive needs to be replaced. This can be done using platform tools such as disk LED indicators.&lt;/p&gt;

&lt;p&gt;In this article, we will discuss the importance of highlighting the disk that needs to be replaced, the difficulties involved in identifying the disk in the server, and the dangers of disconnecting the wrong disk. We will also provide an overview of the different methods available for highlighting the disk that needs to be replaced, so that administrators can make informed decisions about which solution best suits their needs.&lt;/p&gt;

&lt;p&gt;Why is disk identification important? In many cases, servers are configured with RAID arrays, which provide redundancy and improves perfomance. If a disk fails, it is essential to identify the correct disk to replace it in order to maintain the integrity of the system. When upgrading disks, it is also important to ensure that the correct disk is targeted to avoid any potential data loss.&lt;/p&gt;

&lt;p&gt;Risks of incorrectly chosen disks. If the wrong disk is identified, there is a high risk of data loss and system damage, particularly in the case of RAID1 arrays. Before performing any disk-related operations, it is important to take precautions to prevent such risks.&lt;/p&gt;

&lt;p&gt;In this article, we will cover two popular server systems: Huawei and Supermicro, and provide a guide on how to identify disks in both systems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figm0raqnrppr8xn0se6e.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figm0raqnrppr8xn0se6e.jpg" alt="Supermicro front view" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before performing any disk-related operations, it is important to check the contents of the &lt;code&gt;locate&lt;/code&gt; file and set the value to &lt;code&gt;0&lt;/code&gt;  to ensure that the disk you are manipulating is the one you need.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;find /sys &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'locate'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;echo &lt;/span&gt;0 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Huawei.
&lt;/h3&gt;

&lt;p&gt;Disk Identification on Huawei servers.&lt;/p&gt;

&lt;p&gt;We will assume that the failed disk has the identification &lt;code&gt;/dev/sdaj&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To identify a disk in a Huawei server, you can use the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the system shell&lt;/li&gt;
&lt;li&gt;Locate the disk:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; /sys/class/enclosure/&lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;/device/block/sdaj    &amp;lt;TAB&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use the TAB key to autocomplete the device name, for example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; /sys/class/enclosure/0&lt;span class="se"&gt;\:&lt;/span&gt;0&lt;span class="se"&gt;\:&lt;/span&gt;38&lt;span class="se"&gt;\:&lt;/span&gt;0/ArrayDevice23/device/block/sdaj/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To find the location of the ArrayDevice, run the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; find /sys &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"locate"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;ArrayDevice23

/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/host0/port-0:0/expander-0:0/port-0:0:38/end_device-0:0:38/target0:0:38/0:0:38:0/enclosure/0:0:38:0/ArrayDevice23/locate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Turn on the UID LED:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;1 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/host0/port-0:0/expander-0:0/port-0:0:38/end_device-0:0:38/target0:0:38/0:0:38:0/enclosure/0:0:38:0/ArrayDevice23/locate'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Supermicro.
&lt;/h3&gt;

&lt;p&gt;Disk Identification on Supermicro servers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When using Supermicro, I came across two ways to identify disks. The only difference is the presence of a space in the slot name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Method #1
&lt;/h4&gt;

&lt;p&gt;We will assume that the failed disk has the identification &lt;code&gt;/dev/sda&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the system shell&lt;/li&gt;
&lt;li&gt;Locate the disk:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; /sys/class/enclosure/&lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;/device/block/sda    &amp;lt;TAB&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use the TAB key to autocomplete the device name, for example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; /sys/class/enclosure/1&lt;span class="se"&gt;\:&lt;/span&gt;0&lt;span class="se"&gt;\:&lt;/span&gt;13&lt;span class="se"&gt;\:&lt;/span&gt;0/Slot00/device/block/sda/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To find the location of the ArrayDevice, run the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; find /sys &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"locate"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;Slot00
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/host1/port-1:1/expander-1:1/port-1:1:11/end_device-1:1:11/target1:0:25/1:0:25:0/enclosure/1:0:25:0/Slot00/locate
/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/host1/port-1:0/expander-1:0/port-1:0:13/end_device-1:0:13/target1:0:13/1:0:13:0/enclosure/1:0:13:0/Slot00/locate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Turn on the UID LED:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;1 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/host1/port-1:1/expander-1:1/port-1:1:11/end_device-1:1:11/target1:0:25/1:0:25:0/enclosure/1:0:25:0/Slot00/locate'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Method #2
&lt;/h4&gt;

&lt;p&gt;We will assume that the failed disk has the identification &lt;code&gt;/dev/sdh&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the system shell&lt;/li&gt;
&lt;li&gt;Locate the disk:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; /sys/class/enclosure/&lt;span class="k"&gt;*&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;/device/block/sdh/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use the TAB key to autocomplete the device name, for example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;ls&lt;/span&gt; /sys/class/enclosure/0&lt;span class="se"&gt;\:&lt;/span&gt;0&lt;span class="se"&gt;\:&lt;/span&gt;25&lt;span class="se"&gt;\:&lt;/span&gt;0/Slot&lt;span class="se"&gt;\ &lt;/span&gt;08/device/block/sdh/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To find the location of the ArrayDevice, run the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; find /sys &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"locate"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;Slot&lt;span class="se"&gt;\ &lt;/span&gt;08
/sys/devices/pci0000:00/0000:00:02.2/0000:03:00.0/host0/port-0:1/expander-0:1/port-0:1:0/end_device-0:1:0/target0:0:25/0:0:25:0/enclosure/0:0:25:0/Slot 08/locate
/sys/devices/pci0000:00/0000:00:02.2/0000:03:00.0/host0/port-0:0/expander-0:0/port-0:0:24/end_device-0:0:24/target0:0:24/0:0:24:0/enclosure/0:0:24:0/Slot 08/locate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Turn on the UID LED:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;1 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/sys/devices/pci0000:00/0000:00:02.2/0000:03:00.0/host0/port-0:0/expander-0:0/port-0:0:24/end_device-0:0:24/target0:0:24/0:0:24:0/enclosure/0:0:24:0/Slot 08/locate'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some cases to identify a disk in server, you will need to use a specialized disk compatible with controller that has the ability to analyze errors and display an indicator, usually in red. The process may differ depending on the platform, so it is recommended to consult the user manual or vendor's documentation for specific instructions.&lt;/p&gt;

&lt;p&gt;In exceptional cases where there is no UID LED indication, you can use less reliable methods. For example by loading the drive with reads, which will cause a continuous green LED indication.&lt;/p&gt;

&lt;p&gt;In conclusion, disk identification is an important aspect of server management that must be performed with care to prevent data loss and system damage. By following the steps outlined in this guide, you can identify disks in Huawei and Supermicro servers with confidence. I hope my experience will help you to identify disks when it is not possible to enable disk UID indication using IPMI.&lt;/p&gt;

</description>
      <category>announcement</category>
      <category>devto</category>
      <category>community</category>
      <category>offers</category>
    </item>
  </channel>
</rss>
