Skip to content

tree: add windows tree support#3440

Open
bcapener wants to merge 4 commits into
linux-nvme:masterfrom
Micron-TPG-OSS:bcapener/add-tree-support
Open

tree: add windows tree support#3440
bcapener wants to merge 4 commits into
linux-nvme:masterfrom
Micron-TPG-OSS:bcapener/add-tree-support

Conversation

@bcapener

@bcapener bcapener commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Add tree.c and lib.c support. Adds ctrl-map.c for mapping controller name, nvmeX, to controller path, since windows controller paths might not fit within the d_name field of the dirent struct. The ctrl-map also creates a subsystem name to replicate linux's nvme-subsysX naming.

@bcapener bcapener marked this pull request as ready for review June 10, 2026 20:04
@igaw

igaw commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

The patch is too big to be properly reviewed. Can you at least split into two parts, the first one refactoring the existing code before adding new code?

@bcapener

Copy link
Copy Markdown
Contributor Author

Good idea. Sorry, I could not think of a better way to split this up. The refactoring of the existing code can be found here #3450 , I'll use the PR for adding the new code.

@igaw

igaw commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

I've merged #3450 so you can rebase this PR :)

@bcapener bcapener marked this pull request as draft June 17, 2026 15:32
@bcapener bcapener force-pushed the bcapener/add-tree-support branch from 0b4d062 to 9f6484f Compare June 17, 2026 15:54
@bcapener bcapener marked this pull request as ready for review June 17, 2026 16:06
@bcapener

Copy link
Copy Markdown
Contributor Author

Thanks Daniel, I have rebased this PR with upstream changes.

Comment thread libnvme/src/nvme/ctrl-map.c
Comment thread libnvme/src/nvme/ctrl-map.c Outdated
size_t count;
size_t capacity;
bool initialized;
} ctrl_map;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not using the ccan hash table here? It should work for the use case here as far I can tell.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I reworked it to use ccan hash tables

Comment thread libnvme/src/nvme/ctrl-map.c Outdated
Comment thread libnvme/src/nvme/ctrl-map.c Outdated
struct libnvme_passthru_cmd cmd;
int ret;

ctx = libnvme_create_global_ctx(NULL, LIBNVME_DEFAULT_LOGLEVEL);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A don't think this should be here. Creating inside the library a global context is not correct.

@bcapener bcapener Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, i have removed this and passed it as an argument. thanks!


*ctrls = NULL;

libnvme_ctrl_map_clear();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see why you had to create global context hidden inside the ctrl map code. I suppose we should look how to extend the scan API in a sane way.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I got this right, we should add the global context to the filter APIs. This would allow to pass it down into the library. Let me try this quickly.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we could even ditch the whole filter API on closer inspection...

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to get rid of all the libnvme_filter_ public API and added the all libnvme_scan_ functions a global context when it didn't have anything else like libnvme_ctrl_t. That means all the scan functions should then have access to the global context either directly or indirectly through an other object.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. thanks

Comment thread libnvme/src/nvme/lib-win.c Outdated
if (hostnqn)
hnqn = strdup(hostnqn);
else
hnqn = strdup("nqn.2014-08.org.nvmexpress:uuid:00000000-0000-0000-0000-000000000000");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't Microsoft have a default UUID? Should be we just use one instead providing an NULL one?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth this trouble for a value that will not be used on windows? from what I understand Host NQN and Host ID are for fabrics. Or are there other multi-host scenarios that I am not aware of?

Microsoft does have UUIDs but I am not sure they are equivalent.
Options are:

  1. Windows MachineGuid: found in registry, HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid, used as a Windows-installation identifier. It is generated during Windows installation. Caveat: MachineGuid is tied to the Windows installation, not necessarily the physical host. It can be duplicated if an image/VM was cloned without proper generalization, and it can change after reinstall/sysprep.
  2. SMBIOS System UUID: From microsoft's docs "Universally unique identifier (UUID) for this product. A UUID is a 128-bit identifier that is guaranteed to be different from other generated UUIDs. If a UUID is not available, a UUID of all zeros is used." link. Caveat: In real systems, especially VMs, lab platforms, broken BIOS implementations, and cloned images, SMBIOS UUID can be all zeroes, all FFs, duplicated, or changed by virtualization settings.
  3. nvme-cli manages: An LLM suggested the the only way to get the equivalent of linux's /etc/nvme/hostid would be to generate the UUID ourselves and save the value somewhere, like in the windows registry. This solution does not excite me, seems problematic.

Note: the information was sourced from an LLM, though I did try to verify it personally as best as I could. the caveats are a direct copy of LLM output.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we wanted to implement this, I was thinking about using the SMBIOS System UUID with maybe the MachineGuid as a fallback.

@igaw igaw Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked what we do in Linux implementation in this scenario:

__libnvme_public char *libnvmf_generate_hostid(void)
{
	int ret;
	char uuid_str[NVME_UUID_LEN_STRING];
	unsigned char uuid[NVME_UUID_LEN];

	ret = uuid_from_dmi(uuid_str);
	if (ret < 0)
		ret = uuid_from_device_tree(uuid_str);
	if (ret < 0) {
		if (libnvme_random_uuid(uuid) < 0)
			memset(uuid, 0, NVME_UUID_LEN);
		libnvme_uuid_to_string(uuid, uuid_str);
	}

	return strdup(uuid_str);
}


int libnvmf_host_get_ids(struct libnvme_global_ctx *ctx,
		      const char *hostnqn_arg, const char *hostid_arg,
		      char **hostnqn, char **hostid)
{
[...]

	if (!hid) {
		hid = libnvmf_generate_hostid();
		if (!hid)
			return -ENOMEM;

		libnvme_msg(ctx, LIBNVME_LOG_DEBUG,
			 "warning: using auto generated hostid and hostnqn\n");
	}

	/* incomplete configuration, thus derive hostnqn from hostid */
	if (!hnqn) {
		hnqn = libnvmf_generate_hostnqn_from_hostid(hid);
		if (!hnqn)
			return -ENOMEM;
	}
[...]
}

That means if all fails we just generate a UUID and use this one. I just realized I moved this part under CONFIG_FABRICS feature flag. Looks like the generate hostid/hostnqn should always be available. Let me fix this.

Anyway, I think it would be good to have something similar on Windows, so the ports behave similar.

Comment thread libnvme/src/nvme/tree.c Outdated
Comment thread libnvme/src/nvme/tree.c Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Windows support for libnvme’s “tree” enumeration and controller/namespace discovery by introducing a Windows controller mapping layer and wiring it into scanning/open paths. It extends the Windows build to link against SetupAPI/ConfigMgr32 and implements Windows-specific controller/namespace enumeration and attribute population.

Changes:

  • Add a Windows controller map (ctrl-map.c) to translate nvmeX naming into Windows device paths and provide subsystem naming analogous to Linux (nvme-subsysX).
  • Implement Windows controller/namespace scanning and open logic (tree-win.c, filters-win.c, lib-win.c) using the controller map.
  • Update Meson build files to compile/link Windows-specific sources and dependencies.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
meson.build Adds Windows dependency detection for setupapi and cfgmgr32.
libnvme/src/meson.build Builds nvme/ctrl-map.c on Windows and links setupapi/cfgmgr32.
libnvme/src/nvme/tree.c Adjusts subsystem init/scan to tolerate missing sysfs dir (Windows).
libnvme/src/nvme/tree-win.c Implements Windows controller reconfigure, host lookup, ctrl scan, and namespace open/init paths.
libnvme/src/nvme/lib-win.c Implements Windows transport handle open/close and nvmeX<->PhysicalDrive mapping in libnvme_open.
libnvme/src/nvme/filters-win.c Implements Windows controller and namespace enumeration using the controller map.
libnvme/src/nvme/private-ctrl-map.h Adds Windows-only controller map API.
libnvme/src/nvme/ctrl-map.c New Windows controller mapping implementation based on SetupAPI/CM APIs and Identify.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread libnvme/src/nvme/tree.c Outdated
Comment thread libnvme/src/nvme/lib-win.c
Comment thread libnvme/src/nvme/lib-win.c
Comment thread libnvme/src/nvme/tree-win.c
Comment thread libnvme/src/nvme/tree-win.c
Comment thread libnvme/src/nvme/tree-win.c
@igaw

igaw commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

BTW, I'll try to look into the scan API issue next week.

@bcapener bcapener force-pushed the bcapener/add-tree-support branch from 9f6484f to 2afe3fc Compare June 22, 2026 16:52
@igaw

igaw commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

fwiw, I making some good progress with the API review which should help this PR. It's still WIP but I hope to sort out some of the quirks soonish to unblock you here: https://github.com/igaw/nvme-cli/tree/api-review

bcapener added 2 commits June 30, 2026 11:13
Add tree.c and lib.c support. Adds ctrl-map.c for mapping controller name,
nvmeX, to controller path, since windows controller paths might not fit
within the d_name field of the dirent struct.
The ctrl-map also creates a subsystem name to replicate
linux's nvme-subsysX naming.

Signed-off-by: Brandon Capener <bcapener@micron.com>
Remove the use of libnvme_create_global_ctx from
within libnvme and have the ctx passed in via
argument.

Signed-off-by: Brandon Capener <bcapener@micron.com>
bcapener added 2 commits June 30, 2026 11:13
windows related includes should come after
private-ctrl-map.h to avoid issues when
windows includes are added to private-ctrl-map.h.
windows can be particular about the order.

Signed-off-by: Brandon Capener <bcapener@micron.com>
…ystem handling

Use ccan libraries hash tables instead of an array to keep track of controller paths.

Signed-off-by: Brandon Capener <bcapener@micron.com>
@bcapener bcapener force-pushed the bcapener/add-tree-support branch from f4bfadc to 1842e74 Compare June 30, 2026 18:15
@igaw

igaw commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

From my first pass through the commits the final result looks good. I'll give it another look tomorrow, tired from reviewing the whole day, so not good to through such a big change too quickly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants