Add logic to set custom Log File Page number (#371)

* Add logic to set custom Log File Page number

Signed-off-by: Nicholas-Daffern <Nicholas.Daffern@ibm.com>
This commit is contained in:
Nicholas Daffern
2023-01-25 10:33:24 +00:00
committed by GitHub Enterprise
parent 862427306b
commit ed618dc6f6
9 changed files with 238 additions and 38 deletions

View File

@@ -1,5 +1,5 @@
/*
© Copyright IBM Corporation 2017, 2022
© Copyright IBM Corporation 2017, 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -55,23 +55,36 @@ func createDirStructure() error {
func createQueueManager(name string, devMode bool) (bool, error) {
log.Printf("Creating queue manager %v", name)
// Run 'dspmqinf' to check if 'mqs.ini' configuration file exists
// If command succeeds, the queue manager (or standby queue manager) has already been created
_, _, err := command.Run("dspmqinf", name)
if err == nil {
log.Printf("Detected existing queue manager %v", name)
return false, nil
}
mounts, err := containerruntime.GetMounts()
if err != nil {
log.Printf("Error getting mounts for queue manager")
return false, err
}
dataDir := getQueueManagerDataDir(mounts, name)
// Run 'dspmqinf' to check if 'mqs.ini' configuration file exists
// If command succeeds, the queue manager (or standby queue manager) has already been created
_, _, err = command.Run("dspmqinf", name)
if err == nil {
log.Printf("Detected existing queue manager %v", name)
// Check if MQ_QMGR_LOG_FILE_PAGES matches the value set in qm.ini
lfp := os.Getenv("MQ_QMGR_LOG_FILE_PAGES")
if lfp != "" {
qmIniBytes, err := readQMIni(dataDir)
if err != nil {
log.Printf("Error reading qm.ini : %v", err)
return false, err
}
if !validateLogFilePageSetting(qmIniBytes, lfp) {
log.Println("Warning: the value of MQ_QMGR_LOG_FILE_PAGES does not match the value of 'LogFilePages' in the qm.ini. This setting cannot be altered after Queue Manager creation.")
}
}
return false, nil
}
// Check if 'qm.ini' configuration file exists for the queue manager
// TODO : handle possible race condition - use a file lock?
dataDir := getQueueManagerDataDir(mounts, name)
_, err = os.Stat(filepath.Join(dataDir, "qm.ini"))
if err != nil {
// If 'qm.ini' is not found - run 'crtmqm' to create a new queue manager
@@ -96,6 +109,25 @@ func createQueueManager(name string, devMode bool) (bool, error) {
return true, nil
}
//readQMIni reads the qm.ini file and returns it as a byte array
//This function is specific to comply with the nosec.
func readQMIni(dataDir string) ([]byte, error) {
qmgrDir := filepath.Join(dataDir, "qm.ini")
// #nosec G304 - qmgrDir filepath is derived from dspmqinf
iniFileBytes, err := ioutil.ReadFile(qmgrDir)
if err != nil {
return nil, err
}
return iniFileBytes, err
}
//validateLogFilePageSetting validates if the specified logFilePage number is equal to the existing value in the qm.ini
func validateLogFilePageSetting(iniFileBytes []byte, logFilePages string) bool {
lfpString := "LogFilePages=" + logFilePages
qminiConfigStr := string(iniFileBytes)
return strings.Contains(qminiConfigStr, lfpString)
}
func updateCommandLevel() error {
level, ok := os.LookupEnv("MQ_CMDLEVEL")
if ok && level != "" {
@@ -238,6 +270,14 @@ func getCreateQueueManagerArgs(mounts map[string]string, name string, devMode bo
if _, ok := mounts["/mnt/mqm-data"]; ok {
args = append(args, "-md", "/mnt/mqm-data/qmgrs")
}
if os.Getenv("MQ_QMGR_LOG_FILE_PAGES") != "" {
_, err = strconv.Atoi(os.Getenv("MQ_QMGR_LOG_FILE_PAGES"))
if err != nil {
log.Printf("Error processing MQ_QMGR_LOG_FILE_PAGES, the default value for LogFilePages will be used. Err: %v", err)
} else {
args = append(args, "-lf", os.Getenv("MQ_QMGR_LOG_FILE_PAGES"))
}
}
args = append(args, name)
return args
}

View File

@@ -0,0 +1,86 @@
/*
© Copyright IBM Corporation 2023
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"io/ioutil"
"testing"
)
func Test_validateLogFilePageSetting(t *testing.T) {
type args struct {
iniFilePath string
isValid bool
logFilePagesValue string
}
tests := []struct {
name string
args args
}{
{
name: "TestLogFilePages1",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_1.ini",
isValid: true,
logFilePagesValue: "1235",
},
},
{
name: "TestLogFilePages2",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_2.ini",
isValid: true,
logFilePagesValue: "2224",
},
},
{
name: "TestLogFilePages3",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_3.ini",
isValid: false,
logFilePagesValue: "1235",
},
},
{
name: "TestLogFilePages4",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_4.ini",
isValid: false,
logFilePagesValue: "1235",
},
},
{
name: "TestLogFilePages5",
args: args{
iniFilePath: "./test-files/testvalidateLogFilePages_5.ini",
isValid: false,
logFilePagesValue: "1235",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
iniFileBytes, err := ioutil.ReadFile(tt.args.iniFilePath)
if err != nil {
t.Fatal(err)
}
validate := validateLogFilePageSetting(iniFileBytes, tt.args.logFilePagesValue)
if validate != tt.args.isValid {
t.Fatalf("Expected ini file validation output to be %v got %v", tt.args.isValid, validate)
}
})
}
}

View File

@@ -0,0 +1,9 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogFilePages=1235
LogBufferPages=0
LogWriteIntegrity=TripleWrite

View File

@@ -0,0 +1,9 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogFilePages=2224
LogBufferPages=0
LogWriteIntegrity=TripleWrite

View File

@@ -0,0 +1,9 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogFilePages=6002
LogBufferPages=0
LogWriteIntegrity=TripleWrite

View File

@@ -0,0 +1,8 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogBufferPages=0
LogWriteIntegrity=TripleWrite

View File

@@ -0,0 +1,8 @@
ExitPath:
ExitsDefaultPath=/mnt/mqm/data/exits
ExitsDefaultPath64=/mnt/mqm/data/exits64
Log:
LogPrimaryFiles=3
LogSecondaryFiles=2
LogBufferPages=1235
LogWriteIntegrity=TripleWrite