Linux-Development-Sys Digest #742, Volume #8 Wed, 23 May 01 04:13:11 EDT
Contents:
Re: How i sleep a thread, and doesn't block another thread? ("Arthur H. Gold")
Re: wildcard [1-10] (Kasper Dupont)
Newbie question about Linux Devie Driver Application ("nickwang")
Re: How to find system and user memory used? (Kasper Dupont)
Re: Kernel (mal)function after harmless driver Segmenttion Error (Kasper Dupont)
Tmpfs in 2.4.4 (Kasper Dupont)
Re: Newbie question about Linux Devie Driver Application (Kasper Dupont)
Re: Newbie question about Linux Devie Driver Application (=?iso-8859-1?Q?Andr=E9?=
David)
Re: Kernel memory maps --- what are the limits? (Kasper Dupont)
----------------------------------------------------------------------------
Date: Wed, 23 May 2001 00:35:35 -0500
From: "Arthur H. Gold" <[EMAIL PROTECTED]>
Subject: Re: How i sleep a thread, and doesn't block another thread?
"Nils O. Sel=E5sdal" wrote:
> =
> "killerlife" <[EMAIL PROTECTED]> wrote in message
> news:9ed9j4$3nk$[EMAIL PROTECTED]...
> > How i sleep a thread, and doesn't block another thread?
> > Who can tell me where are i can find the document for pthread?
> Is there a reason why sleep(.) usleep(.) shouldnt work?
Actually you should probably use nanosleep() instead, as it doesn't
interfere with signals.
The pthread documentation is part of the info pages for glibc (`info
libc') under Add-ons -> POSIX Threads.
HTH,
--ag
-- =
Artie Gold, Austin, TX (finger the cs.utexas.edu account for more info)
mailto:[EMAIL PROTECTED] or mailto:[EMAIL PROTECTED]
--
I am looking for work. Contact me.
------------------------------
From: Kasper Dupont <[EMAIL PROTECTED]>
Subject: Re: wildcard [1-10]
Date: Wed, 23 May 2001 07:15:18 +0000
Ryan Storgaard wrote:
>
> Hi there,
>
> I am writing a script to move and/or delete files/directories and I ran into
> a problem when using a wildcard...
>
> for example,
>
> rm -r -f [1-9] works fine, but I need to remove past 9. And of course, as
> soon as I put [1-10] I run into problems because bash is taking the 10 as
> 1,0 ...
>
> I can work around this but I was just curious if it was possible to do the
> above somehow.
>
> cheers,
>
> Ryan
If you are using bash2 and have the extglob
option enabled you can use @([1-9]|10)
That is the simplest I can come up with.
--
Kasper Dupont
------------------------------
From: "nickwang" <[EMAIL PROTECTED]>
Subject: Newbie question about Linux Devie Driver Application
Date: Wed, 23 May 2001 15:18:24 +0800
HI,all
I've got some questions about Linux application like below:
I wrote a application to use the ioctl(int fd,int cmd) function.
The "fd" parameter is the file handler. I'm not sure about the "cmd"
parameter.
I just "#define LCD_HD44780_CLEAR _IO("I",0X11)",and then use the
"LCD_HD44780_CLEAR"
as "cmd", but error show like this "lcd.c:41 invalid operands to binary <<"
line 41 is where the "ioctl(int fd,LCD_HD44780_CLEAR)"is.
What is the problem?
Thank you!
------------------------------
From: Kasper Dupont <[EMAIL PROTECTED]>
Subject: Re: How to find system and user memory used?
Date: Wed, 23 May 2001 07:19:29 +0000
[EMAIL PROTECTED] wrote:
>
> Thanks for all answers.
>
> If I only want to backup all users' files, not system files,
> I want to know each user's memory of files used and all users'
> memory of files used. What command do I need to use excepting
> gtop, ktop or free? Thanks
>
> Best regards
> Jiying
These might help you:
df -h
du -sh /home/* /home
--
Kasper Dupont
------------------------------
From: Kasper Dupont <[EMAIL PROTECTED]>
Subject: Re: Kernel (mal)function after harmless driver Segmenttion Error
Date: Wed, 23 May 2001 07:24:28 +0000
Norm Dresner wrote:
>
> A few weeks ago I'd noticed that when a new driver I was writing crashed
> with a segmentation error that the system log ceased to function. Several
> readers in this newsgroup pointed out that the failure could have been
> caused by my driver clobbering essential kernel code, and I while I didn't
> agree, I couldn't prove otherwise.
>
> Yesterday, after finally getting the driver working, I intentionally
> introduced a controllable segmentation fault into it via an ioctl-code which
> tried to read from the raw PCI address -- not the ioremap-ed virtual address
> that I know works. That's all it did: read a word from this address into a
> local variable and if successful print it out via printk().
>
> And, exactly as before, after the segmentation fault, the system log was
> inoperative. This time I know that there was no clobbering of kernel code.
> So ... I ask again: Why does the system log either die or hang after any
> segmentation error?
>
> Thanks
> Norm
A segmentation fault in the kernel can lead to
inconsistency in the internal data structures.
Even if you don't change anything there might
be problems because some of the procedure calls
on the stack might have started doing something
that they don't get the chacne to finish.
Unless you know the exact layout of the kernel
stack and how these functions work you will not
be able to tell wether the kernel is left in a
consistent state.
--
Kasper Dupont
------------------------------
From: Kasper Dupont <[EMAIL PROTECTED]>
Subject: Tmpfs in 2.4.4
Date: Wed, 23 May 2001 07:35:37 +0000
This is a multi-part message in MIME format.
==============368192BA7572B1952B36D9E
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
I can see that in 2.4.4 the tmpfs filesystem
is finally starting to be really usefull.
There still are a few things that bothers me:
1) I cannot mount a file on a tmpfs filesystem
throught the loopback device. I know I have
to implement the readpage function to get
this working, but I have no clue about what
to put in this function. Any suggestions?
2) The resouce limits cannot be specified in a
usefull way. It is possible to specify an
upper limit on the number of data pages and
inodes, but it is not possible to specify
that the filesystem has to report ENOSPC
when the system is low on memory. I have
implemented a patch to allow this kind of
resource limits and a few related features.
The patch works fine for me, but it would be
nice having some more people testing it. In
particular I'm worried about potential SMP
problems.
--
Kasper Dupont
==============368192BA7572B1952B36D9E
Content-Type: text/plain; charset=us-ascii; name="tmpfs_limits.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="tmpfs_limits.patch"
diff -urN old/include/linux/shmem_fs.h new/include/linux/shmem_fs.h
--- old/include/linux/shmem_fs.h Wed May 23 07:44:24 2001
+++ new/include/linux/shmem_fs.h Wed May 23 07:45:03 2001
@@ -33,6 +33,13 @@
unsigned long max_inodes; /* How many inodes are allowed */
unsigned long free_inodes; /* How many are left for allocation */
spinlock_t stat_lock;
+
+ /* Improved resource limits */
+ unsigned long reserved_blocks; /* Blocks reserved for root */
+ unsigned long reserved_inodes; /* Inodes reserved for root */
+ unsigned long reserved_mem; /* Memory reserved for rest of system */
+ uid_t reserved_uid; /* User with acces to reserved blocks
+ * and inodes */
};
#endif
diff -urN old/mm/shmem.c new/mm/shmem.c
--- old/mm/shmem.c Wed May 23 07:44:02 2001
+++ new/mm/shmem.c Wed May 23 07:48:38 2001
@@ -14,6 +14,13 @@
* which makes it a completely usable filesystem.
*/
+/*
+ * Improved resource limits.
+ *
+ * Copyright (C) 2001 Kasper Dupont <[EMAIL PROTECTED]>
+ *
+ */
+
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -49,6 +56,34 @@
#define BLOCKS_PER_PAGE (PAGE_SIZE/512)
+/* shmem_sb_sys_free - compute free space in super block and system
+ *
+ * @shmem_sb: Super block to get parameters from
+ *
+ * Compute amount of memory we can be allowed to use, it is the
+ * minimum of two different limits. The first limit is the free
+ * space according to super block. The second limit is the free
+ * memory in system - the reserved memory according to super block.
+ *
+ * Must be called with shmem_sb->stat_lock held.
+ */
+
+static inline unsigned long shmem_sb_sys_free(struct shmem_sb_info * shmem_sb)
+{
+ unsigned long free_mem =
+ nr_free_pages() +
+ nr_swap_pages +
+ atomic_read(&buffermem_pages);
+ unsigned long reserved_mem =
+ shmem_sb->reserved_mem;
+ unsigned long free_blocks =
+ shmem_sb->free_blocks;
+
+ if (free_mem<reserved_mem) return 0;
+ if (free_blocks < free_mem-reserved_mem) return free_blocks;
+ return free_mem-reserved_mem;
+}
+
/*
* shmem_recalc_inode - recalculate the size of an inode
*
@@ -353,12 +388,19 @@
info->swapped--;
spin_unlock (&info->lock);
} else {
+ unsigned long currently_free;
+ struct shmem_sb_info * shmem_sb = &inode->i_sb->u.shmem_sb;
spin_unlock (&info->lock);
- spin_lock (&inode->i_sb->u.shmem_sb.stat_lock);
- if (inode->i_sb->u.shmem_sb.free_blocks == 0)
+ spin_lock (&shmem_sb->stat_lock);
+ currently_free=shmem_sb_sys_free(shmem_sb);
+ if (currently_free == 0)
+ goto no_space;
+ if ((currently_free <= shmem_sb->reserved_blocks)&&
+ (current->fsuid != shmem_sb->reserved_uid)&&
+ (!capable(CAP_SYS_RESOURCE)))
goto no_space;
- inode->i_sb->u.shmem_sb.free_blocks--;
- spin_unlock (&inode->i_sb->u.shmem_sb.stat_lock);
+ shmem_sb->free_blocks--;
+ spin_unlock (&shmem_sb->stat_lock);
/* Ok, get a new page. We don't have to worry about the
* info->lock spinlock here: we cannot race against
@@ -506,6 +548,13 @@
spin_unlock (&sb->u.shmem_sb.stat_lock);
return NULL;
}
+ if ((sb->u.shmem_sb.free_inodes <= sb->u.shmem_sb.reserved_inodes)
+ &&(current->fsuid != sb->u.shmem_sb.reserved_uid)
+ &&(!capable(CAP_SYS_RESOURCE)))
+ {
+ spin_unlock (&sb->u.shmem_sb.stat_lock);
+ return NULL;
+ }
sb->u.shmem_sb.free_inodes--;
spin_unlock (&sb->u.shmem_sb.stat_lock);
@@ -758,21 +807,22 @@
static int shmem_statfs(struct super_block *sb, struct statfs *buf)
{
+ struct shmem_sb_info *info = &sb->u.shmem_sb;
buf->f_type = TMPFS_MAGIC;
buf->f_bsize = PAGE_CACHE_SIZE;
- spin_lock (&sb->u.shmem_sb.stat_lock);
- if (sb->u.shmem_sb.max_blocks == ULONG_MAX) {
- /*
- * This is only a guestimate and not honoured.
- * We need it to make some programs happy which like to
- * test the free space of a file system.
- */
- buf->f_bavail = buf->f_bfree = nr_free_pages() + nr_swap_pages +
atomic_read(&buffermem_pages);
- buf->f_blocks = buf->f_bfree + ULONG_MAX - sb->u.shmem_sb.free_blocks;
- } else {
- buf->f_blocks = sb->u.shmem_sb.max_blocks;
- buf->f_bavail = buf->f_bfree = sb->u.shmem_sb.free_blocks;
- }
+ spin_lock (&info->stat_lock);
+ /*
+ * This is only a guestimate and not honoured.
+ * We need it to make some programs happy which like to
+ * test the free space of a file system.
+ */
+ buf->f_bfree = shmem_sb_sys_free(info);
+ if (buf->f_bfree < info->reserved_blocks)
+ buf->f_bavail=0;
+ else
+ buf->f_bavail=buf->f_bfree-info->reserved_blocks;
+ buf->f_blocks = buf->f_bfree + info->max_blocks - info->free_blocks;
+
buf->f_files = sb->u.shmem_sb.max_inodes;
buf->f_ffree = sb->u.shmem_sb.free_inodes;
spin_unlock (&sb->u.shmem_sb.stat_lock);
@@ -977,7 +1027,8 @@
return res;
}
-static int shmem_parse_options(char *options, int *mode, unsigned long * blocks,
unsigned long *inodes)
+static int shmem_parse_options(char *options,int *mode,
+ struct shmem_sb_info *args)
{
char *this_char, *value;
@@ -989,22 +1040,22 @@
*value++ = 0;
if (!strcmp(this_char,"size")) {
unsigned long long size;
- if (!value || !*value || !blocks)
+ if (!value || !*value)
return 1;
size = memparse(value,&value);
if (*value)
return 1;
- *blocks = size >> PAGE_CACHE_SHIFT;
+ args->max_blocks = size >> PAGE_CACHE_SHIFT;
} else if (!strcmp(this_char,"nr_blocks")) {
- if (!value || !*value || !blocks)
+ if (!value || !*value)
return 1;
- *blocks = memparse(value,&value);
+ args->max_blocks = memparse(value,&value);
if (*value)
return 1;
} else if (!strcmp(this_char,"nr_inodes")) {
- if (!value || !*value || !inodes)
+ if (!value || !*value)
return 1;
- *inodes = memparse(value,&value);
+ args->max_inodes = memparse(value,&value);
if (*value)
return 1;
} else if (!strcmp(this_char,"mode")) {
@@ -1013,36 +1064,84 @@
*mode = simple_strtoul(value,&value,8);
if (*value)
return 1;
+ } else if (!strcmp(this_char,"reserved_blocks")) {
+ if (!value || !*value)
+ return 1;
+ args->reserved_blocks = memparse(value,&value);
+ if (*value)
+ return 1;
+ } else if (!strcmp(this_char,"reserved_inodes")) {
+ if (!value || !*value)
+ return 1;
+ args->reserved_inodes = memparse(value,&value);
+ if (*value)
+ return 1;
+ } else if (!strcmp(this_char,"reserved_mem")) {
+ if (!value || !*value)
+ return 1;
+ args->reserved_mem = memparse(value,&value);
+ if (*value)
+ return 1;
+ } else if (!strcmp(this_char,"reserved_uid")) {
+ if (!value || !*value)
+ return 1;
+ args->reserved_uid = memparse(value,&value);
+ if (*value)
+ return 1;
}
else
return 1;
}
+
+ if (args->max_blocks<5) args->max_blocks=5;
+ if (args->max_inodes<9) args->max_inodes=9;
+ if (args->reserved_blocks > args->max_blocks-2)
+ args->reserved_blocks = args->max_blocks-2;
+ if (args->reserved_inodes > args->max_inodes-4)
+ args->reserved_inodes = args->max_inodes-4;
+
return 0;
}
static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
{
int error;
- unsigned long max_blocks, blocks;
- unsigned long max_inodes, inodes;
+ unsigned long blocks;
+ unsigned long inodes;
struct shmem_sb_info *info = &sb->u.shmem_sb;
+ struct shmem_sb_info args;
+
+ /* FIXME: We unlock the stats while parsing options.
+ * Is that a good thing to do? In fact I don't
+ * think it makes any difference. Somebody should
+ * consider this closely, can anything go wrong,
+ * can it be made more efficient.
+ */
+
+ spin_lock(&info->stat_lock);
+ args=*info;
+ spin_unlock(&info->stat_lock);
- if (shmem_parse_options (data, NULL, &max_blocks, &max_inodes))
+ if (shmem_parse_options (data, NULL, &args))
return -EINVAL;
spin_lock(&info->stat_lock);
blocks = info->max_blocks - info->free_blocks;
inodes = info->max_inodes - info->free_inodes;
error = -EINVAL;
- if (max_blocks < blocks)
+ if (args.max_blocks < blocks)
goto out;
- if (max_inodes < inodes)
+ if (args.max_inodes < inodes)
goto out;
error = 0;
- info->max_blocks = max_blocks;
- info->free_blocks = max_blocks - blocks;
- info->max_inodes = max_inodes;
- info->free_inodes = max_inodes - inodes;
+ info->max_blocks = args.max_blocks;
+ info->free_blocks = args.max_blocks - blocks;
+ info->max_inodes = args.max_inodes;
+ info->free_inodes = args.max_inodes - inodes;
+ info->reserved_blocks = args.reserved_blocks;
+ info->reserved_inodes = args.reserved_inodes;
+ info->reserved_mem = args.reserved_mem;
+ info->reserved_uid = args.reserved_uid;
out:
spin_unlock(&info->stat_lock);
return error;
@@ -1058,22 +1157,27 @@
{
struct inode * inode;
struct dentry * root;
- unsigned long blocks = ULONG_MAX; /* unlimited */
- unsigned long inodes = ULONG_MAX; /* unlimited */
+ struct shmem_sb_info * info = &sb->u.shmem_sb;
int mode = S_IRWXUGO | S_ISVTX;
+ info->max_blocks=ULONG_MAX; /* unlimited */
+ info->max_inodes=ULONG_MAX; /* unlimited */
+ info->reserved_blocks = 0;
+ info->reserved_inodes = 0;
+ info->reserved_mem = 8192; /* 32MB */
+ info->reserved_uid = 0; /* root */
+
#ifdef CONFIG_TMPFS
- if (shmem_parse_options (data, &mode, &blocks, &inodes)) {
+ if (shmem_parse_options (data, &mode, info )) {
printk(KERN_ERR "tmpfs invalid option\n");
return NULL;
}
#endif
- spin_lock_init (&sb->u.shmem_sb.stat_lock);
- sb->u.shmem_sb.max_blocks = blocks;
- sb->u.shmem_sb.free_blocks = blocks;
- sb->u.shmem_sb.max_inodes = inodes;
- sb->u.shmem_sb.free_inodes = inodes;
+ spin_lock_init (&info->stat_lock);
+ info->free_blocks = info->max_blocks;
+ info->free_inodes = info->max_inodes;
+
sb->s_maxbytes = (unsigned long long)(SHMEM_NR_DIRECT +
(ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)) << PAGE_CACHE_SHIFT;
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
==============368192BA7572B1952B36D9E==
------------------------------
From: Kasper Dupont <[EMAIL PROTECTED]>
Subject: Re: Newbie question about Linux Devie Driver Application
Date: Wed, 23 May 2001 07:37:45 +0000
nickwang wrote:
>
> HI,all
> I've got some questions about Linux application like below:
> I wrote a application to use the ioctl(int fd,int cmd) function.
> The "fd" parameter is the file handler. I'm not sure about the "cmd"
> parameter.
> I just "#define LCD_HD44780_CLEAR _IO("I",0X11)",and then use the
> "LCD_HD44780_CLEAR"
> as "cmd", but error show like this "lcd.c:41 invalid operands to binary <<"
> line 41 is where the "ioctl(int fd,LCD_HD44780_CLEAR)"is.
> What is the problem?
> Thank you!
There is a difference between single and double
quotes. You have to write:
#define LCD_HD44780_CLEAR _IO('I',0X11)
--
Kasper Dupont
------------------------------
From: =?iso-8859-1?Q?Andr=E9?= David <[EMAIL PROTECTED]>
Subject: Re: Newbie question about Linux Devie Driver Application
Date: Wed, 23 May 2001 09:40:09 +0200
This is a multi-part message in MIME format.
==============AD505407DA6A2F35B7E1EA77
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
nickwang wrote:
>
> HI,all
> I've got some questions about Linux application like below:
> I wrote a application to use the ioctl(int fd,int cmd) function.
> The "fd" parameter is the file handler. I'm not sure about the "cmd"
> parameter.
> I just "#define LCD_HD44780_CLEAR _IO("I",0X11)",and then use the
> "LCD_HD44780_CLEAR"
> as "cmd", but error show like this "lcd.c:41 invalid operands to binary <<"
> line 41 is where the "ioctl(int fd,LCD_HD44780_CLEAR)"is.
> What is the problem?
> Thank you!
Hi,
>From what I know, the cmd must be in agreement with the device driver's
definitions. So the device driver responsible for the fd you're
operating with should provide some header file you include to know the
available commands. You can't just go and define your own cmd's.
Also you shouldn't call the fucntion with "int fd", just fd.
Cheers,
Andre
ps - I don't know what __IO() is ... but it doesn't look like an int.
And from the man pages:
int ioctl(int d, int request, ...)
[The "third" argument is traditionally char *argp, and will be so
named for this discussion.]
DESCRIPTION
The ioctl function manipulates the underlying device parameters
of special files. In particular, many operating characteristics of
character special files (e.g. terminals) may be controlled with ioctl
requests. The argument d must be an open file descriptor.
An ioctl request has encoded in it whether the argument is an
in parameter or out parameter, and the size of the argument argp in
bytes. Macros and defines used in specifying an ioctl request are
located in the file <sys/ioctl.h>.
--
"Share the code. If you hide it ain't good."
Popular knowledge
==============AD505407DA6A2F35B7E1EA77
Content-Type: text/x-vcard; charset=us-ascii;
name="Andre.David.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Andr� David
Content-Disposition: attachment;
filename="Andre.David.vcf"
begin:vcard
n:David;Andr�
tel;cell:+41792013849
tel;work:+41227676147
x-mozilla-html:FALSE
org:CERN - European Centre for Nuclear Research;EP/NA60
adr:;;;;;;
version:2.1
email;internet:[EMAIL PROTECTED]
note:Geneva, Switzerland
x-mozilla-cpt:;-16000
fn:Andr� David
end:vcard
==============AD505407DA6A2F35B7E1EA77==
------------------------------
From: Kasper Dupont <[EMAIL PROTECTED]>
Subject: Re: Kernel memory maps --- what are the limits?
Date: Wed, 23 May 2001 08:01:00 +0000
[EMAIL PROTECTED] wrote:
>
> Reading through the kernel startup code, I recently discovered that
> the mem= commandline parameter can be used to build all sorts of weird
> memory maps. GREAT! Especially as I was in need of a way to restrict
> the memory Linux accesses....
>
> However, it seems that Linux implicitly uses some memory even if a user
> supplied memory map does not include it. Also, there seems to be a need
> for at least some "low" memory, or things get slow.
> I was wondering whether someone with a better view of the big picture could
> shed some light on the following effects:
>
> * boot with "mem=16M@16M". Booted like this, Linux will run extremely
> slow. I can't quite work out why. This would be my preferred memory
> map.
> * boot with "mem=12M@16M mem=4M@8M". Booted like this, linux will be just
> fine. However, it appears to still be using some memory in the
> 1M-4M range; If my user space program overwrites that (physical)
> address range, the kernel will crash
>
> This is with the latest 2.4.4 kernel, booted via lilo. Especially the
> second case seems to be a bug --- the kernel should either complain
> that it can't live without that memory, or leave the memory
> alone. Accepting the absence of memory, yet still using it, is just
> wrong.
>
> Can anybody explain to me why these two effects happen? And possibly, how
> I can overcome them?
>
> Thanks,
>
> Bernie
>
> --
> Thou wilt show my head to the people: it is worth showing
> Georges Jacques Danton
> French revolutionary
> To his executioner, 5 April 1794
The kernel itself will after decompresion be located
starting at 1M. And that happens before the mem=
options are parsed. So for sure overwriting the 1M-4M
range will crash since it is the kernel you are
overwriting.
Having the kernel on another physical address will
require rewriting parts of the kernel and its startup
code and maybee also the boot loader.
If the performance decreases when you only use memory
above 16M it could be the case that you have one of
those motherboards that only cache the first 16M of
physical memory. There might be other possible
explanations, but I cannot think of any right now.
--
Kasper Dupont
------------------------------
** FOR YOUR REFERENCE **
The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:
Internet: [EMAIL PROTECTED]
You can send mail to the entire list by posting to the
comp.os.linux.development.system newsgroup.
Linux may be obtained via one of these FTP sites:
ftp.funet.fi pub/Linux
tsx-11.mit.edu pub/linux
sunsite.unc.edu pub/Linux
End of Linux-Development-System Digest
******************************