> ## Documentation Index
> Fetch the complete documentation index at: https://felimet-hub.jmcores.com/llms.txt
> Use this file to discover all available pages before exploring further.

# WSL Ubuntu System Migration Guide

> Move a space-hungry WSL Ubuntu off the C drive to another disk: package and redeploy with wsl --export / --import, keeping all software and settings while freeing system-drive space.

export const TerminalDemo = ({lang = "zh", title, prompt, commands}) => {
  const L = ({
    zh: {
      play: "播放",
      pause: "暫停",
      step: "下一步",
      replay: "重新播放",
      reset: "重設",
      winTitle: "Windows PowerShell",
      hint: "點播放，逐行看驗證流程實際跑出來的樣子"
    },
    en: {
      play: "Play",
      pause: "Pause",
      step: "Step",
      replay: "Replay",
      reset: "Reset",
      winTitle: "Windows PowerShell",
      hint: "Press play to watch the verification run line by line"
    }
  })[lang] || ({});
  const defaultCmds = [{
    cmd: "nvidia-smi",
    output: ["Mon Jun  8 14:30:12 2026", "+-----------------------------------------------------------------------------+", "| NVIDIA-SMI 552.22       Driver Version: 552.22       CUDA Version: 12.4     |", "|-------------------------------+----------------------+----------------------+", "| GPU  Name           TCC/WDDM  | Bus-Id        Disp.A | Volatile Uncorr. ECC |", "| Fan  Temp Perf Pwr:Usage/Cap  | Memory-Usage         | GPU-Util  Compute M. |", "|===============================+======================+======================|", "|   0  GeForce RTX 3080  WDDM   | 00000000:01:00.0  On |                  N/A |", "| 30%   42C  P8    21W / 320W   |    842MiB / 10240MiB |      2%      Default |", "+-------------------------------+----------------------+----------------------+"]
  }, {
    cmd: "nvcc -V",
    output: ["nvcc: NVIDIA (R) Cuda compiler driver", "Copyright (c) 2005-2024 NVIDIA Corporation", "Built on Tue_Feb_27_16:28:36_2024", "Cuda compilation tools, release 12.4, V12.4.99", "Build cuda_12.4.r12.4/compiler.34097967_0"]
  }, {
    cmd: "python gpu_test.py",
    output: ["========================================", "PyTorch Version: 2.6.0+cu124", "CUDA Available:  True", "Device Name:     NVIDIA GeForce RTX 3080", "CUDA Version:    12.4", "✓ cuDNN Test Passed! Convolution executed successfully.", "========================================"]
  }];
  const raw = commands && commands.length ? commands : defaultCmds;
  const cmds = raw.map(c => ({
    cmd: c.cmd,
    lines: Array.isArray(c.output) ? c.output : String(c.output || "").split("\n")
  }));
  const PROMPT = prompt || "PS C:\\Users\\dev>";
  const TITLE = title || L.winTitle;
  const [idx, setIdx] = useState(0);
  const [typed, setTyped] = useState(0);
  const [outN, setOutN] = useState(0);
  const [stage, setStage] = useState("cmd");
  const [running, setRunning] = useState(false);
  const [done, setDone] = useState(false);
  useEffect(() => {
    if (!running || done) return;
    const cur = cmds[idx];
    if (!cur) {
      setRunning(false);
      setDone(true);
      return;
    }
    if (stage === "cmd") {
      if (typed < cur.cmd.length) {
        const id = setTimeout(() => setTyped(typed + 1), 28);
        return () => clearTimeout(id);
      }
      const id = setTimeout(() => setStage("out"), 200);
      return () => clearTimeout(id);
    }
    if (stage === "out") {
      if (outN < cur.lines.length) {
        const id = setTimeout(() => setOutN(outN + 1), 70);
        return () => clearTimeout(id);
      }
      const id = setTimeout(() => {
        if (idx + 1 < cmds.length) {
          setIdx(idx + 1);
          setTyped(0);
          setOutN(0);
          setStage("cmd");
        } else {
          setRunning(false);
          setDone(true);
        }
      }, 360);
      return () => clearTimeout(id);
    }
  }, [running, done, idx, typed, outN, stage]);
  const reset = () => {
    setRunning(false);
    setDone(false);
    setIdx(0);
    setTyped(0);
    setOutN(0);
    setStage("cmd");
  };
  const playPause = () => {
    if (done) {
      reset();
      setRunning(true);
      return;
    }
    setRunning(!running);
  };
  const step = () => {
    setRunning(false);
    if (done) return;
    if (idx + 1 < cmds.length) {
      setIdx(idx + 1);
      setTyped(0);
      setOutN(0);
      setStage("cmd");
    } else {
      const cur = cmds[idx];
      setTyped(cur.cmd.length);
      setOutN(cur.lines.length);
      setStage("out");
      setDone(true);
    }
  };
  const css = `
.td-root{--bg:#f4eee4;--bd:#e2d7c6;--ink:#5b5048;--accent:#bf7551;--accent-l:#cf8a68;
  --scr:#1c1815;--scr-fg:#e9e1d4;--scr-prompt:#cf8a68;--scr-dim:#8d8478;--scr-ok:#8fb573;--scr-err:#d98a72;
  border:1px solid var(--bd);border-radius:14px;overflow:hidden;background:var(--bg);
  font-family:ui-sans-serif,system-ui,"Noto Sans TC",sans-serif;margin:1.25rem 0;box-shadow:0 1px 2px rgba(60,40,25,.06);}
.dark .td-root{--bg:#26221e;--bd:#3a332c;--ink:#cabfb2;}
.td-bar{display:flex;align-items:center;gap:.6rem;padding:.55rem .8rem;background:linear-gradient(var(--bg),color-mix(in srgb,var(--bg) 90%,#000));border-bottom:1px solid var(--bd);}
.td-dots{display:flex;gap:.4rem;}
.td-dots i{width:11px;height:11px;border-radius:50%;display:block;}
.td-dots i:nth-child(1){background:#d98a72;} .td-dots i:nth-child(2){background:#dcb46a;} .td-dots i:nth-child(3){background:#8fb573;}
.td-title{font-size:.78rem;color:var(--ink);font-weight:600;letter-spacing:.01em;flex:1;text-align:center;opacity:.85;}
.td-ctrl{display:flex;align-items:center;gap:.3rem;}
.td-btn{display:inline-flex;align-items:center;gap:.32rem;border:1px solid var(--bd);background:transparent;color:var(--ink);
  border-radius:8px;padding:.3rem .55rem;font-size:.74rem;font-weight:600;cursor:pointer;transition:all .15s ease;line-height:1;}
.td-btn:hover{border-color:var(--accent);color:var(--accent);background:color-mix(in srgb,var(--accent) 10%,transparent);}
.td-btn svg{width:13px;height:13px;}
.td-btn--primary{background:var(--accent);border-color:var(--accent);color:#fff;}
.dark .td-btn--primary{background:var(--accent-l);border-color:var(--accent-l);}
.td-btn--primary:hover{background:var(--accent-l);color:#fff;}
.td-count{font-size:.72rem;color:var(--ink);opacity:.6;font-variant-numeric:tabular-nums;margin-left:.2rem;}
.td-screen{background:var(--scr);color:var(--scr-fg);padding:.85rem 1rem 1.05rem;font-family:ui-monospace,"Cascadia Code","Consolas",monospace;
  font-size:.8rem;line-height:1.55;overflow-x:auto;min-height:120px;}
.td-block{margin-bottom:.5rem;}
.td-cmdline{white-space:pre;}
.td-prompt{color:var(--scr-prompt);font-weight:600;}
.td-cmd{color:#f3ecdf;}
.td-out{white-space:pre;color:var(--scr-fg);opacity:.92;}
.td-out.ok{color:var(--scr-ok);font-weight:600;}
.td-out.err{color:var(--scr-err);font-weight:600;}
.td-cursor{display:inline-block;width:8px;height:1em;background:var(--scr-prompt);margin-left:1px;vertical-align:text-bottom;
  animation:tdblink 1s steps(2,start) infinite;}
@keyframes tdblink{to{opacity:0;}}
.td-hint{padding:.5rem .9rem;font-size:.72rem;color:var(--ink);opacity:.6;border-top:1px solid var(--bd);background:var(--bg);}
@media (max-width:600px){.td-screen{font-size:.68rem;} .td-title{display:none;} .td-btn{padding:.28rem .42rem;}}
`;
  const PlayIcon = () => <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M7 5.5v13l11-6.5z" /></svg>;
  const PauseIcon = () => <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><rect x="6.5" y="5" width="4" height="14" rx="1" /><rect x="13.5" y="5" width="4" height="14" rx="1" /></svg>;
  const StepIcon = () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 4l10 8-10 8z" /><line x1="19" y1="5" x2="19" y2="19" /></svg>;
  const ResetIcon = () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12a9 9 0 1 0 3-6.7L3 8" /><path d="M3 3v5h5" /></svg>;
  const shown = Math.min(idx + (done ? 1 : 0), cmds.length);
  return <div className="td-root">
      <style>{css}</style>
      <div className="td-bar">
        <span className="td-dots"><i /><i /><i /></span>
        <span className="td-title">{TITLE}</span>
        <span className="td-ctrl">
          <button className="td-btn td-btn--primary" onClick={playPause}>
            {running ? <PauseIcon /> : <PlayIcon />}
            {done ? L.replay : running ? L.pause : L.play}
          </button>
          <button className="td-btn" onClick={step} disabled={done}><StepIcon />{L.step}</button>
          <button className="td-btn" onClick={reset}><ResetIcon />{L.reset}</button>
          <span className="td-count">{shown}/{cmds.length}</span>
        </span>
      </div>
      <div className="td-screen">
        {Array.from({
    length: idx + 1
  }).map((_, i) => {
    const c = cmds[i];
    if (!c) return null;
    const isCur = i === idx;
    const cmdText = isCur ? c.cmd.slice(0, typed) : c.cmd;
    const lines = isCur ? c.lines.slice(0, outN) : c.lines;
    const cursor = isCur && !done && stage === "cmd";
    return <div className="td-block" key={i}>
              <div className="td-cmdline">
                <span className="td-prompt">{PROMPT}</span> <span className="td-cmd">{cmdText}</span>
                {cursor && <span className="td-cursor" />}
              </div>
              {lines.map((ln, j) => {
      const tr = ln.trim();
      const cls = tr.startsWith("✓") ? "ok" : tr.startsWith("✗") || tr.startsWith("✘") ? "err" : "";
      return <div className={"td-out " + cls} key={j}>{ln.length ? ln : " "}</div>;
    })}
            </div>;
  })}
      </div>
      <div className="td-hint">{L.hint}</div>
    </div>;
};

`WSL` `Ubuntu` `Windows`

Move a WSL Ubuntu that eats up C-drive space to another disk, freeing the system drive while keeping all installed software and settings. The approach: package with `wsl --export` into a tar, redeploy with `wsl --import` to the new location, switch the default, then clean up the old install.

<Note>
  The migration temporarily stops the WSL service, so do it outside working hours. The whole process takes about 30 minutes to 2 hours depending on system size.
</Note>

## Before you start

### Requirements

| Item            | Minimum           | Recommended       | Notes                                  |
| --------------- | ----------------- | ----------------- | -------------------------------------- |
| Disk space      | Ubuntu size × 1.2 | Ubuntu size × 1.5 | Target disk needs enough room          |
| RAM             | 4GB               | 8GB+              | Large systems need more memory         |
| Windows version | Windows 10 v1903  | Windows 11        | Newer versions have better WSL support |
| Privileges      | Standard user     | Administrator     | Admin rights avoid permission issues   |

### Backup strategy

Migration is relatively safe, but take precautions first.

<Tabs>
  <Tab title="Back up key data">
    Ubuntu is fully packaged and redeployed during migration. Back up important user data to the cloud or external storage, especially:

    * `/home/<username>/`: user home directory
    * `/opt/`: third-party software
    * custom config files
  </Tab>

  <Tab title="System restore point">
    Create a Windows system restore point to roll back to the pre-migration state if needed:

    1. Open "System Protection" settings
    2. Select the system drive
    3. Create a restore point with a descriptive label
  </Tab>
</Tabs>

<Warning>
  Allow enough time for the migration and do not cut power or shut down mid-process.
</Warning>

## Migration steps

<Steps>
  <Step title="Check system state">
    Open PowerShell as administrator and list all WSL distros (name, state, WSL version, default marker):

    ```powershell theme={null}
    wsl -l -v
    ```

    <Note>Record the exact distro name (e.g. `Ubuntu-22.04`); later steps use it.</Note>
  </Step>

  <Step title="Package the Ubuntu system">
    Export the current Ubuntu to a portable tar (adjust the distro name and target path):

    ```powershell theme={null}
    wsl --export Ubuntu-22.04 D:\ubuntu-22.04-backup.tar
    ```

    | Parameter                    | Example     | Notes                                |
    | ---------------------------- | ----------- | ------------------------------------ |
    | `Ubuntu-22.04`               | distro name | The name confirmed in step 1         |
    | `D:\ubuntu-22.04-backup.tar` | export path | Full path and filename of the backup |

    <Warning>The export shows no progress and runs continuously. Be patient and do not interrupt it or close the window. Watch the target file size to monitor progress.</Warning>
  </Step>

  <Step title="Deploy to the new location">
    Create the migrated Ubuntu instance:

    ```powershell theme={null}
    wsl --import Ubuntu-22.04-diskD D:\Ubuntu-22.04-diskD D:\ubuntu-22.04-backup.tar
    ```

    The parameters are, in order: new instance name (your choice), the folder where its files actually live, and the export path from step 2. Use a descriptive name (e.g. `Ubuntu-DataDisk`) and avoid special characters and spaces. Run `wsl -l -v` again to confirm the new instance appears.
  </Step>

  <Step title="Set default and fix the user">
    Point the default WSL distro at the new instance:

    ```powershell theme={null}
    wsl --setdefault Ubuntu-22.04-diskD
    ```

    <Warning>
      **After `wsl --import` the default user becomes root** (imported distros do not keep the original default user). Create `/etc/wsl.conf` inside the new instance to set the default user, then `wsl --shutdown` to restart and log in as your normal account:

      ```ini theme={null}
      [user]
      default=<your-username>
      ```
    </Warning>

    Verify it starts:

    ```powershell theme={null}
    wsl
    ```
  </Step>

  <Step title="Clean up the old system">
    Once the new environment works, remove the old Ubuntu to free the C drive:

    ```powershell theme={null}
    wsl --unregister Ubuntu-22.04
    ```

    <Warning>This permanently deletes the old Ubuntu install. Be sure the new environment works before running it.</Warning>

    Use Disk Cleanup to check the C-drive gain, confirm the WSL folder is gone, and run `wsl -l -v` to confirm the old distro disappeared. Keep the tar as an extra backup for a while, then delete once stable:

    ```powershell theme={null}
    del D:\ubuntu-22.04-backup.tar
    ```
  </Step>
</Steps>

Here is roughly what the full migration flow looks like, from confirming the source through export, deploy, and verifying the new instance:

<TerminalDemo
  lang="en"
  title="Windows PowerShell"
  prompt={"PS C:\\>"}
  commands={[
{
  cmd: "wsl -l -v",
  output: [
    "  NAME            STATE           VERSION",
    "* Ubuntu-22.04    Running         2",
  ],
},
{
  cmd: "wsl --export Ubuntu-22.04 D:\\ubuntu-22.04-backup.tar",
  output: [
    "Exporting the distribution, this may take a few minutes...",
    "The operation completed successfully.",
  ],
},
{
  cmd: "wsl --import Ubuntu-22.04-diskD D:\\Ubuntu-22.04-diskD D:\\ubuntu-22.04-backup.tar",
  output: [
    "Importing the distribution...",
    "The operation completed successfully.",
  ],
},
{
  cmd: "wsl -l -v",
  output: [
    "  NAME                  STATE           VERSION",
    "* Ubuntu-22.04          Stopped         2",
    "  Ubuntu-22.04-diskD    Stopped         2",
  ],
},
]}
/>

## Troubleshooting

<Tabs>
  <Tab title="Export fails">
    | Cause                    | Check                    | Fix                        |
    | ------------------------ | ------------------------ | -------------------------- |
    | Not enough disk space    | Check target free space  | Free space or switch disks |
    | Insufficient privileges  | Confirm running as admin | Reopen PowerShell as admin |
    | Ubuntu not fully stopped | Check WSL state          | `wsl --shutdown` and retry |
  </Tab>

  <Tab title="Deploy errors">
    Check in order:

    1. Verify the tar: `wsl --list --verbose`
    2. Clean residual instance: `wsl --unregister Ubuntu-22.04-diskD`
    3. Redeploy: `wsl --import Ubuntu-22.04-diskD D:\Ubuntu-22.04-diskD D:\ubuntu-22.04-backup.tar`
  </Tab>

  <Tab title="Startup issues">
    If the new environment will not start:

    1. Check all instance states: `wsl --list --verbose`
    2. Force-terminate the bad instance: `wsl --terminate Ubuntu-22.04-diskD`
    3. Start the specific distro: `wsl --distribution Ubuntu-22.04-diskD`
  </Tab>
</Tabs>

### Emergency recovery

If migration hits a serious, unrecoverable problem:

1. Verify the original tar exists and is intact
2. Clean the problem instance: `wsl --unregister Ubuntu-22.04-diskD`
3. Redeploy with the same import command
4. If still broken, temporarily fall back to the original instance until resolved

<Warning>Recovery returns to the pre-migration state but loses any changes made during migration. Evaluate carefully before running it.</Warning>
