[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

ANNOUNCE: rebootless installs via new patch



Hi all, I am almost finished with the boot-floppies support for this.
Basically this all ends up allowing for rebootless installs.

I'de like to see this in the main kernel-source package so each arch wont
have to incorporate it seperately.

Once I have dbootstrap and busybox's init handling this properly, I will
commit the changes.

Thanks,
  Ben

-- 
 -----------=======-=-======-=========-----------=====------------=-=------
/  Ben Collins  --  ...on that fantastic voyage...  --  Debian GNU/Linux   \
`     bcollins@debian.org  --  bcollins@openldap.org  --  bmc@visi.net     '
 `---=========------=======-------------=-=-----=-===-======-------=--=---'
--- kernel-source-2.2.14.old/fs/dcache.c	Tue Jan  4 18:59:27 2000
+++ kernel-source-2.2.14/fs/dcache.c	Sun Jan 16 12:50:12 2000
@@ -327,7 +327,7 @@
  * child dentries were freed. This allows a non-destructive
  * test for unmounting a device.
  */
-int is_root_busy(struct dentry *root)
+int __is_root_busy(struct dentry *root,int ignore_mount_points)
 {
 	struct dentry *this_parent = root;
 	struct list_head *next;
@@ -339,15 +339,20 @@
 	while (next != &this_parent->d_subdirs) {
 		struct list_head *tmp = next;
 		struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+		int effective_count;
 		next = tmp->next;
+		/* Mount points may not count */
+		effective_count = dentry->d_count;
+		if (ignore_mount_points && dentry->d_mounts != dentry)
+			effective_count--;
 		/* Decrement count for unused children */
-		count += (dentry->d_count - 1);
+		count += (effective_count - 1);
 		if (!list_empty(&dentry->d_subdirs)) {
 			this_parent = dentry;
 			goto repeat;
 		}
 		/* root is busy if any leaf is busy */
-		if (dentry->d_count)
+		if (effective_count)
 			return 1;
 	}
 	/*
@@ -359,6 +364,11 @@
 		goto resume;
 	}
 	return (count > 1); /* remaining users? */
+}
+
+int is_root_busy(struct dentry *root)
+{
+	return __is_root_busy(root,0);
 }
 
 /*
--- kernel-source-2.2.14.old/fs/super.c	Tue Jan  4 18:59:52 2000
+++ kernel-source-2.2.14/fs/super.c	Sun Jan 16 12:50:12 2000
@@ -316,11 +316,15 @@
 	struct proc_nfs_info *nfs_infop;
 	struct nfs_server *nfss;
 	int len = 0;
+	char *path,*buffer = (char *) __get_free_page(GFP_KERNEL);
 
+	if (!buffer) return 0;
 	while ( tmp && len < PAGE_SIZE - 160)
 	{
+		path = d_path(tmp->mnt_sb->s_root,buffer,PAGE_SIZE);
 		len += sprintf( buf + len, "%s %s %s %s",
-			tmp->mnt_devname, tmp->mnt_dirname, tmp->mnt_sb->s_type->name,
+			tmp->mnt_devname, path,
+			tmp->mnt_sb->s_type->name,
 			tmp->mnt_flags & MS_RDONLY ? "ro" : "rw" );
 		for (fs_infop = fs_info; fs_infop->flag; fs_infop++) {
 		  if (tmp->mnt_flags & fs_infop->flag) {
@@ -377,6 +381,7 @@
 		tmp = tmp->mnt_next;
 	}
 
+	free_page((unsigned long) buffer);
 	return len;
 }
 
@@ -476,6 +481,34 @@
 	return NULL;
 }
 
+static void detach_mount_points(struct super_block *sb)
+{
+	struct super_block *s;
+
+	for (s = sb_entry(super_blocks.next); s != sb_entry(&super_blocks);
+		s = sb_entry(s->s_list.next)) {
+		struct dentry *root,*covered;
+
+		if (!s->s_dev || s == sb) continue;
+		root = s->s_root;
+		covered = root->d_covers;
+		if (covered->d_sb != sb) continue;
+		if (covered->d_inode->i_count != 1) {
+			printk(KERN_CRIT "detach_mount_points: inode %ld on %s "
+			"count %d (must be 1)\n",covered->d_inode->i_ino,
+			kdevname(sb->s_dev),covered->d_inode->i_count);
+			continue;
+		}
+		covered->d_mounts = covered; /* l'art pour l'art ... */
+		dput(covered);
+		root->d_covers = root;
+		printk(KERN_DEBUG "detached %s (count %d)",kdevname(s->s_dev),
+			root->d_count);
+		printk(" from %s (count %d)\n",kdevname(sb->s_dev),
+			sb->s_root->d_count);
+	}
+}
+
 asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf)
 {
         struct super_block *s;
@@ -612,8 +645,15 @@
 	struct dentry * root = sb->s_root;
 	struct dentry * covered = root->d_covers;
 
-	if (root->d_count != 1)
-		return -EBUSY;
+	printk(KERN_DEBUG "d_umount: ref %d\n",root->d_count);
+	if (root->d_count != 1) {
+		if (__is_root_busy(sb->s_root,1)) return -EBUSY;
+		else {
+			detach_mount_points(sb);
+			shrink_dcache_sb(sb);
+			fsync_dev(sb->s_dev);
+		}
+	}
 
 	if (root->d_inode->i_state)
 		return -EBUSY;
@@ -680,7 +720,8 @@
 	shrink_dcache_sb(sb);
 	fsync_dev(dev);
 
-	if (dev==ROOT_DEV && !unmount_root) {
+	printk(KERN_DEBUG "do_umount: ref %d\n",sb->s_root->d_count);
+	if (dev==ROOT_DEV && !unmount_root && __is_root_busy(sb->s_root,1)) {
 		/*
 		 * Special case for "unmounting" root ...
 		 * we just try to remount it readonly.
--- kernel-source-2.2.14.old/include/linux/dcache.h	Tue Jan  4 18:59:53 2000
+++ kernel-source-2.2.14/include/linux/dcache.h	Sun Jan 16 12:50:12 2000
@@ -150,6 +150,7 @@
 
 /* test whether root is busy without destroying dcache */
 extern int is_root_busy(struct dentry *);
+extern int __is_root_busy(struct dentry *,int ignore_mount_points);
 
 /* test whether we have any submounts in a subdir tree */
 extern int have_submounts(struct dentry *);
--- kernel-source-2.2.14.old/include/linux/sysctl.h	Tue Jan  4 18:59:53 2000
+++ kernel-source-2.2.14/include/linux/sysctl.h	Sun Jan 16 20:41:26 2000
@@ -106,6 +106,7 @@
 	KERN_SYSRQ=38,		/* int: Sysreq enable */
 	KERN_SHMALL=41,		/* int: maximum size of shared memory */
 	KERN_SPARC_STOP_A=44,	/* int: Sparc Stop-A enable */
+	KERN_INITCHROOT=45,	/* string: allows detecting chroot patch */
 };
 
 
--- kernel-source-2.2.14.old/kernel/sysctl.c	Tue Jan  4 18:59:54 2000
+++ kernel-source-2.2.14/kernel/sysctl.c	Sun Jan 16 21:13:46 2000
@@ -87,6 +87,7 @@
 static ctl_table debug_table[];
 static ctl_table dev_table[];
 
+static char init_chroot[256];
 
 /* /proc declarations: */
 
@@ -231,6 +232,8 @@
 	{KERN_SYSRQ, "sysrq", &sysrq_enabled, sizeof (int),
 	 0644, NULL, &proc_dointvec},
 #endif	 
+	{KERN_INITCHROOT, "init-chroot", &init_chroot, 256,
+	 0644, NULL, &proc_dostring, &sysctl_string},
 	{0}
 };
 
@@ -294,6 +297,7 @@
 
 void __init sysctl_init(void)
 {
+    	init_chroot[0] = '\0';
 #ifdef CONFIG_PROC_FS
 	register_proc_table(root_table, &proc_sys_root);
 #endif

Reply to: