1. package manager

  1. import (
  1.     "net/http"
  1.     "github.com/030io/whalefs/manager/volume"
  1.     "os"
  1.     "io/ioutil"
  1.     "strings"
  1.     "strconv"
  1.     "fmt"
  1.     "time"
  1.     "github.com/030io/whalefs/master/api"
  1.     "github.com/030io/whalefs/master"
  1.     "github.com/030io/whalefs/utils/disk"
  1. )

  1. var (
  1.     MaxDiskUsedPercent uint = 99
  1.     HeartbeatDuration time.Duration = time.Second * 5
  1.     ReadOnly bool = false
  1.     DefaultExpires = time.Minute * 30
  1. )

  1. type VolumeManager struct {
  1.     DataDir string
  1.     Volumes map[uint64]*volume.Volume
  1.     AdminPort int
  1.     AdminHost string
  1.     PublicPort int
  1.     PublicHost string
  1.     AdminServer *http.ServeMux
  1.     PublicServer *http.ServeMux
  1.     Machine string
  1.     DataCenter string
  1.     MasterHost string
  1.     MasterPort int
  1. }

  1. func NewVolumeManager(dir string) (*VolumeManager, error) {
  1.     f, err := os.OpenFile(dir, os.O_RDWR, 0)
  1.     if os.IsNotExist(err) {
  1.         panic(err)
  1.     } else if os.IsPermission(err) {
  1.         ReadOnly = true
  1.     }
  1.     f.Close()
  1.     vm := new(VolumeManager)
  1.     vm.DataDir = dir
  1.     fileInfos, err := ioutil.ReadDir(dir)
  1.     if err != nil {
  1.         panic(err)
  1.     }
  1.     vm.Volumes = make(map[uint64]*volume.Volume)
  1.     for _, fi := range fileInfos {
  1.         fileName := fi.Name()
  1.         if strings.HasSuffix(fileName, ".data") {
  1.             vid, err := strconv.ParseUint(fileName[:len(fileName) - 5], 10, 64)
  1.             if err != nil {
  1.                 panic(err)
  1.             }
  1.             vm.Volumes[vid], err = volume.NewVolume(dir, vid)
  1.             if err != nil {
  1.                 panic(err)
  1.             }
  1.         }
  1.     }
  1.     vm.AdminPort = 7800
  1.     vm.AdminHost = "localhost"
  1.     vm.PublicPort = 7900
  1.     vm.PublicHost = "localhost"
  1.     vm.AdminServer = http.NewServeMux()
  1.     vm.PublicServer = http.NewServeMux()
  1.     vm.PublicServer.HandleFunc("/", vm.publicEntry)
  1.     vm.AdminServer.HandleFunc("/", vm.adminEntry)
  1.     vm.MasterHost = "localhost"
  1.     vm.MasterPort = 8888
  1.     return vm, nil
  1. }

  1. func (vm *VolumeManager)Start() {
  1.     go vm.Heartbeat()

  1.     go func() {
  1.         err := http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", vm.AdminPort), vm.AdminServer)
  1.         if err != nil {
  1.             panic(err)
  1.         }
  1.     }()

  1.     err := http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", vm.PublicPort), vm.PublicServer)
  1.     if err != nil {
  1.         panic(err)
  1.     }
  1. }

  1. func (vm *VolumeManager)Stop() {
  1.     for _, v := range vm.Volumes {
  1.         v.Close()
  1.     }
  1. }

  1. func (vm *VolumeManager)Heartbeat() {
  1.     tick := time.NewTicker(HeartbeatDuration)
  1.     defer tick.Stop()
  1.     for {
  1.         vms := new(master.VolumeManagerStatus)
  1.         vms.AdminHost = vm.AdminHost
  1.         vms.AdminPort = vm.AdminPort
  1.         vms.PublicHost = vm.PublicHost
  1.         vms.PublicPort = vm.PublicPort
  1.         vms.Machine = vm.Machine
  1.         vms.DataCenter = vm.Machine
  1.         vms.VStatusList = make([]*master.VolumeStatus, 0, len(vm.Volumes))

  1.         diskUsage, _ := disk.DiskUsage(vm.DataDir)
  1.         vms.DiskSize = diskUsage.Size
  1.         vms.DiskUsed = diskUsage.Used
  1.         vms.DiskFree = diskUsage.Free
  1.         vms.MaxDiskUsed = diskUsage.Size / 100 * uint64(MaxDiskUsedPercent)
  1.         vms.VolumeMaxSize = volume.MaxVolumeSize

  1.         diskUsedPercent := uint(float64(diskUsage.Used) / float64(diskUsage.Size) * 100)
  1.         if ReadOnly || diskUsedPercent >= MaxDiskUsedPercent {
  1.             //禁止所有volume再进行truncate
  1.             volume.MaxVolumeSize = 0
  1.             vms.CanCreateVolume = false
  1.         } else {
  1.             vms.CanCreateVolume = true
  1.         }

  1.         for vid, v := range vm.Volumes {
  1.             vs := new(master.VolumeStatus)
  1.             vs.Id = vid
  1.             vs.DataFileSize = v.GetDatafileSize()
  1.             vs.Writable = !ReadOnly && v.WriteAble
  1.             vs.MaxFreeSpace = v.GetMaxFreeSpace()
  1.             vms.VStatusList = append(vms.VStatusList, vs)
  1.         }

  1.         api.Heartbeat(vm.MasterHost, vm.MasterPort, vms)
  1.         <-tick.C
  1.     }
  1. }

volume_manager.go的更多相关文章

  1. Kubeadm安装Kubernetes环境

    Kubeadm方式号称一键安装部署,很多人也试过并且顺利成功,可到了我这里因为折腾系统问题,倒腾出不少的坑出来. kubeadm好处是自动配置了必要的服务,以及缺省配置了安全的认证,etcd,apis ...

  2. 基于openstack stable queens版本阅读解析

    基于openstack stable queens版本阅读解析 基于 centos7.5 的linux系统 架构 如下所示,为cinder的官方架构说明: 这里写图片描述 各个组件介绍如下: - DB ...

  3. cinder-volume服务上报自己的状态给cinder-scheduler的rpc通信代码分析

    以juno版本为基础,主要从消息的生产者-消费者模型及rpc client/server模型来分析cinder-volume是如何跟cinder-scheduler服务进行rpc通信的 1.cinde ...

  4. kubelet之volume manager源码分析

    kubernetes ceph-csi分析目录导航 基于tag v1.17.4 https://github.com/kubernetes/kubernetes/releases/tag/v1.17. ...

随机推荐

  1. Java内部类与外部类

    错误提示: 没有任何类型 TestThread 的外层实例可访问.必须用类型 TestThread 的外层实例(例如,x.new A(),其中 x 是 TestThread 的实例)来限定分配. pu ...

  2. javascript原始值和对象引用

    一句话来说:原始值是不可变的,而对象引用是可变的. js中的原始值(undefined.null.布尔值.数字和字符串)与对象(包括数组和函数)有着本质的区别.原始值是不可更改的,任何方法都无法更改一 ...

  3. ruby中printf "%x"%-4为何会打印开头..

    先看一下ruby中printf "%x" % -4的返回结果: irb(main):134:0> printf "%x\n" % -4 ..fc 前面的. ...

  4. ASP.NET Core 2.0 : 九.从Windows发布到CentOS的跨平台部署

    本文聊一下如何在Windows上用VS开发并发布, 然后将其部署到CentOS上.对于我们一些常在Windows上逛的来说,CentOS用起来还真有些麻烦.MSDN官方有篇文章大概讲了一下(链接),按 ...

  5. JavaScript中对象数组 作业 题目如下

    var BaiduUsers = [], WechatUsers = []; var User = function(id, name, phone, gender, age, salary) { t ...

  6. Application "org.eclipse.ui.ide.workbench" could not be found in the registry.问题的解决

    今天升级Eclipse,升级完Restart,碰到启动不了让看日志,日志里主要错误信息即是Application "org.eclipse.ui.ide.workbench" co ...

  7. sqlite db数据的导出

    sqlite的db数据一般是filename.db的格式,用普通文本编辑器打开是乱码,用sqlite名令操作比较麻烦,有时版本格式问题还会起阻扰,有一个GUI工具可以对sqlite db格式数据进行管 ...

  8. POSTGRESQL 并发控制

    http://meidayhxp.blog.163.com/blog/static/117608156201210243837491/ 这个内容是官方Doc中的一章,具体是那一版的,还未确认. 第九章 ...

  9. Page.ClientScript.RegisterStartupScript用法小结

    使用类型.键.脚本文本和指示是否添加脚本标记的布尔值向 Page 对象注册启动脚本. 参数 type 要注册的启动脚本的类型. key 要注册的启动脚本的键. script 要注册的启动脚本文本. a ...

  10. invalid bound statement (not found)

    invalid bound statement (not found) mybatis 错误: 一般是Mapepr.xml文件中文nameapce没有和mapper接口发生映射,导致mybatis绑定 ...