From 7b73a20d34f72027e25bcfe964f60121197347a3 Mon Sep 17 00:00:00 2001 From: Alexey Kostin Date: Tue, 19 Feb 2019 10:16:11 +0300 Subject: [PATCH] No pointers, different types, prepare functions, crush --- ceph-gobench.go | 41 ++++-- cephconnection.go | 2 +- flags.go | 4 +- types.go | 363 ++++++++++++++++++++++++++++++---------------- 4 files changed, 269 insertions(+), 141 deletions(-) diff --git a/ceph-gobench.go b/ceph-gobench.go index 6bdf058..de59f80 100644 --- a/ceph-gobench.go +++ b/ceph-gobench.go @@ -7,8 +7,9 @@ import ( "time" ) -func get_pool_size(cephconn *Cephconnection, params *Params) *Monanswer { - monjson, err := json.Marshal(Moncommand{Prefix: "osd pool get", Pool: params.pool, Format: "json", Var: "size"}) +func get_pool_size(cephconn *Cephconnection, params Params) Poolinfo { + monjson, err := json.Marshal(map[string]string{"prefix": "osd pool get", "pool": params.pool, + "format": "json", "var": "size"}) if err != nil { log.Fatalf("Can't marshal json mon query. Error: %v", err) } @@ -18,16 +19,16 @@ func get_pool_size(cephconn *Cephconnection, params *Params) *Monanswer { log.Fatalf("Failed exec monCommand. Error: %v", err) } - monanswer := Monanswer{} + monanswer := Poolinfo{} if err := json.Unmarshal([]byte(monrawanswer), &monanswer); err != nil { log.Fatalf("Can't parse monitor answer. Error: %v", err) } - return &monanswer + return monanswer } -func get_pg_by_pool(cephconn *Cephconnection, params *Params) *[]PlacementGroup { - monjson, err := json.Marshal(Moncommand{Prefix: "pg ls-by-pool", Poolstr: params.pool, Format: "json"}) +func get_pg_by_pool(cephconn *Cephconnection, params Params) []PlacementGroup { + monjson, err := json.Marshal(map[string]string{"prefix": "pg ls-by-pool", "poolstr": params.pool, "format": "json"}) if err != nil { log.Fatalf("Can't marshal json mon query. Error: %v", err) } @@ -40,9 +41,17 @@ func get_pg_by_pool(cephconn *Cephconnection, params *Params) *[]PlacementGroup if err := json.Unmarshal([]byte(monrawanswer), &monanswer); err != nil { log.Fatalf("Can't parse monitor answer. Error: %v", err) } - return &monanswer + return monanswer } +//func get_crush_dump(params Params, cephconn *Cephconnection) OsdCrushDump { +// +//} + +//func get_acting_osd(params Params, ) map[string]float64 { +// +//} + func main() { params := Route() cephconn := connectioninit(params) @@ -51,11 +60,6 @@ func main() { // https://tracker.ceph.com/issues/24114 time.Sleep(time.Millisecond * 100) - stats, _ := cephconn.ioctx.GetPoolStats() - log.Println(stats) - - log.Printf("%v\n", params.blocksize) - var buffs [][]byte for i := 0; i < 2*params.threadsCount; i++ { buffs = append(buffs, make([]byte, params.blocksize)) @@ -67,13 +71,18 @@ func main() { log.Fatalln(err) } } - monanswersize := get_pool_size(cephconn, params) - if monanswersize.Size != 1 { + poolinfo := get_pool_size(cephconn, params) + if poolinfo.Size != 1 { log.Fatalf("Pool size must be 1. Current size for pool %v is %v. Don't forget that it must be useless pool (not production). Do:\n # ceph osd pool set %v min_size 1\n # ceph osd pool set %v size 1", - monanswersize.Pool, monanswersize.Size, monanswersize.Pool, monanswersize.Pool) + poolinfo.Pool, poolinfo.Size, poolinfo.Pool, poolinfo.Pool) } placementGroups := get_pg_by_pool(cephconn, params) - log.Println(placementGroups) + for _, value := range placementGroups { + log.Printf("%+v\n", value) + } } + +//TODO Получить структуру пула (osd dump), рул. Получить все рулы (osd crush dump). Разобрать краш карту, получить список осд. +//TODO получить список PG, если не все находятся на нужных OSD выкинуть эксепшн. diff --git a/cephconnection.go b/cephconnection.go index d25f0e7..9d19b0a 100644 --- a/cephconnection.go +++ b/cephconnection.go @@ -6,7 +6,7 @@ import ( "os" ) -func connectioninit(params *Params) *Cephconnection { +func connectioninit(params Params) *Cephconnection { cephconn := &Cephconnection{} var err error if _, err := os.Stat(params.config); os.IsNotExist(err) { diff --git a/flags.go b/flags.go index 71becc7..9c17b07 100644 --- a/flags.go +++ b/flags.go @@ -7,7 +7,7 @@ import ( "strings" ) -func Route() *Params { +func Route() Params { params := Params{} gnuflag.DurationVar(¶ms.duration, "duration", 30, "Time limit for each test in seconds") @@ -61,5 +61,5 @@ func Route() *Params { log.Println("Can't convert defined block size. 4K block size will be used\n") params.blocksize = 4096 } - return ¶ms + return params } diff --git a/types.go b/types.go index 9f28c46..457fe1d 100644 --- a/types.go +++ b/types.go @@ -18,15 +18,7 @@ type Cephconnection struct { ioctx *rados.IOContext } -type Moncommand struct { - Prefix string `json:"prefix"` - Pool string `json:"pool"` - Format string `json:"format"` - Var string `json:"var,omitempty"` - Poolstr string `json:"poolstr,omitempty"` -} - -type Monanswer struct { +type Poolinfo struct { Pool string `json:"pool,omitempty"` PoolId int `json:"pool_id,omitempty"` Size int `json:"size,omitempty"` @@ -34,120 +26,247 @@ type Monanswer struct { func (times *PlacementGroup) StringsToTimes() { const LongForm = "2006-01-02 15:04:05.000000" - times.Last_fresh, _ = time.Parse(LongForm, times.Last_fresh_str) - times.Last_change, _ = time.Parse(LongForm, times.Last_fresh_str) - times.Last_active, _ = time.Parse(LongForm, times.Last_active_str) - times.Last_peered, _ = time.Parse(LongForm, times.Last_peered_str) - times.Last_clean, _ = time.Parse(LongForm, times.Last_clean_str) - times.Last_became_active, _ = time.Parse(LongForm, times.Last_became_active_str) - times.Last_became_peered, _ = time.Parse(LongForm, times.Last_became_peered_str) - times.Last_unstale, _ = time.Parse(LongForm, times.Last_unstale_str) - times.Last_undegraded, _ = time.Parse(LongForm, times.Last_undegraded_str) - times.Last_fullsized, _ = time.Parse(LongForm, times.Last_fullsized_str) - times.Last_deep_scrub_stamp, _ = time.Parse(LongForm, times.Last_deep_scrub_stamp_str) - times.Last_deep_scrub, _ = time.Parse(LongForm, times.Last_deep_scrub_str) - times.Last_clean_scrub_stamp, _ = time.Parse(LongForm, times.Last_clean_scrub_stamp_str) - times.Last_scrub_stamp, _ = time.Parse(LongForm, times.Last_scrub_stamp_str) - times.Last_scrub, _ = time.Parse(LongForm, times.Last_scrub_str) + times.LastFreshT, _ = time.Parse(LongForm, times.LastFresh) + times.LastChangeT, _ = time.Parse(LongForm, times.LastChange) + times.LastActiveT, _ = time.Parse(LongForm, times.LastActive) + times.LastPeeredT, _ = time.Parse(LongForm, times.LastPeered) + times.LastCleanT, _ = time.Parse(LongForm, times.LastClean) + times.LastBecameActiveT, _ = time.Parse(LongForm, times.LastBecameActive) + times.LastBecamePeeredT, _ = time.Parse(LongForm, times.LastBecamePeered) + times.LastUnstaleT, _ = time.Parse(LongForm, times.LastUnstale) + times.LastUndegradedT, _ = time.Parse(LongForm, times.LastUndegraded) + times.LastFullsizedT, _ = time.Parse(LongForm, times.LastFullsized) + times.LastDeepScrubStampT, _ = time.Parse(LongForm, times.LastDeepScrubStamp) + times.LastDeepScrubT, _ = time.Parse(LongForm, times.LastDeepScrub) + times.LastCleanScrubStampT, _ = time.Parse(LongForm, times.LastCleanScrubStamp) + times.LastScrubStampT, _ = time.Parse(LongForm, times.LastScrubStamp) + times.LastScrubT, _ = time.Parse(LongForm, times.LastScrub) +} + +type OsdCrushDump struct { + Buckets []struct { + Alg string `json:"alg"` + Hash string `json:"hash"` + ID int64 `json:"id"` + Items []struct { + ID int64 `json:"id"` + Pos int64 `json:"pos"` + Weight int64 `json:"weight"` + } `json:"items"` + Name string `json:"name"` + TypeID int64 `json:"type_id"` + TypeName string `json:"type_name"` + Weight int64 `json:"weight"` + } `json:"buckets"` + ChooseArgs struct{} `json:"choose_args"` + Devices []struct { + Class string `json:"class"` + ID int64 `json:"id"` + Name string `json:"name"` + } `json:"devices"` + Rules []struct { + MaxSize int64 `json:"max_size"` + MinSize int64 `json:"min_size"` + RuleID int64 `json:"rule_id"` + RuleName string `json:"rule_name"` + Ruleset int64 `json:"ruleset"` + Steps []struct { + Item int64 `json:"item"` + ItemName string `json:"item_name"` + Num int64 `json:"num"` + Op string `json:"op"` + Type string `json:"type"` + } `json:"steps"` + Type int64 `json:"type"` + } `json:"rules"` + Tunables struct { + AllowedBucketAlgs int64 `json:"allowed_bucket_algs"` + ChooseLocalFallbackTries int64 `json:"choose_local_fallback_tries"` + ChooseLocalTries int64 `json:"choose_local_tries"` + ChooseTotalTries int64 `json:"choose_total_tries"` + ChooseleafDescendOnce int64 `json:"chooseleaf_descend_once"` + ChooseleafStable int64 `json:"chooseleaf_stable"` + ChooseleafVaryR int64 `json:"chooseleaf_vary_r"` + HasV2Rules int64 `json:"has_v2_rules"` + HasV3Rules int64 `json:"has_v3_rules"` + HasV4Buckets int64 `json:"has_v4_buckets"` + HasV5Rules int64 `json:"has_v5_rules"` + LegacyTunables int64 `json:"legacy_tunables"` + MinimumRequiredVersion string `json:"minimum_required_version"` + OptimalTunables int64 `json:"optimal_tunables"` + Profile string `json:"profile"` + RequireFeatureTunables int64 `json:"require_feature_tunables"` + RequireFeatureTunables2 int64 `json:"require_feature_tunables2"` + RequireFeatureTunables3 int64 `json:"require_feature_tunables3"` + RequireFeatureTunables5 int64 `json:"require_feature_tunables5"` + StrawCalcVersion int64 `json:"straw_calc_version"` + } `json:"tunables"` + Types []struct { + Name string `json:"name"` + TypeID int64 `json:"type_id"` + } `json:"types"` +} + +type OsdDump struct { + Buckets []struct { + Alg string `json:"alg"` + Hash string `json:"hash"` + ID int64 `json:"id"` + Items []struct { + ID int64 `json:"id"` + Pos int64 `json:"pos"` + Weight int64 `json:"weight"` + } `json:"items"` + Name string `json:"name"` + TypeID int64 `json:"type_id"` + TypeName string `json:"type_name"` + Weight int64 `json:"weight"` + } `json:"buckets"` + ChooseArgs struct{} `json:"choose_args"` + Devices []struct { + Class string `json:"class"` + ID int64 `json:"id"` + Name string `json:"name"` + } `json:"devices"` + Rules []struct { + MaxSize int64 `json:"max_size"` + MinSize int64 `json:"min_size"` + RuleID int64 `json:"rule_id"` + RuleName string `json:"rule_name"` + Ruleset int64 `json:"ruleset"` + Steps []struct { + Item int64 `json:"item"` + ItemName string `json:"item_name"` + Num int64 `json:"num"` + Op string `json:"op"` + Type string `json:"type"` + } `json:"steps"` + Type int64 `json:"type"` + } `json:"rules"` + Tunables struct { + AllowedBucketAlgs int64 `json:"allowed_bucket_algs"` + ChooseLocalFallbackTries int64 `json:"choose_local_fallback_tries"` + ChooseLocalTries int64 `json:"choose_local_tries"` + ChooseTotalTries int64 `json:"choose_total_tries"` + ChooseleafDescendOnce int64 `json:"chooseleaf_descend_once"` + ChooseleafStable int64 `json:"chooseleaf_stable"` + ChooseleafVaryR int64 `json:"chooseleaf_vary_r"` + HasV2Rules int64 `json:"has_v2_rules"` + HasV3Rules int64 `json:"has_v3_rules"` + HasV4Buckets int64 `json:"has_v4_buckets"` + HasV5Rules int64 `json:"has_v5_rules"` + LegacyTunables int64 `json:"legacy_tunables"` + MinimumRequiredVersion string `json:"minimum_required_version"` + OptimalTunables int64 `json:"optimal_tunables"` + Profile string `json:"profile"` + RequireFeatureTunables int64 `json:"require_feature_tunables"` + RequireFeatureTunables2 int64 `json:"require_feature_tunables2"` + RequireFeatureTunables3 int64 `json:"require_feature_tunables3"` + RequireFeatureTunables5 int64 `json:"require_feature_tunables5"` + StrawCalcVersion int64 `json:"straw_calc_version"` + } `json:"tunables"` + Types []struct { + Name string `json:"name"` + TypeID int64 `json:"type_id"` + } `json:"types"` } type PlacementGroup struct { - Pgid string `json:"pgid"` - Version string `json:"version"` - Reported_seq string `json:"reported_seq"` - Reported_epoch string `json:"reported_epoch"` - State string `json:"state"` - Last_fresh_str string `json:"last_fresh"` - Last_fresh time.Time - Last_change_str string `json:"last_change"` - Last_change time.Time - Last_active_str string `json:"last_active"` - Last_active time.Time - Last_peered_str string `json:"last_peered"` - Last_peered time.Time - Last_clean_str string `json:"last_clean"` - Last_clean time.Time - Last_became_active_str string `json:"last_became_active"` - Last_became_active time.Time - Last_became_peered_str string `json:"last_became_peered"` - Last_became_peered time.Time - Last_unstale_str string `json:"last_unstale"` - Last_unstale time.Time - Last_undegraded_str string `json:"last_undegraded"` - Last_undegraded time.Time - Last_fullsized_str string `json:"last_fullsized"` - Last_fullsized time.Time - Mapping_epoch float64 `json:"mapping_epoch"` - Log_start string `json:"log_start"` - Ondisk_log_start string `json:"ondisk_log_start"` - Created float64 `json:"created"` - Last_epoch_clean float64 `json:"last_epoch_clean"` - Parent string `json:"parent"` - Parent_split_bits float64 `json:"parent_split_bits"` - Last_scrub_str string `json:"last_scrub"` - Last_scrub time.Time - Last_scrub_stamp_str string `json:"last_scrub_stamp"` - Last_scrub_stamp time.Time - Last_deep_scrub_str string `json:"last_deep_scrub"` - Last_deep_scrub time.Time - Last_deep_scrub_stamp_str string `json:"last_deep_scrub_stamp"` - Last_deep_scrub_stamp time.Time - Last_clean_scrub_stamp_str string `json:"last_clean_scrub_stamp"` - Last_clean_scrub_stamp time.Time - Log_size float64 `json:"log_size"` - Ondisk_log_size float64 `json:"ondisk_log_size"` - Stats_invalid bool `json:"stats_invalid"` - Dirty_stats_invalid bool `json:"dirty_stats_invalid"` - Omap_stats_invalid bool `json:"omap_stats_invalid"` - Hitset_stats_invalid bool `json:"hitset_stats_invalid"` - Hitset_bytes_stats_invalid bool `json:"hitset_bytes_stats_invalid"` - Pin_stats_invalid bool `json:"pin_stats_invalid"` - Manifest_stats_invalid bool `json:"manifest_stats_invalid"` - Snaptrimq_len float64 `json:"snaptrimq_len"` - Stat_sum StatSum `json:"stat_sum"` - Up []float64 `json:"up"` - Acting []float64 `json:"acting"` - Blocked_by []float64 `json:"blocked_by"` - Up_primary float64 `json:"up_primary"` - Acting_primary float64 `json:"acting_primary"` - Purged_snaps []string `json:"purged_snaps"` -} - -type StatSum struct { - Num_objects float64 `json:"num_objects"` - Num_object_clones float64 `json:"num_object_clones"` - Num_object_copies float64 `json:"num_object_copies"` - Num_objects_missing_on_primary float64 `json:"num_objects_missing_on_primary"` - Num_objects_missing float64 `json:"num_objects_missing"` - Num_objects_degraded float64 `json:"num_objects_degraded"` - Num_objects_misplaced float64 `json:"num_objects_misplaced"` - Num_objects_unfound float64 `json:"num_objects_unfound"` - Num_objects_dirty float64 `json:"num_objects_dirty"` - Num_whiteouts float64 `json:"num_whiteouts"` - Num_read float64 `json:"num_read"` - Num_read_kb float64 `json:"num_read_kb"` - Num_write float64 `json:"num_write"` - Num_write_kb float64 `json:"num_write_kb"` - Num_scrub_errors float64 `json:"num_scrub_errors"` - Num_shallow_scrub_errors float64 `json:"num_shallow_scrub_errors"` - Num_deep_scrub_errors float64 `json:"num_deep_scrub_errors"` - Num_objects_recovered float64 `json:"num_objects_recovered"` - Num_bytes_recovered float64 `json:"num_bytes_recovered"` - Num_keys_recovered float64 `json:"num_keys_recovered"` - Num_objects_omap float64 `json:"num_objects_omap"` - Num_objects_hit_set_archive float64 `json:"num_objects_hit_set_archive"` - Num_bytes_hit_set_archive float64 `json:"num_bytes_hit_set_archive"` - Num_flush float64 `json:"num_flush"` - Num_flush_kb float64 `json:"num_flush_kb"` - Num_evict float64 `json:"num_evict"` - Num_evict_kb float64 `json:"num_evict_kb"` - Num_promote float64 `json:"num_promote"` - Num_flush_mode_high float64 `json:"num_flush_mode_high"` - Num_flush_mode_low float64 `json:"num_flush_mode_low"` - Num_evict_mode_some float64 `json:"num_evict_mode_some"` - Num_evict_mode_full float64 `json:"num_evict_mode_full"` - Num_objects_pinned float64 `json:"num_objects_pinned"` - Num_legacy_snapsets float64 `json:"num_legacy_snapsets"` - Num_large_omap_objects float64 `json:"num_large_omap_objects"` - Num_objects_manifest float64 `json:"num_objects_manifest"` + Acting []int64 `json:"acting"` + ActingPrimary int64 `json:"acting_primary"` + BlockedBy []interface{} `json:"blocked_by"` + Created int64 `json:"created"` + DirtyStatsInvalid bool `json:"dirty_stats_invalid"` + HitsetBytesStatsInvalid bool `json:"hitset_bytes_stats_invalid"` + HitsetStatsInvalid bool `json:"hitset_stats_invalid"` + LastActive string `json:"last_active"` + LastActiveT time.Time + LastBecameActive string `json:"last_became_active"` + LastBecameActiveT time.Time + LastBecamePeered string `json:"last_became_peered"` + LastBecamePeeredT time.Time + LastChange string `json:"last_change"` + LastChangeT time.Time + LastClean string `json:"last_clean"` + LastCleanT time.Time + LastCleanScrubStamp string `json:"last_clean_scrub_stamp"` + LastCleanScrubStampT time.Time + LastDeepScrub string `json:"last_deep_scrub"` + LastDeepScrubT time.Time + LastDeepScrubStamp string `json:"last_deep_scrub_stamp"` + LastDeepScrubStampT time.Time + LastEpochClean int64 `json:"last_epoch_clean"` + LastFresh string `json:"last_fresh"` + LastFreshT time.Time + LastFullsized string `json:"last_fullsized"` + LastFullsizedT time.Time + LastPeered string `json:"last_peered"` + LastPeeredT time.Time + LastScrub string `json:"last_scrub"` + LastScrubT time.Time + LastScrubStamp string `json:"last_scrub_stamp"` + LastScrubStampT time.Time + LastUndegraded string `json:"last_undegraded"` + LastUndegradedT time.Time + LastUnstale string `json:"last_unstale"` + LastUnstaleT time.Time + LogSize int64 `json:"log_size"` + LogStart string `json:"log_start"` + ManifestStatsInvalid bool `json:"manifest_stats_invalid"` + MappingEpoch int64 `json:"mapping_epoch"` + OmapStatsInvalid bool `json:"omap_stats_invalid"` + OndiskLogSize int64 `json:"ondisk_log_size"` + OndiskLogStart string `json:"ondisk_log_start"` + Parent string `json:"parent"` + ParentSplitBits int64 `json:"parent_split_bits"` + Pgid string `json:"pgid"` + PinStatsInvalid bool `json:"pin_stats_invalid"` + PurgedSnaps []interface{} `json:"purged_snaps"` + ReportedEpoch string `json:"reported_epoch"` + ReportedSeq string `json:"reported_seq"` + SnaptrimqLen int64 `json:"snaptrimq_len"` + StatSum struct { + NumBytes int64 `json:"num_bytes"` + NumBytesHitSetArchive int64 `json:"num_bytes_hit_set_archive"` + NumBytesRecovered int64 `json:"num_bytes_recovered"` + NumDeepScrubErrors int64 `json:"num_deep_scrub_errors"` + NumEvict int64 `json:"num_evict"` + NumEvictKb int64 `json:"num_evict_kb"` + NumEvictModeFull int64 `json:"num_evict_mode_full"` + NumEvictModeSome int64 `json:"num_evict_mode_some"` + NumFlush int64 `json:"num_flush"` + NumFlushKb int64 `json:"num_flush_kb"` + NumFlushModeHigh int64 `json:"num_flush_mode_high"` + NumFlushModeLow int64 `json:"num_flush_mode_low"` + NumKeysRecovered int64 `json:"num_keys_recovered"` + NumLargeOmapObjects int64 `json:"num_large_omap_objects"` + NumLegacySnapsets int64 `json:"num_legacy_snapsets"` + NumObjectClones int64 `json:"num_object_clones"` + NumObjectCopies int64 `json:"num_object_copies"` + NumObjects int64 `json:"num_objects"` + NumObjectsDegraded int64 `json:"num_objects_degraded"` + NumObjectsDirty int64 `json:"num_objects_dirty"` + NumObjectsHitSetArchive int64 `json:"num_objects_hit_set_archive"` + NumObjectsManifest int64 `json:"num_objects_manifest"` + NumObjectsMisplaced int64 `json:"num_objects_misplaced"` + NumObjectsMissing int64 `json:"num_objects_missing"` + NumObjectsMissingOnPrimary int64 `json:"num_objects_missing_on_primary"` + NumObjectsOmap int64 `json:"num_objects_omap"` + NumObjectsPinned int64 `json:"num_objects_pinned"` + NumObjectsRecovered int64 `json:"num_objects_recovered"` + NumObjectsUnfound int64 `json:"num_objects_unfound"` + NumPromote int64 `json:"num_promote"` + NumRead int64 `json:"num_read"` + NumReadKb int64 `json:"num_read_kb"` + NumScrubErrors int64 `json:"num_scrub_errors"` + NumShallowScrubErrors int64 `json:"num_shallow_scrub_errors"` + NumWhiteouts int64 `json:"num_whiteouts"` + NumWrite int64 `json:"num_write"` + NumWriteKb int64 `json:"num_write_kb"` + } `json:"stat_sum"` + State string `json:"state"` + StatsInvalid bool `json:"stats_invalid"` + Up []int64 `json:"up"` + UpPrimary int64 `json:"up_primary"` + Version string `json:"version"` }