2 #include <kvm/kvm-cmd.h>
3 #include <kvm/builtin-setup.h>
5 #include <kvm/parse-options.h>
15 #include <sys/types.h>
22 #define KVM_PID_FILE_PATH "/.kvm-tools/"
23 #define HOME_DIR getenv("HOME")
25 static const char *instance_name
;
27 static const char * const setup_usage
[] = {
28 "kvm setup [-n name]",
32 static const struct option setup_options
[] = {
33 OPT_GROUP("General options:"),
34 OPT_STRING('n', "name", &instance_name
, "name", "Instance name"),
38 static void parse_setup_options(int argc
, const char **argv
)
41 argc
= parse_options(argc
, argv
, setup_options
, setup_usage
,
42 PARSE_OPT_STOP_AT_NON_OPTION
);
48 void kvm_setup_help(void)
50 usage_with_options(setup_usage
, setup_options
);
53 static int copy_file(const char *from
, const char *to
)
60 in_fd
= open(from
, O_RDONLY
);
64 if (fstat(in_fd
, &st
) < 0)
67 out_fd
= open(to
, O_RDWR
| O_CREAT
| O_TRUNC
, st
.st_mode
& (S_IRWXU
|S_IRWXG
|S_IRWXO
));
71 src
= mmap(NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, in_fd
, 0);
72 if (src
== MAP_FAILED
)
75 if (ftruncate(out_fd
, st
.st_size
) < 0)
76 goto error_munmap_src
;
78 dst
= mmap(NULL
, st
.st_size
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, out_fd
, 0);
79 if (dst
== MAP_FAILED
)
80 goto error_munmap_src
;
82 memcpy(dst
, src
, st
.st_size
);
84 if (fsync(out_fd
) < 0)
85 goto error_munmap_dst
;
90 munmap(dst
, st
.st_size
);
92 munmap(src
, st
.st_size
);
101 static const char *guestfs_dirs
[] = {
115 static const char *guestfs_symlinks
[] = {
123 static int copy_init(const char *guestfs_name
)
127 snprintf(path
, PATH_MAX
, "%s%s%s/virt/init", HOME_DIR
, KVM_PID_FILE_PATH
, guestfs_name
);
129 return copy_file("guest/init", path
);
132 static int make_guestfs_symlink(const char *guestfs_name
, const char *path
)
134 char target
[PATH_MAX
];
137 snprintf(name
, PATH_MAX
, "%s%s%s%s", HOME_DIR
, KVM_PID_FILE_PATH
, guestfs_name
, path
);
139 snprintf(target
, PATH_MAX
, "/host%s", path
);
141 return symlink(target
, name
);
144 static void make_root_dir(void)
148 snprintf(name
, PATH_MAX
, "%s%s", HOME_DIR
, KVM_PID_FILE_PATH
);
153 static void make_dir(const char *dir
)
157 snprintf(name
, PATH_MAX
, "%s%s%s", HOME_DIR
, KVM_PID_FILE_PATH
, dir
);
162 static void make_guestfs_dir(const char *guestfs_name
, const char *dir
)
166 snprintf(name
, PATH_MAX
, "%s%s", guestfs_name
, dir
);
171 static int do_setup(const char *guestfs_name
)
177 make_dir(guestfs_name
);
179 for (i
= 0; i
< ARRAY_SIZE(guestfs_dirs
); i
++)
180 make_guestfs_dir(guestfs_name
, guestfs_dirs
[i
]);
182 for (i
= 0; i
< ARRAY_SIZE(guestfs_symlinks
); i
++) {
183 make_guestfs_symlink(guestfs_name
, guestfs_symlinks
[i
]);
186 return copy_init(guestfs_name
);
189 int kvm_cmd_setup(int argc
, const char **argv
, const char *prefix
)
191 parse_setup_options(argc
, argv
);
193 if (instance_name
== NULL
)
196 return do_setup(instance_name
);