Re: Device Mapper Persistent Configuration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Gili,

For some reason, reply-all did not pick up your email address.  My mistake.

1)  This is usually done from user space.  User space programs can run really early.  mdadm does this to start software raid sets.  It is probably possible to scan devices from the module, but a lot of stuff may not be there yet if you statically load it.  device-mapper block devices are allowed to "stack", so one of your constituent devices could be /dev/md0, or crypt target, or a network mount, or who knows.

In terms of "how early" your user space program can run, the answer is that it can run from initrd before the root file system is even mounted read/write.

2)  Creating stuff in proc has a number of articles on-line.  I don't have a link handy right now.  One thing to watch out for is that the proc interface changed pretty radically in 3.10.0.  Before this, files uses a simple buffer API.  After this, file use the stock system sequential file API.  The buffer API had an edge condition deadlock, thus the change.

The "pieces" are proc_mkdir(...) to create a directory (pretty simple), and here are helper functions from some of my code to create and delete an actual proc "file".  Note that this code does not use function prototypes, so RdFn and WtFn should actually be prototyped as:

int ProcRead_vars_stream(struct seq_file *m, void *dev, void *pv)

I use "dev" as a pointer to the "device context" that device mapper uses to track instances.  Device context is actually a windows driver term for block filters, which are the analog of a device mapper block filter.  "pv" is a pointer to more local data.  This can let you write a single proc handler function, but give it multiple tasks based on the data parameter.

This code is from a really big and convoluted module, so I can't give you much more of it.


void * _shim_create_proc_seq_entry(char *name, void *parent, int mode, void *RdFn, void *WtFn, void *dev, void *data, u64 MaxIdx)

{
    struct _PROC_RES *r;

    if ( !( r = kzalloc(sizeof(*r), GFP_KERNEL) ) ) return NULL;

    r->file_ops.owner    = THIS_MODULE;

    strcpy(r->name, name);
    r->mode       = mode;
    r->RdFn       = RdFn;
    r->ShowFn     = RdFn;
    r->WtFn       = WtFn;
    r->dev        = dev;
    r->data       = data;
    r->ProcParent = parent;
    r->MaxIdx     = MaxIdx;

    switch ( mode ) {
        case 0 :            // Read only - single access
            r->file_ops.open    = _shim_proc_open;
            r->file_ops.read    = seq_read;
            r->file_ops.llseek  = seq_lseek;
            r->file_ops.release = single_release;
            r->ProcHandle = proc_create_data(r->name, 0, parent, &r->file_ops, r);
            break;
        case 1 :            // Read only - multiple access
            r->file_ops.open    = _shim_proc_open_mul;
            r->file_ops.read    = seq_read;
            r->file_ops.llseek  = seq_lseek;
            r->file_ops.release = seq_release;

            r->seq_ops.start = _shim_proc_seq_start;
            r->seq_ops.next  = _shim_proc_seq_next;
            r->seq_ops.stop  = _shim_proc_seq_stop;
            r->seq_ops.show  = _shim_proc_seq_show;

            r->ProcHandle = proc_create_data(r->name, 0, parent, &r->file_ops, r);
            break;
        case 2 :            // Write only
            BUG();
            break;
        case 3 :            // Read write - single access
            r->file_ops.open    = _shim_proc_open;
            r->file_ops.read    = seq_read;
            r->file_ops.write   = _shim_proc_seq_write;
            r->file_ops.llseek  = seq_lseek;
            r->file_ops.release = single_release;
            r->ProcHandle = proc_create_data(r->name, 0644, parent, &r->file_ops, r);
            break;
    }

    return r;
}

void _shim_remove_proc_seq_entry(void *data)

{
    struct _PROC_RES    *r = data;

    remove_proc_entry(r->name, r->ProcParent);
    kfree(r);
}


On Sun, Jun 28, 2015 at 11:42 PM, Gili B <gilib123@xxxxxxxxxxx> wrote:
Hi
I didnt receive the email below, so I've copied and pasted it from the archive , sory .
 
Thanks for the reply ..
I have a few followup quesions:
1) If I use a special signature to identify disks, like in mdraid, why must I have a user space tool to discover disks?
If I want all volumes up and ready during a reboot, I prefer that the module do it when it loads.
A user space program will start too late in the boot process.
2)Can you point me to some guide on how to export stuff in proc ?
 
Thanks
-gili

 
 On Sun, Jun 28, 2015 at 8:21 AM, Gili B <gilib123 hotmail com> wrote:

hi
We are starting working on a new device mapper module which has targets similar
to the ones in thin module (pool and thin),  but it adds some additional features.
The user should be able to create and use file systems on the thin volumes.
I wanted to know what is the recommended  way to make the configuration with dmsetup
persistent ?

​You should probably use mdraid as an inspiration.  Put a signature block on every member device.  You can then write a user-space tool to scan devices and find the collections.  Be sure to use a good "signature" for your type of device, plus a good UUID signature so that different generations can be identified.
 
We want that all file systems will be available after reboot.

​If you get the device running early enough, then fstab should be able to mount file systems.
 
Should we write our own configuration tool?  should we add special configuration files?

​You will probably need a user-space tool.  You can probably get away with no configuration file, but you should again use mdraid as inspiration so that your user-space tool gets limits of where to look for member pieces.
 
Should the kernel module we write , automatically discover all the configration and initialize accordingly?
 
 
Regarding debug - Is there a generic way to run dmsetup for example that
prints some inside details on the targets? (for example number of outstanding ios, memory used etc)

​You can do this three ways.  1)  build in IOCTL into your module that can query stuff.  2) export stuff in /sys.  3) export stuff in /proc.  I personally like exporting debug stuff into /proc.  Remember that printk is your friend.  I have even created "command" file in proc that then dump debug information with printk.  If you use /proc, you need to handle multiple instances of your mapper.  I use /proc/{my_project_name}/{instance_name}/...
 
 

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel



--
Doug Dumitru
EasyCo LLC
--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel

[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux