Skip to content

Commit 85a9d3d

Browse files
committed
Added support for multiple RDBMSes
This patch adds support for reading from multiple RDBMS systems, namely MariaDB and SQLite. That is a complementary patch to the same kind of support that was added to the kern_bin_db part. Signed-off-by: Lev Veyde <[email protected]>
1 parent 1c4e671 commit 85a9d3d

File tree

8 files changed

+60
-89
lines changed

8 files changed

+60
-89
lines changed

README.md

+16-20
Original file line numberDiff line numberDiff line change
@@ -49,43 +49,39 @@ Descr: kernel symbol navigator
4949
-s <v> Specifies symbol
5050
-i <v> Specifies instance
5151
-f <v> Specifies config file
52-
-u <v> Forces use specified database userid
53-
-p <v> Forecs use specified password
54-
-d <v> Forecs use specified DBhost
55-
-p <v> Forecs use specified DBPort
52+
-e <v> Forces to use a specified DB Driver (i.e. postgres, mysql or sqlite3)
53+
-d <v> Forces to use a specified DB DSN
5654
-m <v> Sets display mode 2=subsystems,1=all
5755
-h This Help
5856
```
5957

6058
## Sample configuration:
6159
```
6260
{
63-
"DBURL":"dbs.hqhome163.com",
64-
"DBPort":5432,
65-
"DBUser":"alessandro",
66-
"DBPassword":"<password>",
67-
"DBTargetDB":"kernel_bin",
68-
"Symbol":"__arm64_sys_getppid",
69-
"Instance":1,
70-
"Mode":1,
71-
"Excluded": ["rcu_.*", "kmalloc", "kfree"],
72-
"MaxDepth":0,
73-
"Jout": "JsonOutputPlain"
61+
"DBDriver": "postgres",
62+
"DBDSN": "host=dbs.hqhome163.com port=5432 user=alessandro password=<password> dbname=kernel_bin sslmode=disable",
63+
"Symbol": "__arm64_sys_getppid",
64+
"Instance": 1,
65+
"Mode": 1,
66+
"Excluded": ["rcu_.*", "kmalloc", "kfree"],
67+
"MaxDepth": 0,
68+
"Jout": "JsonOutputPlain"
7469
}
7570
```
7671
Configuration is a file containing a JSON serialized conf object
7772

7873
|Field |description |type |Default value |
7974
|-------------|-----------------------------------------------------------------------------------------------------------|--------|-------------------|
80-
|DBURL |Host name ot ip address of the psql instance |string |dbs.hqhome163.com |
81-
|DBPort |tcp port where psql instance is listening |integer |5432 |
82-
|DBUser |Valid username on the psql instance |string |alessandro |
83-
|DBPassword |Valid password on the psql instance |string |<password> |
84-
|DBTargetDB |The identifier for the DB containing symbols |string |kernel_bin |
75+
|DBDriver |Name of DB engine driver, i.e. postgres, mysql or sqlite3 |string |postgres |
76+
|DBDSN |DSN in the engine specific format |string |See Note |
8577
|Symbol |The symbol where start the navigation |string |NULL |
8678
|Instance |The interesting symbols instance identifier |integer |1 |
8779
|Mode |Mode of plotting: 1 symbols, 2 subsystems, 3 subsystems with labels,4 target subsystem isolation |integer |2 |
8880
|Excluded |List of symbols/subsystem not to be expanded |string[]|["rcu_.*"] |
8981
|MaxDepth |Max number of levels to explore 0 no limit |integer |0 |
9082
|Jout |Type of output: GraphOnly, JsonOutputPlain, JsonOutputB64, JsonOutputGZB64 |enum |GraphOnly |
9183
|Target_sybsys|List of subsys that need to be highlighted. if empty, only the subs that contain the start is highlighted |string |[] |
84+
85+
**NOTE:** Currently the default DBDSN value is set to:
86+
host=dbs.hqhome163.com port=5432 user=alessandro password=<password> dbname=kernel_bin sslmode=disable
87+
to be consistent with the previous default configuration.

config.go

+10-34
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ const (
1919
appDescr string = "Descr: kernel symbol navigator"
2020
)
2121

22-
const DBPortNumber = 5432
23-
2422
type argFunc func(*configuration, []string) error
2523

2624
// Command line switch elements.
@@ -36,10 +34,8 @@ type cmdLineItems struct {
3634
// Represents the application configuration.
3735
type configuration struct {
3836
cmdlineNeeds map[string]bool
39-
DBTargetDB string
40-
DBUrl string
41-
DBUser string
42-
DBPassword string
37+
DBDriver string
38+
DBDSN string
4339
Symbol string
4440
Jout string
4541
ExcludedBefore []string
@@ -48,16 +44,12 @@ type configuration struct {
4844
Instance int
4945
MaxDepth int
5046
Mode outMode
51-
DBPort int
5247
}
5348

5449
// Instance of default configuration values.
5550
var defaultConfig = configuration{
56-
DBUrl: "dbs.hqhome163.com",
57-
DBPort: DBPortNumber,
58-
DBUser: "alessandro",
59-
DBPassword: "<password>",
60-
DBTargetDB: "kernel_bin",
51+
DBDriver: "postgres",
52+
DBDSN: "host=dbs.hqhome163.com port=5432 user=alessandro password=<password> dbname=kernel_bin sslmode=disable",
6153
Symbol: "",
6254
Instance: 0,
6355
Mode: printSubsys,
@@ -88,10 +80,8 @@ func cmdLineItemInit() []cmdLineItems {
8880
pushCmdLineItem("-s", "Specifies symbol", true, true, funcSymbol, &res)
8981
pushCmdLineItem("-i", "Specifies instance", true, true, funcInstance, &res)
9082
pushCmdLineItem("-f", "Specifies config file", true, false, funcJconf, &res)
91-
pushCmdLineItem("-u", "Forces use specified database userid", true, false, funcDBUser, &res)
92-
pushCmdLineItem("-p", "Forces use specified password", true, false, funcDBPass, &res)
93-
pushCmdLineItem("-d", "Forces use specified DBHost", true, false, funcDBHost, &res)
94-
pushCmdLineItem("-p", "Forces use specified DBPort", true, false, funcDBPort, &res)
83+
pushCmdLineItem("-e", "Forces to use a specified DB Driver (i.e. postgres, mysql or sqlite3)", true, false, funcDBDriver, &res)
84+
pushCmdLineItem("-d", "Forces to use a specified DB DSN", true, false, funcDBDSN, &res)
9585
pushCmdLineItem("-m", "Sets display mode 2=subsystems,1=all", true, false, funcMode, &res)
9686
pushCmdLineItem("-x", "Specify Max depth in call flow exploration", true, false, funcDepth, &res)
9787
pushCmdLineItem("-h", "This help", false, false, funcHelp, &res)
@@ -133,27 +123,13 @@ func funcSymbol(conf *configuration, fn []string) error {
133123
return nil
134124
}
135125

136-
func funcDBUser(conf *configuration, user []string) error {
137-
conf.DBUser = user[0]
138-
return nil
139-
}
140-
141-
func funcDBPass(conf *configuration, pass []string) error {
142-
conf.DBPassword = pass[0]
143-
return nil
144-
}
145-
146-
func funcDBHost(conf *configuration, host []string) error {
147-
conf.DBUrl = host[0]
126+
func funcDBDriver(conf *configuration, driver []string) error {
127+
conf.DBDriver = driver[0]
148128
return nil
149129
}
150130

151-
func funcDBPort(conf *configuration, port []string) error {
152-
s, err := strconv.Atoi(port[0])
153-
if err != nil {
154-
return err
155-
}
156-
conf.DBPort = s
131+
func funcDBDSN(conf *configuration, dsn []string) error {
132+
conf.DBDSN = dsn[0]
157133
return nil
158134
}
159135

psql.go db.go

+19-17
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import (
1313
"sort"
1414
"strings"
1515

16+
_ "github.com/go-sql-driver/mysql"
1617
_ "github.com/lib/pq"
18+
_ "github.com/mattn/go-sqlite3"
1719
)
1820

1921
type outMode int64
@@ -43,11 +45,8 @@ type adjM struct {
4345

4446
// Sql connection configuration.
4547
type connectToken struct {
46-
host string
47-
port int
48-
user string
49-
pass string
50-
dbname string
48+
DBDriver string
49+
DBDSN string
5150
}
5251

5352
type entry struct {
@@ -74,8 +73,7 @@ type Cache struct {
7473

7574
// Connects the target db and returns the handle.
7675
func connectDb(t *connectToken) *sql.DB {
77-
psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", t.host, t.port, t.user, t.pass, t.dbname)
78-
db, err := sql.Open("postgres", psqlconn)
76+
db, err := sql.Open(t.DBDriver, t.DBDSN)
7977
if err != nil {
8078
panic(err)
8179
}
@@ -92,9 +90,10 @@ func getEntryById(db *sql.DB, symbolId int, instance int, cache map[int]entry) (
9290
}
9391

9492
query := "select symbol_id, symbol_name, subsys_name, file_name from " +
95-
"(select * from symbols, files where symbols.symbol_file_ref_id=files.file_id and symbols.symbol_instance_id_ref=$2) as dummy " +
96-
"left outer join tags on dummy.symbol_file_ref_id=tags.tag_file_ref_id where symbol_id=$1 and symbol_instance_id_ref=$2"
97-
rows, err := db.Query(query, symbolId, instance)
93+
"(select * from symbols, files where symbols.symbol_file_ref_id=files.file_id and symbols.symbol_instance_id_ref=%[2]d) as dummy " +
94+
"left outer join tags on dummy.symbol_file_ref_id=tags.tag_file_ref_id where symbol_id=%[1]d and symbol_instance_id_ref=%[2]d"
95+
query = fmt.Sprintf(query, symbolId, instance)
96+
rows, err := db.Query(query)
9897
if err != nil {
9998
panic(err)
10099
}
@@ -132,8 +131,9 @@ func getSuccessorsById(db *sql.DB, symbolId int, instance int, cache Cache) ([]e
132131
return res, nil
133132
}
134133

135-
query := "select caller, callee, source_line, ref_addr from xrefs where caller =$1 and xref_instance_id_ref=$2"
136-
rows, err := db.Query(query, symbolId, instance)
134+
query := "select caller, callee, source_line, ref_addr from xrefs where caller = %[1]d and xref_instance_id_ref = %[2]d"
135+
query = fmt.Sprintf(query, symbolId, instance)
136+
rows, err := db.Query(query)
137137
if err != nil {
138138
panic(err)
139139
}
@@ -195,12 +195,13 @@ func getSubsysFromSymbolName(db *sql.DB, symbol string, instance int, subsytemsC
195195
if res, ok := subsytemsCache[symbol]; ok {
196196
return res, nil
197197
}
198-
query := "select (select symbol_type from symbols where symbol_name=$1 and symbol_instance_id_ref=$2) as type, subsys_name from " +
198+
query := "select (select symbol_type from symbols where symbol_name='%[1]s' and symbol_instance_id_ref=%[2]d) as type, subsys_name from " +
199199
"(select count(*) as cnt, subsys_name from tags where subsys_name in (select subsys_name from symbols, " +
200-
"tags where symbols.symbol_file_ref_id=tags.tag_file_ref_id and symbols.symbol_name=$1 and symbols.symbol_instance_id_ref=$2) " +
200+
"tags where symbols.symbol_file_ref_id=tags.tag_file_ref_id and symbols.symbol_name='%[1]s' and symbols.symbol_instance_id_ref=%[2]d) " +
201201
"group by subsys_name order by cnt desc) as tbl;"
202202

203-
rows, err := db.Query(query, symbol, instance)
203+
query = fmt.Sprintf(query, symbol, instance)
204+
rows, err := db.Query(query)
204205
if err != nil {
205206
panic(err)
206207
}
@@ -229,8 +230,9 @@ func getSubsysFromSymbolName(db *sql.DB, symbol string, instance int, subsytemsC
229230
func sym2num(db *sql.DB, symb string, instance int) (int, error) {
230231
var res = 0
231232
var cnt = 0
232-
query := "select symbol_id from symbols where symbols.symbol_name=$1 and symbols.symbol_instance_id_ref=$2"
233-
rows, err := db.Query(query, symb, instance)
233+
query := "select symbol_id from symbols where symbols.symbol_name='%[1]s' and symbols.symbol_instance_id_ref=%[2]d"
234+
query = fmt.Sprintf(query, symb, instance)
235+
rows, err := db.Query(query)
234236
if err != nil {
235237
panic(err)
236238
}

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ module nav
33
go 1.18
44

55
require (
6+
github.com/go-sql-driver/mysql v1.7.0 // indirect
67
github.com/lib/pq v1.10.6 // indirect
8+
github.com/mattn/go-sqlite3 v1.14.16 // indirect
79
)

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
2+
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
13
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
24
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
5+
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
6+
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
37
github.com/radareorg/r2pipe-go v0.2.1 h1:2bVIi7qHPQCdjjngcJbQO2VHSqPaRBt5LUAMk2uq84o=
48
github.com/radareorg/r2pipe-go v0.2.1/go.mod h1:HNUWNjS7SjzhZ7McDLhvIBSOLz1X9DNLjj4J52pAj3Y=

main_test.go

+6-12
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@ import (
1616
func compareConfigs(c1 configuration, c2 configuration) bool {
1717

1818
res := true
19-
res = res && c1.DBUrl == c2.DBUrl
20-
res = res && c1.DBPort == c2.DBPort
21-
res = res && c1.DBUser == c2.DBUser
22-
res = res && c1.DBPassword == c2.DBPassword
23-
res = res && c1.DBTargetDB == c2.DBTargetDB
19+
res = res && c1.DBDriver == c2.DBDriver
20+
res = res && c1.DBDSN == c2.DBDSN
2421
res = res && c1.Symbol == c2.Symbol
2522
res = res && c1.Instance == c2.Instance
2623
res = res && c1.Mode == c2.Mode
@@ -41,11 +38,8 @@ func compareConfigs(c1 configuration, c2 configuration) bool {
4138
func TestConfig(t *testing.T) {
4239

4340
var testConfig = configuration{
44-
DBUrl: "dummy",
45-
DBPort: 1234,
46-
DBUser: "dummy",
47-
DBPassword: "dummy",
48-
DBTargetDB: "dummy",
41+
DBDriver: "dummy",
42+
DBDSN: "dummy",
4943
Symbol: "dummy",
5044
Instance: 1234,
5145
Mode: 1234,
@@ -106,8 +100,8 @@ func TestConfig(t *testing.T) {
106100
}
107101

108102
tmp := testConfig
109-
tmp.DBUser = "new"
110-
os.Args = []string{"nav", "-i", "1", "-s", "symb", "-f", current + "/t_files/test1.json", "-u", "new"}
103+
tmp.DBDriver = "new"
104+
os.Args = []string{"nav", "-i", "1", "-s", "symb", "-f", current + "/t_files/test1.json", "-e", "new"}
111105
conf, err = argsParse(cmdLineItemInit())
112106
if err != nil {
113107
t.Error("Unexpected conf error while reading from existing file", err, current+"/t_files/test1.json")

nav.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func main() {
190190
fmt.Printf("Unknown mode %s\n", conf.Jout)
191191
os.Exit(-2)
192192
}
193-
t := connectToken{conf.DBUrl, conf.DBPort, conf.DBUser, conf.DBPassword, conf.DBTargetDB}
193+
t := connectToken{conf.DBDriver, conf.DBDSN}
194194
db := connectDb(&t)
195195

196196
output, err := generateOutput(db, &conf)

t_files/test1.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
{
2-
"DBURL":"dummy",
3-
"DBPort":1234,
4-
"DBUser":"dummy",
5-
"DBPassword":"dummy",
6-
"DBTargetDB":"dummy",
2+
"DBDriver":"dummy",
3+
"DBDSN":"dummy",
74
"Symbol":"dummy",
85
"Instance":1234,
96
"Mode":1234,

0 commit comments

Comments
 (0)