diff options
author | Karel Zak | 2018-10-12 12:50:03 +0200 |
---|---|---|
committer | Karel Zak | 2018-12-07 12:32:57 +0100 |
commit | 5bb395f4f60f4c163ccf036421fafc72e5f5259e (patch) | |
tree | 024068c22a4d0b753417ad2dcd1daac839ea0681 /misc-utils/lsblk.h | |
parent | lsblk: properly initialize structs (diff) | |
download | kernel-qcow2-util-linux-5bb395f4f60f4c163ccf036421fafc72e5f5259e.tar.gz kernel-qcow2-util-linux-5bb395f4f60f4c163ccf036421fafc72e5f5259e.tar.xz kernel-qcow2-util-linux-5bb395f4f60f4c163ccf036421fafc72e5f5259e.zip |
lsblk: add basic function to build devices tree
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/lsblk.h')
-rw-r--r-- | misc-utils/lsblk.h | 99 |
1 files changed, 96 insertions, 3 deletions
diff --git a/misc-utils/lsblk.h b/misc-utils/lsblk.h index 935c9de15..05740ec5d 100644 --- a/misc-utils/lsblk.h +++ b/misc-utils/lsblk.h @@ -14,12 +14,14 @@ #include <libsmartcols.h> #include "c.h" +#include "list.h" #include "debug.h" #define LSBLK_DEBUG_INIT (1 << 1) #define LSBLK_DEBUG_FILTER (1 << 2) #define LSBLK_DEBUG_DEV (1 << 3) #define LSBLK_DEBUG_CXT (1 << 4) +#define LSBLK_DEBUG_TREE (1 << 5) #define LSBLK_DEBUG_ALL 0xFFFF UL_DEBUG_DECLARE_MASK(lsblk); @@ -64,11 +66,29 @@ struct lsblk_devprop { char *model; /* disk model */ }; +/* Device dependence + * + * Note that the same device may be slave/holder for more another devices. It + * means we need to allocate list member rather than use @child directly. + */ +struct lsblk_devdep { + struct list_head ls_deps; /* item in parent->deps */ + struct lsblk_device *child; +}; + struct lsblk_device { - struct lsblk_device *parent; - struct lsblk_devprop *properties; + int refcount; + + struct list_head deps; /* list with lsblk_devdep */ + struct list_head ls_roots; /* item in devtree->roots list */ + struct list_head ls_devices; /* item in devtree->devices list */ - struct libscols_line *scols_line; + struct lsblk_devtree *tree; + + struct lsblk_devprop *properties; + struct libscols_line *scols_line; + + struct lsblk_device *parent; /* obsolete */ struct stat st; char *name; /* kernel name in /sys/block */ @@ -98,6 +118,55 @@ struct lsblk_device { blkid_requested : 1; }; + +/* + * Note that lsblk tree uses botton devices (devices without slaves) as root + * of the tree, and partitions are interpreted as a dependence too; it means: + * sda -> sda1 -> md0 + * + * The flag 'is_inverted' turns the tree over (root is device without holders): + * md0 -> sda1 -> sda + */ +struct lsblk_devtree { + int refcount; + + struct list_head roots; /* tree root devices */ + struct list_head devices; /* all devices */ + + unsigned int is_inverse : 1; /* inverse tree */ +}; + + +/* + * Generic iterator + */ +struct lsblk_iter { + struct list_head *p; /* current position */ + struct list_head *head; /* start position */ + int direction; /* LSBLK_ITER_{FOR,BACK}WARD */ +}; + +#define LSBLK_ITER_FORWARD 0 +#define LSBLK_ITER_BACKWARD 1 + +#define IS_ITER_FORWARD(_i) ((_i)->direction == LSBLK_ITER_FORWARD) +#define IS_ITER_BACKWARD(_i) ((_i)->direction == LSBLK_ITER_BACKWARD) + +#define LSBLK_ITER_INIT(itr, list) \ + do { \ + (itr)->p = IS_ITER_FORWARD(itr) ? \ + (list)->next : (list)->prev; \ + (itr)->head = (list); \ + } while(0) + +#define LSBLK_ITER_ITERATE(itr, res, restype, member) \ + do { \ + res = list_entry((itr)->p, restype, member); \ + (itr)->p = IS_ITER_FORWARD(itr) ? \ + (itr)->p->next : (itr)->p->prev; \ + } while(0) + + /* lsblk-mnt.c */ extern void lsblk_mnt_init(void); extern void lsblk_mnt_deinit(void); @@ -109,4 +178,28 @@ extern void lsblk_device_free_properties(struct lsblk_devprop *p); extern struct lsblk_devprop *lsblk_device_get_properties(struct lsblk_device *dev); extern void lsblk_properties_deinit(void); +/* lsblk-devtree.c */ +void lsblk_reset_iter(struct lsblk_iter *itr, int direction); +struct lsblk_device *lsblk_new_device(struct lsblk_devtree *tree); +void lsblk_ref_device(struct lsblk_device *dev); +void lsblk_unref_device(struct lsblk_device *dev); +struct lsblk_devdep *lsblk_device_new_dependence(struct lsblk_device *parent, struct lsblk_device *child); +int lsblk_device_next_child(struct lsblk_device *dev, + struct lsblk_iter *itr, + struct lsblk_device **child); + +struct lsblk_devtree *lsblk_new_devtree(void); +void lsblk_ref_devtree(struct lsblk_devtree *tr); +void lsblk_unref_devtree(struct lsblk_devtree *tr); +int lsblk_devtree_add_root(struct lsblk_devtree *tr, struct lsblk_device *dev); +int lsblk_devtree_next_root(struct lsblk_devtree *tr, + struct lsblk_iter *itr, + struct lsblk_device **dev); +int lsblk_devtree_add_device(struct lsblk_devtree *tr, struct lsblk_device *dev); +int lsblk_devtree_next_device(struct lsblk_devtree *tr, + struct lsblk_iter *itr, + struct lsblk_device **dev); +struct lsblk_device *lsblk_devtree_get_device(struct lsblk_devtree *tr, const char *name); + + #endif /* UTIL_LINUX_LSBLK_H */ |