unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* LVM support
@ 2015-04-15  5:07 Tomáš Čech
  2015-04-15 12:32 ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Tomáš Čech @ 2015-04-15  5:07 UTC (permalink / raw)
  To: guix-devel

Hi Guix,

as project for my Hackweek in SUSE I decided to spend my time on LVM
support in GuixSD - something I miss greatly. This also means that
I'll have much less time for that after this week :(

So far I spent time on reviving my GuixSD installation and preparing
staticly linked binaries for initrd. I have now lvm2 package with
extra output "static". 

What next?

Now the simplest way would be to simply call

vgchange --activate y

Matching configuration could be one configuration option:
(use-lvm?)


That would scan all block devices and look for LVM signature.

Pros:
- it's super simple!
Cons:
- if LVM with filesystem required at boot-time is not found, error
  is not detected or returned by LVM itself



Slightly bit more complicated way could be

vgchange --activate y <volume_group_name>

for every volume group defined in system configuration. Matching configuration could be
(logical-volume-groups '("system" "data"))

e.g. specify list of volume group names used by system.

Pros:
- still simple
- if group activation fails, I can detect it and report it to user

Cons:
- some block devices with LVM may not be available at boot-time (like
  iSCSI devices accessible through network only or Luks devices
  available after entering password)

That is my current approach.



I could also specify whether it should be made available at boot time or not
(logical-volume-groups '('("system" #t)
                         '("data"   #f)))

(sorry for my poor Scheme taste here :)

Pros:
- with this I could say that volume group "system" should be activated
  at boot time, but "data" should be activated later.

Cons:
- starting to be more complicated - I need both initrd stage LVM
  activation and root filesystem stage LVM activation (implemented as
  service? which dependencies it has?)


Or do it in different way. I'd rather not propose here any wild ideas
for configuration but if you can devise something better, please tell
me...



S_W

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-04-15  5:07 LVM support Tomáš Čech
@ 2015-04-15 12:32 ` Ludovic Courtès
  2015-04-16  6:24   ` Tomáš Čech
  0 siblings, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2015-04-15 12:32 UTC (permalink / raw)
  To: guix-devel

Tomáš Čech <sleep_walker@gnu.org> skribis:

> as project for my Hackweek in SUSE I decided to spend my time on LVM
> support in GuixSD - something I miss greatly. This also means that
> I'll have much less time for that after this week :(

Well this is nice already!

> So far I spent time on reviving my GuixSD installation and preparing
> staticly linked binaries for initrd. I have now lvm2 package with
> extra output "static". 

Don’t worry about static linking or anything: you can use any package,
including dynamically-linked, and it will be magically added to the
initrd if needed.

Then as a second step, since that’ll probably be very big, you can work
on statically-linked variants of the relevant packages (as done for
‘e2fsck/static’.)

> Now the simplest way would be to simply call
>
> vgchange --activate y
>
> Matching configuration could be one configuration option:
> (use-lvm?)
>
>
> That would scan all block devices and look for LVM signature.
>
> Pros:
> - it's super simple!
> Cons:
> - if LVM with filesystem required at boot-time is not found, error
>  is not detected or returned by LVM itself
>
>
>
> Slightly bit more complicated way could be
>
> vgchange --activate y <volume_group_name>
>
> for every volume group defined in system configuration. Matching configuration could be
> (logical-volume-groups '("system" "data"))
>
> e.g. specify list of volume group names used by system.
>
> Pros:
> - still simple
> - if group activation fails, I can detect it and report it to user
>
> Cons:
> - some block devices with LVM may not be available at boot-time (like
>  iSCSI devices accessible through network only or Luks devices
>  available after entering password)
>
> That is my current approach.
>
>
>
> I could also specify whether it should be made available at boot time or not
> (logical-volume-groups '('("system" #t)
>                         '("data"   #f)))
>
> (sorry for my poor Scheme taste here :)
>
> Pros:
> - with this I could say that volume group "system" should be activated
>  at boot time, but "data" should be activated later.
>
> Cons:
> - starting to be more complicated - I need both initrd stage LVM
>  activation and root filesystem stage LVM activation (implemented as
>  service? which dependencies it has?)

Sorry I’m not really familiar with LVM.

Technically, if LVM volumes are mapped devices, the best would be to
define a <mapped-device-kind> structure for them, as discussed on IRC
(like ‘luks-device-mapping’ in (gnu system).)

Then users would need to adjust their ‘mapped-devices’ accordingly (info
"(guix) Mapped Devices").

How does that sound?

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-04-15 12:32 ` Ludovic Courtès
@ 2015-04-16  6:24   ` Tomáš Čech
  2015-04-16 12:47     ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Tomáš Čech @ 2015-04-16  6:24 UTC (permalink / raw)
  To: guix-devel

On Wed, Apr 15, 2015 at 02:32:14PM +0200, Ludovic Courtès wrote:
>Tomáš Čech <sleep_walker@gnu.org> skribis:
>
>> as project for my Hackweek in SUSE I decided to spend my time on LVM
>> support in GuixSD - something I miss greatly. This also means that
>> I'll have much less time for that after this week :(
>
>Well this is nice already!
>
>> So far I spent time on reviving my GuixSD installation and preparing
>> staticly linked binaries for initrd. I have now lvm2 package with
>> extra output "static".
>
>Don’t worry about static linking or anything: you can use any package,
>including dynamically-linked, and it will be magically added to the
>initrd if needed.
>
>Then as a second step, since that’ll probably be very big, you can work
>on statically-linked variants of the relevant packages (as done for
>‘e2fsck/static’.)

I did this already :)

>
>> Now the simplest way would be to simply call
>>
>> vgchange --activate y
>>
>> Matching configuration could be one configuration option:
>> (use-lvm?)
>>
>>
>> That would scan all block devices and look for LVM signature.
>>
>> Pros:
>> - it's super simple!
>> Cons:
>> - if LVM with filesystem required at boot-time is not found, error
>>  is not detected or returned by LVM itself
>>
>>
>>
>> Slightly bit more complicated way could be
>>
>> vgchange --activate y <volume_group_name>
>>
>> for every volume group defined in system configuration. Matching configuration could be
>> (logical-volume-groups '("system" "data"))
>>
>> e.g. specify list of volume group names used by system.
>>
>> Pros:
>> - still simple
>> - if group activation fails, I can detect it and report it to user
>>
>> Cons:
>> - some block devices with LVM may not be available at boot-time (like
>>  iSCSI devices accessible through network only or Luks devices
>>  available after entering password)
>>
>> That is my current approach.
>>
>>
>>
>> I could also specify whether it should be made available at boot time or not
>> (logical-volume-groups '('("system" #t)
>>                         '("data"   #f)))
>>
>> (sorry for my poor Scheme taste here :)
>>
>> Pros:
>> - with this I could say that volume group "system" should be activated
>>  at boot time, but "data" should be activated later.
>>
>> Cons:
>> - starting to be more complicated - I need both initrd stage LVM
>>  activation and root filesystem stage LVM activation (implemented as
>>  service? which dependencies it has?)
>
>Sorry I’m not really familiar with LVM.

It's implemented using device mapper but instead of mapping one block
device to another you map one block device to whole group (like
playground where you can do anything).


>
>Technically, if LVM volumes are mapped devices, the best would be to
>define a <mapped-device-kind> structure for them, as discussed on IRC
>(like ‘luks-device-mapping’ in (gnu system).)

I didn't like the idea first because it felt confusing and
unatural. Words like `mapping' and `source' and `target' are
misleading. But from programming POV it seems to be the easisest
approach in the end.

(define-record-type* <mapped-device> mapped-device
  make-mapped-device
  mapped-device?
  (source    mapped-device-source)                ;string
  (target    mapped-device-target)                ;string
  (type      mapped-device-type))                 ;<mapped-device-kind>
	  
`source' will be ignored (I not only don't need it but I don't even
know how to pass it or what it should do). `target' will be used for
volume group name. mapped-device-kind structure is easily applicable.


On the other hand problem starts with need-for-boot?. Device mapped
device will be activated during the boot (which is desirable for LVM)
only if there is filesystem which uses such device and has
`need-for-boot?' set to #t.

I needed to tweak operating-system-boot-mapped-devices to not filter
mappings of the new type at all. Now it seems to generate initrd
capable of booting root filesystem from LVM :)

The thing is that this design is not nice. I always admired Scheme's
power in expressing things naturally. mapped-device interface is for
mapping 1 block device to 1 block device which will contain 1
filesystem.


Design I'm thinking about would follow file-system structure. For
device property (I'm not sure if this is proper word in Scheme for
item of record type) to define functions like `partition' (disk,
number), `mapped-device' (source, target, type), `logical-volume' (group,
volume) and whatever would be needed further. You could then express
your mount in more powerful way like:

(partition "sda" 1)

(mapped-device
  (partition "sda" 2)
  "encrypted_swap"
  luks-mapping-type)

(logical-volume
  "system_group"
  "root")


(mapped-device
  (logical-volume "some_group" "some_volume")
  "encrypted data"
  luks-mapping-type)

etc.


Of course, it would lead to more complicated code to handle such
configuration, but it would definitely feel more natural.

When other block device type (like iSCSI) would be required, just
another function (or whatever it is) would be implemented.

Please don't tell me 'this is not how Guix works' :)

Best regards,

S_W

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-04-16  6:24   ` Tomáš Čech
@ 2015-04-16 12:47     ` Ludovic Courtès
  2015-04-17  1:09       ` Tomáš Čech
  0 siblings, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2015-04-16 12:47 UTC (permalink / raw)
  To: guix-devel

Tomáš Čech <sleep_walker@gnu.org> skribis:

> On Wed, Apr 15, 2015 at 02:32:14PM +0200, Ludovic Courtès wrote:

[...]

>>Sorry I’m not really familiar with LVM.
>
> It's implemented using device mapper but instead of mapping one block
> device to another you map one block device to whole group (like
> playground where you can do anything).

What do you mean by “whole group”?  A tree under /dev/mapper?

>>Technically, if LVM volumes are mapped devices, the best would be to
>>define a <mapped-device-kind> structure for them, as discussed on IRC
>>(like ‘luks-device-mapping’ in (gnu system).)
>
> I didn't like the idea first because it felt confusing and
> unatural. Words like `mapping' and `source' and `target' are
> misleading. But from programming POV it seems to be the easisest
> approach in the end.

I would think the terms are pretty descriptive, esp. when looking at the
corresponding section of the manual, but I’m biased.  ;-)

Now, my understanding of your message is not so much that the terms are
misleading, but rather that the abstraction is bogus (which appears to
be the case based on what you say.)

> On the other hand problem starts with need-for-boot?. Device mapped
> device will be activated during the boot (which is desirable for LVM)
> only if there is filesystem which uses such device and has
> `need-for-boot?' set to #t.

Right.  I was hesitant about this approach actually, see 9cb426b8.

> I needed to tweak operating-system-boot-mapped-devices to not filter
> mappings of the new type at all. Now it seems to generate initrd
> capable of booting root filesystem from LVM :)

Nice!  Could you post your working version of the patch, just to make
things more concrete?

> The thing is that this design is not nice. I always admired Scheme's
> power in expressing things naturally. mapped-device interface is for
> mapping 1 block device to 1 block device which will contain 1
> filesystem.

Understood.  This has nothing to do with Scheme, really.  :-)

> Design I'm thinking about would follow file-system structure. For
> device property (I'm not sure if this is proper word in Scheme for
> item of record type) to define functions like `partition' (disk,
> number), `mapped-device' (source, target, type), `logical-volume' (group,
> volume) and whatever would be needed further. You could then express
> your mount in more powerful way like:
>
> (partition "sda" 1)
>
> (mapped-device
>  (partition "sda" 2)
>  "encrypted_swap"
>  luks-mapping-type)
>
> (logical-volume
>  "system_group"
>  "root")
>
>
> (mapped-device
>  (logical-volume "some_group" "some_volume")
>  "encrypted data"
>  luks-mapping-type)
>
> etc.

I see.  Looks good!

Does the volume some_group/some_volume have an associated /dev node or
tree?  What does it look like?

Really a detail, but I think "/dev/sda2" or (partition "/dev/sda2") is
enough; no need to abstract it, IMO, since device node name is up to the
user.

> Of course, it would lead to more complicated code to handle such
> configuration, but it would definitely feel more natural.
>
> When other block device type (like iSCSI) would be required, just
> another function (or whatever it is) would be implemented.

Anything special about iSCSI?  I would expect iSCSI partitions/disks to
just have block devices as usual, no?

Thank you!

Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-04-16 12:47     ` Ludovic Courtès
@ 2015-04-17  1:09       ` Tomáš Čech
  2015-04-21 15:52         ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Tomáš Čech @ 2015-04-17  1:09 UTC (permalink / raw)
  To: guix-devel


[-- Attachment #1.1: Type: text/plain, Size: 5200 bytes --]

On Thu, Apr 16, 2015 at 02:47:52PM +0200, Ludovic Courtès wrote:
>Tomáš Čech <sleep_walker@gnu.org> skribis:
>
>> On Wed, Apr 15, 2015 at 02:32:14PM +0200, Ludovic Courtès wrote:
>
>[...]
>
>>>Sorry I’m not really familiar with LVM.
>>
>> It's implemented using device mapper but instead of mapping one block
>> device to another you map one block device to whole group (like
>> playground where you can do anything).
>
>What do you mean by “whole group”?  A tree under /dev/mapper?

From device node POV it generates
/dev/<volume_group_name>/<logical_volume_name> and it also creates
/dev/mapper/<volume_group_name>-<logical_volume_name> and
/dev/dm-<number>.

From block device perspective it adds another level of "partitioning"
to "physical volume" partitions. You gather block devices (can be
partitions, disks, anything), create volume group to join the space
into one entity and then create logical volumes without caring where
it really is. Logical volumes are useful for resizing, adding and
removing filesystems - it has always the same device node.


>
>>>Technically, if LVM volumes are mapped devices, the best would be to
>>>define a <mapped-device-kind> structure for them, as discussed on IRC
>>>(like ‘luks-device-mapping’ in (gnu system).)
>>
>> I didn't like the idea first because it felt confusing and
>> unatural. Words like `mapping' and `source' and `target' are
>> misleading. But from programming POV it seems to be the easisest
>> approach in the end.
>
>I would think the terms are pretty descriptive, esp. when looking at the
>corresponding section of the manual, but I’m biased.  ;-)

I meant in LVM context of course.

>Now, my understanding of your message is not so much that the terms are
>misleading, but rather that the abstraction is bogus (which appears to
>be the case based on what you say.)
>
>> On the other hand problem starts with need-for-boot?. Device mapped
>> device will be activated during the boot (which is desirable for LVM)
>> only if there is filesystem which uses such device and has
>> `need-for-boot?' set to #t.
>
>Right.  I was hesitant about this approach actually, see 9cb426b8.

Ah, OK, I didn't updated since I started to work on LVM.

>> I needed to tweak operating-system-boot-mapped-devices to not filter
>> mappings of the new type at all. Now it seems to generate initrd
>> capable of booting root filesystem from LVM :)
>
>Nice!  Could you post your working version of the patch, just to make
>things more concrete?

I attach patch to this mail.

>> The thing is that this design is not nice. I always admired Scheme's
>> power in expressing things naturally. mapped-device interface is for
>> mapping 1 block device to 1 block device which will contain 1
>> filesystem.
>
>Understood.  This has nothing to do with Scheme, really.  :-)
>
>> Design I'm thinking about would follow file-system structure. For
>> device property (I'm not sure if this is proper word in Scheme for
>> item of record type) to define functions like `partition' (disk,
>> number), `mapped-device' (source, target, type), `logical-volume' (group,
>> volume) and whatever would be needed further. You could then express
>> your mount in more powerful way like:
>>
>> (partition "sda" 1)
>>
>> (mapped-device
>>  (partition "sda" 2)
>>  "encrypted_swap"
>>  luks-mapping-type)
>>
>> (logical-volume
>>  "system_group"
>>  "root")
>>
>>
>> (mapped-device
>>  (logical-volume "some_group" "some_volume")
>>  "encrypted data"
>>  luks-mapping-type)
>>
>> etc.
>
>I see.  Looks good!
>
>Does the volume some_group/some_volume have an associated /dev node or
>tree?  What does it look like?

Yes, it does, I described above.

>Really a detail, but I think "/dev/sda2" or (partition "/dev/sda2") is
>enough; no need to abstract it, IMO, since device node name is up to the
>user.

Well, I faced situations where such freedom of expression would be
handy, but there were rare. sda says that it is the first found scsi
device in the system but it doesn't say anything about accessibility
of the device (`local-disk' should be introduced as well I think).

>> Of course, it would lead to more complicated code to handle such
>> configuration, but it would definitely feel more natural.
>>
>> When other block device type (like iSCSI) would be required, just
>> another function (or whatever it is) would be implemented.
>
>Anything special about iSCSI?  I would expect iSCSI partitions/disks to
>just have block devices as usual, no?

Yes, but when you have root filesystem on iSCSI, you need to perform
other actions to make that block device available as with device
mapping or LVM...

(You need to configure and establish connection to iSCSI target.)



Ad the progress - current state of the patch is that it should work
for filesystems mounted from initrd. And is ugly.

As I understand the problem, created device nodes are missing after
switch-root and it seems it tried to mount filesystems before starting
eudev. I'll have a look on that again after some sleep.

Thank you for your comments.

S_W


[-- Attachment #1.2: lvm.patch --]
[-- Type: text/plain, Size: 5818 bytes --]

diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index caec80f..18d1f06 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -1638,6 +1638,33 @@ mapper.  Kernel components are part of Linux-libre.")
     ;; Command-line tools are GPLv2.
     (license (list gpl2 lgpl2.1))))
 
+(define-public lvm2/static
+  (package
+    (name "lvm2-static")
+    (version (package-version lvm2))
+    (build-system trivial-build-system)
+    (source #f)
+    (arguments
+     `(#:modules ((guix build utils))
+       #:builder
+       (begin
+         (use-modules (guix build utils))
+         (let ((source (string-append (assoc-ref %build-inputs "lvm2") "/sbin"))
+               (bin    (string-append (assoc-ref %outputs "out") "/sbin")))
+           (mkdir-p bin)
+           (for-each (lambda (file)
+                       (copy-file (string-append source "/" file)
+                                  (string-append bin "/" file)))
+                     '("lvm.static" "dmsetup.static"))))))
+
+     (native-inputs `(("lvm2" ,lvm2 "static")))
+     (synopsis "Statically-linked commands from lvm2")
+     (description
+      "This package provides statically-linked binaries dmsetup and lvm taken
+from lvm2 package.  It is meant to be used in initrds.")
+     (home-page (package-home-page lvm2))
+     (license (package-license lvm2))))
+
 (define-public wireless-tools
   (package
     (name "wireless-tools")
diff --git a/gnu/system.scm b/gnu/system.scm
index 6cf12df..7c1e67c 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -41,6 +41,7 @@
   #:use-module (gnu packages compression)
   #:use-module (gnu packages firmware)
   #:autoload   (gnu packages cryptsetup) (cryptsetup)
+  #:autoload   (gnu packages linux) (lvm2/static)
   #:use-module (gnu services)
   #:use-module (gnu services dmd)
   #:use-module (gnu services base)
@@ -86,7 +87,9 @@
             %base-packages
             %base-firmware
 
-            luks-device-mapping))
+            luks-device-mapping
+            lvm-mapping
+            lvm-mapping-used?))
 
 ;;; Commentary:
 ;;;
@@ -208,6 +211,27 @@ file."
    (open open-luks-device)
    (close close-luks-device)))
 
+(define (logical-volume-group-activate source target)
+  #~(zero? (system* (string-append #$lvm2/static "/sbin/lvm.static")
+                         "vgchange" "--activate" "y" #$target)))
+
+(define (logical-volume-group-deactivate source target)
+  #~(zero? (system* (string-append #$lvm2/static "/sbin/lvm.static")
+                    "vgchange" "--activate" "n" #$target)))
+
+(define (lvm-mapping-used? devices)
+  (not
+   (null? (filter
+           (lambda (md)
+             (eq? (mapped-device-type md)
+                  lvm-mapping))
+           devices))))
+
+(define lvm-mapping
+  (mapped-device-kind
+   (open  logical-volume-group-activate)
+   (close logical-volume-group-deactivate)))
+
 (define (other-file-system-services os)
   "Return file system services for the file systems of OS that are not marked
 as 'needed-for-boot'."
@@ -267,7 +291,10 @@ from the initrd."
         (file-systems (operating-system-file-systems os)))
    (filter (lambda (md)
              (let ((user (mapped-device-user md file-systems)))
-               (and user (file-system-needed-for-boot? user))))
+               (or
+                (and user (file-system-needed-for-boot? user))
+                (and (eq? (mapped-device-type md)
+                          lvm-mapping)))))
            devices)))
 
 (define (device-mapping-services os)
diff --git a/gnu/system/linux-initrd.scm b/gnu/system/linux-initrd.scm
index 83685ad..fc8bbd3 100644
--- a/gnu/system/linux-initrd.scm
+++ b/gnu/system/linux-initrd.scm
@@ -25,6 +25,7 @@
                 #:select (%store-prefix))
   #:use-module ((guix derivations)
                 #:select (derivation->output-path))
+  #:use-module (gnu system)
   #:use-module (gnu packages cpio)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages linux)
@@ -212,6 +213,9 @@ loaded at boot time in the order in which they appear."
                   file-systems)
             (list e2fsck/static)
             '())
+      ,@(if (lvm-mapping-used? mapped-devices)
+            (list lvm2/static)
+            '())
       ,@(if volatile-root?
             (list unionfs-fuse/static)
             '())))
@@ -241,7 +245,19 @@ loaded at boot time in the order in which they appear."
 
          (boot-system #:mounts '#$(map file-system->spec file-systems)
                       #:pre-mount (lambda ()
-                                    (and #$@device-mapping-commands))
+                                    (and #$@device-mapping-commands
+                                         ;; If we activated any volume group, we
+                                         ;; need to ensure that device nodes are
+                                         ;; created.  Add code here to call it
+                                         ;; once for all activations.
+                                         #$(when (lvm-mapping-used? mapped-devices)
+                                             #~(zero?
+                                                (system* (string-append
+                                                          #$lvm2/static
+                                                          "/sbin/lvm.static")
+                                                         "vgscan"
+                                                         "--mknodes")))))
+
                       #:linux-modules '#$linux-modules
                       #:linux-module-directory '#$kodir
                       #:qemu-guest-networking? #$qemu-networking?

[-- Attachment #2: Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-04-17  1:09       ` Tomáš Čech
@ 2015-04-21 15:52         ` Ludovic Courtès
  2015-05-01 11:32           ` Tomáš Čech
  0 siblings, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2015-04-21 15:52 UTC (permalink / raw)
  To: guix-devel

Tomáš Čech <sleep_walker@gnu.org> skribis:

> On Thu, Apr 16, 2015 at 02:47:52PM +0200, Ludovic Courtès wrote:
>>Tomáš Čech <sleep_walker@gnu.org> skribis:
>>
>>> On Wed, Apr 15, 2015 at 02:32:14PM +0200, Ludovic Courtès wrote:
>>
>>[...]
>>
>>>>Sorry I’m not really familiar with LVM.
>>>
>>> It's implemented using device mapper but instead of mapping one block
>>> device to another you map one block device to whole group (like
>>> playground where you can do anything).
>>
>>What do you mean by “whole group”?  A tree under /dev/mapper?
>
> From device node POV it generates
> /dev/<volume_group_name>/<logical_volume_name> and it also creates
> /dev/mapper/<volume_group_name>-<logical_volume_name> and
> /dev/dm-<number>.

OK.

> From block device perspective it adds another level of "partitioning"
> to "physical volume" partitions. You gather block devices (can be
> partitions, disks, anything), create volume group to join the space
> into one entity and then create logical volumes without caring where
> it really is. Logical volumes are useful for resizing, adding and
> removing filesystems - it has always the same device node.

Yes, that part I knew.  ;-)


[...]

> --- a/gnu/system.scm
> +++ b/gnu/system.scm
> @@ -41,6 +41,7 @@
>    #:use-module (gnu packages compression)
>    #:use-module (gnu packages firmware)
>    #:autoload   (gnu packages cryptsetup) (cryptsetup)
> +  #:autoload   (gnu packages linux) (lvm2/static)
>    #:use-module (gnu services)
>    #:use-module (gnu services dmd)
>    #:use-module (gnu services base)
> @@ -86,7 +87,9 @@
>              %base-packages
>              %base-firmware
>  
> -            luks-device-mapping))
> +            luks-device-mapping
> +            lvm-mapping
> +            lvm-mapping-used?))
>  
>  ;;; Commentary:
>  ;;;
> @@ -208,6 +211,27 @@ file."
>     (open open-luks-device)
>     (close close-luks-device)))
>  
> +(define (logical-volume-group-activate source target)
> +  #~(zero? (system* (string-append #$lvm2/static "/sbin/lvm.static")
> +                         "vgchange" "--activate" "y" #$target)))
> +
> +(define (logical-volume-group-deactivate source target)
> +  #~(zero? (system* (string-append #$lvm2/static "/sbin/lvm.static")
> +                    "vgchange" "--activate" "n" #$target)))
> +
> +(define (lvm-mapping-used? devices)
> +  (not
> +   (null? (filter
> +           (lambda (md)
> +             (eq? (mapped-device-type md)
> +                  lvm-mapping))
> +           devices))))
> +
> +(define lvm-mapping
> +  (mapped-device-kind
> +   (open  logical-volume-group-activate)
> +   (close logical-volume-group-deactivate)))

This looks good to me!

So I would declare

  (mapped-device
    (source "/dev/sda")
    (target "volume_group_name-logical_volume_name")
    (kind lvm-device-mapping))

and that would give me
/dev/mapper/volume_group_name-logical_volume_name, right?

>  (define (other-file-system-services os)
>    "Return file system services for the file systems of OS that are not marked
>  as 'needed-for-boot'."
> @@ -267,7 +291,10 @@ from the initrd."
>          (file-systems (operating-system-file-systems os)))
>     (filter (lambda (md)
>               (let ((user (mapped-device-user md file-systems)))
> -               (and user (file-system-needed-for-boot? user))))
> +               (or
> +                (and user (file-system-needed-for-boot? user))
> +                (and (eq? (mapped-device-type md)
> +                          lvm-mapping)))))
>             devices)))

I don’t think it’s necessary: if a ‘file-system’ object has
"/dev/mapper/volume_group_name-logical_volume_name" has its ‘device’
field, then this device mapping will automatically be recognized as
needed-for-boot, won’t it?

> --- a/gnu/system/linux-initrd.scm
> +++ b/gnu/system/linux-initrd.scm
> @@ -25,6 +25,7 @@
>                  #:select (%store-prefix))
>    #:use-module ((guix derivations)
>                  #:select (derivation->output-path))
> +  #:use-module (gnu system)
>    #:use-module (gnu packages cpio)
>    #:use-module (gnu packages compression)
>    #:use-module (gnu packages linux)
> @@ -212,6 +213,9 @@ loaded at boot time in the order in which they appear."
>                    file-systems)
>              (list e2fsck/static)
>              '())
> +      ,@(if (lvm-mapping-used? mapped-devices)
> +            (list lvm2/static)
> +            '())
>        ,@(if volatile-root?
>              (list unionfs-fuse/static)
>              '())))
> @@ -241,7 +245,19 @@ loaded at boot time in the order in which they appear."
>  
>           (boot-system #:mounts '#$(map file-system->spec file-systems)
>                        #:pre-mount (lambda ()
> -                                    (and #$@device-mapping-commands))
> +                                    (and #$@device-mapping-commands
> +                                         ;; If we activated any volume group, we
> +                                         ;; need to ensure that device nodes are
> +                                         ;; created.  Add code here to call it
> +                                         ;; once for all activations.
> +                                         #$(when (lvm-mapping-used? mapped-devices)
> +                                             #~(zero?
> +                                                (system* (string-append
> +                                                          #$lvm2/static
> +                                                          "/sbin/lvm.static")
> +                                                         "vgscan"
> +                                                         "--mknodes")))))

So ‘lvm vgchange --activate y’ does not create /dev nodes?  Would it be
possible to change the command returned by
‘logical-volume-group-activate’ to somehow create the nodes?  That would
be ideal.

Thanks!

Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-04-21 15:52         ` Ludovic Courtès
@ 2015-05-01 11:32           ` Tomáš Čech
  2015-05-03 19:59             ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Tomáš Čech @ 2015-05-01 11:32 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 7229 bytes --]

On Tue, Apr 21, 2015 at 05:52:33PM +0200, Ludovic Courtès wrote:
>Tomáš Čech <sleep_walker@gnu.org> skribis:
>
>> On Thu, Apr 16, 2015 at 02:47:52PM +0200, Ludovic Courtès wrote:
>>>Tomáš Čech <sleep_walker@gnu.org> skribis:
>>>
>>>> On Wed, Apr 15, 2015 at 02:32:14PM +0200, Ludovic Courtès wrote:
>>>
>>>[...]
>>>
>>>>>Sorry I’m not really familiar with LVM.
>>>>
>>>> It's implemented using device mapper but instead of mapping one block
>>>> device to another you map one block device to whole group (like
>>>> playground where you can do anything).
>>>
>>>What do you mean by “whole group”?  A tree under /dev/mapper?
>>
>> From device node POV it generates
>> /dev/<volume_group_name>/<logical_volume_name> and it also creates
>> /dev/mapper/<volume_group_name>-<logical_volume_name> and
>> /dev/dm-<number>.
>
>OK.
>
>> From block device perspective it adds another level of "partitioning"
>> to "physical volume" partitions. You gather block devices (can be
>> partitions, disks, anything), create volume group to join the space
>> into one entity and then create logical volumes without caring where
>> it really is. Logical volumes are useful for resizing, adding and
>> removing filesystems - it has always the same device node.
>
>Yes, that part I knew.  ;-)
>
>
>[...]
>
>> --- a/gnu/system.scm
>> +++ b/gnu/system.scm
>> @@ -41,6 +41,7 @@
>>    #:use-module (gnu packages compression)
>>    #:use-module (gnu packages firmware)
>>    #:autoload   (gnu packages cryptsetup) (cryptsetup)
>> +  #:autoload   (gnu packages linux) (lvm2/static)
>>    #:use-module (gnu services)
>>    #:use-module (gnu services dmd)
>>    #:use-module (gnu services base)
>> @@ -86,7 +87,9 @@
>>              %base-packages
>>              %base-firmware
>>
>> -            luks-device-mapping))
>> +            luks-device-mapping
>> +            lvm-mapping
>> +            lvm-mapping-used?))
>>
>>  ;;; Commentary:
>>  ;;;
>> @@ -208,6 +211,27 @@ file."
>>     (open open-luks-device)
>>     (close close-luks-device)))
>>
>> +(define (logical-volume-group-activate source target)
>> +  #~(zero? (system* (string-append #$lvm2/static "/sbin/lvm.static")
>> +                         "vgchange" "--activate" "y" #$target)))
>> +
>> +(define (logical-volume-group-deactivate source target)
>> +  #~(zero? (system* (string-append #$lvm2/static "/sbin/lvm.static")
>> +                    "vgchange" "--activate" "n" #$target)))
>> +
>> +(define (lvm-mapping-used? devices)
>> +  (not
>> +   (null? (filter
>> +           (lambda (md)
>> +             (eq? (mapped-device-type md)
>> +                  lvm-mapping))
>> +           devices))))
>> +
>> +(define lvm-mapping
>> +  (mapped-device-kind
>> +   (open  logical-volume-group-activate)
>> +   (close logical-volume-group-deactivate)))
>
>This looks good to me!
>
>So I would declare
>
>  (mapped-device
>    (source "/dev/sda")
>    (target "volume_group_name-logical_volume_name")
>    (kind lvm-device-mapping))
>
>and that would give me
>/dev/mapper/volume_group_name-logical_volume_name, right?

Volume group can be on multiple block devices. For now I rely on autodetect
abilities of LVM.

So you would declare:

(mapped-device
  (source "") ; irrelevant for LVM
  (target "volume_group_name")
  (type lvm-mapping))

and that would give you
/dev/mapper/volume_group_name-some_volume
/dev/mapper/volume_group_name-other_volume
...

and more conveniently
/dev/volume_group_name/some_volume
/dev/volume_group_name/other_volume
...

>
>>  (define (other-file-system-services os)
>>    "Return file system services for the file systems of OS that are not marked
>>  as 'needed-for-boot'."
>> @@ -267,7 +291,10 @@ from the initrd."
>>          (file-systems (operating-system-file-systems os)))
>>     (filter (lambda (md)
>>               (let ((user (mapped-device-user md file-systems)))
>> -               (and user (file-system-needed-for-boot? user))))
>> +               (or
>> +                (and user (file-system-needed-for-boot? user))
>> +                (and (eq? (mapped-device-type md)
>> +                          lvm-mapping)))))
>>             devices)))
>
>I don’t think it’s necessary: if a ‘file-system’ object has
>"/dev/mapper/volume_group_name-logical_volume_name" has its ‘device’
>field, then this device mapping will automatically be recognized as
>needed-for-boot, won’t it?

Yes, you're right, this chunk shouldn't be needed at all. Good catch!

>> --- a/gnu/system/linux-initrd.scm
>> +++ b/gnu/system/linux-initrd.scm
>> @@ -25,6 +25,7 @@
>>                  #:select (%store-prefix))
>>    #:use-module ((guix derivations)
>>                  #:select (derivation->output-path))
>> +  #:use-module (gnu system)
>>    #:use-module (gnu packages cpio)
>>    #:use-module (gnu packages compression)
>>    #:use-module (gnu packages linux)
>> @@ -212,6 +213,9 @@ loaded at boot time in the order in which they appear."
>>                    file-systems)
>>              (list e2fsck/static)
>>              '())
>> +      ,@(if (lvm-mapping-used? mapped-devices)
>> +            (list lvm2/static)
>> +            '())
>>        ,@(if volatile-root?
>>              (list unionfs-fuse/static)
>>              '())))
>> @@ -241,7 +245,19 @@ loaded at boot time in the order in which they appear."
>>
>>           (boot-system #:mounts '#$(map file-system->spec file-systems)
>>                        #:pre-mount (lambda ()
>> -                                    (and #$@device-mapping-commands))
>> +                                    (and #$@device-mapping-commands
>> +                                         ;; If we activated any volume group, we
>> +                                         ;; need to ensure that device nodes are
>> +                                         ;; created.  Add code here to call it
>> +                                         ;; once for all activations.
>> +                                         #$(when (lvm-mapping-used? mapped-devices)
>> +                                             #~(zero?
>> +                                                (system* (string-append
>> +                                                          #$lvm2/static
>> +                                                          "/sbin/lvm.static")
>> +                                                         "vgscan"
>> +                                                         "--mknodes")))))
>
>So ‘lvm vgchange --activate y’ does not create /dev nodes?

Right.

>Would it be possible to change the command returned by
>‘logical-volume-group-activate’ to somehow create the nodes?  That would
>be ideal.

There are two actions needed to be taken:
1] volume group activation
2] creation of nodes

This design choice does as many 1] as needed and 2] once in the end.

I could do always 1] and 2] for every volume group, but I didn't find it nice,
since previous 2] calls are useless only slowing down the process. Do you
really think I should change it?

Thanks for your review.

S_W

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-05-01 11:32           ` Tomáš Čech
@ 2015-05-03 19:59             ` Ludovic Courtès
  2015-05-07  8:02               ` Tomáš Čech
  0 siblings, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2015-05-03 19:59 UTC (permalink / raw)
  To: guix-devel

Sorry for the delay.

Tomáš Čech <sleep_walker@gnu.org> skribis:

> On Tue, Apr 21, 2015 at 05:52:33PM +0200, Ludovic Courtès wrote:

[...]

>>So I would declare
>>
>>  (mapped-device
>>    (source "/dev/sda")
>>    (target "volume_group_name-logical_volume_name")
>>    (kind lvm-device-mapping))
>>
>>and that would give me
>>/dev/mapper/volume_group_name-logical_volume_name, right?
>
> Volume group can be on multiple block devices. For now I rely on autodetect
> abilities of LVM.
>
> So you would declare:
>
> (mapped-device
>  (source "") ; irrelevant for LVM
>  (target "volume_group_name")
>  (type lvm-mapping))
>
> and that would give you
> /dev/mapper/volume_group_name-some_volume
> /dev/mapper/volume_group_name-other_volume
> ...
>
> and more conveniently
> /dev/volume_group_name/some_volume
> /dev/volume_group_name/other_volume
> ...

OK.  So the ‘source’ is irrelevant because ‘vgscan’ magically creates
the device nodes for volumes such that users don’t have to know what the
underlying block devices are, right?


[...]

>>>           (boot-system #:mounts '#$(map file-system->spec file-systems)
>>>                        #:pre-mount (lambda ()
>>> -                                    (and #$@device-mapping-commands))
>>> +                                    (and #$@device-mapping-commands
>>> +                                         ;; If we activated any volume group, we
>>> +                                         ;; need to ensure that device nodes are
>>> +                                         ;; created.  Add code here to call it
>>> +                                         ;; once for all activations.
>>> +                                         #$(when (lvm-mapping-used? mapped-devices)
>>> +                                             #~(zero?
>>> +                                                (system* (string-append
>>> +                                                          #$lvm2/static
>>> +                                                          "/sbin/lvm.static")
>>> +                                                         "vgscan"
>>> +                                                         "--mknodes")))))
>>
>>So ‘lvm vgchange --activate y’ does not create /dev nodes?
>
> Right.
>
>>Would it be possible to change the command returned by
>>‘logical-volume-group-activate’ to somehow create the nodes?  That would
>>be ideal.
>
> There are two actions needed to be taken:
> 1] volume group activation
> 2] creation of nodes
>
> This design choice does as many 1] as needed and 2] once in the end.
>
> I could do always 1] and 2] for every volume group, but I didn't find it nice,
> since previous 2] calls are useless only slowing down the process. Do you
> really think I should change it?

No, you’re right, what you did makes a lot of sense (thanks for bearing
with me!).

Could you send an updated patch?  It sounds like we’re almost there,
I guess.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-05-03 19:59             ` Ludovic Courtès
@ 2015-05-07  8:02               ` Tomáš Čech
  2015-05-19 10:32                 ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Tomáš Čech @ 2015-05-07  8:02 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 3881 bytes --]

On Sun, May 03, 2015 at 09:59:53PM +0200, Ludovic Courtès wrote:
>Sorry for the delay.

Sorry for all the delays :)

>
>Tomáš Čech <sleep_walker@gnu.org> skribis:
>
>> On Tue, Apr 21, 2015 at 05:52:33PM +0200, Ludovic Courtès wrote:
>
>[...]
>
>>>So I would declare
>>>
>>>  (mapped-device
>>>    (source "/dev/sda")
>>>    (target "volume_group_name-logical_volume_name")
>>>    (kind lvm-device-mapping))
>>>
>>>and that would give me
>>>/dev/mapper/volume_group_name-logical_volume_name, right?
>>
>> Volume group can be on multiple block devices. For now I rely on autodetect
>> abilities of LVM.
>>
>> So you would declare:
>>
>> (mapped-device
>>  (source "") ; irrelevant for LVM
>>  (target "volume_group_name")
>>  (type lvm-mapping))
>>
>> and that would give you
>> /dev/mapper/volume_group_name-some_volume
>> /dev/mapper/volume_group_name-other_volume
>> ...
>>
>> and more conveniently
>> /dev/volume_group_name/some_volume
>> /dev/volume_group_name/other_volume
>> ...
>
>OK.  So the ‘source’ is irrelevant because ‘vgscan’ magically creates
>the device nodes for volumes such that users don’t have to know what the
>underlying block devices are, right?

Yes.


>[...]
>
>>>>           (boot-system #:mounts '#$(map file-system->spec file-systems)
>>>>                        #:pre-mount (lambda ()
>>>> -                                    (and #$@device-mapping-commands))
>>>> +                                    (and #$@device-mapping-commands
>>>> +                                         ;; If we activated any volume group, we
>>>> +                                         ;; need to ensure that device nodes are
>>>> +                                         ;; created.  Add code here to call it
>>>> +                                         ;; once for all activations.
>>>> +                                         #$(when (lvm-mapping-used? mapped-devices)
>>>> +                                             #~(zero?
>>>> +                                                (system* (string-append
>>>> +                                                          #$lvm2/static
>>>> +                                                          "/sbin/lvm.static")
>>>> +                                                         "vgscan"
>>>> +                                                         "--mknodes")))))
>>>
>>>So ‘lvm vgchange --activate y’ does not create /dev nodes?
>>
>> Right.
>>
>>>Would it be possible to change the command returned by
>>>‘logical-volume-group-activate’ to somehow create the nodes?  That would
>>>be ideal.
>>
>> There are two actions needed to be taken:
>> 1] volume group activation
>> 2] creation of nodes
>>
>> This design choice does as many 1] as needed and 2] once in the end.
>>
>> I could do always 1] and 2] for every volume group, but I didn't find it nice,
>> since previous 2] calls are useless only slowing down the process. Do you
>> really think I should change it?
>
>No, you’re right, what you did makes a lot of sense (thanks for bearing
>with me!).

Good.

>Could you send an updated patch?  It sounds like we’re almost there,
>I guess.

Not there yet. Now I need to make some changes with mounting order to help
non-root filesystems on LVM volume.

Right now it seems it tries to:
1] mount all filesystems
2] run udev

But I need to make it:
1] mount /dev
2] run udev service (with the `udevadm settle' in the end)
3] mount the rest of filesystems

It seems that /sys and /proc is mounted already from initrd phase using
mount-essential-file-systems. Is there reason not to put /dev there as well?

I see none so I'll try to add /dev filesystem mounting there (and to
move-essential-file-systems) and remove it from %base-file-systems.

Best regards,

S_W

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: LVM support
  2015-05-07  8:02               ` Tomáš Čech
@ 2015-05-19 10:32                 ` Ludovic Courtès
  0 siblings, 0 replies; 11+ messages in thread
From: Ludovic Courtès @ 2015-05-19 10:32 UTC (permalink / raw)
  To: guix-devel

Tomáš Čech <sleep_walker@gnu.org> skribis:

> On Sun, May 03, 2015 at 09:59:53PM +0200, Ludovic Courtès wrote:

[...]

>>Could you send an updated patch?  It sounds like we’re almost there,
>>I guess.
>
> Not there yet. Now I need to make some changes with mounting order to help
> non-root filesystems on LVM volume.
>
> Right now it seems it tries to:
> 1] mount all filesystems
> 2] run udev

Right.

> But I need to make it:
> 1] mount /dev
> 2] run udev service (with the `udevadm settle' in the end)
> 3] mount the rest of filesystems

OK.

Note that ‘file-system-service’ has a #:requirements parameter, which is
where we could pass '(udev).  But maybe some of the file systems defined
in (gnu system file-systems) need to be mounted before udev is started.
You’ll have to try.  ;-)

> It seems that /sys and /proc is mounted already from initrd phase using
> mount-essential-file-systems. Is there reason not to put /dev there as well?

The reason to do it this way is that it avoids another special case.
That said, in practice /dev is mounted from the initrd because
%devtmpfs-file-system has ‘needed-for-boot?’ set.

> I see none so I'll try to add /dev filesystem mounting there (and to
> move-essential-file-systems) and remove it from %base-file-systems.

I don’t think this is necessary.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* LVM support
  2018-07-30 12:47     ` Pierre Neidhardt
@ 2018-08-19 11:06       ` Ludovic Courtès
  0 siblings, 0 replies; 11+ messages in thread
From: Ludovic Courtès @ 2018-08-19 11:06 UTC (permalink / raw)
  To: Pierre Neidhardt; +Cc: guix-devel, Nils Gillmann

Hi!

Pierre Neidhardt <ambrevar@gmail.com> skribis:

> Also how far did we go with LVM support?

This was discussed looong ago (whether/how the device-mapping code would
be a good fit for LVM) but we don’t have any code.

This would be nice to have, though I wouldn’t consider it a blocker for
1.0.

Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-08-19 11:06 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-15  5:07 LVM support Tomáš Čech
2015-04-15 12:32 ` Ludovic Courtès
2015-04-16  6:24   ` Tomáš Čech
2015-04-16 12:47     ` Ludovic Courtès
2015-04-17  1:09       ` Tomáš Čech
2015-04-21 15:52         ` Ludovic Courtès
2015-05-01 11:32           ` Tomáš Čech
2015-05-03 19:59             ` Ludovic Courtès
2015-05-07  8:02               ` Tomáš Čech
2015-05-19 10:32                 ` Ludovic Courtès
  -- strict thread matches above, loose matches on Subject: below --
2018-07-29 15:18 Roadmap for Guix 1.0 Ludovic Courtès
2018-07-30  1:23 ` Pjotr Prins
2018-07-30  9:02   ` Nils Gillmann
2018-07-30 12:47     ` Pierre Neidhardt
2018-08-19 11:06       ` LVM support Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).