Beispiel #1
0
void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old)
{
        struct udev_list_entry *list_entry;

        /* update possible left-over symlinks */
        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev_old)) {
                const char *name = udev_list_entry_get_name(list_entry);
                struct udev_list_entry *list_entry_current;
                int found;

                /* check if old link name still belongs to this device */
                found = 0;
                udev_list_entry_foreach(list_entry_current, udev_device_get_devlinks_list_entry(dev)) {
                        const char *name_current = udev_list_entry_get_name(list_entry_current);

                        if (streq(name, name_current)) {
                                found = 1;
                                break;
                        }
                }
                if (found)
                        continue;

                log_debug("update old name, '%s' no longer belonging to '%s'",
                     name, udev_device_get_devpath(dev));
                link_update(dev, name, false);
        }
}
QStringList Device::alternateDeviceSymlinks() const
{
    if (!d)
        return QStringList();

    return listFromListEntry(udev_device_get_devlinks_list_entry(d->udev));
}
Beispiel #3
0
void udev_node_add(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid)
{
        struct udev *udev = udev_device_get_udev(dev);
        char filename[UTIL_PATH_SIZE];
        struct udev_list_entry *list_entry;
        int err = 0;

        info(udev, "handling device node '%s', devnum=%s, mode=%#o, uid=%d, gid=%d\n",
             udev_device_get_devnode(dev), udev_device_get_id_filename(dev), mode, uid, gid);

        if (node_fixup(dev, mode, uid, gid) < 0)
                return;

        /* always add /dev/{block,char}/$major:$minor */
        snprintf(filename, sizeof(filename), "%s/%s/%u:%u",
                 udev_get_dev_path(udev),
                 strcmp(udev_device_get_subsystem(dev), "block") == 0 ? "block" : "char",
                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
        node_symlink(udev, udev_device_get_devnode(dev), filename);

        /* create/update symlinks, add symlinks to name index */
        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) {
                if (udev_list_entry_get_num(list_entry))
                        /* simple unmanaged link name */
                        node_symlink(udev, udev_device_get_devnode(dev), udev_list_entry_get_name(list_entry));
                else
                        link_update(dev, udev_list_entry_get_name(list_entry), 1);
        }
}
Beispiel #4
0
static void print_record(struct udev_device *device) {
        const char *str;
        int i;
        struct udev_list_entry *list_entry;

        printf("P: %s\n", udev_device_get_devpath(device));

        str = udev_device_get_devnode(device);
        if (str != NULL)
                printf("N: %s\n", str + STRLEN("/dev/"));

        i = udev_device_get_devlink_priority(device);
        if (i != 0)
                printf("L: %i\n", i);

        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
                printf("S: %s\n",
                       udev_list_entry_get_name(list_entry) + STRLEN("/dev/"));

        udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
                printf("E: %s=%s\n",
                       udev_list_entry_get_name(list_entry),
                       udev_list_entry_get_value(list_entry));
        printf("\n");
}
Beispiel #5
0
void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev_old, int test)
{
	struct udev *udev = udev_device_get_udev(dev);
	struct udev_list_entry *list_entry;
	const char *devnode_old;

	/* update possible left-over symlinks */
	udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev_old)) {
		const char *name = udev_list_entry_get_name(list_entry);
		struct udev_list_entry *list_entry_current;
		int found;

		/* check if old link name is now our node name */
		if (strcmp(name, udev_device_get_devnode(dev)) == 0)
			continue;

		/* check if old link name still belongs to this device */
		found = 0;
		udev_list_entry_foreach(list_entry_current, udev_device_get_devlinks_list_entry(dev)) {
			const char *name_current = udev_list_entry_get_name(list_entry_current);

			if (strcmp(name, name_current) == 0) {
				found = 1;
				break;
			}
		}
		if (found)
			continue;

		info(udev, "update old symlink '%s' no longer belonging to '%s'\n", name, udev_device_get_devpath(dev));
		name_index(udev, udev_device_get_devpath(dev), name, 0, test);
		update_link(dev, name, test);
	}

	/*
	 * if the node name has changed, delete the node,
	 * and possibly restore a symlink of another device
	 */
	devnode_old = udev_device_get_devnode(dev_old);
	if (devnode_old != NULL) {
		const char *devnode = udev_device_get_devnode(dev);

		if (devnode != NULL && strcmp(devnode_old, devnode) != 0)
			update_link(dev, devnode_old, test);
	}
}
Beispiel #6
0
int udev_node_remove(struct udev_device *dev)
{
	struct udev *udev = udev_device_get_udev(dev);
	struct udev_list_entry *list_entry;
	const char *devnode;
	struct stat stats;
	struct udev_device *dev_check;
	char filename[UTIL_PATH_SIZE];
	int err = 0;

	/* remove/update symlinks, remove symlinks from name index */
	udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
		link_update(dev, udev_list_entry_get_name(list_entry), 0);

	devnode = udev_device_get_devnode(dev);
	if (devnode == NULL)
		goto out;

	if (stat(devnode, &stats) != 0) {
		info(udev, "device node '%s' not found\n", devnode);
		goto out;
	}

	if (stats.st_rdev != udev_device_get_devnum(dev)) {
		info(udev, "device node '%s' points to a different device, skip removal\n", devnode);
		err = -1;
		goto out;
	}

	dev_check = udev_device_new_from_syspath(udev, udev_device_get_syspath(dev));
	if (dev_check != NULL) {
		/* do not remove device node if the same sys-device is re-created in the meantime */
		info(udev, "keeping device node of existing device'%s'\n", devnode);
		udev_device_unref(dev_check);
		goto out;
	}

	info(udev, "removing device node '%s'\n", devnode);
	err = util_unlink_secure(udev, devnode);
	if (err == 0)
		util_delete_path(udev, devnode);

	/* remove /dev/{block,char}/$major:$minor */
	snprintf(filename, sizeof(filename), "%s/%s/%u:%u",
		 udev_get_dev_path(udev),
		 strcmp(udev_device_get_subsystem(dev), "block") == 0 ? "block" : "char",
		 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
	unlink(filename);
out:
	return err;
}
Beispiel #7
0
void udev_node_remove(struct udev_device *dev) {
        struct udev_list_entry *list_entry;
        char filename[UTIL_PATH_SIZE];

        /* remove/update symlinks, remove symlinks from name index */
        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
                link_update(dev, udev_list_entry_get_name(list_entry), false);

        /* remove /dev/{block,char}/$major:$minor */
        snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
                 streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
        unlink(filename);
}
Beispiel #8
0
static void print_device(struct udev_device *device)
{
    const char *str;
    dev_t devnum;
    int count;
    struct udev_list_entry *list_entry;

    printf("*** device: %p ***\n", device);
    str = udev_device_get_action(device);
    if (str != NULL)
        printf("action:    '%s'\n", str);

    str = udev_device_get_syspath(device);
    printf("syspath:   '%s'\n", str);

    str = udev_device_get_sysname(device);
    printf("sysname:   '%s'\n", str);

    str = udev_device_get_sysnum(device);
    if (str != NULL)
        printf("sysnum:    '%s'\n", str);

    str = udev_device_get_devpath(device);
    printf("devpath:   '%s'\n", str);

    str = udev_device_get_subsystem(device);
    if (str != NULL)
        printf("subsystem: '%s'\n", str);

    str = udev_device_get_devtype(device);
    if (str != NULL)
        printf("devtype:   '%s'\n", str);

    str = udev_device_get_driver(device);
    if (str != NULL)
        printf("driver:    '%s'\n", str);

    str = udev_device_get_devnode(device);
    if (str != NULL)
        printf("devname:   '%s'\n", str);

    devnum = udev_device_get_devnum(device);
    if (major(devnum) > 0)
        printf("devnum:    %u:%u\n", major(devnum), minor(devnum));

    count = 0;
    udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
        printf("link:      '%s'\n", udev_list_entry_get_name(list_entry));
        count++;
    }
Beispiel #9
0
void udev_node_remove(struct udev_device *dev) {
        struct udev_list_entry *list_entry;
        char filename[DEV_NUM_PATH_MAX];

        /* remove/update symlinks, remove symlinks from name index */
        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
                link_update(dev, udev_list_entry_get_name(list_entry), false);

        /* remove /dev/{block,char}/$major:$minor */
        xsprintf_dev_num_path(filename,
                              streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
                              udev_device_get_devnum(dev));
        unlink(filename);
}
int udev_node_remove(struct udev_device *dev)
{
	struct udev *udev = udev_device_get_udev(dev);
	struct udev_list_entry *list_entry;
	const char *devnode;
	char partitionname[UTIL_PATH_SIZE];
	struct stat stats;
	int err = 0;
	int num;

	/* remove,update symlinks, remove symlinks from name index */
	udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
		link_update(dev, udev_list_entry_get_name(list_entry), 0);

	devnode = udev_device_get_devnode(dev);
	if (devnode == NULL)
		return 0;
	if (stat(devnode, &stats) != 0) {
		info(udev, "device node '%s' not found\n", devnode);
		return 0;
	}
	if (stats.st_rdev != udev_device_get_devnum(dev)) {
		info(udev, "device node '%s' points to a different device, skip removal\n", devnode);
		return -1;
	}

	info(udev, "removing device node '%s'\n", devnode);
	err = util_unlink_secure(udev, devnode);
	if (err)
		return err;

	num = udev_device_get_num_fake_partitions(dev);
	if (num > 0) {
		int i;

		info(udev, "removing all_partitions '%s[1-%i]'\n", devnode, num);
		if (num > 255)
			return -1;
		for (i = 1; i <= num; i++) {
			snprintf(partitionname, sizeof(partitionname), "%s%d", devnode, i);
			partitionname[sizeof(partitionname)-1] = '\0';
			util_unlink_secure(udev, partitionname);
		}
	}
	util_delete_path(udev, devnode);
	return err;
}
Beispiel #11
0
int udev_node_add(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid, int test)
{
	struct udev *udev = udev_device_get_udev(dev);
	int i;
	int num;
	struct udev_list_entry *list_entry;
	int err = 0;

	info(udev, "creating device node '%s', devnum=%d:%d, mode=%#o, uid=%d, gid=%d\n",
	     udev_device_get_devnode(dev),
	     major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)),
	     mode, uid, gid);

	util_create_path(udev, udev_device_get_devnode(dev));
	if (!test)
		if (udev_node_mknod(dev, NULL, makedev(0,0), mode, uid, gid) != 0) {
			err = -1;
			goto exit;
		}

	/* create all_partitions if requested */
	num = udev_device_get_num_fake_partitions(dev);
	if (num > 0) {
		info(udev, "creating device partition nodes '%s[1-%i]'\n", udev_device_get_devnode(dev), num);
		if (!test) {
			for (i = 1; i <= num; i++) {
				char partitionname[UTIL_PATH_SIZE];
				dev_t part_devnum;

				snprintf(partitionname, sizeof(partitionname), "%s%d",
					 udev_device_get_devnode(dev), i);
				partitionname[sizeof(partitionname)-1] = '\0';
				part_devnum = makedev(major(udev_device_get_devnum(dev)),
						    minor(udev_device_get_devnum(dev)) + i);
				udev_node_mknod(dev, partitionname, part_devnum, mode, uid, gid);
			}
		}
	}

	/* add node to name index */
	name_index(udev, udev_device_get_devpath(dev), udev_device_get_devnode(dev), 1, test);

	/* create/update symlinks, add symlinks to name index */
	udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) {
		name_index(udev, udev_device_get_devpath(dev), udev_list_entry_get_name(list_entry), 1, test);
		update_link(dev, udev_list_entry_get_name(list_entry), test);
	}
Beispiel #12
0
static int
udev_device_get_devid(struct udev_device *dev, char *bufptr, size_t buflen)
{
	struct udev_list_entry *entry;
	const char *bus;
	char devbyid[MAXPATHLEN];

	/* The bus based by-id path is preferred */
	bus = udev_device_get_property_value(dev, "ID_BUS");

	if (bus == NULL) {
		const char *dm_uuid;

		/*
		 * For multipath nodes use the persistent uuid based identifier
		 *
		 * Example: 'dm-uuid-mpath-35000c5006304de3f'
		 */
		dm_uuid = udev_device_get_property_value(dev, "DM_UUID");
		if (dm_uuid != NULL) {
			(void) snprintf(bufptr, buflen, "dm-uuid-%s", dm_uuid);
			return (0);
		}
		return (ENODATA);
	}

	/*
	 * locate the bus specific by-id link
	 *
	 * Example: 'scsi-MG03SCA300_350000494a8cb3d67-part1'
	 */
	(void) snprintf(devbyid, sizeof (devbyid), "%s%s-", DEV_BYID_PATH, bus);
	entry = udev_device_get_devlinks_list_entry(dev);
	while (entry != NULL) {
		const char *name;

		name = udev_list_entry_get_name(entry);
		if (strncmp(name, devbyid, strlen(devbyid)) == 0) {
			name += strlen(DEV_BYID_PATH);
			(void) stpncpy(bufptr, name, buflen);
			return (0);
		}
		entry = udev_list_entry_get_next(entry);
	}

	return (ENODATA);
}
int udev_node_add(struct udev_device *dev, mode_t mode, uid_t uid, gid_t gid)
{
	struct udev *udev = udev_device_get_udev(dev);
	int i;
	int num;
	struct udev_list_entry *list_entry;
	int err = 0;

	info(udev, "creating device node '%s', devnum=%d:%d, mode=%#o, uid=%d, gid=%d\n",
	     udev_device_get_devnode(dev),
	     major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)),
	     mode, uid, gid);

	if (udev_node_mknod(dev, NULL, makedev(0,0), mode, uid, gid) != 0) {
		err = -1;
		goto exit;
	}

	/* create all_partitions if requested */
	num = udev_device_get_num_fake_partitions(dev);
	if (num > 0) {
		info(udev, "creating device partition nodes '%s[1-%i]'\n", udev_device_get_devnode(dev), num);
		for (i = 1; i <= num; i++) {
			char partitionname[UTIL_PATH_SIZE];
			dev_t part_devnum;

			snprintf(partitionname, sizeof(partitionname), "%s%d",
				 udev_device_get_devnode(dev), i);
			partitionname[sizeof(partitionname)-1] = '\0';
			part_devnum = makedev(major(udev_device_get_devnum(dev)),
					    minor(udev_device_get_devnum(dev)) + i);
			udev_node_mknod(dev, partitionname, part_devnum, mode, uid, gid);
		}
	}

	/* create/update symlinks, add symlinks to name index */
	udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) {
		if (udev_list_entry_get_flag(list_entry))
			/* simple unmanaged link name */
			node_symlink(udev, udev_device_get_devnode(dev), udev_list_entry_get_name(list_entry));
		else
			link_update(dev, udev_list_entry_get_name(list_entry), 1);
	}
exit:
	return err;
}
Beispiel #14
0
extern int udev_node_remove(struct udev_device *dev, int test)
{
	struct udev *udev = udev_device_get_udev(dev);
	struct udev_list_entry *list_entry;
	const char *devnode;
	char partitionname[UTIL_PATH_SIZE];
	struct stat stats;
	int err = 0;
	int num;

	/* remove node from name index */
	name_index(udev, udev_device_get_devpath(dev), udev_device_get_devnode(dev), 0, test);

	/* remove,update symlinks, remove symlinks from name index */
	udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev)) {
		name_index(udev, udev_device_get_devpath(dev), udev_list_entry_get_name(list_entry), 0, test);
		update_link(dev, udev_list_entry_get_name(list_entry), test);
	}
Beispiel #15
0
void udev_node_remove(struct udev_device *dev)
{
        struct udev *udev = udev_device_get_udev(dev);
        struct udev_list_entry *list_entry;
        const char *devnode;
        struct stat stats;
        struct udev_device *dev_check;
        char filename[UTIL_PATH_SIZE];

        /* remove/update symlinks, remove symlinks from name index */
        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
                link_update(dev, udev_list_entry_get_name(list_entry), 0);

        /* remove /dev/{block,char}/$major:$minor */
        snprintf(filename, sizeof(filename), "%s/%s/%u:%u",
                 udev_get_dev_path(udev),
                 strcmp(udev_device_get_subsystem(dev), "block") == 0 ? "block" : "char",
                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
        unlink(filename);
}
Beispiel #16
0
void udev_node_add(struct udev_device *dev, bool apply, mode_t mode, uid_t uid, gid_t gid)
{
        char filename[UTIL_PATH_SIZE];
        struct udev_list_entry *list_entry;

        log_debug("handling device node '%s', devnum=%s, mode=%#o, uid=%d, gid=%d\n",
                  udev_device_get_devnode(dev), udev_device_get_id_filename(dev), mode, uid, gid);

        if (node_permissions_apply(dev, apply, mode, uid, gid) < 0)
                return;

        /* always add /dev/{block,char}/$major:$minor */
        snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
                 streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
                 major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
        node_symlink(dev, udev_device_get_devnode(dev), filename);

        /* create/update symlinks, add symlinks to name index */
        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
                        link_update(dev, udev_list_entry_get_name(list_entry), true);
}
Beispiel #17
0
void udev_node_add(struct udev_device *dev, bool apply,
                   mode_t mode, uid_t uid, gid_t gid,
                   struct udev_list *seclabel_list) {
        char filename[DEV_NUM_PATH_MAX];
        struct udev_list_entry *list_entry;

        log_debug("handling device node '%s', devnum=%s, mode=%#o, uid="UID_FMT", gid="GID_FMT,
                  udev_device_get_devnode(dev), udev_device_get_id_filename(dev), mode, uid, gid);

        if (node_permissions_apply(dev, apply, mode, uid, gid, seclabel_list) < 0)
                return;

        /* always add /dev/{block,char}/$major:$minor */
        xsprintf_dev_num_path(filename,
                              streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
                              udev_device_get_devnum(dev));
        node_symlink(dev, udev_device_get_devnode(dev), filename);

        /* create/update symlinks, add symlinks to name index */
        udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(dev))
                        link_update(dev, udev_list_entry_get_name(list_entry), true);
}
Beispiel #18
0
int main( int argc, char** argv ) {
   
   int rc = 0;
   char pathbuf[PATH_MAX+1];
   struct udev* udev_client = NULL;
   struct udev_monitor* monitor = NULL;
   int monitor_fd = 0;
   struct udev_device* dev = NULL;
   struct pollfd pfd[1];
   int num_events = INT_MAX;
   int num_forks = 0;
   
   // usage: $0 [num events to process [num times to fork]]
   if( argc > 1 ) {
      char* tmp = NULL;
      num_events = (int)strtol( argv[1], &tmp, 10 );
      if( tmp == argv[1] || *tmp != '\0' ) {
         fprintf(stderr, "Usage: %s [number of events to process [number of times to fork]]\n", argv[0] );
         exit(1);
      }
      
      if( argc > 2 ) {
         
         num_forks = (int)strtol( argv[2], &tmp, 10 );
         if( tmp == argv[2] || *tmp != '\0' ) {
            fprintf(stderr, "Usage: %s [number of events to process [number of times to fork]]\n", argv[0] );
            exit(1);
         }
      }
   }
   
   // make sure events dir exists 
   log_trace("events directory '%s'", UDEV_FS_EVENTS_DIR);
   
   rc = mkdir( UDEV_FS_EVENTS_DIR, 0700 );
   if( rc != 0 ) {
      
      rc = -errno;
      if( rc != -EEXIST ) {
         log_error("mkdir('%s') rc = %d", UDEV_FS_EVENTS_DIR, rc );
         exit(1);
      }
   }
   
   udev_monitor_fs_events_path( "", pathbuf, 0 );
   
   printf("Watching '%s'\n", pathbuf );
   
   udev_client = udev_new();
   if( udev_client == NULL ) {
      
      // OOM
      exit(2);
   }
   
   monitor = udev_monitor_new_from_netlink( udev_client, "udev" );
   if( monitor == NULL ) {
      
      // OOM or error
      udev_unref( udev_client );
      exit(2);
   }
   
   printf("Press Ctrl-C to quit\n");
   
   monitor_fd = udev_monitor_get_fd( monitor );
   if( monitor_fd < 0 ) {
      
      rc = -errno;
      log_error("udev_monitor_get_fd rc = %d\n", rc );
      exit(3);
   }
   
   pfd[0].fd = monitor_fd;
   pfd[0].events = POLLIN;
   
   while( num_events > 0 ) {
      
      // wait for the next device 
      rc = poll( pfd, 1, -1 );
      if( rc < 0 ) {
      
         log_error("poll(%d) rc = %d\n", monitor_fd, rc );
         break;
      }
      
      // get devices 
      while( num_events > 0 ) {
         
         dev = udev_monitor_receive_device( monitor );
         if( dev == NULL ) {
            break;
         }
         
         int pid = getpid();
         struct udev_list_entry *list_entry = NULL;
         
         printf("[%d] [%d] ACTION:     '%s'\n", pid, num_events, udev_device_get_action( dev ) );
         printf("[%d] [%d] SEQNUM:      %llu\n", pid, num_events, udev_device_get_seqnum( dev ) );
         printf("[%d] [%d] USEC:        %llu\n", pid, num_events, udev_device_get_usec_since_initialized( dev ) );
         printf("[%d] [%d] DEVNODE:    '%s'\n", pid, num_events, udev_device_get_devnode( dev ) );
         printf("[%d] [%d] DEVPATH:    '%s'\n", pid, num_events, udev_device_get_devpath( dev ) );
         printf("[%d] [%d] SYSNAME:    '%s'\n", pid, num_events, udev_device_get_sysname( dev ) );
         printf("[%d] [%d] SYSPATH:    '%s'\n", pid, num_events, udev_device_get_syspath( dev ) );
         printf("[%d] [%d] SUBSYSTEM:  '%s'\n", pid, num_events, udev_device_get_subsystem( dev ) );
         printf("[%d] [%d] DEVTYPE:    '%s'\n", pid, num_events, udev_device_get_devtype( dev ) );
         printf("[%d] [%d] SYSNUM:     '%s'\n", pid, num_events, udev_device_get_sysnum( dev ) );
         printf("[%d] [%d] DRIVER:     '%s'\n", pid, num_events, udev_device_get_driver( dev ) );
         printf("[%d] [%d] DEVNUM:      %d:%d\n", pid, num_events, major( udev_device_get_devnum( dev ) ), minor( udev_device_get_devnum( dev ) ) );
         printf("[%d] [%d] IFINDEX:    '%s'\n", pid, num_events, udev_device_get_property_value( dev, "IFINDEX" ) );
         printf("[%d] [%d] DEVMODE:    '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVMODE" ) );
         printf("[%d] [%d] DEVUID:     '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVUID" ) );
         printf("[%d] [%d] DEVGID:     '%s'\n", pid, num_events, udev_device_get_property_value( dev, "DEVGID" ) );         
         
         list_entry = udev_device_get_devlinks_list_entry( dev );
         udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) {
          
            printf("[%d] [%d] devlink:    '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ) );
         }
         
         list_entry = udev_device_get_properties_list_entry( dev );
         udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) {
            
            printf("[%d] [%d] property:   '%s' = '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ), udev_list_entry_get_value( list_entry ) );
         }
         
         list_entry = udev_device_get_tags_list_entry( dev );
         udev_list_entry_foreach( list_entry, udev_list_entry_get_next( list_entry )) {
            
            printf("[%d] [%d] tag:        '%s'\n", pid, num_events, udev_list_entry_get_name( list_entry ) );
         }
Beispiel #19
0
static void dev_kmsg_record(Server *s, const char *p, size_t l) {

        _cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL, *identifier = NULL, *pid = NULL;
        struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
        char *kernel_device = NULL;
        unsigned long long usec;
        size_t n = 0, z = 0, j;
        int priority, r;
        char *e, *f, *k;
        uint64_t serial;
        size_t pl;

        assert(s);
        assert(p);

        if (l <= 0)
                return;

        e = memchr(p, ',', l);
        if (!e)
                return;
        *e = 0;

        r = safe_atoi(p, &priority);
        if (r < 0 || priority < 0 || priority > 999)
                return;

        if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN)
                return;

        l -= (e - p) + 1;
        p = e + 1;
        e = memchr(p, ',', l);
        if (!e)
                return;
        *e = 0;

        r = safe_atou64(p, &serial);
        if (r < 0)
                return;

        if (s->kernel_seqnum) {
                /* We already read this one? */
                if (serial < *s->kernel_seqnum)
                        return;

                /* Did we lose any? */
                if (serial > *s->kernel_seqnum)
                        server_driver_message(s, 0,
                                              "MESSAGE_ID=" SD_MESSAGE_JOURNAL_MISSED_STR,
                                              LOG_MESSAGE("Missed %"PRIu64" kernel messages",
                                                          serial - *s->kernel_seqnum),
                                              NULL);

                /* Make sure we never read this one again. Note that
                 * we always store the next message serial we expect
                 * here, simply because this makes handling the first
                 * message with serial 0 easy. */
                *s->kernel_seqnum = serial + 1;
        }

        l -= (e - p) + 1;
        p = e + 1;
        f = memchr(p, ';', l);
        if (!f)
                return;
        /* Kernel 3.6 has the flags field, kernel 3.5 lacks that */
        e = memchr(p, ',', l);
        if (!e || f < e)
                e = f;
        *e = 0;

        r = safe_atollu(p, &usec);
        if (r < 0)
                return;

        l -= (f - p) + 1;
        p = f + 1;
        e = memchr(p, '\n', l);
        if (!e)
                return;
        *e = 0;

        pl = e - p;
        l -= (e - p) + 1;
        k = e + 1;

        for (j = 0; l > 0 && j < N_IOVEC_KERNEL_FIELDS; j++) {
                char *m;
                /* Metadata fields attached */

                if (*k != ' ')
                        break;

                k++, l--;

                e = memchr(k, '\n', l);
                if (!e)
                        return;

                *e = 0;

                if (cunescape_length_with_prefix(k, e - k, "_KERNEL_", UNESCAPE_RELAX, &m) < 0)
                        break;

                if (startswith(m, "_KERNEL_DEVICE="))
                        kernel_device = m + 15;

                iovec[n++] = IOVEC_MAKE_STRING(m);
                z++;

                l -= (e - k) + 1;
                k = e + 1;
        }

        if (kernel_device) {
                struct udev_device *ud;

                ud = udev_device_new_from_device_id(s->udev, kernel_device);
                if (ud) {
                        const char *g;
                        struct udev_list_entry *ll;
                        char *b;

                        g = udev_device_get_devnode(ud);
                        if (g) {
                                b = strappend("_UDEV_DEVNODE=", g);
                                if (b) {
                                        iovec[n++] = IOVEC_MAKE_STRING(b);
                                        z++;
                                }
                        }

                        g = udev_device_get_sysname(ud);
                        if (g) {
                                b = strappend("_UDEV_SYSNAME=", g);
                                if (b) {
                                        iovec[n++] = IOVEC_MAKE_STRING(b);
                                        z++;
                                }
                        }

                        j = 0;
                        ll = udev_device_get_devlinks_list_entry(ud);
                        udev_list_entry_foreach(ll, ll) {

                                if (j > N_IOVEC_UDEV_FIELDS)
                                        break;

                                g = udev_list_entry_get_name(ll);
                                if (g) {
                                        b = strappend("_UDEV_DEVLINK=", g);
                                        if (b) {
                                                iovec[n++] = IOVEC_MAKE_STRING(b);
                                                z++;
                                        }
                                }

                                j++;
                        }

                        udev_device_unref(ud);
                }
        }

        if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", usec) >= 0)
                iovec[n++] = IOVEC_MAKE_STRING(source_time);

        iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=kernel");

        if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
                iovec[n++] = IOVEC_MAKE_STRING(syslog_priority);

        if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
                iovec[n++] = IOVEC_MAKE_STRING(syslog_facility);

        if ((priority & LOG_FACMASK) == LOG_KERN)
                iovec[n++] = IOVEC_MAKE_STRING("SYSLOG_IDENTIFIER=kernel");
        else {
                pl -= syslog_parse_identifier((const char**) &p, &identifier, &pid);

                /* Avoid any messages we generated ourselves via
                 * log_info() and friends. */
                if (pid && is_us(pid))
                        goto finish;

                if (identifier) {
                        syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
                        if (syslog_identifier)
                                iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier);
                }

                if (pid) {
                        syslog_pid = strappend("SYSLOG_PID=", pid);
                        if (syslog_pid)
                                iovec[n++] = IOVEC_MAKE_STRING(syslog_pid);
                }
        }

        if (cunescape_length_with_prefix(p, pl, "MESSAGE=", UNESCAPE_RELAX, &message) >= 0)
                iovec[n++] = IOVEC_MAKE_STRING(message);

        server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, priority, 0);

finish:
        for (j = 0; j < z; j++)
                free(iovec[j].iov_base);
}