[patch] fstab-sync gets to write to /etc/auto.hal
Luke Kenneth Casson Leighton
lkcl at lkcl.net
Wed Sep 22 15:01:33 PDT 2004
ha ha. 's'veryfunny. makes HAL go up-and-down like a yoyo with
automount going "oh yes, here _i'll_ mount it for you, and here's
it gone again..."
so what does HAL do? it goes "oo, mtab's changed again like it did
4 seconds ago _let's_ tell the user _all_ about it".
stage 2 will be an option to _disable_ the mount and umount stuff
in HAL (based on a config opt in /etc/hal/hald.conf).
not sure whether to do a stage 3 which is to remove the entry from
/etc/auto.hal [because i think if i do that it causes automount to
react a bit funny: the kernel doesn't bother to send notify messages
back to /usr/sbin/automount if a mountpoint is missing from the
config file and a user tries to access it]
in combination with using fusexmp - the example code from the file
system user space - i believe this will solve once and for all the
"users removing drives" issue.
no, despite kernel 2.6 reputedly being capable of having USB drives
nicked out from under it, it _doesn't_ work.
l.
--
--
Truth, honesty and respect are rare commodities that all spring from
the same well: Love. If you love yourself and everyone and everything
around you, funnily and coincidentally enough, life gets a lot better.
--
<a href="http://lkcl.net"> lkcl.net </a> <br />
<a href="mailto:lkcl at lkcl.net"> lkcl at lkcl.net </a> <br />
-------------- next part --------------
--- ../../tmp/hal-0.2.97+cvs20040907/tools/fstab-sync.c 2004-09-01 17:47:06.000000000 +0100
+++ fstab-sync.c 2004-09-22 22:42:11.000000000 +0100
@@ -77,6 +76,15 @@
#define TEMP_FSTAB_PREFIX ".fstab.hal."
#define TEMP_FSTAB_MAX_LENGTH 64
+#ifndef AUTOFS_SYNC_MOUNT_ROOT
+# define AUTOFS_SYNC_MOUNT_ROOT "/etc/auto.hal"
+#endif
+
+/* only used for non-automount fstab-sync management: for
+ * automount management, place an entry in /etc/auto.master:
+ * /media /etc/auto.hal --timeout 2
+ */
+
#ifndef FSTAB_SYNC_MOUNT_ROOT
# define FSTAB_SYNC_MOUNT_ROOT "/media"
#endif
@@ -127,9 +135,30 @@
FS_TABLE_NUM_FIELD_TYPES
} FSTableFieldType;
+static FSTableFieldType fstab_fields[] =
+{
+ FS_TABLE_FIELD_TYPE_BLOCK_DEVICE,
+ FS_TABLE_FIELD_TYPE_MOUNT_POINT,
+ FS_TABLE_FIELD_TYPE_FILE_SYSTEM_TYPE,
+ FS_TABLE_FIELD_TYPE_MOUNT_OPTIONS,
+ FS_TABLE_FIELD_TYPE_DUMP_FREQUENCY,
+ FS_TABLE_FIELD_TYPE_PASS_NUMBER,
+ FS_TABLE_FIELD_TYPE_WHITE_SPACE
+};
+
+static FSTableFieldType autofs_fields[] =
+{
+ FS_TABLE_FIELD_TYPE_MOUNT_POINT,
+ FS_TABLE_FIELD_TYPE_FILE_SYSTEM_TYPE,
+ FS_TABLE_FIELD_TYPE_MOUNT_OPTIONS,
+ FS_TABLE_FIELD_TYPE_BLOCK_DEVICE,
+ FS_TABLE_FIELD_TYPE_WHITE_SPACE
+};
+
typedef struct FSTableField
{
FSTableFieldType type;
+ char *prefix;
char *value;
struct FSTableField *next;
} FSTableField;
@@ -160,6 +189,12 @@
static LibHalContext *hal_context = NULL;
static pid_t pid;
+static boolean automount = FALSE;
+static char *fstab_path;
+static char extra_mount_opts[80];
+
+static FSTableFieldType *fs_fields;
+
static void fs_table_line_add_field (FSTableLine *line, FSTableField *field);
static boolean fs_table_line_is_generated (FSTableLine *line);
static void fs_table_line_update_pointer (FSTableLine *line, FSTableField *field);
@@ -283,19 +318,26 @@
#endif /* HAVE_SELINUX */
static FSTableField *
-fs_table_field_new (FSTableFieldType type, const char *value)
+autofs_table_field_new (FSTableFieldType type, const char *value, const char *prefix)
{
FSTableField *field;
field = malloc (sizeof (FSTableLine));
field->type = type;
+ field->prefix = prefix ? strdup(prefix) : NULL;
field->value = strdup (value);
field->next = NULL;
return field;
}
+static FSTableField *
+fs_table_field_new (FSTableFieldType type, const char *value)
+{
+ return autofs_table_field_new(type, value, NULL);
+}
+
static void
fs_table_field_free (FSTableField *field)
{
@@ -305,6 +347,11 @@
field->type = FS_TABLE_FIELD_TYPE_WHITE_SPACE;
+ if (field->prefix != NULL)
+ {
+ free (field->prefix);
+ field->prefix = NULL;
+ }
if (field->value != NULL)
{
free (field->value);
@@ -341,6 +388,44 @@
}
static FSTableLine *
+autofs_table_line_new_from_field_values (const char *block_device,
+ const char *mount_point,
+ const char *fs_type,
+ const char *mount_options,
+ int dump_frequency,
+ int pass_number)
+{
+ FSTableLine *line;
+ FSTableField *field;
+
+ line = fs_table_line_new ();
+
+ field = autofs_table_field_new (FS_TABLE_FIELD_TYPE_MOUNT_POINT, mount_point, NULL);
+ fs_table_line_add_field (line, field);
+
+ field = fs_table_field_new (FS_TABLE_FIELD_TYPE_WHITE_SPACE,
+ get_whitespace (mount_point, 24));
+ fs_table_line_add_field (line, field);
+
+ field = autofs_table_field_new (FS_TABLE_FIELD_TYPE_FILE_SYSTEM_TYPE, fs_type, "-fstype=");
+ fs_table_line_add_field (line, field);
+
+ field = autofs_table_field_new (FS_TABLE_FIELD_TYPE_MOUNT_OPTIONS, mount_options,
+ mount_options && mount_options[0] ? "," : NULL);
+ fs_table_line_add_field (line, field);
+
+ field = fs_table_field_new (FS_TABLE_FIELD_TYPE_WHITE_SPACE,
+ get_whitespace (mount_options, 24));
+ fs_table_line_add_field (line, field);
+
+ field = autofs_table_field_new (FS_TABLE_FIELD_TYPE_BLOCK_DEVICE, block_device,
+ block_device && block_device[0] ? ":" : NULL);
+ fs_table_line_add_field (line, field);
+
+ return line;
+}
+
+static FSTableLine *
fs_table_line_new_from_field_values (const char *block_device,
const char *mount_point,
const char *fs_type,
@@ -416,6 +501,8 @@
static boolean fs_table_line_is_generated (FSTableLine *line)
{
+ if (automount)
+ return TRUE;
#ifdef FSTAB_SYNC_USE_NOOP_MOUNT_OPTION
if (!fs_table_line_has_mount_option (line, FSTAB_SYNC_MOUNT_MANAGED_KEYWORD))
@@ -468,6 +555,24 @@
}
}
+static void blat_output(size_t *output_string_length,
+ size_t *output_string_capacity,
+ char **output_string,
+ const char *val)
+{
+ size_t field_length = strlen (val);
+
+ if ((*output_string_length) + field_length >= (*output_string_capacity) - 1)
+ {
+ (*output_string_capacity) *= 2;
+
+ (*output_string) = realloc ((*output_string), (*output_string_capacity));
+ }
+
+ strcpy ((*output_string) + (*output_string_length), val);
+ (*output_string_length) += field_length;
+}
+
static char *
fs_table_to_string (FSTable *table, size_t *length)
{
@@ -488,19 +593,12 @@
field = line->fields;
while (field != NULL)
{
- size_t field_length;
-
- field_length = strlen (field->value);
-
- if (output_string_length + field_length >= output_string_capacity - 1)
- {
- output_string_capacity *= 2;
-
- output_string = realloc (output_string, output_string_capacity);
- }
-
- strcpy (output_string + output_string_length, field->value);
- output_string_length += field_length;
+ if (field->prefix != NULL)
+ blat_output(&output_string_length, &output_string_capacity,
+ &output_string, field->prefix);
+ if (field->value != NULL)
+ blat_output(&output_string_length, &output_string_capacity,
+ &output_string, field->value);
field = field->next;
}
@@ -670,13 +768,16 @@
{
FSTableLine *table_line;
FSTableField *field;
- char *field_value, *p;
+ char *field_value, *p, *prefix;
+ int fld_idx = 0;
FSTableFieldType current_field;
size_t i;
+ fstab_update_debug (_("%d: starting fs_table_parse_line: %s\n"), pid, line);
+
table_line = fs_table_line_new ();
- current_field = FS_TABLE_FIELD_TYPE_BLOCK_DEVICE;
+ current_field = fs_fields[fld_idx];
p = (char *) line;
i = 0;
while (*p != '\0' && current_field <= FS_TABLE_FIELD_TYPE_WHITE_SPACE)
@@ -724,8 +825,17 @@
break;
}
+ if (automount && current_field == FS_TABLE_FIELD_TYPE_FILE_SYSTEM_TYPE)
+ {
+ while (line[i] != '\0' && !isspace (line[i]) && line[i] != ',' &&
+ i < length)
+ i++;
+ }
+ else
+ {
while (line[i] != '\0' && !isspace (line[i]) && i < length)
i++;
+ }
if (i > length || (line[i] == '\0' && i < length))
{
@@ -740,10 +850,33 @@
}
assert (line + i != p);
+ prefix = NULL;
+ if (automount && current_field == FS_TABLE_FIELD_TYPE_FILE_SYSTEM_TYPE)
+ {
+ /* assume it starts with -fstype= */
+ field_value = strndup (p+8, line + i - p-8);
+ prefix = "-fstype=";
+ }
+ else if (automount && current_field == FS_TABLE_FIELD_TYPE_MOUNT_OPTIONS)
+ {
+ field_value = strndup (p+1, line + i - p-1);
+ if (field_value[0])
+ prefix=",";
+ }
+ else if (automount && current_field == FS_TABLE_FIELD_TYPE_BLOCK_DEVICE)
+ {
+ field_value = strndup (p+1, line + i - p-1);
+ prefix=":";
+ }
+ else
field_value = strndup (p, line + i - p);
- field = fs_table_field_new (current_field, field_value);
- current_field++;
+
+ fprintf(stderr, "%d %s ", current_field, field_value);
+
+ field = autofs_table_field_new (current_field, field_value, prefix);
+ fld_idx++;
+ current_field = fs_fields[fld_idx];
free (field_value);
fs_table_line_add_field (table_line, field);
@@ -751,6 +884,8 @@
p = (char *) line + i;
}
+ fprintf(stderr, "\n");
+
fs_table_add_line (table, table_line);
return TRUE;
@@ -1164,6 +1299,8 @@
static boolean
create_mount_point_for_volume (Volume *volume)
{
+ if (automount)
+ return TRUE;
/* FIXME: Should only mkdir if we need to and should do so
* recursively for each component of the mount root.
@@ -1219,7 +1356,7 @@
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);
+ fstab_update_debug (_("%d: Found %s pointing to %s in %s"), pid, field->value, buf, fstab_path);
hal_device_set_property_string (hal_context, volume->udi, "block.device", field->value);
return TRUE;
}
@@ -1320,7 +1457,11 @@
options[0] = '\0';
- strcat_len (options, "noauto,user,exec");
+ strcat_len (options, "noauto,user");
+
+ if (extra_mount_opts[0])
+ strcat_len (options, ",");
+ strcat_len (options, extra_mount_opts);
#ifdef FSTAB_SYNC_USE_NOOP_MOUNT_OPTION
strcat_len (options, "," FSTAB_SYNC_MOUNT_MANAGED_KEYWORD);
@@ -1336,6 +1477,12 @@
strcat_len (options, ",noatime,sync");
}
+ if (automount)
+ line = autofs_table_line_new_from_field_values (volume->block_device,
+ volume->mount_point,
+ volume->fs_type,
+ strdup (options), 0, 0);
+ else
line = fs_table_line_new_from_field_values (volume->block_device,
volume->mount_point,
volume->fs_type,
@@ -1436,10 +1583,20 @@
return FALSE;
}
+ if (automount)
+ {
+ if (dev_number == 0)
+ snprintf (desired_name, sizeof (desired_name), "%s", volume->type);
+ else
+ snprintf (desired_name, sizeof (desired_name), "%s%d", volume->type, dev_number);
+ }
+ else
+ {
if (dev_number == 0)
snprintf (desired_name, sizeof (desired_name), FSTAB_SYNC_MOUNT_ROOT "/%s", volume->type);
else
snprintf (desired_name, sizeof (desired_name), FSTAB_SYNC_MOUNT_ROOT "/%s%d", volume->type, dev_number);
+ }
/* see if it's in fstab */
for (line = table->lines; line != NULL; line = line->next) {
@@ -1449,11 +1606,14 @@
}
}
+ if (!automount)
+ {
/* see if the mount point physically exists */
if (stat (desired_name, &statbuf) == 0 || errno != ENOENT) {
dev_number++;
goto tryagain;
}
+ }
volume->mount_point = strdup (desired_name);
return TRUE;
@@ -1482,12 +1642,12 @@
if (volume == NULL)
return FALSE;
- dir = strdup (_PATH_FSTAB);
+ dir = strdup (fstab_path);
last_slash = strrchr (dir, '/');
if (last_slash)
*last_slash = '\0';
- fs_table = fs_table_new (_PATH_FSTAB);
+ fs_table = fs_table_new (fstab_path);
if (fs_table == NULL)
goto error;
@@ -1497,7 +1657,7 @@
if (fd < 0)
goto error;
- fstab_modification_time = get_file_modification_time (_PATH_FSTAB);
+ fstab_modification_time = get_file_modification_time (fstab_path);
if (fstab_modification_time == 0)
goto error;
@@ -1513,7 +1673,7 @@
/* Someone changed the fs table under us, better start over.
*/
- if (get_file_modification_time (_PATH_FSTAB) != fstab_modification_time)
+ if (get_file_modification_time (fstab_path) != fstab_modification_time)
{
close (fd);
unlink (temp_filename);
@@ -1521,10 +1681,10 @@
return add_udi (udi);
}
- if (rename (temp_filename, _PATH_FSTAB) < 0)
+ if (rename (temp_filename, fstab_path) < 0)
{
fstab_update_debug (_("%d: Failed to rename '%s' to '%s': %s\n"),
- pid, temp_filename, _PATH_FSTAB, strerror (errno));
+ pid, temp_filename, fstab_path, strerror (errno));
goto error;
}
@@ -1539,7 +1699,7 @@
volume_free (volume);
#ifdef HAVE_SELINUX
- restore_selinux_context(_PATH_FSTAB);
+ restore_selinux_context(fstab_path);
#endif
return TRUE;
@@ -1563,7 +1723,7 @@
FSTableLine *line = NULL;
char *temp_filename = NULL;
time_t fstab_modification_time;
- int fd;
+ int fd = -1;
boolean is_volume;
char *dir = NULL;
char *last_slash;
@@ -1580,19 +1740,22 @@
block_device = hal_device_get_property_string (hal_context, udi, "block.device");
- dir = strdup (_PATH_FSTAB);
+ if (block_device == NULL)
+ goto error;
+
+ dir = strdup (fstab_path);
last_slash = strrchr (dir, '/');
if (last_slash)
*last_slash = '\0';
- fs_table = fs_table_new (_PATH_FSTAB);
+ fs_table = fs_table_new (fstab_path);
fd = open_temp_fstab_file (dir, &temp_filename);
if (fd < 0)
goto error;
- fstab_modification_time = get_file_modification_time (_PATH_FSTAB);
+ fstab_modification_time = get_file_modification_time (fstab_path);
if (fstab_modification_time == 0)
goto error;
@@ -1609,7 +1772,7 @@
assert (line->mount_point != NULL);
- if (rmdir (line->mount_point) < 0)
+ if (!automount && rmdir (line->mount_point) < 0)
{
fstab_update_debug (_("%d: Failed to remove mount point '%s': %s\n"),
pid, line->mount_point, strerror (errno));
@@ -1622,7 +1785,7 @@
/* Someone changed the fs table under us, better start over.
*/
- if (get_file_modification_time (_PATH_FSTAB) != fstab_modification_time)
+ if (get_file_modification_time (fstab_path) != fstab_modification_time)
{
close (fd);
unlink (temp_filename);
@@ -1630,10 +1793,10 @@
return remove_udi (udi);
}
- if (rename (temp_filename, _PATH_FSTAB) < 0)
+ if (rename (temp_filename, fstab_path) < 0)
{
fstab_update_debug (_("%d: Failed to rename '%s' to '%s': %s\n"),
- pid, temp_filename, _PATH_FSTAB, strerror (errno));
+ pid, temp_filename, fstab_path, strerror (errno));
goto error;
}
@@ -1646,7 +1809,7 @@
fs_table_line_free (line);
#ifdef HAVE_SELINUX
- restore_selinux_context(_PATH_FSTAB);
+ restore_selinux_context(fstab_path);
#endif
return TRUE;
@@ -1655,6 +1818,7 @@
if (fd >= 0)
close (fd);
+ if (block_device != NULL)
free (block_device);
if (temp_filename != NULL)
@@ -1746,19 +1910,19 @@
char *dir = NULL;
char *last_slash;
- dir = strdup (_PATH_FSTAB);
+ dir = strdup (fstab_path);
last_slash = strrchr (dir, '/');
if (last_slash)
*last_slash = '\0';
- fs_table = fs_table_new (_PATH_FSTAB);
+ fs_table = fs_table_new (fstab_path);
fd = open_temp_fstab_file (dir, &temp_filename);
if (fd < 0)
goto error;
- fstab_modification_time = get_file_modification_time (_PATH_FSTAB);
+ fstab_modification_time = get_file_modification_time (fstab_path);
if (fstab_modification_time == 0)
goto error;
@@ -1770,24 +1934,24 @@
/* Someone changed the fs table under us, better start over.
*/
- if (get_file_modification_time (_PATH_FSTAB) != fstab_modification_time)
+ if (get_file_modification_time (fstab_path) != fstab_modification_time)
{
close (fd);
unlink (temp_filename);
return clean ();
}
- if (rename (temp_filename, _PATH_FSTAB) < 0)
+ if (rename (temp_filename, fstab_path) < 0)
{
fstab_update_debug (_("%d: Failed to rename '%s' to '%s': %s\n"),
- pid, temp_filename, _PATH_FSTAB, strerror (errno));
+ pid, temp_filename, fstab_path, strerror (errno));
goto error;
}
close (fd);
#ifdef HAVE_SELINUX
- restore_selinux_context(_PATH_FSTAB);
+ restore_selinux_context(fstab_path);
#endif
syslog (LOG_INFO, _("removed all generated mount points"));
@@ -1804,6 +1968,51 @@
return FALSE;
}
+static int read_line(int input_fd, char *line, size_t max_read)
+{
+ /* inefficient. i don't care. really. ItWorks(tm). ILovePython(tm). */
+ size_t bytes_read;
+ size_t into = 0;
+ while ((bytes_read = read (input_fd, line, 1)) != 0 &&
+ *line != '\n' && into < max_read)
+ {
+ into++;
+ line++;
+ }
+
+ *line = 0;
+
+ return bytes_read == 1;
+
+}
+/* hacked-up function to read some additional mount options
+ * to be tacked onto all entries put into /etc/fstab (or /etc/auto.hal).
+ * e.g. you might want to specify "sync,dirsync" or "uid=fred". or noexec.
+ * uid=fred is essential for autofs because otherwise the file system
+ * can get mounted as root...
+ */
+static void read_fstab_conf_options(void)
+{
+ int f = open("/etc/fstab-sync.conf", O_RDONLY);
+ if (f == -1)
+ return;
+ char line[80];
+ while (read_line(f, line, sizeof(line)))
+ {
+ char *p;
+ p = strchr(line, '=');
+ if (p == NULL)
+ continue;
+ *p = 0;
+ if (strcmp(line, "EXTRA_MOUNT_OPTS") == 0)
+ {
+ strncpy(extra_mount_opts, p+1, sizeof(extra_mount_opts));
+ }
+ }
+
+ close(f);
+}
+
int
main (int argc, const char *argv[])
{
@@ -1814,6 +2023,20 @@
const char **left_over_args = NULL;
int lockfd = -1;
+ extra_mount_opts[0] = 0;
+ read_fstab_conf_options();
+
+ /* choose between autofs and fstab based on last part of name of program
+ * so we can do /etc/hal/devices.d/50-autofs.hal and expect it to work */
+ fstab_path = fstab_path;
+ fs_fields = fstab_fields;
+ if (strcmp(&(argv[0][strlen(argv[0])-10]), "autofs.hal") == 0)
+ {
+ automount = TRUE;
+ fstab_path = AUTOFS_SYNC_MOUNT_ROOT;
+ fs_fields = autofs_fields;
+ }
+
pid = getpid ();
openlog (PROGRAM_NAME, LOG_PID, LOG_USER);
@@ -1895,6 +2118,7 @@
fstab_update_debug (_("%d: ###################################\n"), pid);
fstab_update_debug (_("%d: %s entering; %s udi=%s\n"),
pid, PROGRAM_NAME, argv[1], hal_device_udi);
+ if (!automount)
fstab_update_debug (("%d: mount_root=" FSTAB_SYNC_MOUNT_ROOT
#ifdef FSTAB_SYNC_USE_NOOP_MOUNT_OPTION
" use_managed=yes"
@@ -1902,16 +2126,15 @@
" use_managed=no"
#endif
" managed_keyword=" FSTAB_SYNC_MOUNT_MANAGED_KEYWORD "\n"), pid);
-
- lockfd = open (_PATH_FSTAB, O_RDONLY);
+ lockfd = open (fstab_path, O_RDONLY);
if (lockfd < 0) {
fstab_update_debug (_("%d: couldn't open %s O_RDONLY; bailing out\n"),
- pid, _PATH_FSTAB);
+ pid, fstab_path);
retval = 1;
goto out;
}
- fstab_update_debug (_("%d: Acquiring advisory lock on "
- _PATH_FSTAB "\n"), pid);
+ fstab_update_debug (_("%d: Acquiring advisory lock on %s\n"),
+ pid, fstab_path);
if (flock (lockfd, LOCK_EX) != 0) {
fstab_update_debug (_("%d: Error acquiring lock '%s'; bailing out\n"),
pid, strerror(errno));
@@ -1964,7 +2187,7 @@
if (hal_device_udi != NULL) {
fstab_update_debug (_("%d: Releasing advisory lock on %s\n"),
- pid, _PATH_FSTAB);
+ pid, fstab_path);
if (flock (lockfd, LOCK_EX) != 0) {
fstab_update_debug (_("%d: Error releasing lock '%s'\n"), pid,
strerror(errno));
-------------- next part --------------
_______________________________________________
hal mailing list
hal at freedesktop.org
http://freedesktop.org/mailman/listinfo/hal
More information about the Hal
mailing list