Tux for 2.6.7 (or 2.6.8)

Ingo Molnar mingo at elte.hu
Thu Sep 9 16:59:32 UTC 2004


* fredrik danerklint <fredan-tux at fredan.org> wrote:

> > the most recent port of Tux is in Arjan's kernel rpms (which are also
> > the rpms used for Fedora 2 and 3):
> >
> >   http://redhat.com/~arjanv/2.6/
> >
> > the Tux patch in the SRPM should apply to vanilla kernels too.
> 
> The patch which is inside the file  
> http://people.redhat.com/arjanv/2.6/SRPMS.kernel/kernel-2.6.8-1.533.src.rpm
> (linux-2.6.2-tux.patch) does work on a vanilla 2.6.8.1 kernel. However, there 
> are four missing symbols, which need to be fixed. 
> 
> Output from dmesg:
> tux: Unknown symbol chroot
> tux: Unknown symbol write
> tux: Unknown symbol chdir
> tux: Unknown symbol read

indeed. The way to do syscalls from within the kernel has changed yet
again. Does the attached patch help? (the patch also cleans up the
cpumask parsing code. This resulted in the log_cpu_mask tunable moving
from /proc/sys/net/tux/ to /proc/net/tux/.)

	Ingo
-------------- next part --------------
--- linux/include/net/tux.h.orig	
+++ linux/include/net/tux.h	
@@ -37,6 +37,8 @@
 #include <linux/compiler.h>
 #include <linux/mount.h>
 #include <linux/zlib.h>
+#include <linux/syscalls.h>
+#include <linux/cpumask.h>
 
 #include <net/tcp.h>
 #include <net/tux_u.h>
@@ -709,13 +711,13 @@ extern void send_abuf (tux_req_t *req, u
 
 extern int idle_event (tux_req_t *req);
 extern int output_space_event (tux_req_t *req);
-extern unsigned int log_cpu_mask;
+extern cpumask_t tux_log_cpu_mask;
 extern unsigned int tux_compression;
 extern unsigned int tux_noid;
 extern unsigned int tux_cgi_inherit_cpu;
 extern unsigned int tux_zerocopy_header;
 extern unsigned int tux_zerocopy_sendfile;
-extern unsigned int tux_cgi_cpu_mask;
+extern cpumask_t tux_cgi_cpu_mask;
 extern tux_proto_t tux_proto_http;
 extern tux_proto_t tux_proto_ftp;
 extern unsigned int tux_all_userspace;
--- linux/fs/open.c.orig	
+++ linux/fs/open.c	
@@ -536,6 +536,8 @@ out:
 	return error;
 }
 
+EXPORT_SYMBOL(sys_chdir);
+
 asmlinkage long sys_fchdir(unsigned int fd)
 {
 	struct file *file;
@@ -592,6 +594,8 @@ out:
 	return error;
 }
 
+EXPORT_SYMBOL(sys_chroot);
+
 asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
 {
 	struct inode * inode;
--- linux/fs/read_write.c.orig	
+++ linux/fs/read_write.c	
@@ -315,6 +315,8 @@ asmlinkage ssize_t sys_write(unsigned in
 	return ret;
 }
 
+EXPORT_SYMBOL(sys_write);
+
 asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf,
 			     size_t count, loff_t pos)
 {
--- linux/net/tux/main.c.orig	
+++ linux/net/tux/main.c	
@@ -192,9 +192,9 @@ int tux_chroot (char *dir)
 	set_fs(KERNEL_DS);
 	cap_raise (current->cap_effective, CAP_SYS_CHROOT);
 
-	err = chroot(dir);
+	err = sys_chroot(dir);
 	if (!err)
-		chdir("/");
+		sys_chdir("/");
 
 	current->cap_effective = saved_cap;
 	set_fs(oldmm);
@@ -446,14 +446,14 @@ static int user_req_start_thread (thread
 	cpu = ti->cpu;
 #if CONFIG_SMP
 	{
-		unsigned int mask;
-		cpumask_t cpu_mask, map;
+		unsigned int home_cpu;
+		cpumask_t map;
 
-		mask = 1 << ((cpu + tux_cpu_offset) % num_online_cpus());
+		home_cpu = (cpu + tux_cpu_offset) % num_online_cpus();
+		map = cpumask_of_cpu(home_cpu);
 
-		mask_to_cpumask(mask, &cpu_mask);
-		cpus_and(map, cpu_mask, cpu_online_map);
-		if(!(cpus_empty(map)))
+		cpus_and(map, map, cpu_online_map);
+		if (!(cpus_empty(map)))
 			set_cpus_allowed(current, map);		
 	}
 #endif
--- linux/net/tux/extcgi.c.orig	
+++ linux/net/tux/extcgi.c	
@@ -87,7 +87,7 @@ repeat:
 repeat_read:
 		Dprintk("reading %d bytes via read().\n", left);
 		oldmm = get_fs(); set_fs(KERNEL_DS);
-		len = read(2, tmp, left);
+		len = sys_read(2, tmp, left);
 		set_fs(oldmm);
 		Dprintk("got %d bytes from read() (total: %d).\n", len, total);
 		if (len > 0)
@@ -275,7 +275,7 @@ static int exec_external_cgi (void *data
 
 		Dprintk("POST data to CGI:\n");
 		oldmm = get_fs(); set_fs(KERNEL_DS);
-		ret = write(1, req->post_data_str, req->post_data_len);
+		ret = sys_write(1, req->post_data_str, req->post_data_len);
 		set_fs(oldmm);
 		Dprintk("write() returned: %d.\n", ret);
 		if (ret != req->post_data_len)
--- linux/net/tux/proc.c.orig	
+++ linux/net/tux/proc.c	
@@ -53,11 +53,11 @@ unsigned int tux_ftp_virtual_server = 0;
 unsigned int mass_hosting_hash = 0;
 unsigned int strip_host_tail = 0;
 unsigned int tux_max_object_size = 0;
-unsigned int log_cpu_mask = ~0;
+cpumask_t tux_log_cpu_mask = CPU_MASK_ALL;
 unsigned int tux_compression = 0;
 unsigned int tux_noid = 0;
 unsigned int tux_cgi_inherit_cpu = 0;
-unsigned int tux_cgi_cpu_mask = ~0;
+cpumask_t tux_cgi_cpu_mask = CPU_MASK_ALL;
 unsigned int tux_zerocopy_header = 1;
 unsigned int tux_max_free_requests = 1000;
 unsigned int tux_ignore_query = 0;
@@ -622,18 +622,6 @@ static ctl_table tux_table[] = {
 		NULL,
 		NULL
 	},
-	{	NET_TUX_CGI_CPU_MASK,
-		"cgi_cpu_mask",
-		&tux_cgi_cpu_mask,
-		sizeof(int),
-		0644,
-		NULL,
-		proc_dointvec,
-		&sysctl_intvec,
-		NULL,
-		NULL,
-		NULL
-	},
 	{	NET_TUX_ZEROCOPY_HEADER,
 		"zerocopy_header",
 		&tux_zerocopy_header,
@@ -770,6 +758,7 @@ static ctl_table tux_root_table[] = {
 
 static struct proc_dir_entry * root_tux_dir;
 static struct proc_dir_entry * log_cpu_mask_entry;
+static struct proc_dir_entry * cgi_cpu_mask_entry;
 static struct proc_dir_entry * stat_entry;
 static struct proc_dir_entry * tux_dir [CONFIG_TUX_NUMTHREADS];
 static struct proc_dir_entry * listen_dir [CONFIG_TUX_NUMTHREADS];
@@ -777,51 +766,29 @@ static struct proc_dir_entry * listen_di
 tux_socket_t tux_listen [CONFIG_TUX_NUMTHREADS][CONFIG_TUX_NUMSOCKETS] =
  { [0 ... CONFIG_TUX_NUMTHREADS-1] = { {&tux_proto_http, 0, 80, NULL}, } };
 
-#define HEX_DIGITS 8
-
-static int hex_read_proc (char *page, char **start, off_t off,
-			int count, int *eof, void *data)
+static int cpu_mask_read_proc (char *page, char **start, off_t off,
+					int count, int *eof, void *data)
 {
-	if (count < HEX_DIGITS+1)
+	int len = cpumask_scnprintf(page, count, *(cpumask_t *)data);
+	if (count - len < 2)
 		return -EINVAL;
-	return sprintf (page, "%08x\n", *(unsigned int *)data);
+	len += sprintf(page + len, "\n");
+	return len;
 }
 
-static int hex_write_proc (struct file *file, const char *buffer,
+static int cpu_mask_write_proc (struct file *file,
+					const char __user *buffer,
 					unsigned long count, void *data)
 {
-	char hexnum [HEX_DIGITS];
-	unsigned int new_value;
-	unsigned int i, full_count = count;
-
-	if (!count)
-		return -EINVAL;
-	if (count > HEX_DIGITS)
-		count = HEX_DIGITS;
-	if (copy_from_user(hexnum, buffer, count))
-		return -EFAULT;
-
-	/*
-	 * Parse the first 8 characters as a hex string, any non-hex char
-	 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are the same.
-	 */
-	new_value = 0;
-
-	for (i = 0; i < count; i++) {
-		unsigned int c = hexnum[i];
-
-		switch (c) {
-			case '0' ... '9': c -= '0'; break;
-			case 'a' ... 'f': c -= 'a'-10; break;
-			case 'A' ... 'F': c -= 'A'-10; break;
-		default:
-			goto out;
-		}
-		new_value = (new_value << 4) | c;
-	}
-out:
-	*(int *)data = new_value;
+	cpumask_t *mask = (cpumask_t *)data;
+	unsigned long full_count = count, err;
+	cpumask_t new_value;
+
+	err = cpumask_parse(buffer, count, new_value);
+	if (err)
+		return err;
 
+	*mask = new_value;
 	return full_count;
 }
 
@@ -1118,6 +1085,7 @@ static void cleanup_tux_proc (void)
 		unregister_tux_proc(i);
 	remove_proc_entry(stat_entry->name, root_tux_dir);
 	remove_proc_entry(log_cpu_mask_entry->name, root_tux_dir);
+	remove_proc_entry(cgi_cpu_mask_entry->name, root_tux_dir);
 	remove_proc_entry(root_tux_dir->name, proc_net);
 }
 
@@ -1135,12 +1103,21 @@ static void init_tux_proc (void)
 	entry = create_proc_entry("log_cpu_mask", 0700, root_tux_dir);
 
 	entry->nlink = 1;
-	entry->data = (void *)&log_cpu_mask;
-	entry->read_proc = hex_read_proc;
-	entry->write_proc = hex_write_proc;
+	entry->data = (void *)&tux_log_cpu_mask;
+	entry->read_proc = cpu_mask_read_proc;
+	entry->write_proc = cpu_mask_write_proc;
 
 	log_cpu_mask_entry = entry;
 
+	entry = create_proc_entry("cgi_cpu_mask", 0700, root_tux_dir);
+
+	entry->nlink = 1;
+	entry->data = (void *)&tux_cgi_cpu_mask;
+	entry->read_proc = cpu_mask_read_proc;
+	entry->write_proc = cpu_mask_write_proc;
+
+	cgi_cpu_mask_entry = entry;
+
 	entry = create_proc_entry("stat", 0700, root_tux_dir);
 
 	entry->nlink = 1;
@@ -1169,22 +1146,4 @@ void end_sysctl(void)
 	unregister_sysctl_table(tux_table_header);
 }
 
-#if CONFIG_SMP
-void mask_to_cpumask(unsigned int mask, cpumask_t *cpu_mask)
-{
-
-	unsigned int bit_mask, i;
-
-	bit_mask = 1 << 31;
-
-	for (i=NR_CPUS-1; i--; i >= 0) {
-		if(mask & bit_mask)
-			cpu_set(i, *cpu_mask);
-		else
-			cpu_clear(i, *cpu_mask);
-		mask <<= 1;
-	}
-
-}
-#endif
 
--- linux/net/tux/cgi.c.orig	
+++ linux/net/tux/cgi.c	
@@ -75,14 +75,12 @@ static int exec_helper (void * data)
 	sprintf(current->comm,"doexec - %d", current->pid);
 #if CONFIG_SMP
 	if (!tux_cgi_inherit_cpu) {
+		cpumask_t map;
 		
-		cpumask_t cgi_mask, map;
-		
-		mask_to_cpumask(tux_cgi_cpu_mask, &cgi_mask);
-		cpus_and(map, cpu_online_map, cgi_mask);
+		cpus_and(map, cpu_online_map, tux_cgi_cpu_mask);
 	
 		if (!(cpus_empty(map)))
-			set_cpus_allowed(current, cgi_mask);
+			set_cpus_allowed(current, map);
 		else
 			set_cpus_allowed(current, cpu_online_map);
 	}
--- linux/net/tux/logger.c.orig	
+++ linux/net/tux/logger.c	
@@ -766,11 +766,10 @@ static int logger_thread (void *data)
 	printk(KERN_NOTICE "TUX: logger thread started.\n");
 #if CONFIG_SMP
 	{
-		cpumask_t log_mask, map;
+		cpumask_t map;
 
-		mask_to_cpumask(log_cpu_mask, &log_mask);
-		cpus_and(map, cpu_online_map, log_mask);
-		if(!(cpus_empty(map)))
+		cpus_and(map, cpu_online_map, tux_log_cpu_mask);
+		if (!(cpus_empty(map)))
 			set_cpus_allowed(current, map);
 
 	}


More information about the tux-list mailing list