diff --git a/packages/mediacenter/xbmc/patches/xbmc-AML-XB9295c3f-udev-mount.patch b/packages/mediacenter/xbmc/patches/xbmc-AML-XB9295c3f-udev-mount.patch new file mode 100644 index 0000000000..dbdcec8273 --- /dev/null +++ b/packages/mediacenter/xbmc/patches/xbmc-AML-XB9295c3f-udev-mount.patch @@ -0,0 +1,367 @@ +From 9295c3ffac97c64cebee88229ee6ac8376f150ae Mon Sep 17 00:00:00 2001 +From: davilla +Date: Fri, 20 Apr 2012 13:23:19 -0400 +Subject: [PATCH] [aml] fixed, add UDevProvider to handle usb disk add/remove + storage handling + +--- + xbmc/storage/linux/LinuxStorageProvider.h | 5 + + xbmc/storage/linux/Makefile | 9 +- + xbmc/storage/linux/UDevProvider.cpp | 241 ++++++++++++++++++++++++++++++ + xbmc/storage/linux/UDevProvider.h | 55 +++++++ + 4 files changed, 306 insertions(+), 4 deletions(-) + create mode 100644 xbmc/storage/linux/UDevProvider.cpp + create mode 100644 xbmc/storage/linux/UDevProvider.h + +diff --git a/xbmc/storage/linux/LinuxStorageProvider.h b/xbmc/storage/linux/LinuxStorageProvider.h +index 1f14548..740b282 100644 +--- a/xbmc/storage/linux/LinuxStorageProvider.h ++++ b/xbmc/storage/linux/LinuxStorageProvider.h +@@ -21,6 +21,7 @@ + #include "storage/IStorageProvider.h" + #include "HALProvider.h" + #include "DeviceKitDisksProvider.h" ++#include "UDevProvider.h" + #include "UDisksProvider.h" + #include "PosixMountProvider.h" + +@@ -41,6 +42,10 @@ class CLinuxStorageProvider : public IStorageProvider + if (m_instance == NULL) + m_instance = new CHALProvider(); + #endif ++#ifdef HAVE_LIBUDEV ++ if (m_instance == NULL) ++ m_instance = new CUDevProvider(); ++#endif + + if (m_instance == NULL) + m_instance = new CPosixMountProvider(); +diff --git a/xbmc/storage/linux/Makefile b/xbmc/storage/linux/Makefile +index 9be601d..325f84d 100644 +--- a/xbmc/storage/linux/Makefile ++++ b/xbmc/storage/linux/Makefile +@@ -1,8 +1,9 @@ +-SRCS=DeviceKitDisksProvider.cpp \ +- HALProvider.cpp \ +- UDisksProvider.cpp \ ++SRCS = DeviceKitDisksProvider.cpp ++SRCS += UDisksProvider.cpp ++SRCS += HALProvider.cpp ++SRCS += UDevProvider.cpp + +-LIB=storage_linux.a ++LIB = storage_linux.a + + include ../../../Makefile.include + -include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) +diff --git a/xbmc/storage/linux/UDevProvider.cpp b/xbmc/storage/linux/UDevProvider.cpp +new file mode 100644 +index 0000000..21b6b50 +--- /dev/null ++++ b/xbmc/storage/linux/UDevProvider.cpp +@@ -0,0 +1,241 @@ ++/* ++ * Copyright (C) 2005-2012 Team XBMC ++ * http://www.xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, write to ++ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ++ * http://www.gnu.org/copyleft/gpl.html ++ * ++ */ ++ ++#include "UDevProvider.h" ++ ++#ifdef HAVE_LIBUDEV ++ ++#include "linux/PosixMountProvider.h" ++#include "utils/log.h" ++#include "utils/URIUtils.h" ++ ++extern "C" { ++#include ++#include ++} ++ ++static const char *get_mountpoint(const char *devnode) ++{ ++ static char buf[4096]; ++ const char *delim = " "; ++ const char *mountpoint = NULL; ++ FILE *fp = fopen("/proc/mounts", "r"); ++ ++ while (fgets(buf, sizeof (buf), fp)) ++ { ++ const char *node = strtok(buf, delim); ++ if (strcmp(node, devnode) == 0) ++ { ++ mountpoint = strtok(NULL, delim); ++ break; ++ } ++ } ++ ++ if (mountpoint != NULL) ++ { ++ // If mount point contain characters like space, it is converted to ++ // "\040". This situation should be handled. ++ char *c1, *c2; ++ for (c1 = c2 = (char*)mountpoint; *c2; ++c1) ++ { ++ if (*c2 == '\\') ++ { ++ *c1 = (((c2[1] - '0') << 6) | ((c2[2] - '0') << 3) | (c2[3] - '0')); ++ c2 += 4; ++ continue; ++ } ++ if (c1 != c2) ++ *c1 = *c2; ++ ++c2; ++ } ++ *c1 = *c2; ++ } ++ ++ fclose(fp); ++ return mountpoint; ++} ++ ++CUDevProvider::CUDevProvider() ++{ ++ m_udev = NULL; ++ m_udevMon = NULL; ++} ++ ++void CUDevProvider::Initialize() ++{ ++ CLog::Log(LOGDEBUG, "Selected UDev as storage provider"); ++ ++ m_udev = udev_new(); ++ if (!m_udev) ++ { ++ CLog::Log(LOGERROR, "%s - failed to allocate udev context", __FUNCTION__); ++ return; ++ } ++ /* set up a devices monitor that listen for any device change */ ++ m_udevMon = udev_monitor_new_from_netlink(m_udev, "udev"); ++ udev_monitor_filter_add_match_subsystem_devtype(m_udevMon, "block", "disk"); ++ udev_monitor_filter_add_match_subsystem_devtype(m_udevMon, "block", "partition"); ++ udev_monitor_enable_receiving(m_udevMon); ++ ++ PumpDriveChangeEvents(NULL); ++} ++ ++void CUDevProvider::Stop() ++{ ++ udev_monitor_unref(m_udevMon); ++ udev_unref(m_udev); ++} ++ ++void CUDevProvider::GetDisks(VECSOURCES& disks, bool removable) ++{ ++ // enumerate existing block devices ++ struct udev_enumerate *u_enum = udev_enumerate_new(m_udev); ++ if (u_enum == NULL) ++ { ++ fprintf(stderr, "Error: udev_enumerate_new(udev)\n"); ++ return; ++ } ++ ++ udev_enumerate_add_match_subsystem(u_enum, "block"); ++ udev_enumerate_add_match_property(u_enum, "DEVTYPE", "disk"); ++ udev_enumerate_add_match_property(u_enum, "DEVTYPE", "partition"); ++ udev_enumerate_scan_devices(u_enum); ++ ++ struct udev_list_entry *u_list_ent; ++ struct udev_list_entry *u_first_list_ent; ++ u_first_list_ent = udev_enumerate_get_list_entry(u_enum); ++ udev_list_entry_foreach(u_list_ent, u_first_list_ent) ++ { ++ const char *name = udev_list_entry_get_name(u_list_ent); ++ struct udev *context = udev_enumerate_get_udev(u_enum); ++ struct udev_device *device = udev_device_new_from_syspath(context, name); ++ if (device == NULL) ++ continue; ++ ++ // filter out devices that are not mounted ++ const char *mountpoint = get_mountpoint(udev_device_get_devnode(device)); ++ if (!mountpoint) ++ { ++ udev_device_unref(device); ++ continue; ++ } ++ ++ // filter out things mounted on /tmp ++ if (strstr(mountpoint, "/tmp")) ++ { ++ udev_device_unref(device); ++ continue; ++ } ++ ++ // look for usb devices on the usb bus or mounted on /media/usbX (sdcards) ++ const char *bus = udev_device_get_property_value(device, "ID_BUS"); ++ if (removable && ++ ((bus && strstr(bus, "usb")) || ++ (mountpoint && strstr(mountpoint, "usb")))) ++ { ++ const char *label = udev_device_get_property_value(device, "ID_FS_LABEL"); ++ if (!label) ++ label = URIUtils::GetFileName(mountpoint); ++ ++ CMediaSource share; ++ share.strName = label; ++ share.strPath = mountpoint; ++ share.m_ignore = true; ++ share.m_iDriveType = CMediaSource::SOURCE_TYPE_REMOVABLE; ++ AddOrReplace(disks, share); ++ } ++ udev_device_unref(device); ++ } ++ udev_enumerate_unref(u_enum); ++} ++ ++void CUDevProvider::GetLocalDrives(VECSOURCES &localDrives) ++{ ++ GetDisks(localDrives, false); ++} ++ ++void CUDevProvider::GetRemovableDrives(VECSOURCES &removableDrives) ++{ ++ GetDisks(removableDrives, true); ++} ++ ++bool CUDevProvider::Eject(CStdString mountpath) ++{ ++ return false; ++} ++ ++std::vector CUDevProvider::GetDiskUsage() ++{ ++ CPosixMountProvider legacy; ++ return legacy.GetDiskUsage(); ++} ++ ++bool CUDevProvider::PumpDriveChangeEvents(IStorageEventsCallback *callback) ++{ ++ bool changed = false; ++ ++ fd_set readfds; ++ FD_ZERO(&readfds); ++ FD_SET(udev_monitor_get_fd(m_udevMon), &readfds); ++ ++ // non-blocking, check the file descriptor for received data ++ struct timeval tv = {0}; ++ int count = select(udev_monitor_get_fd(m_udevMon) + 1, &readfds, NULL, NULL, &tv); ++ if (count < 0) ++ return false; ++ ++ if (FD_ISSET(udev_monitor_get_fd(m_udevMon), &readfds)) ++ { ++ struct udev_device *dev = udev_monitor_receive_device(m_udevMon); ++ if (!dev) ++ return false; ++ ++ const char *action = udev_device_get_action(dev); ++ const char *devtype = udev_device_get_devtype(dev); ++ if (action) ++ { ++ const char *label = udev_device_get_property_value(dev, "ID_FS_LABEL"); ++ const char *mountpoint = get_mountpoint(udev_device_get_devnode(dev)); ++ if (!label) ++ label = URIUtils::GetFileName(mountpoint); ++ ++ if (!strcmp(action, "add") && !strcmp(devtype, "partition")) ++ { ++ CLog::Log(LOGNOTICE, "UDev: Added %s", mountpoint); ++ if (callback) ++ callback->OnStorageAdded(label, mountpoint); ++ changed = true; ++ } ++ if (!strcmp(action, "remove") && !strcmp(devtype, "partition")) ++ { ++ CLog::Log(LOGNOTICE, "UDev: Removed %s", mountpoint); ++ if (callback) ++ callback->OnStorageSafelyRemoved(label); ++ changed = true; ++ } ++ } ++ udev_device_unref(dev); ++ } ++ ++ return changed; ++} ++ ++#endif +diff --git a/xbmc/storage/linux/UDevProvider.h b/xbmc/storage/linux/UDevProvider.h +new file mode 100644 +index 0000000..6b51e2a +--- /dev/null ++++ b/xbmc/storage/linux/UDevProvider.h +@@ -0,0 +1,55 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2012 Team XBMC ++ * http://www.xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, write to ++ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ++ * http://www.gnu.org/copyleft/gpl.html ++ * ++ */ ++ ++#include "storage/IStorageProvider.h" ++ ++#ifdef HAVE_LIBUDEV ++ ++struct udev; ++struct udev_monitor; ++ ++class CUDevProvider : public IStorageProvider ++{ ++public: ++ CUDevProvider(); ++ virtual ~CUDevProvider() { } ++ ++ virtual void Initialize(); ++ virtual void Stop(); ++ ++ virtual void GetLocalDrives(VECSOURCES &localDrives); ++ virtual void GetRemovableDrives(VECSOURCES &removableDrives); ++ ++ virtual bool Eject(CStdString mountpath); ++ ++ virtual std::vector GetDiskUsage(); ++ ++ virtual bool PumpDriveChangeEvents(IStorageEventsCallback *callback); ++ ++private: ++ void GetDisks(VECSOURCES& devices, bool removable); ++ ++ struct udev *m_udev; ++ struct udev_monitor *m_udevMon; ++}; ++ ++#endif +-- +1.8.1.6 +