tmpfs: support user quotas
Subsystems (5)
RFC PATCH 1/1 tmpfs: support user quotas
From: Davidlohr Bueso <[email protected]>
This patch adds a new RLIMIT_TMPFSQUOTA resource limit to restrict an individual user's quota across all mounted tmpfs filesystems. It's well known that a user can easily fill up commonly used directories (like /tmp, /dev/shm) causing programs to break through DoS.
By default the soft and hard limits are set the RLIM_INFINITY, thus maintaining the current functionality and allowing the user to populate the fs all he wants.
This is one of the features requested in the Plumbers wishlist (http://0pointer.de/blog/projects/plumbers-wishlist-2.html).
---
This is my first patch in these waters, so if I'm doing anything terrible wrong here please bare with me.
fs/proc/base.c | 1 + include/asm-generic/resource.h | 4 +++- include/linux/sched.h | 3 +++ mm/shmem.c | 14 ++++++++++++-- 4 files changed, 19 insertions(+), 3 deletions(-)
fs/proc/base.c +1 -0
@@ -511,6 +511,7 @@ static const struct limit_names lnames[RLIM_NLIMITS] = { [RLIMIT_NICE] = {"Max nice priority", NULL}, [RLIMIT_RTPRIO] = {"Max realtime priority", NULL}, [RLIMIT_RTTIME] = {"Max realtime timeout", "us"}, + [RLIMIT_TMPFSQUOTA] = {"Max tmpfs user quota", "bytes"}, };/* Display limits for a process */
include/asm-generic/resource.h +3 -1
@@ -45,7 +45,8 @@0-39 for nice level 19 .. -20 */ #define RLIMIT_RTPRIO 14/* maximum realtime priority */ #define RLIMIT_RTTIME 15/* timeout for RT tasks in us */ -#define RLIM_NLIMITS 16 +#define RLIMIT_TMPFSQUOTA 16/* maximum bytes for tmpfs quota */ +#define RLIM_NLIMITS 17/* * SuS says limits have to be unsigned.
@@ -87,6 +88,7 @@ [RLIMIT_NICE] = { 0, 0 }, \ [RLIMIT_RTPRIO] = { 0, 0 }, \ [RLIMIT_RTTIME] = { RLIM_INFINITY, RLIM_INFINITY }, \ + [RLIMIT_TMPFSQUOTA] = { RLIM_INFINITY, RLIM_INFINITY }, \ } #endif /* __KERNEL__ */
include/linux/sched.h +3 -0
@@ -703,6 +703,9 @@ struct user_struct {/* protected by mq_lock */ unsigned long mq_bytes;/* How many bytes can be allocated to mqueue? */ #endif +#ifdef CONFIG_TMPFS +atomic_long_t shmem_bytes; +#endif unsigned long locked_shm;/* How many pages of mlocked shm ? */ #ifdef CONFIG_KEYS
mm/shmem.c +12 -2
@@ -1159,7 +1159,12 @@ shmem_write_begin(struct file *file, struct address_space *mapping, struct page **pagep, void **fsdata) { struct inode *inode = mapping->host; +struct user_struct *user=current_user ();pgoff_t index = pos >>PAGE_CACHE_SHIFT ; + +if (atomic_long_read (&user->shmem_bytes) + len > +rlimit (RLIMIT_TMPFSQUOTA )) +return -ENOSPC ;return shmem_getpage (inode, index, pagep,SGP_WRITE ,NULL ); }
@@ -1169,10 +1174,12 @@ shmem_write_end(struct file *file, struct address_space *mapping, struct page *page, void *fsdata) { struct inode *inode = mapping->host; +struct user_struct *user=current_user (); -if (pos + copied > inode->i_size) +if (pos + copied > inode->i_size) {i_size_write (inode, pos + copied); - +atomic_long_add (copied, &user->shmem_bytes); + }set_page_dirty (page);unlock_page (page);page_cache_release (page);
@@ -1535,12 +1542,15 @@ out:static int shmem_unlink (struct inode *dir,struct dentry *dentry) {struct inode *inode = dentry->d_inode; +struct user_struct *user =current_user ();if (inode->i_nlink >1 && !S_ISDIR (inode->i_mode))shmem_free_inode (inode->i_sb); dir->i_size -=BOGO_DIRENT_SIZE ; inode->i_ctime = dir->i_ctime = dir->i_mtime =CURRENT_TIME ; +atomic_long_sub (inode->i_size, &user->shmem_bytes); +drop_nlink (inode);dput (dentry);/* Undo the count from "create" - this does all the work */ return 0 ;
Signature · 10 lines
1.7.4.1 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 4 lines · Davidlohr Bueso
From: Davidlohr Bueso <[email protected]>
This patch adds a new
RLIMIT_TMPFSQUOTAresource limit to restrict an individual user's quota across all mounted tmpfs filesystems. It's well known that a user can easily fill up commonly used directories (like /tmp,/dev/shm) causing programs to break through DoS.
Thanks a lot for this work! One comment without looking at the patch in detail:
mm/shmem.c shmem_write_begin(struct file *file, struct address_space *mapping, · line 1167
Quoted 3 lines
mm/shmem.c +3
-0+if (atomic_long_read (&user->shmem_bytes) + len > +rlimit (RLIMIT_TMPFSQUOTA )) +return -ENOSPC ;
This should be EDQUOT "Disk quota exceeded", not ENOSPC "No space left on device".
Lennart
Signature · 8 lines
Lennart Poettering - Red Hat, Inc. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 4 lines · Davidlohr Bueso
From: Davidlohr Bueso <[email protected]>
This patch adds a new
RLIMIT_TMPFSQUOTAresource limit to restrict an individual user's quota across all mounted tmpfs filesystems. It's well known that a user can easily fill up commonly used directories (like /tmp,/dev/shm) causing programs to break through DoS.
Please jyst implement the normal user/group quota interfaces we use for other filesystem.
Quoted 9 lines · Christoph Hellwig
Quoted 4 lines · Davidlohr Bueso
From: Davidlohr Bueso <[email protected]>
This patch adds a new
RLIMIT_TMPFSQUOTAresource limit to restrict an individual user's quota across all mounted tmpfs filesystems. It's well known that a user can easily fill up commonly used directories (like /tmp,/dev/shm) causing programs to break through DoS.Please jyst implement the normal user/group quota interfaces we use for other filesystem.
Please don't.
tmpfs by its very nature is volatile, which means that we'd have to upload the quota data explicitly each time we mount a tmpfs, which means we'd have to add quite some userspace infrastructure to make tmpfs work with quota. Either every time a tmpfs is mounted we'd have to apply a quota for every configured user and every future user to it (which is simply not realistic) or on every user logging in we'd have to go through all tmpfs mount points and apply a user-specific quota setting to it -- which isn't much less ugly and complex. Just using a user-specific RLIMIT is much much simpler and beautiful there, and requires almost no changes to userspace.
On top of that I think a global quota over all tmpfs is actually preferable than a per-tmpfs quota, because what you want to enforce is that clients cannot drain the pool that tmpfs is backed from but how they distribute their share of that pool on the various tmpfs mounted doesn't really matter in order to avoid DoS vulnerabilities.
In short: a resource limit for tmpfs quota looks like the best solution here, which does exactly what userspace wants.
Lennart
--
Lennart Poettering - Red Hat, Inc.
Quoted 25 lines · Lennart Poettering
Quoted 9 lines · Christoph Hellwig
Quoted 4 lines · Davidlohr Bueso
From: Davidlohr Bueso <[email protected]>
This patch adds a new
RLIMIT_TMPFSQUOTAresource limit to restrict an individual user's quota across all mounted tmpfs filesystems. It's well known that a user can easily fill up commonly used directories (like /tmp,/dev/shm) causing programs to break through DoS.Please jyst implement the normal user/group quota interfaces we use for other filesystem.
Please don't.
tmpfs by its very nature is volatile, which means that we'd have to upload the quota data explicitly each time we mount a tmpfs, which means we'd have to add quite some userspace infrastructure to make tmpfs work with quota. Either every time a tmpfs is mounted we'd have to apply a quota for every configured user and every future user to it (which is simply not realistic) or on every user logging in we'd have to go through all tmpfs mount points and apply a user-specific quota setting to it -- which isn't much less ugly and complex. Just using a user-specific RLIMIT is much much simpler and beautiful there, and requires almost no changes to userspace.
Quoted 5 lines
On top of that I think a global quota over all tmpfs is actually preferable than a per-tmpfs quota, because what you want to enforce is that clients cannot drain the pool that tmpfs is backed from but how they distribute their share of that pool on the various tmpfs mounted doesn't really matter in order to avoid DoS vulnerabilities.
Right, rlimit approach guarantees a simple way of dealing with users across all tmpfs instances.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 2 lines
Right, rlimit approach guarantees a simple way of dealing with users across all tmpfs instances.
Which is almost certainly not what you want to happen. Think about direct rendering.
For simple stuff tmpfs already supports size/nr_blocks/nr_inodes mount options so you can mount private resource constrained tmpfs objects already without kernel changes. No rlimit hacks needed - and rlimit is the wrong API anyway.
Alan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 10 lines · Alan Cox
Quoted 2 lines
Right, rlimit approach guarantees a simple way of dealing with users across all tmpfs instances.
Which is almost certainly not what you want to happen. Think about direct rendering.
For simple stuff tmpfs already supports size/nr_blocks/nr_inodes mount options so you can mount private resource constrained tmpfs objects already without kernel changes. No rlimit hacks needed - and rlimit is the wrong API anyway.
What part of the message did you read? This is about _per_user_ limits, not global limits!
Any untrusted user can fill /dev/shm today and DOS many services that way on any machine out there. Same for /tmp when it's a tmpfs, or /run/user. This is an absolutely unacceptable state and needs fixing.
I don't care about which interface it is, if someting else fits better, let's discuss that, but it has surely absolutely noting to do with size/nr_blocks/nr_inodes.
Kay
Quoted 2 lines
What part of the message did you read? This is about _per_user_ limits, not global limits!
What part of 'we support lots of mounts' don't you understand. Or perhaps you could go use a control group for it ?
Quoted 3 lines
Any untrusted user can fill
/dev/shmtoday and DOS many services that way on any machine out there. Same for /tmp when it's a tmpfs, or/run/user. This is an absolutely unacceptable state and needs fixing.
Actually if you've mounted it with limits they can be a nuisance but little more, and if you are running with memory overcommit disabled then its accounted for in that. If you are running with memory over commit allowed (as eg Red Hat and Fedora do) you are peeing into the wind at this point anyway so wasting time.
Quoted 3 lines
I don't care about which interface it is, if someting else fits better, let's discuss that, but it has surely absolutely noting to do with size/nr_blocks/nr_inodes.
Per user would be quota, per process would be rlimit. Quite simple really, nice standard interfaces we've had for years. Various systems have been quotaing /tmp/ for a long time. Smart secure ones of course mount a per user /tmp via PAM or similar to avoid /tmp attacks and in that case the mount options I pointed out already do the job.
Quota isn't entirely trivial because you want your quota db initialised at mount so you'd need to pass a quota file pointer to the mount command ideally. All doable however and makes the management easy and means you get all the application expected behaviour when you exceed your limits (that is for properly written stuff - lots of crappy badly written desktop programs randomly crash or worse as we already know)
This is why I'm confused - you are wittering about all sorts of security stuff but you are not addressing the more serious matters first - the ones that go beyond a DoS.
Alan
Quoted 5 lines · Alan Cox
Quoted 2 lines
What part of the message did you read? This is about _per_user_ limits, not global limits!
What part of 'we support lots of mounts' don't you understand. Or perhaps you could go use a control group for it ?
We are trying to implement an indirect limit on slab objects in the memory controller.
Our specific use case is to control the number of dentries currently pinned in some given physical filesystem. If you can't allocate a dentry from the dentry cache, you can also not DoS a system - in our case, a container.
Maybe this will also solve your problems?
Quoted 31 lines
Quoted 3 lines
Any untrusted user can fill
/dev/shmtoday and DOS many services that way on any machine out there. Same for /tmp when it's a tmpfs, or/run/user. This is an absolutely unacceptable state and needs fixing.Actually if you've mounted it with limits they can be a nuisance but little more, and if you are running with memory overcommit disabled then its accounted for in that. If you are running with memory over commit allowed (as eg Red Hat and Fedora do) you are peeing into the wind at this point anyway so wasting time.
Quoted 3 lines
I don't care about which interface it is, if someting else fits better, let's discuss that, but it has surely absolutely noting to do with size/nr_blocks/nr_inodes.
Per user would be quota, per process would be rlimit. Quite simple really, nice standard interfaces we've had for years. Various systems have been quotaing
/tmp/for a long time. Smart secure ones of course mount a per user /tmp via PAM or similar to avoid /tmp attacks and in that case the mount options I pointed out already do the job.Quota isn't entirely trivial because you want your quota db initialised at mount so you'd need to pass a quota file pointer to the mount command ideally. All doable however and makes the management easy and means you get all the application expected behaviour when you exceed your limits (that is for properly written stuff - lots of crappy badly written desktop programs randomly crash or worse as we already know)
This is why I'm confused - you are wittering about all sorts of security stuff but you are not addressing the more serious matters first - the ones that go beyond a DoS.
Quoted 8 lines
Alan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email:<a href=mailto:"[email protected]"> [email protected]</a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 2 lines · Alan Cox
Per user would be quota, per process would be rlimit. Quite simple really, nice standard interfaces we've had for years. Various systems
Uh, have you ever really looked at resource limits? Some of them are per-user, not per-process, i.e. RLIMIT_NPROC. And this would just be another one.
Lennart
Signature · 8 lines
Lennart Poettering - Red Hat, Inc. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 8 lines · On Tue, 8 Nov 2011 00:07:12 +0100 Lennart Poettering <[email protected]>…
Quoted 2 lines · Alan Cox
Per user would be quota, per process would be rlimit. Quite simple really, nice standard interfaces we've had for years. Various systems
Uh, have you ever really looked at resource limits? Some of them are per-user, not per-process, i.e.
RLIMIT_NPROC. And this would just be another one.
NPROC is a bit of an oddity.
And the standards have no idea how a resource limit hit for an fs would be reported, nor how an app installer would check for it. Quota on the other hand is defined behaviour.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 6 lines · Alan Cox
Quoted 2 lines · On Tue, 8 Nov 2011 00:07:12 +0100 Lennart Poettering <[email protected]>…
On Mon, 07.11.11 22:53, Alan Cox ([email protected]) wrote:
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
Per user would be quota, per process would be rlimit. Quite simple really, nice standard interfaces we've had for years. Various systems
Uh, have you ever really looked at resource limits? Some of them are per-user, not per-process, i.e.
RLIMIT_NPROC. And this would just be another one.NPROC is a bit of an oddity.
And half of the other resource limits are "oddities" too? For example RLIMIT_SIGPENDING is per-user and so is RLIMIT_MSGQUEUE, and others too.
Quoted 3 lines
And the standards have no idea how a resource limit hit for an fs would be reported, nor how an app installer would check for it. Quota on the other hand is defined behaviour.
EDQUOT is POSIX, but afaik there is no POSIX standardized API for quota, is there? i.e. the reporting of the user hitting quota is defined, but how to set the quota is left open. Which is nice, since it gives us the flexibility to use resource limits here, since they so nicely apply to the problem.
Lennart
Signature · 1 line
Lennart Poettering - Red Hat, Inc.
Quoted 3 lines
And half of the other resource limits are "oddities" too? For example
RLIMIT_SIGPENDINGis per-user and so isRLIMIT_MSGQUEUE, and others too.
When you look at the standards - yes.
Quoted 6 lines
Quoted 3 lines
And the standards have no idea how a resource limit hit for an fs would be reported, nor how an app installer would check for it. Quota on the other hand is defined behaviour.
EDQUOT is POSIX, but afaik there is no POSIX standardized API for quota, is there? i.e. the reporting of the user hitting quota is defined, but
Its part of Unix and its well defined and used by applications, both for hitting quota (the easy bit), checking quota (when checking space for things particularly), and manipulating them
The latter bit is nice, it means you can mount with a user quota set in the mount options, and if you want then use quota tools to change the quota of a specific user or two that have special rules.
Alan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 6 lines · Alan Cox
Quoted 3 lines
Right, rlimit approach guarantees a simple way of dealing with users across all tmpfs instances.
Which is almost certainly not what you want to happen. Think about direct rendering.
I don't see what direct rendering has to do with closing the security hole that /dev/shm currently is.
Quoted 4 lines
For simple stuff tmpfs already supports size/nr_blocks/nr_inodes mount options so you can mount private resource constrained tmpfs objects already without kernel changes. No rlimit hacks needed - and rlimit is the wrong API anyway.
Uh? I am pretty sure we don't want to mount a private tmpfs for each user in /dev/shm and /tmp. If you have 500 users you'd have 500 tmpfs on /tmp and on /dev/shm. Despite that without some ugly namespace hackery you couldn't make them all appear in /tmp as /dev/shm without subdirectories. Don't forget that /dev/shm and /tmp are an established userspace API.
Resource limits are exactly the API that makes sense here, because:
a) we only want one tmpfs on /tmp, and one tmpfs on /dev/shm, not 500 on each for each user
b) we cannot move /dev/shm, /tmp around without breaking userspace massively
c) we want a global limit across all tmpfs file systems for each user
d) we don't want to have to upload the quota database into each tmpfs at mount time.
And hence: a per user RLIMIT is exactly the minimal solution we want here.
Lennart
Signature · 8 lines
Lennart Poettering - Red Hat, Inc. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 24 lines · Lennart Poettering
Quoted 6 lines · Alan Cox
Quoted 3 lines
Right, rlimit approach guarantees a simple way of dealing with users across all tmpfs instances.
Which is almost certainly not what you want to happen. Think about direct rendering.
I don't see what direct rendering has to do with closing the security hole that
/dev/shmcurrently is.Quoted 4 lines
For simple stuff tmpfs already supports size/nr_blocks/nr_inodes mount options so you can mount private resource constrained tmpfs objects already without kernel changes. No rlimit hacks needed - and rlimit is the wrong API anyway.
Uh? I am pretty sure we don't want to mount a private tmpfs for each user in
/dev/shmand /tmp. If you have 500 users you'd have 500 tmpfs on /tmp and on/dev/shm. Despite that without some ugly namespace hackery you couldn't make them all appear in /tmp as/dev/shmwithout subdirectories. Don't forget that/dev/shmand /tmp are an established userspace API.
Quoted 4 lines
Resource limits are exactly the API that makes sense here, because:
a) we only want one tmpfs on /tmp, and one tmpfs on
/dev/shm, not 500 on each for each user
Ok, seems fair.
Quoted 2 lines
b) we cannot move
/dev/shm, /tmp around without breaking userspace massively
agreed.
Quoted 2 lines
c) we want a global limit across all tmpfs file systems for each user
Why? Is there any benefit this?
Quoted 5 lines
d) we don't want to have to upload the quota database into each tmpfs at mount time.
And hence: a per user RLIMIT is exactly the minimal solution we want here.
If you want per-user limitation, RLIMIT is bad idea. RLIMIT is only inherited by fork. So, The api semantics clearly mismatch your usecase.
Instead, I suggest to implement new sysfs knob.
Thank you.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 4 lines · KOSAKI Motohiro
(11/7/2011 6:30 AM), Lennart Poettering wrote:
If you want per-user limitation, RLIMIT is bad idea. RLIMIT is only inherited by fork. So, The api semantics clearly mismatch your usecase.
Like RLIMIT_NPROC?
Quoted 1 line
Instead, I suggest to implement new sysfs knob.
Where would users show up in sysfs?
Kay
Quoted 8 lines · Kay Sievers
Quoted 4 lines · KOSAKI Motohiro
(11/7/2011 6:30 AM), Lennart Poettering wrote:
If you want per-user limitation, RLIMIT is bad idea. RLIMIT is only inherited by fork. So, The api semantics clearly mismatch your usecase.
Like
RLIMIT_NPROC?
I suggest to don't follow useless interfaces.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 5 lines
Quoted 2 lines
Which is almost certainly not what you want to happen. Think about direct rendering.
I don't see what direct rendering has to do with closing the security hole that
/dev/shmcurrently is.
Direct render objects (like shared memory objects) are backed by shmfs, so if you impose random limits on the shmfs you'll get weird graphics happenings. You use a *lot* of shmfs objects when you are running 3D gaming, enormous amounts for all your textures and the like.
The DRM case means you can't set tight limits on shmfs and expect to play Warcraft.
Quoted 2 lines
Uh? I am pretty sure we don't want to mount a private tmpfs for each user in
/dev/shmand /tmp. If you have 500 users you'd have 500 tmpfs on
Oh I do. That would actually do something abut temporary file handling which is a much much bigger issue than a DoS when people get it wrong. It's a bit of Unix history that wants sorting out more than /usr and /bin...
Quoted 1 line
/tmp and on
/dev/shm. Despite that without some ugly namespace hackery
Only if they were all logged in
Quoted 3 lines
you couldn't make them all appear in /tmp as
/dev/shmwithout subdirectories. Don't forget that/dev/shmand /tmp are an established userspace API.
Don't forget there have been pam modules for doing per user /tmp/ for years and years.
Quoted 1 line
Resource limits are exactly the API that makes sense here, because:
No because they are inherited process things and the exhaustion behaviour is not standards defined. Christoph is right that this should be implemnted via quota.
It might well be that your quota implementation is handled by a mount option (sysfs just makes it more complex) and that
mount blah -oquotaallusers=16G
is how you set it up, but doing it via quota interfaces makes all sorts of crap just work including warning users about quota limits.
Alan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
mm/shmem.c shmem_write_begin(struct file *file, struct address_space *mapping, · line 1163
Quoted 6 lines · Davidlohr Bueso
mm/shmem.c +3
-0@@ -1159,7 +1159,12 @@ shmem_write_begin(struct file *file, struct address_space *mapping, struct page **pagep, void **fsdata) + if (atomic_long_read(&user->shmem_bytes) + len > + rlimit(RLIMIT_TMPFSQUOTA)) + return -ENOSPC;
Is this a per-process or per-user limit? If it's per-process, it doesn't really do much good, because a user can use multiple processes to over-run the limit (either intentionally or accidentally).
mm/shmem.c shmem_write_end(struct file *file, struct address_space *mapping, · line 1179
Quoted 7 lines
mm/shmem.c +3
-0@@ -1169,10 +1174,12 @@ shmem_write_end(struct file *file, struct address_space *mapping, struct page *page, void *fsdata) +if (pos + copied > inode->i_size) {i_size_write (inode, pos + copied); +atomic_long_add (copied, &user->shmem_bytes); + }
If this is per-user, it's racy with shmem_write_begin() - two processes can hit the write_begin(), be under quota by (say) 1M, but by the time they both complete the user is 1M over the quota.
mm/shmem.c out: · line 1552
Quoted 3 lines
mm/shmem.c +2
-0@@ -1535,12 +1542,15 @@ static int shmem_unlink(struct inode *dir, struct dentry *dentry) + struct user_struct *user = current_user(); +atomic_long_sub (inode->i_size, &user->shmem_bytes);
What happens here if user 'fred' creates a file on a tmpfs, and then logs out so he has no processes running, and then root does a 'find tmpfs -user fred -exec rm {} \;' to clean up? We just decremented root's quota, not fred's....
Quoted 5 lines · On Mon, 2011-11-07 at 04:11 -0500, [email protected] wrote:
Quoted 2 lines · Davidlohr Bueso
mm/shmem.c +0
-0@@ -1159,7 +1159,12 @@ shmem_write_begin(struct file *file, struct address_space *mapping, struct page **pagep, void **fsdata)
Quoted 7 lines
mm/shmem.c shmem_write_begin(struct file *file, struct address_space *mapping, · line 1167
Quoted 3 lines
mm/shmem.c +3
-0+if (atomic_long_read (&user->shmem_bytes) + len > +rlimit (RLIMIT_TMPFSQUOTA )) +return -ENOSPC ;Is this a per-process or per-user limit? If it's per-process, it doesn't really do much good, because a user can use multiple processes to over-run the limit (either intentionally or accidentally).
This is a per-user limit.
Quoted 4 lines
Quoted 3 lines
mm/shmem.c +0
-0@@ -1169,10 +1174,12 @@ shmem_write_end(struct file *file, struct address_space *mapping, struct page *page, void *fsdata)
Quoted 8 lines
mm/shmem.c shmem_write_end(struct file *file, struct address_space *mapping, · line 1182
Quoted 4 lines
mm/shmem.c +3
-0+if (pos + copied > inode->i_size) {i_size_write (inode, pos + copied); +atomic_long_add (copied, &user->shmem_bytes); + }If this is per-user, it's racy with
shmem_write_begin()- two processes can hit thewrite_begin(), be under quota by (say) 1M, but by the time they both complete the user is 1M over the quota.
I guess using a spinlock instead of atomic operations would serve the purpose.
Quoted 8 lines
mm/shmem.c out: · line 1552
Quoted 3 lines
mm/shmem.c +2
-0@@ -1535,12 +1542,15 @@ static int shmem_unlink(struct inode *dir, struct dentry *dentry) + struct user_struct *user = current_user(); +atomic_long_sub (inode->i_size, &user->shmem_bytes);What happens here if user 'fred' creates a file on a tmpfs, and then logs out so he has no processes running, and then root does a 'find tmpfs -user fred -exec rm {} \;' to clean up? We just decremented root's quota, not fred's....
Would the same would occur with mqueues? I haven't tested it but I don't see anywhere that user->mq_bytes is decreased like this.
Thanks,
Davidlohr
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>