2019-03-20 19:14:20 +00:00
/ *
Copyright 2019 The Ceph - CSI Authors .
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 (
"flag"
2019-11-06 04:52:07 +00:00
"fmt"
2019-03-20 19:14:20 +00:00
"os"
2019-11-06 04:52:07 +00:00
"runtime"
2019-06-20 19:30:40 +00:00
"time"
2019-03-20 19:14:20 +00:00
2020-04-17 09:23:49 +00:00
"github.com/ceph/ceph-csi/internal/cephfs"
"github.com/ceph/ceph-csi/internal/liveness"
"github.com/ceph/ceph-csi/internal/rbd"
"github.com/ceph/ceph-csi/internal/util"
2020-04-15 03:38:16 +00:00
2020-07-09 05:14:10 +00:00
klog "k8s.io/klog/v2"
2019-03-20 19:14:20 +00:00
)
const (
2019-06-20 19:30:40 +00:00
rbdType = "rbd"
cephfsType = "cephfs"
livenessType = "liveness"
2019-03-20 19:14:20 +00:00
2019-06-20 19:30:40 +00:00
rbdDefaultName = "rbd.csi.ceph.com"
cephfsDefaultName = "cephfs.csi.ceph.com"
livenessDefaultName = "liveness.csi.ceph.com"
2020-07-21 05:10:13 +00:00
pollTime = 60 // seconds
probeTimeout = 3 // seconds
2019-03-20 19:14:20 +00:00
)
var (
2019-08-14 05:57:45 +00:00
conf util . Config
)
func init ( ) {
2019-03-20 19:14:20 +00:00
// common flags
2019-08-14 05:57:45 +00:00
flag . StringVar ( & conf . Vtype , "type" , "" , "driver type [rbd|cephfs|liveness]" )
flag . StringVar ( & conf . Endpoint , "endpoint" , "unix://tmp/csi.sock" , "CSI endpoint" )
flag . StringVar ( & conf . DriverName , "drivername" , "" , "name of the driver" )
flag . StringVar ( & conf . NodeID , "nodeid" , "" , "node id" )
flag . StringVar ( & conf . InstanceID , "instanceid" , "" , "Unique ID distinguishing this instance of Ceph CSI among other" +
2019-05-28 19:03:18 +00:00
" instances, when sharing Ceph clusters across CSI instances for provisioning" )
2019-08-14 05:57:45 +00:00
flag . IntVar ( & conf . PidLimit , "pidlimit" , 0 , "the PID limit to configure through cgroups" )
2019-08-14 06:42:17 +00:00
flag . BoolVar ( & conf . IsControllerServer , "controllerserver" , false , "start cephcsi controller server" )
flag . BoolVar ( & conf . IsNodeServer , "nodeserver" , false , "start cephcsi node server" )
2020-01-24 16:26:56 +00:00
flag . StringVar ( & conf . DomainLabels , "domainlabels" , "" , "list of kubernetes node labels, that determines the topology" +
" domain the node belongs to, separated by ','" )
2019-03-20 19:14:20 +00:00
// cephfs related flags
2019-10-10 10:15:44 +00:00
flag . BoolVar ( & conf . ForceKernelCephFS , "forcecephkernelclient" , false , "enable Ceph Kernel clients on kernel < 4.17 which support quotas" )
2019-06-20 19:30:40 +00:00
2019-08-21 09:28:02 +00:00
// liveness/grpc metrics related flags
flag . IntVar ( & conf . MetricsPort , "metricsport" , 8080 , "TCP port for liveness/grpc metrics requests" )
flag . StringVar ( & conf . MetricsPath , "metricspath" , "/metrics" , "path of prometheus endpoint where metrics will be available" )
2020-07-21 05:10:13 +00:00
flag . DurationVar ( & conf . PollTime , "polltime" , time . Second * pollTime , "time interval in seconds between each poll" )
flag . DurationVar ( & conf . PoolTimeout , "timeout" , time . Second * probeTimeout , "probe timeout in seconds" )
2019-08-21 09:28:02 +00:00
2020-03-31 05:59:29 +00:00
flag . BoolVar ( & conf . EnableGRPCMetrics , "enablegrpcmetrics" , false , "[DEPRECATED] enable grpc metrics" )
2019-08-21 09:28:02 +00:00
flag . StringVar ( & conf . HistogramOption , "histogramoption" , "0.5,2,6" ,
2020-03-31 05:59:29 +00:00
"[DEPRECATED] Histogram option for grpc metrics, should be comma separated value, ex:= 0.5,2,6 where start=0.5 factor=2, count=6" )
2019-08-21 09:28:02 +00:00
2020-06-24 06:44:02 +00:00
flag . UintVar ( & conf . RbdHardMaxCloneDepth , "rbdhardmaxclonedepth" , 8 , "Hard limit for maximum number of nested volume clones that are taken before a flatten occurs" )
flag . UintVar ( & conf . RbdSoftMaxCloneDepth , "rbdsoftmaxclonedepth" , 4 , "Soft limit for maximum number of nested volume clones that are taken before a flatten occurs" )
2020-07-01 05:27:11 +00:00
flag . UintVar ( & conf . MaxSnapshotsOnImage , "maxsnapshotsonimage" , 450 , "Maximum number of snapshots allowed on rbd image without flattening" )
2020-06-24 08:12:12 +00:00
flag . BoolVar ( & conf . SkipForceFlatten , "skipforceflatten" , false ,
"skip image flattening if kernel support mapping of rbd images which has the deep-flatten feature" )
2019-11-06 04:52:07 +00:00
flag . BoolVar ( & conf . Version , "version" , false , "Print cephcsi version information" )
2019-03-20 19:14:20 +00:00
klog . InitFlags ( nil )
if err := flag . Set ( "logtostderr" , "true" ) ; err != nil {
klog . Exitf ( "failed to set logtostderr flag: %v" , err )
}
flag . Parse ( )
}
func getDriverName ( ) string {
// was explicitly passed a driver name
2019-08-14 05:57:45 +00:00
if conf . DriverName != "" {
return conf . DriverName
2019-03-20 19:14:20 +00:00
}
// select driver name based on volume type
2019-08-14 05:57:45 +00:00
switch conf . Vtype {
2019-03-20 19:14:20 +00:00
case rbdType :
return rbdDefaultName
case cephfsType :
return cephfsDefaultName
2019-06-20 19:30:40 +00:00
case livenessType :
return livenessDefaultName
2019-03-20 19:14:20 +00:00
default :
return ""
}
}
func main ( ) {
2019-11-06 04:52:07 +00:00
if conf . Version {
fmt . Println ( "Cephcsi Version:" , util . DriverVersion )
fmt . Println ( "Git Commit:" , util . GitCommit )
fmt . Println ( "Go Version:" , runtime . Version ( ) )
fmt . Println ( "Compiler:" , runtime . Compiler )
fmt . Printf ( "Platform: %s/%s\n" , runtime . GOOS , runtime . GOARCH )
2020-06-22 06:58:47 +00:00
if kv , err := util . GetKernelVersion ( ) ; err == nil {
2020-06-17 18:31:10 +00:00
fmt . Println ( "Kernel:" , kv )
}
2019-11-06 04:52:07 +00:00
os . Exit ( 0 )
}
2020-07-09 14:48:24 +00:00
util . DefaultLog ( "Driver version: %s and Git version: %s" , util . DriverVersion , util . GitCommit )
2019-05-28 19:03:18 +00:00
2019-08-14 05:57:45 +00:00
if conf . Vtype == "" {
cleanup: prevent Go panic on missing driver type
When running the 'cephcsi' executable without arguments, a Go panic is
reported:
$ ./_output/cephcsi
F1026 13:59:04.302740 3409054 cephcsi.go:126] driver type not specified
goroutine 1 [running]:
k8s.io/klog/v2.stacks(0xc000010001, 0xc0000520a0, 0x48, 0x9a)
/go/src/github.com/ceph/ceph-csi/vendor/k8s.io/klog/v2/klog.go:996 +0xb9
k8s.io/klog/v2.(*loggingT).output(0x2370360, 0xc000000003, 0x0, 0x0, 0xc000194770, 0x20cb265, 0xa, 0x7e, 0x413500)
/go/src/github.com/ceph/ceph-csi/vendor/k8s.io/klog/v2/klog.go:945 +0x191
k8s.io/klog/v2.(*loggingT).println(0x2370360, 0x3, 0x0, 0x0, 0xc000163e08, 0x1, 0x1)
/go/src/github.com/ceph/ceph-csi/vendor/k8s.io/klog/v2/klog.go:699 +0x11a
k8s.io/klog/v2.Fatalln(...)
/go/src/github.com/ceph/ceph-csi/vendor/k8s.io/klog/v2/klog.go:1456
main.main()
/go/src/github.com/ceph/ceph-csi/cmd/cephcsi.go:126 +0xafa
Just logging the error and exiting should be sufficient. This stack-trace
from the Go panic does not add any useful information.
Signed-off-by: Niels de Vos <ndevos@redhat.com>
2020-10-26 13:08:55 +00:00
logAndExit ( "driver type not specified" )
2019-03-20 19:14:20 +00:00
}
dname := getDriverName ( )
err := util . ValidateDriverName ( dname )
if err != nil {
2020-10-26 13:18:48 +00:00
logAndExit ( err . Error ( ) )
2019-03-20 19:14:20 +00:00
}
2019-07-04 09:49:57 +00:00
2019-07-26 12:36:43 +00:00
// the driver may need a higher PID limit for handling all concurrent requests
2019-08-14 05:57:45 +00:00
if conf . PidLimit != 0 {
2019-08-21 09:28:02 +00:00
currentLimit , pidErr := util . GetPIDLimit ( )
if pidErr != nil {
klog . Errorf ( "Failed to get the PID limit, can not reconfigure: %v" , pidErr )
2019-07-26 12:36:43 +00:00
} else {
2020-07-09 14:48:24 +00:00
util . DefaultLog ( "Initial PID limit is set to %d" , currentLimit )
2019-08-14 05:57:45 +00:00
err = util . SetPIDLimit ( conf . PidLimit )
2019-07-26 12:36:43 +00:00
if err != nil {
2019-08-14 05:57:45 +00:00
klog . Errorf ( "Failed to set new PID limit to %d: %v" , conf . PidLimit , err )
2019-07-26 12:36:43 +00:00
} else {
s := ""
2019-08-14 05:57:45 +00:00
if conf . PidLimit == - 1 {
2019-07-26 12:36:43 +00:00
s = " (max)"
}
2020-07-09 14:48:24 +00:00
util . DefaultLog ( "Reconfigured PID limit to %d%s" , conf . PidLimit , s )
2019-07-26 12:36:43 +00:00
}
}
}
2019-08-21 09:28:02 +00:00
if conf . EnableGRPCMetrics || conf . Vtype == livenessType {
// validate metrics endpoint
conf . MetricsIP = os . Getenv ( "POD_IP" )
if conf . MetricsIP == "" {
klog . Warning ( "missing POD_IP env var defaulting to 0.0.0.0" )
conf . MetricsIP = "0.0.0.0"
}
err = util . ValidateURL ( & conf )
if err != nil {
klog . Fatalln ( err )
}
}
2020-07-09 14:48:24 +00:00
util . DefaultLog ( "Starting driver type: %v with name: %v" , conf . Vtype , dname )
2019-08-14 05:57:45 +00:00
switch conf . Vtype {
2019-03-20 19:14:20 +00:00
case rbdType :
2020-06-24 06:44:02 +00:00
validateCloneDepthFlag ( & conf )
2020-07-01 05:27:11 +00:00
validateMaxSnaphostFlag ( & conf )
2019-03-20 19:14:20 +00:00
driver := rbd . NewDriver ( )
2020-07-10 10:44:59 +00:00
driver . Run ( & conf )
2019-03-20 19:14:20 +00:00
case cephfsType :
driver := cephfs . NewDriver ( )
2020-07-10 10:44:59 +00:00
driver . Run ( & conf )
2019-03-20 19:14:20 +00:00
2019-06-20 19:30:40 +00:00
case livenessType :
2019-08-14 05:57:45 +00:00
liveness . Run ( & conf )
2019-06-20 19:30:40 +00:00
2019-03-20 19:14:20 +00:00
default :
2019-08-14 05:57:45 +00:00
klog . Fatalln ( "invalid volume type" , conf . Vtype ) // calls exit
2019-03-20 19:14:20 +00:00
}
os . Exit ( 0 )
}
2020-06-24 06:44:02 +00:00
func validateCloneDepthFlag ( conf * util . Config ) {
// keeping hardlimit to 14 as max to avoid max image depth
if conf . RbdHardMaxCloneDepth == 0 || conf . RbdHardMaxCloneDepth > 14 {
klog . Fatalln ( "rbdhardmaxclonedepth flag value should be between 1 and 14" )
}
if conf . RbdSoftMaxCloneDepth > conf . RbdHardMaxCloneDepth {
klog . Fatalln ( "rbdsoftmaxclonedepth flag value should not be greater than rbdhardmaxclonedepth" )
}
}
2020-07-01 05:27:11 +00:00
func validateMaxSnaphostFlag ( conf * util . Config ) {
// maximum number of snapshots on an image are 510 [1] and 16 images in
// a parent/child chain [2],keeping snapshot limit to 500 to avoid issues.
// [1] https://github.com/torvalds/linux/blob/master/drivers/block/rbd.c#L98
// [2] https://github.com/torvalds/linux/blob/master/drivers/block/rbd.c#L92
if conf . MaxSnapshotsOnImage == 0 || conf . MaxSnapshotsOnImage > 500 {
klog . Fatalln ( "maxsnapshotsonimage flag value should be between 1 and 500" )
}
}
2020-10-27 07:13:30 +00:00
func logAndExit ( msg string ) {
klog . Errorln ( msg )
os . Exit ( 1 )
}