github.com/kaisenlinux/docker@v0.0.0-20230510090727-ea55db55fac7/engine/contrib/docker-device-tool/device_tool.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package main
     5  
     6  import (
     7  	"flag"
     8  	"fmt"
     9  	"os"
    10  	"path"
    11  	"sort"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"github.com/docker/docker/daemon/graphdriver/devmapper"
    16  	"github.com/docker/docker/pkg/devicemapper"
    17  	"github.com/sirupsen/logrus"
    18  )
    19  
    20  func usage() {
    21  	fmt.Fprintf(os.Stderr, "Usage: %s <flags>  [status] | [list] | [device id]  | [resize new-pool-size] | [snap new-id base-id] | [remove id] | [mount id mountpoint]\n", os.Args[0])
    22  	flag.PrintDefaults()
    23  	os.Exit(1)
    24  }
    25  
    26  func byteSizeFromString(arg string) (int64, error) {
    27  	digits := ""
    28  	rest := ""
    29  	last := strings.LastIndexAny(arg, "0123456789")
    30  	if last >= 0 {
    31  		digits = arg[:last+1]
    32  		rest = arg[last+1:]
    33  	}
    34  
    35  	val, err := strconv.ParseInt(digits, 10, 64)
    36  	if err != nil {
    37  		return val, err
    38  	}
    39  
    40  	rest = strings.ToLower(strings.TrimSpace(rest))
    41  
    42  	var multiplier int64
    43  	switch rest {
    44  	case "":
    45  		multiplier = 1
    46  	case "k", "kb":
    47  		multiplier = 1024
    48  	case "m", "mb":
    49  		multiplier = 1024 * 1024
    50  	case "g", "gb":
    51  		multiplier = 1024 * 1024 * 1024
    52  	case "t", "tb":
    53  		multiplier = 1024 * 1024 * 1024 * 1024
    54  	default:
    55  		return 0, fmt.Errorf("Unknown size unit: %s", rest)
    56  	}
    57  
    58  	return val * multiplier, nil
    59  }
    60  
    61  func main() {
    62  	root := flag.String("r", "/var/lib/docker", "Docker root dir")
    63  	flDebug := flag.Bool("D", false, "Debug mode")
    64  
    65  	flag.Parse()
    66  
    67  	if *flDebug {
    68  		os.Setenv("DEBUG", "1")
    69  		logrus.SetLevel(logrus.DebugLevel)
    70  	}
    71  
    72  	if flag.NArg() < 1 {
    73  		usage()
    74  	}
    75  
    76  	args := flag.Args()
    77  
    78  	home := path.Join(*root, "devicemapper")
    79  	devices, err := devmapper.NewDeviceSet(home, false, nil, nil, nil)
    80  	if err != nil {
    81  		fmt.Println("Can't initialize device mapper: ", err)
    82  		os.Exit(1)
    83  	}
    84  
    85  	switch args[0] {
    86  	case "status":
    87  		status := devices.Status()
    88  		fmt.Printf("Pool name: %s\n", status.PoolName)
    89  		fmt.Printf("Data Loopback file: %s\n", status.DataLoopback)
    90  		fmt.Printf("Metadata Loopback file: %s\n", status.MetadataLoopback)
    91  		fmt.Printf("Sector size: %d\n", status.SectorSize)
    92  		fmt.Printf("Data use: %d of %d (%.1f %%)\n", status.Data.Used, status.Data.Total, 100.0*float64(status.Data.Used)/float64(status.Data.Total))
    93  		fmt.Printf("Metadata use: %d of %d (%.1f %%)\n", status.Metadata.Used, status.Metadata.Total, 100.0*float64(status.Metadata.Used)/float64(status.Metadata.Total))
    94  	case "list":
    95  		ids := devices.List()
    96  		sort.Strings(ids)
    97  		for _, id := range ids {
    98  			fmt.Println(id)
    99  		}
   100  	case "device":
   101  		if flag.NArg() < 2 {
   102  			usage()
   103  		}
   104  		status, err := devices.GetDeviceStatus(args[1])
   105  		if err != nil {
   106  			fmt.Println("Can't get device info: ", err)
   107  			os.Exit(1)
   108  		}
   109  		fmt.Printf("Id: %d\n", status.DeviceID)
   110  		fmt.Printf("Size: %d\n", status.Size)
   111  		fmt.Printf("Transaction Id: %d\n", status.TransactionID)
   112  		fmt.Printf("Size in Sectors: %d\n", status.SizeInSectors)
   113  		fmt.Printf("Mapped Sectors: %d\n", status.MappedSectors)
   114  		fmt.Printf("Highest Mapped Sector: %d\n", status.HighestMappedSector)
   115  	case "resize":
   116  		if flag.NArg() < 2 {
   117  			usage()
   118  		}
   119  
   120  		size, err := byteSizeFromString(args[1])
   121  		if err != nil {
   122  			fmt.Println("Invalid size: ", err)
   123  			os.Exit(1)
   124  		}
   125  
   126  		err = devices.ResizePool(size)
   127  		if err != nil {
   128  			fmt.Println("Error resizing pool: ", err)
   129  			os.Exit(1)
   130  		}
   131  
   132  	case "snap":
   133  		if flag.NArg() < 3 {
   134  			usage()
   135  		}
   136  
   137  		err := devices.AddDevice(args[1], args[2], nil)
   138  		if err != nil {
   139  			fmt.Println("Can't create snap device: ", err)
   140  			os.Exit(1)
   141  		}
   142  	case "remove":
   143  		if flag.NArg() < 2 {
   144  			usage()
   145  		}
   146  
   147  		err := devicemapper.RemoveDevice(args[1])
   148  		if err != nil {
   149  			fmt.Println("Can't remove device: ", err)
   150  			os.Exit(1)
   151  		}
   152  	case "mount":
   153  		if flag.NArg() < 3 {
   154  			usage()
   155  		}
   156  
   157  		err := devices.MountDevice(args[1], args[2], "")
   158  		if err != nil {
   159  			fmt.Println("Can't mount device: ", err)
   160  			os.Exit(1)
   161  		}
   162  	default:
   163  		fmt.Printf("Unknown command %s\n", args[0])
   164  		usage()
   165  
   166  		os.Exit(1)
   167  	}
   168  }