[4/7] tty: Prepare tracking bitmaps for multiple devpts handling

Submitted by Cyrill Gorcunov on Feb. 2, 2017, 8:02 a.m.

Details

Message ID 1486022529-1901-5-git-send-email-gorcunov@openvz.org
State New
Series "tty: Add support for multiple devpts instances"
Headers show

Commit Message

Cyrill Gorcunov Feb. 2, 2017, 8:02 a.m.
When multiple devpts will be addressed each bitmap
have to belong own mount instance, so allocate them
dinamically.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
---
 criu/tty.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 105 insertions(+), 16 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/tty.c b/criu/tty.c
index 2c0c56c57515..5ee9b85d0019 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -150,9 +150,6 @@  static LIST_HEAD(all_ttys);
 #define STTY_INDEX	1010
 #define INDEX_ERR	(MAX_TTYS + 1)
 
-static DECLARE_BITMAP(tty_bitmap, (MAX_TTYS << 1));
-static DECLARE_BITMAP(tty_active_pairs, (MAX_TTYS << 1));
-
 struct tty_driver {
 	short				type;
 	short				subtype;
@@ -166,6 +163,47 @@  struct tty_driver {
 #define TTY_SUBTYPE_MASTER			0x0001
 #define TTY_SUBTYPE_SLAVE			0x0002
 
+typedef struct tty_bitmap_s {
+	struct tty_bitmap_s		*next;
+	unsigned long			bitmap[BITS_TO_LONGS((MAX_TTYS << 1))];
+	int				mnt_id;
+} tty_bitmap_t;
+
+static tty_bitmap_t *tty_info_id_bitmap;
+static tty_bitmap_t *tty_active_pairs_bitmap;
+
+static void tty_free_bitmap(tty_bitmap_t *root)
+{
+	tty_bitmap_t *t, *next;
+
+	for (t = root; t; t = next) {
+		next = t->next;
+		xfree(t);
+	}
+}
+
+static unsigned long *tty_lookup_bitmap(tty_bitmap_t **root, int mnt_id)
+{
+	tty_bitmap_t *t, *prev;
+
+	for (t = *root, prev = NULL; t; prev = t, t = t->next) {
+		if (t->mnt_id == mnt_id)
+			return t->bitmap;
+	}
+
+	t = xzalloc(sizeof(*t));
+	if (!t)
+		return NULL;
+
+	if (prev)
+		prev->next = t;
+	if (!*root)
+		*root = t;
+
+	t->mnt_id = mnt_id;
+	return t->bitmap;
+}
+
 static int ptm_fd_get_index(int fd, const struct fd_parms *p)
 {
 	int index;
@@ -367,13 +405,13 @@  static int tty_get_index(u32 id)
 }
 
 /* Make sure the active pairs do exist */
-static int tty_verify_active_pairs(void * unused)
+static int __tty_verify_active_pairs(unsigned long *bitmap)
 {
 	unsigned long i, unpaired_slaves = 0;
 
-	for_each_bit(i, tty_active_pairs) {
+	for_each_bit(i, bitmap) {
 		if ((i % 2) == 0) {
-			if (test_bit(i + 1, tty_active_pairs)) {
+			if (test_bit(i + 1, bitmap)) {
 				i++;
 				continue;
 			}
@@ -399,6 +437,18 @@  static int tty_verify_active_pairs(void * unused)
 	return 0;
 }
 
+static int tty_verify_active_pairs(void *unused)
+{
+	tty_bitmap_t *t;
+
+	for (t = tty_active_pairs_bitmap; t; t = t->next) {
+		if (__tty_verify_active_pairs(t->bitmap))
+			return -1;
+	}
+
+	return 0;
+}
+
 static int tty_test_and_set(int bit, unsigned long *bitmap)
 {
 	int ret;
@@ -738,12 +788,11 @@  static bool tty_is_hung(struct tty_info *info)
 	return info->tie->termios == NULL;
 }
 
-static bool tty_has_active_pair(struct tty_info *info)
+static bool tty_has_active_pair(struct tty_info *info, unsigned long *bitmap)
 {
 	int d = tty_is_master(info) ? -1 : + 1;
 
-	return test_bit(info->tfe->tty_info_id + d,
-			tty_active_pairs);
+	return test_bit(info->tfe->tty_info_id + d, bitmap);
 }
 
 static void tty_show_pty_info(char *prefix, struct tty_info *info)
@@ -1233,7 +1282,13 @@  static int tty_find_restoring_task(struct tty_info *info)
 
 	if (info->tie->sid) {
 		if (!tty_is_master(info)) {
-			if (tty_has_active_pair(info))
+			unsigned long *bitmap;
+
+			bitmap = tty_lookup_bitmap(&tty_active_pairs_bitmap,
+						   info->tfe->mnt_id);
+			if (!bitmap)
+				goto nobitmap;
+			if (tty_has_active_pair(info, bitmap))
 				return 0;
 			else
 				goto shell_job;
@@ -1263,9 +1318,15 @@  static int tty_find_restoring_task(struct tty_info *info)
 
 		goto notask;
 	} else {
+		unsigned long *bitmap;
+
 		if (tty_is_master(info))
 			return 0;
-		if (tty_has_active_pair(info))
+		bitmap = tty_lookup_bitmap(&tty_active_pairs_bitmap,
+					   info->tfe->mnt_id);
+		if (!bitmap)
+			goto nobitmap;
+		if (tty_has_active_pair(info, bitmap))
 			return 0;
 	}
 
@@ -1279,6 +1340,9 @@  shell_job:
 notask:
 	pr_err("No task found with sid %d\n", info->tie->sid);
 	return -1;
+nobitmap:
+	pr_err("No pairing bitmap for %#x\n", info->tfe->id);
+	return -1;
 }
 
 static int tty_setup_orphan_slavery(void)
@@ -1594,8 +1658,18 @@  static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
 	 * can't be used. Most likely they appear if a user has
 	 * dumped program when it was closing a peer.
 	 */
-	if (is_pty(info->driver) && info->tie->termios)
-		tty_test_and_set(info->tfe->tty_info_id, tty_active_pairs);
+	if (is_pty(info->driver) && info->tie->termios) {
+		unsigned long *bitmap;
+
+		bitmap = tty_lookup_bitmap(&tty_active_pairs_bitmap,
+					   info->tfe->mnt_id);
+		if (!bitmap) {
+			pr_err("No pairing bitmap for %#x\n", info->tfe->id);
+			return -1;
+		}
+
+		tty_test_and_set(info->tfe->tty_info_id, bitmap);
+	}
 
 	pr_info("Collected tty ID %#x (%s)\n", info->tfe->id, info->driver->name);
 
@@ -1793,8 +1867,16 @@  static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, int mnt_id,
 	 * not yet supported by our tool and better to
 	 * inform a user about such situation.
 	 */
-	if (is_pty(driver))
-		tty_test_and_set(id, tty_active_pairs);
+	if (is_pty(driver)) {
+		unsigned long *bitmap;
+
+		bitmap = tty_lookup_bitmap(&tty_active_pairs_bitmap, mnt_id);
+		if (!bitmap) {
+			pr_err("No pairing bitmap for %#x\n", id);
+			return -1;
+		}
+		tty_test_and_set(id, bitmap);
+	}
 
 	info.termios		= &termios;
 	info.termios_locked	= &termios_locked;
@@ -1842,6 +1924,7 @@  static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
 	TtyFileEntry e = TTY_FILE_ENTRY__INIT;
 	int ret = 0, index = -1, mnt_id;
 	struct tty_driver *driver;
+	unsigned long *bitmap;
 
 	pr_info("Dumping tty %d with id %#x\n", lfd, id);
 
@@ -1906,7 +1989,11 @@  static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
 	 * transport anyway.
 	 */
 
-	if (!tty_test_and_set(e.tty_info_id, tty_bitmap))
+	bitmap = tty_lookup_bitmap(&tty_info_id_bitmap, mnt_id);
+	if (!bitmap)
+		return -ENOMEM;
+
+	if (!tty_test_and_set(e.tty_info_id, bitmap))
 		ret = dump_tty_info(lfd, e.tty_info_id, p, mnt_id, driver, index);
 
 	if (!ret)
@@ -2150,4 +2237,6 @@  int tty_prep_fds(void)
 void tty_fini_fds(void)
 {
 	close_service_fd(SELF_STDIN_OFF);
+	tty_free_bitmap(tty_info_id_bitmap);
+	tty_free_bitmap(tty_active_pairs_bitmap);
 }

Comments

Pavel Emelianov Feb. 8, 2017, 8:37 a.m.
On 02/02/2017 11:02 AM, Cyrill Gorcunov wrote:
> When multiple devpts will be addressed each bitmap
> have to belong own mount instance, so allocate them
> dinamically.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>  criu/tty.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 105 insertions(+), 16 deletions(-)
> 
> diff --git a/criu/tty.c b/criu/tty.c
> index 2c0c56c57515..5ee9b85d0019 100644
> --- a/criu/tty.c
> +++ b/criu/tty.c
> @@ -150,9 +150,6 @@ static LIST_HEAD(all_ttys);
>  #define STTY_INDEX	1010
>  #define INDEX_ERR	(MAX_TTYS + 1)
>  
> -static DECLARE_BITMAP(tty_bitmap, (MAX_TTYS << 1));
> -static DECLARE_BITMAP(tty_active_pairs, (MAX_TTYS << 1));
> -
>  struct tty_driver {
>  	short				type;
>  	short				subtype;
> @@ -166,6 +163,47 @@ struct tty_driver {
>  #define TTY_SUBTYPE_MASTER			0x0001
>  #define TTY_SUBTYPE_SLAVE			0x0002
>  
> +typedef struct tty_bitmap_s {
> +	struct tty_bitmap_s		*next;
> +	unsigned long			bitmap[BITS_TO_LONGS((MAX_TTYS << 1))];
> +	int				mnt_id;
> +} tty_bitmap_t;
> +
> +static tty_bitmap_t *tty_info_id_bitmap;
> +static tty_bitmap_t *tty_active_pairs_bitmap;
> +
> +static void tty_free_bitmap(tty_bitmap_t *root)
> +{
> +	tty_bitmap_t *t, *next;
> +
> +	for (t = root; t; t = next) {
> +		next = t->next;
> +		xfree(t);
> +	}
> +}
> +
> +static unsigned long *tty_lookup_bitmap(tty_bitmap_t **root, int mnt_id)

It's much better to keep the bitmap on mount_info->private field
rather than introduce yet another list for it.

> +{
> +	tty_bitmap_t *t, *prev;
> +
> +	for (t = *root, prev = NULL; t; prev = t, t = t->next) {
> +		if (t->mnt_id == mnt_id)
> +			return t->bitmap;
> +	}
> +
> +	t = xzalloc(sizeof(*t));
> +	if (!t)
> +		return NULL;
> +
> +	if (prev)
> +		prev->next = t;
> +	if (!*root)
> +		*root = t;
> +
> +	t->mnt_id = mnt_id;
> +	return t->bitmap;
> +}
> +
>  static int ptm_fd_get_index(int fd, const struct fd_parms *p)
>  {
>  	int index;
> @@ -367,13 +405,13 @@ static int tty_get_index(u32 id)
>  }
>  
>  /* Make sure the active pairs do exist */
> -static int tty_verify_active_pairs(void * unused)
> +static int __tty_verify_active_pairs(unsigned long *bitmap)
>  {
>  	unsigned long i, unpaired_slaves = 0;
>  
> -	for_each_bit(i, tty_active_pairs) {
> +	for_each_bit(i, bitmap) {
>  		if ((i % 2) == 0) {
> -			if (test_bit(i + 1, tty_active_pairs)) {
> +			if (test_bit(i + 1, bitmap)) {
>  				i++;
>  				continue;
>  			}
> @@ -399,6 +437,18 @@ static int tty_verify_active_pairs(void * unused)
>  	return 0;
>  }
>  
> +static int tty_verify_active_pairs(void *unused)
> +{
> +	tty_bitmap_t *t;
> +
> +	for (t = tty_active_pairs_bitmap; t; t = t->next) {
> +		if (__tty_verify_active_pairs(t->bitmap))
> +			return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  static int tty_test_and_set(int bit, unsigned long *bitmap)
>  {
>  	int ret;
> @@ -738,12 +788,11 @@ static bool tty_is_hung(struct tty_info *info)
>  	return info->tie->termios == NULL;
>  }
>  
> -static bool tty_has_active_pair(struct tty_info *info)
> +static bool tty_has_active_pair(struct tty_info *info, unsigned long *bitmap)
>  {
>  	int d = tty_is_master(info) ? -1 : + 1;
>  
> -	return test_bit(info->tfe->tty_info_id + d,
> -			tty_active_pairs);
> +	return test_bit(info->tfe->tty_info_id + d, bitmap);
>  }
>  
>  static void tty_show_pty_info(char *prefix, struct tty_info *info)
> @@ -1233,7 +1282,13 @@ static int tty_find_restoring_task(struct tty_info *info)
>  
>  	if (info->tie->sid) {
>  		if (!tty_is_master(info)) {
> -			if (tty_has_active_pair(info))
> +			unsigned long *bitmap;
> +
> +			bitmap = tty_lookup_bitmap(&tty_active_pairs_bitmap,
> +						   info->tfe->mnt_id);
> +			if (!bitmap)
> +				goto nobitmap;
> +			if (tty_has_active_pair(info, bitmap))
>  				return 0;
>  			else
>  				goto shell_job;
> @@ -1263,9 +1318,15 @@ static int tty_find_restoring_task(struct tty_info *info)
>  
>  		goto notask;
>  	} else {
> +		unsigned long *bitmap;
> +
>  		if (tty_is_master(info))
>  			return 0;
> -		if (tty_has_active_pair(info))
> +		bitmap = tty_lookup_bitmap(&tty_active_pairs_bitmap,
> +					   info->tfe->mnt_id);
> +		if (!bitmap)
> +			goto nobitmap;
> +		if (tty_has_active_pair(info, bitmap))
>  			return 0;
>  	}
>  
> @@ -1279,6 +1340,9 @@ shell_job:
>  notask:
>  	pr_err("No task found with sid %d\n", info->tie->sid);
>  	return -1;
> +nobitmap:
> +	pr_err("No pairing bitmap for %#x\n", info->tfe->id);
> +	return -1;
>  }
>  
>  static int tty_setup_orphan_slavery(void)
> @@ -1594,8 +1658,18 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
>  	 * can't be used. Most likely they appear if a user has
>  	 * dumped program when it was closing a peer.
>  	 */
> -	if (is_pty(info->driver) && info->tie->termios)
> -		tty_test_and_set(info->tfe->tty_info_id, tty_active_pairs);
> +	if (is_pty(info->driver) && info->tie->termios) {
> +		unsigned long *bitmap;
> +
> +		bitmap = tty_lookup_bitmap(&tty_active_pairs_bitmap,
> +					   info->tfe->mnt_id);
> +		if (!bitmap) {
> +			pr_err("No pairing bitmap for %#x\n", info->tfe->id);
> +			return -1;
> +		}
> +
> +		tty_test_and_set(info->tfe->tty_info_id, bitmap);
> +	}
>  
>  	pr_info("Collected tty ID %#x (%s)\n", info->tfe->id, info->driver->name);
>  
> @@ -1793,8 +1867,16 @@ static int dump_tty_info(int lfd, u32 id, const struct fd_parms *p, int mnt_id,
>  	 * not yet supported by our tool and better to
>  	 * inform a user about such situation.
>  	 */
> -	if (is_pty(driver))
> -		tty_test_and_set(id, tty_active_pairs);
> +	if (is_pty(driver)) {
> +		unsigned long *bitmap;
> +
> +		bitmap = tty_lookup_bitmap(&tty_active_pairs_bitmap, mnt_id);
> +		if (!bitmap) {
> +			pr_err("No pairing bitmap for %#x\n", id);
> +			return -1;
> +		}
> +		tty_test_and_set(id, bitmap);
> +	}
>  
>  	info.termios		= &termios;
>  	info.termios_locked	= &termios_locked;
> @@ -1842,6 +1924,7 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
>  	TtyFileEntry e = TTY_FILE_ENTRY__INIT;
>  	int ret = 0, index = -1, mnt_id;
>  	struct tty_driver *driver;
> +	unsigned long *bitmap;
>  
>  	pr_info("Dumping tty %d with id %#x\n", lfd, id);
>  
> @@ -1906,7 +1989,11 @@ static int dump_one_tty(int lfd, u32 id, const struct fd_parms *p)
>  	 * transport anyway.
>  	 */
>  
> -	if (!tty_test_and_set(e.tty_info_id, tty_bitmap))
> +	bitmap = tty_lookup_bitmap(&tty_info_id_bitmap, mnt_id);
> +	if (!bitmap)
> +		return -ENOMEM;
> +
> +	if (!tty_test_and_set(e.tty_info_id, bitmap))
>  		ret = dump_tty_info(lfd, e.tty_info_id, p, mnt_id, driver, index);
>  
>  	if (!ret)
> @@ -2150,4 +2237,6 @@ int tty_prep_fds(void)
>  void tty_fini_fds(void)
>  {
>  	close_service_fd(SELF_STDIN_OFF);
> +	tty_free_bitmap(tty_info_id_bitmap);
> +	tty_free_bitmap(tty_active_pairs_bitmap);
>  }
>
Cyrill Gorcunov Feb. 8, 2017, 3:48 p.m.
On Wed, Feb 08, 2017 at 11:37:55AM +0300, Pavel Emelyanov wrote:
> > +
> > +static unsigned long *tty_lookup_bitmap(tty_bitmap_t **root, int mnt_id)
> 
> It's much better to keep the bitmap on mount_info->private field
> rather than introduce yet another list for it.

And how on earth it's better? mount subsystem has nothing to do with
tty system, completely. For this reason our tty module is isolated
from anything else.

	Cyrill