Skip to content

tree: add windows tree support#3440

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

tree: add windows tree support#3440
bcapener wants to merge 1 commit 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
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>
@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.

#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "private-ctrl-map.h"

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.

this should be grouped with the other local headers below

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.

* Creates a temporary transport context and handle internally.
* Returns 0 on success with id_ctrl filled in, negative errno on failure.
*/
static int identify_ctrl_from_handle(HANDLE h, struct nvme_id_ctrl *id_ctrl)

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 would suggest to use the libnvme typedefs here, because it looks a bit strange below when assiging it to hdl->fd = h.

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.


*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.

Comment thread libnvme/src/nvme/lib-win.c
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?

Comment thread libnvme/src/nvme/tree.c

s->model = libnvme_get_attr(path, "model");
if (!s->model)
if (path && !s->model)

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.

This whole hunk doesn't look right. What does it try to do?

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.

All of these changes in tree.c (including the other comment below) were our attempt to avoid using #ifndef _WIN32, instead we check if the sysfs_dir is not NULL, so that code will only run on linux and not windows.

	if (path && !s->model)
		s->model = strdup("undefined");

here we don't want s->model set to "undefined" on windows, since it will be set somewhere else, that is why we added the path check.

Comment thread libnvme/src/nvme/tree.c
subsysnqn = libnvme_get_attr(path, "subsysnqn");
if (!subsysnqn)
return -ENODEV;
}

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.

same here, what does it try to fix and if so, it should definitely be a separate patch with a proper commit message.

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.

see other comment #3440 (comment)

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
Comment on lines 628 to +632
libnvme_msg(ctx, LIBNVME_LOG_DEBUG, "scan subsystem %s\n", name);
ret = asprintf(&path, "%s/%s", libnvme_subsys_sysfs_dir(), name);
if (ret < 0)
return -ENOMEM;
if (sysfs_dir) {
ret = asprintf(&path, "%s/%s", sysfs_dir, name);
if (ret < 0)
return -ENOMEM;
Comment on lines +127 to +137
/* Handle test devices */
if (!strncmp(name, "NVME_TEST_FD", 12)) {
hdl->type = LIBNVME_TRANSPORT_HANDLE_TYPE_DIRECT;
hdl->fd = LIBNVME_TEST_FD;

if (!strcmp(name, "NVME_TEST_FD64"))
hdl->ioctl_admin_state = IOCTL_STATE_IOCTL64;

*hdlp = hdl;
return 0;
}
Comment on lines +168 to +173
/* Store the nvmeX or nvmeXnY-style name in hdl->name. */
hdl->name = strdup(name);
if (!hdl->name) {
free(hdl);
return -ENOMEM;
}
Comment on lines +149 to +153
char *state = c->state;

c->state = strdup("");
free(state);
return c->state;
Comment on lines +58 to +63
c->hdl = NULL;
c->name = xstrdup(name);
c->sysfs_dir = xstrdup(path);

if (!libnvme_ctrl_get_transport_handle(c))
return -ENODEV;
Comment on lines +455 to +458
n->sysfs_dir = strdup(name); /* \\\\.\\PhysicalDriveX */

*ns = n;
return 0;
@igaw

igaw commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

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

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