Page 1 of 2
StarWindX Auth/Session Bug?
Posted: Sat Sep 27, 2025 11:41 pm
by cypher2000
I can consistently reproduce this issue.
If I use PowerShell (StarWind VSAN Free) to create any type of LUN (HA or flat) once, it will work fine. Every time after the first time, it will fail with error "104 You are authenticated already."
I've been able to isolate this to being a fault either in StarWindX (in the form of not closing connections) or to the StarWind service itself (similar, not closing connections).
If I eliminate PowerShell and use COM to call the StarWindX code, I can generate the same outcome with this:
Server.CreateDevice(varFirstNode.ImagePath, varFirstNode.ImageName, StarWindDeviceType.STARWIND_HA_DEVICE, varFirstNodeParams)
The only way to fix the error is to reboot the StarWind server or restart the service. This is obviously really bad because it means taking down the system every time I need to make a LUN change.
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 3:27 am
by yaroslav (staff)
Hi,
Please tell me more about the setup:namely, I am curious about the StarWind VSAN deployment. Is it CVM or Windows-based service?
That's strange as I was able to create multiple volumes using
viewtopic.php?f=5&t=6852&p=37208&hilit=HINT8#p37208 in 19551.
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 3:33 am
by cypher2000
It is the Windows binary build. If you're curious to see it reproduced, I'm currently rebuilding the trial back under free and then I can show you.
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 4:06 am
by yaroslav (staff)
Thanks for pointing it out. I will also test it because I remember it was working, and my colleagues also use similar scripts for creation.
And I am very sorry for asking you to rebuild the whole thing: the current build does not allow switching to Free from Trial at all... We are working on less disruptive ways.
Thanks and sorry again.
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 12:33 pm
by cypher2000
I was a little disappointed with that change in licensing mechanism. I understand why they did it, though. If you could go from trial to free, people could get around the GUI license restriction when they occasionally make changes by requesting a trial license, using the UI, then switching back to free.
I'm not sure how customizable your licensing is, but I looked at it in a text editor and it looks like pretty simple XML with a signature at the bottom. One potential way around it would be to generate a non-expiring NFR license that has the same restrictions and features as the free license file. Since it would be read in as NFR, it would not be blocked by the free license check.
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 12:38 pm
by cypher2000
Back on original topic....The link you shared goes to a copy of the script that's already what I'm running. See below. Before I posted, I wanted to ensure my custom script module that is far more user friendly was not the culprit, but the results are consistent between my code and your official script here.
Code: Select all
param($addr="10.10.10.1", $port=3261, $user="root", $password="starwind",
$addr2="10.10.10.2", $port2=$port, $user2=$user, $password2=$password,
#common
$initMethod="Clear",
$size=12,
$sectorSize=512,
$failover=0,
$bmpType=1,
$bmpStrategy=0,
#primary node
$imagePath="My Computer\B\LUNs",
$imageName="masterImg21",
$createImage=$true,
$storageName="",
$targetAlias="targetha21",
$poolName="pool1",
$syncSessionCount=1,
$aluaOptimized=$true,
$cacheMode="none",
$cacheSize=0,
$syncInterface="#p2={0}:3260" -f $addr2,
$hbInterface="",
$createTarget=$true,
$bmpFolderPath="",
#secondary node
$imagePath2="My Computer\B\LUNs",
$imageName2="partnerImg22",
$createImage2=$true,
$storageName2="",
$targetAlias2="partnerha22",
$poolName2="pool1",
$syncSessionCount2=1,
$aluaOptimized2=$false,
$cacheMode2=$cacheMode,
$cacheSize2=$cacheSize,
$syncInterface2="#p1={0}:3260" -f $addr,
$hbInterface2="",
$createTarget2=$true,
$bmpFolderPath2=""
)
Import-Module StarWindX
try
{
Enable-SWXLog
$server = New-SWServer -host $addr -port $port -user $user -password $password
$server.Connect()
$firstNode = new-Object Node
$firstNode.HostName = $addr
$firstNode.HostPort = $port
$firstNode.Login = $user
$firstNode.Password = $password
$firstNode.ImagePath = $imagePath
$firstNode.ImageName = $imageName
$firstNode.Size = $size
$firstNode.CreateImage = $createImage
$firstNode.StorageName = $storageName
$firstNode.TargetAlias = $targetAlias
$firstNode.SyncInterface = $syncInterface
$firstNode.HBInterface = $hbInterface
$firstNode.PoolName = $poolName
$firstNode.SyncSessionCount = $syncSessionCount
$firstNode.ALUAOptimized = $aluaOptimized
$firstNode.CacheMode = $cacheMode
$firstNode.CacheSize = $cacheSize
$firstNode.FailoverStrategy = $failover
$firstNode.CreateTarget = $createTarget
$firstNode.BitmapStoreType = $bmpType
$firstNode.BitmapStrategy = $bmpStrategy
$firstNode.BitmapFolderPath = $bmpFolderPath
#
# device sector size. Possible values: 512 or 4096(May be incompatible with some clients!) bytes.
#
$firstNode.SectorSize = $sectorSize
$secondNode = new-Object Node
$secondNode.HostName = $addr2
$secondNode.HostPort = $port2
$secondNode.Login = $user2
$secondNode.Password = $password2
$secondNode.ImagePath = $imagePath2
$secondNode.ImageName = $imageName2
$secondNode.CreateImage = $createImage2
$secondNode.StorageName = $storageName2
$secondNode.TargetAlias = $targetAlias2
$secondNode.SyncInterface = $syncInterface2
$secondNode.HBInterface = $hbInterface2
$secondNode.SyncSessionCount = $syncSessionCount2
$secondNode.ALUAOptimized = $aluaOptimized2
$secondNode.CacheMode = $cacheMode2
$secondNode.CacheSize = $cacheSize2
$secondNode.FailoverStrategy = $failover
$secondNode.CreateTarget = $createTarget2
$secondNode.BitmapFolderPath = $bmpFolderPath2
$device = Add-HADevice -server $server -firstNode $firstNode -secondNode $secondNode -initMethod $initMethod
while ($device.SyncStatus -ne [SwHaSyncStatus]::SW_HA_SYNC_STATUS_SYNC)
{
$syncPercent = $device.GetPropertyValue("ha_synch_percent")
Write-Host "Synchronizing: $($syncPercent)%" -foreground yellow
Start-Sleep -m 2000
$device.Refresh()
}
}
catch
{
Write-Host $_ -foreground red
}
finally
{
$server.Disconnect()
}
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 6:59 pm
by yaroslav (staff)
NFR expires in a year and it is a subject of discussion with the account managers.
Try a different initMethod. I often use NotSynchronize for creation.
Sync and hbinterfaces better to be filled with IPs.
I will test running the script on 19551 deployment again during the week.
Thanks for your effort.
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 7:13 pm
by cypher2000
I'm using NotSynchronize by specifcying it as a runtime parameter.
Sync and HB are IP addresses. One thing I'm wondering...should these be #p1 and #p0 instead of #p2 and #p1?
Code: Select all
[string]$PrimaryNodeSyncIPAddress = "10.10.10.1", #The IP address of the synchronization interface on the primary node
[string]$PrimaryNodeHeartbeatIPAddress = "10.255.255.3", #The IP address of the heartbeat interface on the primary node
[string]$SecondaryNodeSyncIPAddress = "10.10.10.2", #The IP address of the synchronization interface on the secondary node
[string]$SecondaryNodeHeartbeatIPAddress = "10.255.255.4", #The IP address of the heartbeat interface on the secondary node
.....
$firstNode.SyncInterface = "#p2=$($SecondaryNodeSyncIPAddress):3260"
$firstNode.HBInterface = "#p2=$($SecondaryNodeHeartbeatIPAddress):3260"
.....
$secondNode.SyncInterface = "#p1=$($PrimaryNodeSyncIPAddress):3260"
$secondNode.HBInterface = "#p1=$($PrimaryNodeHeartbeatIPAddress):3260"
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 7:27 pm
by cypher2000
Also, when you have a moment, can you tell me if there's a way from PowerShell to specify multiple heartbeat interfaces like there is in the UI Replication Manager wizard?
Figuring Out an Improved Script for Creating LUNs
Posted: Sun Sep 28, 2025 8:02 pm
by cypher2000
Code: Select all
param(
#StarWind node settings
[string]$PrimaryNode,
[string]$SecondaryNode,
[ValidateRange(1,65535)]
[int]$Port = 3261,
#Authentication
[string]$Username = "root",
[string]$Password = "starwind",
#LUN creation mode
[ValidateSet("HA", "Flat")]
[string]$LUNType = "HA",
[string]$HATargetSharedPrefix,
#Image settings
[Parameter(Mandatory=$true)]
[string]$ImageName,
[string]$ImagePath = "My computer\B\LUNs",
[long]$ImageSize = 5GB, #starwind expects an integer representing megabytes. We'll convert this number later.
[ValidateSet(512, 4096)]
[int]$SectorSize = 512, #4096 for Hyper-V/Windows, 512 for VMware
[ValidateSet("Disabled", "WriteBack", "WriteThrough")]
[string]$CacheMode = "Disabled", # None (safest), wb = WriteBack (data loss on power failure), wt = WriteThrough (caches reads only)
[ValidateRange(0, 1099511627776)]
[int]$CacheSize = 0,
[bool]$CreateImage = $true, # Really not a reason to ever set as false
#HA settings
[ValidateSet("Clear","NotSynchronize","SyncFromFirst","SyncFromSecond","SyncFromThird")]
[string]$InitMethod = "Clear", #Clear = blank both; NotSynchronize = don't init; SyncFromFirst; SyncFromSecond; SyncFromThird
[ValidateSet("Heartbeat", "NodeMajority")]
[string]$FailoverStrategy = "Heartbeat", #0 = Heartbeat, 1 = Node Majority
[ValidateSet("RAM", "Disk")]
[string]$JournalType = "Disk", # 1 = RAM (fastest, risky), 2 = Disk (variable speed, safer)
[ValidateSet("OnFail", "Always")]
[string]$JournalStrategy = "OnFail", # 1 = Write on fail (fast, slower during failures, mostly safe), 2 = Always write (always slower, safest)
[string]$JournalPath = "$($ImagePath)\$($ImageName)-JL",
[string]$TargetAlias = $ImageName,
[switch]$DisableAutomaticSynchronization,
[string]$PoolName = "pool1",
[string]$StorageName = "",
[int]$SyncSessionCount = 1,
[int]$NUMANode = 0,
[bool]$ALUAOptimized = $true,
[string]$PrimaryNodeSyncIPAddress = "10.10.10.1", #The IP address of the synchronization interface on the primary node
[string]$PrimaryNodeHeartbeatIPAddress = "10.255.255.3", #The IP address of the heartbeat interface on the primary node
[string]$SecondaryNodeSyncIPAddress = "10.10.10.2", #The IP address of the synchronization interface on the secondary node
[string]$SecondaryNodeHeartbeatIPAddress = "10.255.255.4", #The IP address of the heartbeat interface on the secondary node
[bool]$CreateTarget = $true,
[switch]$FeedbackEnabled
)
###
# Local Variables
###
# We use these to store StarWind-friendly equivalents of the user-friendly values collected in the parameters
$varPrimaryNodeIP = $null
$varSecondaryNodeIP = $null
$varInitMethod = $InitMethod
$varSectorSize = $SectorSize
$varFailoverStrategy = 0
$varJournalType = 2
$varJournalStrategy = 1
$varCacheMode = "none"
#####
# Validation
#####
#### We do all our math as long, since the powershell friendly notations are 64-bit integers
#4K Can't do < 2MB
if($ImageSize -le 2MB -and $SectorSize -eq 4096) { throw "It is not supported to create images smaller than 2MB with 4K sector size." }
#Prevent buffer overflow when converting long to int.
#Technically the boundary is not exactly 1.89PB, it's ~1.91PB, but we play safe here
#1.89PB turns into 2029372047MB after we later convert to int32, which is safely under the upper bound of int32
if($ImageSize -gt 1.89PB) {
throw "The ImageSize specified is too large. The maximum size accepted is 1.89 petabytes."
}
#Volumes under 10GB are generally meaningless, so if we get a request for a tiny one, verify it's intentional
if($ImageSize -lt 10GB) {
$ConfirmSize = Read-Host -Prompt "The size you specified is $($ImageSize / 1MB)MB. This is less than 10GB. Some modern filesystems, like NTFS, may struggle with this volume size. Do you want to proceed with this size? [y/N]"
if($ConfirmSize.ToLower() -ne "y") { $ImageSize = Read-Host -Prompt "Please enter a new image size. Image size must be an integer." }
}
### Since we're done using the PowerShell notation now, we need to make something StarWind will understand
#Convert friendly image size input to starwind notation
#StarWind requires an int value measured as MB
#Constants: 1TB = [long]1099511627776; 1MB = [int]1048576
#Example: 1TB / 1MB = 1048576MB --> Bytes: 1099511627776 bytes / 1048576 bytes = 1048576 megabytes
#So in the above example, this conversion will turn the long value of 1TB entered by the user into an integer value 1048576 understood by StarWind
[int]$ImageSize = [int]($ImageSize / 1MB)
###
# Only HA images
###
if($LUNType -eq "HA") {
#PrimaryNode, test the name provided by the user is actually a server
if($PrimaryNode -eq $null) { throw "HA LUNs require at least two nodes. Please specify a value for PrimaryNode." }
$Resolver = (Resolve-DnsName $PrimaryNode -Type A -DnsOnly -ErrorAction SilentlyContinue).IPAddress
if($Resolver -eq $null) {
throw "Unable to resolve the name supplied in PrimaryNode. This must be a valid DNS name resolving to another StarWind cluster node."
} else { $varPrimaryNodeIP = $Resolver }
#SecondaryNode, test the name provided by the user is actually a server
if($SecondaryNode -eq $null) { throw "HA LUNs require at least two nodes. Please specify a value for SecondaryNode." }
$Resolver = (Resolve-DnsName $SecondaryNode -Type A -DnsOnly -ErrorAction SilentlyContinue).IPAddress
if($Resolver -eq $null) {
throw "Unable to resolve the name supplied in SecondaryNode. This must be a valid DNS name resolving to another StarWind cluster node."
} else {
$varSecondaryNodeIP = $Resolver
}
}
###
# Only local flat images
###
if($LUNType -eq "Flat") {
#PrimaryNode, test the name provided by the user is actually a server
if($PrimaryNode -eq $null) { throw "HA LUNs require at least two nodes. Please specify a value for PrimaryNode." }
$Resolver = (Resolve-DnsName $PrimaryNode -Type A -DnsOnly -ErrorAction SilentlyContinue).IPAddress
if($Resolver -eq $null) {
throw "Unable to resolve the name supplied in PrimaryNode. This must be a valid DNS name resolving to another StarWind cluster node."
} else { $varPrimaryNodeIP = $Resolver }
}
###
# All Image Types
###
# StarWind expects none, wb, wt as string values, so we convert the enum to the intended string
switch ($CacheMode) {
"Disabled" {
$varCacheMode = "none"
}
"WriteBack" {
$varCacheMode = "wb"
}
"WriteThrough" {
$varCacheMode = "wt"
}
default {
$varCacheMode = "none"
}
}
Enable-SWXLog -level SW_LOG_LEVEL_DEBUG
$Server = New-SWServer -host $PrimaryNode -port $Port -user $Username -password $Password
$Server.Connect()
try
{
if($LUNType -eq "HA") {
$firstNode = new-Object Node
$firstNode.HostName = $varPrimaryNodeIP
$firstNode.HostPort = $Port
$firstNode.Login = $Username
$firstNode.Password = $Password
$firstNode.ImagePath = $ImagePath
$firstNode.ImageName = $ImageName
$firstNode.Size = $ImageSize
$firstNode.CreateImage = $true
$firstNode.StorageName = $StorageName
$firstNode.TargetAlias = $TargetAlias
$firstNode.CacheMode = $varCacheMode
$firstNode.CacheSize = $CacheSize
$firstNode.CreateTarget = $CreateTarget
$firstNode.SectorSize = $varSectorSize
$firstNode.SyncInterface = "#p2=$($SecondaryNodeSyncIPAddress):3260"
$firstNode.HBInterface = "#p2=$($SecondaryNodeHeartbeatIPAddress):3260"
$firstNode.PoolName = $PoolName
$firstNode.SyncSessionCount = $SyncSessionCount
$firstNode.ALUAOptimized = $ALUAOptimized
$firstNode.FailoverStrategy = $varFailoverStrategy
$firstNode.BitmapStoreType = $varJournalType
$firstNode.BitmapStrategy = $varJournalStrategy
$secondNode = new-Object Node
$secondNode.HostName = $SecondaryNode
$secondNode.HostPort = $Port
$secondNode.Login = $Username
$secondNode.Password = $Password
$secondNode.ImagePath = $ImagePath
$secondNode.ImageName = $ImageName
$secondNode.Size = $ImageSize
$secondNode.CreateImage = $CreateImage
$secondNode.StorageName = $StorageName
$secondNode.TargetAlias = $TargetAlias
$secondNode.CacheMode = $varCacheMode
$secondNode.CacheSize = $CacheSize
$secondNode.CreateTarget = $CreateTarget
$secondNode.SectorSize = $varSectorSize
$secondNode.SyncInterface = "#p1=$($PrimaryNodeSyncIPAddress):3260"
$secondNode.HBInterface = "#p1=$($PrimaryNodeHeartbeatIPAddress):3260"
$secondNode.PoolName = $PoolName
$secondNode.SyncSessionCount = $SyncSessionCount
$secondNode.ALUAOptimized = $ALUAOptimized
$secondNode.FailoverStrategy = $varFailoverStrategy
$secondNode.BitmapStrategy = $varJournalStrategy
$secondNode.BitmapStoreType = $varJournalType
# BitmapFolderPath is only needed if using disk-based journaling
if($JournalType -eq "Disk") {
$firstNode.BitmapFolderPath = $JournalPath
$secondNode.BitmapFolderPath = $JournalPath
#Convert StarWind path to Windows path
$TestPath = "\\{server}\$($JournalPath.Substring($JournalPath.IndexOf("\") + 1, 1))$\$($JournalPath.SubString($JournalPath.IndexOf("\") + 3))"
$PrimaryPath = $TestPath.Replace("{server}",$PrimaryNode)
$SecondaryPath = $TestPath.Replace("{server}",$SecondaryNode)
if((Test-Path $PrimaryPath) -eq $false) {
#BitmapFolderPath doesn't exist, try to create it
New-Item $PrimaryPath -ErrorAction Stop -ItemType Directory
}
if((Test-Path $SecondaryPath) -eq $false) {
#BitmapFolderPath doesn't exist, try to create it
New-Item $SecondaryPath -ErrorAction Stop -ItemType Directory
}
}
#If we have a defined HA target prefix, use it for simple multipathing
if($HATargetSharedPrefix -ne $null) {
$TargetName = "iqn.2008-08.com.starwindsoftware:$($HATargetSharedPrefix)-$($TargetAlias)"
$firstNode.TargetName = $TargetName
$secondNode.TargetName = $TargetName
}
if($DisableAutomaticSynchronization.IsPresent) {
$firstNode.AutoSynch = $false
$secondNode.AutoSynch = $false
} else {
$firstNode.AutoSynch = $true
$secondNode.AutoSynch = $true
}
if($FeedbackEnabled.IsPresent) {
Write-Host "Generated primary node:" -ForegroundColor Yellow
$firstNode |FL
Write-Host ""
Write-Host "Generated secondary node:" -ForegroundColor Yellow
$secondNode |FL
}
$device = Add-HADevice `
-server $Server `
-firstNode $firstNode `
-secondNode $secondNode `
-initMethod $varInitMethod
while ($device.SyncStatus -ne [SwHaSyncStatus]::SW_HA_SYNC_STATUS_SYNC)
{
$syncPercent = $device.GetPropertyValue("ha_synch_percent")
Write-Progress -Activity "Configuring HA for $($ImageName)" -CurrentOperation "Synchronizing nodes..." -PercentComplete $syncPercent
Start-Sleep -Seconds 10
$device.Refresh()
}
Write-Progress -Completed -Activity "Configuring HA for $($ImageName)"
Write-Host "Created HA device:" -ForegroundColor Yellow
$device |FL
}
if($LUNType -eq "Flat") {
New-ImageFile `
-server $Server `
-path $ImagePath `
-fileName $ImageName `
-size $ImageSize
$device = Add-ImageDevice `
-server $Server `
-path $ImagePath `
-fileName $ImageName `
-sectorSize $varSectorSize `
-NumaNode $NUMANode `
-CacheMode $varCacheMode `
-CacheSize $CacheSize
$target = New-Target `
-server $Server `
-alias $TargetAlias `
-devices $device.Name
}
}
catch
{
Write-Host $_ -foreground red
}
finally
{
if($Server.Connected) {
$Server.Disconnect()
}
}
if($Server.Connected) {
$Server.Disconnect()
}
Re: StarWindX Auth/Session Bug?
Posted: Sun Sep 28, 2025 10:03 pm
by yaroslav (staff)
cypher2000 wrote: ↑Sun Sep 28, 2025 7:27 pm
Also, when you have a moment, can you tell me if there's a way from PowerShell to specify multiple heartbeat interfaces like there is in the UI Replication Manager wizard?
Yes, Check out the script here
viewtopic.php?f=5&t=6852&p=37208&hilit=HINT8#p37208.
$syncInterface="#p2=172.16.20.231:3260,172.27.21.231:3260",
Same applies to heartbeat.
Also, according to my script, we use #p2 abd 1 to introduce IPs of a partner.
Thanks for your effort! Will save this thread.
I hope you still can get some rest.
Re: StarWindX Auth/Session Bug?
Posted: Mon Sep 29, 2025 11:14 am
by cypher2000
Thank you for all your help, Yaroslav. Can you ask someone from sales to reach out to me? The last time I checked in on pricing, we weren't yet able to afford a license with support (hence needing the free version), but I would like to check in and see if there's been any changes.
Also, are you interested in reviewing the script I'm building to see if it might be a good candidate for inclusion in future releases of the free edition? If so, I have a few more tweaks to make (such as including Get-Help content), and when ready I can schedule 30 minutes with you to demo it for you and answer any questions for documentation.
Re: StarWindX Auth/Session Bug?
Posted: Mon Sep 29, 2025 11:58 am
by yaroslav (staff)
Yes, please, it will be interesting to see it.
Thanks!
Re: StarWindX Auth/Session Bug?
Posted: Fri Oct 03, 2025 6:05 pm
by cypher2000
Hi Yaroslav,
I'm adding the functionality I mentioned of supporting multiple heartbeat interfaces.
Does the problem pop out to you from this error output?
Code: Select all
Request to SAT-SAN-V1-01.HYPERNOC.IO ( 10.128.124.50 ) : 3261
-
control 0x000002772900C840 -AddPartner:"" -PartnerTargetName:"#p1=iqn.2008-08.com.starwindsoftware:sat-san-v1.hypernoc.io-sat-san-c1-quorum;#p2=iqn.2008-08.com.starwindsoftware:sat-san-v1.hypernoc.io-sat-san-c1-quorum" -Priority:"#p1=2;#p2=2" -nodeType:"#p1=1;#p2=1" -PartnerIP:"#p1=10.128.124.51:heartbeat:3260:1,10.255.255.4:heartbeat:3260:1;#p2=10.10.10.2:sync:3260:1" -AuthChapType:"#p1=none;#p2=none" -AuthChapLogin:"#p1=0b;#p2=0b" -AuthChapPassword:"#p1=0b;#p2=0b" -AuthMChapName:"#p1=0b;#p2=0b" -AuthMChapSecret:"#p1=0b;#p2=0b" -Replicator:"#p1=0;#p2=0" -typeBitmapStore:"#p1=1;#p2=1"
-
200 Failed: invalid partner info..
Re: StarWindX Auth/Session Bug?
Posted: Fri Oct 03, 2025 6:06 pm
by cypher2000
This piece stands out to me, but I haven't found a way to change it:
-Priority:"#p1=2;#p2=2"
Is the priority value supposed to be the same for both?