Date: Mon, 23 Jun 2025 16:25:02 +0000 From: bugzilla-noreply@freebsd.org To: bugs@FreeBSD.org Subject: [Bug 287741] ctld deletes ports if they already exist Message-ID: <bug-287741-227-IQLFYncUq9@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-287741-227@https.bugs.freebsd.org/bugzilla/>
index | next in thread | previous in thread | raw e-mail
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287741 --- Comment #3 from Alan Somers <asomers@FreeBSD.org> --- The scenario that 5f89aea7b74aa4605b25af62e31303097a4a48cc helps with is when two separate processes both do "service ctld restart" or "service ctld reload" at the same time. It also helps if ctld receives a signal while it's still starting up. Both of those scenarios could cause kernel_port_add() to fail. Some background info: there are really multiple separate lists of CTL ports. One is the kernel's list. That's the list that you can see with "ctladm portlist". ctld's kernel_port_add() function adds ports to that list. Another is the list of ports that existed in the kernel before this ctld instance started. That's stored in ctld's "kports" variable. Finally, there's the list of ports that are managed by this ctld instance and also exist in the kernel. That's stored in the newconf variable. What 5f89aea7b74 does is it removes a port from the newconf variable if the kernel rejected it, for any reason. But it doesn't attempt to remove ports from the kernel. That would require kernel_port_remove(). Note that ctld is careful not to call kernel_port_add() for ports that already exist within the kernel. The reason for this complicated dance is that ctld is technically optional. Almost everything it can do can also be done with ctladm. And in theory it should be possible to run multiple instances of ctld at the same time, each managing different LUNs and targets (though I don't know of anybody who actually does that). So each ctld instance must take care not to interfere with kernel ports created by another ctld instance, or by ctladm. Unfortunately, if ctld crashes or gets killed by a signal, then when the next ctld process starts, it will see many kernel ports and think that they might be managed by a different ctld instance. So it won't try to manage it. 5f89aea7b74 fixes a bug of that sort. We can't simply remove the kernel_port_add() call, because that would break the ability to use ctladm to add ports manually, and break the ability to run multiple ctld instances. If kernel_port_add() fails because the port already exists, that suggests to me another race similar to what 5f89aea7b74 fixed. Absent any race, port_find() should've found an existing port, causing kernel_port_add() to be skipped. So you really need to determine why kernel_port_add() is failing. The three likeliest reasons I can think of are simultaneous "service ctld ..." calls, direct use of ctladm, or ctld crashing or being killed by a signal. We can certainly fix the log message, as you suggested in your email. -- You are receiving this mail because: You are the assignee for the bug.home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-287741-227-IQLFYncUq9>
