Skip to content

Commit 70bdebc

Browse files
committed
drivers: Add VirtioFS shares for vfkit and krunkit
Add --virtiofs-share flag for specifying one or more shared directories on the host to share with the guest using Virtiofs. Testing with krunkit shows that virtiofs mount is 10 times faster than 9p mount. Usage: --virtiofs-share SHARED_DIR:MOUNT_TAG[,SHARED_DIR:MOUNT_TAG...] Example: minikube start --virtiofs-share /Users/joe/models:models In krunkit and vfkit, every virtiofs shared directory will be added as: --device virtio-fs,sharedDir=/shared-dir,mountTag=mount-tag In the guest the shared directory will be mounted using: sudo mount -t virtiofs models /mnt/models This change only adds the options and configure vfkit and krunkit. The next step is connecting to the guest and mounting the shared directories. More work is needed to add VirtioFS to qemu. I'm starting with fkit and krunkit since they have identical interface (krunkit was designed as drop-in replacement for vfkit).
1 parent f0519e4 commit 70bdebc

File tree

7 files changed

+89
-0
lines changed

7 files changed

+89
-0
lines changed

cmd/minikube/cmd/start_flags.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const (
5656
humanReadableDiskSize = "disk-size"
5757
nfsSharesRoot = "nfs-shares-root"
5858
nfsShare = "nfs-share"
59+
virtiofsShare = "virtiofs-share"
5960
kubernetesVersion = "kubernetes-version"
6061
noKubernetes = "no-kubernetes"
6162
hostOnlyCIDR = "host-only-cidr"
@@ -283,6 +284,9 @@ func initDriverFlags() {
283284

284285
// qemu
285286
startCmd.Flags().String(qemuFirmwarePath, "", "Path to the qemu firmware file. Defaults: For Linux, the default firmware location. For macOS, the brew installation location. For Windows, C:\\Program Files\\qemu\\share")
287+
288+
// vfkit, krunkit
289+
startCmd.Flags().StringSlice(virtiofsShare, []string{}, "Local folders to share with guest via Virtiofs mounts (vfkit and krunkit drivers only)")
286290
}
287291

288292
// initNetworkingFlags inits the commandline flags for connectivity related flags for start
@@ -583,6 +587,7 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, rtime str
583587
HyperkitVSockPorts: viper.GetStringSlice(vsockPorts),
584588
NFSShare: viper.GetStringSlice(nfsShare),
585589
NFSSharesRoot: viper.GetString(nfsSharesRoot),
590+
VirtiofsShare: viper.GetStringSlice(virtiofsShare),
586591
DockerEnv: config.DockerEnv,
587592
DockerOpt: config.DockerOpt,
588593
InsecureRegistry: insecureRegistry,
@@ -832,6 +837,7 @@ func updateExistingConfigFromFlags(cmd *cobra.Command, existing *config.ClusterC
832837
updateStringSliceFromFlag(cmd, &cc.HyperkitVSockPorts, vsockPorts)
833838
updateStringSliceFromFlag(cmd, &cc.NFSShare, nfsShare)
834839
updateStringFromFlag(cmd, &cc.NFSSharesRoot, nfsSharesRoot)
840+
updateStringSliceFromFlag(cmd, &cc.VirtiofsShare, virtiofsShare)
835841
updateStringFromFlag(cmd, &cc.HostOnlyCIDR, hostOnlyCIDR)
836842
updateStringFromFlag(cmd, &cc.HypervVirtualSwitch, hypervVirtualSwitch)
837843
updateBoolFromFlag(cmd, &cc.HypervUseExternalSwitch, hypervUseExternalSwitch)

pkg/drivers/krunkit/krunkit.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ type Driver struct {
7171
CPU int
7272
Memory int
7373
ExtraDisks int
74+
VirtiofsShare []string
7475
MACAddress string
7576
VmnetHelper vmnet.Helper
7677
}
@@ -231,6 +232,15 @@ func (d *Driver) startKrunkit(socketPath string) error {
231232
"--device", fmt.Sprintf("virtio-blk,path=%s", pkgdrivers.ExtraDiskPath(d.BaseDriver, i)))
232233
}
233234

235+
for _, s := range d.VirtiofsShare {
236+
vs, err := pkgdrivers.ParseVirtiofsShare(s)
237+
if err != nil {
238+
return err
239+
}
240+
args = append(args,
241+
"--device", fmt.Sprintf("virtio-fs,sharedDir=%s,mountTag=%s", vs.SharedDir, vs.MountTag))
242+
}
243+
234244
log.Debugf("executing: krunkit %s", strings.Join(args, " "))
235245
cmd := exec.Command(driverName, args...)
236246

pkg/drivers/vfkit/vfkit.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ type Driver struct {
7272
CPU int
7373
Memory int
7474
ExtraDisks int
75+
VirtiofsShare []string
7576
Network string // "", "nat", "vmnet-shared"
7677
MACAddress string // For network=nat, network=""
7778
VmnetHelper *vmnet.Helper // For network=vmnet-shared
@@ -312,6 +313,15 @@ func (d *Driver) startVfkit(socketPath string) error {
312313
startCmd = append(startCmd,
313314
"--device", fmt.Sprintf("virtio-serial,logFilePath=%s", serialPath))
314315

316+
for _, s := range d.VirtiofsShare {
317+
vs, err := pkgdrivers.ParseVirtiofsShare(s)
318+
if err != nil {
319+
return err
320+
}
321+
startCmd = append(startCmd,
322+
"--device", fmt.Sprintf("virtio-fs,sharedDir=%s,mountTag=%s", vs.SharedDir, vs.MountTag))
323+
}
324+
315325
log.Debugf("executing: vfkit %s", strings.Join(startCmd, " "))
316326
os.Remove(d.sockfilePath())
317327
cmd := exec.Command("vfkit", startCmd...)

pkg/drivers/virtiofs.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package drivers
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"path/filepath"
23+
"strings"
24+
)
25+
26+
// VirtiofsShare is a directory on the host shared with the guest using
27+
// virtiofs.
28+
type VirtiofsShare struct {
29+
SharedDir string
30+
MountTag string
31+
}
32+
33+
// ParseVirtiofsShare parses --virtiofs-share argument and returns a validated VirtiofsShare.
34+
// - SharedDir is an absolute path to existing directory to share with the guest.
35+
// - MountTag is a non-empty string without leading or trailing whitespace.
36+
func ParseVirtiofsShare(s string) (*VirtiofsShare, error) {
37+
pair := strings.SplitN(s, ":", 2)
38+
if len(pair) != 2 {
39+
return nil, fmt.Errorf("invalid virtiofsShare string %q: (expected '/shared-dir:mount-tag')", s)
40+
}
41+
42+
sharedDir := pair[0]
43+
mountTag := pair[1]
44+
45+
if !filepath.IsAbs(sharedDir) {
46+
return nil, fmt.Errorf("shared directory %q is not absolute path", sharedDir)
47+
}
48+
49+
if fs, err := os.Stat(sharedDir); err != nil {
50+
return nil, fmt.Errorf("failed to validate shared directory %q: %w", sharedDir, err)
51+
} else if !fs.IsDir() {
52+
return nil, fmt.Errorf("shared directory %q is not a directory", sharedDir)
53+
}
54+
55+
if mountTag == "" || mountTag != strings.TrimSpace(mountTag) {
56+
return nil, fmt.Errorf("invalid mount tag: %q", mountTag)
57+
}
58+
59+
return &VirtiofsShare{SharedDir: sharedDir, MountTag: mountTag}, nil
60+
}

pkg/minikube/config/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type ClusterConfig struct {
6363
DisableDriverMounts bool // Only used by virtualbox
6464
NFSShare []string
6565
NFSSharesRoot string
66+
VirtiofsShare []string
6667
UUID string // Only used by hyperkit to restore the mac address
6768
NoVTXCheck bool // Only used by virtualbox
6869
DNSProxy bool // Only used by virtualbox

pkg/minikube/registry/drvs/krunkit/krunkit.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func configure(cfg config.ClusterConfig, n config.Node) (interface{}, error) {
7676
Memory: cfg.Memory,
7777
CPU: cfg.CPUs,
7878
ExtraDisks: cfg.ExtraDisks,
79+
VirtiofsShare: cfg.VirtiofsShare,
7980
VmnetHelper: vmnet.Helper{
8081
MachineDir: filepath.Join(storePath, "machines", machineName),
8182
InterfaceID: u,

pkg/minikube/registry/drvs/vfkit/vfkit.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ func configure(cfg config.ClusterConfig, n config.Node) (interface{}, error) {
9999
Memory: cfg.Memory,
100100
CPU: cfg.CPUs,
101101
ExtraDisks: cfg.ExtraDisks,
102+
VirtiofsShare: cfg.VirtiofsShare,
102103
Network: cfg.Network,
103104
MACAddress: mac,
104105
VmnetHelper: helper,

0 commit comments

Comments
 (0)