github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/transitions/api_internal.go (about) 1 // Copyright (c) 2015-2021, NVIDIA CORPORATION. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package transitions 5 6 import ( 7 "container/list" 8 "fmt" 9 "sync" 10 11 "github.com/swiftstack/ProxyFS/conf" 12 "github.com/swiftstack/ProxyFS/logger" 13 ) 14 15 type loggerCallbacksInterfaceStruct struct { 16 } 17 18 var loggerCallbacksInterface loggerCallbacksInterfaceStruct 19 20 type registrationItemStruct struct { 21 packageName string 22 callbacks Callbacks 23 } 24 25 type volumeStruct struct { 26 name string 27 served bool 28 volumeGroup *volumeGroupStruct 29 } 30 31 type volumeGroupStruct struct { 32 name string 33 served bool 34 activePeer string 35 virtualIPAddr string 36 volumeList map[string]*volumeStruct // Key: volumeStruct.name 37 } 38 39 type confMapDeltaStruct struct { 40 volumeGroupList map[string]*volumeGroupStruct // Key: volumeGroupStruct.name 41 servedVolumeGroupList map[string]*volumeGroupStruct // Key: volumeGroupStruct.name 42 remoteVolumeGroupList map[string]*volumeGroupStruct // Key: volumeGroupStruct.name 43 44 createdVolumeGroupList map[string]*volumeGroupStruct // Key: volumeGroupStruct.name 45 movedVolumeGroupList map[string]*volumeGroupStruct // Key: volumeGroupStruct.name 46 destroyedVolumeGroupList map[string]*volumeGroupStruct // Key: volumeGroupStruct.name 47 48 volumeList map[string]*volumeStruct // Key: volumeStruct.name 49 servedVolumeList map[string]*volumeStruct // Key: volumeStruct.name 50 remoteVolumeList map[string]*volumeStruct // Key: volumeStruct.name 51 52 createdVolumeList map[string]*volumeStruct // Key: volumeStruct.name 53 movedVolumeList map[string]*volumeStruct // Key: volumeStruct.name 54 destroyedVolumeList map[string]*volumeStruct // Key: volumeStruct.name 55 56 toStopServingVolumeList map[string]*volumeStruct // Key: volumeStruct.name 57 toStartServingVolumeList map[string]*volumeStruct // Key: volumeStruct.name 58 } 59 60 type globalsStruct struct { 61 sync.Mutex // Used only for protecting insertions into registration{List|Set} during init() phase 62 registrationList *list.List 63 registrationSet map[string]*registrationItemStruct // Key: registrationItemStruct.packageName 64 currentConfMapDelta *confMapDeltaStruct 65 } 66 67 var globals globalsStruct 68 69 func init() { 70 globals.Lock() 71 globals.registrationList = list.New() 72 globals.registrationSet = make(map[string]*registrationItemStruct) 73 globals.Unlock() 74 75 Register("logger", &loggerCallbacksInterface) 76 } 77 78 func register(packageName string, callbacks Callbacks) { 79 var ( 80 alreadyRegisted bool 81 registrationItem *registrationItemStruct 82 ) 83 84 globals.Lock() 85 _, alreadyRegisted = globals.registrationSet[packageName] 86 if alreadyRegisted { 87 logger.Fatalf("transitions.Register(%s,) called twice", packageName) 88 } 89 registrationItem = ®istrationItemStruct{packageName, callbacks} 90 _ = globals.registrationList.PushBack(registrationItem) 91 globals.registrationSet[packageName] = registrationItem 92 globals.Unlock() 93 } 94 95 func up(confMap conf.ConfMap) (err error) { 96 var ( 97 newConfMapDelta *confMapDeltaStruct 98 registrationItem *registrationItemStruct 99 registrationListElement *list.Element 100 registrationListPackageNameStringSlice []string 101 volume *volumeStruct 102 volumeGroup *volumeGroupStruct 103 volumeGroupName string 104 volumeName string 105 ) 106 107 defer func() { 108 if nil == err { 109 logger.Infof("transitions.Up() returning successfully") 110 } else { 111 // On the relatively good likelihood that at least logger.Up() worked... 112 logger.Errorf("transitions.Up() returning with failure: %v", err) 113 } 114 }() 115 116 globals.currentConfMapDelta = &confMapDeltaStruct{ 117 volumeGroupList: make(map[string]*volumeGroupStruct), 118 servedVolumeGroupList: make(map[string]*volumeGroupStruct), 119 remoteVolumeGroupList: make(map[string]*volumeGroupStruct), 120 121 createdVolumeGroupList: make(map[string]*volumeGroupStruct), 122 movedVolumeGroupList: make(map[string]*volumeGroupStruct), 123 destroyedVolumeGroupList: make(map[string]*volumeGroupStruct), 124 125 volumeList: make(map[string]*volumeStruct), 126 servedVolumeList: make(map[string]*volumeStruct), 127 remoteVolumeList: make(map[string]*volumeStruct), 128 129 createdVolumeList: make(map[string]*volumeStruct), 130 movedVolumeList: make(map[string]*volumeStruct), 131 destroyedVolumeList: make(map[string]*volumeStruct), 132 133 toStopServingVolumeList: make(map[string]*volumeStruct), 134 toStartServingVolumeList: make(map[string]*volumeStruct), 135 } 136 137 newConfMapDelta, err = computeConfMapDelta(confMap) 138 if nil != err { 139 return 140 } 141 142 if 0 != len(newConfMapDelta.movedVolumeGroupList) { 143 err = fmt.Errorf("transitions.Up() did not expect movedVolumeGroupList to be non-empty") 144 return 145 } 146 if 0 != len(newConfMapDelta.destroyedVolumeGroupList) { 147 err = fmt.Errorf("transitions.Up() did not expect destroyedVolumeGroupList to be non-empty") 148 return 149 } 150 if 0 != len(newConfMapDelta.movedVolumeList) { 151 err = fmt.Errorf("transitions.Up() did not expect movedVolumeList to be non-empty") 152 return 153 } 154 if 0 != len(newConfMapDelta.destroyedVolumeList) { 155 err = fmt.Errorf("transitions.Up() did not expect destroyedVolumeList to be non-empty") 156 return 157 } 158 159 globals.currentConfMapDelta = newConfMapDelta 160 161 // Issue Callbacks.Up() calls from Front() to Back() of globals.registrationList 162 163 registrationListElement = globals.registrationList.Front() 164 165 for nil != registrationListElement { 166 registrationItem = registrationListElement.Value.(*registrationItemStruct) 167 logger.Tracef("transitions.Up() calling %s.Up()", registrationItem.packageName) 168 err = registrationItem.callbacks.Up(confMap) 169 if nil != err { 170 logger.Errorf("transitions.Up() call to %s.Up() failed: %v", registrationItem.packageName, err) 171 err = fmt.Errorf("%s.Up() failed: %v", registrationItem.packageName, err) 172 return 173 } 174 registrationListElement = registrationListElement.Next() 175 } 176 177 // Log transitions registrationList from Front() to Back() 178 179 registrationListPackageNameStringSlice = make([]string, 0, globals.registrationList.Len()) 180 181 registrationListElement = globals.registrationList.Front() 182 183 for nil != registrationListElement { 184 registrationItem = registrationListElement.Value.(*registrationItemStruct) 185 registrationListPackageNameStringSlice = append(registrationListPackageNameStringSlice, registrationItem.packageName) 186 registrationListElement = registrationListElement.Next() 187 } 188 189 logger.Infof("Transitions Package Registration List: %v", registrationListPackageNameStringSlice) 190 191 // Issue Callbacks.VolumeGroupCreated() calls from Front() to Back() of globals.registrationList 192 193 registrationListElement = globals.registrationList.Front() 194 195 for nil != registrationListElement { 196 registrationItem = registrationListElement.Value.(*registrationItemStruct) 197 for volumeGroupName, volumeGroup = range globals.currentConfMapDelta.createdVolumeGroupList { 198 logger.Tracef("transitions.Up() calling %s.VolumeGroupCreated(,%s,%s,%s)", registrationItem.packageName, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr) 199 err = registrationItem.callbacks.VolumeGroupCreated(confMap, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr) 200 if nil != err { 201 logger.Errorf("transitions.Up() call to %s.VolumeGroupCreated(,%s,%s,%s) failed: %v", registrationItem.packageName, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr, err) 202 err = fmt.Errorf("%s.VolumeGroupCreated(,%s,,) failed: %v", registrationItem.packageName, volumeGroupName, err) 203 return 204 } 205 } 206 registrationListElement = registrationListElement.Next() 207 } 208 209 // Issue Callbacks.VolumeCreated() calls from Front() to Back() of globals.registrationList 210 211 registrationListElement = globals.registrationList.Front() 212 213 for nil != registrationListElement { 214 registrationItem = registrationListElement.Value.(*registrationItemStruct) 215 for volumeName, volume = range globals.currentConfMapDelta.createdVolumeList { 216 logger.Tracef("transitions.Up() calling %s.VolumeCreated(,%s,%s)", registrationItem.packageName, volumeName, volume.volumeGroup.name) 217 err = registrationItem.callbacks.VolumeCreated(confMap, volumeName, volume.volumeGroup.name) 218 if nil != err { 219 logger.Errorf("transitions.Up() call to %s.VolumeCreated(,%s,%s) failed: %v", registrationItem.packageName, volumeName, volume.volumeGroup.name, err) 220 err = fmt.Errorf("%s.VolumeCreated(,%s,) failed: %v", registrationItem.packageName, volumeName, err) 221 return 222 } 223 } 224 registrationListElement = registrationListElement.Next() 225 } 226 227 // Issue Callbacks.ServeVolume() calls from Front() to Back() of globals.registrationList 228 229 registrationListElement = globals.registrationList.Front() 230 231 for nil != registrationListElement { 232 registrationItem = registrationListElement.Value.(*registrationItemStruct) 233 for volumeName, volume = range globals.currentConfMapDelta.servedVolumeList { 234 logger.Tracef("transitions.Up() calling %s.ServeVolume(,%s)", registrationItem.packageName, volumeName) 235 err = registrationItem.callbacks.ServeVolume(confMap, volumeName) 236 if nil != err { 237 logger.Errorf("transitions.Up() call to %s.ServeVolume(,%s) failed: %v", registrationItem.packageName, volumeName, err) 238 err = fmt.Errorf("%s.ServeVolume(,%s) failed: %v", registrationItem.packageName, volumeName, err) 239 return 240 } 241 } 242 registrationListElement = registrationListElement.Next() 243 } 244 245 // Issue Callbacks.SignaledFinish() calls from Front() to Back() of globals.registrationList 246 247 registrationListElement = globals.registrationList.Front() 248 249 for nil != registrationListElement { 250 registrationItem = registrationListElement.Value.(*registrationItemStruct) 251 logger.Tracef("transitions.SignaledFinish() calling %s.SignaledFinish()", registrationItem.packageName) 252 err = registrationItem.callbacks.SignaledFinish(confMap) 253 if nil != err { 254 logger.Errorf("transitions.SignaledFinish() call to %s.SignaledFinish() failed: %v", registrationItem.packageName, err) 255 err = fmt.Errorf("%s.SignaledFinish() failed: %v", registrationItem.packageName, err) 256 return 257 } 258 registrationListElement = registrationListElement.Next() 259 } 260 261 return 262 } 263 264 func signaled(confMap conf.ConfMap) (err error) { 265 var ( 266 newConfMapDelta *confMapDeltaStruct 267 registrationItem *registrationItemStruct 268 registrationListElement *list.Element 269 volume *volumeStruct 270 volumeGroup *volumeGroupStruct 271 volumeGroupName string 272 volumeName string 273 ) 274 275 logger.Infof("transitions.Signaled() called") 276 defer func() { 277 if nil == err { 278 logger.Infof("transitions.Signaled() returning successfully") 279 } else { 280 logger.Errorf("transitions.Signaled() returning with failure: %v", err) 281 } 282 }() 283 284 newConfMapDelta, err = computeConfMapDelta(confMap) 285 if nil != err { 286 return 287 } 288 289 globals.currentConfMapDelta = newConfMapDelta 290 291 // Issue Callbacks.VolumeToBeUnserved() calls from Back() to Front() of globals.registrationList 292 293 registrationListElement = globals.registrationList.Back() 294 295 for nil != registrationListElement { 296 registrationItem = registrationListElement.Value.(*registrationItemStruct) 297 for volumeName = range globals.currentConfMapDelta.toStopServingVolumeList { 298 logger.Tracef("transitions.Signaled() calling %s.VolumeToBeUnserved(,%s)", registrationItem.packageName, volumeName) 299 err = registrationItem.callbacks.VolumeToBeUnserved(confMap, volumeName) 300 if nil != err { 301 logger.Errorf("transitions.Signaled() call to %s.VolumeToBeUnserved(,%s) failed: %v", registrationItem.packageName, volumeName, err) 302 err = fmt.Errorf("%s.VolumeToBeUnserved(,%s) failed: %v", registrationItem.packageName, volumeName, err) 303 return 304 } 305 } 306 registrationListElement = registrationListElement.Prev() 307 } 308 309 // Issue Callbacks.SignaledStart() calls from Back() to Front() of globals.registrationList 310 311 registrationListElement = globals.registrationList.Back() 312 313 for nil != registrationListElement { 314 registrationItem = registrationListElement.Value.(*registrationItemStruct) 315 logger.Tracef("transitions.Signaled() calling %s.SignaledStart()", registrationItem.packageName) 316 err = registrationItem.callbacks.SignaledStart(confMap) 317 if nil != err { 318 logger.Errorf("transitions.Signaled() call to %s.SignaledStart() failed: %v", registrationItem.packageName, err) 319 err = fmt.Errorf("%s.SignaledStart() failed: %v", registrationItem.packageName, err) 320 return 321 } 322 registrationListElement = registrationListElement.Prev() 323 } 324 325 // Issue Callbacks.UnserveVolume() calls from Back() to Front() of globals.registrationList 326 327 registrationListElement = globals.registrationList.Back() 328 329 for nil != registrationListElement { 330 registrationItem = registrationListElement.Value.(*registrationItemStruct) 331 for volumeName = range globals.currentConfMapDelta.toStopServingVolumeList { 332 logger.Tracef("transitions.Signaled() calling %s.UnserveVolume(,%s)", registrationItem.packageName, volumeName) 333 err = registrationItem.callbacks.UnserveVolume(confMap, volumeName) 334 if nil != err { 335 logger.Errorf("transitions.Signaled() call to %s.UnserveVolume(,%s) failed: %v", registrationItem.packageName, volumeName, err) 336 err = fmt.Errorf("%s.UnserveVolume(,%s) failed: %v", registrationItem.packageName, volumeName, err) 337 return 338 } 339 } 340 registrationListElement = registrationListElement.Prev() 341 } 342 343 // Issue Callbacks.VolumeGroupCreated() calls from Front() to Back() of globals.registrationList 344 345 registrationListElement = globals.registrationList.Front() 346 347 for nil != registrationListElement { 348 registrationItem = registrationListElement.Value.(*registrationItemStruct) 349 for volumeGroupName, volumeGroup = range globals.currentConfMapDelta.createdVolumeGroupList { 350 logger.Tracef("transitions.Signaled() calling %s.VolumeGroupCreated(,%s,%s,%s)", registrationItem.packageName, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr) 351 err = registrationItem.callbacks.VolumeGroupCreated(confMap, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr) 352 if nil != err { 353 logger.Errorf("transitions.Signaled() call to %s.VolumeGroupCreated(,%s,%s,%s) failed: %v", registrationItem.packageName, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr, err) 354 err = fmt.Errorf("%s.VolumeGroupCreated(,%s,,) failed: %v", registrationItem.packageName, volumeName, err) 355 return 356 } 357 } 358 registrationListElement = registrationListElement.Next() 359 } 360 361 // Issue Callbacks.VolumeCreated() calls from Front() to Back() of globals.registrationList 362 363 registrationListElement = globals.registrationList.Front() 364 365 for nil != registrationListElement { 366 registrationItem = registrationListElement.Value.(*registrationItemStruct) 367 for volumeName, volume = range globals.currentConfMapDelta.createdVolumeList { 368 logger.Tracef("transitions.Signaled() calling %s.VolumeCreated(,%s,%s)", registrationItem.packageName, volumeName, volume.volumeGroup.name) 369 err = registrationItem.callbacks.VolumeCreated(confMap, volumeName, volume.volumeGroup.name) 370 if nil != err { 371 logger.Errorf("transitions.Signaled() call to %s.VolumeCreated(,%s,%s) failed: %v", registrationItem.packageName, volumeName, volume.volumeGroup.name, err) 372 err = fmt.Errorf("%s.VolumeCreated(,%s,) failed: %v", registrationItem.packageName, volumeName, err) 373 return 374 } 375 } 376 registrationListElement = registrationListElement.Next() 377 } 378 379 // Issue Callbacks.VolumeGroupMoved() calls from Front() to Back() of globals.registrationList 380 381 registrationListElement = globals.registrationList.Front() 382 383 for nil != registrationListElement { 384 registrationItem = registrationListElement.Value.(*registrationItemStruct) 385 for volumeGroupName, volumeGroup = range globals.currentConfMapDelta.movedVolumeGroupList { 386 logger.Tracef("transitions.Signaled() calling %s.VolumeGroupMoved(,%s,%s,%s)", registrationItem.packageName, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr) 387 err = registrationItem.callbacks.VolumeGroupMoved(confMap, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr) 388 if nil != err { 389 logger.Errorf("transitions.Signaled() call to %s.VolumeGroupMoved(,%s,%s,%s) failed: %v", registrationItem.packageName, volumeGroupName, volumeGroup.activePeer, volumeGroup.virtualIPAddr, err) 390 err = fmt.Errorf("%s.VolumeGroupMoved(,%s,,) failed: %v", registrationItem.packageName, volumeName, err) 391 return 392 } 393 } 394 registrationListElement = registrationListElement.Next() 395 } 396 397 // Issue Callbacks.VolumeMoved() calls from Front() to Back() of globals.registrationList 398 399 registrationListElement = globals.registrationList.Front() 400 401 for nil != registrationListElement { 402 registrationItem = registrationListElement.Value.(*registrationItemStruct) 403 for volumeName, volume = range globals.currentConfMapDelta.movedVolumeList { 404 logger.Tracef("transitions.Signaled() calling %s.VolumeMoved(,%s,%s)", registrationItem.packageName, volumeName, volume.volumeGroup.name) 405 err = registrationItem.callbacks.VolumeMoved(confMap, volumeName, volume.volumeGroup.name) 406 if nil != err { 407 logger.Errorf("transitions.Signaled() call to %s.VolumeMoved(,%s,%s) failed: %v", registrationItem.packageName, volumeName, volume.volumeGroup.name, err) 408 err = fmt.Errorf("%s.VolumeMoved(,%s,) failed: %v", registrationItem.packageName, volumeName, err) 409 return 410 } 411 } 412 registrationListElement = registrationListElement.Next() 413 } 414 415 // Issue Callbacks.VolumeDestroyed() calls from Back() to Front() of globals.registrationList 416 417 registrationListElement = globals.registrationList.Back() 418 419 for nil != registrationListElement { 420 registrationItem = registrationListElement.Value.(*registrationItemStruct) 421 for volumeName, volume = range globals.currentConfMapDelta.destroyedVolumeList { 422 logger.Tracef("transitions.Signaled() calling %s.VolumeDestroyed(,%s)", registrationItem.packageName, volumeName) 423 err = registrationItem.callbacks.VolumeDestroyed(confMap, volumeName) 424 if nil != err { 425 logger.Errorf("transitions.Signaled() call to %s.VolumeDestroyed(,%s) failed: %v", registrationItem.packageName, volumeName, err) 426 err = fmt.Errorf("%s.VolumeDestroyed(,%s) failed: %v", registrationItem.packageName, volumeName, err) 427 return 428 } 429 } 430 registrationListElement = registrationListElement.Prev() 431 } 432 433 // Issue Callbacks.VolumeGroupDestroyed() calls from Back() to Front() of globals.registrationList 434 435 registrationListElement = globals.registrationList.Back() 436 437 for nil != registrationListElement { 438 registrationItem = registrationListElement.Value.(*registrationItemStruct) 439 for volumeGroupName = range globals.currentConfMapDelta.destroyedVolumeGroupList { 440 logger.Tracef("transitions.Signaled() calling %s.VolumeGroupDestroyed(,%s)", registrationItem.packageName, volumeGroupName) 441 err = registrationItem.callbacks.VolumeGroupDestroyed(confMap, volumeGroupName) 442 if nil != err { 443 logger.Errorf("transitions.Signaled() call to %s.VolumeGroupDestroyed(,%s) failed: %v", registrationItem.packageName, volumeGroupName, err) 444 err = fmt.Errorf("%s.VolumeGroupDestroyed(,%s) failed: %v", registrationItem.packageName, volumeGroupName, err) 445 return 446 } 447 } 448 registrationListElement = registrationListElement.Prev() 449 } 450 451 // Issue Callbacks.ServeVolume() calls from Front() to Back() of globals.registrationList 452 453 registrationListElement = globals.registrationList.Front() 454 455 for nil != registrationListElement { 456 registrationItem = registrationListElement.Value.(*registrationItemStruct) 457 for volumeName, volume = range globals.currentConfMapDelta.toStartServingVolumeList { 458 if volume.served { 459 logger.Tracef("transitions.Signaled() calling %s.ServeVolume(,%s)", registrationItem.packageName, volumeGroupName) 460 err = registrationItem.callbacks.ServeVolume(confMap, volumeName) 461 if nil != err { 462 logger.Errorf("transitions.Signaled() call to %s.ServeVolume(,%s) failed: %v", registrationItem.packageName, volumeGroupName, err) 463 err = fmt.Errorf("%s.ServeVolume(,%s) failed: %v", registrationItem.packageName, volumeName, err) 464 return 465 } 466 } 467 } 468 registrationListElement = registrationListElement.Next() 469 } 470 471 // Issue Callbacks.SignaledFinish() calls from Front() to Back() of globals.registrationList 472 473 registrationListElement = globals.registrationList.Front() 474 475 for nil != registrationListElement { 476 registrationItem = registrationListElement.Value.(*registrationItemStruct) 477 logger.Tracef("transitions.Signaled() calling %s.SignaledFinish()", registrationItem.packageName) 478 err = registrationItem.callbacks.SignaledFinish(confMap) 479 if nil != err { 480 logger.Errorf("transitions.Signaled() call to %s.SignaledFinish() failed: %v", registrationItem.packageName, err) 481 err = fmt.Errorf("%s.SignaledFinish() failed: %v", registrationItem.packageName, err) 482 return 483 } 484 registrationListElement = registrationListElement.Next() 485 } 486 487 return 488 } 489 490 func down(confMap conf.ConfMap) (err error) { 491 var ( 492 newConfMapDelta *confMapDeltaStruct 493 registrationItem *registrationItemStruct 494 registrationListElement *list.Element 495 volumeGroupName string 496 volumeName string 497 ) 498 499 logger.Infof("transitions.Down() called") 500 defer func() { 501 if nil != err { 502 // On the relatively good likelihood that the failure occurred before calling logger.Down()... 503 logger.Errorf("transitions.Down() returning with failure: %v", err) 504 } 505 }() 506 507 newConfMapDelta, err = computeConfMapDelta(confMap) 508 if nil != err { 509 return 510 } 511 512 if 0 != len(newConfMapDelta.createdVolumeGroupList) { 513 err = fmt.Errorf("transitions.Down() did not expect createdVolumeGroupList to be non-empty") 514 return 515 } 516 if 0 != len(newConfMapDelta.movedVolumeGroupList) { 517 err = fmt.Errorf("transitions.Down() did not expect movedVolumeGroupList to be non-empty") 518 return 519 } 520 if 0 != len(newConfMapDelta.destroyedVolumeGroupList) { 521 err = fmt.Errorf("transitions.Down() did not expect destroyedVolumeGroupList to be non-empty") 522 return 523 } 524 if 0 != len(newConfMapDelta.createdVolumeList) { 525 err = fmt.Errorf("transitions.Down() did not expect createdVolumeList to be non-empty") 526 return 527 } 528 if 0 != len(newConfMapDelta.movedVolumeList) { 529 err = fmt.Errorf("transitions.Down() did not expect movedVolumeList to be non-empty") 530 return 531 } 532 if 0 != len(newConfMapDelta.destroyedVolumeList) { 533 err = fmt.Errorf("transitions.Down() did not expect destroyedVolumeList to be non-empty") 534 return 535 } 536 537 globals.currentConfMapDelta = newConfMapDelta 538 539 // Issue Callbacks.VolumeToBeUnserved() calls from Back() to Front() of globals.registrationList 540 541 registrationListElement = globals.registrationList.Back() 542 543 for nil != registrationListElement { 544 registrationItem = registrationListElement.Value.(*registrationItemStruct) 545 for volumeName = range globals.currentConfMapDelta.servedVolumeList { 546 logger.Tracef("transitions.Signaled() calling %s.VolumeToBeUnserved(,%s)", registrationItem.packageName, volumeName) 547 err = registrationItem.callbacks.VolumeToBeUnserved(confMap, volumeName) 548 if nil != err { 549 logger.Errorf("transitions.Signaled() call to %s.VolumeToBeUnserved(,%s) failed: %v", registrationItem.packageName, volumeName, err) 550 err = fmt.Errorf("%s.VolumeToBeUnserved(,%s) failed: %v", registrationItem.packageName, volumeName, err) 551 return 552 } 553 } 554 registrationListElement = registrationListElement.Prev() 555 } 556 557 // Issue Callbacks.SignaledStart() calls from Back() to Front() of globals.registrationList 558 559 registrationListElement = globals.registrationList.Back() 560 561 for nil != registrationListElement { 562 registrationItem = registrationListElement.Value.(*registrationItemStruct) 563 logger.Tracef("transitions.Down() calling %s.SignaledStart()", registrationItem.packageName) 564 err = registrationItem.callbacks.SignaledStart(confMap) 565 if nil != err { 566 logger.Errorf("transitions.Down() call to %s.SignaledStart() failed: %v", registrationItem.packageName, err) 567 err = fmt.Errorf("%s.SignaledStart() failed: %v", registrationItem.packageName, err) 568 return 569 } 570 registrationListElement = registrationListElement.Prev() 571 } 572 573 // Issue Callbacks.UnserveVolume() calls from Back() to Front() of globals.registrationList 574 575 registrationListElement = globals.registrationList.Back() 576 577 for nil != registrationListElement { 578 registrationItem = registrationListElement.Value.(*registrationItemStruct) 579 for volumeName = range globals.currentConfMapDelta.servedVolumeList { 580 logger.Tracef("transitions.Down() calling %s.UnserveVolume(,%s)", registrationItem.packageName, volumeName) 581 err = registrationItem.callbacks.UnserveVolume(confMap, volumeName) 582 if nil != err { 583 logger.Errorf("transitions.Down() call to %s.UnserveVolume(,%s) failed: %v", registrationItem.packageName, volumeName, err) 584 err = fmt.Errorf("%s.UnserveVolume(,%s) failed: %v", registrationItem.packageName, volumeName, err) 585 return 586 } 587 } 588 registrationListElement = registrationListElement.Prev() 589 } 590 591 // Issue Callbacks.VolumeDestroyed() calls from Back() to Front() of globals.registrationList 592 593 registrationListElement = globals.registrationList.Back() 594 595 for nil != registrationListElement { 596 registrationItem = registrationListElement.Value.(*registrationItemStruct) 597 for volumeName = range globals.currentConfMapDelta.volumeList { 598 logger.Tracef("transitions.Down() calling %s.VolumeDestroyed(,%s)", registrationItem.packageName, volumeName) 599 err = registrationItem.callbacks.VolumeDestroyed(confMap, volumeName) 600 if nil != err { 601 logger.Errorf("transitions.Down() call to %s.VolumeDestroyed(,%s) failed: %v", registrationItem.packageName, volumeName, err) 602 err = fmt.Errorf("%s.VolumeDestroyed(,%s) failed: %v", registrationItem.packageName, volumeName, err) 603 return 604 } 605 } 606 registrationListElement = registrationListElement.Prev() 607 } 608 609 // Issue Callbacks.VolumeGroupDestroyed() calls from Back() to Front() of globals.registrationList 610 611 registrationListElement = globals.registrationList.Back() 612 613 for nil != registrationListElement { 614 registrationItem = registrationListElement.Value.(*registrationItemStruct) 615 for volumeGroupName = range globals.currentConfMapDelta.volumeGroupList { 616 logger.Tracef("transitions.Down() calling %s.VolumeGroupDestroyed(,%s)", registrationItem.packageName, volumeGroupName) 617 err = registrationItem.callbacks.VolumeGroupDestroyed(confMap, volumeGroupName) 618 if nil != err { 619 logger.Errorf("transitions.Down() call to %s.VolumeGroupDestroyed(,%s) failed: %v", registrationItem.packageName, volumeGroupName, err) 620 err = fmt.Errorf("%s.VolumeGroupDestroyed(,%s) failed: %v", registrationItem.packageName, volumeGroupName, err) 621 return 622 } 623 } 624 registrationListElement = registrationListElement.Prev() 625 } 626 627 // Issue Callbacks.Down() calls from Back() to Front() of globals.registrationList 628 629 registrationListElement = globals.registrationList.Back() 630 631 for nil != registrationListElement { 632 registrationItem = registrationListElement.Value.(*registrationItemStruct) 633 logger.Tracef("transitions.Down() calling %s.Down()", registrationItem.packageName) 634 err = registrationItem.callbacks.Down(confMap) 635 if nil != err { 636 logger.Errorf("transitions.Down() call to %s.Down() failed: %v", registrationItem.packageName, err) 637 err = fmt.Errorf("%s.Down() failed: %v", registrationItem.packageName, err) 638 return 639 } 640 registrationListElement = registrationListElement.Prev() 641 } 642 643 return 644 } 645 646 func computeConfMapDelta(confMap conf.ConfMap) (newConfMapDelta *confMapDeltaStruct, err error) { 647 var ( 648 fsGlobalsVolumeGroupList []string 649 ok bool 650 volume *volumeStruct 651 volumeGroup *volumeGroupStruct 652 volumeGroupName string 653 volumeGroupVolumeList []string 654 volumeGroupPreviously *volumeGroupStruct 655 volumeName string 656 volumePreviously *volumeStruct 657 whoAmI string 658 ) 659 660 // TODO: Remove call to upgradeConfMapIfNeeded() once backwards compatibility is no longer required 661 662 err = upgradeConfMapIfNeeded(confMap) 663 if nil != err { 664 return 665 } 666 667 // Initialize lists used in computation 668 669 newConfMapDelta = &confMapDeltaStruct{ 670 volumeGroupList: make(map[string]*volumeGroupStruct), 671 servedVolumeGroupList: make(map[string]*volumeGroupStruct), 672 remoteVolumeGroupList: make(map[string]*volumeGroupStruct), 673 674 createdVolumeGroupList: make(map[string]*volumeGroupStruct), 675 movedVolumeGroupList: make(map[string]*volumeGroupStruct), 676 destroyedVolumeGroupList: make(map[string]*volumeGroupStruct), 677 678 volumeList: make(map[string]*volumeStruct), 679 servedVolumeList: make(map[string]*volumeStruct), 680 remoteVolumeList: make(map[string]*volumeStruct), 681 682 createdVolumeList: make(map[string]*volumeStruct), 683 movedVolumeList: make(map[string]*volumeStruct), 684 destroyedVolumeList: make(map[string]*volumeStruct), 685 686 toStopServingVolumeList: make(map[string]*volumeStruct), 687 toStartServingVolumeList: make(map[string]*volumeStruct), 688 } 689 690 // Ingest confMap 691 692 whoAmI, err = confMap.FetchOptionValueString("Cluster", "WhoAmI") 693 if nil != err { 694 return 695 } 696 697 fsGlobalsVolumeGroupList, err = confMap.FetchOptionValueStringSlice("FSGlobals", "VolumeGroupList") 698 if nil != err { 699 return 700 } 701 702 for _, volumeGroupName = range fsGlobalsVolumeGroupList { 703 volumeGroup = &volumeGroupStruct{name: volumeGroupName, volumeList: make(map[string]*volumeStruct)} 704 705 newConfMapDelta.volumeGroupList[volumeGroupName] = volumeGroup 706 707 volumeGroup.activePeer, err = confMap.FetchOptionValueString("VolumeGroup:"+volumeGroupName, "PrimaryPeer") 708 if nil != err { 709 if nil == confMap.VerifyOptionValueIsEmpty("VolumeGroup:"+volumeGroupName, "PrimaryPeer") { 710 volumeGroup.activePeer = "" 711 } else { 712 return 713 } 714 } 715 716 volumeGroup.served = (whoAmI == volumeGroup.activePeer) 717 718 if volumeGroup.served { 719 newConfMapDelta.servedVolumeGroupList[volumeGroupName] = volumeGroup 720 } else { 721 newConfMapDelta.remoteVolumeGroupList[volumeGroupName] = volumeGroup 722 } 723 724 volumeGroup.virtualIPAddr, err = confMap.FetchOptionValueString("VolumeGroup:"+volumeGroupName, "VirtualIPAddr") 725 if nil != err { 726 if nil == confMap.VerifyOptionValueIsEmpty("VolumeGroup:"+volumeGroupName, "VirtualIPAddr") { 727 volumeGroup.virtualIPAddr = "" 728 } else { 729 return 730 } 731 } 732 733 volumeGroupVolumeList, err = confMap.FetchOptionValueStringSlice("VolumeGroup:"+volumeGroupName, "VolumeList") 734 if nil != err { 735 return 736 } 737 738 for _, volumeName = range volumeGroupVolumeList { 739 volume = &volumeStruct{name: volumeName, served: volumeGroup.served, volumeGroup: volumeGroup} 740 741 newConfMapDelta.volumeList[volumeName] = volume 742 743 if volume.served { 744 newConfMapDelta.servedVolumeList[volumeName] = volume 745 } else { 746 newConfMapDelta.remoteVolumeList[volumeName] = volume 747 } 748 749 volumeGroup.volumeList[volumeName] = volume 750 } 751 } 752 753 // Compute changes to VolumeGroupList 754 755 for volumeGroupName, volumeGroup = range newConfMapDelta.volumeGroupList { 756 volumeGroupPreviously, ok = globals.currentConfMapDelta.volumeGroupList[volumeGroupName] 757 if ok { 758 if volumeGroupPreviously.activePeer != volumeGroup.activePeer { 759 newConfMapDelta.movedVolumeGroupList[volumeGroupName] = volumeGroup 760 } 761 } else { 762 newConfMapDelta.createdVolumeGroupList[volumeGroupName] = volumeGroup 763 } 764 } 765 766 for volumeGroupName, volumeGroup = range globals.currentConfMapDelta.volumeGroupList { 767 _, ok = newConfMapDelta.volumeGroupList[volumeGroupName] 768 if !ok { 769 newConfMapDelta.destroyedVolumeGroupList[volumeGroupName] = volumeGroup 770 } 771 } 772 773 // Compute changes to VolumeList 774 775 for volumeName, volume = range newConfMapDelta.volumeList { 776 volumePreviously, ok = globals.currentConfMapDelta.volumeList[volumeName] 777 if ok { 778 if volumePreviously.volumeGroup.name != volume.volumeGroup.name { 779 newConfMapDelta.movedVolumeList[volumeName] = volume 780 } 781 } else { 782 newConfMapDelta.createdVolumeList[volumeName] = volume 783 } 784 } 785 786 for volumeName, volume = range globals.currentConfMapDelta.volumeList { 787 _, ok = newConfMapDelta.volumeList[volumeName] 788 if !ok { 789 newConfMapDelta.destroyedVolumeList[volumeName] = volume 790 } 791 } 792 793 // Compute to{Stop|Start}ServingVolumeList 794 795 for volumeName, volume = range newConfMapDelta.destroyedVolumeList { 796 _, ok = globals.currentConfMapDelta.servedVolumeList[volumeName] 797 if ok { 798 newConfMapDelta.toStopServingVolumeList[volumeName] = volume 799 } 800 } 801 for volumeName, volume = range newConfMapDelta.movedVolumeList { 802 _, ok = globals.currentConfMapDelta.servedVolumeList[volumeName] 803 if ok { 804 newConfMapDelta.toStopServingVolumeList[volumeName] = volume 805 } 806 } 807 for _, volumeGroup = range newConfMapDelta.movedVolumeGroupList { 808 for volumeName, volume = range volumeGroup.volumeList { 809 _, ok = globals.currentConfMapDelta.servedVolumeList[volumeName] 810 if ok { 811 newConfMapDelta.toStopServingVolumeList[volumeName] = volume 812 } 813 } 814 } 815 816 for _, volumeGroup = range newConfMapDelta.movedVolumeGroupList { 817 for volumeName, volume = range volumeGroup.volumeList { 818 _, ok = newConfMapDelta.servedVolumeList[volumeName] 819 if ok { 820 newConfMapDelta.toStartServingVolumeList[volumeName] = volume 821 } 822 } 823 } 824 for volumeName, volume = range newConfMapDelta.movedVolumeList { 825 _, ok = newConfMapDelta.servedVolumeList[volumeName] 826 if ok { 827 newConfMapDelta.toStartServingVolumeList[volumeName] = volume 828 } 829 } 830 for volumeName, volume = range newConfMapDelta.createdVolumeList { 831 _, ok = newConfMapDelta.servedVolumeList[volumeName] 832 if ok { 833 newConfMapDelta.toStartServingVolumeList[volumeName] = volume 834 } 835 } 836 837 // All done 838 839 err = nil 840 return 841 } 842 843 // upgradeConfMapIfNeeded should be removed once backwards compatibility is no longer required... 844 // 845 // In the meantime, the changes are: 846 // 847 // MaxFlushSize moves from FlowControl: section to the Volume: section (for each Volume referencing it) 848 // MaxFlushTime moves from FlowControl: section to the Volume: section (for each Volume referencing it) 849 // FileDefragmentChunkSize (if present) moves from FlowControl: section to the Volume: section (for each Volume referencing it) 850 // FileDefragmentChunkDelay (if present) moves from FlowControl: section to the Volume: section (for each Volume referencing it) 851 // 852 // VolumeList in FSGlobals is renamed VolumeGroupList 853 // 854 // VolumeGroup: section is created for every Volume: section 855 // VolumeList in VolumeGroup: section references the identically named Volume 856 // VirtualIPAddr in VolumeGroup: section is empty 857 // PrimaryPeer moves from Volume: section to VolumeGroup: section 858 // ReadCacheLineSize moves from FlowControl: section to VolumeGroup: section (for each Volume referencing it) 859 // ReadCacheWeight moves from FlowControl: section to VolumeGroup: section (for each Volume referencing it) 860 // 861 // PrimaryPeer is removed from Volume: section 862 // FlowControl is removed from Volume: section 863 // 864 // FlowControl: section is removed 865 // 866 // Generation of the name of the created VolumeGroup for each Volume 867 // is computed by prepending an optional prefix and appending an 868 // optional suffix as specified in the conf.ConfMap 869 // 870 // The upgrade will commence if FSGlobals section contains a VolumeList 871 // The upgrade is unnecessary if FSGlobals section already container a VolumeGroupList 872 // 873 func upgradeConfMapIfNeeded(confMap conf.ConfMap) (err error) { 874 var ( 875 autoVolumeGroupNamePrefix string 876 autoVolumeGroupNamePrefixOK bool 877 autoVolumeGroupNamePrefixSlice []string 878 autoVolumeGroupNameSuffix string 879 autoVolumeGroupNameSuffixOK bool 880 autoVolumeGroupNameSuffixSlice []string 881 fileDefragmentChunkDelay conf.ConfMapOption 882 fileDefragmentChunkDelayOK bool 883 fileDefragmentChunkSize conf.ConfMapOption 884 fileDefragmentChunkSizeOK bool 885 flowControl conf.ConfMapSection 886 flowControlName conf.ConfMapOption 887 flowControlNameOK bool 888 flowControlOK bool 889 flowControlSet map[string]struct{} 890 flowControlSetElement string 891 fsGlobals conf.ConfMapSection 892 fsGlobalsOK bool 893 maxFlushSize conf.ConfMapOption 894 maxFlushSizeOK bool 895 maxFlushTime conf.ConfMapOption 896 maxFlushTimeOK bool 897 primaryPeer conf.ConfMapOption 898 primaryPeerOK bool 899 readCacheLineSize conf.ConfMapOption 900 readCacheLineSizeOK bool 901 readCacheWeight conf.ConfMapOption 902 readCacheWeightOK bool 903 transitions conf.ConfMapSection 904 transitionsOK bool 905 volume conf.ConfMapSection 906 volumeGroup conf.ConfMapSection 907 volumeGroupList conf.ConfMapOption 908 volumeGroupListOK bool 909 volumeOK bool 910 volumeList conf.ConfMapOption 911 volumeListOK bool 912 volumeName string 913 ) 914 915 fsGlobals, fsGlobalsOK = confMap["FSGlobals"] 916 917 if !fsGlobalsOK { 918 err = fmt.Errorf("confMap must contain an FSGlobals section") 919 return 920 } 921 922 volumeList, volumeListOK = fsGlobals["VolumeList"] 923 _, volumeGroupListOK = fsGlobals["VolumeGroupList"] 924 925 if (!volumeListOK && !volumeGroupListOK) || (volumeListOK && volumeGroupListOK) { 926 err = fmt.Errorf("confMap must contain precisely one of FSGlobals.VolumeList or FSGlobals.VolumeGroupList") 927 return 928 } 929 930 if volumeGroupListOK { 931 // No need to upgrade confMap 932 err = nil 933 return 934 } 935 936 transitions, transitionsOK = confMap["Transitions"] 937 if transitionsOK { 938 autoVolumeGroupNamePrefixSlice, autoVolumeGroupNamePrefixOK = transitions["AutoVolumeGroupPrefix"] 939 if autoVolumeGroupNamePrefixOK { 940 switch len(autoVolumeGroupNamePrefixSlice) { 941 case 0: 942 autoVolumeGroupNamePrefix = "" 943 case 1: 944 autoVolumeGroupNamePrefix = autoVolumeGroupNamePrefixSlice[0] 945 default: 946 err = fmt.Errorf("confMap must not contain a multi-valued Transitions:AutoVolumeGroupPrefix key") 947 return 948 } 949 } 950 autoVolumeGroupNameSuffixSlice, autoVolumeGroupNameSuffixOK = transitions["AutoVolumeGroupSuffix"] 951 if autoVolumeGroupNameSuffixOK { 952 switch len(autoVolumeGroupNameSuffixSlice) { 953 case 0: 954 autoVolumeGroupNameSuffix = "" 955 case 1: 956 autoVolumeGroupNameSuffix = autoVolumeGroupNameSuffixSlice[0] 957 default: 958 err = fmt.Errorf("confMap must not contain a multi-valued Transitions:AutoVolumeGroupSuffix key") 959 return 960 } 961 } 962 } else { 963 autoVolumeGroupNamePrefix = "" 964 autoVolumeGroupNameSuffix = "" 965 } 966 967 volumeGroupList = make(conf.ConfMapOption, 0, len(volumeList)) 968 for _, volumeName = range volumeList { 969 volumeGroupList = append(volumeGroupList, autoVolumeGroupNamePrefix+volumeName+autoVolumeGroupNameSuffix) 970 } 971 fsGlobals["VolumeGroupList"] = volumeGroupList 972 973 delete(fsGlobals, "VolumeList") 974 975 flowControlSet = make(map[string]struct{}) 976 977 for _, volumeName = range volumeList { 978 volume, volumeOK = confMap["Volume:"+volumeName] 979 if !volumeOK { 980 err = fmt.Errorf("confMap must contain a Volume:%s section", volumeName) 981 return 982 } 983 984 primaryPeer, primaryPeerOK = volume["PrimaryPeer"] 985 if !primaryPeerOK || (1 < len(primaryPeer)) { 986 err = fmt.Errorf("confMap must contain an empty or single-valued Volume:%s.PrimaryPeer key", volumeName) 987 return 988 } 989 990 flowControlName, flowControlNameOK = volume["FlowControl"] 991 if !flowControlNameOK || (1 != len(flowControlName)) { 992 err = fmt.Errorf("confMap must contain a single-valued Volume:%s.FlowControl key", volumeName) 993 return 994 } 995 996 flowControlSet[flowControlName[0]] = struct{}{} 997 998 flowControl, flowControlOK = confMap["FlowControl:"+flowControlName[0]] 999 if !flowControlOK { 1000 err = fmt.Errorf("confMap must contain a FlowControl:%s section", flowControlName) 1001 return 1002 } 1003 1004 maxFlushSize, maxFlushSizeOK = flowControl["MaxFlushSize"] 1005 if !maxFlushSizeOK { 1006 err = fmt.Errorf("confMap must contain a FlowControl:%s.MaxFlushSize key", flowControlName[0]) 1007 return 1008 } 1009 1010 maxFlushTime, maxFlushTimeOK = flowControl["MaxFlushTime"] 1011 if !maxFlushTimeOK { 1012 err = fmt.Errorf("confMap must contain a FlowControl:%s.MaxFlushTime key", flowControlName[0]) 1013 return 1014 } 1015 1016 fileDefragmentChunkSize, fileDefragmentChunkSizeOK = flowControl["FileDefragmentChunkSize"] 1017 fileDefragmentChunkDelay, fileDefragmentChunkDelayOK = flowControl["FileDefragmentChunkDelay"] 1018 1019 readCacheLineSize, readCacheLineSizeOK = flowControl["ReadCacheLineSize"] 1020 if !readCacheLineSizeOK { 1021 err = fmt.Errorf("confMap must contain a FlowControl:%s.ReadCacheLineSize key", flowControlName[0]) 1022 return 1023 } 1024 1025 readCacheWeight, readCacheWeightOK = flowControl["ReadCacheWeight"] 1026 if !readCacheWeightOK { 1027 err = fmt.Errorf("confMap must contain a FlowControl:%s.ReadCacheWeight key", flowControlName[0]) 1028 return 1029 } 1030 1031 volumeGroup = make(conf.ConfMapSection) 1032 1033 volumeGroup["VolumeList"] = []string{volumeName} 1034 volumeGroup["VirtualIPAddr"] = []string{} 1035 volumeGroup["PrimaryPeer"] = primaryPeer 1036 volumeGroup["ReadCacheLineSize"] = readCacheLineSize 1037 volumeGroup["ReadCacheWeight"] = readCacheWeight 1038 1039 confMap["VolumeGroup:"+autoVolumeGroupNamePrefix+volumeName+autoVolumeGroupNameSuffix] = volumeGroup 1040 1041 volume["MaxFlushSize"] = maxFlushSize 1042 volume["MaxFlushTime"] = maxFlushTime 1043 1044 if fileDefragmentChunkSizeOK { 1045 volume["FileDefragmentChunkSize"] = fileDefragmentChunkSize 1046 } 1047 if fileDefragmentChunkDelayOK { 1048 volume["FileDefragmentChunkDelay"] = fileDefragmentChunkDelay 1049 } 1050 1051 delete(volume, "PrimaryPeer") 1052 delete(volume, "FlowControl") 1053 } 1054 1055 for flowControlSetElement = range flowControlSet { 1056 delete(confMap, "FlowControl:"+flowControlSetElement) 1057 } 1058 1059 err = nil 1060 return 1061 } 1062 1063 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) Up(confMap conf.ConfMap) (err error) { 1064 return logger.Up(confMap) 1065 } 1066 1067 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) VolumeGroupCreated(confMap conf.ConfMap, volumeGroupName string, activePeer string, virtualIPAddr string) (err error) { 1068 return nil 1069 } 1070 1071 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) VolumeGroupMoved(confMap conf.ConfMap, volumeGroupName string, activePeer string, virtualIPAddr string) (err error) { 1072 return nil 1073 } 1074 1075 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) VolumeGroupDestroyed(confMap conf.ConfMap, volumeGroupName string) (err error) { 1076 return nil 1077 } 1078 1079 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) VolumeCreated(confMap conf.ConfMap, volumeName string, volumeGroupName string) (err error) { 1080 return nil 1081 } 1082 1083 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) VolumeMoved(confMap conf.ConfMap, volumeName string, volumeGroupName string) (err error) { 1084 return nil 1085 } 1086 1087 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) VolumeDestroyed(confMap conf.ConfMap, volumeName string) (err error) { 1088 return nil 1089 } 1090 1091 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) ServeVolume(confMap conf.ConfMap, volumeName string) (err error) { 1092 return nil 1093 } 1094 1095 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) UnserveVolume(confMap conf.ConfMap, volumeName string) (err error) { 1096 return nil 1097 } 1098 1099 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) VolumeToBeUnserved(confMap conf.ConfMap, volumeName string) (err error) { 1100 return nil 1101 } 1102 1103 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) SignaledStart(confMap conf.ConfMap) (err error) { 1104 return logger.SignaledStart(confMap) 1105 } 1106 1107 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) SignaledFinish(confMap conf.ConfMap) (err error) { 1108 return logger.SignaledFinish(confMap) 1109 } 1110 1111 func (loggerCallbacksInterface *loggerCallbacksInterfaceStruct) Down(confMap conf.ConfMap) (err error) { 1112 return logger.Down(confMap) 1113 } 1114 1115 func dumpGlobals(indent string) { 1116 var ( 1117 registrationItem *registrationItemStruct 1118 registrationListElement *list.Element 1119 volume *volumeStruct 1120 volumeGroup *volumeGroupStruct 1121 volumeGroupName string 1122 volumeName string 1123 ) 1124 1125 registrationListElement = globals.registrationList.Front() 1126 1127 if nil == registrationListElement { 1128 fmt.Printf("%sregistrationList: <empty>\n", indent) 1129 } else { 1130 fmt.Printf("%sregistrationList:", indent) 1131 for nil != registrationListElement { 1132 registrationItem = registrationListElement.Value.(*registrationItemStruct) 1133 fmt.Printf(" %s", registrationItem.packageName) 1134 registrationListElement = registrationListElement.Next() 1135 } 1136 fmt.Println() 1137 } 1138 1139 if 0 == len(globals.currentConfMapDelta.volumeGroupList) { 1140 fmt.Printf("%svolumeGroupList: <empty>\n", indent) 1141 } else { 1142 fmt.Printf("%svolumeGroupList:\n", indent) 1143 for volumeGroupName, volumeGroup = range globals.currentConfMapDelta.volumeGroupList { 1144 fmt.Printf("%s %+v [volumeList:", indent, volumeGroup) 1145 for volumeName = range volumeGroup.volumeList { 1146 fmt.Printf(" %s", volumeName) 1147 } 1148 fmt.Printf("]\n") 1149 } 1150 } 1151 1152 if 0 == len(globals.currentConfMapDelta.servedVolumeGroupList) { 1153 fmt.Printf("%sservedVolumeGroupList: <empty>\n", indent) 1154 } else { 1155 fmt.Printf("%sservedVolumeGroupList:", indent) 1156 for volumeGroupName = range globals.currentConfMapDelta.servedVolumeGroupList { 1157 fmt.Printf(" %s", volumeGroupName) 1158 } 1159 fmt.Println() 1160 } 1161 1162 if 0 == len(globals.currentConfMapDelta.remoteVolumeGroupList) { 1163 fmt.Printf("%sremoteVolumeGroupList: <empty>\n", indent) 1164 } else { 1165 fmt.Printf("%sremoteVolumeGroupList:", indent) 1166 for volumeGroupName = range globals.currentConfMapDelta.remoteVolumeGroupList { 1167 fmt.Printf(" %s", volumeGroupName) 1168 } 1169 fmt.Println() 1170 } 1171 1172 if 0 == len(globals.currentConfMapDelta.createdVolumeGroupList) { 1173 fmt.Printf("%screatedVolumeGroupList: <empty>\n", indent) 1174 } else { 1175 fmt.Printf("%screatedVolumeGroupList:", indent) 1176 for volumeGroupName = range globals.currentConfMapDelta.createdVolumeGroupList { 1177 fmt.Printf(" %s", volumeGroupName) 1178 } 1179 fmt.Println() 1180 } 1181 1182 if 0 == len(globals.currentConfMapDelta.movedVolumeGroupList) { 1183 fmt.Printf("%smovedVolumeGroupList: <empty>\n", indent) 1184 } else { 1185 fmt.Printf("%smovedVolumeGroupList:", indent) 1186 for volumeGroupName = range globals.currentConfMapDelta.movedVolumeGroupList { 1187 fmt.Printf(" %s", volumeGroupName) 1188 } 1189 fmt.Println() 1190 } 1191 1192 if 0 == len(globals.currentConfMapDelta.destroyedVolumeGroupList) { 1193 fmt.Printf("%sdestroyedVolumeGroupList: <empty>\n", indent) 1194 } else { 1195 fmt.Printf("%sdestroyedVolumeGroupList:", indent) 1196 for volumeGroupName = range globals.currentConfMapDelta.destroyedVolumeGroupList { 1197 fmt.Printf(" %s", volumeGroupName) 1198 } 1199 fmt.Println() 1200 } 1201 1202 if 0 == len(globals.currentConfMapDelta.volumeList) { 1203 fmt.Printf("%svolumeList: <empty>\n", indent) 1204 } else { 1205 fmt.Printf("%svolumeList:\n", indent) 1206 for volumeName, volume = range globals.currentConfMapDelta.volumeList { 1207 fmt.Printf("%s %+v [volumeGroup: %s]\n", indent, volume, volume.volumeGroup.name) 1208 } 1209 } 1210 1211 if 0 == len(globals.currentConfMapDelta.servedVolumeList) { 1212 fmt.Printf("%sservedVolumeList: <empty>\n", indent) 1213 } else { 1214 fmt.Printf("%sservedVolumeList:", indent) 1215 for volumeName = range globals.currentConfMapDelta.servedVolumeList { 1216 fmt.Printf(" %s", volumeName) 1217 } 1218 fmt.Println() 1219 } 1220 1221 if 0 == len(globals.currentConfMapDelta.remoteVolumeList) { 1222 fmt.Printf("%sremoteVolumeList: <empty>\n", indent) 1223 } else { 1224 fmt.Printf("%sremoteVolumeList:", indent) 1225 for volumeName = range globals.currentConfMapDelta.remoteVolumeList { 1226 fmt.Printf(" %s", volumeName) 1227 } 1228 fmt.Println() 1229 } 1230 1231 if 0 == len(globals.currentConfMapDelta.createdVolumeList) { 1232 fmt.Printf("%screatedVolumeList: <empty>\n", indent) 1233 } else { 1234 fmt.Printf("%screatedVolumeList:", indent) 1235 for volumeName = range globals.currentConfMapDelta.createdVolumeList { 1236 fmt.Printf(" %s", volumeName) 1237 } 1238 fmt.Println() 1239 } 1240 1241 if 0 == len(globals.currentConfMapDelta.movedVolumeList) { 1242 fmt.Printf("%smovedVolumeList: <empty>\n", indent) 1243 } else { 1244 fmt.Printf("%smovedVolumeList:", indent) 1245 for volumeName = range globals.currentConfMapDelta.movedVolumeList { 1246 fmt.Printf(" %s", volumeName) 1247 } 1248 fmt.Println() 1249 } 1250 1251 if 0 == len(globals.currentConfMapDelta.destroyedVolumeList) { 1252 fmt.Printf("%sdestroyedVolumeList: <empty>\n", indent) 1253 } else { 1254 fmt.Printf("%sdestroyedVolumeList:", indent) 1255 for volumeName = range globals.currentConfMapDelta.destroyedVolumeList { 1256 fmt.Printf(" %s", volumeName) 1257 } 1258 fmt.Println() 1259 } 1260 1261 if 0 == len(globals.currentConfMapDelta.toStopServingVolumeList) { 1262 fmt.Printf("%stoStopServingVolumeList: <empty>\n", indent) 1263 } else { 1264 fmt.Printf("%stoStopServingVolumeList:", indent) 1265 for volumeName = range globals.currentConfMapDelta.toStopServingVolumeList { 1266 fmt.Printf(" %s", volumeName) 1267 } 1268 fmt.Println() 1269 } 1270 1271 if 0 == len(globals.currentConfMapDelta.toStartServingVolumeList) { 1272 fmt.Printf("%stoStartServingVolumeList: <empty>\n", indent) 1273 } else { 1274 fmt.Printf("%stoStartServingVolumeList:", indent) 1275 for volumeName = range globals.currentConfMapDelta.toStartServingVolumeList { 1276 fmt.Printf(" %s", volumeName) 1277 } 1278 fmt.Println() 1279 } 1280 }