int main(int argc, char **argv) { blkid_dev dev; blkid_cache cache; int ret; if (argc != 2) { fprintf(stderr, "Usage: %s device\n" "Probe a single device to determine type\n", argv[0]); exit(1); } if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) { fprintf(stderr, "%s: error creating cache (%d)\n", argv[0], ret); exit(1); } dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL); if (!dev) { printf("%s: %s has an unsupported type\n", argv[0], argv[1]); return (1); } printf("TYPE='%s'\n", dev->bid_type ? dev->bid_type : "(null)"); if (dev->bid_label) printf("LABEL='%s'\n", dev->bid_label); if (dev->bid_uuid) printf("UUID='%s'\n", dev->bid_uuid); blkid_free_dev(dev); return (0); }
/* * Find a tagname (e.g. LABEL or UUID) on a specific device. */ char *blkid_get_tag_value(blkid_cache cache, const char *tagname, const char *devname) { blkid_tag found; blkid_dev dev; blkid_cache c = cache; char *ret = NULL; DBG(DEBUG_RESOLVE, printf("looking for %s on %s\n", tagname, devname)); if (!devname) return NULL; if (!cache) { if (blkid_get_cache(&c, NULL) < 0) return NULL; } if ((dev = blkid_get_dev(c, devname, BLKID_DEV_NORMAL)) && (found = blkid_find_tag_dev(dev, tagname))) ret = blkid_strdup(found->bit_val); if (!cache) blkid_put_cache(c); return ret; }
/* * Allocate a new device struct with device name filled in. Will handle * finding the device on lines of the form: * <device foo=bar>devname</device> * <device>devname<foo>bar</foo></device> */ static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp) { char *start, *tmp, *end, *name; int ret; if ((ret = parse_start(cp)) <= 0) return ret; start = tmp = strchr(*cp, '>'); if (!start) { DBG(READ, ul_debug("blkid: short line parsing dev: %s", *cp)); return -BLKID_ERR_CACHE; } start = skip_over_blank(start + 1); end = skip_over_word(start); DBG(READ, ul_debug("device should be %*s", (int)(end - start), start)); if (**cp == '>') *cp = end; else (*cp)++; *tmp = '\0'; if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) { DBG(READ, ul_debug("blkid: missing </device> ending: %s", end)); } else if (tmp) *tmp = '\0'; if (end - start <= 1) { DBG(READ, ul_debug("blkid: empty device name: %s", *cp)); return -BLKID_ERR_CACHE; } name = strndup(start, end - start); if (name == NULL) return -BLKID_ERR_MEM; DBG(READ, ul_debug("found dev %s", name)); if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) { free(name); return -BLKID_ERR_MEM; } free(name); return 1; }
/* Search for a partition to resize and expand it if possible. * Both the partition table and the filesytem will be updated. */ int CgptResize(CgptResizeParams *params) { blkid_cache cache = NULL; blkid_dev found_dev = NULL; int err = CGPT_FAILED; if (params == NULL || params->partition_desc == NULL) return CGPT_FAILED; if (blkid_get_cache(&cache, NULL) < 0) goto exit; found_dev = blkid_get_dev(cache, params->partition_desc, BLKID_DEV_NORMAL); if (!found_dev) { Error("device not found %s\n", params->partition_desc); goto exit; } err = resize_partition(params, found_dev); exit: blkid_put_cache(cache); return err; }
int main(int argc, char **argv) { blkid_cache cache = NULL; char *devices[128] = { NULL, }; char *show[128] = { NULL, }; char *search_type = NULL, *search_value = NULL; char *read = NULL; char *write = NULL; int fltr_usage = 0; char **fltr_type = NULL; int fltr_flag = BLKID_FLTR_ONLYIN; unsigned int numdev = 0, numtag = 0; int version = 0; int err = 4; unsigned int i; int output_format = 0; int lookup = 0, gc = 0, lowprobe = 0, eval = 0; int c; uintmax_t offset = 0, size = 0; show[0] = NULL; while ((c = getopt (argc, argv, "c:f:ghilL:n:o:O:ps:S:t:u:U:w:v")) != EOF) switch (c) { case 'c': if (optarg && !*optarg) read = NULL; else read = optarg; if (!write) write = read; break; case 'L': eval++; search_value = strdup(optarg); search_type = strdup("LABEL"); break; case 'n': if (fltr_usage) { fprintf(stderr, "error: -u and -n options are mutually exclusive\n"); exit(4); } fltr_type = list_to_types(optarg, &fltr_flag); break; case 'u': if (fltr_type) { fprintf(stderr, "error: -u and -n options are mutually exclusive\n"); exit(4); } fltr_usage = list_to_usage(optarg, &fltr_flag); break; case 'U': eval++; search_value = strdup(optarg); search_type = strdup("UUID"); break; case 'i': lowprobe |= LOWPROBE_TOPOLOGY; break; case 'l': lookup++; break; case 'g': gc = 1; break; case 'o': if (!strcmp(optarg, "value")) output_format = OUTPUT_VALUE_ONLY; else if (!strcmp(optarg, "device")) output_format = OUTPUT_DEVICE_ONLY; else if (!strcmp(optarg, "list")) output_format = OUTPUT_PRETTY_LIST; else if (!strcmp(optarg, "udev")) output_format = OUTPUT_UDEV_LIST; else if (!strcmp(optarg, "export")) output_format = OUTPUT_EXPORT_LIST; else if (!strcmp(optarg, "full")) output_format = 0; else { fprintf(stderr, "Invalid output format %s. " "Choose from value,\n\t" "device, list, udev or full\n", optarg); exit(4); } break; case 'O': if (strtosize(optarg, &offset)) fprintf(stderr, "Invalid offset '%s' specified\n", optarg); break; case 'p': lowprobe |= LOWPROBE_SUPERBLOCKS; break; case 's': if (numtag + 1 >= sizeof(show) / sizeof(*show)) { fprintf(stderr, "Too many tags specified\n"); usage(err); } show[numtag++] = optarg; show[numtag] = NULL; break; case 'S': if (strtosize(optarg, &size)) fprintf(stderr, "Invalid size '%s' specified\n", optarg); break; case 't': if (search_type) { fprintf(stderr, "Can only search for " "one NAME=value pair\n"); usage(err); } if (blkid_parse_tag_string(optarg, &search_type, &search_value)) { fprintf(stderr, "-t needs NAME=value pair\n"); usage(err); } break; case 'v': version = 1; break; case 'w': if (optarg && !*optarg) write = NULL; else write = optarg; break; case 'h': err = 0; default: usage(err); } while (optind < argc) devices[numdev++] = argv[optind++]; if (version) { print_version(stdout); goto exit; } /* convert LABEL/UUID lookup to evaluate request */ if (lookup && output_format == OUTPUT_DEVICE_ONLY && search_type && (!strcmp(search_type, "LABEL") || !strcmp(search_type, "UUID"))) { eval++; lookup = 0; } if (!lowprobe && !eval && blkid_get_cache(&cache, read) < 0) goto exit; if (gc) { blkid_gc_cache(cache); err = 0; goto exit; } err = 2; if (eval == 0 && (output_format & OUTPUT_PRETTY_LIST)) { if (lowprobe) { fprintf(stderr, "The low-level probing mode does not " "support 'list' output format\n"); exit(4); } pretty_print_dev(NULL); } if (lowprobe) { /* * Low-level API */ blkid_probe pr; if (!numdev) { fprintf(stderr, "The low-level probing mode " "requires a device\n"); exit(4); } /* automatically enable 'export' format for I/O Limits */ if (!output_format && (lowprobe & LOWPROBE_TOPOLOGY)) output_format = OUTPUT_EXPORT_LIST; pr = blkid_new_probe(); if (!pr) goto exit; if (lowprobe & LOWPROBE_SUPERBLOCKS) { blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION); if (fltr_usage && blkid_probe_filter_superblocks_usage( pr, fltr_flag, fltr_usage)) goto exit; else if (fltr_type && blkid_probe_filter_superblocks_type( pr, fltr_flag, fltr_type)) goto exit; } for (i = 0; i < numdev; i++) err = lowprobe_device(pr, devices[i], lowprobe, show, output_format, (blkid_loff_t) offset, (blkid_loff_t) size); blkid_free_probe(pr); } else if (eval) { /* * Evaluate API */ char *res = blkid_evaluate_tag(search_type, search_value, NULL); if (res) { err = 0; printf("%s\n", res); } } else if (lookup) { /* * Classic (cache based) API */ blkid_dev dev; if (!search_type) { fprintf(stderr, "The lookup option requires a " "search type specified using -t\n"); exit(4); } /* Load any additional devices not in the cache */ for (i = 0; i < numdev; i++) blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); if ((dev = blkid_find_dev_with_tag(cache, search_type, search_value))) { print_tags(dev, show, output_format); err = 0; } /* If we didn't specify a single device, show all available devices */ } else if (!numdev) { blkid_dev_iterate iter; blkid_dev dev; blkid_probe_all(cache); iter = blkid_dev_iterate_begin(cache); blkid_dev_set_search(iter, search_type, search_value); while (blkid_dev_next(iter, &dev) == 0) { dev = blkid_verify(cache, dev); if (!dev) continue; print_tags(dev, show, output_format); err = 0; } blkid_dev_iterate_end(iter); /* Add all specified devices to cache (optionally display tags) */ } else for (i = 0; i < numdev; i++) { blkid_dev dev = blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); if (dev) { if (search_type && !blkid_dev_has_tag(dev, search_type, search_value)) continue; print_tags(dev, show, output_format); err = 0; } } exit: free(search_type); free(search_value); free_types_list(fltr_type); if (!lowprobe && !eval) blkid_put_cache(cache); return err; }
int main(int argc, char **argv) { blkid_cache cache = NULL; char *devices[128] = { NULL, }; char *show[128] = { NULL, }; char *search_type = NULL, *search_value = NULL; char *read = NULL; char *write = NULL; unsigned int numdev = 0, numtag = 0; int version = 0; int err = 4; unsigned int i; int output_format = 0; int lookup = 0, gc = 0; int c; while ((c = getopt (argc, argv, "c:f:ghlLo:s:t:w:v")) != EOF) switch (c) { case 'c': if (optarg && !*optarg) read = NULL; else read = optarg; if (!write) write = read; break; case 'l': lookup++; break; case 'L': output_format = OUTPUT_PRETTY_LIST; break; case 'g': gc = 1; break; case 'o': if (!strcmp(optarg, "value")) output_format = OUTPUT_VALUE_ONLY; else if (!strcmp(optarg, "device")) output_format = OUTPUT_DEVICE_ONLY; else if (!strcmp(optarg, "list")) output_format = OUTPUT_PRETTY_LIST; else if (!strcmp(optarg, "full")) output_format = 0; else { fprintf(stderr, "Invalid output format %s. " "Choose from value,\n\t" "device, list, or full\n", optarg); exit(1); } break; case 's': if (numtag >= sizeof(show) / sizeof(*show)) { fprintf(stderr, "Too many tags specified\n"); usage(err); } show[numtag++] = optarg; break; case 't': if (search_type) { fprintf(stderr, "Can only search for " "one NAME=value pair\n"); usage(err); } if (blkid_parse_tag_string(optarg, &search_type, &search_value)) { fprintf(stderr, "-t needs NAME=value pair\n"); usage(err); } break; case 'v': version = 1; break; case 'w': if (optarg && !*optarg) write = NULL; else write = optarg; break; case 'h': err = 0; default: usage(err); } while (optind < argc) devices[numdev++] = argv[optind++]; if (version) { print_version(stdout); goto exit; } if (blkid_get_cache(&cache, read) < 0) goto exit; err = 2; if (gc) { blkid_gc_cache(cache); goto exit; } if (output_format & OUTPUT_PRETTY_LIST) pretty_print_dev(NULL); if (lookup) { blkid_dev dev; if (!search_type) { fprintf(stderr, "The lookup option requires a " "search type specified using -t\n"); exit(1); } /* Load any additional devices not in the cache */ for (i = 0; i < numdev; i++) blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); if ((dev = blkid_find_dev_with_tag(cache, search_type, search_value))) { print_tags(dev, show, numtag, output_format); err = 0; } /* If we didn't specify a single device, show all available devices */ } else if (!numdev) { blkid_dev_iterate iter; blkid_dev dev; blkid_probe_all(cache); iter = blkid_dev_iterate_begin(cache); blkid_dev_set_search(iter, search_type, search_value); while (blkid_dev_next(iter, &dev) == 0) { dev = blkid_verify(cache, dev); if (!dev) continue; print_tags(dev, show, numtag, output_format); err = 0; } blkid_dev_iterate_end(iter); /* Add all specified devices to cache (optionally display tags) */ } else for (i = 0; i < numdev; i++) { blkid_dev dev = blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); if (dev) { if (search_type && !blkid_dev_has_tag(dev, search_type, search_value)) continue; print_tags(dev, show, numtag, output_format); err = 0; } } exit: free(search_type); free(search_value); blkid_put_cache(cache); return err; }
int get_devinfo(struct s_devinfo *outdev, char *indevname, int min, int maj) { char sysblkdevname[512]; blkid_tag_iterate iter; char sysblkinfo[PATH_MAX]; const char *type, *value; struct stat64 statbuf; struct dirent *dir; char temp[PATH_MAX]; blkid_dev dev; DIR *dirdesc; FILE *finfo; int found; int fd; int i; // init memset(outdev, 0, sizeof(struct s_devinfo)); // defaults values outdev->devtype=BLKDEV_INVALID; snprintf(outdev->label, sizeof(outdev->label), " "); snprintf(outdev->uuid, sizeof(outdev->uuid), "<unknown>"); snprintf(outdev->fsname, sizeof(outdev->fsname), "<unknown>"); // check the name starts with "/dev/" if ((strlen(indevname) < 5) || (memcmp(indevname, "/dev/", 5)!=0)) return -1; // get short name ("/dev/sda1" -> "sda1") snprintf(outdev->devname, sizeof(outdev->devname), "%s", indevname+5); // skip "/dev/" // get long name if there is one (eg: LVM / devmapper) snprintf(outdev->longname, sizeof(outdev->longname), "%s", indevname); if ((dirdesc=opendir("/dev/mapper"))!=NULL) { found=false; while (((dir=readdir(dirdesc)) != NULL) && found==false) { snprintf(temp, sizeof(temp), "/dev/mapper/%s", dir->d_name); if ((stat64(temp, &statbuf)==0) && S_ISBLK(statbuf.st_mode) && (major(statbuf.st_rdev)==maj) && (minor(statbuf.st_rdev)==min)) { snprintf(outdev->longname, sizeof(outdev->longname), "%s", temp); found=true; } } closedir(dirdesc); } // get device basic info (size, major, minor) if (((fd=open64(outdev->longname, O_RDONLY|O_LARGEFILE))<0) || ((outdev->devsize=lseek64(fd, 0, SEEK_END))<0) || (fstat64(fd, &statbuf)!=0) || (!S_ISBLK(statbuf.st_mode)) || (close(fd)<0)) return -1; outdev->rdev=statbuf.st_rdev; outdev->major=major(statbuf.st_rdev); outdev->minor=minor(statbuf.st_rdev); format_size(outdev->devsize, outdev->txtsize, sizeof(outdev->txtsize), 'h'); if (outdev->devsize==1024) // ignore extended partitions return -1; // devname shown in /sys/block (eg for HP-cciss: "cciss/c0d0" -> "cciss!c0d0") snprintf(sysblkdevname, sizeof(sysblkdevname), "%s", outdev->devname); for (i=0; (sysblkdevname[i]!=0) && (i<sizeof(sysblkdevname)); i++) if (sysblkdevname[i]=='/') sysblkdevname[i]='!'; // check if it's a physical disk (there is a "/sys/block/${devname}/device") snprintf(sysblkinfo, sizeof(sysblkinfo), "/sys/block/%s/device", sysblkdevname); if (stat64(sysblkinfo, &statbuf)==0) { outdev->devtype=BLKDEV_PHYSDISK; snprintf(sysblkinfo, sizeof(sysblkinfo), "/sys/block/%s/device/model", sysblkdevname); if ( ((finfo=fopen(sysblkinfo, "rb")) != NULL) && (fread(temp, 1, sizeof(temp), finfo)>0) && fclose(finfo)==0 ) for (i=0; (temp[i]!=0) && (temp[i]!='\r') && (temp[i]!='\n'); i++) outdev->name[i]=temp[i]; } else { outdev->devtype=BLKDEV_FILESYSDEV; } // get blkid infos about the device (label, uuid) blkid_cache cache = NULL; if (blkid_get_cache(&cache, NULL) < 0) return -1; if ((dev=blkid_get_dev(cache, outdev->longname, BLKID_DEV_NORMAL))!=NULL) { iter = blkid_tag_iterate_begin(dev); while (blkid_tag_next(iter, &type, &value)==0) { if (strcmp(type, "LABEL")==0) snprintf(outdev->label, sizeof(outdev->label), "%s", value); else if (strcmp(type, "UUID")==0) snprintf(outdev->uuid, sizeof(outdev->uuid), "%s", value); else if (strcmp(type, "TYPE")==0) snprintf(outdev->fsname, sizeof(outdev->fsname), "%s", value); } blkid_tag_iterate_end(iter); // workaround: blkid < 1.41 don't know ext4 and say it is ext3 instead if (strcmp(outdev->fsname, "ext3")==0) { if (ext3_test(outdev->longname)==true) snprintf(outdev->fsname, sizeof(outdev->fsname), "ext3"); else // cannot run ext4_test(): it would fail on an ext4 when e2fsprogs < 1.41 snprintf(outdev->fsname, sizeof(outdev->fsname), "ext4"); } } blkid_put_cache(cache); // free memory allocated by blkid_get_cache return 0; }
int main(int argc, char **argv) { blkid_cache cache = NULL; char **devices = NULL; char *show[128] = { NULL, }; char *search_type = NULL, *search_value = NULL; char *read = NULL; int fltr_usage = 0; char **fltr_type = NULL; int fltr_flag = BLKID_FLTR_ONLYIN; unsigned int numdev = 0, numtag = 0; int version = 0; int err = BLKID_EXIT_OTHER; unsigned int i; int output_format = 0; int lookup = 0, gc = 0, lowprobe = 0, eval = 0; int c; uintmax_t offset = 0, size = 0; static const ul_excl_t excl[] = { /* rows and cols in in ASCII order */ { 'n','u' }, { 0 } }; int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; show[0] = NULL; atexit(close_stdout); while ((c = getopt (argc, argv, "c:df:ghilL:n:ko:O:ps:S:t:u:U:w:Vv")) != EOF) { err_exclusive_options(c, NULL, excl, excl_st); switch (c) { case 'c': if (optarg && !*optarg) read = NULL; else read = optarg; break; case 'd': raw_chars = 1; break; case 'L': eval++; search_value = xstrdup(optarg); search_type = xstrdup("LABEL"); break; case 'n': fltr_type = list_to_types(optarg, &fltr_flag); break; case 'u': fltr_usage = list_to_usage(optarg, &fltr_flag); break; case 'U': eval++; search_value = xstrdup(optarg); search_type = xstrdup("UUID"); break; case 'i': lowprobe |= LOWPROBE_TOPOLOGY; break; case 'l': lookup++; break; case 'g': gc = 1; break; case 'k': { size_t idx = 0; const char *name = NULL; while (blkid_superblocks_get_name(idx++, &name, NULL) == 0) printf("%s\n", name); exit(EXIT_SUCCESS); } case 'o': if (!strcmp(optarg, "value")) output_format = OUTPUT_VALUE_ONLY; else if (!strcmp(optarg, "device")) output_format = OUTPUT_DEVICE_ONLY; else if (!strcmp(optarg, "list")) output_format = OUTPUT_PRETTY_LIST; /* deprecated */ else if (!strcmp(optarg, "udev")) output_format = OUTPUT_UDEV_LIST; else if (!strcmp(optarg, "export")) output_format = OUTPUT_EXPORT_LIST; else if (!strcmp(optarg, "full")) output_format = 0; else { fprintf(stderr, "Invalid output format %s. " "Choose from value,\n\t" "device, list, udev or full\n", optarg); exit(BLKID_EXIT_OTHER); } break; case 'O': offset = strtosize_or_err(optarg, "invalid offset argument"); break; case 'p': lowprobe |= LOWPROBE_SUPERBLOCKS; break; case 's': if (numtag + 1 >= sizeof(show) / sizeof(*show)) { fprintf(stderr, "Too many tags specified\n"); usage(err); } show[numtag++] = optarg; show[numtag] = NULL; break; case 'S': size = strtosize_or_err(optarg, "invalid size argument"); break; case 't': if (search_type) { fprintf(stderr, "Can only search for " "one NAME=value pair\n"); usage(err); } if (blkid_parse_tag_string(optarg, &search_type, &search_value)) { fprintf(stderr, "-t needs NAME=value pair\n"); usage(err); } break; case 'V': case 'v': version = 1; break; case 'w': /* ignore - backward compatibility */ break; case 'h': err = 0; /* fallthrough */ default: usage(err); } } /* The rest of the args are device names */ if (optind < argc) { devices = xcalloc(argc - optind, sizeof(char *)); while (optind < argc) devices[numdev++] = argv[optind++]; } if (version) { print_version(stdout); goto exit; } /* convert LABEL/UUID lookup to evaluate request */ if (lookup && output_format == OUTPUT_DEVICE_ONLY && search_type && (!strcmp(search_type, "LABEL") || !strcmp(search_type, "UUID"))) { eval++; lookup = 0; } if (!lowprobe && !eval && blkid_get_cache(&cache, read) < 0) goto exit; if (gc) { blkid_gc_cache(cache); err = 0; goto exit; } err = BLKID_EXIT_NOTFOUND; if (eval == 0 && (output_format & OUTPUT_PRETTY_LIST)) { if (lowprobe) { fprintf(stderr, "The low-level probing mode does not " "support 'list' output format\n"); exit(BLKID_EXIT_OTHER); } pretty_print_dev(NULL); } if (lowprobe) { /* * Low-level API */ blkid_probe pr; if (!numdev) { fprintf(stderr, "The low-level probing mode " "requires a device\n"); exit(BLKID_EXIT_OTHER); } /* automatically enable 'export' format for I/O Limits */ if (!output_format && (lowprobe & LOWPROBE_TOPOLOGY)) output_format = OUTPUT_EXPORT_LIST; pr = blkid_new_probe(); if (!pr) goto exit; if (lowprobe & LOWPROBE_SUPERBLOCKS) { blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID | BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE | BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION); if (fltr_usage && blkid_probe_filter_superblocks_usage( pr, fltr_flag, fltr_usage)) goto exit; else if (fltr_type && blkid_probe_filter_superblocks_type( pr, fltr_flag, fltr_type)) goto exit; } for (i = 0; i < numdev; i++) { err = lowprobe_device(pr, devices[i], lowprobe, show, output_format, (blkid_loff_t) offset, (blkid_loff_t) size); if (err) break; } blkid_free_probe(pr); } else if (eval) { /* * Evaluate API */ char *res = blkid_evaluate_tag(search_type, search_value, NULL); if (res) { err = 0; printf("%s\n", res); } } else if (lookup) { /* * Classic (cache based) API */ blkid_dev dev; if (!search_type) { fprintf(stderr, "The lookup option requires a " "search type specified using -t\n"); exit(BLKID_EXIT_OTHER); } /* Load any additional devices not in the cache */ for (i = 0; i < numdev; i++) blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); if ((dev = blkid_find_dev_with_tag(cache, search_type, search_value))) { print_tags(dev, show, output_format); err = 0; } /* If we didn't specify a single device, show all available devices */ } else if (!numdev) { blkid_dev_iterate iter; blkid_dev dev; blkid_probe_all(cache); iter = blkid_dev_iterate_begin(cache); blkid_dev_set_search(iter, search_type, search_value); while (blkid_dev_next(iter, &dev) == 0) { dev = blkid_verify(cache, dev); if (!dev) continue; print_tags(dev, show, output_format); err = 0; } blkid_dev_iterate_end(iter); /* Add all specified devices to cache (optionally display tags) */ } else for (i = 0; i < numdev; i++) { blkid_dev dev = blkid_get_dev(cache, devices[i], BLKID_DEV_NORMAL); if (dev) { if (search_type && !blkid_dev_has_tag(dev, search_type, search_value)) continue; print_tags(dev, show, output_format); err = 0; } } exit: free(search_type); free(search_value); free_types_list(fltr_type); if (!lowprobe && !eval) blkid_put_cache(cache); free(devices); return err; }
int main (int argc, char ** argv) { struct udev * udev; struct udev_device * dev; char * device = NULL; struct udev_monitor * mon = NULL; fd_set readfds; int fdcount, devnum, errcount = 0; unsigned short int i, major, minor; short int * maxminor; char * notification = NULL; char * icon = NULL; NotifyNotification * netlink; NotifyNotification *** netlinkref; blkid_cache cache = NULL; char *read = NULL; blkid_tag_iterate iter; const char *type, *value, *devname; blkid_dev blkdev; GError * error = NULL; printf("%s: %s v%s (compiled: %s)\n", argv[0], PROGNAME, VERSION, DATE); if(!notify_init("Udev-Block-Notification")) { fprintf(stderr, "%s: Can't create notify.\n", argv[0]); exit(EXIT_FAILURE); } udev = udev_new(); if(!udev) { fprintf(stderr, "%s: Can't create udev.\n", argv[0]); exit(EXIT_FAILURE); } mon = udev_monitor_new_from_netlink(udev, "udev"); udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL); udev_monitor_enable_receiving(mon); netlinkref = malloc(256 * sizeof(size_t)); for(i = 0; i < 256; i++) netlinkref[i] = NULL; maxminor = malloc(256 * sizeof(short int)); for(i = 0; i < 256; i++) maxminor[i] = -1; while (1) { FD_ZERO(&readfds); if (mon != NULL) FD_SET(udev_monitor_get_fd(mon), &readfds); fdcount = select(udev_monitor_get_fd(mon) + 1, &readfds, NULL, NULL, NULL); if ((mon != NULL) && FD_ISSET(udev_monitor_get_fd(mon), &readfds)) { dev = udev_monitor_receive_device(mon); if(dev) { device = (char *) udev_device_get_sysname(dev); devnum = udev_device_get_devnum(dev); major = devnum / 256; minor = devnum - (major * 256); switch(udev_device_get_action(dev)[0]) { case 'a': // a: add notification = (char *) malloc(strlen(TEXT_ADD) + strlen(device)); sprintf(notification, TEXT_ADD, device, major, minor); icon = ICON_ADD; break; case 'r': // r: remove notification = (char *) malloc(strlen(TEXT_REMOVE) + strlen(device)); sprintf(notification, TEXT_REMOVE, device, major, minor); icon = ICON_REMOVE; break; case 'm': // m: move notification = (char *) malloc(strlen(TEXT_MOVE) + strlen(device)); sprintf(notification, TEXT_MOVE, device, major, minor); icon = ICON_MOVE; break; case 'c': // c: change notification = (char *) malloc(strlen(TEXT_CHANGE) + strlen(device)); sprintf(notification, TEXT_CHANGE, device, major, minor); icon = ICON_CHANGE; break; default: // we should never get here I think... notification = (char *) malloc(strlen(TEXT_DEFAULT) + strlen(device)); sprintf(notification, TEXT_CHANGE, device, major, minor); icon = ICON_DEFAULT; } blkid_get_cache(&cache, read); blkdev = blkid_get_dev(cache, udev_device_get_devnode(dev), BLKID_DEV_NORMAL); if (blkdev) { iter = blkid_tag_iterate_begin(blkdev); while (blkid_tag_next(iter, &type, &value) == 0) { notification = (char *) realloc(notification, strlen(TEXT_TAG) + strlen(notification) + strlen(type) + strlen(value)); sprintf(notification, TEXT_TAG, notification, type, value); } blkid_tag_iterate_end(iter); blkid_put_cache(cache); } printf("%s: %s\n", argv[0], notification); if (maxminor[major] < minor) { netlinkref[major] = realloc(netlinkref[major], (minor + 1) * sizeof(size_t)); while(maxminor[major] < minor) netlinkref[major][++maxminor[major]] = NULL; } if (netlinkref[major][minor] == NULL) { netlink = notify_notification_new("Udev-Block", notification, icon); netlinkref[major][minor] = netlink; } else { netlink = netlinkref[major][minor]; notify_notification_update(netlink, "Udev-Block", notification, icon); } notify_notification_set_timeout(netlink, NOTIFICATION_TIMEOUT); notify_notification_set_category(netlink, "Udev-Block"); notify_notification_set_urgency (netlink, NOTIFY_URGENCY_NORMAL); while(!notify_notification_show(netlink, &error)) { if (errcount > 1) { fprintf(stderr, "%s: Looks like we can not reconnect to notification daemon... Exiting.\n", argv[0]); exit(EXIT_FAILURE); } else { g_printerr("%s: Error \"%s\" while trying to show notification. Trying to reconnect.\n", argv[0], error->message); errcount++; g_error_free(error); error = NULL; notify_uninit(); usleep(500 * 1000); if(!notify_init("Udev-Block-Notification")) { fprintf(stderr, "%s: Can't create notify.\n", argv[0]); exit(EXIT_FAILURE); } } } errcount = 0; free(notification); udev_device_unref(dev); } // This is not really needed... But we want to make shure not to eat 100% CPU if anything breaks. ;) usleep(500 * 1000); } } udev_unref(udev); return EXIT_SUCCESS; }
static int sl_db_update_filesystem(struct sl_database_connection * db, int host_id, int session_id, const char * path) { struct stat st; int failed = stat(path, &st); if (failed) return failed; struct statfs stfs; failed = statfs(path, &stfs); if (failed) return failed; char * device = blkid_devno_to_devname(st.st_dev); if (device == NULL) { sl_log_write(sl_log_level_notice, sl_log_type_core, "Skip path: { path: %s } because it is not a block device", path); return 0; } char * real_device = realpath(device, NULL); blkid_dev dev = blkid_get_dev(cache, real_device, 0); // find alternative name if (dev == NULL) { char * sys_dev; asprintf(&sys_dev, "/sys/block/%s/dm/name", real_device + 5); int fd = open(sys_dev, O_RDONLY); if (fd > -1) { char buf[64]; ssize_t nb_read = read(fd, buf, 64); buf[nb_read - 1] = '\0'; close(fd); free(real_device); asprintf(&real_device, "/dev/mapper/%s", buf); dev = blkid_get_dev(cache, real_device, 0); } free(sys_dev); } if (dev == NULL) { sl_log_write(sl_log_level_notice, sl_log_type_core, "Skip path: { path: %s } because there is no blkid informations (blkid didn't known filesystem on %s)", path, real_device); free(real_device); free(device); return 0; } sl_log_write(sl_log_level_notice, sl_log_type_core, "Update filesystem: { path: %s }", path); const char * uuid = NULL; const char * label = NULL; const char * type = NULL; blkid_tag_iterate iter = blkid_tag_iterate_begin(dev); const char * key, * value; while (!blkid_tag_next(iter, &key, &value)) { if (!strcmp("UUID", key)) uuid = value; else if (!strcmp("LABEL", key)) label = value; else if (!strcmp("TYPE", key)) type = value; } struct sl_filesystem * fs = sl_filesystem_new(uuid, label, type, st.st_dev, path, stfs.f_bfree, stfs.f_blocks, stfs.f_bsize); blkid_tag_iterate_end(iter); free(device); free(real_device); int s2fs = db->ops->sync_filesystem(db, session_id, fs); if (s2fs < 0) { sl_filesystem_free(fs); return s2fs; } failed = sl_db_update_file(db, host_id, session_id, s2fs, path, NULL, &st); sl_filesystem_free(fs); return failed; }