Beispiel #1
0
gboolean usb_cleanup_timeout(gpointer data)
{
 	/* signal usb disconnected */
        usb_moded_send_signal(USB_DISCONNECTED);
	usb_moded_mode_cleanup(get_usb_module());
	usb_moded_module_cleanup(get_usb_module());
	set_usb_mode(MODE_UNDEFINED);
	return FALSE;
}
static int set_mass_storage_mode(struct mode_list_elem *data)
{
        gchar *command;
        char command2[256], *real_path = NULL, *mountpath;
        const char *mount;
        gchar **mounts;
        int ret = 0, i = 0, mountpoints = 0, fua = 0, try = 0;

        /* send unmount signal so applications can release their grasp on the fs, do this here so they have time to act */
        usb_moded_send_signal(USB_PRE_UNMOUNT);
        fua = find_sync();
        mount = find_mounts();
        if(mount)
        {
        	mounts = g_strsplit(mount, ",", 0);
             	/* check amount of mountpoints */
                for(i=0 ; mounts[i] != NULL; i++)
                {
                	mountpoints++;
                }

		if(strcmp(data->mode_module, MODULE_NONE))
		{
			/* check if the file storage module has been loaded with sufficient luns in the parameter,
			if not, unload and reload or load it. Since  mountpoints start at 0 the amount of them is one more than their id */
			sprintf(command2, "/sys/devices/platform/musb_hdrc/gadget/gadget-lun%d/file", (mountpoints - 1) );
			if(access(command2, R_OK) == -1)
			{
				log_debug("%s does not exist, unloading and reloading mass_storage\n", command2);
				usb_moded_unload_module(MODULE_MASS_STORAGE);
				sprintf(command2, "modprobe %s luns=%d \n", MODULE_MASS_STORAGE, mountpoints);
				log_debug("usb-load command = %s \n", command2);
				ret = system(command2);
				if(ret)
					return(ret);
			}
		}
                /* umount filesystems */
                for(i=0 ; mounts[i] != NULL; i++)
                {
                	/* check if filesystem is mounted or not, if ret = 1 it is already unmounted */
			real_path = realpath(mounts[i], NULL);
			if(real_path)
				mountpath = real_path;
			else
				mountpath = mounts[i];
umount:                 command = g_strconcat("mount | grep ", mountpath, NULL);
                        ret = system(command);
                        g_free(command);
                        if(!ret)
                        {
				/* no check for / needed as that will fail to umount anyway */
				command = g_strconcat("umount ", mountpath, NULL);
                                log_debug("unmount command = %s\n", command);
                                ret = system(command);
                                g_free(command);
                                if(ret != 0)
                                {
					if(try != 3)
					{
						try++;
						sleep(1);
						log_err("Umount failed. Retrying\n");
						report_mass_storage_blocker(mount, 1);
						goto umount;
					}
					else
					{
                                		log_err("Unmounting %s failed\n", mount);
						report_mass_storage_blocker(mount, 2);
                                        	usb_moded_send_error_signal(UMOUNT_ERROR);
     	                                   	return(ret);
					}
                                }
                         }
                         else
                         	/* already unmounted. Set return value to 0 since there is no error */
                                ret = 0;
              	}
		
	        /* activate mounts after sleeping 1s to be sure enumeration happened and autoplay will work in windows*/
		usleep(1800);
                for(i=0 ; mounts[i] != NULL; i++)
                {       
			
			if(strcmp(data->mode_module, MODULE_NONE))
			{
				sprintf(command2, "echo %i  > /sys/devices/platform/musb_hdrc/gadget/gadget-lun%d/nofua", fua, i);
				log_debug("usb lun = %s active\n", command2);
				system(command2);
				sprintf(command2, "/sys/devices/platform/musb_hdrc/gadget/gadget-lun%d/file", i);
				log_debug("usb lun = %s active\n", command2);
				write_to_file(command2, mounts[i]);
			}
			else
			{
				write_to_file("/sys/class/android_usb/android0/enable", "0");
				write_to_file("/sys/class/android_usb/android0/functions", "mass_storage");
				//write_to_file("/sys/class/android_usb/f_mass_storage/lun/nofua", fua);
				write_to_file("/sys/class/android_usb/f_mass_storage/lun/file", mount);
				write_to_file("/sys/class/android_usb/android0/enable", "1");

			}
                }
                g_strfreev(mounts);
		g_free((gpointer *)mount);
		if(real_path)
			free(real_path);
	}
Beispiel #3
0
/** clean up for modules when usb gets disconnected
 *
 * @param module The name of the module to unload
 * @return 0 on success, non-zero on failure
 *
 */
int usb_moded_module_cleanup(const char *module)
{
  	int retry = 0, failure;

	if(!strcmp(module, MODULE_NONE))
		goto END;
	/* wait a bit for all components listening on dbus to clean up their act 
	sleep(2); */
	/* check if things were not reconnected in that timespan 
	if(get_usb_connection_state())
		return(0);
	*/
	
	failure = usb_moded_unload_module(module);

	/* if we have MODULE_MASS_STORAGE it might be MODULE_FILE_STORAGE might
	   be loaded. So check and unload that one if unloading fails first time */
	if(failure && !strcmp(MODULE_MASS_STORAGE, module))
		failure = usb_moded_unload_module(MODULE_FILE_STORAGE);

	/* if it still failed it might be the mode has not been cleaned-up correctly,
	   so we clean up the mode to be sure */
	if(failure)
	{
		usb_moded_mode_cleanup(usb_moded_find_module());
	}

	while(failure)
	{
		/* module did not get unloaded. We will wait a bit and try again */
		sleep(1);
		/* send the REALLY  disconnect message */
		usb_moded_send_signal(USB_REALLY_DISCONNECT);
		failure = usb_moded_unload_module(module);
		log_debug("unloading failure = %d\n", failure);
		if(!failure)
			break;
		if(!usb_moded_find_module())
			goto END;
		retry++;
		if(retry == 2)
			break;
	}
	if(!strcmp(module, MODULE_NETWORK))
	{
		if(retry >= 2)
		{	
			/* we exited the loop due to max retry's. Module is not unloaded yet
			   lets go for more extreme measures
			   lsof, then various options of kill
			*/
			log_info("Oh noes the platform is on fire!\n");
kill:		
			/* DIRTY DESPERATE WORKAROUND */
			/*system("for i in `lsof -t /dev/ttyGS*`; do cat /proc/$i/cmdline | sed 's/|//g' | sed "s/\x00/ /g" | awk '{ print $1 }' | xargs kill; done");
			system("for i in `ps ax | grep phonet-at | grep -v grep | awk '{ print $1 }'`; do kill -9 $i ; done");*/
			/* kill anything that still claims the usb tty's */
			system("for i in `lsof -t /dev/ttyGS*`; do kill -s SIGTERM $i ; done");
			system("for i in `lsof -t /dev/gc*`; do kill -s SIGTERM $i ; done");
			system("for i in `lsof -t /dev/mtp*`; do kill -s SIGTERM $i ; done");
			system("kill -s SIGTERM $(lsof -t /dev/usbacm");
		        // SP: three passes and for loops in sh?
		        // SP: system("kill -s SIGTERM $(lsof -t /dev/ttyGS* /dev/gc* /dev/mtp*") ?
			// SP: or popen + kill loop?
			/* try to unload again and give up if it did not work yet */
			failure = usb_moded_unload_module(module);
			if(failure && retry < 10)
			{
				retry++;
			  // SP: NOTE: we have a root process in busyloop sending kill signals to
			  // user processes? should we give them a chance to react?
				goto kill;
			  // SP: IMHO backwards goto is bad - a loop perhaps?
			}
			if(failure && retry == 10)
			{
				system("for i in `lsof -t /dev/ttyGS*`; do kill -9 $i ; done");
				system("for i in `lsof -t /dev/gc*`; do kill -9 $i ; done");
				system("for i in `lsof -t /dev/mtp*`; do kill -9 $i ; done");
				/* try again since there seem to be hard to kill processes there */
				system("killall -9 obexd");
				system("killall -9 msycnd");
				failure = usb_moded_unload_module(module);
			}

		}
	}
	if(!failure)
		log_info("Module %s unloaded successfully\n", module);
	else
	{
		log_err("Module %s did not unload! Failing and going to undefined.\n", module);
		return(1);
	}
END:
	return(0);
}