[Devel] [PATCH vz8 2/2] ext4: send abort uevent on ext4 journal abort

2020-11-05 Thread Andrey Ryabinin
From: Dmitry Monakhov 

Currenlty error from device result in ext4_abort, but uevent not generated 
because
ext4_abort() caller's context do not allow GFP_KERNEL memory allocation.
Let's relax submission context requirement and deffer actual uevent submission
to work_queue.  It can be any workqueue I've pick rsv_conversion_wq because it 
is
already exists.

khorenko@: "system_wq" does not fit here because at the moment of
work execution sb can be already destroyed.
"EXT4_SB(sb)->rsv_conversion_wq" is flushed before sb is destroyed.

Signed-off-by: Dmitry Monakhov 

[aryabinin rh8 rebase]
Signed-off-by: Andrey Ryabinin 
---
 fs/ext4/ext4.h  |  2 ++
 fs/ext4/super.c | 10 ++
 2 files changed, 12 insertions(+)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 228492c9518f..bbdd7efc8447 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1499,6 +1499,7 @@ struct ext4_sb_info {
__u32 s_csum_seed;
 
bool s_err_event_sent;
+   bool s_abrt_event_sent;
 
/* Reclaim extents from extent status tree */
struct shrinker s_es_shrinker;
@@ -3126,6 +3127,7 @@ enum ext4_event_type {
  EXT4_UA_UMOUNT,
  EXT4_UA_REMOUNT,
  EXT4_UA_ERROR,
+ EXT4_UA_ABORT,
  EXT4_UA_FREEZE,
  EXT4_UA_UNFREEZE,
 };
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 3cc979825ec8..00619f45b1c3 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -420,6 +420,9 @@ static void ext4_send_uevent_work(struct work_struct *w)
case EXT4_UA_ERROR:
ret = add_uevent_var(env, "FS_ACTION=%s", "ERROR");
break;
+   case EXT4_UA_ABORT:
+   ret = add_uevent_var(env, "FS_ACTION=%s", "ABORT");
+   break;
case EXT4_UA_FREEZE:
ret = add_uevent_var(env, "FS_ACTION=%s", "FREEZE");
break;
@@ -576,6 +579,9 @@ static void ext4_handle_error(struct super_block *sb)
if (!test_opt(sb, ERRORS_CONT)) {
journal_t *journal = EXT4_SB(sb)->s_journal;
 
+   if (!xchg(_SB(sb)->s_abrt_event_sent, 1))
+   ext4_send_uevent(sb, EXT4_UA_ABORT);
+
EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED;
if (journal)
jbd2_journal_abort(journal, -EIO);
@@ -801,6 +807,10 @@ void __ext4_abort(struct super_block *sb, const char 
*function,
 
if (sb_rdonly(sb) == 0) {
ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
+
+   if (!xchg(_SB(sb)->s_abrt_event_sent, 1))
+   ext4_send_uevent(sb, EXT4_UA_ABORT);
+
EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED;
/*
 * Make sure updated value of ->s_mount_flags will be visible
-- 
2.26.2

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH vz8 1/2] ext4: add generic uevent infrastructure

2020-11-05 Thread Andrey Ryabinin
From: Dmitry Monakhov 

*Purpose:
It is reasonable to annaunce fs related events via uevent infrastructure.
This patch implement only ext4'th part, but IMHO this should be usefull for
any generic filesystem.

Example: Runtime fs-error is pure async event. Currently there is no good
way to handle this situation and inform user-space about this.

*Implementation:
 Add uevent infrastructure similar to dm uevent
 FS_ACTION = {MOUNT|UMOUNT|REMOUNT|ERROR|FREEZE|UNFREEZE}
 FS_UUID
 FS_NAME
 FS_TYPE

Signed-off-by: Dmitry Monakhov 

[aryabinin: add error event, rh8 rebase]
Signed-off-by: Andrey Ryabinin 
---
 fs/ext4/ext4.h  |  11 +
 fs/ext4/super.c | 128 +++-
 2 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 028832d858fc..228492c9518f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1498,6 +1498,8 @@ struct ext4_sb_info {
/* Precomputed FS UUID checksum for seeding other checksums */
__u32 s_csum_seed;
 
+   bool s_err_event_sent;
+
/* Reclaim extents from extent status tree */
struct shrinker s_es_shrinker;
struct list_head s_es_list; /* List of inodes with reclaimable 
extents */
@@ -3119,6 +3121,15 @@ extern int ext4_check_blockref(const char *, unsigned 
int,
 struct ext4_ext_path;
 struct ext4_extent;
 
+enum ext4_event_type {
+ EXT4_UA_MOUNT,
+ EXT4_UA_UMOUNT,
+ EXT4_UA_REMOUNT,
+ EXT4_UA_ERROR,
+ EXT4_UA_FREEZE,
+ EXT4_UA_UNFREEZE,
+};
+
 /*
  * Maximum number of logical blocks in a file; ext4_extent's ee_block is
  * __le32.
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7fc5ad243953..3cc979825ec8 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -354,6 +354,117 @@ static time64_t __ext4_get_tstamp(__le32 *lo, __u8 *hi)
 #define ext4_get_tstamp(es, tstamp) \
__ext4_get_tstamp(&(es)->tstamp, &(es)->tstamp ## _hi)
 
+static int ext4_uuid_valid(const u8 *uuid)
+{
+   int i;
+
+   for (i = 0; i < 16; i++) {
+   if (uuid[i])
+   return 1;
+   }
+   return 0;
+}
+
+struct ext4_uevent {
+   struct super_block *sb;
+   enum ext4_event_type action;
+   struct work_struct work;
+};
+
+/**
+ * ext4_send_uevent - prepare and send uevent
+ *
+ * @sb:super_block
+ * @action:action type
+ *
+ */
+static void ext4_send_uevent_work(struct work_struct *w)
+{
+   struct ext4_uevent *e = container_of(w, struct ext4_uevent, work);
+   struct super_block *sb = e->sb;
+   struct kobj_uevent_env *env;
+   const u8 *uuid = EXT4_SB(sb)->s_es->s_uuid;
+   enum kobject_action kaction = KOBJ_CHANGE;
+   int ret;
+
+   env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
+   if (!env){
+   kfree(e);
+   return;
+   }
+   ret = add_uevent_var(env, "FS_TYPE=%s", sb->s_type->name);
+   if (ret)
+   goto out;
+   ret = add_uevent_var(env, "FS_NAME=%s", sb->s_id);
+   if (ret)
+   goto out;
+
+   if (ext4_uuid_valid(uuid)) {
+   ret = add_uevent_var(env, "UUID=%pUB", uuid);
+   if (ret)
+   goto out;
+   }
+
+   switch (e->action) {
+   case EXT4_UA_MOUNT:
+   kaction = KOBJ_ONLINE;
+   ret = add_uevent_var(env, "FS_ACTION=%s", "MOUNT");
+   break;
+   case EXT4_UA_UMOUNT:
+   kaction = KOBJ_OFFLINE;
+   ret = add_uevent_var(env, "FS_ACTION=%s", "UMOUNT");
+   break;
+   case EXT4_UA_REMOUNT:
+   ret = add_uevent_var(env, "FS_ACTION=%s", "REMOUNT");
+   break;
+   case EXT4_UA_ERROR:
+   ret = add_uevent_var(env, "FS_ACTION=%s", "ERROR");
+   break;
+   case EXT4_UA_FREEZE:
+   ret = add_uevent_var(env, "FS_ACTION=%s", "FREEZE");
+   break;
+   case EXT4_UA_UNFREEZE:
+   ret = add_uevent_var(env, "FS_ACTION=%s", "UNFREEZE");
+   break;
+   default:
+   ret = -EINVAL;
+   }
+   if (ret)
+   goto out;
+   ret = kobject_uevent_env(&(EXT4_SB(sb)->s_kobj), kaction, env->envp);
+out:
+   kfree(env);
+   kfree(e);
+}
+
+/**
+ * ext4_send_uevent - prepare and schedule event submission
+ *
+ * @sb:super_block
+ * @action:action type
+ *
+ */
+void ext4_send_uevent(struct super_block *sb, enum ext4_event_type action)
+{
+   struct ext4_uevent *e;
+
+   /*
+* May happen if called from ext4_put_super() -> __ext4_abort()
+* -> ext4_send_uevent()
+*/
+   if (!EXT4_SB(sb)->rsv_conversion_wq)
+   return;
+
+   e = kzalloc(sizeof(*e), GFP_NOIO);
+   if (!e)
+   return;
+
+   e->sb = sb;
+   e->action = action;
+   INIT_WORK(>work, ext4_send_uevent_work);
+   

Re: [Devel] [PATCH rh7] ve/net/core: allow to call setsockopt(SO_RCVBUFFORCE) from Containers

2020-11-05 Thread Konstantin Khorenko

On 11/05/2020 06:20 PM, Konstantin Khorenko wrote:

"nft" util (in CentOS 8 environment) does use setsockopt(SO_RCVBUFFORCE)
unconditionally, so we have to allow it from inside a Container.

At the same time we don't want to allow a Container to set too much
memory for a socket, so just threat SO_RCVBUFFORCE like SO_RCVBUF if
called inside a Container.

Simple rule to test:

  # NFT=/usr/sbin/nft ./run-tests.sh -v -g testcases/nft-f/0011manydefines_0

which fails inside a Container because of not enough rcb buffer because
of failed
  setsockopt(3, SOL_SOCKET, SO_RCVBUFFORCE, [10561584], 4) = -1
  EPERM (Operation not permitted)


https://jira.sw.ru/browse/PSBM-121791


Signed-off-by: Konstantin Khorenko 
---
 net/core/sock.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/core/sock.c b/net/core/sock.c
index 07ea42f976cf..44e91c8c0f0a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -793,6 +793,7 @@ int sock_setsockopt(struct socket *sock, int level, int 
optname,
goto set_sndbuf;

case SO_RCVBUF:
+unpriv_rcvbuf:
/* Don't error on this BSD doesn't and if you think
 * about it this is right. Otherwise apps have to
 * play 'guess the biggest size' games. RCVBUF/SNDBUF
@@ -824,11 +825,15 @@ int sock_setsockopt(struct socket *sock, int level, int 
optname,
break;

case SO_RCVBUFFORCE:
-   if (!capable(CAP_NET_ADMIN)) {
+   if (!ve_capable(CAP_NET_ADMIN)) {
ret = -EPERM;
break;
}

+   /* nft utility uses this sockopt in CentOS 8 env */
+   if (!ve_is_super(get_exec_env()))
+   goto unpriv_rcvbuf;
+
/* No negative values (to prevent underflow, as val will be
 * multiplied by 2).
 */


___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel


[Devel] [PATCH rh7] ve/net/core: allow to call setsockopt(SO_RCVBUFFORCE) from Containers

2020-11-05 Thread Konstantin Khorenko
"nft" util (in CentOS 8 environment) does use setsockopt(SO_RCVBUFFORCE)
unconditionally, so we have to allow it from inside a Container.

At the same time we don't want to allow a Container to set too much
memory for a socket, so just threat SO_RCVBUFFORCE like SO_RCVBUF if
called inside a Container.

Simple rule to test:

  # NFT=/usr/sbin/nft ./run-tests.sh -v -g testcases/nft-f/0011manydefines_0

which fails inside a Container because of not enough rcb buffer because
of failed
  setsockopt(3, SOL_SOCKET, SO_RCVBUFFORCE, [10561584], 4) = -1
  EPERM (Operation not permitted)

Signed-off-by: Konstantin Khorenko 
---
 net/core/sock.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/core/sock.c b/net/core/sock.c
index 07ea42f976cf..44e91c8c0f0a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -793,6 +793,7 @@ int sock_setsockopt(struct socket *sock, int level, int 
optname,
goto set_sndbuf;
 
case SO_RCVBUF:
+unpriv_rcvbuf:
/* Don't error on this BSD doesn't and if you think
 * about it this is right. Otherwise apps have to
 * play 'guess the biggest size' games. RCVBUF/SNDBUF
@@ -824,11 +825,15 @@ int sock_setsockopt(struct socket *sock, int level, int 
optname,
break;
 
case SO_RCVBUFFORCE:
-   if (!capable(CAP_NET_ADMIN)) {
+   if (!ve_capable(CAP_NET_ADMIN)) {
ret = -EPERM;
break;
}
 
+   /* nft utility uses this sockopt in CentOS 8 env */
+   if (!ve_is_super(get_exec_env()))
+   goto unpriv_rcvbuf;
+
/* No negative values (to prevent underflow, as val will be
 * multiplied by 2).
 */
-- 
2.24.3

___
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel