static char *evaluate_by_scan(const char *token, const char *value, blkid_cache *cache, struct blkid_config *conf) { blkid_cache c = cache ? *cache : NULL; char *res; DBG(DEBUG_EVALUATE, printf("evaluating by blkid scan %s=%s\n", token, value)); if (!c) { char *cachefile = blkid_get_cache_filename(conf); blkid_get_cache(&c, cachefile); free(cachefile); } if (!c) return NULL; res = blkid_get_devname(c, token, value); if (cache) *cache = c; else blkid_put_cache(c); return res; }
int main(int argc, char **argv) { char *value; blkid_cache cache; blkid_init_debug(BLKID_DEBUG_ALL); if (argc != 2 && argc != 3) { fprintf(stderr, "Usage:\t%s tagname=value\n" "\t%s tagname devname\n" "Find which device holds a given token or\n" "Find what the value of a tag is in a device\n", argv[0], argv[0]); exit(1); } if (blkid_get_cache(&cache, "/dev/null") < 0) { fprintf(stderr, "Couldn't get blkid cache\n"); exit(1); } if (argv[2]) { value = blkid_get_tag_value(cache, argv[1], argv[2]); printf("%s has tag %s=%s\n", argv[2], argv[1], value ? value : "<missing>"); } else { value = blkid_get_devname(cache, argv[1], NULL); printf("%s has tag %s\n", value ? value : "<none>", argv[1]); } blkid_put_cache(cache); return value ? 0 : 1; }
void e2fsck_free_context(e2fsck_t ctx) { if (!ctx) return; e2fsck_reset_context(ctx); if (ctx->blkid) blkid_put_cache(ctx->blkid); if (ctx->profile) profile_release(ctx->profile); if (ctx->filesystem_name) ext2fs_free_mem(&ctx->filesystem_name); if (ctx->device_name) ext2fs_free_mem(&ctx->device_name); if (ctx->log_fn) free(ctx->log_fn); if (ctx->logf) fclose(ctx->logf); if (ctx->problem_log_fn) free(ctx->problem_log_fn); if (ctx->problem_logf) fclose(ctx->problem_logf); ext2fs_free_mem(&ctx); }
/* * 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; }
void fsprobe_exit(void) { if (blprobe) blkid_free_probe(blprobe); if (blcache) blkid_put_cache(blcache); }
void e2fsck_free_context(e2fsck_t ctx) { if (!ctx) return; e2fsck_reset_context(ctx); if (ctx->blkid) blkid_put_cache(ctx->blkid); ext2fs_free_mem(&ctx); }
/* * Locate a device name from a token (NAME=value string), or (name, value) * pair. In the case of a token, value is ignored. If the "token" is not * of the form "NAME=value" and there is no value given, then it is assumed * to be the actual devname and a copy is returned. */ char *blkid_get_devname(blkid_cache cache, const char *token, const char *value) { blkid_dev dev; blkid_cache c = cache; char *t = 0, *v = 0; char *ret = NULL; if (!token) return NULL; if (!cache) { if (blkid_get_cache(&c, NULL) < 0) return NULL; } DBG(DEBUG_RESOLVE, printf("looking for %s%s%s %s\n", token, value ? "=" : "", value ? value : "", cache ? "in cache" : "from disk")); if (!value) { if (!strchr(token, '=')) { ret = blkid_strdup(token); goto out; } blkid_parse_tag_string(token, &t, &v); if (!t || !v) goto out; token = t; value = v; } dev = blkid_find_dev_with_tag(c, token, value); if (!dev) goto out; ret = blkid_strdup(blkid_dev_devname(dev)); out: if (t) free(t); if (v) free(v); if (!cache) { blkid_put_cache(c); } return (ret); }
char * fsprobe_get_fstype_by_devname(const char *devname) { blkid_cache c; char *tp; if (blcache) return blkid_get_tag_value(blcache, "TYPE", devname); /* The cache is not initialized yet. Use empty cache rather than waste * time with /etc/blkid.tab. It seems that probe FS is faster than * parse the cache file. -- kzak (17-May-2007) */ blkid_get_cache(&c, BLKID_EMPTY_CACHE); tp = blkid_get_tag_value(c, "TYPE", devname); blkid_put_cache(c); return tp; }
int main(int argc, char**argv) { blkid_cache cache = NULL; int ret; blkid_init_debug(BLKID_DEBUG_ALL); if (argc > 2) { fprintf(stderr, "Usage: %s [filename]\n" "Test parsing of the cache (filename)\n", argv[0]); exit(1); } if ((ret = blkid_get_cache(&cache, argv[1])) < 0) fprintf(stderr, "error %d reading cache file %s\n", ret, argv[1] ? argv[1] : blkid_get_cache_filename(NULL)); blkid_put_cache(cache); return ret; }
int main(int argc, char *argv[]) { blkid_cache cache = NULL; char *res; if (argc < 3) { fprintf(stderr, "usage: %s <token> <value>\n", argv[0]); return EXIT_FAILURE; } blkid_init_debug(0); res = blkid_evaluate_tag(argv[1], argv[2], &cache); if (res) printf("%s\n", res); if (cache) blkid_put_cache(cache); return res ? EXIT_SUCCESS : EXIT_FAILURE; }
/** * mnt_free_cache: * @cache: pointer to struct libmnt_cache instance * * Deallocates the cache. This function does not care about reference count. Don't * use this function directly -- it's better to use use mnt_unref_cache(). */ void mnt_free_cache(struct libmnt_cache *cache) { size_t i; if (!cache) return; DBG(CACHE, ul_debugobj(cache, "free [refcount=%d]", cache->refcount)); for (i = 0; i < cache->nents; i++) { struct mnt_cache_entry *e = &cache->ents[i]; if (e->value != e->key) free(e->value); free(e->key); } free(cache->ents); if (cache->bc) blkid_put_cache(cache->bc); free(cache); }
/* * Locate a device name from a token (NAME=value string), or (name, value) * pair. In the case of a token, value is ignored. If the "token" is not * of the form "NAME=value" and there is no value given, then it is assumed * to be the actual devname and a copy is returned. */ char *blkid_get_devname(blkid_cache cache, const char *token, const char *value) { blkid_dev dev; blkid_cache c = cache; char *t = 0, *v = 0; char *ret = NULL; if (!token) return NULL; if (!cache && blkid_get_cache(&c, NULL) < 0) return NULL; DBG(RESOLVE, ul_debug("looking for %s%s%s %s", token, value ? "=" : "", value ? value : "", cache ? "in cache" : "from disk")); if (!value) { if (!strchr(token, '=')) { ret = strdup(token); goto out; } blkid_parse_tag_string(token, &t, &v); if (!t || !v) goto out; token = t; value = v; } dev = blkid_find_dev_with_tag(c, token, value); if (!dev) goto out; ret = dev->bid_name ? strdup(dev->bid_name) : NULL; out: free(t); free(v); if (!cache) blkid_put_cache(c); return ret; }
/** * mnt_free_cache: * @cache: pointer to struct libmnt_cache instance * * Deallocates the cache. */ void mnt_free_cache(struct libmnt_cache *cache) { size_t i; if (!cache) return; DBG(CACHE, mnt_debug_h(cache, "free")); for (i = 0; i < cache->nents; i++) { struct mnt_cache_entry *e = &cache->ents[i]; if (e->value != e->key) free(e->value); free(e->key); } free(cache->ents); free(cache->filename); if (cache->bc) blkid_put_cache(cache->bc); blkid_free_probe(cache->pr); free(cache); }
/* 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) { 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; }
/* * Use libblkid to quickly search for zfs devices */ static int zpool_find_import_blkid(libzfs_handle_t *hdl, pool_list_t *pools) { blkid_cache cache; blkid_dev_iterate iter; blkid_dev dev; const char *devname; nvlist_t *config; int fd, err, num_labels; err = blkid_get_cache(&cache, NULL); if (err != 0) { (void) zfs_error_fmt(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "blkid_get_cache() %d"), err); goto err_blkid1; } err = blkid_probe_all(cache); if (err != 0) { (void) zfs_error_fmt(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "blkid_probe_all() %d"), err); goto err_blkid2; } iter = blkid_dev_iterate_begin(cache); if (iter == NULL) { (void) zfs_error_fmt(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "blkid_dev_iterate_begin()")); goto err_blkid2; } err = blkid_dev_set_search(iter, "TYPE", "zfs_member"); if (err != 0) { (void) zfs_error_fmt(hdl, EZFS_BADCACHE, dgettext(TEXT_DOMAIN, "blkid_dev_set_search() %d"), err); goto err_blkid3; } while (blkid_dev_next(iter, &dev) == 0) { devname = blkid_dev_devname(dev); if ((fd = open(devname, O_RDONLY)) < 0) continue; err = zpool_read_label(fd, &config, &num_labels); (void) close(fd); if (err != 0) { (void) no_memory(hdl); goto err_blkid3; } if (config != NULL) { err = add_config(hdl, pools, devname, 0, num_labels, config); if (err != 0) goto err_blkid3; } } err_blkid3: blkid_dev_iterate_end(iter); err_blkid2: blkid_put_cache(cache); err_blkid1: return (err); }
void fsprobe_exit(void) { if (blcache) blkid_put_cache(blcache); }
/* * return 1 if the device looks plausible, creating the file if necessary */ int check_plausibility(const char *device, int flags, int *ret_is_dev) { int fd, ret, is_dev = 0; ext2fs_struct_stat s; int fl = O_RDONLY; blkid_cache cache = NULL; char *fs_type = NULL; char *fs_label = NULL; fd = ext2fs_open_file(device, fl, 0666); if ((fd < 0) && (errno == ENOENT) && (flags & CREATE_FILE)) { fl |= O_CREAT; fd = ext2fs_open_file(device, fl, 0666); if (fd >= 0 && (flags & VERBOSE_CREATE)) printf(_("Creating regular file %s\n"), device); } if (fd < 0) { fprintf(stderr, _("Could not open %s: %s\n"), device, error_message(errno)); if (errno == ENOENT) fputs(_("\nThe device apparently does not exist; " "did you specify it correctly?\n"), stderr); exit(1); } if (ext2fs_fstat(fd, &s) < 0) { perror("stat"); exit(1); } close(fd); if (S_ISBLK(s.st_mode)) is_dev = 1; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) /* On FreeBSD, all disk devices are character specials */ if (S_ISCHR(s.st_mode)) is_dev = 1; #endif if (ret_is_dev) *ret_is_dev = is_dev; if ((flags & CHECK_BLOCK_DEV) && !is_dev) { printf(_("%s is not a block special device.\n"), device); return 0; } /* * Note: we use the older-style blkid API's here because we * want as much functionality to be available when using the * internal blkid library, when e2fsprogs is compiled for * non-Linux systems that will probably not have the libraries * from util-linux available. We only use the newer * blkid-probe interfaces to access functionality not * available in the original blkid library. */ if ((flags & CHECK_FS_EXIST) && blkid_get_cache(&cache, NULL) >= 0) { fs_type = blkid_get_tag_value(cache, "TYPE", device); if (fs_type) fs_label = blkid_get_tag_value(cache, "LABEL", device); blkid_put_cache(cache); } if (fs_type) { if (fs_label) printf(_("%s contains a %s file system " "labelled '%s'\n"), device, fs_type, fs_label); else printf(_("%s contains a %s file system\n"), device, fs_type); if (strncmp(fs_type, "ext", 3) == 0) print_ext2_info(device); free(fs_type); free(fs_label); return 0; } ret = check_partition_table(device); if (ret >= 0) return ret; #ifdef HAVE_LINUX_MAJOR_H #ifndef MAJOR #define MAJOR(dev) ((dev)>>8) #define MINOR(dev) ((dev) & 0xff) #endif #ifndef SCSI_BLK_MAJOR #ifdef SCSI_DISK0_MAJOR #ifdef SCSI_DISK8_MAJOR #define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \ ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) || \ ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR)) #else #define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \ ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR)) #endif /* defined(SCSI_DISK8_MAJOR) */ #define SCSI_BLK_MAJOR(M) (SCSI_DISK_MAJOR((M)) || (M) == SCSI_CDROM_MAJOR) #else #define SCSI_BLK_MAJOR(M) ((M) == SCSI_DISK_MAJOR || (M) == SCSI_CDROM_MAJOR) #endif /* defined(SCSI_DISK0_MAJOR) */ #endif /* defined(SCSI_BLK_MAJOR) */ if (((MAJOR(s.st_rdev) == HD_MAJOR && MINOR(s.st_rdev)%64 == 0) || (SCSI_BLK_MAJOR(MAJOR(s.st_rdev)) && MINOR(s.st_rdev)%16 == 0))) { printf(_("%s is entire device, not just one partition!\n"), device); return 0; } #endif return 1; }
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 fsck_main(int argc, char *argv[]) { int i, status = 0; int interactive = 0; const char *fstab; struct fs_info *fs; setvbuf(stdout, NULL, _IONBF, BUFSIZ); setvbuf(stderr, NULL, _IONBF, BUFSIZ); blkid_get_cache(&cache, NULL); PRS(argc, argv); if (!notitle) printf("fsck %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); fstab = getenv("FSTAB_FILE"); if (!fstab) fstab = _PATH_MNTTAB; load_fs_info(fstab); fsck_path = e2fs_set_sbin_path(); if ((num_devices == 1) || (serialize)) interactive = 1; /* If -A was specified ("check all"), do that! */ if (doall) return check_all(); if (num_devices == 0) { serialize++; interactive++; return check_all(); } for (i = 0 ; i < num_devices; i++) { if (cancel_requested) { if (!kill_sent) { kill_all(SIGTERM); kill_sent++; } break; } fs = lookup(devices[i]); if (!fs) { fs = create_fs_device(devices[i], 0, "auto", 0, -1, -1); if (!fs) continue; } fsck_device(fs, interactive); if (serialize || (max_running && (num_running >= max_running))) { struct fsck_instance *inst; inst = wait_one(0); if (inst) { status |= inst->exit_status; free_instance(inst); } if (verbose > 1) printf("----------------------------------\n"); } } status |= wait_many(FLAG_WAIT_ALL); blkid_put_cache(cache); return status; }
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; }
void mount_blkid_put_cache(void) { blkid_put_cache(blkid); }
int main(int argc, char *argv[]) { int i, status = 0; int interactive = 0; char *oldpath = getenv("PATH"); const char *fstab; struct fs_info *fs; setvbuf(stdout, NULL, _IONBF, BUFSIZ); setvbuf(stderr, NULL, _IONBF, BUFSIZ); #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif blkid_get_cache(&cache, NULL); PRS(argc, argv); if (!notitle) printf("fsck %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); fstab = getenv("FSTAB_FILE"); if (!fstab) fstab = _PATH_MNTTAB; load_fs_info(fstab); /* Update our search path to include uncommon directories. */ if (oldpath) { fsck_path = malloc (strlen (fsck_prefix_path) + 1 + strlen (oldpath) + 1); if (!fsck_path) { fprintf(stderr, "%s: Unable to allocate memory for fsck_path\n", progname); exit(EXIT_ERROR); } strcpy (fsck_path, fsck_prefix_path); strcat (fsck_path, ":"); strcat (fsck_path, oldpath); } else { fsck_path = string_copy(fsck_prefix_path); } if ((num_devices == 1) || (serialize)) interactive = 1; /* If -A was specified ("check all"), do that! */ if (doall) return check_all(); if (num_devices == 0) { serialize++; interactive++; return check_all(); } for (i = 0 ; i < num_devices; i++) { if (cancel_requested) { if (!kill_sent) { kill_all(SIGTERM); kill_sent++; } break; } fs = lookup(devices[i]); if (!fs) { fs = create_fs_device(devices[i], 0, "auto", 0, -1, -1); if (!fs) continue; } if (ignore_mounted && is_mounted(fs->device)) continue; fsck_device(fs, interactive); if (serialize || (max_running && (num_running >= max_running))) { struct fsck_instance *inst; inst = wait_one(0); if (inst) { status |= inst->exit_status; free_instance(inst); } if (verbose > 1) printf("----------------------------------\n"); } } status |= wait_many(FLAG_WAIT_ALL); free(fsck_path); blkid_put_cache(cache); return status; }
static errcode_t ext2fs_get_journal(ext2_filsys fs, journal_t **ret_journal) { struct process_block_struct pb; struct ext2_super_block *sb = fs->super; struct ext2_super_block jsuper; struct buffer_head *bh; struct inode *j_inode = NULL; struct kdev_s *dev_fs = NULL, *dev_journal; const char *journal_name = 0; journal_t *journal = NULL; errcode_t retval = 0; io_manager io_ptr = 0; unsigned long long start = 0; int ext_journal = 0; int tried_backup_jnl = 0; retval = ext2fs_get_memzero(sizeof(journal_t), &journal); if (retval) return retval; retval = ext2fs_get_memzero(2 * sizeof(struct kdev_s), &dev_fs); if (retval) goto errout; dev_journal = dev_fs+1; dev_fs->k_fs = dev_journal->k_fs = fs; dev_fs->k_dev = K_DEV_FS; dev_journal->k_dev = K_DEV_JOURNAL; journal->j_dev = dev_journal; journal->j_fs_dev = dev_fs; journal->j_inode = NULL; journal->j_blocksize = fs->blocksize; if (uuid_is_null(sb->s_journal_uuid)) { if (!sb->s_journal_inum) { retval = EXT2_ET_BAD_INODE_NUM; goto errout; } retval = ext2fs_get_memzero(sizeof(*j_inode), &j_inode); if (retval) goto errout; j_inode->i_fs = fs; j_inode->i_ino = sb->s_journal_inum; retval = ext2fs_read_inode(fs, sb->s_journal_inum, &j_inode->i_ext2); if (retval) { try_backup_journal: if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS || tried_backup_jnl) goto errout; memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode)); memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks, EXT2_N_BLOCKS*4); j_inode->i_ext2.i_size_high = sb->s_jnl_blocks[15]; j_inode->i_ext2.i_size = sb->s_jnl_blocks[16]; j_inode->i_ext2.i_links_count = 1; j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600; tried_backup_jnl++; } if (!j_inode->i_ext2.i_links_count || !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) { retval = EXT2_ET_NO_JOURNAL; goto try_backup_journal; } if (EXT2_I_SIZE(&j_inode->i_ext2) / journal->j_blocksize < JFS_MIN_JOURNAL_BLOCKS) { retval = EXT2_ET_JOURNAL_TOO_SMALL; goto try_backup_journal; } pb.last_block = -1; retval = ext2fs_block_iterate3(fs, j_inode->i_ino, BLOCK_FLAG_HOLE, 0, process_journal_block, &pb); if ((pb.last_block + 1) * fs->blocksize < (int) EXT2_I_SIZE(&j_inode->i_ext2)) { retval = EXT2_ET_JOURNAL_TOO_SMALL; goto try_backup_journal; } if (tried_backup_jnl && (fs->flags & EXT2_FLAG_RW)) { retval = ext2fs_write_inode(fs, sb->s_journal_inum, &j_inode->i_ext2); if (retval) goto errout; } journal->j_maxlen = EXT2_I_SIZE(&j_inode->i_ext2) / journal->j_blocksize; #ifdef USE_INODE_IO retval = ext2fs_inode_io_intern2(fs, sb->s_journal_inum, &j_inode->i_ext2, &journal_name); if (retval) goto errout; io_ptr = inode_io_manager; #else journal->j_inode = j_inode; fs->journal_io = fs->io; retval = (errcode_t)journal_bmap(journal, 0, &start); if (retval) goto errout; #endif } else { ext_journal = 1; if (!fs->journal_name) { char uuid[37]; blkid_cache blkid; blkid_get_cache(&blkid, NULL); uuid_unparse(sb->s_journal_uuid, uuid); fs->journal_name = blkid_get_devname(blkid, "UUID", uuid); if (!fs->journal_name) fs->journal_name = blkid_devno_to_devname(sb->s_journal_dev); blkid_put_cache(blkid); } journal_name = fs->journal_name; if (!journal_name) { retval = EXT2_ET_LOAD_EXT_JOURNAL; goto errout; } jfs_debug(1, "Using journal file %s\n", journal_name); io_ptr = unix_io_manager; } #if 0 test_io_backing_manager = io_ptr; io_ptr = test_io_manager; #endif #ifndef USE_INODE_IO if (ext_journal) #endif { retval = io_ptr->open(journal_name, fs->flags & EXT2_FLAG_RW, &fs->journal_io); } if (retval) goto errout; io_channel_set_blksize(fs->journal_io, fs->blocksize); if (ext_journal) { blk64_t maxlen; start = ext2fs_journal_sb_start(fs->blocksize) - 1; bh = getblk(dev_journal, start, fs->blocksize); if (!bh) { retval = EXT2_ET_NO_MEMORY; goto errout; } ll_rw_block(READ, 1, &bh); retval = bh->b_err; if (retval) { brelse(bh); goto errout; } memcpy(&jsuper, start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET, sizeof(jsuper)); #ifdef WORDS_BIGENDIAN if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) ext2fs_swap_super(&jsuper); #endif if (jsuper.s_magic != EXT2_SUPER_MAGIC || !ext2fs_has_feature_journal_dev(&jsuper)) { retval = EXT2_ET_LOAD_EXT_JOURNAL; brelse(bh); goto errout; } /* Make sure the journal UUID is correct */ if (memcmp(jsuper.s_uuid, fs->super->s_journal_uuid, sizeof(jsuper.s_uuid))) { retval = EXT2_ET_LOAD_EXT_JOURNAL; brelse(bh); goto errout; } /* Check the superblock checksum */ if (ext2fs_has_feature_metadata_csum(&jsuper)) { struct struct_ext2_filsys fsx; struct ext2_super_block superx; void *p; p = start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET; memcpy(&fsx, fs, sizeof(fsx)); memcpy(&superx, fs->super, sizeof(superx)); fsx.super = &superx; ext2fs_set_feature_metadata_csum(fsx.super); if (!ext2fs_superblock_csum_verify(&fsx, p)) { retval = EXT2_ET_LOAD_EXT_JOURNAL; brelse(bh); goto errout; } } brelse(bh); maxlen = ext2fs_blocks_count(&jsuper); journal->j_maxlen = (maxlen < 1ULL << 32) ? maxlen : (1ULL << 32) - 1; start++; } bh = getblk(dev_journal, start, journal->j_blocksize); if (!bh) { retval = EXT2_ET_NO_MEMORY; goto errout; } journal->j_sb_buffer = bh; journal->j_superblock = (journal_superblock_t *)bh->b_data; #ifdef USE_INODE_IO if (j_inode) ext2fs_free_mem(&j_inode); #endif *ret_journal = journal; return 0; errout: if (dev_fs) ext2fs_free_mem(&dev_fs); if (j_inode) ext2fs_free_mem(&j_inode); if (journal) ext2fs_free_mem(&journal); return retval; }