hal/tools fstab-sync.c,1.9,1.10
David Zeuthen
david at freedesktop.org
Thu Aug 19 10:58:17 PDT 2004
Update of /cvs/hal/hal/tools
In directory pdx:/tmp/cvs-serv20892/tools
Modified Files:
fstab-sync.c
Log Message:
2004-08-19 David Zeuthen <david at fubar.dk>
* tools/fstab-sync.c: Lot's of changes: remove old locking code;
fix security issue (remove dev,suid) with the given mount options
(RH bug #130290); Use a, pretty lame perhaps, heuristic to add
noatime,sync for hotpluggable volumes smaller than 1GB. Check device
mentioned in /etc/fstab for symlink and if found, update the
block.device property in HAL if applicable; Use macros for mount
root and noop keyword (see configure.in changes).
* hald/linux/block_class_device.c (volume_set_size): New function
(detect_media): Call volume_set_size
(block_class_pre_process): Call volume_set_size
* doc/spec/hal-spec.xml.in: Add documentation for volume.block_size
and volume.num_blocks.
* configure.in: Add gobject>=2.2.2 to PKG_CHECK_MODULES. Patch from
Steve Grubb <linux_4ever at yahoo.com>. Added some configuration options
for fstab-sync.
Index: fstab-sync.c
===================================================================
RCS file: /cvs/hal/hal/tools/fstab-sync.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- fstab-sync.c 17 Aug 2004 09:52:09 -0000 1.9
+++ fstab-sync.c 19 Aug 2004 17:58:15 -0000 1.10
@@ -60,10 +60,14 @@
#define PROGRAM_NAME "fstab-sync"
#define TEMP_FSTAB_PREFIX ".fstab.hal."
#define TEMP_FSTAB_MAX_LENGTH 64
-#define MOUNT_ROOT "/media/"
-#define LOCK_TIMEOUT 60 /* seconds */
-#define LOCK_TIMEOUT_WAIT 500000 /* microseconds */
+#ifndef FSTAB_SYNC_MOUNT_ROOT
+# define FSTAB_SYNC_MOUNT_ROOT "/media"
+#endif
+
+#ifndef FSTAB_SYNC_MOUNT_MANAGED_KEYWORD
+# define FSTAB_SYNC_MOUNT_MANAGED_KEYWORD "kudzu"
+#endif
#ifndef TRUE
#define TRUE 1
@@ -84,12 +88,16 @@
*/
typedef struct
{
- char *udi; /**< UDI from HAL */
- char *block_device; /**< Special device file */
- char *type; /**< Name used in mount point construction, e.g. "cdrw" */
- char *fs_type; /**< Filesystem type or blank */
- char *mount_point; /**< Final unique mount point, e.g "/media/cdrw2" */
- char *label; /**< Label of media or blank */
+ char *udi; /**< UDI from HAL */
+ char *block_device; /**< Special device file */
+ char *type; /**< Name used in mount point construction, e.g. "cdrw" */
+ char *fs_type; /**< Filesystem type or blank */
+ char *mount_point; /**< Final unique mount point, e.g "/media/cdrw2" */
+ char *label; /**< Label of media or blank */
+ boolean is_hotpluggable; /**< TRUE if the volume stems from a hotpluggable drive */
+ boolean is_optical_drive; /**< TRUE if the volume is on an optical drive*/
+ dbus_int64_t size; /**< Size in bytes of the volume or -1 if not available */
+ char *bus; /**< Type of bus the device is connected to */
} Volume;
typedef enum
@@ -150,7 +158,6 @@
static inline int get_random_int_in_range (int low, int high);
-static int open_and_lock_file (const char *filename);
static int open_temp_fstab_file (const char *dir, char **filename);
static char *get_hal_string_property (const char *udi, const char *property);
@@ -162,6 +169,7 @@
static boolean create_mount_point_for_volume (Volume *volume);
static boolean fs_table_add_volume (FSTable *table, Volume *volume);
static FSTableLine *fs_table_remove_volume (FSTable *table, Volume *volume);
+static boolean fs_table_line_has_mount_option (FSTableLine *line, const char *option);
static boolean add_udi (const char *udi, boolean should_mount_device);
static boolean remove_udi (const char *udi);
@@ -302,12 +310,12 @@
static boolean fs_table_line_is_generated (FSTableLine *line)
{
-#ifdef USE_NOOP_MOUNT_OPTION
- if (!fs_table_line_has_mount_option (line, "kudzu"))
+#ifdef FSTAB_SYNC_USE_NOOP_MOUNT_OPTION
+ if (!fs_table_line_has_mount_option (line, FSTAB_SYNC_MOUNT_MANAGED_KEYWORD))
return FALSE;
#endif
- if (strncmp (line->mount_point, MOUNT_ROOT, sizeof (MOUNT_ROOT) -1) != 0)
+ if (strncmp (line->mount_point, FSTAB_SYNC_MOUNT_ROOT "/", sizeof (FSTAB_SYNC_MOUNT_ROOT "/") -1) != 0)
return FALSE;
return TRUE;
@@ -424,7 +432,7 @@
table->parse_buffer[0] = '\0';
table->parse_buffer_length = 0;
- input_fd = open_and_lock_file (filename);
+ input_fd = open (filename, O_RDONLY);
if (input_fd < 0)
goto error;
@@ -996,6 +1004,9 @@
volume_new (const char *udi)
{
Volume *volume;
+ char *storudi;
+ dbus_int32_t num_blocks;
+ dbus_int32_t block_size;
if (!udi_is_volume_or_nonpartition_drive (udi))
return NULL;
@@ -1033,6 +1044,28 @@
if (volume->label == NULL)
volume->label = strdup ("");
+
+ storudi = hal_device_get_property_string (hal_context, udi, "block.storage_device");
+ volume->is_hotpluggable = hal_device_get_property_bool (hal_context, storudi, "storage.hotpluggable");
+
+ if (strcmp (hal_device_get_property_string (hal_context, storudi, "storage.drive_type"),
+ "cdrom") == 0) {
+ volume->is_optical_drive = TRUE;
+ } else {
+ volume->is_optical_drive = FALSE;
+ }
+ volume->bus = hal_device_get_property_string (hal_context, storudi, "storage.bus");
+ free (storudi);
+
+ if (hal_device_property_exists (hal_context, udi, "volume.block_size") &&
+ hal_device_property_exists (hal_context, udi, "volume.num_blocks")) {
+ block_size = hal_device_get_property_int (hal_context, udi, "volume.block_size");
+ num_blocks = hal_device_get_property_int (hal_context, udi, "volume.num_blocks");
+ volume->size = block_size * num_blocks;
+ } else {
+ volume->size = -1;
+ }
+
return volume;
}
@@ -1072,6 +1105,12 @@
free (volume->type);
volume->type = NULL;
}
+
+ if (volume->bus != NULL)
+ {
+ free (volume->bus);
+ volume->bus = NULL;
+ }
}
/* FIXME: This function should be more fleshed out then it is
@@ -1083,7 +1122,7 @@
/* FIXME: Should only mkdir if we need to and should do so
* recursively for each component of the mount root.
*/
- mkdir (MOUNT_ROOT, 0775);
+ mkdir (FSTAB_SYNC_MOUNT_ROOT "/", 0775);
return (mkdir (volume->mount_point, 0775) != -1) || errno == EEXIST;
}
@@ -1093,6 +1132,7 @@
fs_table_has_volume (FSTable *table, Volume *volume)
{
FSTableLine *line;
+ struct stat statbuf;
line = table->lines;
while (line != NULL)
@@ -1110,6 +1150,32 @@
if (strcmp (field->value, volume->block_device) == 0)
return TRUE;
+ /* Check if it's a symlink */
+ if (lstat (field->value, &statbuf) == 0) {
+
+ if (S_ISLNK(statbuf.st_mode)) {
+ char buf[256];
+
+ memset (buf, '\0', sizeof (buf));
+
+ if (readlink (field->value, buf, sizeof (buf)) > 0) {
+
+ printf ("*** buf=%s hal=%s, udi=%s\n",
+ buf, volume->block_device, volume->udi);
+
+ if (strcmp (volume->block_device, buf) == 0) {
+ /* update block.device with new value */
+ fstab_update_debug (_("%d: Found %s pointing to %s in" _PATH_FSTAB),
+ pid, field->value, buf);
+ hal_device_set_property_string (hal_context, volume->udi,
+ "block.device", field->value);
+ return TRUE;
+ }
+
+ }
+ }
+ }
+
/* Mount by label, more tricky, see below... */
if (strncmp (field->value, "LABEL=", 6) == 0 &&
strlen (field->value) > 6 &&
@@ -1179,11 +1245,19 @@
return FALSE;
}
+#define OPTIONS_SIZE 256
+
+/* safely strcat() at most the remaining space in 'dst' */
+#define strcat_len(dst, src) do { \
+ dst[sizeof (dst) - 1] = '\0'; \
+ strncat (dst, src, sizeof (dst) - strlen (dst) - 1); \
+} while(0)
+
static boolean
fs_table_add_volume (FSTable *table, Volume *volume)
{
- char *mount_options;
FSTableLine *line;
+ char options[OPTIONS_SIZE];
if (fs_table_has_volume (table, volume))
{
@@ -1192,26 +1266,28 @@
return FALSE;
}
- if (hal_device_property_exists (hal_context, volume->udi, "storage.drive_type") &&
- strcmp (hal_device_get_property_string (hal_context, volume->udi, "storage.drive_type"),
- "cdrom") == 0) {
-#ifdef USE_NOOP_MOUNT_OPTION
- mount_options = "noauto,user,exec,dev,suid,kudzu,ro";
-#else
- mount_options = "noauto,user,exec,dev,suid,ro";
-#endif
- } else {
-#ifdef USE_NOOP_MOUNT_OPTION
- mount_options = "noauto,user,exec,dev,suid,kudzu";
-#else
- mount_options = "noauto,user,exec,dev,suid";
+ options[0] = '\0';
+
+ strcat_len (options, "noauto,user,exec");
+
+#ifdef FSTAB_SYNC_USE_NOOP_MOUNT_OPTION
+ strcat_len (options, "," FSTAB_SYNC_MOUNT_MANAGED_KEYWORD);
#endif
- }
+
+ if (volume->is_optical_drive)
+ strcat_len (options, ",ro");
+
+ /* cheeasy heuristic for memory sticks */
+ if (volume->size > 0 &&
+ volume->size < 1024*1024*1024 && /* 1GB */
+ volume->is_hotpluggable) {
+ strcat_len (options, ",noatime,sync");
+ }
line = fs_table_line_new_from_field_values (volume->block_device,
volume->mount_point,
volume->fs_type,
- mount_options, 0, 0);
+ strdup (options), 0, 0);
fs_table_add_line (table, line);
return TRUE;
@@ -1291,60 +1367,6 @@
return buf.st_mtime;
}
-static int
-open_and_lock_file (const char *filename)
-{
- struct flock lock;
- int fd, saved_errno, lock_status;
- time_t timeout;
-
- fd = open (filename, O_RDONLY);
-
- if (fd < 0)
- {
- fstab_update_debug (_("%d: failed to open '%s': %s\n"),
- pid, filename, strerror (errno));
- return FALSE;
- }
-
- lock.l_type = F_RDLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0;
-
- timeout = time (NULL) + LOCK_TIMEOUT;
-
- while ((lock_status = fcntl (fd, F_SETLK, &lock)) < 0)
- {
- saved_errno = errno;
-
- if (saved_errno != EACCES
- && saved_errno != EAGAIN
- && saved_errno != EINTR)
- break;
-
- usleep (LOCK_TIMEOUT_WAIT);
-
- if (time (NULL) > timeout)
- {
- fstab_update_debug (_("%d: timed out waiting for read lock on '%s'\n"),
- pid, filename);
- close (fd);
- return FALSE;
- }
- }
-
- if (lock_status < 0)
- {
- fstab_update_debug (_("%d: Could not get read lock on '%s': %s\n"),
- pid, filename, strerror (saved_errno));
- close (fd);
- return FALSE;
- }
-
- return fd;
-}
-
static boolean
volume_determine_mount_point (Volume *volume, FSTable *table)
{
@@ -1371,7 +1393,7 @@
else
continue;
- if (strcmp (mount_root, MOUNT_ROOT) != 0)
+ if (strcmp (mount_root, FSTAB_SYNC_MOUNT_ROOT "/") != 0)
{
free (mount_root);
continue;
@@ -1405,15 +1427,15 @@
next_available_device_number++;
}
- length = strlen (volume->type) + sizeof (MOUNT_ROOT) + 6 /* digits */;
+ length = strlen (volume->type) + sizeof (FSTAB_SYNC_MOUNT_ROOT "/") + 6 /* digits */;
volume->mount_point = malloc (length);
if (next_available_device_number == 0)
{
- strcpy (volume->mount_point, MOUNT_ROOT);
+ strcpy (volume->mount_point, FSTAB_SYNC_MOUNT_ROOT "/");
strcat (volume->mount_point, volume->type);
}
- else if (snprintf (volume->mount_point, length, MOUNT_ROOT"%s%lu",
+ else if (snprintf (volume->mount_point, length, FSTAB_SYNC_MOUNT_ROOT"/%s%lu",
volume->type, next_available_device_number) > length)
{
fstab_update_debug (_("%d: Could not use mount point '%s': %s\n"),
@@ -1787,6 +1809,13 @@
fstab_update_debug (_("%d: ###################################\n"), pid);
fstab_update_debug (_("%d: %s entering; %s udi=%s\n"),
pid, PROGRAM_NAME, argv[1], hal_device_udi);
+ fstab_update_debug (("%d: mount_root=" FSTAB_SYNC_MOUNT_ROOT
+#ifdef FSTAB_SYNC_USE_NOOP_MOUNT_OPTION
+ " use_managed=yes"
+#else
+ " use_managed=no"
+#endif
+ " managed_keyword=" FSTAB_SYNC_MOUNT_MANAGED_KEYWORD "\n"), pid);
lockfd = open (_PATH_FSTAB, O_RDONLY);
if (lockfd < 0) {
More information about the hal-commit
mailing list