]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume: Using --readonly for {vg|pv|lv}s commands 21519/head
authorErwan Velu <erwan@redhat.com>
Fri, 13 Apr 2018 08:16:44 +0000 (10:16 +0200)
committerErwan Velu <erwan@redhat.com>
Thu, 19 Apr 2018 09:57:27 +0000 (11:57 +0200)
The actual code is detecting {vg|pv|lv}s by running the usual {vg|pv|lv}s commands.
Those calls expect lvmetad to be aware of the actual state of them.
This works actually pretty well in most of the cases.

When ceph-volume is run from a container,
this code also works from the container itself but don't on the host.

On the host side, running {vg|pv|lv}s commands reports nothing,
making ceph-volume reporting "No valid Ceph devices found"
The root cause is lvmetad not receiving the udev notification and so,
{vg|pv|lv}s commands reports the 'known' state instead of the 'real' state.

This is a major issue as it means that it exists cases or maybe races where
ceph-volume reports "No valid Ceph devices found" while the disk
actually have some Ceph data & metadata on them.
This could be interpreted like disks are free/available while they are not.
This will mislead users or configuration tools trying to understand the
current state of a node.

In July 2015, as per https://www.redhat.com/archives/lvm-devel/2015-July/msg00086.html,
a new option called "--readonly" have been added to lvm2.
One of the most interesting part of it is : "disable using lvmetad so VGs are read from disk"

In our case, that feature is really interesting as it means that
everytime ceph-volume calls a {vg|pv|lv}s command, it will read the
metadata from the disks instead of considering the lvmetad status.

This patch change all the {vg|pv|lv}s call to use --readonly.
It solves the bug exposed here and doesn't affect the traditional use-case.
The main benefit of this patch is to avoid a false report of a disk not having metadata.

(cherry picked from commit 7be00cd19297ec80b4a629e2fc1e79c64205402c)
Fixes: https://tracker.ceph.com/issues/23693
Signed-off-by: Erwan Velu <erwan@redhat.com>
src/ceph-volume/ceph_volume/api/lvm.py

index 656c19ddfb3483ccb248461d0da14e5b312aa938..cd5891d48aa127017552bc731f3c8115a00fcc5a 100644 (file)
@@ -78,7 +78,7 @@ def get_api_vgs():
 
     Command and sample delimeted output, should look like::
 
-        $ vgs --noheadings --separator=';' \
+        $ vgs --noheadings --readonly --separator=';' \
           -o vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free
           ubuntubox-vg;1;2;0;wz--n-;299.52g;12.00m
           osd_vg;3;1;0;wz--n-;29.21g;9.21g
@@ -86,7 +86,7 @@ def get_api_vgs():
     """
     fields = 'vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free'
     stdout, stderr, returncode = process.call(
-        ['vgs', '--noheadings', '--separator=";"', '-o', fields]
+        ['vgs', '--noheadings', '--readonly', '--separator=";"', '-o', fields]
     )
     return _output_parser(stdout, fields)
 
@@ -98,14 +98,14 @@ def get_api_lvs():
 
     Command and delimeted output, should look like::
 
-        $ lvs --noheadings --separator=';' -o lv_tags,lv_path,lv_name,vg_name
+        $ lvs --noheadings --readonly --separator=';' -o lv_tags,lv_path,lv_name,vg_name
           ;/dev/ubuntubox-vg/root;root;ubuntubox-vg
           ;/dev/ubuntubox-vg/swap_1;swap_1;ubuntubox-vg
 
     """
     fields = 'lv_tags,lv_path,lv_name,vg_name,lv_uuid'
     stdout, stderr, returncode = process.call(
-        ['lvs', '--noheadings', '--separator=";"', '-o', fields]
+        ['lvs', '--noheadings', '--readonly', '--separator=";"', '-o', fields]
     )
     return _output_parser(stdout, fields)
 
@@ -119,7 +119,7 @@ def get_api_pvs():
 
     Command and delimeted output, should look like::
 
-        $ pvs --noheadings --separator=';' -o pv_name,pv_tags,pv_uuid
+        $ pvs --noheadings --readonly --separator=';' -o pv_name,pv_tags,pv_uuid
           /dev/sda1;;
           /dev/sdv;;07A4F654-4162-4600-8EB3-88D1E42F368D
 
@@ -127,7 +127,7 @@ def get_api_pvs():
     fields = 'pv_name,pv_tags,pv_uuid,vg_name'
 
     stdout, stderr, returncode = process.call(
-        ['pvs', '--no-heading', '--separator=";"', '-o', fields]
+        ['pvs', '--no-heading', '--readonly', '--separator=";"', '-o', fields]
     )
 
     return _output_parser(stdout, fields)