1 package PVE
::Ceph
::Tools
;
10 use PVE
::Tools
qw(run_command dir_glob_foreach);
13 my $ccname = 'ceph'; # ceph cluster name
14 my $ceph_cfgdir = "/etc/ceph";
15 my $pve_ceph_cfgpath = "/etc/pve/$ccname.conf";
16 my $ceph_cfgpath = "$ceph_cfgdir/$ccname.conf";
18 my $pve_mon_key_path = "/etc/pve/priv/$ccname.mon.keyring";
19 my $pve_ckeyring_path = "/etc/pve/priv/$ccname.client.admin.keyring";
20 my $ceph_bootstrap_osd_keyring = "/var/lib/ceph/bootstrap-osd/$ccname.keyring";
21 my $ceph_bootstrap_mds_keyring = "/var/lib/ceph/bootstrap-mds/$ccname.keyring";
22 my $ceph_mds_data_dir = '/var/lib/ceph/mds';
25 ceph_bin
=> "/usr/bin/ceph",
26 ceph_mon
=> "/usr/bin/ceph-mon",
27 ceph_mgr
=> "/usr/bin/ceph-mgr",
28 ceph_osd
=> "/usr/bin/ceph-osd",
29 ceph_mds
=> "/usr/bin/ceph-mds",
34 pve_ceph_cfgpath
=> $pve_ceph_cfgpath,
35 pve_mon_key_path
=> $pve_mon_key_path,
36 pve_ckeyring_path
=> $pve_ckeyring_path,
37 ceph_bootstrap_osd_keyring
=> $ceph_bootstrap_osd_keyring,
38 ceph_bootstrap_mds_keyring
=> $ceph_bootstrap_mds_keyring,
39 ceph_mds_data_dir
=> $ceph_mds_data_dir,
40 long_rados_timeout
=> 60,
43 sub get_local_version
{
46 if (check_ceph_installed
('ceph_bin', $noerr)) {
48 run_command
([$ceph_service->{ceph_bin
}, '--version'],
50 outfunc
=> sub { $ceph_version = shift; });
51 if ($ceph_version && $ceph_version =~ /^ceph.*\s((\d+)\.(\d+)\.(\d+))/) {
52 # return (version, major, minor, patch) : major;
53 return wantarray ?
($1, $2, $3, $4) : $2;
63 my $value = $config_hash->{$key};
65 die "no such ceph config '$key'" if !$value;
70 sub purge_all_ceph_files
{
71 # fixme: this is very dangerous - should we really support this function?
75 unlink $pve_ceph_cfgpath;
76 unlink $pve_ckeyring_path;
77 unlink $pve_mon_key_path;
79 unlink $ceph_bootstrap_osd_keyring;
80 unlink $ceph_bootstrap_mds_keyring;
82 system("rm -rf /var/lib/ceph/mon/ceph-*");
87 sub check_ceph_installed
{
88 my ($service, $noerr) = @_;
90 $service = 'ceph_bin' if !defined($service);
92 if (! -x
$ceph_service->{$service}) {
93 die "binary not installed: $ceph_service->{$service}\n" if !$noerr;
100 sub check_ceph_inited
{
103 return undef if !check_ceph_installed
('ceph_mon', $noerr);
105 if (! -f
$pve_ceph_cfgpath) {
106 die "pveceph configuration not initialized\n" if !$noerr;
113 sub check_ceph_enabled
{
116 return undef if !check_ceph_inited
($noerr);
118 if (! -f
$ceph_cfgpath) {
119 die "pveceph configuration not enabled\n" if !$noerr;
127 my ($pool, $param, $rados) = @_;
129 if (!defined($rados)) {
130 $rados = PVE
::RADOS-
>new();
133 my $pg_num = $param->{pg_num
} || 128;
134 my $size = $param->{size
} || 3;
135 my $min_size = $param->{min_size
} || 2;
136 my $application = $param->{application
} // 'rbd';
138 $rados->mon_command({
139 prefix
=> "osd pool create",
141 pg_num
=> int($pg_num),
145 $rados->mon_command({
146 prefix
=> "osd pool set",
153 $rados->mon_command({
154 prefix
=> "osd pool set",
161 if (defined($param->{crush_rule
})) {
162 $rados->mon_command({
163 prefix
=> "osd pool set",
166 val
=> $param->{crush_rule
},
171 $rados->mon_command({
172 prefix
=> "osd pool application enable",
180 my ($pool, $rados) = @_;
182 if (!defined($rados)) {
183 $rados = PVE
::RADOS-
>new();
186 my $res = $rados->mon_command({ prefix
=> "osd lspools" });
192 my ($pool, $rados) = @_;
194 if (!defined($rados)) {
195 $rados = PVE
::RADOS-
>new();
198 # fixme: '--yes-i-really-really-mean-it'
199 $rados->mon_command({
200 prefix
=> "osd pool delete",
203 sure
=> '--yes-i-really-really-mean-it',
208 sub setup_pve_symlinks
{
209 # fail if we find a real file instead of a link
210 if (-f
$ceph_cfgpath) {
211 my $lnk = readlink($ceph_cfgpath);
212 die "file '$ceph_cfgpath' already exists\n"
213 if !$lnk || $lnk ne $pve_ceph_cfgpath;
215 symlink($pve_ceph_cfgpath, $ceph_cfgpath) ||
216 die "unable to create symlink '$ceph_cfgpath' - $!\n";
220 # Ceph versions greater Hammer use 'ceph' as user and group instead
221 # of 'root', and use systemd.
222 sub systemd_managed
{
224 if (-f
"/lib/systemd/system/ceph-osd\@.service") {
231 # wipe the first 200 MB to clear off leftovers from previous use, otherwise a
236 my @wipe_cmd = qw(/bin/dd if=/dev/zero bs=1M conv=fdatasync);
238 foreach my $devpath (@devs) {
239 my $devname = basename
($devpath);
240 my $dev_size = PVE
::Tools
::file_get_contents
("/sys/class/block/$devname/size");
242 ($dev_size) = $dev_size =~ m
|(\d
+)|; # untaint $dev_size
243 die "Coulnd't get the size of the device $devname\n" if (!defined($dev_size));
245 my $size = ($dev_size * 512 / 1024 / 1024);
246 my $count = ($size < 200) ?
$size : 200;
248 print "wipe disk/partition: $devpath\n";
249 eval { run_command
([@wipe_cmd, "count=$count", "of=${devpath}"]) };