mirror of
https://github.com/systemd/systemd.git
synced 2025-03-19 22:50:17 +03:00
libudev: record and export "age" of device record
This commit is contained in:
parent
93a724d3f8
commit
9c6a11b1c6
@ -12,6 +12,8 @@ GTK_DOC_CHECK(1.10)
|
||||
AC_PREFIX_DEFAULT([/usr])
|
||||
AC_PATH_PROG([XSLTPROC], [xsltproc])
|
||||
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt], [], [AC_MSG_ERROR([POSIX RT library not found])])
|
||||
|
||||
AC_ARG_WITH([rootlibdir],
|
||||
AS_HELP_STRING([--with-rootlibdir=DIR], [rootfs directory to install shared libraries]),
|
||||
[], [with_rootlibdir=$libdir])
|
||||
|
@ -55,6 +55,7 @@ udev_device_get_devnum
|
||||
udev_device_get_action
|
||||
udev_device_get_sysattr_value
|
||||
udev_device_get_seqnum
|
||||
udev_device_get_usec_since_initialized
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -37,6 +37,7 @@ udev_device_get_action
|
||||
udev_device_get_driver
|
||||
udev_device_get_devnum
|
||||
udev_device_get_seqnum
|
||||
udev_device_get_usec_since_initialized
|
||||
udev_device_get_sysattr_value
|
||||
udev_enumerate_new
|
||||
udev_enumerate_ref
|
||||
|
@ -147,6 +147,8 @@ int udev_device_update_db(struct udev_device *udev_device)
|
||||
fprintf(f, "L:%i\n", udev_device_get_devlink_priority(udev_device));
|
||||
if (udev_device_get_watch_handle(udev_device) >= 0)
|
||||
fprintf(f, "W:%i\n", udev_device_get_watch_handle(udev_device));
|
||||
if (udev_device_get_usec_initialized(udev_device) > 0)
|
||||
fprintf(f, "I:%llu\n", udev_device_get_usec_initialized(udev_device));
|
||||
udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) {
|
||||
if (!udev_list_entry_get_flags(list_entry))
|
||||
continue;
|
||||
|
@ -63,6 +63,7 @@ struct udev_device {
|
||||
struct udev_list_node sysattr_list;
|
||||
struct udev_list_node tags_list;
|
||||
unsigned long long int seqnum;
|
||||
unsigned long long int usec_initialized;
|
||||
int event_timeout;
|
||||
int timeout;
|
||||
int devlink_priority;
|
||||
@ -284,6 +285,9 @@ int udev_device_read_db(struct udev_device *udev_device)
|
||||
case 'W':
|
||||
udev_device_set_watch_handle(udev_device, atoi(val));
|
||||
break;
|
||||
case 'I':
|
||||
udev_device_set_usec_initialized(udev_device, strtoull(val, NULL, 10));
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
@ -1094,6 +1098,44 @@ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
|
||||
return udev_device->seqnum;
|
||||
}
|
||||
|
||||
/**
|
||||
* udev_device_get_usec_since_initialized:
|
||||
* @udev_device: udev device
|
||||
*
|
||||
* Return the number of microseconds passed since udev set up the
|
||||
* device for the first time.
|
||||
*
|
||||
* This is only implemented for devices with need to store properties
|
||||
* in the udev database. All other devices return 0 here.
|
||||
*
|
||||
* Returns: the number of microseconds since the device was first seen.
|
||||
**/
|
||||
unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device)
|
||||
{
|
||||
unsigned long long now;
|
||||
|
||||
if (udev_device == NULL)
|
||||
return 0;
|
||||
if (!udev_device->info_loaded)
|
||||
udev_device_read_db(udev_device);
|
||||
if (udev_device->usec_initialized == 0)
|
||||
return 0;
|
||||
now = usec_monotonic();
|
||||
if (now == 0)
|
||||
return 0;
|
||||
return now - udev_device->usec_initialized;
|
||||
}
|
||||
|
||||
unsigned long long udev_device_get_usec_initialized(struct udev_device *udev_device)
|
||||
{
|
||||
return udev_device->usec_initialized;
|
||||
}
|
||||
|
||||
void udev_device_set_usec_initialized(struct udev_device *udev_device, unsigned long long usec_initialized)
|
||||
{
|
||||
udev_device->usec_initialized = usec_initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* udev_device_get_sysattr_value:
|
||||
* @udev_device: udev device
|
||||
@ -1318,7 +1360,7 @@ const char *udev_device_get_id_filename(struct udev_device *udev_device)
|
||||
* device node permissions and context, or has renamed a network
|
||||
* device.
|
||||
*
|
||||
* For now, this is only implemented for devices with a device node
|
||||
* This is only implemented for devices with a device node
|
||||
* or network interfaces. All other devices return 1 here.
|
||||
*
|
||||
* Returns: 1 if the device is set up. 0 otherwise.
|
||||
|
@ -98,6 +98,8 @@ int udev_device_get_event_timeout(struct udev_device *udev_device);
|
||||
int udev_device_set_event_timeout(struct udev_device *udev_device, int event_timeout);
|
||||
int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum);
|
||||
int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum);
|
||||
unsigned long long udev_device_get_usec_initialized(struct udev_device *udev_device);
|
||||
void udev_device_set_usec_initialized(struct udev_device *udev_device, unsigned long long usec_initialized);
|
||||
int udev_device_get_devlink_priority(struct udev_device *udev_device);
|
||||
int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio);
|
||||
int udev_device_get_watch_handle(struct udev_device *udev_device);
|
||||
@ -224,6 +226,7 @@ int util_run_program(struct udev *udev, const char *command, char **envp,
|
||||
const sigset_t *sigmask, bool reset_prio);
|
||||
int util_resolve_subsys_kernel(struct udev *udev, const char *string,
|
||||
char *result, size_t maxsize, int read_value);
|
||||
unsigned long long usec_monotonic(void);
|
||||
|
||||
/* libudev-selinux-private.c */
|
||||
#ifndef WITH_SELINUX
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "libudev.h"
|
||||
@ -553,3 +554,15 @@ uint64_t util_string_bloom64(const char *str)
|
||||
bits |= 1LLU << ((hash >> 18) & 63);
|
||||
return bits;
|
||||
}
|
||||
|
||||
#define USEC_PER_SEC 1000000ULL
|
||||
#define NSEC_PER_USEC 1000ULL
|
||||
unsigned long long usec_monotonic(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
|
||||
return 0;
|
||||
return (unsigned long long) ts.tv_sec * USEC_PER_SEC +
|
||||
(unsigned long long) ts.tv_nsec / NSEC_PER_USEC;
|
||||
}
|
||||
|
@ -97,6 +97,7 @@ const char *udev_device_get_driver(struct udev_device *udev_device);
|
||||
dev_t udev_device_get_devnum(struct udev_device *udev_device);
|
||||
const char *udev_device_get_action(struct udev_device *udev_device);
|
||||
unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device);
|
||||
unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device);
|
||||
const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr);
|
||||
|
||||
/*
|
||||
|
@ -6,6 +6,6 @@ includedir=@prefix@/include
|
||||
Name: libudev
|
||||
Description: Library to access udev device information
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -ludev
|
||||
Libs: -L${libdir} -ludev -lrt
|
||||
Libs.private:
|
||||
Cflags: -I${includedir}
|
||||
|
@ -643,6 +643,13 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules)
|
||||
err = udev_node_add(dev, event->mode, event->uid, event->gid);
|
||||
}
|
||||
|
||||
/* preserve old, or get new initialization timestamp */
|
||||
if (event->dev_db != NULL && udev_device_get_usec_initialized(event->dev_db) > 0)
|
||||
udev_device_set_usec_initialized(event->dev, udev_device_get_usec_initialized(event->dev_db));
|
||||
else
|
||||
udev_device_set_usec_initialized(event->dev, usec_monotonic());
|
||||
|
||||
/* (re)write database file */
|
||||
udev_device_update_db(dev);
|
||||
udev_device_tag_index(dev, event->dev_db, true);
|
||||
udev_device_set_is_initialized(dev);
|
||||
|
Loading…
x
Reference in New Issue
Block a user