why we only save lv that seg_start_pe=="0" in _reloadlvs

Hello, everyone! if we reload lvs, why we don't update lvs that seg_start_pe != "0" ? there's in [1] with red mark. what seg_start_pe means? If this lv is a vm template, may seg_start_pe is not zero, and we should ignore it? [1] vdsm/storage/lvm.py def _reloadlvs(self, vgName, lvNames=None): lvNames = _normalizeargs(lvNames) cmd = list(LVS_CMD) if lvNames: cmd.extend(["%s/%s" % (vgName, lvName) for lvName in lvNames]) else: cmd.append(vgName) rc, out, err = self.cmd(cmd, self._getVGDevs((vgName,))) with self._lock: if rc != 0: log.warning("lvm lvs failed: %s %s %s", str(rc), str(out), str(err)) lvNames = lvNames if lvNames else self._lvs.keys() for l in lvNames: if isinstance(self._lvs.get(l), Stub): self._lvs[l] = Unreadable(self._lvs[l].name, True) return dict(self._lvs) updatedLVs = {} for line in out: fields = [field.strip() for field in line.split(SEPARATOR)] lv = makeLV(*fields) # For LV we are only interested in its first extent if lv.seg_start_pe == "0": self._lvs[(lv.vg_name, lv.name)] = lv updatedLVs[(lv.vg_name, lv.name)] = lv # Determine if there are stale LVs if lvNames: staleLVs = (lvName for lvName in lvNames if (vgName, lvName) not in updatedLVs.iterkeys()) else: # All the LVs in the VG staleLVs = (lvName for v, lvName in self._lvs.keys() if (v == vgName) and ((vgName, lvName) not in updatedLVs.iterkeys())) for lvName in staleLVs: log.warning("Removing stale lv: %s/%s", vgName, lvName) self._lvs.pop((vgName, lvName), None) log.debug("lvs reloaded") return updatedLVs -- Cheers, Pencc

On Mon, Sep 17, 2018 at 3:51 PM pengyixiang <yxpengi386@163.com> wrote:
Hello, everyone! if we reload lvs, why we don't update lvs that seg_start_pe != "0" ? there's in [1] with red mark. what seg_start_pe means?
It is kind of hidden in lvm manual, but if you read carefully lvs(8): -o|--options String Comma-separated, ordered list of fields to display in columns. String arg syntax is: [+|-|#]Field1[,Field2 ...] The prefix + will append the specified fields to the default fields, - will remove the specified fields from the default fields, and # will compact specified fields (removing them when empty for all rows.) Use -o help to view the list of all available fields. Use separate lists of fields to add, remove or compact by repeating the -o option: -o+field1,field2 -o-field3,field4 -o#field5. These lists are evaluated from left to right. Use field name lv_all to view all LV fields, vg_all all VG fields, pv_all all PV fields, pvseg_all all PV segment fields, seg_all all LV segment fields, and pvseg_all all PV segment columns. See the lvm.conf report section for more config options. See lvmreport(7) for more information about reporting. and you follow the instructions: "Use -o help to view the list of all available fields" You will find: $ lvs -o help 2>&1 | grep seg_start_pe seg_start_pe - Offset within the LV to the start of the segment in physical extents.
If this lv is a vm template, may seg_start_pe is not zero, and we should ignore it?
This is not related to templates. At this level vdsm lvm module does not know anything about templates. I think the issue is getting multiple lines for same lv in lvs output, when you specify -o devices. If an lv has several segments, lvs will return separate line for every segment. You can simulate this case with these commands: $ sudo losetup -f /tmp/backing --show /dev/loop2 $ sudo pvcreate /dev/loop2 Physical volume "/dev/loop2" successfully created. $ sudo vgcreate test /dev/loop2 Volume group "test" successfully created $ sudo lvcreate -n lv1 -L 100m test Logical volume "lv1" created. $ sudo lvcreate -n lv2 -L 100m test Logical volume "lv2" created. $ sudo lvextend -L 200m test/lv1 Size of logical volume test/lv1 changed from 100.00 MiB (25 extents) to 200.00 MiB (50 extents). Logical volume test/lv1 successfully resized. $ sudo lvs -o lv_name,seg_start_pe,seg_pe_ranges,devices test LV Start PE Ranges Devices lv1 0 /dev/loop2:0-24 /dev/loop2(0) lv1 25 /dev/loop2:50-74 /dev/loop2(50) lv2 0 /dev/loop2:25-49 /dev/loop2(25) Looks like the only reason we query seg_start_pe is to filter the lines about the first segment of an lv. ...
updatedLVs = {} for line in out: fields = [field.strip() for field in line.split(SEPARATOR)] lv = makeLV(*fields) # For LV we are only interested in its first extent if lv.seg_start_pe == "0": self._lvs[(lv.vg_name, lv.name)] = lv updatedLVs[(lv.vg_name, lv.name)] = lv
...
This stores the info about the first segment in the cache, and drop possibly other lines about the next segments. We probably can eliminate multiple lines by using --select, which was not availabe when this code was written: $ sudo lvs -o lv_name,seg_pe_ranges,devices test --select 'seg_start_pe=0' LV PE Ranges Devices lv1 /dev/loop2:0-24 /dev/loop2(0) lv2 /dev/loop2:25-49 /dev/loop2(25) It would be nice if someone would have time to do this. Cheers, Nir
participants (2)
-
Nir Soffer
-
pengyixiang