[PATCH] eject -T support

Tito farmatito at tiscali.it
Fri Oct 6 09:09:18 PDT 2006


On Friday 6 October 2006 01:12, you wrote:
> On Thursday 05 October 2006 00:01, Tito wrote:
> > On Wednesday 4 October 2006 23:37, Aurelien Jacobs wrote:
> > > On Mon, 2 Oct 2006 22:49:08 +0200
> > > Denis Vlasenko <vda.linux at googlemail.com> wrote:
> > > > Applied. Please yell if something doesn't work...
> > > 
> > > As I've said earlier, Tito's version doesn't work.
> > > eject -T don't close the tray when it's open :-(
> > > The ioctl(dev,CDROM_DRIVE_STATUS) is really needed.
> > > 
> > > Aurel
> > 
> > Denis,
> > Aurel is right please apply the original patch
> > as my doesn't work as expected due to poor testing
> > (me bad!) and therefor the size savings are worthless.
> 
> Fixed, please test...

Hi,
works for me.

About this comment:
	// FIXME: what if something is mounted OVER our cdrom?
	// We will unmount something else??!
	// What if cdrom is mounted many times?

1)  something mounted OVER our cdrom:

/dev/hdd   on /media/cdrom1 type iso9660 (ro,noexec,nosuid,nodev)
/dev/hdb1 on /media/cdrom1 type reiserfs (rw)

./busybox eject
eject: /dev/cdrom: Input/output error

/dev/hdd   on /media/cdrom1 type iso9660 (ro,noexec,nosuid,nodev)

the overmounted block device is unmounted and eject fails.

2)  cdrom is mounted many times:

/dev/hdd on /media/cdrom1 type iso9660 (ro)
/dev/hdd on /media/cdrom0 type iso9660 (ro)

root at localhost:/dev/pts/1:/root/Desktop/busybox# ./busybox eject
eject: /dev/cdrom: Input/output error

cat /proc/mounts
/dev/hdd /media/cdrom1 iso9660 ro 0 0

cat /etc/mtab

/dev/hda1 on / type ext3 (rw,noatime,errors=remount-ro)
proc on /proc type proc (rw)
/sys on /sys type sysfs (rw)
varrun on /var/run type tmpfs (rw)
varlock on /var/lock type tmpfs (rw)
udev on /dev type tmpfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
devshm on /dev/shm type tmpfs (rw)
/dev/hda2 on /boot type ext2 (rw)

block device is unmounted one time, eject fails,
mtab is not updated correctly.

These corner cases seems to be fixed by this example code,
but it is rather bloated as it imports half of umount's code 
and is not well tested. 
If you want to take a look at it....maybe you can squeeze it
or you have some better idea.

Ciao,
Tito

int eject_main(int argc, char **argv)
{
	unsigned long flags;
	char *device;
	char *dir;
	int dev, cmd;
	FILE *fp;
	struct mtab_list {
		char *dir;
		char *device;
		struct mtab_list *next;
	} *mtl, *m;
	struct mntent *me;

	m = mtl = 0;
	opt_complementary = "?:?1:t--T:T--t";
	flags = getopt32(argc, argv, "tT");

	device = realpath(argv[optind] ? : "/dev/cdrom", NULL);

	while ((me = find_mount_point(device, bb_path_mtab_file))) {
		dir = xstrdup(me->mnt_dir);
		if (!(fp = setmntent(bb_path_mtab_file, "r")))
			bb_perror_msg_and_die(bb_path_mtab_file);
		while ((me = getmntent(fp))) {
			m = xmalloc(sizeof(struct mtab_list));
			m->next = mtl;
			m->device = xstrdup(me->mnt_fsname);
			m->dir = xstrdup(me->mnt_dir);
			mtl = m;
		}
		endmntent(fp);
		while (m) {
			if (!strcmp(device, m->device) || !strcmp(dir, m->dir)) {
				umount(m->dir);
				if (ENABLE_FEATURE_MTAB_SUPPORT) erase_mtab(m->dir);
			}
			m = m->next;
		}
		if (ENABLE_FEATURE_CLEAN_UP) free(dir);
	}
	
	if (ENABLE_FEATURE_CLEAN_UP) {
		while (mtl) {
			m = mtl->next;
			free(mtl->device);
			free(mtl->dir);
			free(mtl);
			mtl = m;
		}
	}

	dev = xopen(device, O_RDONLY|O_NONBLOCK);
	cmd = CDROMEJECT;
	if (flags & FLAG_CLOSE
	|| (flags & FLAG_SMART && ioctl(dev, CDROM_DRIVE_STATUS) == CDS_TRAY_OPEN))
		cmd = CDROMCLOSETRAY;
	if (ioctl(dev, cmd)) {
		bb_perror_msg_and_die("%s", device);
	}

	if (ENABLE_FEATURE_CLEAN_UP) {
		close(dev);
		free(device);
	}
	return EXIT_SUCCESS;
}
> vda
> 


More information about the busybox mailing list